Lines Matching +full:host +full:- +full:only
1 // SPDX-License-Identifier: GPL-2.0
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
12 #include <linux/dma-mapping.h>
13 #include <linux/io-64-nonatomic-hi-lo.h>
15 #include <linux/mmc/host.h>
61 * - host->chan_{rx,tx} will be used as a flag of enabling/disabling the dma
62 * - Since this SDHI DMAC register set has 16 but 32-bit width, we
69 * On R-Car H3 ES1.* and M3-W ES1.0, when multiple SDHI channels use
72 * So, this driver then uses one RX DMAC channel only.
96 .scc_offset = 0 - 0x1000,
99 /* DMAC can handle 32bit blk count but only 1 segment */
114 /* DMAC can handle 32bit blk count but only 1 segment */
120 { .compatible = "renesas,sdhi-r7s9210", .data = &of_rza2_compatible, },
121 { .compatible = "renesas,sdhi-mmc-r8a77470", .data = &of_rcar_gen3_compatible, },
122 { .compatible = "renesas,sdhi-r8a7795", .data = &of_rcar_gen3_compatible, },
123 { .compatible = "renesas,sdhi-r8a7796", .data = &of_rcar_gen3_compatible, },
124 { .compatible = "renesas,rcar-gen3-sdhi", .data = &of_rcar_gen3_compatible, },
130 renesas_sdhi_internal_dmac_dm_write(struct tmio_mmc_host *host, in renesas_sdhi_internal_dmac_dm_write() argument
133 writeq(val, host->ctl + addr); in renesas_sdhi_internal_dmac_dm_write()
137 renesas_sdhi_internal_dmac_enable_dma(struct tmio_mmc_host *host, bool enable) in renesas_sdhi_internal_dmac_enable_dma() argument
139 struct renesas_sdhi *priv = host_to_priv(host); in renesas_sdhi_internal_dmac_enable_dma()
141 if (!host->chan_tx || !host->chan_rx) in renesas_sdhi_internal_dmac_enable_dma()
145 renesas_sdhi_internal_dmac_dm_write(host, DM_CM_INFO1, in renesas_sdhi_internal_dmac_enable_dma()
148 if (priv->dma_priv.enable) in renesas_sdhi_internal_dmac_enable_dma()
149 priv->dma_priv.enable(host, enable); in renesas_sdhi_internal_dmac_enable_dma()
153 renesas_sdhi_internal_dmac_abort_dma(struct tmio_mmc_host *host) { in renesas_sdhi_internal_dmac_abort_dma() argument
156 renesas_sdhi_internal_dmac_enable_dma(host, false); in renesas_sdhi_internal_dmac_abort_dma()
158 renesas_sdhi_internal_dmac_dm_write(host, DM_CM_RST, in renesas_sdhi_internal_dmac_abort_dma()
160 renesas_sdhi_internal_dmac_dm_write(host, DM_CM_RST, in renesas_sdhi_internal_dmac_abort_dma()
165 renesas_sdhi_internal_dmac_enable_dma(host, true); in renesas_sdhi_internal_dmac_abort_dma()
169 renesas_sdhi_internal_dmac_dataend_dma(struct tmio_mmc_host *host) { in renesas_sdhi_internal_dmac_dataend_dma() argument
170 struct renesas_sdhi *priv = host_to_priv(host); in renesas_sdhi_internal_dmac_dataend_dma()
172 tasklet_schedule(&priv->dma_priv.dma_complete); in renesas_sdhi_internal_dmac_dataend_dma()
176 renesas_sdhi_internal_dmac_start_dma(struct tmio_mmc_host *host, in renesas_sdhi_internal_dmac_start_dma() argument
179 struct scatterlist *sg = host->sg_ptr; in renesas_sdhi_internal_dmac_start_dma()
185 if (!dma_map_sg(&host->pdev->dev, sg, host->sg_len, in renesas_sdhi_internal_dmac_start_dma()
189 /* This DMAC cannot handle if buffer is not 8-bytes alignment */ in renesas_sdhi_internal_dmac_start_dma()
193 if (data->flags & MMC_DATA_READ) { in renesas_sdhi_internal_dmac_start_dma()
202 renesas_sdhi_internal_dmac_enable_dma(host, true); in renesas_sdhi_internal_dmac_start_dma()
205 renesas_sdhi_internal_dmac_dm_write(host, DM_CM_DTRAN_MODE, in renesas_sdhi_internal_dmac_start_dma()
207 renesas_sdhi_internal_dmac_dm_write(host, DM_DTRAN_ADDR, in renesas_sdhi_internal_dmac_start_dma()
210 host->dma_on = true; in renesas_sdhi_internal_dmac_start_dma()
215 dma_unmap_sg(&host->pdev->dev, sg, host->sg_len, mmc_get_dma_dir(data)); in renesas_sdhi_internal_dmac_start_dma()
218 renesas_sdhi_internal_dmac_enable_dma(host, false); in renesas_sdhi_internal_dmac_start_dma()
223 struct tmio_mmc_host *host = (struct tmio_mmc_host *)arg; in renesas_sdhi_internal_dmac_issue_tasklet_fn() local
225 tmio_mmc_enable_mmc_irqs(host, TMIO_STAT_DATAEND); in renesas_sdhi_internal_dmac_issue_tasklet_fn()
228 renesas_sdhi_internal_dmac_dm_write(host, DM_CM_DTRAN_CTRL, in renesas_sdhi_internal_dmac_issue_tasklet_fn()
232 static bool renesas_sdhi_internal_dmac_complete(struct tmio_mmc_host *host) in renesas_sdhi_internal_dmac_complete() argument
236 if (!host->dma_on) in renesas_sdhi_internal_dmac_complete()
239 if (!host->data) in renesas_sdhi_internal_dmac_complete()
242 if (host->data->flags & MMC_DATA_READ) in renesas_sdhi_internal_dmac_complete()
247 renesas_sdhi_internal_dmac_enable_dma(host, false); in renesas_sdhi_internal_dmac_complete()
248 dma_unmap_sg(&host->pdev->dev, host->sg_ptr, host->sg_len, dir); in renesas_sdhi_internal_dmac_complete()
253 host->dma_on = false; in renesas_sdhi_internal_dmac_complete()
260 struct tmio_mmc_host *host = (struct tmio_mmc_host *)arg; in renesas_sdhi_internal_dmac_complete_tasklet_fn() local
262 spin_lock_irq(&host->lock); in renesas_sdhi_internal_dmac_complete_tasklet_fn()
263 if (!renesas_sdhi_internal_dmac_complete(host)) in renesas_sdhi_internal_dmac_complete_tasklet_fn()
266 tmio_mmc_do_data_irq(host); in renesas_sdhi_internal_dmac_complete_tasklet_fn()
268 spin_unlock_irq(&host->lock); in renesas_sdhi_internal_dmac_complete_tasklet_fn()
271 static void renesas_sdhi_internal_dmac_end_dma(struct tmio_mmc_host *host) in renesas_sdhi_internal_dmac_end_dma() argument
273 if (host->data) in renesas_sdhi_internal_dmac_end_dma()
274 renesas_sdhi_internal_dmac_complete(host); in renesas_sdhi_internal_dmac_end_dma()
278 renesas_sdhi_internal_dmac_request_dma(struct tmio_mmc_host *host, in renesas_sdhi_internal_dmac_request_dma() argument
281 struct renesas_sdhi *priv = host_to_priv(host); in renesas_sdhi_internal_dmac_request_dma()
284 renesas_sdhi_internal_dmac_dm_write(host, DM_CM_INFO1_MASK, in renesas_sdhi_internal_dmac_request_dma()
286 renesas_sdhi_internal_dmac_dm_write(host, DM_CM_INFO2_MASK, in renesas_sdhi_internal_dmac_request_dma()
289 /* Each value is set to non-zero to assume "enabling" each DMA */ in renesas_sdhi_internal_dmac_request_dma()
290 host->chan_rx = host->chan_tx = (void *)0xdeadbeaf; in renesas_sdhi_internal_dmac_request_dma()
292 tasklet_init(&priv->dma_priv.dma_complete, in renesas_sdhi_internal_dmac_request_dma()
294 (unsigned long)host); in renesas_sdhi_internal_dmac_request_dma()
295 tasklet_init(&host->dma_issue, in renesas_sdhi_internal_dmac_request_dma()
297 (unsigned long)host); in renesas_sdhi_internal_dmac_request_dma()
301 renesas_sdhi_internal_dmac_release_dma(struct tmio_mmc_host *host) in renesas_sdhi_internal_dmac_release_dma() argument
304 host->chan_rx = host->chan_tx = NULL; in renesas_sdhi_internal_dmac_release_dma()
318 * Whitelist of specific R-Car Gen3 SoC ES versions to use this DMAC
334 struct device *dev = &pdev->dev; in renesas_sdhi_internal_dmac_probe()
337 global_flags |= (unsigned long)soc->data; in renesas_sdhi_internal_dmac_probe()