drivers/mmc/host/sdhci-of-k1.c

Source file repositories/reference/linux-study-clean/drivers/mmc/host/sdhci-of-k1.c

File Facts

System
Linux kernel
Corpus path
drivers/mmc/host/sdhci-of-k1.c
Extension
.c
Size
17578 bytes
Lines
601
Domain
Driver Families
Bucket
drivers/mmc
Inferred role
Driver Families: implementation source
Status
source implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

struct spacemit_sdhci_host {
	struct clk *clk_core;
	struct clk *clk_io;
	struct pinctrl *pinctrl;
	struct pinctrl_state *pinctrl_default;
	struct pinctrl_state *pinctrl_uhs;
};

/* All helper functions will update clr/set while preserve rest bits */
static inline void spacemit_sdhci_setbits(struct sdhci_host *host, u32 val, int reg)
{
	sdhci_writel(host, sdhci_readl(host, reg) | val, reg);
}

static inline void spacemit_sdhci_clrbits(struct sdhci_host *host, u32 val, int reg)
{
	sdhci_writel(host, sdhci_readl(host, reg) & ~val, reg);
}

static inline void spacemit_sdhci_clrsetbits(struct sdhci_host *host, u32 clr, u32 set, int reg)
{
	u32 val = sdhci_readl(host, reg);

	val = (val & ~clr) | set;
	sdhci_writel(host, val, reg);
}

static void spacemit_sdhci_set_rx_delay(struct sdhci_host *host, u8 delay)
{
	spacemit_sdhci_clrsetbits(host, SDHC_RX_DLINE_CODE_MASK,
				  FIELD_PREP(SDHC_RX_DLINE_CODE_MASK, delay),
				  SPACEMIT_SDHC_DLINE_CTRL_REG);
}

static void spacemit_sdhci_set_tx_delay(struct sdhci_host *host, u8 delay)
{
	spacemit_sdhci_clrsetbits(host, SDHC_TX_DLINE_CODE_MASK,
				  FIELD_PREP(SDHC_TX_DLINE_CODE_MASK, delay),
				  SPACEMIT_SDHC_DLINE_CTRL_REG);
}

static void spacemit_sdhci_set_tx_dline_reg(struct sdhci_host *host, u8 dline_reg)
{
	spacemit_sdhci_clrsetbits(host, SDHC_TX_DLINE_REG_MASK,
				  FIELD_PREP(SDHC_TX_DLINE_REG_MASK, dline_reg),
				  SPACEMIT_SDHC_DLINE_CFG_REG);
}

static void spacemit_sdhci_tx_tuning_prepare(struct sdhci_host *host)
{
	spacemit_sdhci_setbits(host, SDHC_TX_MUX_SEL, SPACEMIT_SDHC_TX_CFG_REG);
	spacemit_sdhci_setbits(host, SDHC_DLINE_PU, SPACEMIT_SDHC_DLINE_CTRL_REG);
	udelay(5);
}

static void spacemit_sdhci_prepare_tuning(struct sdhci_host *host)
{
	spacemit_sdhci_clrsetbits(host, SDHC_RX_DLINE_REG_MASK,
				  FIELD_PREP(SDHC_RX_DLINE_REG_MASK, SPACEMIT_RX_DLINE_REG),
				  SPACEMIT_SDHC_DLINE_CFG_REG);

	spacemit_sdhci_setbits(host, SDHC_DLINE_PU, SPACEMIT_SDHC_DLINE_CTRL_REG);
	udelay(5);

	spacemit_sdhci_clrsetbits(host, SDHC_RX_SDCLK_SEL1_MASK, SDHC_RX_SDCLK_SEL1,
				  SPACEMIT_SDHC_RX_CFG_REG);

	if (host->mmc->ios.timing == MMC_TIMING_MMC_HS200)
		spacemit_sdhci_setbits(host, SDHC_HS200_USE_RFIFO, SPACEMIT_SDHC_PHY_FUNC_REG);
}

static void spacemit_sdhci_reset(struct sdhci_host *host, u8 mask)
{
	sdhci_reset(host, mask);

	if (mask != SDHCI_RESET_ALL)
		return;

	spacemit_sdhci_setbits(host, SDHC_PHY_FUNC_EN | SDHC_PHY_PLL_LOCK,
			       SPACEMIT_SDHC_PHY_CTRL_REG);

	spacemit_sdhci_clrsetbits(host, SDHC_PHY_DRIVE_SEL,
				  SDHC_RX_BIAS_CTRL | FIELD_PREP(SDHC_PHY_DRIVE_SEL, 4),
				  SPACEMIT_SDHC_PHY_PADCFG_REG);

	if (!(host->mmc->caps2 & MMC_CAP2_NO_MMC))
		spacemit_sdhci_setbits(host, SDHC_MMC_CARD_MODE, SPACEMIT_SDHC_MMC_CTRL_REG);

	spacemit_sdhci_setbits(host, SDHC_GEN_PAD_CLK_ON, SPACEMIT_SDHC_LEGACY_CTRL_REG);

Annotation

Implementation Notes