drivers/phy/rockchip/phy-rockchip-emmc.c
Source file repositories/reference/linux-study-clean/drivers/phy/rockchip/phy-rockchip-emmc.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/phy/rockchip/phy-rockchip-emmc.c- Extension
.c- Size
- 12491 bytes
- Lines
- 428
- Domain
- Driver Families
- Bucket
- drivers/phy
- 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/delay.hlinux/hw_bitfield.hlinux/mfd/syscon.hlinux/module.hlinux/of.hlinux/of_address.hlinux/phy/phy.hlinux/platform_device.hlinux/regmap.h
Detected Declarations
struct rockchip_emmc_phyfunction rockchip_emmc_phy_powerfunction rockchip_emmc_phy_initfunction rockchip_emmc_phy_exitfunction rockchip_emmc_phy_power_offfunction rockchip_emmc_phy_power_onfunction convert_drive_impedance_ohmfunction rockchip_emmc_phy_probe
Annotated Snippet
struct rockchip_emmc_phy {
unsigned int reg_offset;
struct regmap *reg_base;
struct clk *emmcclk;
unsigned int drive_impedance;
unsigned int enable_strobe_pulldown;
unsigned int output_tapdelay_select;
};
static int rockchip_emmc_phy_power(struct phy *phy, bool on_off)
{
struct rockchip_emmc_phy *rk_phy = phy_get_drvdata(phy);
unsigned int caldone;
unsigned int dllrdy;
unsigned int freqsel = PHYCTRL_FREQSEL_200M;
unsigned long rate;
int ret;
/*
* Keep phyctrl_pdb and phyctrl_endll low to allow
* initialization of CALIO state M/C DFFs
*/
regmap_write(rk_phy->reg_base,
rk_phy->reg_offset + GRF_EMMCPHY_CON6,
HIWORD_UPDATE(PHYCTRL_PDB_PWR_OFF,
PHYCTRL_PDB_MASK,
PHYCTRL_PDB_SHIFT));
regmap_write(rk_phy->reg_base,
rk_phy->reg_offset + GRF_EMMCPHY_CON6,
HIWORD_UPDATE(PHYCTRL_ENDLL_DISABLE,
PHYCTRL_ENDLL_MASK,
PHYCTRL_ENDLL_SHIFT));
/* Already finish power_off above */
if (on_off == PHYCTRL_PDB_PWR_OFF)
return 0;
rate = clk_get_rate(rk_phy->emmcclk);
if (rate != 0) {
unsigned long ideal_rate;
unsigned long diff;
switch (rate) {
case 1 ... 74999999:
ideal_rate = 50000000;
freqsel = PHYCTRL_FREQSEL_50M;
break;
case 75000000 ... 124999999:
ideal_rate = 100000000;
freqsel = PHYCTRL_FREQSEL_100M;
break;
case 125000000 ... 174999999:
ideal_rate = 150000000;
freqsel = PHYCTRL_FREQSEL_150M;
break;
default:
ideal_rate = 200000000;
break;
}
diff = (rate > ideal_rate) ?
rate - ideal_rate : ideal_rate - rate;
/*
* In order for tuning delays to be accurate we need to be
* pretty spot on for the DLL range, so warn if we're too
* far off. Also warn if we're above the 200 MHz max. Don't
* warn for really slow rates since we won't be tuning then.
*/
if ((rate > 50000000 && diff > 15000000) || (rate > 200000000))
dev_warn(&phy->dev, "Unsupported rate: %lu\n", rate);
}
/*
* According to the user manual, calpad calibration
* cycle takes more than 2us without the minimal recommended
* value, so we may need a little margin here
*/
udelay(3);
regmap_write(rk_phy->reg_base,
rk_phy->reg_offset + GRF_EMMCPHY_CON6,
HIWORD_UPDATE(PHYCTRL_PDB_PWR_ON,
PHYCTRL_PDB_MASK,
PHYCTRL_PDB_SHIFT));
/*
* According to the user manual, it asks driver to wait 5us for
* calpad busy trimming. However it is documented that this value is
* PVT(A.K.A process,voltage and temperature) relevant, so some
Annotation
- Immediate include surface: `linux/clk.h`, `linux/delay.h`, `linux/hw_bitfield.h`, `linux/mfd/syscon.h`, `linux/module.h`, `linux/of.h`, `linux/of_address.h`, `linux/phy/phy.h`.
- Detected declarations: `struct rockchip_emmc_phy`, `function rockchip_emmc_phy_power`, `function rockchip_emmc_phy_init`, `function rockchip_emmc_phy_exit`, `function rockchip_emmc_phy_power_off`, `function rockchip_emmc_phy_power_on`, `function convert_drive_impedance_ohm`, `function rockchip_emmc_phy_probe`.
- Atlas domain: Driver Families / drivers/phy.
- 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.