xref: /aosp_15_r20/external/coreboot/src/vendorcode/cavium/bdk/libbdk-hal/bdk-sata.c (revision b9411a12aaaa7e1e6a6fb7c5e057f44ee179a49c)
1 /***********************license start***********************************
2 * Copyright (c) 2003-2017  Cavium Inc. ([email protected]). All rights
3 * reserved.
4 *
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions are
8 * met:
9 *
10 *   * Redistributions of source code must retain the above copyright
11 *     notice, this list of conditions and the following disclaimer.
12 *
13 *   * Redistributions in binary form must reproduce the above
14 *     copyright notice, this list of conditions and the following
15 *     disclaimer in the documentation and/or other materials provided
16 *     with the distribution.
17 *
18 *   * Neither the name of Cavium Inc. nor the names of
19 *     its contributors may be used to endorse or promote products
20 *     derived from this software without specific prior written
21 *     permission.
22 *
23 * This Software, including technical data, may be subject to U.S. export
24 * control laws, including the U.S. Export Administration Act and its
25 * associated regulations, and may be subject to export or import
26 * regulations in other countries.
27 *
28 * TO THE MAXIMUM EXTENT PERMITTED BY LAW, THE SOFTWARE IS PROVIDED "AS IS"
29 * AND WITH ALL FAULTS AND CAVIUM INC. MAKES NO PROMISES, REPRESENTATIONS OR
30 * WARRANTIES, EITHER EXPRESS, IMPLIED, STATUTORY, OR OTHERWISE, WITH RESPECT
31 * TO THE SOFTWARE, INCLUDING ITS CONDITION, ITS CONFORMITY TO ANY
32 * REPRESENTATION OR DESCRIPTION, OR THE EXISTENCE OF ANY LATENT OR PATENT
33 * DEFECTS, AND CAVIUM SPECIFICALLY DISCLAIMS ALL IMPLIED (IF ANY) WARRANTIES
34 * OF TITLE, MERCHANTABILITY, NONINFRINGEMENT, FITNESS FOR A PARTICULAR
35 * PURPOSE, LACK OF VIRUSES, ACCURACY OR COMPLETENESS, QUIET ENJOYMENT,
36 * QUIET POSSESSION OR CORRESPONDENCE TO DESCRIPTION. THE ENTIRE  RISK
37 * ARISING OUT OF USE OR PERFORMANCE OF THE SOFTWARE LIES WITH YOU.
38 ***********************license end**************************************/
39 #include <bdk.h>
40 #include <malloc.h>
41 #include "libbdk-arch/bdk-csrs-sata.h"
42 
43 /* This code is an optional part of the BDK. It is only linked in
44     if BDK_REQUIRE() needs it */
45 BDK_REQUIRE_DEFINE(SATA);
46 
47 /* Most all information used to create this code was gotten from this wiki
48    page: http://wiki.osdev.org/AHCI */
49 
50 /**
51  * Following code defines different kinds of FIS specified in Serial
52  *    ATA Revision 3.0.
53  */
54 typedef enum
55 {
56     FIS_TYPE_REG_H2D    = 0x27, /**< Register FIS - host to device */
57     FIS_TYPE_REG_D2H    = 0x34, /**< Register FIS - device to host */
58     FIS_TYPE_DMA_ACT    = 0x39, /**< DMA activate FIS - device to host */
59     FIS_TYPE_DMA_SETUP  = 0x41, /**< DMA setup FIS - bidirectional */
60     FIS_TYPE_DATA       = 0x46, /**< Data FIS - bidirectional */
61     FIS_TYPE_BIST       = 0x58, /**< BIST activate FIS - bidirectional */
62     FIS_TYPE_PIO_SETUP  = 0x5F, /**< PIO setup FIS - device to host */
63     FIS_TYPE_DEV_BITS   = 0xA1, /**< Set device bits FIS - device to host */
64 } fis_type_t;
65 
66 /**
67  * A host to device register FIS is used by the host to send
68  * command or control to a device. As illustrated in the
69  * following data structure, it contains the IDE registers such
70  * as command, LBA, device, feature, count and control. An ATA
71  * command is constructed in this structure and issued to the
72  * device. All reserved fields in an FIS should be cleared to
73  * zero.
74  */
75 typedef struct
76 {
77 #if __BYTE_ORDER == __LITTLE_ENDIAN
78         // DWORD 0
79         uint8_t fis_type;   /**< FIS_TYPE_REG_H2D */
80         uint8_t pmport:4;   /**< Port multiplier */
81         uint8_t rsv0:3;     /**< Reserved */
82         uint8_t c:1;        /**< 1: Command, 0: Control */
83         uint8_t command;    /**< Command register */
84         uint8_t featurel;   /**< Feature register, 7:0 */
85         // DWORD 1
86         uint8_t lba0;       /**< LBA low register, 7:0 */
87         uint8_t lba1;       /**< LBA mid register, 15:8 */
88         uint8_t lba2;       /**< LBA high register, 23:16 */
89         uint8_t device;     /**< Device register */
90         // DWORD 2
91         uint8_t lba3;       /**< LBA register, 31:24 */
92         uint8_t lba4;       /**< LBA register, 39:32 */
93         uint8_t lba5;       /**< LBA register, 47:40 */
94         uint8_t featureh;   /**< Feature register, 15:8 */
95         // DWORD 3
96         uint16_t count;     /**< Count register */
97         uint8_t icc;        /**< Isochronous command completion */
98         uint8_t control;    /**< Control register */
99         // DWORD 4
100         uint8_t rsv1[4];    /**< Reserved */
101 #else
102         // DWORD 0
103         uint8_t fis_type;   /**< FIS_TYPE_REG_H2D */
104         uint8_t c:1;        /**< 1: Command, 0: Control */
105         uint8_t rsv0:3;     /**< Reserved */
106         uint8_t pmport:4;   /**< Port multiplier */
107         uint8_t command;    /**< Command register */
108         uint8_t featurel;   /**< Feature register, 7:0 */
109         // DWORD 1
110         uint8_t lba0;       /**< LBA low register, 7:0 */
111         uint8_t lba1;       /**< LBA mid register, 15:8 */
112         uint8_t lba2;       /**< LBA high register, 23:16 */
113         uint8_t device;     /**< Device register */
114         // DWORD 2
115         uint8_t lba3;       /**< LBA register, 31:24 */
116         uint8_t lba4;       /**< LBA register, 39:32 */
117         uint8_t lba5;       /**< LBA register, 47:40 */
118         uint8_t featureh;   /**< Feature register, 15:8 */
119         // DWORD 3
120         uint16_t count;     /**< Count register */
121         uint8_t icc;        /**< Isochronous command completion */
122         uint8_t control;    /**< Control register */
123         // DWORD 4
124         uint8_t rsv1[4];    /**< Reserved */
125 #endif
126 } fis_reg_h2d_t;
127 
128 /**
129  * A device to host register FIS is used by the device to notify
130  * the host that some ATA register has changed. It contains the
131  * updated task files such as status, error and other registers.
132  */
133 typedef struct
134 {
135 #if __BYTE_ORDER == __LITTLE_ENDIAN
136         // DWORD 0
137         uint8_t fis_type;    /**< FIS_TYPE_REG_D2H */
138         uint8_t pmport:4;    /**< Port multiplier */
139         uint8_t rsv0:2;      /**< Reserved */
140         uint8_t i:1;         /**< Interrupt bit */
141         uint8_t rsv1:1;      /**< Reserved */
142         uint8_t status;      /**< Status register */
143         uint8_t error;       /**< Error register */
144         // DWORD 1
145         uint8_t lba0;        /**< LBA low register, 7:0 */
146         uint8_t lba1;        /**< LBA mid register, 15:8 */
147         uint8_t lba2;        /**< LBA high register, 23:16 */
148         uint8_t device;      /**< Device register */
149         // DWORD 2
150         uint8_t lba3;        /**< LBA register, 31:24 */
151         uint8_t lba4;        /**< LBA register, 39:32 */
152         uint8_t lba5;        /**< LBA register, 47:40 */
153         uint8_t rsv2;        /**< Reserved */
154         // DWORD 3
155         uint8_t countl;      /**< Count register, 7:0 */
156         uint8_t counth;      /**< Count register, 15:8 */
157         uint8_t rsv3[2];     /**< Reserved */
158         // DWORD 4
159         uint8_t rsv4[4];     /**< Reserved */
160 #else
161         // DWORD 0
162         uint8_t fis_type;    /**< FIS_TYPE_REG_D2H */
163         uint8_t rsv1:1;      /**< Reserved */
164         uint8_t i:1;         /**< Interrupt bit */
165         uint8_t rsv0:2;      /**< Reserved */
166         uint8_t pmport:4;    /**< Port multiplier */
167         uint8_t status;      /**< Status register */
168         uint8_t error;       /**< Error register */
169         // DWORD 1
170         uint8_t lba0;        /**< LBA low register, 7:0 */
171         uint8_t lba1;        /**< LBA mid register, 15:8 */
172         uint8_t lba2;        /**< LBA high register, 23:16 */
173         uint8_t device;      /**< Device register */
174         // DWORD 2
175         uint8_t lba3;        /**< LBA register, 31:24 */
176         uint8_t lba4;        /**< LBA register, 39:32 */
177         uint8_t lba5;        /**< LBA register, 47:40 */
178         uint8_t rsv2;        /**< Reserved */
179         // DWORD 3
180         uint8_t countl;      /**< Count register, 7:0 */
181         uint8_t counth;      /**< Count register, 15:8 */
182         uint8_t rsv3[2];     /**< Reserved */
183         // DWORD 4
184         uint8_t rsv4[4];     /**< Reserved */
185 #endif
186 } fis_reg_d2h_t;
187 
188 /**
189  * This FIS is used by the host or device to send data payload.
190  * The data size can be varied.
191  */
192 typedef struct
193 {
194 #if __BYTE_ORDER == __LITTLE_ENDIAN
195         // DWORD 0
196         uint8_t fis_type;   /**< FIS_TYPE_DATA */
197         uint8_t pmport:4;   /**< Port multiplier */
198         uint8_t rsv0:4;     /**< Reserved */
199         uint8_t rsv1[2];    /**< Reserved */
200         // DWORD 1 ~ N
201         uint32_t data[1];   /**< Payload */
202 #else
203         // DWORD 0
204         uint8_t fis_type;   /**< FIS_TYPE_DATA */
205         uint8_t rsv0:4;     /**< Reserved */
206         uint8_t pmport:4;   /**< Port multiplier */
207         uint8_t rsv1[2];    /**< Reserved */
208         // DWORD 1 ~ N
209         uint32_t data[1];   /**< Payload */
210 #endif
211 } fis_data_t;
212 
213 /**
214  * This FIS is used by the device to tell the host that it's
215  * about to send or ready to receive a PIO data payload.
216  */
217 typedef struct
218 {
219 #if __BYTE_ORDER == __LITTLE_ENDIAN
220         // DWORD 0
221         uint8_t fis_type;   /**< FIS_TYPE_PIO_SETUP */
222         uint8_t pmport:4;   /**< Port multiplier */
223         uint8_t rsv0:1;     /**< Reserved */
224         uint8_t d:1;        /**< Data transfer direction, 1 - device to host */
225         uint8_t i:1;        /**< Interrupt bit */
226         uint8_t rsv1:1;
227         uint8_t status;     /**< Status register */
228         uint8_t error;      /**< Error register */
229         // DWORD 1
230         uint8_t lba0;       /**< LBA low register, 7:0 */
231         uint8_t lba1;       /**< LBA mid register, 15:8 */
232         uint8_t lba2;       /**< LBA high register, 23:16 */
233         uint8_t device;     /**< Device register */
234         // DWORD 2
235         uint8_t lba3;       /**< LBA register, 31:24 */
236         uint8_t lba4;       /**< LBA register, 39:32 */
237         uint8_t lba5;       /**< LBA register, 47:40 */
238         uint8_t rsv2;       /**< Reserved */
239         // DWORD 3
240         uint8_t countl;     /**< Count register, 7:0 */
241         uint8_t counth;     /**< Count register, 15:8 */
242         uint8_t rsv3;       /**< Reserved */
243         uint8_t e_status;   /**< New value of status register */
244         // DWORD 4
245         uint16_t tc;        /**< Transfer count */
246         uint8_t rsv4[2];    /**< Reserved */
247 #else
248         // DWORD 0
249         uint8_t fis_type;   /**< FIS_TYPE_PIO_SETUP */
250         uint8_t rsv1:1;
251         uint8_t i:1;        /**< Interrupt bit */
252         uint8_t d:1;        /**< Data transfer direction, 1 - device to host */
253         uint8_t rsv0:1;     /**< Reserved */
254         uint8_t pmport:4;   /**< Port multiplier */
255         uint8_t status;     /**< Status register */
256         uint8_t error;      /**< Error register */
257         // DWORD 1
258         uint8_t lba0;       /**< LBA low register, 7:0 */
259         uint8_t lba1;       /**< LBA mid register, 15:8 */
260         uint8_t lba2;       /**< LBA high register, 23:16 */
261         uint8_t device;     /**< Device register */
262         // DWORD 2
263         uint8_t lba3;       /**< LBA register, 31:24 */
264         uint8_t lba4;       /**< LBA register, 39:32 */
265         uint8_t lba5;       /**< LBA register, 47:40 */
266         uint8_t rsv2;       /**< Reserved */
267         // DWORD 3
268         uint8_t countl;     /**< Count register, 7:0 */
269         uint8_t counth;     /**< Count register, 15:8 */
270         uint8_t rsv3;       /**< Reserved */
271         uint8_t e_status;   /**< New value of status register */
272         // DWORD 4
273         uint16_t tc;        /**< Transfer count */
274         uint8_t rsv4[2];    /**< Reserved */
275 #endif
276 } fis_pio_setup_t;
277 
278 /**
279  * DMA Setup ? Device to Host
280  */
281 typedef struct __attribute__ ((__packed__))
282 {
283 #if __BYTE_ORDER == __LITTLE_ENDIAN
284         // DWORD 0
285         uint8_t fis_type;   /**< FIS_TYPE_DMA_SETUP */
286         uint8_t pmport:4;   /**< Port multiplier */
287         uint8_t rsv0:1;     /**< Reserved */
288         uint8_t d:1;        /**< Data transfer direction, 1 - device to host */
289         uint8_t i:1;        /**< Interrupt bit */
290         uint8_t a:1;        /**< Auto-activate. Specifies if DMA Activate FIS is needed */
291         uint8_t rsved[2];   /**< Reserved */
292         //DWORD 1&2
293         uint64_t DMAbufferID; /**< DMA Buffer Identifier. Used to Identify DMA buffer in host memory. SATA Spec says host specific and not in Spec. Trying AHCI spec might work. */
294         //DWORD 3
295         uint32_t rsvd;      /**< More reserved */
296         //DWORD 4
297         uint32_t DMAbufOffset; /**< Byte offset into buffer. First 2 bits must be 0 */
298         //DWORD 5
299         uint32_t TransferCount; /**< Number of bytes to transfer. Bit 0 must be 0 */
300         //DWORD 6
301         uint32_t resvd;     /**< Reserved */
302 #else
303         // DWORD 0
304         uint8_t fis_type;   /**< FIS_TYPE_DMA_SETUP */
305         uint8_t a:1;        /**< Auto-activate. Specifies if DMA Activate FIS is needed */
306         uint8_t i:1;        /**< Interrupt bit */
307         uint8_t d:1;        /**< Data transfer direction, 1 - device to host */
308         uint8_t rsv0:1;     /**< Reserved */
309         uint8_t pmport:4;   /**< Port multiplier */
310         uint8_t rsved[2];   /**< Reserved */
311         //DWORD 1&2
312         uint64_t DMAbufferID; /**< DMA Buffer Identifier. Used to Identify DMA buffer in host memory. SATA Spec says host specific and not in Spec. Trying AHCI spec might work. */
313         //DWORD 3
314         uint32_t rsvd;      /**< More reserved */
315         //DWORD 4
316         uint32_t DMAbufOffset; /**< Byte offset into buffer. First 2 bits must be 0 */
317         //DWORD 5
318         uint32_t TransferCount; /**< Number of bytes to transfer. Bit 0 must be 0 */
319         //DWORD 6
320         uint32_t resvd;     /**< Reserved */
321 #endif
322 } fis_dma_setup_t;
323 
324 typedef struct __attribute__ ((__packed__))
325 {
326     uint8_t fis_type;   /**< FIS_TYPE_BIST */
327     uint8_t pmport:4;   /**< Port multiplier */
328     uint8_t rsv0:4;     /**< Reserved */
329     uint8_t v:1;        /**< Vendor Specific */
330     uint8_t r:1;        /**< Reserved */
331     uint8_t p:1;        /**< Primitive bit */
332     uint8_t f:1;        /**< Far end analog loopback */
333     uint8_t l:1;        /**< Far end retimed loopback */
334     uint8_t s:1;        /**< Scrambling bypass */
335     uint8_t a:1;        /**< Align bypass */
336     uint8_t t:1;        /**< Far end transmit only */
337     uint8_t rsv1;       /**< Reserved */
338     uint32_t data1;     /**< Only valid when "t" is set */
339     uint32_t data2;     /**< Only valid when "t" is set */
340 } fis_bist_t;
341 
342 /**
343  * Received FIS Structure - AHCI rev 1.3 page 35
344  */
345 typedef struct
346 {
347         // 0x00
348         fis_dma_setup_t dsfis;      /**< DMA Setup FIS */
349         uint8_t         pad0[4];    /* Filler 0x1c - 0x1f */
350         // 0x20
351         fis_pio_setup_t psfis;      /**< PIO Setup FIS */
352         uint8_t         pad1[12];   /* Filler 0x34 - 0x3f */
353         // 0x40
354         fis_reg_d2h_t   rfis;       /**< Device to Host (D2H) Register FIS */
355         uint8_t         pad2[4];    /* Filler 0x54 - 0x57 */
356         // 0x58
357         uint8_t         sdbfis[8];  /**< Set Device Bit FIS */
358         // 0x60
359         uint8_t         ufis[64];   /**< Unknown FIS (up to 64 bytes) */
360         // 0xA0
361         uint8_t         rsv[0x100-0xA0]; /* Reserved */
362 } hba_fis_t;
363 
364 /**
365  * Command header - AHCI rev 1.3 page 36
366  */
367 typedef struct
368 {
369 #if __BYTE_ORDER == __LITTLE_ENDIAN
370         // DW0
371         uint8_t cfl:5;      /**< Command FIS length in DWORDS, 2 ~ 16 */
372         uint8_t a:1;        /**< ATAPI */
373         uint8_t w:1;        /**< Write, 1: H2D, 0: D2H */
374         uint8_t p:1;        /**< Prefetchable */
375         uint8_t r:1;        /**< Reset */
376         uint8_t b:1;        /**< BIST */
377         uint8_t c:1;        /**< Clear busy upon R_OK */
378         uint8_t rsv0:1;     /**< Reserved */
379         uint8_t pmp:4;      /**< Port multiplier port */
380         uint16_t prdtl;     /**< Physical region descriptor table length in entries */
381         // DW1
382         uint32_t prdbc;     /**< Physical region descriptor byte count transferred */
383         // DW2, 3
384         uint64_t ctba;      /**< Command table descriptor base address. Must be 128 byte aligned */
385         // DW4 - 7
386         uint32_t rsv1[4];   /**< Reserved */
387 #else
388         // DW0
389         uint8_t p:1;        /**< Prefetchable */
390         uint8_t w:1;        /**< Write, 1: H2D, 0: D2H */
391         uint8_t a:1;        /**< ATAPI */
392         uint8_t cfl:5;      /**< Command FIS length in DWORDS, 2 ~ 16 */
393         uint8_t pmp:4;      /**< Port multiplier port */
394         uint8_t c:1;        /**< Clear busy upon R_OK */
395         uint8_t b:1;        /**< BIST */
396         uint8_t r:1;        /**< Reset */
397         uint8_t rsv0:1;     /**< Reserved */
398         uint16_t prdtl;     /**< Physical region descriptor table length in entries */
399         // DW1
400         uint32_t prdbc;     /**< Physical region descriptor byte count transferred */
401         // DW2, 3
402         uint64_t ctba;      /**< Command table descriptor base address */
403         // DW4 - 7
404         uint32_t rsv1[4];   /**< Reserved */
405 #endif
406 } hba_cmd_header_t;
407 
408 /**
409  * Physical Region Descriptor Table Entry - AHCI rev 1.3 page 39
410  */
411 typedef struct
412 {
413 #if __BYTE_ORDER == __LITTLE_ENDIAN
414 	uint64_t dba;       /**< Data base address. Must be 2 byte aligned */
415 	uint32_t rsv0;      /**< Reserved */
416 	uint32_t dbc:22;    /**< Byte count - 1, 4M max. Must be even number of bytes to transfer */
417 	uint32_t rsv1:9;    /**< Reserved */
418 	uint32_t i:1;       /**< Interrupt on completion */
419 #else
420         uint64_t dba;       /**< Data base address */
421         uint32_t rsv0;      /**< Reserved */
422         uint32_t dbc;
423 #endif
424 } hba_prdt_entry_t;
425 
426 /**
427  * Command Table - AHCI rev 1.3 page 39
428  */
429 typedef struct
430 {
431 	uint8_t cfis[64];   /**< Command FIS */
432 	uint8_t acmd[16];   /**< ATAPI command, 12 or 16 bytes */
433         uint8_t rsv[48];    /**< Reserved */
434 	hba_prdt_entry_t prdt_entry[1]; /**< Physical region descriptor table entries, 0 ~ 65535 */
435 } hba_cmd_tbl_t;
436 
437 /**
438  * Return the number of SATA controllers on the chip
439  *
440  * @param node   Node to query
441  *
442  * @return Number of controllers, could be zero.
443  */
bdk_sata_get_controllers(bdk_node_t node)444 int bdk_sata_get_controllers(bdk_node_t node)
445 {
446     if (CAVIUM_IS_MODEL(CAVIUM_CN88XX))
447         return 16; /* 16 controllers on QLMs 2,3, 6-7 */
448     else if (CAVIUM_IS_MODEL(CAVIUM_CN83XX))
449         return 6; /* 6 controllers on DLMs 4-6 */
450     else if (CAVIUM_IS_MODEL(CAVIUM_CN81XX))
451         return 2; /* 2 controllers on DLM 2 */
452     else if (CAVIUM_IS_MODEL(CAVIUM_CN93XX))
453         return 4; /* 4 controllers on DLM 4-5 */
454     else
455         return 0;
456 }
457 
__bdk_sata_is_initialized(bdk_node_t node,int controller)458 static int __bdk_sata_is_initialized(bdk_node_t node, int controller)
459 {
460     /* Make sure port is clocked before proceeding */
461     BDK_CSR_INIT(uctl_ctl, node, BDK_SATAX_UCTL_CTL(controller));
462     if (!uctl_ctl.s.a_clk_en || uctl_ctl.s.a_clkdiv_rst)
463         return 0;
464 
465     /* See if the controller is started */
466     BDK_CSR_INIT(cmd, node, BDK_SATAX_UAHC_P0_CMD(controller));
467     return cmd.s.st;
468 }
469 
470 /**
471  * Initialize a SATA controller and begin device detection
472  *
473  * @param node       Node to initialize
474  * @param controller Which controller to initialize
475  *
476  * @return Zero on success, negative on failure
477  */
bdk_sata_initialize(bdk_node_t node,int controller)478 int bdk_sata_initialize(bdk_node_t node, int controller)
479 {
480     _Static_assert(sizeof(fis_reg_h2d_t) == 5 * 4, "Size of fis_reg_h2d_t wrong");
481     _Static_assert(sizeof(fis_reg_d2h_t)== 5 * 4, "Size of fis_reg_d2h_t wrong");
482     _Static_assert(sizeof(fis_data_t) == 2 * 4, "Size of fis_data_t wrong");
483     _Static_assert(sizeof(fis_pio_setup_t) == 5 * 4, "Size of fis_pio_setup_t wrong");
484     _Static_assert(sizeof(fis_dma_setup_t) == 7 * 4, "Size of fis_dma_setup_t wrong");
485     _Static_assert(sizeof(fis_bist_t) == 3 * 4, "Size of fis_bist_t wrong");
486     _Static_assert(sizeof(hba_fis_t) == 256, "Size of hba_fis_t wrong");
487     _Static_assert(sizeof(hba_cmd_header_t) == 8 * 4, "Size of hba_cmd_header_t wrong");
488     _Static_assert(sizeof(hba_prdt_entry_t) == 4 * 4, "Size of hba_prdt_entry_t wrong");
489     _Static_assert(sizeof(hba_cmd_tbl_t)== 128 + sizeof(hba_prdt_entry_t), "Size of hba_cmd_tbl_t wrong");
490 
491     /* Make sure port is clocked before proceeding */
492     BDK_CSR_INIT(uctl_ctl, node, BDK_SATAX_UCTL_CTL(controller));
493     if (!uctl_ctl.s.a_clk_en || uctl_ctl.s.a_clkdiv_rst)
494     {
495         bdk_error("N%d.SATA%d: Not in SATA mode\n", node, controller);
496         return -1;
497     }
498 
499     /* The following SATA setup is from the AHCI 1.3 spec, section
500        10.1.1, Firmware Specific Initialization. */
501     /* Early firmware setup was done in __bdk_qlm_set_sata(), we're not
502        starting the staggered spin-up process */
503 
504     /* 1. Indicate that system software is AHCI aware by setting GHC.AE to '1'. */
505     BDK_CSR_MODIFY(c, node, BDK_SATAX_UAHC_GBL_GHC(controller),
506         c.s.ae = 1);    /* AHCI enable */
507 
508     /* 2. Ensure that PxCMD.ST = '0', PxCMD.CR = '0', PxCMD.FRE = '0',
509        PxCMD.FR = '0', and PxSCTL.DET = '0'. */
510     BDK_CSR_INIT(p0_cmd, node, BDK_SATAX_UAHC_P0_CMD(controller));
511     if (p0_cmd.s.st)
512         bdk_error("N%d.SATA%d: PxCMD[ST] is illegally set during init\n", node, controller);
513     if (p0_cmd.s.cr)
514         bdk_error("N%d.SATA%d: PxCMD[CR] is illegally set during init\n", node, controller);
515     if (p0_cmd.s.fre)
516         bdk_error("N%d.SATA%d: PxCMD[FRE] is illegally set during init\n", node, controller);
517     if (p0_cmd.s.fr)
518         bdk_error("N%d.SATA%d: PxCMD[FR] is illegally set during init\n", node, controller);
519     BDK_CSR_INIT(p0_sctl, node, BDK_SATAX_UAHC_P0_SCTL(controller));
520     if (p0_sctl.s.det)
521         bdk_error("N%d.SATA%d: PxSCTL[DET] is illegally set during init\n", node, controller);
522 
523     /* 3. Allocate memory for the command list and the FIS receive area. Set
524        PxCLB and PxCLBU to the physical address of the allocated command list.
525        Set PxFB and PxFBU to the physical address of the allocated FIS receive
526        area. Then set PxCMD.FRE to '1'. */
527     /* Allocate area for commands */
528     uint64_t clb_pa = BDK_CSR_READ(node, BDK_SATAX_UAHC_P0_CLB(controller));
529     if (clb_pa == 0)
530     {
531         void *clb = memalign(1024, sizeof(hba_cmd_header_t) * 32);
532         if (clb == NULL)
533         {
534             bdk_error("N%d.SATA%d: Failed to allocate command list\n", node, controller);
535             return -1;
536         }
537         memset(clb, 0, sizeof(hba_cmd_header_t) * 32);
538         BDK_CSR_WRITE(node, BDK_SATAX_UAHC_P0_CLB(controller),
539             bdk_ptr_to_phys(clb));
540     }
541     /* Allocate area for FIS DMAs */
542     uint64_t fb_pa = BDK_CSR_READ(node, BDK_SATAX_UAHC_P0_FB(controller));
543     if (fb_pa == 0)
544     {
545         hba_fis_t *fb = memalign(256, sizeof(hba_fis_t));
546         if (fb == NULL)
547         {
548             bdk_error("N%d.SATA%d: Failed to allocate FIS\n", node, controller);
549             return -1;
550         }
551         memset(fb, 0, sizeof(hba_fis_t));
552         BDK_CSR_WRITE(node, BDK_SATAX_UAHC_P0_FB(controller),
553             bdk_ptr_to_phys(fb));
554     }
555 
556     BDK_CSR_MODIFY(c, node, BDK_SATAX_UAHC_P0_CMD(controller),
557         c.s.fre = 1);   /* FIS-receive enable */
558 
559     /* 4. Initiate a spin up of the SATA drive attached to the port; i.e. set
560        PxCMD.SUD to '1'.*/
561     BDK_CSR_MODIFY(c, node, BDK_SATAX_UAHC_P0_CMD(controller),
562         c.s.pod = 1;    /* Power on the device, only has affect if SATAX_UAHC_P0_CMD[CPD]=1 */
563         c.s.sud = 1);   /* Spin-up device */
564 
565     /* 5. Wait for a positive indication that a device is attached to the port
566        (the maximum amount of time to wait for presence indication is specified
567        in the Serial ATA Revision 2.6 specification). This is done by polling
568        PxSSTS.DET. If PxSSTS.DET returns a value of 1h or 3h when read, then
569        system software shall continue to the next step, otherwise if the
570        polling process times out system software moves to the next implemented
571        port and returns to step 1. */
572     /* Waiting for device detection, up to 500ms. PxCMD[DET] must be 1 or 3 */
573     uint64_t timeout = bdk_clock_get_count(BDK_CLOCK_TIME) + bdk_clock_get_rate(bdk_numa_local(), BDK_CLOCK_TIME) / 2;
574     BDK_CSR_INIT(p0_ssts, node, BDK_SATAX_UAHC_P0_SSTS(controller));
575     while ((p0_ssts.s.det != 1) && (p0_ssts.s.det != 3) &&
576            (bdk_clock_get_count(BDK_CLOCK_TIME) <= timeout))
577     {
578         p0_ssts.u = BDK_CSR_READ(node, BDK_SATAX_UAHC_P0_SSTS(controller));
579         bdk_thread_yield();
580     }
581     if ((p0_ssts.s.det != 1) && (p0_ssts.s.det != 3))
582     {
583         bdk_error("N%d.SATA%d: PxSCTL[DET]=%d failed to detect a device\n", node, controller, p0_ssts.s.det);
584         goto fail;
585     }
586 
587     /* 6. Clear the PxSERR register, by writing '1s' to each implemented bit
588        location. */
589     BDK_CSR_WRITE(node, BDK_SATAX_UAHC_P0_SERR(controller), -1);
590 
591     /* 7. Wait for indication that SATA drive is ready. This is determined via
592        an examination of PxTFD.STS. If PxTFD.STS.BSY, PxTFD.STS.DRQ, and
593        PxTFD.STS.ERR are all '0', prior to the maximum allowed time as
594        specified in the ATA/ATAPI-7 specification, the device is ready. */
595     /* Wait for the device to be ready. BSY(7), DRQ(3), and ERR(0) must be clear */
596     if (BDK_CSR_WAIT_FOR_FIELD(node, BDK_SATAX_UAHC_P0_TFD(controller), sts & 0x89, ==, 0, 5000000))
597     {
598         BDK_CSR_INIT(p0_tfd, node, BDK_SATAX_UAHC_P0_TFD(controller));
599         bdk_error("N%d.SATA%d: PxTFD[STS]=0x%x, Drive not ready\n", node, controller, p0_tfd.s.sts);
600         goto fail;
601     }
602 
603     /* Enable AHCI command queuing */
604     BDK_CSR_MODIFY(c, node, BDK_SATAX_UAHC_GBL_CCC_CTL(controller),
605         c.s.tv = 0;
606         c.s.en = 1);
607     BDK_CSR_MODIFY(c, node, BDK_SATAX_UAHC_GBL_CCC_PORTS(controller),
608         c.s.prt = 1);
609 
610     /* Enable the FIS and clear any pending errors */
611     BDK_CSR_MODIFY(c, node, BDK_SATAX_UAHC_P0_FBS(controller),
612         c.s.dec = 1;
613         c.s.en = 1);
614 
615     /* Disable all interrupts */
616     BDK_CSR_WRITE(node, BDK_SATAX_UAHC_P0_IE(controller), 0);
617 
618     /* Clear all status bits */
619     BDK_CSR_WRITE(node, BDK_SATAX_UAHC_P0_IS(controller), -1);
620 
621     /* Start the port controller */
622     BDK_CSR_MODIFY(c, node, BDK_SATAX_UAHC_P0_CMD(controller),
623         c.s.st = 1); /* Start the controller */
624     return 0;
625 
626 fail:
627     bdk_sata_shutdown(node, controller);
628     return -1;
629 }
630 
631 /**
632  * Shutdown a SATA controller
633  *
634  * @param node       Node to access
635  * @param controller Controller to shutdown
636  *
637  * @return Zero on success, negative on failure
638  */
bdk_sata_shutdown(bdk_node_t node,int controller)639 int bdk_sata_shutdown(bdk_node_t node, int controller)
640 {
641     /* Remember the current speed limit and power management */
642     BDK_CSR_INIT(p0_sctl, node, BDK_SATAX_UAHC_P0_SCTL(controller));
643     /* Perform a HBA reset */
644     BDK_CSR_MODIFY(c, node, BDK_SATAX_UAHC_GBL_GHC(controller),
645         c.s.hr = 1);
646     /* Wait for the reset to complete */
647     if (BDK_CSR_WAIT_FOR_FIELD(node, BDK_SATAX_UAHC_GBL_GHC(controller), hr, ==, 0, 100000))
648     {
649         bdk_error("N%d.SATA%d: Timeout waiting for HBA reset to complete\n", node, controller);
650         return -1;
651     }
652     /* Restore the speed limit and power management */
653     BDK_CSR_MODIFY(c, node, BDK_SATAX_UAHC_P0_SCTL(controller),
654         c.s.ipm = p0_sctl.s.ipm;
655         c.s.spd = p0_sctl.s.spd);
656     return 0;
657 }
658 
659 /**
660  * Return the number of SATA ports connected to this AHCI controller
661  *
662  * @param node       Node to query
663  * @param controller SATA controller
664  *
665  * @return Number of ports. Zero if the controller doesn't connect to a QLM.
666  */
bdk_sata_get_ports(bdk_node_t node,int controller)667 int bdk_sata_get_ports(bdk_node_t node, int controller)
668 {
669     BDK_CSR_INIT(ctl, node, BDK_SATAX_UAHC_GBL_CCC_CTL(controller));
670     return (ctl.s.en) ? 1 : 0;
671 }
672 
673 /**
674  * Convert an IDE string into a C string with a NULL terminator
675  *
676  * @param buffer   Buffer for new string. Must be one longer than length
677  * @param original IDE string of identify command
678  * @param length   Length of the string in bytes
679  */
get_ide_string(char * buffer,void * original,int length)680 static void get_ide_string(char *buffer, void *original, int length)
681 {
682     /* Copy the IDE string 2 bytes at a time, swapping as we go */
683     uint16_t *newp = (uint16_t *)buffer;
684     uint16_t *oldp = (uint16_t *)original;
685     for (int i = 0; i < length / 2; i++)
686         newp[i] = bdk_swap16(oldp[i]);
687 
688     /* Force a NULL terminator */
689     buffer[length] = 0;
690 
691     /* Remove all trailing spaces */
692     while (buffer[length-1] == ' ')
693     {
694         buffer[length - 1] = 0;
695         length--;
696     }
697 }
698 
issue_command(bdk_node_t node,int controller,int command,int is_write,uint64_t lba,void * buffer,int size)699 static int issue_command(bdk_node_t node, int controller, int command, int is_write, uint64_t lba, void *buffer, int size)
700 {
701     /* Pick a command slot to use */
702     int slot = 0;
703     hba_cmd_header_t *cmd_header = bdk_phys_to_ptr(BDK_CSR_READ(node, BDK_SATAX_UAHC_P0_CLB(controller)));
704     cmd_header += slot;
705 
706     /* Build a command table with the command to execute */
707     hba_cmd_tbl_t cmd_table BDK_CACHE_LINE_ALIGNED;
708     memset(&cmd_table, 0, sizeof(hba_cmd_tbl_t));
709     /* Where the data is */
710     cmd_table.prdt_entry[0].dba = bdk_cpu_to_le64(bdk_ptr_to_phys(buffer));
711     cmd_table.prdt_entry[0].dbc = bdk_cpu_to_le32(size - 1);
712 
713     /* The actual command */
714     fis_reg_h2d_t *cmd_fis = (fis_reg_h2d_t *)cmd_table.cfis;
715     cmd_fis->fis_type = FIS_TYPE_REG_H2D;
716     cmd_fis->command = command;
717     cmd_fis->device = 1 << 6; /* LBA mode */
718     cmd_fis->c = 1; /* Write command register */
719     cmd_fis->lba0 = (lba >> 0) & 0xff;
720     cmd_fis->lba1 = (lba >> 8) & 0xff;
721     cmd_fis->lba2 = (lba >> 16) & 0xff;
722     cmd_fis->lba3 = (lba >> 24) & 0xff;
723     cmd_fis->lba4 = (lba >> 32) & 0xff;
724     cmd_fis->lba5 = (lba >> 40) & 0xff;
725     cmd_fis->count = bdk_cpu_to_le16(size / 512);
726 
727     /* Setup the command header */
728     cmd_header->cfl = sizeof(fis_reg_h2d_t) / 4;
729     cmd_header->w = is_write;
730     cmd_header->prdtl = bdk_cpu_to_le16(1);
731     cmd_header->ctba = bdk_cpu_to_le64(bdk_ptr_to_phys(&cmd_table));
732 
733     BDK_WMB;
734 
735     /* Check that the slot is idle */
736     BDK_CSR_INIT(ci, node, BDK_SATAX_UAHC_P0_CI(controller));
737     if (ci.u & (1<<slot))
738     {
739         bdk_error("N%d.SATA%d: Command slot busy before submit\n", node, controller);
740         return -1;
741     }
742 
743     /* Clear all status bits */
744     BDK_CSR_WRITE(node, BDK_SATAX_UAHC_P0_IS(controller), -1);
745     BDK_CSR_READ(node, BDK_SATAX_UAHC_P0_IS(controller));
746 
747     /* Issue command */
748     BDK_CSR_WRITE(node, BDK_SATAX_UAHC_P0_CI(controller), 1 << slot);
749 
750     /* Wait for command accept */
751     const int TIMEOUT = 5000000; /* 5 seconds */
752     if (BDK_CSR_WAIT_FOR_FIELD(node,BDK_SATAX_UAHC_P0_CI(controller), ci & (1<<slot), ==, 0, TIMEOUT))
753     {
754         bdk_error("N%d.SATA%d: Command timeout\n", node, controller);
755         bdk_sata_shutdown(node, controller);
756         return -1;
757     }
758 
759     /* Wait for completion */
760     if (BDK_CSR_WAIT_FOR_FIELD(node,BDK_SATAX_UAHC_P0_IS(controller), dhrs | c.s.pss | c.s.dss, !=, 0, TIMEOUT))
761     {
762         bdk_error("N%d.SATA%d: Command Response timeout\n", node, controller);
763         bdk_sata_shutdown(node, controller);
764         return -1;
765     }
766 
767     /* Read status */
768     BDK_CSR_INIT(p_is, node, BDK_SATAX_UAHC_P0_IS(controller));
769     if (p_is.s.tfes)
770     {
771         bdk_error("N%d.SATA%d: Task-file error\n", node, controller);
772         bdk_sata_shutdown(node, controller);
773         return -1;
774     }
775     return 0;
776 }
777 
778 /**
779  * Identify the SATA device connected to a controller
780  *
781  * @param node       Node to query
782  * @param controller Controller to query
783  * @param port       Which SATA port on the controller, zero based
784  *
785  * @return Size of the disk in bytes
786  */
bdk_sata_identify(bdk_node_t node,int controller,int port)787 uint64_t bdk_sata_identify(bdk_node_t node, int controller, int port)
788 {
789     if (!__bdk_sata_is_initialized(node, controller))
790     {
791         if (bdk_sata_initialize(node, controller))
792             return 0;
793     }
794 
795     const int TIMEOUT = 1000000; /* 1 seconds */
796     if (BDK_CSR_WAIT_FOR_FIELD(node, BDK_SATAX_UAHC_P0_SSTS(controller), ipm, !=, 0, TIMEOUT))
797     {
798         bdk_error("N%d.SATA%d: Device not present or communication not established\n", node, controller);
799         return 0;
800     }
801 
802     /* Read the Serial ATA Status */
803     BDK_CSR_INIT(ssts, node, BDK_SATAX_UAHC_P0_SSTS(controller));
804 
805     /* Check the link power state */
806     switch (ssts.s.ipm)
807     {
808         case 0: /* Device not present or communication not established */
809             BDK_TRACE(SATA, "N%d.SATA%d: Device not present or communication not established\n", node, controller);
810             return 0;
811         case 1: /* Interface in active state */
812             BDK_TRACE(SATA, "N%d.SATA%d: Interface in active state\n", node, controller);
813             break;
814         case 2: /* Interface in Partial power management state */
815             BDK_TRACE(SATA, "N%d.SATA%d: Interface in Partial power management state\n", node, controller);
816             return 0;
817         case 6: /* Interface in Slumber power management state */
818             BDK_TRACE(SATA, "N%d.SATA%d: Interface in Slumber power management state\n", node, controller);
819             return 0;
820         case 8: /* Interface in DevSleep power management state */
821             BDK_TRACE(SATA, "N%d.SATA%d: Interface in DevSleep power management state\n", node, controller);
822             return 0;
823         default:
824             BDK_TRACE(SATA, "N%d.SATA%d: Interface in unknown power state %d\n", node, controller, ssts.s.ipm);
825             return 0;
826     }
827 
828     /* Check the link speed */
829     switch (ssts.s.spd)
830     {
831         case 0: /* Device not present or communication not established */
832             BDK_TRACE(SATA, "N%d.SATA%d: Device not present or communication not established\n", node, controller);
833             return 0;
834         case 1:
835         case 2:
836         case 3:
837             BDK_TRACE(SATA, "N%d.SATA%d: Speed Gen%d\n", node, controller, ssts.s.spd);
838             break;
839         default:
840             BDK_TRACE(SATA, "N%d.SATA%d: Interface in unknown speed %d\n", node, controller, ssts.s.spd);
841             return 0;
842     }
843 
844     /* Check the device detection */
845     switch (ssts.s.det)
846     {
847         case 0: /* No device detected and Phy communication not established */
848             BDK_TRACE(SATA, "N%d.SATA%d: No device detected and Phy communication not established\n", node, controller);
849             return 0;
850         case 1: /* Device presence detected but Phy communication not established */
851             BDK_TRACE(SATA, "N%d.SATA%d: Device presence detected but Phy communication not established\n", node, controller);
852             return 0;
853         case 3: /* Device presence detected and Phy communication established */
854             BDK_TRACE(SATA, "N%d.SATA%d: Device presence detected and Phy communication established\n", node, controller);
855             break;
856         case 4: /* Phy in offline mode as a result of the interface being disabled or running in a BIST loopback mode */
857             BDK_TRACE(SATA, "N%d.SATA%d: Phy in offline mode\n", node, controller);
858             return 0;
859         default:
860             BDK_TRACE(SATA, "N%d.SATA%d: Device presence in unknown state %d\n", node, controller, ssts.s.det);
861             return 0;
862     }
863 
864     /* Read the port signature to identify the device type */
865     BDK_CSR_INIT(sig, node, BDK_SATAX_UAHC_P0_SIG(controller));
866     switch (sig.s.sig)
867     {
868         case 0x00000101: /* SATA_SIG_ATA 0x00000101, SATA drive */
869             BDK_TRACE(SATA, "N%d.SATA%d: SATA drive\n", node, controller);
870             break;
871         case 0xEB140101: /* SATA_SIG_ATAPI 0xEB140101, SATAPI drive */
872             BDK_TRACE(SATA, "N%d.SATA%d: ATAPI drive, not supported by the BDK\n", node, controller);
873             return 0;
874         case 0xC33C0101: /* SATA_SIG_SEMB 0xC33C0101, Enclosure management bridge */
875             BDK_TRACE(SATA, "N%d.SATA%d: Enclosure management bridge, not supported by the BDK\n", node, controller);
876             return 0;
877         case 0x96690101: /* SATA_SIG_PM 0x96690101, Port multiplier */
878             BDK_TRACE(SATA, "N%d.SATA%d: Port multiplier, not supported by the BDK\n", node, controller);
879             return 0;
880         default: /* Just assume it is a drive */
881             BDK_TRACE(SATA, "N%d.SATA%d: Unknown signature 0x%08x, assuming a SATA drive\n", node, controller, sig.u);
882             break;
883     }
884 
885     /* Send identify to the device */
886     const int ATA_CMD_IDENTIFY = 0xec;
887     char buffer[512];
888     if (issue_command(node, controller, ATA_CMD_IDENTIFY, 0, 0, buffer, sizeof(buffer)))
889         return 0;
890 
891     /* Extract the data out of the IDENTIFY response */
892     uint16_t *ptr = (uint16_t *)buffer;
893     uint64_t sectors = bdk_le16_to_cpu(ptr[57]);
894     sectors += (uint32_t)bdk_le16_to_cpu(ptr[58]) << 16;
895     char serial[20  + 1];
896     get_ide_string(serial, ptr + 10, 20);
897     char firmware[8 + 1];
898     get_ide_string(firmware, ptr + 23, 8);
899     char model[40 + 1];
900     get_ide_string(model, ptr + 27, 40);
901 
902     printf("N%d.SATA%d: Model=\"%s\", Firmware=\"%s\", Serial=\"%s\", Sectors=%lu, Link=Gen%d\n",
903         node, controller, model, firmware, serial, sectors, ssts.s.spd);
904 
905     /* Return size in bytes */
906     return sectors * 512;
907 }
908 
909 /**
910  * Read data from a SATA device
911  *
912  * @param node       Node the controller is on
913  * @param controller Which controller
914  * @param port       Which port on the controller, zero based
915  * @param lba        48 bit Block address to read
916  * @param sectors    Number of 512 bytes sectors to read
917  * @param buffer     Buffer to receive the data. Must be at least 512 * sectors in size
918  *
919  * @return Zero on success, negative on failure
920  */
bdk_sata_read(bdk_node_t node,int controller,int port,uint64_t lba,int sectors,void * buffer)921 int bdk_sata_read(bdk_node_t node, int controller, int port, uint64_t lba, int sectors, void *buffer)
922 {
923     if (!__bdk_sata_is_initialized(node, controller))
924     {
925         if (bdk_sata_initialize(node, controller))
926             return -1;
927     }
928 
929     const int ATA_READ_DMA = 0xc8;
930     if (issue_command(node, controller, ATA_READ_DMA, 0, lba, buffer, sectors * 512))
931         return -1;
932     return 0;
933 }
934 
935 /**
936  * Write data to a SATA device
937  *
938  * @param node       Node the controller is on
939  * @param controller Which controller
940  * @param port       Which port on the controller, zero based
941  * @param lba        48 bit Block address to write
942  * @param sectors    Number of 512 bytes sectors to write
943  * @param buffer     Data buffer to write. Must be at least 512 * sectors in size
944  *
945  * @return Zero on success, negative on failure
946  */
bdk_sata_write(bdk_node_t node,int controller,int port,uint64_t lba,int sectors,const void * buffer)947 int bdk_sata_write(bdk_node_t node, int controller, int port, uint64_t lba, int sectors, const void *buffer)
948 {
949     if (!__bdk_sata_is_initialized(node, controller))
950     {
951         if (bdk_sata_initialize(node, controller))
952             return -1;
953     }
954 
955     const int ATA_WRITE_DMA = 0xca;
956     if (issue_command(node, controller, ATA_WRITE_DMA, 1, lba, (void*)buffer, sectors * 512))
957         return -1;
958     return 0;
959 }
960 
961 /**
962  * Enter one of the SATA pattern generation / loop testing modes
963  *
964  * @param node       Node to access
965  * @param controller SATA controller to access
966  * @param port       Which port on the controller
967  * @param mode       Test mode to enter
968  *
969  * @return Zero on success, negative on failure
970  */
bdk_sata_bist_fis(bdk_node_t node,int controller,int port,bdk_sata_bist_fis_t mode)971 int bdk_sata_bist_fis(bdk_node_t node, int controller, int port, bdk_sata_bist_fis_t mode)
972 {
973     if (!__bdk_sata_is_initialized(node, controller))
974     {
975         if (bdk_sata_initialize(node, controller))
976             return -1;
977     }
978 
979     /* Select the port we're doing BIST loopback on */
980     BDK_CSR_MODIFY(c, node, BDK_SATAX_UAHC_GBL_TESTR(controller),
981         c.s.psel = port);
982 
983     /* Select the pattern */
984     int pattern;
985     switch (mode)
986     {
987         case BDK_SATA_BIST_SW_TX_ONLY_SSOP:
988         case BDK_SATA_BIST_SW_TX_ONLY_HTDP:
989         case BDK_SATA_BIST_SW_TX_ONLY_LTDP:
990         case BDK_SATA_BIST_SW_TX_ONLY_LFSCP:
991         case BDK_SATA_BIST_SW_TX_ONLY_COMP:
992         case BDK_SATA_BIST_SW_TX_ONLY_LBP:
993         case BDK_SATA_BIST_SW_TX_ONLY_MFTP:
994         case BDK_SATA_BIST_SW_TX_ONLY_HFTP:
995         case BDK_SATA_BIST_SW_TX_ONLY_LFTP:
996             pattern = mode - BDK_SATA_BIST_SW_TX_ONLY_SSOP;
997             break;
998         default:
999             pattern = 1; /* HTDP */
1000             break;
1001     }
1002     BDK_CSR_MODIFY(c, node, BDK_SATAX_UAHC_GBL_BISTCR(controller),
1003         c.s.pattern = pattern);
1004 
1005     /*
1006         Note from the Synopsys SATA bist training video on pattern generation
1007         without using BIST FIS.
1008 
1009         1) Far-end Re-timed Loopback Responder Mode (Software Initiated)
1010 
1011         In this mode the host controller receives the pattern and transmits
1012         it back out. The setup of the mode is done by software, so no BIST FIS
1013         frames are needed. After software sets it up, any pattern generator
1014         should be able to send a pattern and get it back.
1015 
1016         Setup:
1017         1) Write SATAX_UAHC_GBL_BISTCR.ferlib = 1
1018         2) Connect pattern generator
1019         3) Pattern generator must send ALIGNs for PHY sync up
1020         4) Pattern should be looped back out
1021 
1022         2) Far-end Transmit Only Responder Mode (Software Initiated)
1023 
1024         In this mode the host controller sends a transmit pattern and ignores
1025         all input. This is useful for checking the TX eye diagram without an
1026         external pattern generator.
1027 
1028         Setup:
1029         1) Write SATAX_UAHC_GBL_BISTCR.pattern to select the pattern.
1030         2) Write SATAX_UAHC_GBL_BISTCR.txo = 1.
1031         3) Host starts sending the requested BIST pattern.
1032 
1033         BIST FIS Modes:
1034         1) Far-end Analog Loopback (F=1)
1035             Far end loops the received pattern back to transmit without retiming
1036             the symbols. This is optional in the SATA 3.0 spec.
1037         2) Far-end Retimed Loopback (L=1)
1038             Far end loops the received pattern back to transmit after retiming
1039             the symbols. This is mandatory in the SATA 3.0 spec.
1040         3) Far-end Transmit Only (T=1, with other bits)
1041             Far end transits a pattern and ignores its input. This is optional
1042             in the SATA 3.0 spec.
1043     */
1044     if (mode == BDK_SATA_BIST_SW_RETIMED)
1045     {
1046         /* No FIS, just enter local retimed loopback */
1047         BDK_CSR_MODIFY(c, node, BDK_SATAX_UAHC_GBL_BISTCR(controller),
1048             c.s.ferlib = 1);
1049         BDK_TRACE(SATA, "N%d.SATA%d: Started Retimed loopback\n", node, controller);
1050         return 0;
1051     }
1052     else if ((mode >= BDK_SATA_BIST_SW_TX_ONLY_SSOP) && (mode <= BDK_SATA_BIST_SW_TX_ONLY_LFTP))
1053     {
1054         /* No FIS, just enter local transit only */
1055         BDK_CSR_MODIFY(c, node, BDK_SATAX_UAHC_GBL_BISTCR(controller),
1056             c.s.txo = 1);
1057         BDK_TRACE(SATA, "N%d.SATA%d: Started tranmsit only\n", node, controller);
1058         return 0;
1059     }
1060 
1061     /* Issue a BIST FIS command */
1062 
1063     /* Pick a command slot to use */
1064     int slot = 0;
1065     hba_cmd_header_t *cmd_header = bdk_phys_to_ptr(BDK_CSR_READ(node, BDK_SATAX_UAHC_P0_CLB(controller)));
1066     cmd_header += slot;
1067 
1068     /* Build a command table with the command to execute */
1069     hba_cmd_tbl_t cmd_table BDK_CACHE_LINE_ALIGNED;
1070     memset(&cmd_table, 0, sizeof(hba_cmd_tbl_t));
1071 
1072     /* The actual BIST FIS command */
1073     fis_bist_t *bist_fis = (fis_bist_t *)cmd_table.cfis;
1074     bist_fis->fis_type = FIS_TYPE_BIST;
1075     switch (mode)
1076     {
1077         case BDK_SATA_BIST_FIS_RETIMED: /* Send FIS to tell device to enter Retimed loopback */
1078             bist_fis->l = 1;
1079             break;
1080         case BDK_SATA_BIST_FIS_ANALOG:  /* Send FIS to tell device to enter Analog loopback */
1081             bist_fis->f = 1;
1082             break;
1083         case BDK_SATA_BIST_FIS_TX_ONLY: /* Send FIS to tell device to transit only */
1084             bist_fis->t = 1;
1085             break;
1086         default:
1087             bdk_error("Invalid SATA BIST FIS mode %d\n", mode);
1088             return -1;
1089     }
1090 
1091     /* Setup the command header */
1092     memset(cmd_header, 0, sizeof(hba_cmd_header_t));
1093     cmd_header->cfl = sizeof(fis_bist_t) / 4;
1094     cmd_header->b = 1;
1095     cmd_header->ctba = bdk_ptr_to_phys(&cmd_table);
1096 
1097     BDK_WMB;
1098 
1099     /* Check that the slot is idle */
1100     BDK_CSR_INIT(ci, node, BDK_SATAX_UAHC_P0_CI(controller));
1101     if (ci.u & (1<<slot))
1102     {
1103         bdk_error("N%d.SATA%d: Command slot busy before submit\n", node, controller);
1104         return -1;
1105     }
1106 
1107     /* Clear all status bits */
1108     BDK_CSR_WRITE(node, BDK_SATAX_UAHC_P0_IS(controller), -1);
1109     BDK_CSR_READ(node, BDK_SATAX_UAHC_P0_IS(controller));
1110 
1111     /* Issue command */
1112     BDK_CSR_WRITE(node, BDK_SATAX_UAHC_P0_CI(controller), 1 << slot);
1113     BDK_TRACE(SATA, "N%d.SATA%d: Sent BIST FIS\n", node, controller);
1114 
1115     return 0;
1116 }
1117 
1118