drivers/cpufreq/tegra194-cpufreq.c
Source file repositories/reference/linux-study-clean/drivers/cpufreq/tegra194-cpufreq.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/cpufreq/tegra194-cpufreq.c- Extension
.c- Size
- 23290 bytes
- Lines
- 829
- Domain
- Driver Families
- Bucket
- drivers/cpufreq
- 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/cpu.hlinux/cpufreq.hlinux/dma-mapping.hlinux/module.hlinux/of.hlinux/of_platform.hlinux/platform_device.hlinux/slab.hlinux/units.hasm/smp_plat.hsoc/tegra/bpmp.hsoc/tegra/bpmp-abi.h
Detected Declarations
struct tegra_cpu_datastruct tegra_cpu_ctrstruct read_counters_workstruct tegra_cpufreq_opsstruct tegra_cpufreq_socstruct tegra194_cpufreq_datafunction tegra_cpufreq_set_bwfunction tegra_get_cpu_mpidrfunction tegra234_get_cpu_cluster_idfunction tegra234_get_cpu_ndivfunction tegra234_set_cpu_ndivfunction tegra234_read_countersfunction tegra194_get_cpu_cluster_idfunction read_freq_feedbackfunction map_ndiv_to_freqfunction tegra194_read_countersfunction tegra_read_countersfunction tegra194_calculate_speedfunction tegra194_get_cpu_ndiv_sysregfunction tegra194_get_cpu_ndivfunction tegra194_set_cpu_ndiv_sysregfunction tegra194_set_cpu_ndivfunction tegra194_get_speedfunction tegra_cpufreq_init_cpufreq_tablefunction tegra194_cpufreq_initfunction tegra194_cpufreq_onlinefunction tegra194_cpufreq_offlinefunction tegra194_cpufreq_exitfunction tegra194_cpufreq_set_targetfunction tegra194_cpufreq_free_resourcesfunction tegra_cpufreq_bpmp_read_lutfunction tegra194_cpufreq_store_physidsfunction tegra194_cpufreq_probefunction for_each_possible_cpufunction tegra194_cpufreq_remove
Annotated Snippet
struct tegra_cpu_data {
u32 cpuid;
u32 clusterid;
void __iomem *freq_core_reg;
};
struct tegra_cpu_ctr {
u32 cpu;
u32 coreclk_cnt, last_coreclk_cnt;
u32 refclk_cnt, last_refclk_cnt;
};
struct read_counters_work {
struct work_struct work;
struct tegra_cpu_ctr c;
};
struct tegra_cpufreq_ops {
void (*read_counters)(struct tegra_cpu_ctr *c);
void (*set_cpu_ndiv)(struct cpufreq_policy *policy, u64 ndiv);
void (*get_cpu_cluster_id)(u32 cpu, u32 *cpuid, u32 *clusterid);
int (*get_cpu_ndiv)(u32 cpu, u32 cpuid, u32 clusterid, u64 *ndiv);
};
struct tegra_cpufreq_soc {
struct tegra_cpufreq_ops *ops;
int maxcpus_per_cluster;
unsigned int num_clusters;
phys_addr_t actmon_cntr_base;
u32 refclk_delta_min;
};
struct tegra194_cpufreq_data {
void __iomem *regs;
struct cpufreq_frequency_table **bpmp_luts;
const struct tegra_cpufreq_soc *soc;
bool icc_dram_bw_scaling;
struct tegra_cpu_data *cpu_data;
};
static struct workqueue_struct *read_counters_wq;
static int tegra_cpufreq_set_bw(struct cpufreq_policy *policy, unsigned long freq_khz)
{
struct tegra194_cpufreq_data *data = cpufreq_get_driver_data();
struct dev_pm_opp *opp;
struct device *dev;
int ret;
dev = get_cpu_device(policy->cpu);
if (!dev)
return -ENODEV;
opp = dev_pm_opp_find_freq_exact(dev, freq_khz * KHZ, true);
if (IS_ERR(opp))
return PTR_ERR(opp);
ret = dev_pm_opp_set_opp(dev, opp);
if (ret)
data->icc_dram_bw_scaling = false;
dev_pm_opp_put(opp);
return ret;
}
static void tegra_get_cpu_mpidr(void *mpidr)
{
*((u64 *)mpidr) = read_cpuid_mpidr() & MPIDR_HWID_BITMASK;
}
static void tegra234_get_cpu_cluster_id(u32 cpu, u32 *cpuid, u32 *clusterid)
{
u64 mpidr;
smp_call_function_single(cpu, tegra_get_cpu_mpidr, &mpidr, true);
if (cpuid)
*cpuid = MPIDR_AFFINITY_LEVEL(mpidr, 1);
if (clusterid)
*clusterid = MPIDR_AFFINITY_LEVEL(mpidr, 2);
}
static int tegra234_get_cpu_ndiv(u32 cpu, u32 cpuid, u32 clusterid, u64 *ndiv)
{
struct tegra194_cpufreq_data *data = cpufreq_get_driver_data();
*ndiv = readl(data->cpu_data[cpu].freq_core_reg) & NDIV_MASK;
return 0;
}
Annotation
- Immediate include surface: `linux/cpu.h`, `linux/cpufreq.h`, `linux/dma-mapping.h`, `linux/module.h`, `linux/of.h`, `linux/of_platform.h`, `linux/platform_device.h`, `linux/slab.h`.
- Detected declarations: `struct tegra_cpu_data`, `struct tegra_cpu_ctr`, `struct read_counters_work`, `struct tegra_cpufreq_ops`, `struct tegra_cpufreq_soc`, `struct tegra194_cpufreq_data`, `function tegra_cpufreq_set_bw`, `function tegra_get_cpu_mpidr`, `function tegra234_get_cpu_cluster_id`, `function tegra234_get_cpu_ndiv`.
- Atlas domain: Driver Families / drivers/cpufreq.
- 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.