linux/drivers/mmc/host/meson-gx-mmc.c

// SPDX-License-Identifier: GPL-2.0-only
/*
 * Amlogic SD/eMMC driver for the GX/S905 family SoCs
 *
 * Copyright (c) 2016 BayLibre, SAS.
 * Author: Kevin Hilman <[email protected]>
 */
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/delay.h>
#include <linux/device.h>
#include <linux/iopoll.h>
#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/ioport.h>
#include <linux/dma-mapping.h>
#include <linux/mmc/host.h>
#include <linux/mmc/mmc.h>
#include <linux/mmc/sdio.h>
#include <linux/mmc/slot-gpio.h>
#include <linux/io.h>
#include <linux/clk.h>
#include <linux/clk-provider.h>
#include <linux/regulator/consumer.h>
#include <linux/reset.h>
#include <linux/interrupt.h>
#include <linux/bitfield.h>
#include <linux/pinctrl/consumer.h>

#define DRIVER_NAME

#define SD_EMMC_CLOCK
#define CLK_DIV_MASK
#define CLK_SRC_MASK
#define CLK_CORE_PHASE_MASK
#define CLK_TX_PHASE_MASK
#define CLK_RX_PHASE_MASK
#define CLK_PHASE_0
#define CLK_PHASE_180
#define CLK_V2_TX_DELAY_MASK
#define CLK_V2_RX_DELAY_MASK
#define CLK_V2_ALWAYS_ON
#define CLK_V2_IRQ_SDIO_SLEEP

#define CLK_V3_TX_DELAY_MASK
#define CLK_V3_RX_DELAY_MASK
#define CLK_V3_ALWAYS_ON
#define CLK_V3_IRQ_SDIO_SLEEP

#define CLK_TX_DELAY_MASK(h)
#define CLK_RX_DELAY_MASK(h)
#define CLK_ALWAYS_ON(h)
#define CLK_IRQ_SDIO_SLEEP(h)

#define SD_EMMC_DELAY
#define SD_EMMC_ADJUST
#define ADJUST_ADJ_DELAY_MASK
#define ADJUST_DS_EN
#define ADJUST_ADJ_EN

#define SD_EMMC_DELAY1
#define SD_EMMC_DELAY2
#define SD_EMMC_V3_ADJUST

#define SD_EMMC_CALOUT
#define SD_EMMC_START
#define START_DESC_INIT
#define START_DESC_BUSY
#define START_DESC_ADDR_MASK

#define SD_EMMC_CFG
#define CFG_BUS_WIDTH_MASK
#define CFG_BUS_WIDTH_1
#define CFG_BUS_WIDTH_4
#define CFG_BUS_WIDTH_8
#define CFG_DDR
#define CFG_BLK_LEN_MASK
#define CFG_RESP_TIMEOUT_MASK
#define CFG_RC_CC_MASK
#define CFG_STOP_CLOCK
#define CFG_CLK_ALWAYS_ON
#define CFG_CHK_DS
#define CFG_AUTO_CLK
#define CFG_ERR_ABORT

#define SD_EMMC_STATUS
#define STATUS_BUSY
#define STATUS_DESC_BUSY
#define STATUS_DATI

#define SD_EMMC_IRQ_EN
#define IRQ_RXD_ERR_MASK
#define IRQ_TXD_ERR
#define IRQ_DESC_ERR
#define IRQ_RESP_ERR
#define IRQ_CRC_ERR
#define IRQ_RESP_TIMEOUT
#define IRQ_DESC_TIMEOUT
#define IRQ_TIMEOUTS
#define IRQ_END_OF_CHAIN
#define IRQ_RESP_STATUS
#define IRQ_SDIO
#define IRQ_EN_MASK

#define SD_EMMC_CMD_CFG
#define SD_EMMC_CMD_ARG
#define SD_EMMC_CMD_DAT
#define SD_EMMC_CMD_RSP
#define SD_EMMC_CMD_RSP1
#define SD_EMMC_CMD_RSP2
#define SD_EMMC_CMD_RSP3

#define SD_EMMC_RXD
#define SD_EMMC_TXD
#define SD_EMMC_LAST_REG

#define SD_EMMC_SRAM_DATA_BUF_LEN
#define SD_EMMC_SRAM_DATA_BUF_OFF

#define SD_EMMC_CFG_BLK_SIZE
#define SD_EMMC_CFG_RESP_TIMEOUT
#define SD_EMMC_CMD_TIMEOUT
#define SD_EMMC_CMD_TIMEOUT_DATA
#define SD_EMMC_CFG_CMD_GAP
#define SD_EMMC_DESC_BUF_LEN

#define SD_EMMC_PRE_REQ_DONE
#define SD_EMMC_DESC_CHAIN_MODE

#define MUX_CLK_NUM_PARENTS

struct meson_mmc_data {};

struct sd_emmc_desc {};

struct meson_host {};

#define CMD_CFG_LENGTH_MASK
#define CMD_CFG_BLOCK_MODE
#define CMD_CFG_R1B
#define CMD_CFG_END_OF_CHAIN
#define CMD_CFG_TIMEOUT_MASK
#define CMD_CFG_NO_RESP
#define CMD_CFG_NO_CMD
#define CMD_CFG_DATA_IO
#define CMD_CFG_DATA_WR
#define CMD_CFG_RESP_NOCRC
#define CMD_CFG_RESP_128
#define CMD_CFG_RESP_NUM
#define CMD_CFG_DATA_NUM
#define CMD_CFG_CMD_INDEX_MASK
#define CMD_CFG_ERROR
#define CMD_CFG_OWNER

#define CMD_DATA_MASK
#define CMD_DATA_BIG_ENDIAN
#define CMD_DATA_SRAM
#define CMD_RESP_MASK
#define CMD_RESP_SRAM

static unsigned int meson_mmc_get_timeout_msecs(struct mmc_data *data)
{}

static struct mmc_command *meson_mmc_get_next_command(struct mmc_command *cmd)
{}

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

static inline bool meson_mmc_desc_chain_mode(const struct mmc_data *data)
{}

static inline bool meson_mmc_bounce_buf_read(const struct mmc_data *data)
{}

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

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

/*
 * Gating the clock on this controller is tricky.  It seems the mmc clock
 * is also used by the controller.  It may crash during some operation if the
 * clock is stopped.  The safest thing to do, whenever possible, is to keep
 * clock running at stop it at the pad using the pinmux.
 */
static void meson_mmc_clk_gate(struct meson_host *host)
{}

static void meson_mmc_clk_ungate(struct meson_host *host)
{}

static int meson_mmc_clk_set(struct meson_host *host, unsigned long rate,
			     bool ddr)
{}

/*
 * The SD/eMMC IP block has an internal mux and divider used for
 * generating the MMC clock.  Use the clock framework to create and
 * manage these clocks.
 */
static int meson_mmc_clk_init(struct meson_host *host)
{}

static void meson_mmc_disable_resampling(struct meson_host *host)
{}

static void meson_mmc_reset_resampling(struct meson_host *host)
{}

static int meson_mmc_resampling_tuning(struct mmc_host *mmc, u32 opcode)
{}

static int meson_mmc_prepare_ios_clock(struct meson_host *host,
				       struct mmc_ios *ios)
{}

static void meson_mmc_check_resampling(struct meson_host *host,
				       struct mmc_ios *ios)
{}

static void meson_mmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
{}

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

static void meson_mmc_set_blksz(struct mmc_host *mmc, unsigned int blksz)
{}

static void meson_mmc_set_response_bits(struct mmc_command *cmd, u32 *cmd_cfg)
{}

static void meson_mmc_desc_chain_transfer(struct mmc_host *mmc, u32 cmd_cfg)
{}

/* local sg copy for dram_access_quirk */
static void meson_mmc_copy_buffer(struct meson_host *host, struct mmc_data *data,
				  size_t buflen, bool to_buffer)
{}

static void meson_mmc_start_cmd(struct mmc_host *mmc, struct mmc_command *cmd)
{}

static int meson_mmc_validate_dram_access(struct mmc_host *mmc, struct mmc_data *data)
{}

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

static void meson_mmc_read_resp(struct mmc_host *mmc, struct mmc_command *cmd)
{}

static void __meson_mmc_enable_sdio_irq(struct mmc_host *mmc, int enable)
{}

static irqreturn_t meson_mmc_irq(int irq, void *dev_id)
{}

static int meson_mmc_wait_desc_stop(struct meson_host *host)
{}

static irqreturn_t meson_mmc_irq_thread(int irq, void *dev_id)
{}

static void meson_mmc_cfg_init(struct meson_host *host)
{}

static int meson_mmc_card_busy(struct mmc_host *mmc)
{}

static int meson_mmc_voltage_switch(struct mmc_host *mmc, struct mmc_ios *ios)
{}

static void meson_mmc_enable_sdio_irq(struct mmc_host *mmc, int enable)
{}

static void meson_mmc_ack_sdio_irq(struct mmc_host *mmc)
{}

static const struct mmc_host_ops meson_mmc_ops =;

static int meson_mmc_probe(struct platform_device *pdev)
{}

static void meson_mmc_remove(struct platform_device *pdev)
{}

static const struct meson_mmc_data meson_gx_data =;

static const struct meson_mmc_data meson_axg_data =;

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

static struct platform_driver meson_mmc_driver =;

module_platform_driver();

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