Skip to content

Commit

Permalink
Merge tag 'clk-microchip-6.12' of https://git.kernel.org/pub/scm/linu…
Browse files Browse the repository at this point in the history
…x/kernel/git/at91/linux into clk-microchip

Pull Microchip clk driver updates from Claudiu Beznea:

 - support for the Microchip SAM9X7 SoC as follows:
 - updates on the PLL drivers
 - a new clock driver was added for SAM9X7
 - dt-binding documentation updates (for the new clock driver and for
   the slow clock controller that SAM9X7 is using)
 - a fix for the Microchip SAMA7G5 clock driver to avoid allocating mode
   than necessary memory

* tag 'clk-microchip-6.12' of https://git.kernel.org/pub/scm/linux/kernel/git/at91/linux:
  clk: at91: sama7g5: Allocate only the needed amount of memory for PLLs
  clk: at91: sam9x7: add sam9x7 pmc driver
  dt-bindings: clock: at91: Allow PLLs to be exported and referenced in DT
  clk: at91: sama7g5: move mux table macros to header file
  clk: at91: sam9x7: add support for HW PLL freq dividers
  clk: at91: clk-sam9x60-pll: re-factor to support individual core freq outputs
  dt-bindings: clocks: atmel,at91rm9200-pmc: add sam9x7 clock controller
  dt-bindings: clocks: atmel,at91sam9x5-sckc: add sam9x7
  • Loading branch information
bebarino committed Sep 3, 2024
2 parents 8400291 + 2d6e9ee commit 1d777b0
Show file tree
Hide file tree
Showing 9 changed files with 1,035 additions and 36 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ properties:
- atmel,sama5d3-pmc
- atmel,sama5d4-pmc
- microchip,sam9x60-pmc
- microchip,sam9x7-pmc
- microchip,sama7g5-pmc
- const: syscon

Expand Down Expand Up @@ -88,6 +89,7 @@ allOf:
contains:
enum:
- microchip,sam9x60-pmc
- microchip,sam9x7-pmc
- microchip,sama7g5-pmc
then:
properties:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,9 @@ properties:
- atmel,sama5d4-sckc
- microchip,sam9x60-sckc
- items:
- const: microchip,sama7g5-sckc
- enum:
- microchip,sam9x7-sckc
- microchip,sama7g5-sckc
- const: microchip,sam9x60-sckc

reg:
Expand Down
1 change: 1 addition & 0 deletions drivers/clk/at91/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ obj-$(CONFIG_SOC_AT91SAM9) += at91sam9260.o at91sam9rl.o at91sam9x5.o dt-compat.
obj-$(CONFIG_SOC_AT91SAM9) += at91sam9g45.o dt-compat.o
obj-$(CONFIG_SOC_AT91SAM9) += at91sam9n12.o at91sam9x5.o dt-compat.o
obj-$(CONFIG_SOC_SAM9X60) += sam9x60.o
obj-$(CONFIG_SOC_SAM9X7) += sam9x7.o
obj-$(CONFIG_SOC_SAMA5D3) += sama5d3.o dt-compat.o
obj-$(CONFIG_SOC_SAMA5D4) += sama5d4.o dt-compat.o
obj-$(CONFIG_SOC_SAMA5D2) += sama5d2.o dt-compat.o
Expand Down
42 changes: 34 additions & 8 deletions drivers/clk/at91/clk-sam9x60-pll.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,6 @@
#define UPLL_DIV 2
#define PLL_MUL_MAX (FIELD_GET(PMC_PLL_CTRL1_MUL_MSK, UINT_MAX) + 1)

#define FCORE_MIN (600000000)
#define FCORE_MAX (1200000000)

#define PLL_MAX_ID 7

struct sam9x60_pll_core {
Expand Down Expand Up @@ -76,9 +73,15 @@ static unsigned long sam9x60_frac_pll_recalc_rate(struct clk_hw *hw,
{
struct sam9x60_pll_core *core = to_sam9x60_pll_core(hw);
struct sam9x60_frac *frac = to_sam9x60_frac(core);
unsigned long freq;

return parent_rate * (frac->mul + 1) +
freq = parent_rate * (frac->mul + 1) +
DIV_ROUND_CLOSEST_ULL((u64)parent_rate * frac->frac, (1 << 22));

if (core->layout->div2)
freq >>= 1;

return freq;
}

static int sam9x60_frac_pll_set(struct sam9x60_pll_core *core)
Expand Down Expand Up @@ -194,7 +197,8 @@ static long sam9x60_frac_pll_compute_mul_frac(struct sam9x60_pll_core *core,
unsigned long nmul = 0;
unsigned long nfrac = 0;

if (rate < FCORE_MIN || rate > FCORE_MAX)
if (rate < core->characteristics->core_output[0].min ||
rate > core->characteristics->core_output[0].max)
return -ERANGE;

/*
Expand All @@ -214,7 +218,8 @@ static long sam9x60_frac_pll_compute_mul_frac(struct sam9x60_pll_core *core,
}

/* Check if resulted rate is a valid. */
if (tmprate < FCORE_MIN || tmprate > FCORE_MAX)
if (tmprate < core->characteristics->core_output[0].min ||
tmprate > core->characteristics->core_output[0].max)
return -ERANGE;

if (update) {
Expand Down Expand Up @@ -433,6 +438,12 @@ static unsigned long sam9x60_div_pll_recalc_rate(struct clk_hw *hw,
return DIV_ROUND_CLOSEST_ULL(parent_rate, (div->div + 1));
}

static unsigned long sam9x60_fixed_div_pll_recalc_rate(struct clk_hw *hw,
unsigned long parent_rate)
{
return parent_rate >> 1;
}

static long sam9x60_div_pll_compute_div(struct sam9x60_pll_core *core,
unsigned long *parent_rate,
unsigned long rate)
Expand Down Expand Up @@ -607,6 +618,16 @@ static const struct clk_ops sam9x60_div_pll_ops_chg = {
.restore_context = sam9x60_div_pll_restore_context,
};

static const struct clk_ops sam9x60_fixed_div_pll_ops = {
.prepare = sam9x60_div_pll_prepare,
.unprepare = sam9x60_div_pll_unprepare,
.is_prepared = sam9x60_div_pll_is_prepared,
.recalc_rate = sam9x60_fixed_div_pll_recalc_rate,
.round_rate = sam9x60_div_pll_round_rate,
.save_context = sam9x60_div_pll_save_context,
.restore_context = sam9x60_div_pll_restore_context,
};

struct clk_hw * __init
sam9x60_clk_register_frac_pll(struct regmap *regmap, spinlock_t *lock,
const char *name, const char *parent_name,
Expand Down Expand Up @@ -669,7 +690,8 @@ sam9x60_clk_register_frac_pll(struct regmap *regmap, spinlock_t *lock,
goto free;
}

ret = sam9x60_frac_pll_compute_mul_frac(&frac->core, FCORE_MIN,
ret = sam9x60_frac_pll_compute_mul_frac(&frac->core,
characteristics->core_output[0].min,
parent_rate, true);
if (ret < 0) {
hw = ERR_PTR(ret);
Expand Down Expand Up @@ -725,10 +747,14 @@ sam9x60_clk_register_div_pll(struct regmap *regmap, spinlock_t *lock,
else
init.parent_names = &parent_name;
init.num_parents = 1;
if (flags & CLK_SET_RATE_GATE)

if (layout->div2)
init.ops = &sam9x60_fixed_div_pll_ops;
else if (flags & CLK_SET_RATE_GATE)
init.ops = &sam9x60_div_pll_ops;
else
init.ops = &sam9x60_div_pll_ops_chg;

init.flags = flags;

div->core.id = id;
Expand Down
18 changes: 18 additions & 0 deletions drivers/clk/at91/pmc.h
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ struct clk_pll_layout {
u8 frac_shift;
u8 div_shift;
u8 endiv_shift;
u8 div2;
};

extern const struct clk_pll_layout at91rm9200_pll_layout;
Expand All @@ -75,6 +76,7 @@ struct clk_pll_characteristics {
struct clk_range input;
int num_output;
const struct clk_range *output;
const struct clk_range *core_output;
u16 *icpll;
u8 *out;
u8 upll : 1;
Expand Down Expand Up @@ -119,6 +121,22 @@ struct at91_clk_pms {

#define ndck(a, s) (a[s - 1].id + 1)
#define nck(a) (a[ARRAY_SIZE(a) - 1].id + 1)

#define PMC_INIT_TABLE(_table, _count) \
do { \
u8 _i; \
for (_i = 0; _i < (_count); _i++) \
(_table)[_i] = _i; \
} while (0)

#define PMC_FILL_TABLE(_to, _from, _count) \
do { \
u8 _i; \
for (_i = 0; _i < (_count); _i++) { \
(_to)[_i] = (_from)[_i]; \
} \
} while (0)

struct pmc_data *pmc_data_allocate(unsigned int ncore, unsigned int nsystem,
unsigned int nperiph, unsigned int ngck,
unsigned int npck);
Expand Down
7 changes: 7 additions & 0 deletions drivers/clk/at91/sam9x60.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,16 @@ static const struct clk_range plla_outputs[] = {
{ .min = 2343750, .max = 1200000000 },
};

/* Fractional PLL core output range. */
static const struct clk_range core_outputs[] = {
{ .min = 600000000, .max = 1200000000 },
};

static const struct clk_pll_characteristics plla_characteristics = {
.input = { .min = 12000000, .max = 48000000 },
.num_output = ARRAY_SIZE(plla_outputs),
.output = plla_outputs,
.core_output = core_outputs,
};

static const struct clk_range upll_outputs[] = {
Expand All @@ -40,6 +46,7 @@ static const struct clk_pll_characteristics upll_characteristics = {
.input = { .min = 12000000, .max = 48000000 },
.num_output = ARRAY_SIZE(upll_outputs),
.output = upll_outputs,
.core_output = core_outputs,
.upll = true,
};

Expand Down
Loading

0 comments on commit 1d777b0

Please sign in to comment.