Advertisement
rayddteam

fsl_sdhci.diff

Nov 30th, 2012
75
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 12.87 KB | None | 0 0
  1. Index: fsl_sdhc.c
  2. ===================================================================
  3. --- fsl_sdhc.c (revision 243277)
  4. +++ fsl_sdhc.c (working copy)
  5. @@ -64,8 +64,11 @@
  6.  
  7. #include "fsl_sdhc.h"
  8.  
  9. +//#undef FSL_SDHC_NO_DMA
  10. +//#define FSL_SDHC_NO_DMA
  11. +//#undef FSL_SDHC_NO_DMA
  12. #define DEBUG
  13. -#undef DEBUG
  14. +//#undef DEBUG
  15. #ifdef DEBUG
  16. #define DPRINTF(fmt, arg...) printf("DEBUG %s(): " fmt, __FUNCTION__, ##arg)
  17. #else
  18. @@ -90,6 +93,10 @@
  19. static int fsl_sdhc_acquire_host(device_t, device_t);
  20. static int fsl_sdhc_release_host(device_t, device_t);
  21.  
  22. +#ifdef DEBUG
  23. +static void dump_registers(struct fsl_sdhc_softc *);
  24. +#endif
  25. +
  26. static device_method_t fsl_sdhc_methods[] = {
  27. /* device_if */
  28. DEVMETHOD(device_probe, fsl_sdhc_probe),
  29. @@ -119,14 +126,14 @@
  30.  
  31. /* kobj_class definition */
  32. static driver_t fsl_sdhc_driver = {
  33. - "sdhci",
  34. + "sdhci_imx",
  35. fsl_sdhc_methods,
  36. sizeof(struct fsl_sdhc_softc)
  37. };
  38.  
  39. static devclass_t fsl_sdhc_devclass;
  40.  
  41. -DRIVER_MODULE(sdhci, simplebus, fsl_sdhc_driver, fsl_sdhc_devclass, 0, 0);
  42. +DRIVER_MODULE(sdhci_imx, simplebus, fsl_sdhc_driver, fsl_sdhc_devclass, 0, 0);
  43.  
  44.  
  45. /*****************************************************************************
  46. @@ -210,6 +217,7 @@
  47.  
  48. self = sc->self;
  49. node = ofw_bus_get_node(self);
  50. + clock = 0;
  51.  
  52. /* Get sdhci node properties */
  53. if((OF_getprop(node, "clock-frequency", (void *)&clock,
  54. @@ -232,7 +240,9 @@
  55. }
  56. }
  57.  
  58. - DPRINTF("Acquired clock: %d from DTS\n", clock);
  59. + //clock *= 14; /* XXX: Fix FDT better */
  60. + clock = 216000000;
  61. + DPRINTF("Acquired clock: %u from DTS\n", clock);
  62.  
  63. return (clock);
  64. }
  65. @@ -253,8 +263,14 @@
  66. return;
  67.  
  68. if (clock == 0) {
  69. - clear_bit(sc, SDHC_SYSCTL, MASK_CLOCK_CONTROL | SYSCTL_PEREN |
  70. - SYSCTL_HCKEN | SYSCTL_IPGEN);
  71. + if (sc->mode == FSL_SDHC_MODE_MPC)
  72. + clear_bit(sc, SDHC_SYSCTL, MASK_CLOCK_CONTROL |
  73. + SYSCTL_PEREN | SYSCTL_HCKEN | SYSCTL_IPGEN);
  74. + else if (sc->mode == FSL_SDHC_MODE_IMX)
  75. + clear_bit(sc, SDHC_SYSCTL, MASK_CLOCK_CONTROL |
  76. + SYSCTL_SDCLKEN | SYSCTL_PEREN | SYSCTL_HCKEN |
  77. + SYSCTL_IPGEN);
  78. + /* else undefined mode */
  79. return;
  80. }
  81.  
  82. @@ -296,7 +312,12 @@
  83. * it prevents controller from generating card insertion/removal
  84. * interrupts correctly.
  85. */
  86. - set_bit(sc, SDHC_SYSCTL, SYSCTL_PEREN | SYSCTL_HCKEN | SYSCTL_IPGEN);
  87. + if (sc->mode == FSL_SDHC_MODE_MPC)
  88. + set_bit(sc, SDHC_SYSCTL, SYSCTL_PEREN | SYSCTL_HCKEN |
  89. + SYSCTL_IPGEN);
  90. + else if (sc->mode == FSL_SDHC_MODE_IMX)
  91. + set_bit(sc, SDHC_SYSCTL, SYSCTL_SDCLKEN | SYSCTL_PEREN |
  92. + SYSCTL_HCKEN | SYSCTL_IPGEN);
  93.  
  94. sc->slot.clock = clock;
  95.  
  96. @@ -388,7 +409,8 @@
  97. write4(sc, SDHC_DSADDR, sc->dma_phys);
  98.  
  99. /* Enable snooping and fix for AHB2MAG bypass. */
  100. - write4(sc, SDHC_DCR, DCR_SNOOP | DCR_AHB2MAG_BYPASS);
  101. + if (sc->mode == FSL_SDHC_MODE_MPC)
  102. + write4(sc, SDHC_DCR, DCR_SNOOP | DCR_AHB2MAG_BYPASS);
  103. #endif
  104. /* Set data timeout. */
  105. set_bit(sc, SDHC_SYSCTL, 0xe << SHIFT_DTOCV);
  106. @@ -413,13 +435,26 @@
  107. /* Set operation conditions (voltage). */
  108. host->host_ocr = MMC_OCR_320_330 | MMC_OCR_330_340;
  109.  
  110. + host->host_ocr |= MMC_OCR_290_300 | MMC_OCR_300_310; //
  111. +// host->host_ocr |= MMC_OCR_LOW_VOLTAGE; //
  112. +
  113. /* Set additional host controller capabilities. */
  114. host->caps = MMC_CAP_4_BIT_DATA;
  115. + host->caps |= MMC_CAP_HSPEED; //
  116.  
  117. /* Set mode. */
  118. host->mode = mode_sd;
  119. }
  120.  
  121. +#define GPIO_DATA_REG(_u) (*((volatile uint32_t *)(0xf3f84000 + (0x4000 * (_u)))))
  122. +#define GPIO_DIR_REG(_u) (*((volatile uint32_t *)(0xf3f84004 + (0x4000 * (_u)))))
  123. +
  124. +#define GPIO_GET(_b) (GPIO_DATA_REG((_b) / 32) & (1 << ((_b) % 32)))
  125. +#define GPIO_SET(_b) GPIO_DATA_REG((_b) / 32) = GPIO_DATA_REG((_b) / 32) | (1 << ((_b) % 32))
  126. +#define GPIO_CLEAR(_b) GPIO_DATA_REG((_b) / 32) = GPIO_DATA_REG((_b) / 32) & ~(1 << ((_b) % 32))
  127. +#define GPIO_OUT(_b) GPIO_DIR_REG((_b) / 32) = GPIO_DIR_REG((_b) / 32) | (1 << ((_b) % 32))
  128. +#define GPIO_IN(_b) GPIO_DIR_REG((_b) / 32) = GPIO_DIR_REG((_b) / 32) & ~(1 << ((_b) % 32))
  129. +
  130. static void
  131. card_detect_task(void *arg, int pending)
  132. {
  133. @@ -427,7 +462,11 @@
  134. int err;
  135. int insert;
  136.  
  137. +#ifdef GPIO_CD
  138. + insert = GPIO_GET(0)?0:1;
  139. +#else
  140. insert = read4(sc, SDHC_PRSSTAT) & PRSSTAT_CINS;
  141. +#endif
  142.  
  143. mtx_lock(&sc->mtx);
  144.  
  145. @@ -480,10 +519,40 @@
  146. }
  147.  
  148. static void
  149. +transfer_timeout_task(void *arg, int pending)
  150. +{
  151. + struct fsl_sdhc_softc *sc = (struct fsl_sdhc_softc *)arg;
  152. +
  153. + sc->request->cmd->error = MMC_ERR_TIMEOUT;
  154. + sc->command_done = 1;
  155. + sc->data_done = 1;
  156. + dump_registers(sc);
  157. + set_clock(sc, 0);
  158. + reset_controller_dat_cmd(sc);
  159. + set_clock(sc, sc->slot.clock);
  160. + init_controller(sc);
  161. + dump_registers(sc);
  162. +
  163. + mtx_lock(&sc->mtx);
  164. + if (callout_active(&sc->transfer_timeout_callout))
  165. + callout_stop(&sc->transfer_timeout_callout);
  166. + mtx_unlock(&sc->mtx);
  167. +}
  168. +
  169. +static void
  170. +transfer_timeout(void *arg)
  171. +{
  172. + struct fsl_sdhc_softc *sc = arg;
  173. +
  174. + taskqueue_enqueue(taskqueue_swi_giant, &sc->transfer_timeout_task);
  175. + device_printf(sc->self, "Transfer timeout, reseting controller");
  176. +}
  177. +
  178. +static void
  179. finalize_request(struct fsl_sdhc_softc *sc)
  180. {
  181.  
  182. - DPRINTF("finishing request %x\n", sc->request);
  183. + DPRINTF("finishing request %x\n", (uint32_t)sc->request);
  184.  
  185. sc->request->done(sc->request);
  186. sc->request = NULL;
  187. @@ -623,7 +692,8 @@
  188. }
  189.  
  190. if (cmd->error) {
  191. - device_printf(sc->self, "Error interrupt occured\n");
  192. + device_printf(sc->self, "Error interrupt occured, "
  193. + "irq = 0x%08x\n", irq_stat);
  194. reset_controller_dat_cmd(sc);
  195. return;
  196. }
  197. @@ -642,8 +712,9 @@
  198. static inline void
  199. handle_data_intr(struct fsl_sdhc_softc *sc, uint32_t irq_stat)
  200. {
  201. - struct mmc_command *cmd = sc->request->cmd;
  202. + struct mmc_command *cmd;
  203.  
  204. + cmd = sc->request->cmd;
  205. /* Handle errors. */
  206. if (irq_stat & IRQ_DTOE) {
  207. cmd->error = MMC_ERR_TIMEOUT;
  208. @@ -660,8 +731,10 @@
  209. return;
  210. }
  211.  
  212. - if (sc->data_done)
  213. + if (sc->data_done) {
  214. + printf(" [TC/DINT] w/ data_done] ");
  215. return;
  216. + }
  217.  
  218. #ifdef FSL_SDHC_NO_DMA
  219. if (irq_stat & IRQ_BRR) {
  220. @@ -671,30 +744,11 @@
  221. if (irq_stat & IRQ_BWR) {
  222. pio_write_transfer(sc);
  223. }
  224. -#else
  225. - if (irq_stat & IRQ_DINT) {
  226. - struct mmc_data *data = sc->request->cmd->data;
  227. -
  228. - /* Synchronize DMA. */
  229. - if (data->flags & MMC_DATA_READ) {
  230. - bus_dmamap_sync(sc->dma_tag, sc->dma_map,
  231. - BUS_DMASYNC_POSTREAD);
  232. - memcpy(data->data, sc->dma_mem, data->len);
  233. - } else {
  234. - bus_dmamap_sync(sc->dma_tag, sc->dma_map,
  235. - BUS_DMASYNC_POSTWRITE);
  236. - }
  237. -
  238. - /*
  239. - * TODO: For multiple block transfers, address of dma memory
  240. - * in DSADDR register should be set to the beginning of the
  241. - * segment here. Also offset to data pointer should be handled.
  242. - */
  243. - }
  244. #endif
  245.  
  246. - if (irq_stat & IRQ_TC)
  247. + if (irq_stat & IRQ_TC) {
  248. sc->data_done = 1;
  249. + }
  250. }
  251.  
  252. static void
  253. @@ -737,8 +791,10 @@
  254.  
  255. /* Handle request interrupts. */
  256. if (sc->request) {
  257. - handle_command_intr(sc, irq_stat);
  258. - handle_data_intr(sc, irq_stat);
  259. + if (irq_stat & IRQ_CMD_MASK)
  260. + handle_command_intr(sc, irq_stat);
  261. + if (irq_stat & IRQ_DATA_MASK)
  262. + handle_data_intr(sc, irq_stat);
  263.  
  264. /*
  265. * Finalize request when transfer is done successfully
  266. @@ -746,6 +802,8 @@
  267. */
  268. if ((sc->data_done && sc->command_done) ||
  269. (sc->request->cmd->error))
  270. + if (callout_active(&sc->transfer_timeout_callout))
  271. + callout_stop(&sc->transfer_timeout_callout);
  272. finalize_request(sc);
  273. }
  274.  
  275. @@ -773,10 +831,11 @@
  276. device_t self = sc->self;
  277. int err;
  278.  
  279. + /* XXX: fix DMA, now we have panic on block size more than 16384 */
  280. err = bus_dma_tag_create(bus_get_dma_tag(self),
  281. FSL_SDHC_DMA_BLOCK_SIZE, 0, BUS_SPACE_MAXADDR_32BIT,
  282. - BUS_SPACE_MAXADDR, NULL, NULL, FSL_SDHC_DMA_BLOCK_SIZE, 1,
  283. - FSL_SDHC_DMA_BLOCK_SIZE, BUS_DMA_ALLOCNOW, NULL, NULL,
  284. + BUS_SPACE_MAXADDR, NULL, NULL, FSL_SDHC_DMA_BLOCK_SIZE*4, 1,
  285. + FSL_SDHC_DMA_BLOCK_SIZE*4, BUS_DMA_ALLOCNOW, NULL, NULL,
  286. &sc->dma_tag);
  287.  
  288. if (err) {
  289. @@ -792,7 +851,7 @@
  290. }
  291.  
  292. err = bus_dmamap_load(sc->dma_tag, sc->dma_map, (void *)sc->dma_mem,
  293. - FSL_SDHC_DMA_BLOCK_SIZE, dma_get_phys_addr, &sc->dma_phys, 0);
  294. + FSL_SDHC_DMA_BLOCK_SIZE*4, dma_get_phys_addr, &sc->dma_phys, 0);
  295. if (err) {
  296. device_printf(self, "Could not load DMA map!\n");
  297. goto fail2;
  298. @@ -824,10 +883,19 @@
  299. /* Set data preset select. */
  300. if (cmd->data) {
  301. xfertyp |= XFERTYP_DPSEL;
  302. + /* Enable Block count */
  303. + xfertyp |= XFERTYP_BCEN;
  304.  
  305. /* Set transfer direction. */
  306. if (cmd->data->flags & MMC_DATA_READ)
  307. xfertyp |= XFERTYP_DTDSEL;
  308. + if (cmd->data->len > 512) {
  309. + /* Enable Multiblock */
  310. + xfertyp |= XFERTYP_MSBSEL;
  311. + /* Enable AC12 (Errata) */
  312. + xfertyp |= XFERTYP_AC12EN;
  313. + }
  314. +
  315. }
  316.  
  317. /* Set command index check. */
  318. @@ -856,20 +924,6 @@
  319. return (xfertyp);
  320. }
  321.  
  322. -static uint32_t
  323. -set_blkattr_register(const struct mmc_data *data)
  324. -{
  325. -
  326. - if (data->len <= FSL_SDHC_MAX_BLOCK_SIZE) {
  327. - /* One block transfer. */
  328. - return (BLKATTR_BLOCK_COUNT(1) | ((data->len) &
  329. - BLKATTR_BLKSZE));
  330. - }
  331. -
  332. - /* TODO: Write code here for multi-block transfers. */
  333. - return (0);
  334. -}
  335. -
  336. /**
  337. * Initiate data transfer. Interrupt handler will finalize it.
  338. * @todo Implement multi-block transfers.
  339. @@ -879,7 +933,6 @@
  340. static int
  341. start_data(struct fsl_sdhc_softc *sc, struct mmc_data *data)
  342. {
  343. - uint32_t reg;
  344.  
  345. if ((uint32_t)data->data & 0x3) {
  346. device_printf(sc->self, "32-bit unaligned data pointer in "
  347. @@ -901,19 +954,13 @@
  348. bus_dmamap_sync(sc->dma_tag, sc->dma_map,
  349. BUS_DMASYNC_PREREAD);
  350. } else {
  351. - memcpy(sc->dma_mem, data->data, data->len);
  352. + memcpy(sc->dma_mem, data->data, MIN(data->len, 512));
  353. bus_dmamap_sync(sc->dma_tag, sc->dma_map,
  354. BUS_DMASYNC_PREWRITE);
  355. }
  356. #endif
  357. - /* Set block size and count. */
  358. - reg = set_blkattr_register(data);
  359. - if (reg == 0) {
  360. - device_printf(sc->self, "Requested unsupported multi-block "
  361. - "transfer.\n");
  362. - return (-1);
  363. - }
  364. - write4(sc, SDHC_BLKATTR, reg);
  365. + write4(sc, SDHC_BLKATTR, BLKATTR_BLOCK_COUNT((data->len + 511) / 512)|
  366. + MIN(data->len, 512));
  367.  
  368. return (0);
  369. }
  370. @@ -934,7 +981,6 @@
  371. cmd->error = MMC_ERR_NONE;
  372.  
  373. /* TODO: should we check here for card presence and clock settings? */
  374. -
  375. /* Always wait for free CMD line. */
  376. mask = SDHC_CMD_LINE;
  377. /* Wait for free DAT if we have data or busy signal. */
  378. @@ -984,7 +1030,10 @@
  379. {
  380. printf("PRSSTAT = 0x%08x\n", read4(sc, SDHC_PRSSTAT));
  381. printf("PROCTL = 0x%08x\n", read4(sc, SDHC_PROCTL));
  382. - printf("PMUXCR = 0x%08x\n", ccsr_read4(OCP85XX_PMUXCR));
  383. +#if 0 /* Where OCP85XX_PMUXCR is defined? */
  384. + if (sc->mode == FSL_SDHC_MODE_MPC)
  385. + printf("PMUXCR = 0x%08x\n", ccsr_read4(OCP85XX_PMUXCR));
  386. +#endif
  387. printf("HOSTCAPBLT = 0x%08x\n", read4(sc, SDHC_HOSTCAPBLT));
  388. printf("IRQSTAT = 0x%08x\n", read4(sc, SDHC_IRQSTAT));
  389. printf("IRQSTATEN = 0x%08x\n", read4(sc, SDHC_IRQSTATEN));
  390. @@ -992,8 +1041,12 @@
  391. printf("WML = 0x%08x\n", read4(sc, SDHC_WML));
  392. printf("DSADDR = 0x%08x\n", read4(sc, SDHC_DSADDR));
  393. printf("XFERTYP = 0x%08x\n", read4(sc, SDHC_XFERTYP));
  394. - printf("ECMCR = 0x%08x\n", ccsr_read4(OCP85XX_ECMCR));
  395. - printf("DCR = 0x%08x\n", read4(sc, SDHC_DCR));
  396. + if (sc->mode == FSL_SDHC_MODE_MPC) {
  397. +#if 0 /* Where OCP85XX_ECMCR is defined? */
  398. + printf("ECMCR = 0x%08x\n", ccsr_read4(OCP85XX_ECMCR));
  399. +#endif
  400. + printf("DCR = 0x%08x\n", read4(sc, SDHC_DCR));
  401. + }
  402. }
  403. #endif
  404.  
  405. @@ -1006,11 +1059,19 @@
  406. static int
  407. fsl_sdhc_probe(device_t self)
  408. {
  409. + struct fsl_sdhc_softc *sc;
  410. +
  411. static const char *desc =
  412. "Freescale Enhanced Secure Digital Host Controller";
  413.  
  414. - if (!ofw_bus_is_compatible(self, "fsl,p2020-esdhc") &&
  415. - !ofw_bus_is_compatible(self, "fsl,esdhc"))
  416. + sc = device_get_softc(self);
  417. + if (ofw_bus_is_compatible(self, "fsl,p2020-esdhc") ||
  418. + ofw_bus_is_compatible(self, "fsl,esdhc"))
  419. + sc->mode = FSL_SDHC_MODE_DEFAULT;
  420. + else if (ofw_bus_is_compatible(self, "fsl,imx51-esdhc") ||
  421. + ofw_bus_is_compatible(self, "fsl,imx-esdhc"))
  422. + sc->mode = FSL_SDHC_MODE_IMX;
  423. + else
  424. return (ENXIO);
  425.  
  426. device_set_desc(self, desc);
  427. @@ -1073,6 +1134,9 @@
  428. TASK_INIT(&sc->card_detect_task, 0, card_detect_task, sc);
  429. callout_init(&sc->card_detect_callout, 1);
  430.  
  431. + TASK_INIT(&sc->transfer_timeout_task, 0, transfer_timeout_task, sc);
  432. + callout_init(&sc->transfer_timeout_callout, 1);
  433. +
  434. reset_controller_all(sc);
  435. init_controller(sc);
  436. set_clock(sc, 400000);
  437. @@ -1259,6 +1323,8 @@
  438. mtx_lock(&sc->mtx);
  439.  
  440. sc->request = req;
  441. + callout_reset(&sc->transfer_timeout_callout, hz,
  442. + transfer_timeout, sc);
  443. err = start_command(sc, req->cmd);
  444.  
  445. mtx_unlock(&sc->mtx);
  446. @@ -1272,7 +1338,11 @@
  447. struct fsl_sdhc_softc *sc = device_get_softc(self);
  448.  
  449. /* Wouldn't it be faster using branching (if {}) ?? */
  450. +#ifdef GPIO_CD
  451. + return (GPIO_GET(1)?1:0);
  452. +#else
  453. return (((read4(sc, SDHC_PRSSTAT) & PRSSTAT_WPSPL) >> 19) ^ 0x1);
  454. +#endif
  455. }
  456.  
  457. static int
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement