drivers/gpu/drm/sun4i/sun4i_tcon_dclk.c
Source file repositories/reference/linux-study-clean/drivers/gpu/drm/sun4i/sun4i_tcon_dclk.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/gpu/drm/sun4i/sun4i_tcon_dclk.c- Extension
.c- Size
- 4593 bytes
- Lines
- 209
- Domain
- Driver Families
- Bucket
- drivers/gpu
- Inferred role
- Driver Families: exported/initcall integration point
- Status
- integration 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.
- Exports symbols or registers init work; inspect boot/module ordering and who consumes the exported contract.
- 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-provider.hlinux/regmap.hsun4i_tcon.hsun4i_tcon_dclk.h
Detected Declarations
struct sun4i_dclkfunction sun4i_dclk_disablefunction sun4i_dclk_enablefunction sun4i_dclk_is_enabledfunction sun4i_dclk_recalc_ratefunction sun4i_dclk_determine_ratefunction sun4i_dclk_set_ratefunction sun4i_dclk_get_phasefunction sun4i_dclk_set_phasefunction sun4i_dclk_createfunction sun4i_dclk_freeexport sun4i_dclk_createexport sun4i_dclk_free
Annotated Snippet
struct sun4i_dclk {
struct clk_hw hw;
struct regmap *regmap;
struct sun4i_tcon *tcon;
};
static inline struct sun4i_dclk *hw_to_dclk(struct clk_hw *hw)
{
return container_of(hw, struct sun4i_dclk, hw);
}
static void sun4i_dclk_disable(struct clk_hw *hw)
{
struct sun4i_dclk *dclk = hw_to_dclk(hw);
regmap_update_bits(dclk->regmap, SUN4I_TCON0_DCLK_REG,
BIT(SUN4I_TCON0_DCLK_GATE_BIT), 0);
}
static int sun4i_dclk_enable(struct clk_hw *hw)
{
struct sun4i_dclk *dclk = hw_to_dclk(hw);
return regmap_update_bits(dclk->regmap, SUN4I_TCON0_DCLK_REG,
BIT(SUN4I_TCON0_DCLK_GATE_BIT),
BIT(SUN4I_TCON0_DCLK_GATE_BIT));
}
static int sun4i_dclk_is_enabled(struct clk_hw *hw)
{
struct sun4i_dclk *dclk = hw_to_dclk(hw);
u32 val;
regmap_read(dclk->regmap, SUN4I_TCON0_DCLK_REG, &val);
return val & BIT(SUN4I_TCON0_DCLK_GATE_BIT);
}
static unsigned long sun4i_dclk_recalc_rate(struct clk_hw *hw,
unsigned long parent_rate)
{
struct sun4i_dclk *dclk = hw_to_dclk(hw);
u32 val;
regmap_read(dclk->regmap, SUN4I_TCON0_DCLK_REG, &val);
val >>= SUN4I_TCON0_DCLK_DIV_SHIFT;
val &= (1 << SUN4I_TCON0_DCLK_DIV_WIDTH) - 1;
if (!val)
val = 1;
return parent_rate / val;
}
static int sun4i_dclk_determine_rate(struct clk_hw *hw,
struct clk_rate_request *req)
{
struct sun4i_dclk *dclk = hw_to_dclk(hw);
struct sun4i_tcon *tcon = dclk->tcon;
unsigned long best_parent = 0;
u8 best_div = 1;
int i;
for (i = tcon->dclk_min_div; i <= tcon->dclk_max_div; i++) {
u64 ideal = (u64)req->rate * i;
unsigned long rounded;
/*
* ideal has overflowed the max value that can be stored in an
* unsigned long, and every clk operation we might do on a
* truncated u64 value will give us incorrect results.
* Let's just stop there since bigger dividers will result in
* the same overflow issue.
*/
if (ideal > ULONG_MAX)
goto out;
rounded = clk_hw_round_rate(clk_hw_get_parent(hw),
ideal);
if (rounded == ideal) {
best_parent = rounded;
best_div = i;
goto out;
}
if (abs(req->rate - rounded / i) <
abs(req->rate - best_parent / best_div)) {
best_parent = rounded;
Annotation
- Immediate include surface: `linux/clk-provider.h`, `linux/regmap.h`, `sun4i_tcon.h`, `sun4i_tcon_dclk.h`.
- Detected declarations: `struct sun4i_dclk`, `function sun4i_dclk_disable`, `function sun4i_dclk_enable`, `function sun4i_dclk_is_enabled`, `function sun4i_dclk_recalc_rate`, `function sun4i_dclk_determine_rate`, `function sun4i_dclk_set_rate`, `function sun4i_dclk_get_phase`, `function sun4i_dclk_set_phase`, `function sun4i_dclk_create`.
- Atlas domain: Driver Families / drivers/gpu.
- Implementation status: integration 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.