ftide020.c 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347
  1. /*
  2. * Faraday FTIDE020 ATA Controller (AHB)
  3. *
  4. * (C) Copyright 2011 Andes Technology
  5. * Greentime Hu <greentime@andestech.com>
  6. * Macpaul Lin <macpaul@andestech.com>
  7. * Kuo-Wei Chou <kwchou@andestech.com>
  8. *
  9. * SPDX-License-Identifier: GPL-2.0+
  10. */
  11. /* ftide020.c - ide support functions for the FTIDE020_S controller */
  12. #include <config.h>
  13. #include <common.h>
  14. #include <ata.h>
  15. #include <ide.h>
  16. #include <asm/io.h>
  17. #include <api_public.h>
  18. #include "ftide020.h"
  19. /* base address */
  20. #define FTIDE_BASE CONFIG_SYS_ATA_BASE_ADDR
  21. /*
  22. * data address - The CMD and DATA use the same FIFO in FTIDE020_S
  23. * FTIDE_DATA = CONFIG_SYS_ATA_BASE_ADDR + CONFIG_SYS_ATA_DATA_OFFSET
  24. * = &ftide020->rw_fifo
  25. */
  26. #define FTIDE_DATA (&ftide020->rw_fifo)
  27. /* command and data I/O macros */
  28. /* 0x0 - DATA FIFO */
  29. #define WRITE_DATA(x) outl((x), &ftide020->rw_fifo) /* 0x00 */
  30. #define READ_DATA() inl(&ftide020->rw_fifo) /* 0x00 */
  31. /* 0x04 - R: Status Reg, W: CMD_FIFO */
  32. #define WRITE_CMD(x) outl((x), &ftide020->cmd_fifo) /* 0x04 */
  33. #define READ_STATUS() inl(&ftide020->cmd_fifo) /* 0x04 */
  34. void ftide_set_device(int cx8, int dev)
  35. {
  36. static struct ftide020_s *ftide020 = (struct ftide020_s *) FTIDE_BASE;
  37. WRITE_CMD(SET_DEV_CMD | IDE_SET_CX8(cx8) | dev);
  38. }
  39. unsigned char ide_read_register(int dev, unsigned int port)
  40. {
  41. static struct ftide020_s *ftide020 = (struct ftide020_s *) FTIDE_BASE;
  42. ftide_set_device(0, dev);
  43. WRITE_CMD(READ_REG_CMD | IDE_REG_CS_READ(CONFIG_IDE_REG_CS) |
  44. IDE_REG_DA_WRITE(port));
  45. return READ_DATA() & 0xff;
  46. }
  47. void ide_write_register(int dev, unsigned int port, unsigned char val)
  48. {
  49. static struct ftide020_s *ftide020 = (struct ftide020_s *) FTIDE_BASE;
  50. ftide_set_device(0, dev);
  51. WRITE_CMD(WRITE_REG_CMD | IDE_REG_CS_WRITE(CONFIG_IDE_REG_CS) |
  52. IDE_REG_DA_WRITE(port) | val);
  53. }
  54. void ide_write_data(int dev, const ulong *sect_buf, int words)
  55. {
  56. static struct ftide020_s *ftide020 = (struct ftide020_s *) FTIDE_BASE;
  57. ftide_set_device(0, dev);
  58. WRITE_CMD(WRITE_DATA_CMD | ((words << 2) - 1));
  59. /* block write */
  60. outsl(FTIDE_DATA, sect_buf, words);
  61. }
  62. void ide_read_data(int dev, ulong *sect_buf, int words)
  63. {
  64. static struct ftide020_s *ftide020 = (struct ftide020_s *) FTIDE_BASE;
  65. ftide_set_device(0, dev);
  66. WRITE_CMD(READ_DATA_CMD | ((words << 2) - 1));
  67. /* block read */
  68. insl(FTIDE_DATA, sect_buf, words);
  69. }
  70. void ftide_dfifo_ready(ulong *time)
  71. {
  72. static struct ftide020_s *ftide020 = (struct ftide020_s *) FTIDE_BASE;
  73. while (!(READ_STATUS() & STATUS_RFE)) {
  74. if (*time-- == 0)
  75. break;
  76. udelay(100);
  77. }
  78. }
  79. extern ulong ide_bus_offset[CONFIG_SYS_IDE_MAXBUS];
  80. /* Reset_IDE_controller */
  81. static void reset_ide_controller(void)
  82. {
  83. static struct ftide020_s *ftide020 = (struct ftide020_s *) FTIDE_BASE;
  84. unsigned int val;
  85. val = inl(&ftide020->cr);
  86. val |= CONTROL_RST;
  87. outl(val, &ftide020->cr);
  88. /* wait until reset OK, this is poor HW design */
  89. mdelay(50);
  90. val &= ~(CONTROL_RST);
  91. outl(val, &ftide020->cr);
  92. mdelay(50);
  93. val |= CONTROL_SRST;
  94. outl(val, &ftide020->cr);
  95. /* wait until reset OK, this is poor HW design */
  96. mdelay(50);
  97. val &= ~(CONTROL_SRST);
  98. outl(val, &ftide020->cr);
  99. /* IORDY enable for PIO, for 2 device */
  100. val |= (CONTROL_IRE0 | CONTROL_IRE1);
  101. outl(val, &ftide020->cr);
  102. }
  103. /* IDE clock frequence */
  104. uint ftide_clock_freq(void)
  105. {
  106. /*
  107. * todo: To aquire dynamic system frequency is dependend on the power
  108. * management unit which the ftide020 is connected to. In current,
  109. * there are only few PMU supports in u-boot.
  110. * So this function is wait for future enhancement.
  111. */
  112. return 100;
  113. }
  114. /* Calculate Timing Registers */
  115. static unsigned int timing_cal(u16 t0, u16 t1, u16 t2, u16 t4)
  116. {
  117. unsigned int val, ahb_ns = 8;
  118. u8 TEOC, T1, T2, T4;
  119. T1 = (u8) (t1 / ahb_ns);
  120. if ((T1 * ahb_ns) == t1)
  121. T1--;
  122. T2 = (u8) (t2 / ahb_ns);
  123. if ((T2 * ahb_ns) == t2)
  124. T2--;
  125. T4 = (u8) (t4 / ahb_ns);
  126. if ((T4 * ahb_ns) == t4)
  127. T4--;
  128. TEOC = (u8) (t0 / ahb_ns);
  129. if ((TEOC * ahb_ns) == t0)
  130. TEOC--;
  131. TEOC = ((TEOC > (T1 + T2 + T4)) ? (TEOC - (T1 + T2 + T4)) : 0);
  132. /*
  133. * Here the fields in data timing registers in PIO mode
  134. * is accessed the same way as command timing registers.
  135. */
  136. val = DT_REG_PIO_T1(T1) |
  137. DT_REG_PIO_T2(T2) |
  138. DT_REG_PIO_T4(T4) |
  139. DT_REG_PIO_TEOC(TEOC);
  140. return val;
  141. }
  142. /* Set Timing Register */
  143. static unsigned int set_mode_timing(u8 dev, u8 id, u8 mode)
  144. {
  145. static struct ftide020_s *ftide020 = (struct ftide020_s *) FTIDE_BASE;
  146. u16 t0, t1, t2, t4;
  147. u8 tcyc, tcvs, tmli, tenv, tack, trp;
  148. unsigned int val, sysclk = 8;
  149. if (id >= TATOL_TIMING)
  150. return 0;
  151. sysclk = ftide_clock_freq();
  152. switch (id) {
  153. case CMD_TIMING:
  154. if (mode < REG_MODE) {
  155. t0 = REG_ACCESS_TIMING[REG_T0][mode];
  156. t1 = REG_ACCESS_TIMING[REG_T1][mode];
  157. t2 = REG_ACCESS_TIMING[REG_T2][mode];
  158. t4 = REG_ACCESS_TIMING[REG_T4][mode];
  159. val = timing_cal(t0, t1, t2, t4);
  160. outl(val, (dev ? &ftide020->ctrd1 : &ftide020->ctrd0));
  161. return 1;
  162. } else
  163. return 0;
  164. case PIO_TIMING:
  165. if (mode < PIO_MODE) {
  166. t0 = PIO_ACCESS_TIMING[PIO_T0][mode];
  167. t1 = PIO_ACCESS_TIMING[PIO_T1][mode];
  168. t2 = PIO_ACCESS_TIMING[PIO_T2][mode];
  169. t4 = PIO_ACCESS_TIMING[PIO_T4][mode];
  170. val = timing_cal(t0, t1, t2, t4);
  171. outl(val, (dev ? &ftide020->dtrd1 : &ftide020->dtrd0));
  172. return 1;
  173. } else
  174. return 0;
  175. case DMA_TIMING:
  176. if (mode < UDMA_MODE) {
  177. /*
  178. * 0.999 is ceiling
  179. * for tcyc, tcvs, tmli, tenv, trp, tack
  180. */
  181. tcyc = (u8) (((UDMA_ACCESS_TIMING[UDMA_TCYC][mode] \
  182. * sysclk) + 9990) / 10000);
  183. tcvs = (u8) (((UDMA_ACCESS_TIMING[UDMA_TCVS][mode] \
  184. * sysclk) + 9990) / 10000);
  185. tmli = (u8) (((UDMA_ACCESS_TIMING[UDMA_TMLI][mode] \
  186. * sysclk) + 9990) / 10000);
  187. tenv = (u8) (((UDMA_ACCESS_TIMING[UDMA_TENV][mode] \
  188. * sysclk) + 9990) / 10000);
  189. trp = (u8) (((UDMA_ACCESS_TIMING[UDMA_TRP][mode] \
  190. * sysclk) + 9990) / 10000);
  191. tack = (u8) (((UDMA_ACCESS_TIMING[UDMA_TACK][mode] \
  192. * sysclk) + 9990) / 10000);
  193. val = DT_REG_UDMA_TENV((tenv > 0) ? (tenv - 1) : 0) |
  194. DT_REG_UDMA_TMLI((tmli > 0) ? (tmli - 1) : 0) |
  195. DT_REG_UDMA_TCYC((tcyc > 0) ? (tcyc - 1) : 0) |
  196. DT_REG_UDMA_TACK((tack > 0) ? (tack - 1) : 0) |
  197. DT_REG_UDMA_TCVS((tcvs > 0) ? (tcvs - 1) : 0) |
  198. DT_REG_UDMA_TRP((trp > 0) ? (trp - 1) : 0);
  199. outl(val, (dev ? &ftide020->dtrd1 : &ftide020->dtrd0));
  200. return 1;
  201. } else
  202. return 0;
  203. default:
  204. return 0;
  205. }
  206. }
  207. static void ftide_read_hwrev(void)
  208. {
  209. static struct ftide020_s *ftide020 = (struct ftide020_s *) FTIDE_BASE;
  210. unsigned int rev;
  211. rev = inl(&ftide020->revision);
  212. }
  213. static int ftide_controller_probe(void)
  214. {
  215. static struct ftide020_s *ftide020 = (struct ftide020_s *) FTIDE_BASE;
  216. unsigned int bak;
  217. bak = inl(&ftide020->ctrd1);
  218. /* probing by using shorter setup time */
  219. outl(CONFIG_CTRD1_PROBE_T1, &ftide020->ctrd1);
  220. if ((inl(&ftide020->ctrd1) & 0xff) != CONFIG_CTRD1_PROBE_T1) {
  221. outl(bak, &ftide020->ctrd1);
  222. return 0;
  223. }
  224. /* probing by using longer setup time */
  225. outl(CONFIG_CTRD1_PROBE_T2, &ftide020->ctrd1);
  226. if ((inl(&ftide020->ctrd1) & 0xff) != CONFIG_CTRD1_PROBE_T2) {
  227. outl(bak, &ftide020->ctrd1);
  228. return 0;
  229. }
  230. outl(bak, &ftide020->ctrd1);
  231. return 1;
  232. }
  233. /* ide_preinit() was migrated from linux driver ide_probe_for_ftide() */
  234. int ide_preinit(void)
  235. {
  236. static struct ftide020_s *ftide020 = (struct ftide020_s *) FTIDE_BASE;
  237. int status;
  238. unsigned int val;
  239. int i;
  240. status = 1;
  241. for (i = 0; i < CONFIG_SYS_IDE_MAXBUS; i++)
  242. ide_bus_offset[i] = -ATA_STATUS;
  243. /* auto-detect IDE controller */
  244. if (ftide_controller_probe()) {
  245. printf("FTIDE020_S\n");
  246. } else {
  247. printf("FTIDE020_S ATA controller not found.\n");
  248. return API_ENODEV;
  249. }
  250. /* check HW IP revision */
  251. ftide_read_hwrev();
  252. /* set FIFO threshold */
  253. outl(((WRITE_FIFO - RX_THRESH) << 16) | RX_THRESH, &ftide020->dmatirr);
  254. /* set Device_0 PIO_4 timing */
  255. set_mode_timing(0, CMD_TIMING, REG_MODE4);
  256. set_mode_timing(0, PIO_TIMING, PIO_MODE4);
  257. /* set Device_1 PIO_4 timing */
  258. set_mode_timing(1, CMD_TIMING, REG_MODE4);
  259. set_mode_timing(1, PIO_TIMING, PIO_MODE4);
  260. /* from E-bios */
  261. /* little endian */
  262. outl(0x0, &ftide020->cr);
  263. mdelay(10);
  264. outl(0x0fff0fff, &ftide020->ahbtr);
  265. mdelay(10);
  266. /* Enable controller Interrupt */
  267. val = inl(&ftide020->cr);
  268. /* Enable: IDE IRQ, IDE Terminate ERROR IRQ, AHB Timeout error IRQ */
  269. val |= (CONTROL_IIE | CONTROL_TERIE | CONTROL_AERIE);
  270. outl(val, &ftide020->cr);
  271. status = 0;
  272. return status;
  273. }
  274. void ide_set_reset(int flag)
  275. {
  276. debug("ide_set_reset()\n");
  277. reset_ide_controller();
  278. return;
  279. }