drivers/gpu/drm/msm/disp/mdp4/mdp4_lvds_pll.c
Source file repositories/reference/linux-study-clean/drivers/gpu/drm/msm/disp/mdp4/mdp4_lvds_pll.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/gpu/drm/msm/disp/mdp4/mdp4_lvds_pll.c- Extension
.c- Size
- 4446 bytes
- Lines
- 184
- Domain
- Driver Families
- Bucket
- drivers/gpu
- 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/clk-provider.hmdp4_kms.h
Detected Declarations
struct mdp4_lvds_pllstruct pll_ratefunction mdp4_lvds_pll_enablefunction mdp4_lvds_pll_disablefunction mdp4_lvds_pll_recalc_ratefunction mdp4_lvds_pll_determine_ratefunction mdp4_lvds_pll_set_rate
Annotated Snippet
struct mdp4_lvds_pll {
struct clk_hw pll_hw;
struct drm_device *dev;
unsigned long pixclk;
};
#define to_mdp4_lvds_pll(x) container_of(x, struct mdp4_lvds_pll, pll_hw)
static struct mdp4_kms *get_kms(struct mdp4_lvds_pll *lvds_pll)
{
struct msm_drm_private *priv = lvds_pll->dev->dev_private;
return to_mdp4_kms(to_mdp_kms(priv->kms));
}
struct pll_rate {
unsigned long rate;
struct {
uint32_t val;
uint32_t reg;
} conf[32];
};
/* NOTE: keep sorted highest freq to lowest: */
static const struct pll_rate freqtbl[] = {
{ 72000000, {
{ 0x8f, REG_MDP4_LVDS_PHY_PLL_CTRL_1 },
{ 0x30, REG_MDP4_LVDS_PHY_PLL_CTRL_2 },
{ 0xc6, REG_MDP4_LVDS_PHY_PLL_CTRL_3 },
{ 0x10, REG_MDP4_LVDS_PHY_PLL_CTRL_5 },
{ 0x07, REG_MDP4_LVDS_PHY_PLL_CTRL_6 },
{ 0x62, REG_MDP4_LVDS_PHY_PLL_CTRL_7 },
{ 0x41, REG_MDP4_LVDS_PHY_PLL_CTRL_8 },
{ 0x0d, REG_MDP4_LVDS_PHY_PLL_CTRL_9 },
{ 0, 0 } }
},
};
static const struct pll_rate *find_rate(unsigned long rate)
{
int i;
for (i = 1; i < ARRAY_SIZE(freqtbl); i++)
if (rate > freqtbl[i].rate)
return &freqtbl[i-1];
return &freqtbl[i-1];
}
static int mdp4_lvds_pll_enable(struct clk_hw *hw)
{
struct mdp4_lvds_pll *lvds_pll = to_mdp4_lvds_pll(hw);
struct mdp4_kms *mdp4_kms = get_kms(lvds_pll);
const struct pll_rate *pll_rate = find_rate(lvds_pll->pixclk);
int i;
DBG("pixclk=%lu (%lu)", lvds_pll->pixclk, pll_rate->rate);
if (WARN_ON(!pll_rate))
return -EINVAL;
mdp4_write(mdp4_kms, REG_MDP4_LCDC_LVDS_PHY_RESET, 0x33);
for (i = 0; pll_rate->conf[i].reg; i++)
mdp4_write(mdp4_kms, pll_rate->conf[i].reg, pll_rate->conf[i].val);
mdp4_write(mdp4_kms, REG_MDP4_LVDS_PHY_PLL_CTRL_0, 0x01);
/* Wait until LVDS PLL is locked and ready */
while (!mdp4_read(mdp4_kms, REG_MDP4_LVDS_PHY_PLL_LOCKED))
cpu_relax();
return 0;
}
static void mdp4_lvds_pll_disable(struct clk_hw *hw)
{
struct mdp4_lvds_pll *lvds_pll = to_mdp4_lvds_pll(hw);
struct mdp4_kms *mdp4_kms = get_kms(lvds_pll);
DBG("");
mdp4_write(mdp4_kms, REG_MDP4_LVDS_PHY_CFG0, 0x0);
mdp4_write(mdp4_kms, REG_MDP4_LVDS_PHY_PLL_CTRL_0, 0x0);
}
static unsigned long mdp4_lvds_pll_recalc_rate(struct clk_hw *hw,
unsigned long parent_rate)
{
struct mdp4_lvds_pll *lvds_pll = to_mdp4_lvds_pll(hw);
return lvds_pll->pixclk;
}
static int mdp4_lvds_pll_determine_rate(struct clk_hw *hw,
Annotation
- Immediate include surface: `linux/clk.h`, `linux/clk-provider.h`, `mdp4_kms.h`.
- Detected declarations: `struct mdp4_lvds_pll`, `struct pll_rate`, `function mdp4_lvds_pll_enable`, `function mdp4_lvds_pll_disable`, `function mdp4_lvds_pll_recalc_rate`, `function mdp4_lvds_pll_determine_rate`, `function mdp4_lvds_pll_set_rate`.
- Atlas domain: Driver Families / drivers/gpu.
- 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.