linux/drivers/mmc/host/sdhci.h

/* SPDX-License-Identifier: GPL-2.0-or-later */
/*
 *  linux/drivers/mmc/host/sdhci.h - Secure Digital Host Controller Interface driver
 *
 * Header file for Host Controller registers and I/O accessors.
 *
 *  Copyright (C) 2005-2008 Pierre Ossman, All Rights Reserved.
 */
#ifndef __SDHCI_HW_H
#define __SDHCI_HW_H

#include <linux/bits.h>
#include <linux/scatterlist.h>
#include <linux/compiler.h>
#include <linux/types.h>
#include <linux/io.h>
#include <linux/leds.h>
#include <linux/interrupt.h>

#include <linux/mmc/host.h>

/*
 * Controller registers
 */

#define SDHCI_DMA_ADDRESS
#define SDHCI_ARGUMENT2
#define SDHCI_32BIT_BLK_CNT

#define SDHCI_BLOCK_SIZE
#define SDHCI_MAKE_BLKSZ(dma, blksz)

#define SDHCI_BLOCK_COUNT

#define SDHCI_ARGUMENT

#define SDHCI_TRANSFER_MODE
#define SDHCI_TRNS_DMA
#define SDHCI_TRNS_BLK_CNT_EN
#define SDHCI_TRNS_AUTO_CMD12
#define SDHCI_TRNS_AUTO_CMD23
#define SDHCI_TRNS_AUTO_SEL
#define SDHCI_TRNS_READ
#define SDHCI_TRNS_MULTI

#define SDHCI_COMMAND
#define SDHCI_CMD_RESP_MASK
#define SDHCI_CMD_CRC
#define SDHCI_CMD_INDEX
#define SDHCI_CMD_DATA
#define SDHCI_CMD_ABORTCMD

#define SDHCI_CMD_RESP_NONE
#define SDHCI_CMD_RESP_LONG
#define SDHCI_CMD_RESP_SHORT
#define SDHCI_CMD_RESP_SHORT_BUSY

#define SDHCI_MAKE_CMD(c, f)
#define SDHCI_GET_CMD(c)

#define SDHCI_RESPONSE

#define SDHCI_BUFFER

#define SDHCI_PRESENT_STATE
#define SDHCI_CMD_INHIBIT
#define SDHCI_DATA_INHIBIT
#define SDHCI_DOING_WRITE
#define SDHCI_DOING_READ
#define SDHCI_SPACE_AVAILABLE
#define SDHCI_DATA_AVAILABLE
#define SDHCI_CARD_PRESENT
#define SDHCI_CARD_PRES_SHIFT
#define SDHCI_CD_STABLE
#define SDHCI_CD_LVL
#define SDHCI_CD_LVL_SHIFT
#define SDHCI_WRITE_PROTECT
#define SDHCI_DATA_LVL_MASK
#define SDHCI_DATA_LVL_SHIFT
#define SDHCI_DATA_0_LVL_MASK
#define SDHCI_CMD_LVL

#define SDHCI_HOST_CONTROL
#define SDHCI_CTRL_LED
#define SDHCI_CTRL_4BITBUS
#define SDHCI_CTRL_HISPD
#define SDHCI_CTRL_DMA_MASK
#define SDHCI_CTRL_SDMA
#define SDHCI_CTRL_ADMA1
#define SDHCI_CTRL_ADMA32
#define SDHCI_CTRL_ADMA64
#define SDHCI_CTRL_ADMA3
#define SDHCI_CTRL_8BITBUS
#define SDHCI_CTRL_CDTEST_INS
#define SDHCI_CTRL_CDTEST_EN

#define SDHCI_POWER_CONTROL
#define SDHCI_POWER_ON
#define SDHCI_POWER_180
#define SDHCI_POWER_300
#define SDHCI_POWER_330
/*
 * VDD2 - UHS2 or PCIe/NVMe
 * VDD2 power on/off and voltage select
 */
#define SDHCI_VDD2_POWER_ON
#define SDHCI_VDD2_POWER_120
#define SDHCI_VDD2_POWER_180

#define SDHCI_BLOCK_GAP_CONTROL

#define SDHCI_WAKE_UP_CONTROL
#define SDHCI_WAKE_ON_INT
#define SDHCI_WAKE_ON_INSERT
#define SDHCI_WAKE_ON_REMOVE

#define SDHCI_CLOCK_CONTROL
#define SDHCI_DIVIDER_SHIFT
#define SDHCI_DIVIDER_HI_SHIFT
#define SDHCI_DIV_MASK
#define SDHCI_DIV_MASK_LEN
#define SDHCI_DIV_HI_MASK
#define SDHCI_PROG_CLOCK_MODE
#define SDHCI_CLOCK_CARD_EN
#define SDHCI_CLOCK_PLL_EN
#define SDHCI_CLOCK_INT_STABLE
#define SDHCI_CLOCK_INT_EN

#define SDHCI_TIMEOUT_CONTROL

#define SDHCI_SOFTWARE_RESET
#define SDHCI_RESET_ALL
#define SDHCI_RESET_CMD
#define SDHCI_RESET_DATA

#define SDHCI_INT_STATUS
#define SDHCI_INT_ENABLE
#define SDHCI_SIGNAL_ENABLE
#define SDHCI_INT_RESPONSE
#define SDHCI_INT_DATA_END
#define SDHCI_INT_BLK_GAP
#define SDHCI_INT_DMA_END
#define SDHCI_INT_SPACE_AVAIL
#define SDHCI_INT_DATA_AVAIL
#define SDHCI_INT_CARD_INSERT
#define SDHCI_INT_CARD_REMOVE
#define SDHCI_INT_CARD_INT
#define SDHCI_INT_RETUNE
#define SDHCI_INT_CQE
#define SDHCI_INT_ERROR
#define SDHCI_INT_TIMEOUT
#define SDHCI_INT_CRC
#define SDHCI_INT_END_BIT
#define SDHCI_INT_INDEX
#define SDHCI_INT_DATA_TIMEOUT
#define SDHCI_INT_DATA_CRC
#define SDHCI_INT_DATA_END_BIT
#define SDHCI_INT_BUS_POWER
#define SDHCI_INT_AUTO_CMD_ERR
#define SDHCI_INT_ADMA_ERROR
#define SDHCI_INT_TUNING_ERROR

#define SDHCI_INT_NORMAL_MASK
#define SDHCI_INT_ERROR_MASK

#define SDHCI_INT_CMD_MASK
#define SDHCI_INT_DATA_MASK
#define SDHCI_INT_ALL_MASK

#define SDHCI_CQE_INT_ERR_MASK

#define SDHCI_CQE_INT_MASK

#define SDHCI_AUTO_CMD_STATUS
#define SDHCI_AUTO_CMD_TIMEOUT
#define SDHCI_AUTO_CMD_CRC
#define SDHCI_AUTO_CMD_END_BIT
#define SDHCI_AUTO_CMD_INDEX

#define SDHCI_HOST_CONTROL2
#define SDHCI_CTRL_UHS_MASK
#define SDHCI_CTRL_UHS_SDR12
#define SDHCI_CTRL_UHS_SDR25
#define SDHCI_CTRL_UHS_SDR50
#define SDHCI_CTRL_UHS_SDR104
#define SDHCI_CTRL_UHS_DDR50
#define SDHCI_CTRL_HS400
#define SDHCI_CTRL_VDD_180
#define SDHCI_CTRL_DRV_TYPE_MASK
#define SDHCI_CTRL_DRV_TYPE_B
#define SDHCI_CTRL_DRV_TYPE_A
#define SDHCI_CTRL_DRV_TYPE_C
#define SDHCI_CTRL_DRV_TYPE_D
#define SDHCI_CTRL_EXEC_TUNING
#define SDHCI_CTRL_TUNED_CLK
#define SDHCI_CMD23_ENABLE
#define SDHCI_CTRL_V4_MODE
#define SDHCI_CTRL_64BIT_ADDR
#define SDHCI_CTRL_PRESET_VAL_ENABLE

#define SDHCI_CAPABILITIES
#define SDHCI_TIMEOUT_CLK_MASK
#define SDHCI_TIMEOUT_CLK_SHIFT
#define SDHCI_TIMEOUT_CLK_UNIT
#define SDHCI_CLOCK_BASE_MASK
#define SDHCI_CLOCK_BASE_SHIFT
#define SDHCI_CLOCK_V3_BASE_MASK
#define SDHCI_MAX_BLOCK_MASK
#define SDHCI_MAX_BLOCK_SHIFT
#define SDHCI_CAN_DO_8BIT
#define SDHCI_CAN_DO_ADMA2
#define SDHCI_CAN_DO_ADMA1
#define SDHCI_CAN_DO_HISPD
#define SDHCI_CAN_DO_SDMA
#define SDHCI_CAN_DO_SUSPEND
#define SDHCI_CAN_VDD_330
#define SDHCI_CAN_VDD_300
#define SDHCI_CAN_VDD_180
#define SDHCI_CAN_64BIT_V4
#define SDHCI_CAN_64BIT

#define SDHCI_CAPABILITIES_1
#define SDHCI_SUPPORT_SDR50
#define SDHCI_SUPPORT_SDR104
#define SDHCI_SUPPORT_DDR50
#define SDHCI_DRIVER_TYPE_A
#define SDHCI_DRIVER_TYPE_C
#define SDHCI_DRIVER_TYPE_D
#define SDHCI_RETUNING_TIMER_COUNT_MASK
#define SDHCI_USE_SDR50_TUNING
#define SDHCI_RETUNING_MODE_MASK
#define SDHCI_CLOCK_MUL_MASK
#define SDHCI_CAN_DO_ADMA3
#define SDHCI_SUPPORT_HS400

#define SDHCI_MAX_CURRENT
#define SDHCI_MAX_CURRENT_LIMIT
#define SDHCI_MAX_CURRENT_330_MASK
#define SDHCI_MAX_CURRENT_300_MASK
#define SDHCI_MAX_CURRENT_180_MASK
#define SDHCI_MAX_CURRENT_MULTIPLIER

/* 4C-4F reserved for more max current */

#define SDHCI_SET_ACMD12_ERROR
#define SDHCI_SET_INT_ERROR

#define SDHCI_ADMA_ERROR

/* 55-57 reserved */

#define SDHCI_ADMA_ADDRESS
#define SDHCI_ADMA_ADDRESS_HI

/* 60-FB reserved */

#define SDHCI_PRESET_FOR_HIGH_SPEED
#define SDHCI_PRESET_FOR_SDR12
#define SDHCI_PRESET_FOR_SDR25
#define SDHCI_PRESET_FOR_SDR50
#define SDHCI_PRESET_FOR_SDR104
#define SDHCI_PRESET_FOR_DDR50
#define SDHCI_PRESET_FOR_HS400
#define SDHCI_PRESET_DRV_MASK
#define SDHCI_PRESET_CLKGEN_SEL
#define SDHCI_PRESET_SDCLK_FREQ_MASK

#define SDHCI_SLOT_INT_STATUS

#define SDHCI_HOST_VERSION
#define SDHCI_VENDOR_VER_MASK
#define SDHCI_VENDOR_VER_SHIFT
#define SDHCI_SPEC_VER_MASK
#define SDHCI_SPEC_VER_SHIFT
#define SDHCI_SPEC_100
#define SDHCI_SPEC_200
#define SDHCI_SPEC_300
#define SDHCI_SPEC_400
#define SDHCI_SPEC_410
#define SDHCI_SPEC_420

/*
 * End of controller registers.
 */

#define SDHCI_MAX_DIV_SPEC_200
#define SDHCI_MAX_DIV_SPEC_300

/*
 * Host SDMA buffer boundary. Valid values from 4K to 512K in powers of 2.
 */
#define SDHCI_DEFAULT_BOUNDARY_SIZE
#define SDHCI_DEFAULT_BOUNDARY_ARG

/* ADMA2 32-bit DMA descriptor size */
#define SDHCI_ADMA2_32_DESC_SZ

/* ADMA2 32-bit descriptor */
struct sdhci_adma2_32_desc {}  __packed __aligned();

/* ADMA2 data alignment */
#define SDHCI_ADMA2_ALIGN
#define SDHCI_ADMA2_MASK

/*
 * ADMA2 descriptor alignment.  Some controllers (e.g. Intel) require 8 byte
 * alignment for the descriptor table even in 32-bit DMA mode.  Memory
 * allocation is at least 8 byte aligned anyway, so just stipulate 8 always.
 */
#define SDHCI_ADMA2_DESC_ALIGN

/*
 * ADMA2 64-bit DMA descriptor size
 * According to SD Host Controller spec v4.10, there are two kinds of
 * descriptors for 64-bit addressing mode: 96-bit Descriptor and 128-bit
 * Descriptor, if Host Version 4 Enable is set in the Host Control 2
 * register, 128-bit Descriptor will be selected.
 */
#define SDHCI_ADMA2_64_DESC_SZ(host)

/*
 * ADMA2 64-bit descriptor. Note 12-byte descriptor can't always be 8-byte
 * aligned.
 */
struct sdhci_adma2_64_desc {}  __packed __aligned();

#define ADMA2_TRAN_VALID
#define ADMA2_NOP_END_VALID
#define ADMA2_END

/*
 * Maximum segments assuming a 512KiB maximum requisition size and a minimum
 * 4KiB page size. Note this also allows enough for multiple descriptors in
 * case of PAGE_SIZE >= 64KiB.
 */
#define SDHCI_MAX_SEGS

/* Allow for a command request and a data request at the same time */
#define SDHCI_MAX_MRQS

/*
 * 48bit command and 136 bit response in 100KHz clock could take upto 2.48ms.
 * However since the start time of the command, the time between
 * command and response, and the time between response and start of data is
 * not known, set the command transfer time to 10ms.
 */
#define MMC_CMD_TRANSFER_TIME

#define sdhci_err_stats_inc(host, err_name)

enum sdhci_cookie {};

struct sdhci_host {};

struct sdhci_ops {};

#ifdef CONFIG_MMC_SDHCI_IO_ACCESSORS

static inline void sdhci_writel(struct sdhci_host *host, u32 val, int reg)
{}

static inline void sdhci_writew(struct sdhci_host *host, u16 val, int reg)
{}

static inline void sdhci_writeb(struct sdhci_host *host, u8 val, int reg)
{}

static inline u32 sdhci_readl(struct sdhci_host *host, int reg)
{}

static inline u16 sdhci_readw(struct sdhci_host *host, int reg)
{}

static inline u8 sdhci_readb(struct sdhci_host *host, int reg)
{}

#else

static inline void sdhci_writel(struct sdhci_host *host, u32 val, int reg)
{
	writel(val, host->ioaddr + reg);
}

static inline void sdhci_writew(struct sdhci_host *host, u16 val, int reg)
{
	writew(val, host->ioaddr + reg);
}

static inline void sdhci_writeb(struct sdhci_host *host, u8 val, int reg)
{
	writeb(val, host->ioaddr + reg);
}

static inline u32 sdhci_readl(struct sdhci_host *host, int reg)
{
	return readl(host->ioaddr + reg);
}

static inline u16 sdhci_readw(struct sdhci_host *host, int reg)
{
	return readw(host->ioaddr + reg);
}

static inline u8 sdhci_readb(struct sdhci_host *host, int reg)
{
	return readb(host->ioaddr + reg);
}

#endif /* CONFIG_MMC_SDHCI_IO_ACCESSORS */

struct sdhci_host *sdhci_alloc_host(struct device *dev, size_t priv_size);
void sdhci_free_host(struct sdhci_host *host);

static inline void *sdhci_priv(struct sdhci_host *host)
{}

void __sdhci_read_caps(struct sdhci_host *host, const u16 *ver,
		       const u32 *caps, const u32 *caps1);
int sdhci_setup_host(struct sdhci_host *host);
void sdhci_cleanup_host(struct sdhci_host *host);
int __sdhci_add_host(struct sdhci_host *host);
int sdhci_add_host(struct sdhci_host *host);
void sdhci_remove_host(struct sdhci_host *host, int dead);

static inline void sdhci_read_caps(struct sdhci_host *host)
{}

u16 sdhci_calc_clk(struct sdhci_host *host, unsigned int clock,
		   unsigned int *actual_clock);
void sdhci_set_clock(struct sdhci_host *host, unsigned int clock);
void sdhci_enable_clk(struct sdhci_host *host, u16 clk);
void sdhci_set_power(struct sdhci_host *host, unsigned char mode,
		     unsigned short vdd);
void sdhci_set_power_and_bus_voltage(struct sdhci_host *host,
				     unsigned char mode,
				     unsigned short vdd);
void sdhci_set_power_noreg(struct sdhci_host *host, unsigned char mode,
			   unsigned short vdd);
int sdhci_get_cd_nogpio(struct mmc_host *mmc);
int sdhci_get_ro(struct mmc_host *mmc);
void sdhci_request(struct mmc_host *mmc, struct mmc_request *mrq);
int sdhci_request_atomic(struct mmc_host *mmc, struct mmc_request *mrq);
void sdhci_set_bus_width(struct sdhci_host *host, int width);
void sdhci_reset(struct sdhci_host *host, u8 mask);
void sdhci_set_uhs_signaling(struct sdhci_host *host, unsigned timing);
int sdhci_execute_tuning(struct mmc_host *mmc, u32 opcode);
int __sdhci_execute_tuning(struct sdhci_host *host, u32 opcode);
void sdhci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios);
int sdhci_start_signal_voltage_switch(struct mmc_host *mmc,
				      struct mmc_ios *ios);
void sdhci_enable_sdio_irq(struct mmc_host *mmc, int enable);
void sdhci_adma_write_desc(struct sdhci_host *host, void **desc,
			   dma_addr_t addr, int len, unsigned int cmd);

#ifdef CONFIG_PM
int sdhci_suspend_host(struct sdhci_host *host);
int sdhci_resume_host(struct sdhci_host *host);
int sdhci_runtime_suspend_host(struct sdhci_host *host);
int sdhci_runtime_resume_host(struct sdhci_host *host, int soft_reset);
#endif

void sdhci_cqe_enable(struct mmc_host *mmc);
void sdhci_cqe_disable(struct mmc_host *mmc, bool recovery);
bool sdhci_cqe_irq(struct sdhci_host *host, u32 intmask, int *cmd_error,
		   int *data_error);

void sdhci_dumpregs(struct sdhci_host *host);
void sdhci_enable_v4_mode(struct sdhci_host *host);

void sdhci_start_tuning(struct sdhci_host *host);
void sdhci_end_tuning(struct sdhci_host *host);
void sdhci_reset_tuning(struct sdhci_host *host);
void sdhci_send_tuning(struct sdhci_host *host, u32 opcode);
void sdhci_abort_tuning(struct sdhci_host *host, u32 opcode);
void sdhci_switch_external_dma(struct sdhci_host *host, bool en);
void sdhci_set_data_timeout_irq(struct sdhci_host *host, bool enable);
void __sdhci_set_timeout(struct sdhci_host *host, struct mmc_command *cmd);

#endif /* __SDHCI_HW_H */