renesas_sdhi_internal_dmac.c 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623
  1. // SPDX-License-Identifier: GPL-2.0
  2. /*
  3. * DMA support for Internal DMAC with SDHI SD/SDIO controller
  4. *
  5. * Copyright (C) 2016-19 Renesas Electronics Corporation
  6. * Copyright (C) 2016-17 Horms Solutions, Simon Horman
  7. * Copyright (C) 2018-19 Sang Engineering, Wolfram Sang
  8. */
  9. #include <linux/bitops.h>
  10. #include <linux/device.h>
  11. #include <linux/dma-mapping.h>
  12. #include <linux/io-64-nonatomic-hi-lo.h>
  13. #include <linux/mmc/host.h>
  14. #include <linux/mod_devicetable.h>
  15. #include <linux/module.h>
  16. #include <linux/of.h>
  17. #include <linux/pagemap.h>
  18. #include <linux/platform_data/tmio.h>
  19. #include <linux/platform_device.h>
  20. #include <linux/scatterlist.h>
  21. #include <linux/sys_soc.h>
  22. #include "renesas_sdhi.h"
  23. #include "tmio_mmc.h"
  24. #define DM_CM_DTRAN_MODE 0x820
  25. #define DM_CM_DTRAN_CTRL 0x828
  26. #define DM_CM_RST 0x830
  27. #define DM_CM_INFO1 0x840
  28. #define DM_CM_INFO1_MASK 0x848
  29. #define DM_CM_INFO2 0x850
  30. #define DM_CM_INFO2_MASK 0x858
  31. #define DM_DTRAN_ADDR 0x880
  32. /* DM_CM_DTRAN_MODE */
  33. #define DTRAN_MODE_CH_NUM_CH0 0 /* "downstream" = for write commands */
  34. #define DTRAN_MODE_CH_NUM_CH1 BIT(16) /* "upstream" = for read commands */
  35. #define DTRAN_MODE_BUS_WIDTH (BIT(5) | BIT(4))
  36. #define DTRAN_MODE_ADDR_MODE BIT(0) /* 1 = Increment address, 0 = Fixed */
  37. /* DM_CM_DTRAN_CTRL */
  38. #define DTRAN_CTRL_DM_START BIT(0)
  39. /* DM_CM_RST */
  40. #define RST_DTRANRST1 BIT(9)
  41. #define RST_DTRANRST0 BIT(8)
  42. #define RST_RESERVED_BITS GENMASK_ULL(31, 0)
  43. /* DM_CM_INFO1 and DM_CM_INFO1_MASK */
  44. #define INFO1_MASK_CLEAR GENMASK_ULL(31, 0)
  45. #define INFO1_DTRANEND1 BIT(20)
  46. #define INFO1_DTRANEND1_OLD BIT(17)
  47. #define INFO1_DTRANEND0 BIT(16)
  48. /* DM_CM_INFO2 and DM_CM_INFO2_MASK */
  49. #define INFO2_MASK_CLEAR GENMASK_ULL(31, 0)
  50. #define INFO2_DTRANERR1 BIT(17)
  51. #define INFO2_DTRANERR0 BIT(16)
  52. enum renesas_sdhi_dma_cookie {
  53. COOKIE_UNMAPPED,
  54. COOKIE_PRE_MAPPED,
  55. COOKIE_MAPPED,
  56. };
  57. /*
  58. * Specification of this driver:
  59. * - host->chan_{rx,tx} will be used as a flag of enabling/disabling the dma
  60. * - Since this SDHI DMAC register set has 16 but 32-bit width, we
  61. * need a custom accessor.
  62. */
  63. static unsigned long global_flags;
  64. /*
  65. * Workaround for avoiding to use RX DMAC by multiple channels. On R-Car M3-W
  66. * ES1.0, when multiple SDHI channels use RX DMAC simultaneously, sometimes
  67. * hundreds of data bytes are not stored into the system memory even if the
  68. * DMAC interrupt happened. So, this driver then uses one RX DMAC channel only.
  69. */
  70. #define SDHI_INTERNAL_DMAC_RX_IN_USE 0
  71. /* Definitions for sampling clocks */
  72. static struct renesas_sdhi_scc rcar_gen3_scc_taps[] = {
  73. {
  74. .clk_rate = 0,
  75. .tap = 0x00000300,
  76. .tap_hs400_4tap = 0x00000100,
  77. },
  78. };
  79. static const struct renesas_sdhi_of_data of_data_rza2 = {
  80. .tmio_flags = TMIO_MMC_HAS_IDLE_WAIT | TMIO_MMC_CLK_ACTUAL |
  81. TMIO_MMC_HAVE_CBSY,
  82. .tmio_ocr_mask = MMC_VDD_32_33,
  83. .capabilities = MMC_CAP_SD_HIGHSPEED | MMC_CAP_SDIO_IRQ |
  84. MMC_CAP_CMD23 | MMC_CAP_WAIT_WHILE_BUSY,
  85. .bus_shift = 2,
  86. .scc_offset = 0 - 0x1000,
  87. .taps = rcar_gen3_scc_taps,
  88. .taps_num = ARRAY_SIZE(rcar_gen3_scc_taps),
  89. /* DMAC can handle 32bit blk count but only 1 segment */
  90. .max_blk_count = UINT_MAX / TMIO_MAX_BLK_SIZE,
  91. .max_segs = 1,
  92. };
  93. static const struct renesas_sdhi_of_data of_data_rcar_gen3 = {
  94. .tmio_flags = TMIO_MMC_HAS_IDLE_WAIT | TMIO_MMC_CLK_ACTUAL |
  95. TMIO_MMC_HAVE_CBSY | TMIO_MMC_MIN_RCAR2 |
  96. TMIO_MMC_64BIT_DATA_PORT,
  97. .capabilities = MMC_CAP_SD_HIGHSPEED | MMC_CAP_SDIO_IRQ |
  98. MMC_CAP_CMD23 | MMC_CAP_WAIT_WHILE_BUSY,
  99. .capabilities2 = MMC_CAP2_NO_WRITE_PROTECT | MMC_CAP2_MERGE_CAPABLE,
  100. .bus_shift = 2,
  101. .scc_offset = 0x1000,
  102. .taps = rcar_gen3_scc_taps,
  103. .taps_num = ARRAY_SIZE(rcar_gen3_scc_taps),
  104. /* DMAC can handle 32bit blk count but only 1 segment */
  105. .max_blk_count = UINT_MAX / TMIO_MAX_BLK_SIZE,
  106. .max_segs = 1,
  107. .sdhi_flags = SDHI_FLAG_NEED_CLKH_FALLBACK,
  108. };
  109. static const struct renesas_sdhi_of_data of_data_rcar_gen3_no_sdh_fallback = {
  110. .tmio_flags = TMIO_MMC_HAS_IDLE_WAIT | TMIO_MMC_CLK_ACTUAL |
  111. TMIO_MMC_HAVE_CBSY | TMIO_MMC_MIN_RCAR2 |
  112. TMIO_MMC_64BIT_DATA_PORT,
  113. .capabilities = MMC_CAP_SD_HIGHSPEED | MMC_CAP_SDIO_IRQ |
  114. MMC_CAP_CMD23 | MMC_CAP_WAIT_WHILE_BUSY,
  115. .capabilities2 = MMC_CAP2_NO_WRITE_PROTECT | MMC_CAP2_MERGE_CAPABLE,
  116. .bus_shift = 2,
  117. .scc_offset = 0x1000,
  118. .taps = rcar_gen3_scc_taps,
  119. .taps_num = ARRAY_SIZE(rcar_gen3_scc_taps),
  120. /* DMAC can handle 32bit blk count but only 1 segment */
  121. .max_blk_count = UINT_MAX / TMIO_MAX_BLK_SIZE,
  122. .max_segs = 1,
  123. };
  124. static const u8 r8a7796_es13_calib_table[2][SDHI_CALIB_TABLE_MAX] = {
  125. { 3, 3, 3, 3, 3, 3, 3, 4, 4, 5, 6, 7, 8, 9, 10, 15,
  126. 16, 16, 16, 16, 16, 16, 17, 18, 18, 19, 20, 21, 22, 23, 24, 25 },
  127. { 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 7, 8, 11,
  128. 12, 17, 18, 18, 18, 18, 18, 18, 18, 19, 20, 21, 22, 23, 25, 25 }
  129. };
  130. static const u8 r8a77965_calib_table[2][SDHI_CALIB_TABLE_MAX] = {
  131. { 1, 2, 6, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 15, 15, 16,
  132. 17, 18, 19, 20, 21, 22, 23, 24, 25, 25, 26, 27, 28, 29, 30, 31 },
  133. { 2, 3, 4, 4, 5, 6, 7, 9, 10, 11, 12, 13, 14, 15, 16, 17,
  134. 17, 17, 20, 21, 22, 23, 24, 25, 27, 28, 29, 30, 31, 31, 31, 31 }
  135. };
  136. static const u8 r8a77990_calib_table[2][SDHI_CALIB_TABLE_MAX] = {
  137. { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  138. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
  139. { 0, 0, 0, 1, 2, 3, 3, 4, 4, 4, 5, 5, 6, 8, 9, 10,
  140. 11, 12, 13, 15, 16, 17, 17, 18, 18, 19, 20, 22, 24, 25, 26, 26 }
  141. };
  142. static const struct renesas_sdhi_quirks sdhi_quirks_4tap_nohs400 = {
  143. .hs400_disabled = true,
  144. .hs400_4taps = true,
  145. };
  146. static const struct renesas_sdhi_quirks sdhi_quirks_4tap_nohs400_one_rx = {
  147. .hs400_disabled = true,
  148. .hs400_4taps = true,
  149. .dma_one_rx_only = true,
  150. .old_info1_layout = true,
  151. };
  152. static const struct renesas_sdhi_quirks sdhi_quirks_4tap = {
  153. .hs400_4taps = true,
  154. .hs400_bad_taps = BIT(2) | BIT(3) | BIT(6) | BIT(7),
  155. .manual_tap_correction = true,
  156. };
  157. static const struct renesas_sdhi_quirks sdhi_quirks_nohs400 = {
  158. .hs400_disabled = true,
  159. };
  160. static const struct renesas_sdhi_quirks sdhi_quirks_fixed_addr = {
  161. .fixed_addr_mode = true,
  162. };
  163. static const struct renesas_sdhi_quirks sdhi_quirks_bad_taps1357 = {
  164. .hs400_bad_taps = BIT(1) | BIT(3) | BIT(5) | BIT(7),
  165. .manual_tap_correction = true,
  166. };
  167. static const struct renesas_sdhi_quirks sdhi_quirks_bad_taps2367 = {
  168. .hs400_bad_taps = BIT(2) | BIT(3) | BIT(6) | BIT(7),
  169. .manual_tap_correction = true,
  170. };
  171. static const struct renesas_sdhi_quirks sdhi_quirks_r8a7796_es13 = {
  172. .hs400_4taps = true,
  173. .hs400_bad_taps = BIT(2) | BIT(3) | BIT(6) | BIT(7),
  174. .hs400_calib_table = r8a7796_es13_calib_table,
  175. .manual_tap_correction = true,
  176. };
  177. static const struct renesas_sdhi_quirks sdhi_quirks_r8a77965 = {
  178. .hs400_bad_taps = BIT(2) | BIT(3) | BIT(6) | BIT(7),
  179. .hs400_calib_table = r8a77965_calib_table,
  180. .manual_tap_correction = true,
  181. };
  182. static const struct renesas_sdhi_quirks sdhi_quirks_r8a77990 = {
  183. .hs400_calib_table = r8a77990_calib_table,
  184. .manual_tap_correction = true,
  185. };
  186. static const struct renesas_sdhi_quirks sdhi_quirks_rzg2l = {
  187. .fixed_addr_mode = true,
  188. .hs400_disabled = true,
  189. };
  190. /*
  191. * Note for r8a7796 / r8a774a1: we can't distinguish ES1.1 and 1.2 as of now.
  192. * So, we want to treat them equally and only have a match for ES1.2 to enforce
  193. * this if there ever will be a way to distinguish ES1.2.
  194. */
  195. static const struct soc_device_attribute sdhi_quirks_match[] = {
  196. { .soc_id = "r8a774a1", .revision = "ES1.[012]", .data = &sdhi_quirks_4tap_nohs400 },
  197. { .soc_id = "r8a7795", .revision = "ES2.0", .data = &sdhi_quirks_4tap },
  198. { .soc_id = "r8a7796", .revision = "ES1.0", .data = &sdhi_quirks_4tap_nohs400_one_rx },
  199. { .soc_id = "r8a7796", .revision = "ES1.[12]", .data = &sdhi_quirks_4tap_nohs400 },
  200. { .soc_id = "r8a7796", .revision = "ES1.*", .data = &sdhi_quirks_r8a7796_es13 },
  201. { .soc_id = "r8a77980", .revision = "ES1.*", .data = &sdhi_quirks_nohs400 },
  202. { /* Sentinel. */ }
  203. };
  204. static const struct renesas_sdhi_of_data_with_quirks of_r8a7795_compatible = {
  205. .of_data = &of_data_rcar_gen3,
  206. .quirks = &sdhi_quirks_bad_taps2367,
  207. };
  208. static const struct renesas_sdhi_of_data_with_quirks of_r8a77961_compatible = {
  209. .of_data = &of_data_rcar_gen3,
  210. .quirks = &sdhi_quirks_bad_taps1357,
  211. };
  212. static const struct renesas_sdhi_of_data_with_quirks of_r8a77965_compatible = {
  213. .of_data = &of_data_rcar_gen3,
  214. .quirks = &sdhi_quirks_r8a77965,
  215. };
  216. static const struct renesas_sdhi_of_data_with_quirks of_r8a77970_compatible = {
  217. .of_data = &of_data_rcar_gen3_no_sdh_fallback,
  218. .quirks = &sdhi_quirks_nohs400,
  219. };
  220. static const struct renesas_sdhi_of_data_with_quirks of_r8a77990_compatible = {
  221. .of_data = &of_data_rcar_gen3,
  222. .quirks = &sdhi_quirks_r8a77990,
  223. };
  224. static const struct renesas_sdhi_of_data_with_quirks of_rzg2l_compatible = {
  225. .of_data = &of_data_rcar_gen3,
  226. .quirks = &sdhi_quirks_rzg2l,
  227. };
  228. static const struct renesas_sdhi_of_data_with_quirks of_rcar_gen3_compatible = {
  229. .of_data = &of_data_rcar_gen3,
  230. };
  231. static const struct renesas_sdhi_of_data_with_quirks of_rcar_gen3_nohs400_compatible = {
  232. .of_data = &of_data_rcar_gen3,
  233. .quirks = &sdhi_quirks_nohs400,
  234. };
  235. static const struct renesas_sdhi_of_data_with_quirks of_rza2_compatible = {
  236. .of_data = &of_data_rza2,
  237. .quirks = &sdhi_quirks_fixed_addr,
  238. };
  239. static const struct of_device_id renesas_sdhi_internal_dmac_of_match[] = {
  240. { .compatible = "renesas,sdhi-r7s9210", .data = &of_rza2_compatible, },
  241. { .compatible = "renesas,sdhi-mmc-r8a77470", .data = &of_rcar_gen3_compatible, },
  242. { .compatible = "renesas,sdhi-r8a7795", .data = &of_r8a7795_compatible, },
  243. { .compatible = "renesas,sdhi-r8a77961", .data = &of_r8a77961_compatible, },
  244. { .compatible = "renesas,sdhi-r8a77965", .data = &of_r8a77965_compatible, },
  245. { .compatible = "renesas,sdhi-r8a77970", .data = &of_r8a77970_compatible, },
  246. { .compatible = "renesas,sdhi-r8a77990", .data = &of_r8a77990_compatible, },
  247. { .compatible = "renesas,sdhi-r8a77995", .data = &of_rcar_gen3_nohs400_compatible, },
  248. { .compatible = "renesas,sdhi-r9a09g011", .data = &of_rzg2l_compatible, },
  249. { .compatible = "renesas,sdhi-r9a09g057", .data = &of_rzg2l_compatible, },
  250. { .compatible = "renesas,rzg2l-sdhi", .data = &of_rzg2l_compatible, },
  251. { .compatible = "renesas,rcar-gen3-sdhi", .data = &of_rcar_gen3_compatible, },
  252. { .compatible = "renesas,rcar-gen4-sdhi", .data = &of_rcar_gen3_compatible, },
  253. {},
  254. };
  255. MODULE_DEVICE_TABLE(of, renesas_sdhi_internal_dmac_of_match);
  256. static void
  257. renesas_sdhi_internal_dmac_enable_dma(struct tmio_mmc_host *host, bool enable)
  258. {
  259. struct renesas_sdhi *priv = host_to_priv(host);
  260. u32 dma_irqs = INFO1_DTRANEND0 |
  261. (sdhi_has_quirk(priv, old_info1_layout) ?
  262. INFO1_DTRANEND1_OLD : INFO1_DTRANEND1);
  263. if (!host->chan_tx || !host->chan_rx)
  264. return;
  265. writel(enable ? ~dma_irqs : INFO1_MASK_CLEAR, host->ctl + DM_CM_INFO1_MASK);
  266. if (priv->dma_priv.enable)
  267. priv->dma_priv.enable(host, enable);
  268. }
  269. static void
  270. renesas_sdhi_internal_dmac_abort_dma(struct tmio_mmc_host *host)
  271. {
  272. u64 val = RST_DTRANRST1 | RST_DTRANRST0;
  273. renesas_sdhi_internal_dmac_enable_dma(host, false);
  274. writel(RST_RESERVED_BITS & ~val, host->ctl + DM_CM_RST);
  275. writel(RST_RESERVED_BITS | val, host->ctl + DM_CM_RST);
  276. clear_bit(SDHI_INTERNAL_DMAC_RX_IN_USE, &global_flags);
  277. renesas_sdhi_internal_dmac_enable_dma(host, true);
  278. }
  279. static bool renesas_sdhi_internal_dmac_dma_irq(struct tmio_mmc_host *host)
  280. {
  281. struct renesas_sdhi *priv = host_to_priv(host);
  282. struct renesas_sdhi_dma *dma_priv = &priv->dma_priv;
  283. u32 dma_irqs = INFO1_DTRANEND0 |
  284. (sdhi_has_quirk(priv, old_info1_layout) ?
  285. INFO1_DTRANEND1_OLD : INFO1_DTRANEND1);
  286. u32 status = readl(host->ctl + DM_CM_INFO1);
  287. if (status & dma_irqs) {
  288. writel(status ^ dma_irqs, host->ctl + DM_CM_INFO1);
  289. set_bit(SDHI_DMA_END_FLAG_DMA, &dma_priv->end_flags);
  290. if (test_bit(SDHI_DMA_END_FLAG_ACCESS, &dma_priv->end_flags))
  291. queue_work(system_bh_wq, &dma_priv->dma_complete);
  292. }
  293. return status & dma_irqs;
  294. }
  295. static void
  296. renesas_sdhi_internal_dmac_dataend_dma(struct tmio_mmc_host *host)
  297. {
  298. struct renesas_sdhi *priv = host_to_priv(host);
  299. struct renesas_sdhi_dma *dma_priv = &priv->dma_priv;
  300. set_bit(SDHI_DMA_END_FLAG_ACCESS, &dma_priv->end_flags);
  301. if (test_bit(SDHI_DMA_END_FLAG_DMA, &dma_priv->end_flags) ||
  302. host->data->error)
  303. queue_work(system_bh_wq, &dma_priv->dma_complete);
  304. }
  305. /*
  306. * renesas_sdhi_internal_dmac_map() will be called with two different
  307. * sg pointers in two mmc_data by .pre_req(), but tmio host can have a single
  308. * sg_ptr only. So, renesas_sdhi_internal_dmac_{un}map() should use a sg
  309. * pointer in a mmc_data instead of host->sg_ptr.
  310. */
  311. static void
  312. renesas_sdhi_internal_dmac_unmap(struct tmio_mmc_host *host,
  313. struct mmc_data *data,
  314. enum renesas_sdhi_dma_cookie cookie)
  315. {
  316. bool unmap = cookie == COOKIE_UNMAPPED ? (data->host_cookie != cookie) :
  317. (data->host_cookie == cookie);
  318. if (unmap) {
  319. dma_unmap_sg(&host->pdev->dev, data->sg, data->sg_len,
  320. mmc_get_dma_dir(data));
  321. data->host_cookie = COOKIE_UNMAPPED;
  322. }
  323. }
  324. static bool
  325. renesas_sdhi_internal_dmac_map(struct tmio_mmc_host *host,
  326. struct mmc_data *data,
  327. enum renesas_sdhi_dma_cookie cookie)
  328. {
  329. if (data->host_cookie == COOKIE_PRE_MAPPED)
  330. return true;
  331. if (!dma_map_sg(&host->pdev->dev, data->sg, data->sg_len,
  332. mmc_get_dma_dir(data)))
  333. return false;
  334. data->host_cookie = cookie;
  335. /* This DMAC needs buffers to be 128-byte aligned */
  336. if (!IS_ALIGNED(sg_dma_address(data->sg), 128)) {
  337. renesas_sdhi_internal_dmac_unmap(host, data, cookie);
  338. return false;
  339. }
  340. return true;
  341. }
  342. static void
  343. renesas_sdhi_internal_dmac_start_dma(struct tmio_mmc_host *host,
  344. struct mmc_data *data)
  345. {
  346. struct renesas_sdhi *priv = host_to_priv(host);
  347. struct scatterlist *sg = host->sg_ptr;
  348. u32 dtran_mode = DTRAN_MODE_BUS_WIDTH;
  349. if (!sdhi_has_quirk(priv, fixed_addr_mode))
  350. dtran_mode |= DTRAN_MODE_ADDR_MODE;
  351. if (!renesas_sdhi_internal_dmac_map(host, data, COOKIE_MAPPED))
  352. goto force_pio;
  353. if (data->flags & MMC_DATA_READ) {
  354. dtran_mode |= DTRAN_MODE_CH_NUM_CH1;
  355. if (sdhi_has_quirk(priv, dma_one_rx_only) &&
  356. test_and_set_bit(SDHI_INTERNAL_DMAC_RX_IN_USE, &global_flags))
  357. goto force_pio_with_unmap;
  358. } else {
  359. dtran_mode |= DTRAN_MODE_CH_NUM_CH0;
  360. }
  361. priv->dma_priv.end_flags = 0;
  362. renesas_sdhi_internal_dmac_enable_dma(host, true);
  363. /* set dma parameters */
  364. writel(dtran_mode, host->ctl + DM_CM_DTRAN_MODE);
  365. writel(sg_dma_address(sg), host->ctl + DM_DTRAN_ADDR);
  366. host->dma_on = true;
  367. return;
  368. force_pio_with_unmap:
  369. renesas_sdhi_internal_dmac_unmap(host, data, COOKIE_UNMAPPED);
  370. force_pio:
  371. renesas_sdhi_internal_dmac_enable_dma(host, false);
  372. }
  373. static void renesas_sdhi_internal_dmac_issue_work_fn(struct work_struct *work)
  374. {
  375. struct tmio_mmc_host *host = from_work(host, work, dma_issue);
  376. struct renesas_sdhi *priv = host_to_priv(host);
  377. tmio_mmc_enable_mmc_irqs(host, TMIO_STAT_DATAEND);
  378. if (!host->cmd->error) {
  379. /* start the DMAC */
  380. writel(DTRAN_CTRL_DM_START, host->ctl + DM_CM_DTRAN_CTRL);
  381. } else {
  382. /* on CMD errors, simulate DMA end immediately */
  383. set_bit(SDHI_DMA_END_FLAG_DMA, &priv->dma_priv.end_flags);
  384. if (test_bit(SDHI_DMA_END_FLAG_ACCESS, &priv->dma_priv.end_flags))
  385. queue_work(system_bh_wq, &priv->dma_priv.dma_complete);
  386. }
  387. }
  388. static bool renesas_sdhi_internal_dmac_complete(struct tmio_mmc_host *host)
  389. {
  390. enum dma_data_direction dir;
  391. if (!host->dma_on)
  392. return false;
  393. if (!host->data)
  394. return false;
  395. if (host->data->flags & MMC_DATA_READ)
  396. dir = DMA_FROM_DEVICE;
  397. else
  398. dir = DMA_TO_DEVICE;
  399. renesas_sdhi_internal_dmac_enable_dma(host, false);
  400. renesas_sdhi_internal_dmac_unmap(host, host->data, COOKIE_MAPPED);
  401. if (dir == DMA_FROM_DEVICE)
  402. clear_bit(SDHI_INTERNAL_DMAC_RX_IN_USE, &global_flags);
  403. host->dma_on = false;
  404. return true;
  405. }
  406. static void renesas_sdhi_internal_dmac_complete_work_fn(struct work_struct *work)
  407. {
  408. struct renesas_sdhi_dma *dma_priv = from_work(dma_priv, work, dma_complete);
  409. struct renesas_sdhi *priv = container_of(dma_priv, typeof(*priv), dma_priv);
  410. struct tmio_mmc_host *host = priv->host;
  411. spin_lock_irq(&host->lock);
  412. if (!renesas_sdhi_internal_dmac_complete(host))
  413. goto out;
  414. tmio_mmc_do_data_irq(host);
  415. out:
  416. spin_unlock_irq(&host->lock);
  417. }
  418. static void renesas_sdhi_internal_dmac_end_dma(struct tmio_mmc_host *host)
  419. {
  420. if (host->data)
  421. renesas_sdhi_internal_dmac_complete(host);
  422. }
  423. static void renesas_sdhi_internal_dmac_post_req(struct mmc_host *mmc,
  424. struct mmc_request *mrq,
  425. int err)
  426. {
  427. struct tmio_mmc_host *host = mmc_priv(mmc);
  428. struct mmc_data *data = mrq->data;
  429. if (!data)
  430. return;
  431. renesas_sdhi_internal_dmac_unmap(host, data, COOKIE_UNMAPPED);
  432. }
  433. static void renesas_sdhi_internal_dmac_pre_req(struct mmc_host *mmc,
  434. struct mmc_request *mrq)
  435. {
  436. struct tmio_mmc_host *host = mmc_priv(mmc);
  437. struct mmc_data *data = mrq->data;
  438. if (!data)
  439. return;
  440. data->host_cookie = COOKIE_UNMAPPED;
  441. renesas_sdhi_internal_dmac_map(host, data, COOKIE_PRE_MAPPED);
  442. }
  443. static void
  444. renesas_sdhi_internal_dmac_request_dma(struct tmio_mmc_host *host,
  445. struct tmio_mmc_data *pdata)
  446. {
  447. struct renesas_sdhi *priv = host_to_priv(host);
  448. /* Disable DMAC interrupts initially */
  449. writel(INFO1_MASK_CLEAR, host->ctl + DM_CM_INFO1_MASK);
  450. writel(INFO2_MASK_CLEAR, host->ctl + DM_CM_INFO2_MASK);
  451. writel(0, host->ctl + DM_CM_INFO1);
  452. writel(0, host->ctl + DM_CM_INFO2);
  453. /* Each value is set to non-zero to assume "enabling" each DMA */
  454. host->chan_rx = host->chan_tx = (void *)0xdeadbeaf;
  455. INIT_WORK(&priv->dma_priv.dma_complete,
  456. renesas_sdhi_internal_dmac_complete_work_fn);
  457. INIT_WORK(&host->dma_issue,
  458. renesas_sdhi_internal_dmac_issue_work_fn);
  459. /* Add pre_req and post_req */
  460. host->ops.pre_req = renesas_sdhi_internal_dmac_pre_req;
  461. host->ops.post_req = renesas_sdhi_internal_dmac_post_req;
  462. }
  463. static void
  464. renesas_sdhi_internal_dmac_release_dma(struct tmio_mmc_host *host)
  465. {
  466. /* Each value is set to zero to assume "disabling" each DMA */
  467. host->chan_rx = host->chan_tx = NULL;
  468. }
  469. static const struct tmio_mmc_dma_ops renesas_sdhi_internal_dmac_dma_ops = {
  470. .start = renesas_sdhi_internal_dmac_start_dma,
  471. .enable = renesas_sdhi_internal_dmac_enable_dma,
  472. .request = renesas_sdhi_internal_dmac_request_dma,
  473. .release = renesas_sdhi_internal_dmac_release_dma,
  474. .abort = renesas_sdhi_internal_dmac_abort_dma,
  475. .dataend = renesas_sdhi_internal_dmac_dataend_dma,
  476. .end = renesas_sdhi_internal_dmac_end_dma,
  477. .dma_irq = renesas_sdhi_internal_dmac_dma_irq,
  478. };
  479. static int renesas_sdhi_internal_dmac_probe(struct platform_device *pdev)
  480. {
  481. const struct soc_device_attribute *attr;
  482. const struct renesas_sdhi_of_data_with_quirks *of_data_quirks;
  483. const struct renesas_sdhi_quirks *quirks;
  484. struct device *dev = &pdev->dev;
  485. of_data_quirks = of_device_get_match_data(&pdev->dev);
  486. quirks = of_data_quirks->quirks;
  487. attr = soc_device_match(sdhi_quirks_match);
  488. if (attr)
  489. quirks = attr->data;
  490. /* value is max of SD_SECCNT. Confirmed by HW engineers */
  491. dma_set_max_seg_size(dev, 0xffffffff);
  492. return renesas_sdhi_probe(pdev, &renesas_sdhi_internal_dmac_dma_ops,
  493. of_data_quirks->of_data, quirks);
  494. }
  495. static const struct dev_pm_ops renesas_sdhi_internal_dmac_dev_pm_ops = {
  496. SYSTEM_SLEEP_PM_OPS(renesas_sdhi_suspend, renesas_sdhi_resume)
  497. RUNTIME_PM_OPS(tmio_mmc_host_runtime_suspend,
  498. tmio_mmc_host_runtime_resume,
  499. NULL)
  500. };
  501. static struct platform_driver renesas_internal_dmac_sdhi_driver = {
  502. .driver = {
  503. .name = "renesas_sdhi_internal_dmac",
  504. .probe_type = PROBE_PREFER_ASYNCHRONOUS,
  505. .pm = pm_ptr(&renesas_sdhi_internal_dmac_dev_pm_ops),
  506. .of_match_table = renesas_sdhi_internal_dmac_of_match,
  507. },
  508. .probe = renesas_sdhi_internal_dmac_probe,
  509. .remove = renesas_sdhi_remove,
  510. };
  511. module_platform_driver(renesas_internal_dmac_sdhi_driver);
  512. MODULE_DESCRIPTION("Renesas SDHI driver for internal DMAC");
  513. MODULE_AUTHOR("Yoshihiro Shimoda");
  514. MODULE_LICENSE("GPL v2");