cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

renesas_sdhi_internal_dmac.c (18045B)


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