drivers/mmc/host/dw_mmc-hi3798cv200.c
Source file repositories/reference/linux-study-clean/drivers/mmc/host/dw_mmc-hi3798cv200.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/mmc/host/dw_mmc-hi3798cv200.c- Extension
.c- Size
- 5009 bytes
- Lines
- 201
- 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/pm_runtime.hlinux/regmap.hlinux/regulator/consumer.hdw_mmc.hdw_mmc-pltfm.h
Detected Declarations
struct hi3798cv200_privfunction dw_mci_hi3798cv200_set_iosfunction dw_mci_hi3798cv200_execute_tuningfunction dw_mci_hi3798cv200_initfunction dw_mci_hi3798cv200_probefunction dw_mci_hi3798cv200_remove
Annotated Snippet
struct hi3798cv200_priv {
struct clk *sample_clk;
struct clk *drive_clk;
};
static void dw_mci_hi3798cv200_set_ios(struct dw_mci *host, struct mmc_ios *ios)
{
struct hi3798cv200_priv *priv = host->priv;
u32 val;
val = mci_readl(host, UHS_REG);
if (ios->timing == MMC_TIMING_MMC_DDR52 ||
ios->timing == MMC_TIMING_UHS_DDR50)
val |= SDMMC_UHS_DDR;
else
val &= ~SDMMC_UHS_DDR;
mci_writel(host, UHS_REG, val);
val = mci_readl(host, ENABLE_SHIFT);
if (ios->timing == MMC_TIMING_MMC_DDR52)
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 (ios->timing == MMC_TIMING_MMC_HS ||
ios->timing == MMC_TIMING_LEGACY)
clk_set_phase(priv->drive_clk, 180);
else if (ios->timing == MMC_TIMING_MMC_HS200)
clk_set_phase(priv->drive_clk, 135);
}
static int dw_mci_hi3798cv200_execute_tuning(struct dw_mci *host, u32 opcode)
{
static const int degrees[] = { 0, 45, 90, 135, 180, 225, 270, 315 };
struct hi3798cv200_priv *priv = host->priv;
int raise_point = -1, fall_point = -1;
int err, prev_err = -1;
int found = 0;
int i;
for (i = 0; i < ARRAY_SIZE(degrees); i++) {
clk_set_phase(priv->sample_clk, degrees[i]);
mci_writel(host, RINTSTS, ALL_INT_CLR);
err = mmc_send_tuning(host->mmc, opcode, NULL);
if (!err)
found = 1;
if (i > 0) {
if (err && !prev_err)
fall_point = i - 1;
if (!err && prev_err)
raise_point = i;
}
if (raise_point != -1 && fall_point != -1)
goto tuning_out;
prev_err = err;
}
tuning_out:
if (found) {
if (raise_point == -1)
raise_point = 0;
if (fall_point == -1)
fall_point = ARRAY_SIZE(degrees) - 1;
if (fall_point < raise_point) {
if ((raise_point + fall_point) >
(ARRAY_SIZE(degrees) - 1))
i = fall_point / 2;
else
i = (raise_point + ARRAY_SIZE(degrees) - 1) / 2;
} else {
i = (raise_point + fall_point) / 2;
}
clk_set_phase(priv->sample_clk, degrees[i]);
dev_dbg(host->dev, "Tuning clk_sample[%d, %d], set[%d]\n",
raise_point, fall_point, degrees[i]);
} else {
dev_err(host->dev, "No valid clk_sample shift! use default\n");
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/pm_runtime.h`, `linux/regmap.h`.
- Detected declarations: `struct hi3798cv200_priv`, `function dw_mci_hi3798cv200_set_ios`, `function dw_mci_hi3798cv200_execute_tuning`, `function dw_mci_hi3798cv200_init`, `function dw_mci_hi3798cv200_probe`, `function dw_mci_hi3798cv200_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.