1 /*
2  * Copyright (c) 2006-2023, RT-Thread Development Team
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  *
6  * Change Logs:
7  * Date           Author       Notes
8  * 2023-02-25     GuEe-GUI     the first version
9  */
10 
11 #include <rthw.h>
12 #include <rtthread.h>
13 #include <rtdevice.h>
14 
15 #define DBG_TAG "rtdm.ahci"
16 #define DBG_LVL DBG_INFO
17 #include <rtdbg.h>
18 
19 #define HWREG32_FLUSH(base, value)  \
20 do {                                \
21     rt_uint32_t __value = value;    \
22     HWREG32(base) = __value;        \
23     __value = HWREG32(base);        \
24 } while (0)
25 
ahci_fill_cmd_slot(struct rt_ahci_port * port,rt_uint32_t opts)26 static void ahci_fill_cmd_slot(struct rt_ahci_port *port, rt_uint32_t opts)
27 {
28     rt_ubase_t dma_addr = port->cmd_tbl_dma;
29     struct rt_ahci_cmd_hdr *cmd_slot = port->cmd_slot;
30 
31     cmd_slot->opts = rt_cpu_to_le32(opts);
32     cmd_slot->status = 0;
33     cmd_slot->tbl_addr_lo = rt_cpu_to_le32(rt_lower_32_bits(dma_addr));
34     cmd_slot->tbl_addr_hi = rt_cpu_to_le32(rt_upper_32_bits(dma_addr));
35 }
36 
ahci_fill_sg(struct rt_ahci_host * host,int id,void * buffer,rt_size_t buffer_size)37 static int ahci_fill_sg(struct rt_ahci_host *host, int id,
38         void *buffer, rt_size_t buffer_size)
39 {
40     int sg_count;
41     rt_ubase_t dma_addr;
42     struct rt_ahci_port *port = &host->ports[id];
43     struct rt_ahci_sg *ahci_sg = port->cmd_tbl_sg;
44 
45     sg_count = ((buffer_size - 1) / RT_ACHI_PRDT_BYTES_MAX) + 1;
46 
47     if (sg_count > RT_AHCI_MAX_SG)
48     {
49         return -1;
50     }
51 
52     dma_addr = (rt_ubase_t)rt_kmem_v2p(buffer);
53 
54     for (int i = 0; i < sg_count; ++i, ++ahci_sg)
55     {
56         ahci_sg->addr_lo = rt_cpu_to_le32(rt_lower_32_bits(dma_addr));
57         ahci_sg->addr_hi = rt_cpu_to_le32(rt_upper_32_bits(dma_addr));
58 
59         if (ahci_sg->addr_hi && !(host->cap & RT_AHCI_CAP_64))
60         {
61             return -1;
62         }
63 
64         ahci_sg->flags_size = rt_cpu_to_le32(0x3fffff &
65                 (rt_min_t(rt_uint32_t, buffer_size, RT_ACHI_PRDT_BYTES_MAX) - 1));
66 
67         dma_addr += RT_ACHI_PRDT_BYTES_MAX;
68         buffer_size -= RT_ACHI_PRDT_BYTES_MAX;
69     }
70 
71     return sg_count;
72 }
73 
ahci_request_io(struct rt_ahci_host * host,int id,void * fis,rt_size_t fis_size,void * buffer,rt_size_t buffer_size,rt_bool_t is_read)74 static rt_err_t ahci_request_io(struct rt_ahci_host *host, int id,
75         void *fis, rt_size_t fis_size,
76         void *buffer, rt_size_t buffer_size, rt_bool_t is_read)
77 {
78     int sg_count;
79     rt_err_t err;
80     struct rt_ahci_port *port = &host->ports[id];
81 
82     if ((HWREG32(port->regs + RT_AHCI_PORT_SSTS) & 0xf) != RT_AHCI_PORT_SSTS_DET_PHYRDY)
83     {
84         return -RT_EIO;
85     }
86 
87     if ((sg_count = ahci_fill_sg(host, id, buffer, buffer_size)) <= 0)
88     {
89         return -RT_EINVAL;
90     }
91 
92     rt_memcpy(port->cmd_tbl, fis, fis_size);
93     ahci_fill_cmd_slot(port, (fis_size >> 2) | (sg_count << 16) | (!is_read << 6));
94 
95     if (!is_read)
96     {
97         rt_hw_cpu_dcache_ops(RT_HW_CACHE_FLUSH, buffer, buffer_size);
98     }
99 
100     HWREG32_FLUSH(port->regs + RT_AHCI_PORT_CI, 1);
101 
102     err = rt_completion_wait(&port->done, rt_tick_from_millisecond(10000));
103 
104     if (!err && is_read)
105     {
106         rt_hw_cpu_dcache_ops(RT_HW_CACHE_INVALIDATE, buffer, buffer_size);
107     }
108 
109     return err;
110 }
111 
ahci_scsi_cmd_rw(struct rt_ahci_host * host,int id,rt_off_t lba,void * buffer,rt_ssize_t size,rt_bool_t is_read)112 static rt_err_t ahci_scsi_cmd_rw(struct rt_ahci_host *host, int id,
113         rt_off_t lba, void *buffer, rt_ssize_t size, rt_bool_t is_read)
114 {
115     rt_err_t err;
116     rt_uint8_t fis[20];
117     struct rt_ahci_port *port = &host->ports[id];
118 
119     rt_memset(fis, 0, sizeof(fis));
120     fis[0] = RT_AHCI_FIS_TYPE_REG_H2D;
121     fis[1] = 1 << 7; /* Command */
122     fis[2] = is_read ? RT_AHCI_ATA_CMD_READ_EXT : RT_AHCI_ATA_CMD_WRITE_EXT;
123 
124     while (size > 0)
125     {
126         rt_size_t t_size, t_lba;
127 
128         t_lba = rt_min_t(rt_size_t, host->max_blocks, size);
129         t_size = port->block_size * t_lba;
130 
131         fis[3] = 0xe0;                  /* Features */
132         fis[4] = (lba >> 0) & 0xff;     /* LBA low register */
133         fis[5] = (lba >> 8) & 0xff;     /* LBA mid register */
134         fis[6] = (lba >> 16) & 0xff;    /* LBA high register */
135         fis[7] = 1 << 6;                /* Device */
136         fis[8] = ((lba >> 24) & 0xff);  /* LBA register, 31:24 */
137         fis[9] = ((lba >> 32) & 0xff);  /* LBA register, 39:32 */
138         fis[10] = ((lba >> 40) & 0xff); /* LBA register, 47:40 */
139         fis[12] = (t_lba >> 0) & 0xff;  /* Count register, 7:0 */
140         fis[13] = (t_lba >> 8) & 0xff;  /* Count register, 15:8 */
141 
142         if ((err = ahci_request_io(host, id, fis, sizeof(fis), buffer, t_size, is_read)))
143         {
144             return err;
145         }
146 
147         size -= t_lba;
148         lba += t_lba;
149         buffer += t_size;
150     }
151 
152     return RT_EOK;
153 }
154 
ahci_scsi_synchronize_cache(struct rt_ahci_host * host,int id,rt_off_t lba,rt_size_t size)155 static rt_err_t ahci_scsi_synchronize_cache(struct rt_ahci_host *host, int id,
156         rt_off_t lba, rt_size_t size)
157 {
158     rt_uint8_t fis[20];
159     rt_uint16_t *ataid;
160     struct rt_ahci_port *port = &host->ports[id];
161 
162     ataid = port->ataid;
163 
164     if (!rt_ahci_ata_id_wcache_enabled(ataid) &&
165         !rt_ahci_ata_id_has_flush(ataid) &&
166         !rt_ahci_ata_id_has_flush_ext(ataid))
167     {
168         return -RT_ENOSYS;
169     }
170 
171     rt_memset(fis, 0, sizeof(fis));
172     fis[0] = RT_AHCI_FIS_TYPE_REG_H2D;
173     fis[1] = 1 << 7; /* Command */
174 
175     if (rt_ahci_ata_id_has_flush_ext(ataid))
176     {
177         fis[2] = RT_AHCI_ATA_CMD_FLUSH_EXT;
178     }
179     else
180     {
181         fis[2] = RT_AHCI_ATA_CMD_FLUSH;
182     }
183 
184     rt_memcpy(port->cmd_tbl, fis, 20);
185     ahci_fill_cmd_slot(port, 5);
186 
187     HWREG32_FLUSH(port->regs + RT_AHCI_PORT_CI, 1);
188 
189     return rt_completion_wait(&port->done, rt_tick_from_millisecond(5000));
190 }
191 
ahci_scsi_cmd_write_same(struct rt_ahci_host * host,int id,rt_off_t lba,rt_size_t size)192 static rt_err_t ahci_scsi_cmd_write_same(struct rt_ahci_host *host, int id,
193         rt_off_t lba, rt_size_t size)
194 {
195     rt_uint8_t fis[20];
196     struct rt_ahci_port *port = &host->ports[id];
197 
198     rt_memset(fis, 0, sizeof(fis));
199     fis[0] = RT_AHCI_FIS_TYPE_REG_H2D;
200     fis[1] = 1 << 7;                /* Command */
201     fis[2] = RT_AHCI_ATA_CMD_DSM;
202     fis[3] = RT_AHCI_ATA_DSM_TRIM;  /* Features */
203     fis[4] = (lba >> 0) & 0xff;     /* LBA low register */
204     fis[5] = (lba >> 8) & 0xff;     /* LBA mid register */
205     fis[6] = (lba >> 16) & 0xff;    /* LBA high register */
206     fis[7] = 1 << 6;                /* Device */
207     fis[8] = ((lba >> 24) & 0xff);  /* LBA register, 31:24 */
208     fis[9] = ((lba >> 32) & 0xff);  /* LBA register, 39:32 */
209     fis[10] = ((lba >> 40) & 0xff); /* LBA register, 47:40 */
210     fis[12] = (size >> 0) & 0xff;   /* Count register, 7:0 */
211     fis[13] = (size >> 8) & 0xff;   /* Count register, 15:8 */
212 
213     HWREG32_FLUSH(port->regs + RT_AHCI_PORT_CI, 1);
214 
215     return rt_completion_wait(&port->done, rt_tick_from_millisecond(5000));
216 }
217 
ahci_scsi_cmd_read_capacity(struct rt_ahci_host * host,int id,rt_size_t * out_last_block,rt_size_t * out_block_size)218 static rt_err_t ahci_scsi_cmd_read_capacity(struct rt_ahci_host *host, int id,
219         rt_size_t *out_last_block, rt_size_t *out_block_size)
220 {
221     struct rt_ahci_port *port = &host->ports[id];
222 
223     if (!port->ataid)
224     {
225         return -RT_EIO;
226     }
227 
228     *out_last_block = rt_ahci_ata_id_n_sectors(port->ataid) - 1;
229     *out_block_size = port->block_size;
230 
231     return RT_EOK;
232 }
233 
ahci_scsi_cmd_test_unit_ready(struct rt_ahci_host * host,int id)234 static rt_err_t ahci_scsi_cmd_test_unit_ready(struct rt_ahci_host *host, int id)
235 {
236     struct rt_ahci_port *port = &host->ports[id];
237 
238     return port->ataid ? RT_EOK : -RT_EIO;
239 }
240 
ahci_scsi_cmd_inquiry(struct rt_ahci_host * host,int id,char * prodid,rt_size_t prodid_len,char * prodrev,rt_size_t prodrev_len)241 static rt_err_t ahci_scsi_cmd_inquiry(struct rt_ahci_host *host, int id,
242         char *prodid, rt_size_t prodid_len, char *prodrev, rt_size_t prodrev_len)
243 {
244     rt_err_t err;
245     rt_uint8_t fis[20];
246     rt_uint16_t *ataid;
247     struct rt_ahci_port *port = &host->ports[id];
248 
249     if (!port->link)
250     {
251         return -RT_EIO;
252     }
253 
254     if (!port->ataid && !(port->ataid = rt_malloc(RT_AHCI_ATA_ID_WORDS * 2)))
255     {
256         return -RT_ENOMEM;
257     }
258     ataid = port->ataid;
259 
260     rt_memset(fis, 0, sizeof(fis));
261     fis[0] = RT_AHCI_FIS_TYPE_REG_H2D;
262     fis[1] = 1 << 7; /* Command */
263     fis[2] = RT_AHCI_ATA_CMD_ID_ATA;
264 
265     if ((err = ahci_request_io(host, id, fis, sizeof(fis),
266             ataid, RT_AHCI_ATA_ID_WORDS * 2, RT_TRUE)))
267     {
268         return err;
269     }
270 
271     for (int i = 0; i < RT_AHCI_ATA_ID_WORDS; ++i)
272     {
273         ataid[i] = rt_le16_to_cpu(ataid[i]);
274     }
275 
276     for (int i = 0; i < prodid_len / 2; ++i)
277     {
278         rt_uint16_t src = ataid[RT_AHCI_ATA_ID_PROD + i];
279 
280         prodid[i] = (src & 0x00ff) << 8 | (src & 0xff00) >> 8;
281     }
282 
283     for (int i = 0; i < prodrev_len / 2; ++i)
284     {
285         rt_uint16_t src = ataid[RT_AHCI_ATA_ID_FW_REV + i];
286 
287         prodrev[i] = (src & 0x00ff) << 8 | (src & 0xff00) >> 8;
288     }
289 
290     return err;
291 }
292 
ahci_scsi_transfer(struct rt_scsi_device * sdev,struct rt_scsi_cmd * cmd)293 static rt_err_t ahci_scsi_transfer(struct rt_scsi_device *sdev,
294         struct rt_scsi_cmd *cmd)
295 {
296     rt_err_t err;
297     struct rt_ahci_host *host;
298 
299     host = rt_container_of(sdev->host, struct rt_ahci_host, parent);
300 
301     switch (cmd->op.unknow.opcode)
302     {
303     case RT_SCSI_CMD_REQUEST_SENSE:
304     {
305         struct rt_scsi_request_sense_data *request_sense = &cmd->data.request_sense;
306 
307         request_sense->error_code = 0x72;
308 
309         err = RT_EOK;
310     }
311         break;
312 
313     case RT_SCSI_CMD_READ10:
314     {
315         struct rt_scsi_read10 *read10 = &cmd->op.read10;
316 
317         err = ahci_scsi_cmd_rw(host, sdev->id,
318                 rt_be32_to_cpu(read10->lba),
319                 cmd->data.ptr,
320                 rt_be16_to_cpu(read10->size),
321                 RT_TRUE);
322     }
323         break;
324 
325     case RT_SCSI_CMD_READ16:
326     {
327         struct rt_scsi_read16 *read16 = &cmd->op.read16;
328 
329         err = ahci_scsi_cmd_rw(host, sdev->id,
330                 rt_be64_to_cpu(read16->lba),
331                 cmd->data.ptr,
332                 rt_be32_to_cpu(read16->size),
333                 RT_TRUE);
334     }
335         break;
336 
337     case RT_SCSI_CMD_READ12:
338     {
339         struct rt_scsi_read12 *read12 = &cmd->op.read12;
340 
341         err = ahci_scsi_cmd_rw(host, sdev->id,
342                 rt_be32_to_cpu(read12->lba),
343                 cmd->data.ptr,
344                 rt_be32_to_cpu(read12->size),
345                 RT_TRUE);
346     }
347         break;
348 
349     case RT_SCSI_CMD_WRITE10:
350     {
351         struct rt_scsi_write10 *write10 = &cmd->op.write10;
352 
353         err = ahci_scsi_cmd_rw(host, sdev->id,
354                 rt_be32_to_cpu(write10->lba),
355                 cmd->data.ptr,
356                 rt_be16_to_cpu(write10->size),
357                 RT_FALSE);
358     }
359         break;
360 
361     case RT_SCSI_CMD_WRITE16:
362     {
363         struct rt_scsi_write16 *write16 = &cmd->op.write16;
364 
365         err = ahci_scsi_cmd_rw(host, sdev->id,
366                 rt_be64_to_cpu(write16->lba),
367                 cmd->data.ptr,
368                 rt_be32_to_cpu(write16->size),
369                 RT_FALSE);
370     }
371         break;
372 
373     case RT_SCSI_CMD_WRITE12:
374     {
375         struct rt_scsi_write12 *write12 = &cmd->op.write12;
376 
377         err = ahci_scsi_cmd_rw(host, sdev->id,
378                 rt_be32_to_cpu(write12->lba),
379                 cmd->data.ptr,
380                 rt_be32_to_cpu(write12->size),
381                 RT_FALSE);
382     }
383         break;
384 
385     case RT_SCSI_CMD_SYNCHRONIZE_CACHE10:
386     {
387         struct rt_scsi_synchronize_cache10 *synchronize_cache10 = &cmd->op.synchronize_cache10;
388 
389         err = ahci_scsi_synchronize_cache(host, sdev->id,
390                 rt_be32_to_cpu(synchronize_cache10->lba),
391                 rt_be16_to_cpu(synchronize_cache10->size));
392     }
393         break;
394 
395     case RT_SCSI_CMD_SYNCHRONIZE_CACHE16:
396     {
397         struct rt_scsi_synchronize_cache16 *synchronize_cache16 = &cmd->op.synchronize_cache16;
398 
399         err = ahci_scsi_synchronize_cache(host, sdev->id,
400                 rt_be64_to_cpu(synchronize_cache16->lba),
401                 rt_be32_to_cpu(synchronize_cache16->size));
402     }
403         break;
404 
405     case RT_SCSI_CMD_WRITE_SAME10:
406     {
407         struct rt_scsi_write_same10 *write_same10 = &cmd->op.write_same10;
408 
409         err = ahci_scsi_cmd_write_same(host, sdev->id,
410                 rt_be32_to_cpu(write_same10->lba), rt_be16_to_cpu(write_same10->size));
411     }
412         break;
413 
414     case RT_SCSI_CMD_WRITE_SAME16:
415     {
416         struct rt_scsi_write_same16 *write_same16 = &cmd->op.write_same16;
417 
418         err = ahci_scsi_cmd_write_same(host, sdev->id,
419                 rt_be64_to_cpu(write_same16->lba), rt_be32_to_cpu(write_same16->size));
420     }
421         break;
422 
423     case RT_SCSI_CMD_READ_CAPACITY10:
424     {
425         rt_size_t last_block, block_size;
426         struct rt_scsi_read_capacity10_data *data = &cmd->data.read_capacity10;
427 
428         err = ahci_scsi_cmd_read_capacity(host, sdev->id, &last_block, &block_size);
429 
430         if (!err)
431         {
432             if (last_block > 0x100000000ULL)
433             {
434                 last_block = 0xffffffff;
435             }
436 
437             data->last_block = rt_cpu_to_be32(last_block);
438             data->block_size = rt_cpu_to_be32(block_size);
439         }
440     }
441         break;
442 
443     case RT_SCSI_CMD_READ_CAPACITY16:
444     {
445         rt_size_t last_block, block_size;
446         struct rt_scsi_read_capacity16_data *data = &cmd->data.read_capacity16;
447 
448         err = ahci_scsi_cmd_read_capacity(host, sdev->id, &last_block, &block_size);
449 
450         if (!err)
451         {
452             data->last_block = rt_cpu_to_be64(last_block);
453             data->block_size = rt_cpu_to_be32(block_size);
454         }
455     }
456         break;
457 
458     case RT_SCSI_CMD_TEST_UNIT_READY:
459         err = ahci_scsi_cmd_test_unit_ready(host, sdev->id);
460         break;
461 
462     case RT_SCSI_CMD_INQUIRY:
463     {
464         struct rt_ahci_port *port = &host->ports[sdev->id];
465         struct rt_scsi_inquiry_data *inquiry = &cmd->data.inquiry;
466 
467         err = ahci_scsi_cmd_inquiry(host, sdev->id,
468                 inquiry->prodid, sizeof(inquiry->prodid),
469                 inquiry->prodrev, sizeof(inquiry->prodrev));
470 
471         if (!err)
472         {
473             rt_memcpy(inquiry->vendor, "ATA     ", sizeof(inquiry->vendor));
474 
475             if (HWREG32(port->regs + RT_AHCI_PORT_SIG) != RT_AHCI_PORT_SIG_SATA_CDROM)
476             {
477                 port->block_size = 512;
478                 inquiry->devtype = SCSI_DEVICE_TYPE_DIRECT;
479             }
480             else
481             {
482                 port->block_size = 2048;
483                 inquiry->devtype = SCSI_DEVICE_TYPE_CDROM;
484             }
485             inquiry->rmb = 0;
486             inquiry->length = 95 - 4;
487         }
488     }
489         break;
490 
491     case RT_SCSI_CMD_MODE_SENSE:
492     case RT_SCSI_CMD_MODE_SENSE10:
493     case RT_SCSI_CMD_MODE_SELECT:
494     case RT_SCSI_CMD_MODE_SELECT10:
495         return -RT_ENOSYS;
496 
497     default:
498         return -RT_EINVAL;
499     }
500 
501     return err;
502 }
503 
504 static struct rt_scsi_ops ahci_scsi_ops =
505 {
506     .transfer = ahci_scsi_transfer,
507 };
508 
ahci_isr(int irqno,void * param)509 static void ahci_isr(int irqno, void *param)
510 {
511     int id;
512     rt_uint32_t isr;
513     rt_bitmap_t int_map;
514     struct rt_ahci_port *port;
515     struct rt_ahci_host *host = param;
516 
517     int_map = HWREG32(host->regs + RT_AHCI_HBA_INTS);
518 
519     rt_bitmap_for_each_set_bit(&int_map, id, host->ports_nr)
520     {
521         port = &host->ports[id];
522 
523         isr = HWREG32(port->regs + RT_AHCI_PORT_INTS);
524 
525         if (port->link)
526         {
527             if (host->ops->port_isr)
528             {
529                 host->ops->port_isr(host, port, isr);
530             }
531 
532             rt_completion_done(&port->done);
533         }
534 
535         HWREG32(port->regs + RT_AHCI_PORT_INTS) = isr;
536     }
537 
538     HWREG32(host->regs + RT_AHCI_HBA_INTS) = int_map;
539 }
540 
rt_ahci_host_register(struct rt_ahci_host * host)541 rt_err_t rt_ahci_host_register(struct rt_ahci_host *host)
542 {
543     rt_err_t err;
544     rt_uint32_t value;
545     char dev_name[RT_NAME_MAX];
546     struct rt_scsi_host *scsi;
547 
548     if (!host || !host->parent.dev || !host->ops)
549     {
550         return -RT_EINVAL;
551     }
552 
553     host->max_blocks = host->max_blocks ? : 0x80;
554 
555     /*
556      * 1. Reset HBA.
557      */
558     err = -RT_EIO;
559     value = HWREG32(host->regs + RT_AHCI_HBA_GHC);
560 
561     if (!(value & RT_AHCI_GHC_RESET))
562     {
563         HWREG32_FLUSH(host->regs + RT_AHCI_HBA_GHC, value | RT_AHCI_GHC_RESET);
564     }
565 
566     for (int i = 0; i < 5; ++i)
567     {
568         rt_thread_mdelay(200);
569 
570         if (!(HWREG32(host->regs + RT_AHCI_HBA_GHC) & RT_AHCI_GHC_RESET))
571         {
572             err = RT_EOK;
573             break;
574         }
575     }
576 
577     if (err)
578     {
579         goto _fail;
580     }
581 
582     /*
583      * 2. Enable AHCI and get the ports' information.
584      */
585     HWREG32_FLUSH(host->regs + RT_AHCI_HBA_GHC, RT_AHCI_GHC_AHCI_EN);
586 
587     host->cap = HWREG32(host->regs + RT_AHCI_HBA_CAP);
588     host->cap &= RT_AHCI_CAP_SPM | RT_AHCI_CAP_SSS | RT_AHCI_CAP_SIS;
589     HWREG32(host->regs + RT_AHCI_HBA_CAP) = host->cap;
590     host->cap = HWREG32(host->regs + RT_AHCI_HBA_CAP);
591 
592     HWREG32_FLUSH(host->regs + RT_AHCI_HBA_PI, 0xf);
593 
594     if (host->ops->host_init && (err = host->ops->host_init(host)))
595     {
596         goto _fail;
597     }
598 
599     host->ports_nr = (host->cap & RT_AHCI_CAP_NP) + 1;
600     host->ports_map = HWREG32(host->regs + RT_AHCI_HBA_PI);
601 
602     /* Check implemented in firmware */
603     rt_dm_dev_prop_read_u32(host->parent.dev, "ports-implemented", &host->ports_map);
604 
605     for (int i = 0; i < host->ports_nr; ++i)
606     {
607         struct rt_ahci_port *port;
608 
609         if (!(host->ports_map & RT_BIT(i)))
610         {
611             continue;
612         }
613         port = &host->ports[i];
614 
615         /*
616          * 3. Alloc port io memory.
617          */
618         port->regs = host->regs + 0x100 + (i * 0x80);
619 
620         /*
621          * 4. Make port stop.
622          */
623         value = HWREG32(port->regs + RT_AHCI_PORT_CMD);
624         if (value & (RT_AHCI_PORT_CMD_LIST_ON | RT_AHCI_PORT_CMD_FIS_ON |
625                 RT_AHCI_PORT_CMD_FIS_RX | RT_AHCI_PORT_CMD_START))
626         {
627             value &= ~(RT_AHCI_PORT_CMD_LIST_ON | RT_AHCI_PORT_CMD_FIS_ON |
628                     RT_AHCI_PORT_CMD_FIS_RX | RT_AHCI_PORT_CMD_START);
629 
630             HWREG32_FLUSH(port->regs + RT_AHCI_PORT_CMD, value);
631 
632             rt_thread_mdelay(500);
633         }
634 
635         if (host->ops->port_init && (err = host->ops->port_init(host, port)))
636         {
637             LOG_E("Init port[%d] error = %s", rt_strerror(err));
638             continue;
639         }
640 
641         value = HWREG32(port->regs + RT_AHCI_PORT_CMD);
642         value |= RT_AHCI_PORT_CMD_SPIN_UP;
643         HWREG32(port->regs + RT_AHCI_PORT_CMD) = value;
644 
645         /*
646          * 5. Enable port's SATA link.
647          */
648         if (host->ops->port_link_up)
649         {
650             err = host->ops->port_link_up(host, port);
651         }
652         else
653         {
654             err = -RT_ETIMEOUT;
655 
656             for (int retry = 0; retry < 5; ++retry)
657             {
658                 value = HWREG32(port->regs + RT_AHCI_PORT_SSTS);
659 
660                 if ((value & RT_AHCI_PORT_SSTS_DET_MASK) == RT_AHCI_PORT_SSTS_DET_PHYRDY)
661                 {
662                     err = RT_EOK;
663                     break;
664                 }
665 
666                 rt_thread_mdelay(2);
667             }
668         }
669 
670         if (err)
671         {
672             if (HWREG32(port->regs + RT_AHCI_PORT_SSTS) & RT_AHCI_PORT_SSTS_DET_MASK)
673             {
674                 LOG_E("SATA[%d] link error = %s", i, rt_strerror(err));
675             }
676             else
677             {
678                 LOG_D("SATA[%d] not device", i);
679             }
680 
681             continue;
682         }
683 
684         /* Clear error status */
685         if ((value = HWREG32(port->regs + RT_AHCI_PORT_SERR)))
686         {
687             HWREG32(port->regs + RT_AHCI_PORT_SERR) = value;
688         }
689 
690         for (int retry = 0; retry < 5; ++retry)
691         {
692             value = HWREG32(port->regs + RT_AHCI_PORT_TFD);
693             if (!(value & (RT_AHCI_PORT_TFDATA_BSY | RT_AHCI_PORT_TFDATA_DRQ)))
694             {
695                 break;
696             }
697 
698             rt_thread_mdelay(2);
699 
700             value = HWREG32(port->regs + RT_AHCI_PORT_SSTS);
701             if ((value & RT_AHCI_PORT_SSTS_DET_MASK) == RT_AHCI_PORT_SSTS_DET_PHYRDY)
702             {
703                 break;
704             }
705         }
706 
707         value = HWREG32(port->regs + RT_AHCI_PORT_SSTS) & RT_AHCI_PORT_SSTS_DET_MASK;
708         if (value == RT_AHCI_PORT_SSTS_DET_COMINIT)
709         {
710             /* Retry to setup */
711             --i;
712             continue;
713         }
714 
715         /* Clear error */
716         value = HWREG32(port->regs + RT_AHCI_PORT_SERR);
717         HWREG32(port->regs + RT_AHCI_PORT_SERR) = value;
718 
719         /* Clear pending IRQ */
720         if ((value = HWREG32(port->regs + RT_AHCI_PORT_INTS)))
721         {
722             HWREG32(port->regs + RT_AHCI_PORT_INTS) = value;
723         }
724 
725         HWREG32(host->regs + RT_AHCI_HBA_INTS) = RT_BIT(i);
726 
727         value = HWREG32(port->regs + RT_AHCI_PORT_SSTS);
728         if ((value & RT_AHCI_PORT_SSTS_DET_MASK) == RT_AHCI_PORT_SSTS_DET_PHYRDY)
729         {
730             port->link = RT_TRUE;
731         }
732     }
733 
734     HWREG32(host->regs + RT_AHCI_HBA_GHC) |= RT_AHCI_GHC_IRQ_EN;
735 
736     for (int i = 0; i < host->ports_nr; ++i)
737     {
738         void *dma;
739         rt_ubase_t dma_addr;
740         rt_tick_t timeout;
741         struct rt_ahci_port *port = &host->ports[i];
742 
743         if (!port->link)
744         {
745             continue;
746         }
747 
748         /*
749          * 6. Alloc transport memory, Port x Command List and FIS Base Address.
750          */
751         port->dma = rt_dma_alloc_coherent(host->parent.dev,
752                 RT_AHCI_DMA_SIZE, &port->dma_handle);
753 
754         if (!port->dma)
755         {
756             LOG_E("No memory to setup port[%d]", i);
757             break;
758         }
759         dma = port->dma;
760 
761         rt_memset(dma, 0, RT_AHCI_DMA_SIZE);
762 
763         port->cmd_slot = dma;
764         dma += (RT_AHCI_CMD_SLOT_SIZE + 224);
765 
766         port->rx_fis = dma;
767         dma += RT_AHCI_RX_FIS_SIZE;
768 
769         port->cmd_tbl = dma;
770         port->cmd_tbl_dma = (rt_ubase_t)rt_kmem_v2p(dma);
771         dma += RT_AHCI_CMD_TBL_HDR;
772 
773         port->cmd_tbl_sg = dma;
774 
775         dma_addr = (rt_ubase_t)rt_kmem_v2p(port->cmd_slot);
776         HWREG32_FLUSH(port->regs + RT_AHCI_PORT_CLB, rt_lower_32_bits(dma_addr));
777         HWREG32_FLUSH(port->regs + RT_AHCI_PORT_CLBU, rt_upper_32_bits(dma_addr));
778 
779         dma_addr = (rt_ubase_t)rt_kmem_v2p(port->rx_fis);
780         HWREG32_FLUSH(port->regs + RT_AHCI_PORT_FB, rt_lower_32_bits(dma_addr));
781         HWREG32_FLUSH(port->regs + RT_AHCI_PORT_FBU, rt_upper_32_bits(dma_addr));
782 
783         if (host->ops->port_dma_init && (err = host->ops->port_dma_init(host, port)))
784         {
785             LOG_E("Init port[%d] DMA error = %s", rt_strerror(err));
786         }
787 
788         HWREG32_FLUSH(port->regs + RT_AHCI_PORT_CMD, RT_AHCI_PORT_CMD_ACTIVE |
789                 RT_AHCI_PORT_CMD_FIS_RX | RT_AHCI_PORT_CMD_POWER_ON |
790                 RT_AHCI_PORT_CMD_SPIN_UP | RT_AHCI_PORT_CMD_START);
791 
792         /* Wait spinup */
793         err = -RT_ETIMEOUT;
794         timeout = rt_tick_from_millisecond(20000);
795         timeout += rt_tick_get();
796         do {
797             if (!(HWREG32(port->regs + RT_AHCI_PORT_TFD) & RT_AHCI_PORT_TFDATA_BSY))
798             {
799                 err = RT_EOK;
800                 break;
801             }
802 
803             rt_hw_cpu_relax();
804         } while (rt_tick_get() < timeout);
805 
806         if (err)
807         {
808             rt_dma_free_coherent(host->parent.dev, RT_AHCI_DMA_SIZE, port->dma,
809                     port->dma_handle);
810             port->dma = RT_NULL;
811 
812             LOG_E("Start up port[%d] fail", i);
813             continue;
814         }
815 
816         port->int_enabled |= RT_AHCI_PORT_INTE_HBUS_ERR | RT_AHCI_PORT_INTE_IF_ERR |
817                 RT_AHCI_PORT_INTE_CONNECT | RT_AHCI_PORT_INTE_PHYRDY |
818                 RT_AHCI_PORT_INTE_UNK_FIS | RT_AHCI_PORT_INTE_BAD_PMP |
819                 RT_AHCI_PORT_INTE_TF_ERR | RT_AHCI_PORT_INTE_HBUS_DATA_ERR |
820                 RT_AHCI_PORT_INTE_SG_DONE | RT_AHCI_PORT_INTE_SDB_FIS |
821                 RT_AHCI_PORT_INTE_DMAS_FIS | RT_AHCI_PORT_INTE_PIOS_FIS |
822                 RT_AHCI_PORT_INTE_D2H_REG_FIS;
823 
824         HWREG32(port->regs + RT_AHCI_PORT_INTE) = port->int_enabled;
825 
826         rt_completion_init(&port->done);
827     }
828 
829     rt_snprintf(dev_name, sizeof(dev_name), "ahci-%s",
830             rt_dm_dev_get_name(host->parent.dev));
831 
832     rt_hw_interrupt_install(host->irq, ahci_isr, host, dev_name);
833     rt_hw_interrupt_umask(host->irq);
834 
835     scsi = &host->parent;
836     scsi->max_lun = rt_max_t(rt_size_t, scsi->max_lun, 1);
837     scsi->max_id = host->ports_nr;
838     scsi->ops = &ahci_scsi_ops;
839 
840     if ((err = rt_scsi_host_register(scsi)))
841     {
842         goto _fail;
843     }
844 
845     return RT_EOK;
846 
847 _fail:
848     rt_hw_interrupt_mask(host->irq);
849     rt_pic_detach_irq(host->irq, host);
850 
851     return err;
852 }
853 
rt_ahci_host_unregister(struct rt_ahci_host * host)854 rt_err_t rt_ahci_host_unregister(struct rt_ahci_host *host)
855 {
856     rt_err_t err;
857     struct rt_scsi_host *scsi;
858 
859     if (!host)
860     {
861         return -RT_EINVAL;
862     }
863 
864     scsi = &host->parent;
865 
866     if ((err = rt_scsi_host_unregister(scsi)))
867     {
868         return err;
869     }
870 
871     rt_hw_interrupt_mask(host->irq);
872     rt_pic_detach_irq(host->irq, host);
873 
874     for (int i = 0; i < host->ports_nr; ++i)
875     {
876         struct rt_ahci_port *port = &host->ports[i];
877 
878         if (port->ataid)
879         {
880             rt_free(port->ataid);
881         }
882 
883         HWREG32(port->regs) &= ~(RT_AHCI_PORT_CMD_ACTIVE | RT_AHCI_PORT_CMD_POWER_ON |
884                 RT_AHCI_PORT_CMD_SPIN_UP | RT_AHCI_PORT_CMD_START);
885 
886         if (port->dma)
887         {
888             rt_dma_free_coherent(host->parent.dev, RT_AHCI_DMA_SIZE, port->dma,
889                     port->dma_handle);
890         }
891     }
892 
893     HWREG32(host->regs + RT_AHCI_HBA_GHC) &= ~(RT_AHCI_GHC_AHCI_EN | RT_AHCI_GHC_IRQ_EN);
894 
895     return RT_EOK;
896 }
897