ahci.c 24 KB

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