Skip to content

Commit 5299f80

Browse files
varshini-rajendranclaudiubeznea
authored andcommitted
clk: at91: sam9x7: add support for HW PLL freq dividers
Add support for hardware dividers for PLL IDs in sam9x7 SoC. The system PLL - PLLA and the system PLL divided by 2 - PLLADIV2 with PLL ID 0 and 4 respectively, both have a hardware divider /2. This has to be taken into account in the software to obtain the right frequencies. Support for the same is added in the PLL driver. fcorepllack -----> HW Div = 2 -+--> fpllack | +--> HW Div = 2 ---> fplladiv2ck In this case the corepll freq is 1600 MHz. So, the plla freq is 800 MHz after the hardware divider and the plladiv2 freq is 400 MHz after the hardware divider (given that the DIVPMC is 0). Signed-off-by: Varshini Rajendran <[email protected]> Reviewed-by: Claudiu Beznea <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Claudiu Beznea <[email protected]>
1 parent a402c66 commit 5299f80

File tree

2 files changed

+29
-2
lines changed

2 files changed

+29
-2
lines changed

drivers/clk/at91/clk-sam9x60-pll.c

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -73,9 +73,15 @@ static unsigned long sam9x60_frac_pll_recalc_rate(struct clk_hw *hw,
7373
{
7474
struct sam9x60_pll_core *core = to_sam9x60_pll_core(hw);
7575
struct sam9x60_frac *frac = to_sam9x60_frac(core);
76+
unsigned long freq;
7677

77-
return parent_rate * (frac->mul + 1) +
78+
freq = parent_rate * (frac->mul + 1) +
7879
DIV_ROUND_CLOSEST_ULL((u64)parent_rate * frac->frac, (1 << 22));
80+
81+
if (core->layout->div2)
82+
freq >>= 1;
83+
84+
return freq;
7985
}
8086

8187
static int sam9x60_frac_pll_set(struct sam9x60_pll_core *core)
@@ -432,6 +438,12 @@ static unsigned long sam9x60_div_pll_recalc_rate(struct clk_hw *hw,
432438
return DIV_ROUND_CLOSEST_ULL(parent_rate, (div->div + 1));
433439
}
434440

441+
static unsigned long sam9x60_fixed_div_pll_recalc_rate(struct clk_hw *hw,
442+
unsigned long parent_rate)
443+
{
444+
return parent_rate >> 1;
445+
}
446+
435447
static long sam9x60_div_pll_compute_div(struct sam9x60_pll_core *core,
436448
unsigned long *parent_rate,
437449
unsigned long rate)
@@ -606,6 +618,16 @@ static const struct clk_ops sam9x60_div_pll_ops_chg = {
606618
.restore_context = sam9x60_div_pll_restore_context,
607619
};
608620

621+
static const struct clk_ops sam9x60_fixed_div_pll_ops = {
622+
.prepare = sam9x60_div_pll_prepare,
623+
.unprepare = sam9x60_div_pll_unprepare,
624+
.is_prepared = sam9x60_div_pll_is_prepared,
625+
.recalc_rate = sam9x60_fixed_div_pll_recalc_rate,
626+
.round_rate = sam9x60_div_pll_round_rate,
627+
.save_context = sam9x60_div_pll_save_context,
628+
.restore_context = sam9x60_div_pll_restore_context,
629+
};
630+
609631
struct clk_hw * __init
610632
sam9x60_clk_register_frac_pll(struct regmap *regmap, spinlock_t *lock,
611633
const char *name, const char *parent_name,
@@ -725,10 +747,14 @@ sam9x60_clk_register_div_pll(struct regmap *regmap, spinlock_t *lock,
725747
else
726748
init.parent_names = &parent_name;
727749
init.num_parents = 1;
728-
if (flags & CLK_SET_RATE_GATE)
750+
751+
if (layout->div2)
752+
init.ops = &sam9x60_fixed_div_pll_ops;
753+
else if (flags & CLK_SET_RATE_GATE)
729754
init.ops = &sam9x60_div_pll_ops;
730755
else
731756
init.ops = &sam9x60_div_pll_ops_chg;
757+
732758
init.flags = flags;
733759

734760
div->core.id = id;

drivers/clk/at91/pmc.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ struct clk_pll_layout {
6464
u8 frac_shift;
6565
u8 div_shift;
6666
u8 endiv_shift;
67+
u8 div2;
6768
};
6869

6970
extern const struct clk_pll_layout at91rm9200_pll_layout;

0 commit comments

Comments
 (0)