drivers/devfreq/imx8m-ddrc.c
Source file repositories/reference/linux-study-clean/drivers/devfreq/imx8m-ddrc.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/devfreq/imx8m-ddrc.c- Extension
.c- Size
- 12219 bytes
- Lines
- 458
- Domain
- Driver Families
- Bucket
- drivers/devfreq
- 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/mod_devicetable.hlinux/module.hlinux/device.hlinux/platform_device.hlinux/devfreq.hlinux/pm_opp.hlinux/clk.hlinux/clk-provider.hlinux/arm-smccc.h
Detected Declarations
struct imx8m_ddrc_freqstruct imx8m_ddrcfunction imx8m_ddrc_smc_set_freqfunction imx8m_ddrc_set_freqfunction imx8m_ddrc_targetfunction imx8m_ddrc_get_cur_freqfunction imx8m_ddrc_init_freq_infofunction imx8m_ddrc_check_oppsfunction imx8m_ddrc_exitfunction imx8m_ddrc_probe
Annotated Snippet
struct imx8m_ddrc_freq {
unsigned long rate;
unsigned long smcarg;
int dram_core_parent_index;
int dram_alt_parent_index;
int dram_apb_parent_index;
};
/* Hardware limitation */
#define IMX8M_DDRC_MAX_FREQ_COUNT 4
/*
* i.MX8M DRAM Controller clocks have the following structure (abridged):
*
* +----------+ |\ +------+
* | dram_pll |-------|M| dram_core | |
* +----------+ |U|---------->| D |
* /--|X| | D |
* dram_alt_root | |/ | R |
* | | C |
* +---------+ | |
* |FIX DIV/4| | |
* +---------+ | |
* composite: | | |
* +----------+ | | |
* | dram_alt |----/ | |
* +----------+ | |
* | dram_apb |-------------------->| |
* +----------+ +------+
*
* The dram_pll is used for higher rates and dram_alt is used for lower rates.
*
* Frequency switching is implemented in TF-A (via SMC call) and can change the
* configuration of the clocks, including mux parents. The dram_alt and
* dram_apb clocks are "imx composite" and their parent can change too.
*
* We need to prepare/enable the new mux parents head of switching and update
* their information afterwards.
*/
struct imx8m_ddrc {
struct devfreq_dev_profile profile;
struct devfreq *devfreq;
/* For frequency switching: */
struct clk *dram_core;
struct clk *dram_pll;
struct clk *dram_alt;
struct clk *dram_apb;
int freq_count;
struct imx8m_ddrc_freq freq_table[IMX8M_DDRC_MAX_FREQ_COUNT];
};
static struct imx8m_ddrc_freq *imx8m_ddrc_find_freq(struct imx8m_ddrc *priv,
unsigned long rate)
{
struct imx8m_ddrc_freq *freq;
int i;
/*
* Firmware reports values in MT/s, so we round-down from Hz
* Rounding is extra generous to ensure a match.
*/
rate = DIV_ROUND_CLOSEST(rate, 250000);
for (i = 0; i < priv->freq_count; ++i) {
freq = &priv->freq_table[i];
if (freq->rate == rate ||
freq->rate + 1 == rate ||
freq->rate - 1 == rate)
return freq;
}
return NULL;
}
static void imx8m_ddrc_smc_set_freq(int target_freq)
{
struct arm_smccc_res res;
u32 online_cpus = 0;
int cpu;
local_irq_disable();
for_each_online_cpu(cpu)
online_cpus |= (1 << (cpu * 8));
/* change the ddr freqency */
arm_smccc_smc(IMX_SIP_DDR_DVFS, target_freq, online_cpus,
0, 0, 0, 0, 0, &res);
Annotation
- Immediate include surface: `linux/mod_devicetable.h`, `linux/module.h`, `linux/device.h`, `linux/platform_device.h`, `linux/devfreq.h`, `linux/pm_opp.h`, `linux/clk.h`, `linux/clk-provider.h`.
- Detected declarations: `struct imx8m_ddrc_freq`, `struct imx8m_ddrc`, `function imx8m_ddrc_smc_set_freq`, `function imx8m_ddrc_set_freq`, `function imx8m_ddrc_target`, `function imx8m_ddrc_get_cur_freq`, `function imx8m_ddrc_init_freq_info`, `function imx8m_ddrc_check_opps`, `function imx8m_ddrc_exit`, `function imx8m_ddrc_probe`.
- Atlas domain: Driver Families / drivers/devfreq.
- 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.