drivers/mmc/host/dw_mmc-hi3798mv200.c
Source file repositories/reference/linux-study-clean/drivers/mmc/host/dw_mmc-hi3798mv200.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/mmc/host/dw_mmc-hi3798mv200.c- Extension
.c- Size
- 6543 bytes
- Lines
- 243
- 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.
- 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.
- Allocates kernel memory; connect allocation flags and lifetime to context constraints.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/clk.hlinux/mfd/syscon.hlinux/mmc/host.hlinux/module.hlinux/of_address.hlinux/platform_device.hlinux/regmap.hdw_mmc.hdw_mmc-pltfm.h
Detected Declarations
struct dw_mci_hi3798mv200_privfunction dw_mci_hi3798mv200_set_iosfunction dw_mci_hi3798mv200_enable_tuningfunction dw_mci_hi3798mv200_disable_tuningfunction dw_mci_hi3798mv200_execute_tuning_mix_modefunction dw_mci_hi3798mv200_initfunction dw_mci_hi3798mv200_probefunction dw_mci_hi3798mv200_remove
Annotated Snippet
struct dw_mci_hi3798mv200_priv {
struct clk *sample_clk;
struct clk *drive_clk;
struct regmap *crg_reg;
u32 sap_dll_offset;
};
static void dw_mci_hi3798mv200_set_ios(struct dw_mci *host, struct mmc_ios *ios)
{
struct dw_mci_hi3798mv200_priv *priv = host->priv;
struct mmc_clk_phase phase = host->phase_map.phase[ios->timing];
u32 val;
val = mci_readl(host, ENABLE_SHIFT);
if (ios->timing == MMC_TIMING_MMC_DDR52
|| ios->timing == MMC_TIMING_UHS_DDR50)
val |= SDMMC_ENABLE_PHASE;
else
val &= ~SDMMC_ENABLE_PHASE;
mci_writel(host, ENABLE_SHIFT, val);
val = mci_readl(host, DDR_REG);
if (ios->timing == MMC_TIMING_MMC_HS400)
val |= SDMMC_DDR_HS400;
else
val &= ~SDMMC_DDR_HS400;
mci_writel(host, DDR_REG, val);
if (clk_set_rate(host->ciu_clk, ios->clock))
dev_warn(host->dev, "Failed to set rate to %u\n", ios->clock);
else
/*
* CLK_MUX_ROUND_NEAREST is enabled for this clock
* The actual clock rate is not what we set, but a rounded value
* so we should get the rate once again
*/
host->bus_hz = clk_get_rate(host->ciu_clk);
if (phase.valid) {
clk_set_phase(priv->drive_clk, phase.out_deg);
clk_set_phase(priv->sample_clk, phase.in_deg);
} else {
dev_warn(host->dev,
"The phase entry for timing mode %d is missing in device tree.\n",
ios->timing);
}
}
static inline int dw_mci_hi3798mv200_enable_tuning(struct dw_mci *host)
{
struct dw_mci_hi3798mv200_priv *priv = host->priv;
return regmap_clear_bits(priv->crg_reg, priv->sap_dll_offset, SAP_DLL_CTRL_DLLMODE);
}
static inline int dw_mci_hi3798mv200_disable_tuning(struct dw_mci *host)
{
struct dw_mci_hi3798mv200_priv *priv = host->priv;
return regmap_set_bits(priv->crg_reg, priv->sap_dll_offset, SAP_DLL_CTRL_DLLMODE);
}
static int dw_mci_hi3798mv200_execute_tuning_mix_mode(struct dw_mci *host,
u32 opcode)
{
static const int degrees[] = { 0, 45, 90, 135, 180, 225, 270, 315 };
struct dw_mci_hi3798mv200_priv *priv = host->priv;
int raise_point = -1, fall_point = -1, mid;
int err, prev_err = -1;
int found = 0;
int regval;
int i;
int ret;
ret = dw_mci_hi3798mv200_enable_tuning(host);
if (ret < 0)
return ret;
for (i = 0; i < ARRAY_SIZE(degrees); i++) {
clk_set_phase(priv->sample_clk, degrees[i]);
mci_writel(host, RINTSTS, ALL_INT_CLR);
/*
* HiSilicon implemented a tuning mechanism.
* It needs special interaction with the DLL.
*
* Treat edge(flip) found as an error too.
*/
err = mmc_send_tuning(host->mmc, opcode, NULL);
regval = mci_readl(host, TUNING_CTRL);
Annotation
- Immediate include surface: `linux/clk.h`, `linux/mfd/syscon.h`, `linux/mmc/host.h`, `linux/module.h`, `linux/of_address.h`, `linux/platform_device.h`, `linux/regmap.h`, `dw_mmc.h`.
- Detected declarations: `struct dw_mci_hi3798mv200_priv`, `function dw_mci_hi3798mv200_set_ios`, `function dw_mci_hi3798mv200_enable_tuning`, `function dw_mci_hi3798mv200_disable_tuning`, `function dw_mci_hi3798mv200_execute_tuning_mix_mode`, `function dw_mci_hi3798mv200_init`, `function dw_mci_hi3798mv200_probe`, `function dw_mci_hi3798mv200_remove`.
- Atlas domain: Driver Families / drivers/mmc.
- Implementation status: source implementation candidate.
Implementation Notes
- This generated page is the file-by-file coverage layer; curated subsystem chapters should link here when they synthesize a multi-file control flow.
- Core OS pages should be promoted from atlas-only to deep-reviewed when they explain data structures, invariants, locking, lifecycle, and C implementation snippets.
- Driver-family pages are intentionally pattern-oriented unless they are part of the selected PCIe/NVMe representative device path.