linux/drivers/mmc/host/renesas_sdhi_internal_dmac.c

// SPDX-License-Identifier: GPL-2.0
/*
 * DMA support for Internal DMAC with SDHI SD/SDIO controller
 *
 * Copyright (C) 2016-19 Renesas Electronics Corporation
 * Copyright (C) 2016-17 Horms Solutions, Simon Horman
 * Copyright (C) 2018-19 Sang Engineering, Wolfram Sang
 */

#include <linux/bitops.h>
#include <linux/device.h>
#include <linux/dma-mapping.h>
#include <linux/io-64-nonatomic-hi-lo.h>
#include <linux/mmc/host.h>
#include <linux/mod_devicetable.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/pagemap.h>
#include <linux/platform_data/tmio.h>
#include <linux/platform_device.h>
#include <linux/pm_runtime.h>
#include <linux/scatterlist.h>
#include <linux/sys_soc.h>

#include "renesas_sdhi.h"
#include "tmio_mmc.h"

#define DM_CM_DTRAN_MODE
#define DM_CM_DTRAN_CTRL
#define DM_CM_RST
#define DM_CM_INFO1
#define DM_CM_INFO1_MASK
#define DM_CM_INFO2
#define DM_CM_INFO2_MASK
#define DM_DTRAN_ADDR

/* DM_CM_DTRAN_MODE */
#define DTRAN_MODE_CH_NUM_CH0
#define DTRAN_MODE_CH_NUM_CH1
#define DTRAN_MODE_BUS_WIDTH
#define DTRAN_MODE_ADDR_MODE

/* DM_CM_DTRAN_CTRL */
#define DTRAN_CTRL_DM_START

/* DM_CM_RST */
#define RST_DTRANRST1
#define RST_DTRANRST0
#define RST_RESERVED_BITS

/* DM_CM_INFO1 and DM_CM_INFO1_MASK */
#define INFO1_MASK_CLEAR
#define INFO1_DTRANEND1
#define INFO1_DTRANEND1_OLD
#define INFO1_DTRANEND0

/* DM_CM_INFO2 and DM_CM_INFO2_MASK */
#define INFO2_MASK_CLEAR
#define INFO2_DTRANERR1
#define INFO2_DTRANERR0

enum renesas_sdhi_dma_cookie {};

/*
 * Specification of this driver:
 * - host->chan_{rx,tx} will be used as a flag of enabling/disabling the dma
 * - Since this SDHI DMAC register set has 16 but 32-bit width, we
 *   need a custom accessor.
 */

static unsigned long global_flags;
/*
 * Workaround for avoiding to use RX DMAC by multiple channels. On R-Car M3-W
 * ES1.0, when multiple SDHI channels use RX DMAC simultaneously, sometimes
 * hundreds of data bytes are not stored into the system memory even if the
 * DMAC interrupt happened. So, this driver then uses one RX DMAC channel only.
 */
#define SDHI_INTERNAL_DMAC_RX_IN_USE

/* Definitions for sampling clocks */
static struct renesas_sdhi_scc rcar_gen3_scc_taps[] =;

static const struct renesas_sdhi_of_data of_data_rza2 =;

static const struct renesas_sdhi_of_data of_data_rcar_gen3 =;

static const struct renesas_sdhi_of_data of_data_rcar_gen3_no_sdh_fallback =;

static const u8 r8a7796_es13_calib_table[2][SDHI_CALIB_TABLE_MAX] =;

static const u8 r8a77965_calib_table[2][SDHI_CALIB_TABLE_MAX] =;

static const u8 r8a77990_calib_table[2][SDHI_CALIB_TABLE_MAX] =;

static const struct renesas_sdhi_quirks sdhi_quirks_4tap_nohs400 =;

static const struct renesas_sdhi_quirks sdhi_quirks_4tap_nohs400_one_rx =;

static const struct renesas_sdhi_quirks sdhi_quirks_4tap =;

static const struct renesas_sdhi_quirks sdhi_quirks_nohs400 =;

static const struct renesas_sdhi_quirks sdhi_quirks_fixed_addr =;

static const struct renesas_sdhi_quirks sdhi_quirks_bad_taps1357 =;

static const struct renesas_sdhi_quirks sdhi_quirks_bad_taps2367 =;

static const struct renesas_sdhi_quirks sdhi_quirks_r8a7796_es13 =;

static const struct renesas_sdhi_quirks sdhi_quirks_r8a77965 =;

static const struct renesas_sdhi_quirks sdhi_quirks_r8a77990 =;

static const struct renesas_sdhi_quirks sdhi_quirks_rzg2l =;

/*
 * Note for r8a7796 / r8a774a1: we can't distinguish ES1.1 and 1.2 as of now.
 * So, we want to treat them equally and only have a match for ES1.2 to enforce
 * this if there ever will be a way to distinguish ES1.2.
 */
static const struct soc_device_attribute sdhi_quirks_match[]  =;

static const struct renesas_sdhi_of_data_with_quirks of_r8a7795_compatible =;

static const struct renesas_sdhi_of_data_with_quirks of_r8a77961_compatible =;

static const struct renesas_sdhi_of_data_with_quirks of_r8a77965_compatible =;

static const struct renesas_sdhi_of_data_with_quirks of_r8a77970_compatible =;

static const struct renesas_sdhi_of_data_with_quirks of_r8a77990_compatible =;

static const struct renesas_sdhi_of_data_with_quirks of_rzg2l_compatible =;

static const struct renesas_sdhi_of_data_with_quirks of_rcar_gen3_compatible =;

static const struct renesas_sdhi_of_data_with_quirks of_rcar_gen3_nohs400_compatible =;

static const struct renesas_sdhi_of_data_with_quirks of_rza2_compatible =;

static const struct of_device_id renesas_sdhi_internal_dmac_of_match[] =;
MODULE_DEVICE_TABLE(of, renesas_sdhi_internal_dmac_of_match);

static void
renesas_sdhi_internal_dmac_enable_dma(struct tmio_mmc_host *host, bool enable)
{}

static void
renesas_sdhi_internal_dmac_abort_dma(struct tmio_mmc_host *host)
{}

static bool renesas_sdhi_internal_dmac_dma_irq(struct tmio_mmc_host *host)
{}

static void
renesas_sdhi_internal_dmac_dataend_dma(struct tmio_mmc_host *host)
{}

/*
 * renesas_sdhi_internal_dmac_map() will be called with two different
 * sg pointers in two mmc_data by .pre_req(), but tmio host can have a single
 * sg_ptr only. So, renesas_sdhi_internal_dmac_{un}map() should use a sg
 * pointer in a mmc_data instead of host->sg_ptr.
 */
static void
renesas_sdhi_internal_dmac_unmap(struct tmio_mmc_host *host,
				 struct mmc_data *data,
				 enum renesas_sdhi_dma_cookie cookie)
{}

static bool
renesas_sdhi_internal_dmac_map(struct tmio_mmc_host *host,
			       struct mmc_data *data,
			       enum renesas_sdhi_dma_cookie cookie)
{}

static void
renesas_sdhi_internal_dmac_start_dma(struct tmio_mmc_host *host,
				     struct mmc_data *data)
{}

static void renesas_sdhi_internal_dmac_issue_work_fn(struct work_struct *work)
{}

static bool renesas_sdhi_internal_dmac_complete(struct tmio_mmc_host *host)
{}

static void renesas_sdhi_internal_dmac_complete_work_fn(struct work_struct *work)
{}

static void renesas_sdhi_internal_dmac_end_dma(struct tmio_mmc_host *host)
{}

static void renesas_sdhi_internal_dmac_post_req(struct mmc_host *mmc,
						struct mmc_request *mrq,
						int err)
{}

static void renesas_sdhi_internal_dmac_pre_req(struct mmc_host *mmc,
					       struct mmc_request *mrq)
{}

static void
renesas_sdhi_internal_dmac_request_dma(struct tmio_mmc_host *host,
				       struct tmio_mmc_data *pdata)
{}

static void
renesas_sdhi_internal_dmac_release_dma(struct tmio_mmc_host *host)
{}

static const struct tmio_mmc_dma_ops renesas_sdhi_internal_dmac_dma_ops =;

static int renesas_sdhi_internal_dmac_probe(struct platform_device *pdev)
{}

static const struct dev_pm_ops renesas_sdhi_internal_dmac_dev_pm_ops =;

static struct platform_driver renesas_internal_dmac_sdhi_driver =;

module_platform_driver();

MODULE_DESCRIPTION();
MODULE_AUTHOR();
MODULE_LICENSE();