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