Commit 120d5d8b authored by Claudiu Beznea's avatar Claudiu Beznea Committed by Stephen Boyd

clk: at91: sama7g5: do not allow cpu pll to go higher than 1GHz

Since CPU PLL feeds both CPU clock and MCK0, MCK0 cannot go higher
than 200MHz and MCK0 maximum prescaller is 5 limit the CPU PLL at
1GHz to avoid MCK0 overclocking while CPU PLL is changed by DVFS.
Signed-off-by: default avatarClaudiu Beznea <claudiu.beznea@microchip.com>
Link: https://lore.kernel.org/r/1605800597-16720-10-git-send-email-claudiu.beznea@microchip.comSigned-off-by: default avatarStephen Boyd <sboyd@kernel.org>
parent f803858a
...@@ -89,11 +89,40 @@ static const struct clk_pll_layout pll_layout_divio = { ...@@ -89,11 +89,40 @@ static const struct clk_pll_layout pll_layout_divio = {
.endiv_shift = 30, .endiv_shift = 30,
}; };
/*
* CPU PLL output range.
* Notice: The upper limit has been setup to 1000000002 due to hardware
* block which cannot output exactly 1GHz.
*/
static const struct clk_range cpu_pll_outputs[] = {
{ .min = 2343750, .max = 1000000002 },
};
/* PLL output range. */
static const struct clk_range pll_outputs[] = {
{ .min = 2343750, .max = 1200000000 },
};
/* CPU PLL characteristics. */
static const struct clk_pll_characteristics cpu_pll_characteristics = {
.input = { .min = 12000000, .max = 50000000 },
.num_output = ARRAY_SIZE(cpu_pll_outputs),
.output = cpu_pll_outputs,
};
/* PLL characteristics. */
static const struct clk_pll_characteristics pll_characteristics = {
.input = { .min = 12000000, .max = 50000000 },
.num_output = ARRAY_SIZE(pll_outputs),
.output = pll_outputs,
};
/** /**
* PLL clocks description * PLL clocks description
* @n: clock name * @n: clock name
* @p: clock parent * @p: clock parent
* @l: clock layout * @l: clock layout
* @c: clock characteristics
* @t: clock type * @t: clock type
* @f: clock flags * @f: clock flags
* @eid: export index in sama7g5->chws[] array * @eid: export index in sama7g5->chws[] array
...@@ -102,6 +131,7 @@ static const struct { ...@@ -102,6 +131,7 @@ static const struct {
const char *n; const char *n;
const char *p; const char *p;
const struct clk_pll_layout *l; const struct clk_pll_layout *l;
const struct clk_pll_characteristics *c;
unsigned long f; unsigned long f;
u8 t; u8 t;
u8 eid; u8 eid;
...@@ -110,6 +140,7 @@ static const struct { ...@@ -110,6 +140,7 @@ static const struct {
{ .n = "cpupll_fracck", { .n = "cpupll_fracck",
.p = "mainck", .p = "mainck",
.l = &pll_layout_frac, .l = &pll_layout_frac,
.c = &cpu_pll_characteristics,
.t = PLL_TYPE_FRAC, .t = PLL_TYPE_FRAC,
/* /*
* This feeds cpupll_divpmcck which feeds CPU. It should * This feeds cpupll_divpmcck which feeds CPU. It should
...@@ -120,6 +151,7 @@ static const struct { ...@@ -120,6 +151,7 @@ static const struct {
{ .n = "cpupll_divpmcck", { .n = "cpupll_divpmcck",
.p = "cpupll_fracck", .p = "cpupll_fracck",
.l = &pll_layout_divpmc, .l = &pll_layout_divpmc,
.c = &cpu_pll_characteristics,
.t = PLL_TYPE_DIV, .t = PLL_TYPE_DIV,
/* This feeds CPU. It should not be disabled. */ /* This feeds CPU. It should not be disabled. */
.f = CLK_IS_CRITICAL | CLK_SET_RATE_PARENT, .f = CLK_IS_CRITICAL | CLK_SET_RATE_PARENT,
...@@ -130,6 +162,7 @@ static const struct { ...@@ -130,6 +162,7 @@ static const struct {
{ .n = "syspll_fracck", { .n = "syspll_fracck",
.p = "mainck", .p = "mainck",
.l = &pll_layout_frac, .l = &pll_layout_frac,
.c = &pll_characteristics,
.t = PLL_TYPE_FRAC, .t = PLL_TYPE_FRAC,
/* /*
* This feeds syspll_divpmcck which may feed critial parts * This feeds syspll_divpmcck which may feed critial parts
...@@ -141,6 +174,7 @@ static const struct { ...@@ -141,6 +174,7 @@ static const struct {
{ .n = "syspll_divpmcck", { .n = "syspll_divpmcck",
.p = "syspll_fracck", .p = "syspll_fracck",
.l = &pll_layout_divpmc, .l = &pll_layout_divpmc,
.c = &pll_characteristics,
.t = PLL_TYPE_DIV, .t = PLL_TYPE_DIV,
/* /*
* This may feed critial parts of the systems like timers. * This may feed critial parts of the systems like timers.
...@@ -154,6 +188,7 @@ static const struct { ...@@ -154,6 +188,7 @@ static const struct {
{ .n = "ddrpll_fracck", { .n = "ddrpll_fracck",
.p = "mainck", .p = "mainck",
.l = &pll_layout_frac, .l = &pll_layout_frac,
.c = &pll_characteristics,
.t = PLL_TYPE_FRAC, .t = PLL_TYPE_FRAC,
/* /*
* This feeds ddrpll_divpmcck which feeds DDR. It should not * This feeds ddrpll_divpmcck which feeds DDR. It should not
...@@ -164,6 +199,7 @@ static const struct { ...@@ -164,6 +199,7 @@ static const struct {
{ .n = "ddrpll_divpmcck", { .n = "ddrpll_divpmcck",
.p = "ddrpll_fracck", .p = "ddrpll_fracck",
.l = &pll_layout_divpmc, .l = &pll_layout_divpmc,
.c = &pll_characteristics,
.t = PLL_TYPE_DIV, .t = PLL_TYPE_DIV,
/* This feeds DDR. It should not be disabled. */ /* This feeds DDR. It should not be disabled. */
.f = CLK_IS_CRITICAL | CLK_SET_RATE_GATE, }, .f = CLK_IS_CRITICAL | CLK_SET_RATE_GATE, },
...@@ -173,12 +209,14 @@ static const struct { ...@@ -173,12 +209,14 @@ static const struct {
{ .n = "imgpll_fracck", { .n = "imgpll_fracck",
.p = "mainck", .p = "mainck",
.l = &pll_layout_frac, .l = &pll_layout_frac,
.c = &pll_characteristics,
.t = PLL_TYPE_FRAC, .t = PLL_TYPE_FRAC,
.f = CLK_SET_RATE_GATE, }, .f = CLK_SET_RATE_GATE, },
{ .n = "imgpll_divpmcck", { .n = "imgpll_divpmcck",
.p = "imgpll_fracck", .p = "imgpll_fracck",
.l = &pll_layout_divpmc, .l = &pll_layout_divpmc,
.c = &pll_characteristics,
.t = PLL_TYPE_DIV, .t = PLL_TYPE_DIV,
.f = CLK_SET_RATE_GATE | CLK_SET_PARENT_GATE | .f = CLK_SET_RATE_GATE | CLK_SET_PARENT_GATE |
CLK_SET_RATE_PARENT, }, CLK_SET_RATE_PARENT, },
...@@ -188,12 +226,14 @@ static const struct { ...@@ -188,12 +226,14 @@ static const struct {
{ .n = "baudpll_fracck", { .n = "baudpll_fracck",
.p = "mainck", .p = "mainck",
.l = &pll_layout_frac, .l = &pll_layout_frac,
.c = &pll_characteristics,
.t = PLL_TYPE_FRAC, .t = PLL_TYPE_FRAC,
.f = CLK_SET_RATE_GATE, }, .f = CLK_SET_RATE_GATE, },
{ .n = "baudpll_divpmcck", { .n = "baudpll_divpmcck",
.p = "baudpll_fracck", .p = "baudpll_fracck",
.l = &pll_layout_divpmc, .l = &pll_layout_divpmc,
.c = &pll_characteristics,
.t = PLL_TYPE_DIV, .t = PLL_TYPE_DIV,
.f = CLK_SET_RATE_GATE | CLK_SET_PARENT_GATE | .f = CLK_SET_RATE_GATE | CLK_SET_PARENT_GATE |
CLK_SET_RATE_PARENT, }, CLK_SET_RATE_PARENT, },
...@@ -203,12 +243,14 @@ static const struct { ...@@ -203,12 +243,14 @@ static const struct {
{ .n = "audiopll_fracck", { .n = "audiopll_fracck",
.p = "main_xtal", .p = "main_xtal",
.l = &pll_layout_frac, .l = &pll_layout_frac,
.c = &pll_characteristics,
.t = PLL_TYPE_FRAC, .t = PLL_TYPE_FRAC,
.f = CLK_SET_RATE_GATE, }, .f = CLK_SET_RATE_GATE, },
{ .n = "audiopll_divpmcck", { .n = "audiopll_divpmcck",
.p = "audiopll_fracck", .p = "audiopll_fracck",
.l = &pll_layout_divpmc, .l = &pll_layout_divpmc,
.c = &pll_characteristics,
.t = PLL_TYPE_DIV, .t = PLL_TYPE_DIV,
.f = CLK_SET_RATE_GATE | CLK_SET_PARENT_GATE | .f = CLK_SET_RATE_GATE | CLK_SET_PARENT_GATE |
CLK_SET_RATE_PARENT, CLK_SET_RATE_PARENT,
...@@ -217,6 +259,7 @@ static const struct { ...@@ -217,6 +259,7 @@ static const struct {
{ .n = "audiopll_diviock", { .n = "audiopll_diviock",
.p = "audiopll_fracck", .p = "audiopll_fracck",
.l = &pll_layout_divio, .l = &pll_layout_divio,
.c = &pll_characteristics,
.t = PLL_TYPE_DIV, .t = PLL_TYPE_DIV,
.f = CLK_SET_RATE_GATE | CLK_SET_PARENT_GATE | .f = CLK_SET_RATE_GATE | CLK_SET_PARENT_GATE |
CLK_SET_RATE_PARENT, CLK_SET_RATE_PARENT,
...@@ -227,12 +270,14 @@ static const struct { ...@@ -227,12 +270,14 @@ static const struct {
{ .n = "ethpll_fracck", { .n = "ethpll_fracck",
.p = "main_xtal", .p = "main_xtal",
.l = &pll_layout_frac, .l = &pll_layout_frac,
.c = &pll_characteristics,
.t = PLL_TYPE_FRAC, .t = PLL_TYPE_FRAC,
.f = CLK_SET_RATE_GATE, }, .f = CLK_SET_RATE_GATE, },
{ .n = "ethpll_divpmcck", { .n = "ethpll_divpmcck",
.p = "ethpll_fracck", .p = "ethpll_fracck",
.l = &pll_layout_divpmc, .l = &pll_layout_divpmc,
.c = &pll_characteristics,
.t = PLL_TYPE_DIV, .t = PLL_TYPE_DIV,
.f = CLK_SET_RATE_GATE | CLK_SET_PARENT_GATE | .f = CLK_SET_RATE_GATE | CLK_SET_PARENT_GATE |
CLK_SET_RATE_PARENT, }, CLK_SET_RATE_PARENT, },
...@@ -793,18 +838,6 @@ static const struct { ...@@ -793,18 +838,6 @@ static const struct {
.pp_chg_id = INT_MIN, }, .pp_chg_id = INT_MIN, },
}; };
/* PLL output range. */
static const struct clk_range pll_outputs[] = {
{ .min = 2343750, .max = 1200000000 },
};
/* PLL characteristics. */
static const struct clk_pll_characteristics pll_characteristics = {
.input = { .min = 12000000, .max = 50000000 },
.num_output = ARRAY_SIZE(pll_outputs),
.output = pll_outputs,
};
/* MCK0 characteristics. */ /* MCK0 characteristics. */
static const struct clk_master_characteristics mck0_characteristics = { static const struct clk_master_characteristics mck0_characteristics = {
.output = { .min = 50000000, .max = 200000000 }, .output = { .min = 50000000, .max = 200000000 },
...@@ -921,7 +954,7 @@ static void __init sama7g5_pmc_setup(struct device_node *np) ...@@ -921,7 +954,7 @@ static void __init sama7g5_pmc_setup(struct device_node *np)
hw = sam9x60_clk_register_frac_pll(regmap, hw = sam9x60_clk_register_frac_pll(regmap,
&pmc_pll_lock, sama7g5_plls[i][j].n, &pmc_pll_lock, sama7g5_plls[i][j].n,
sama7g5_plls[i][j].p, parent_hw, i, sama7g5_plls[i][j].p, parent_hw, i,
&pll_characteristics, sama7g5_plls[i][j].c,
sama7g5_plls[i][j].l, sama7g5_plls[i][j].l,
sama7g5_plls[i][j].f); sama7g5_plls[i][j].f);
break; break;
...@@ -930,7 +963,7 @@ static void __init sama7g5_pmc_setup(struct device_node *np) ...@@ -930,7 +963,7 @@ static void __init sama7g5_pmc_setup(struct device_node *np)
hw = sam9x60_clk_register_div_pll(regmap, hw = sam9x60_clk_register_div_pll(regmap,
&pmc_pll_lock, sama7g5_plls[i][j].n, &pmc_pll_lock, sama7g5_plls[i][j].n,
sama7g5_plls[i][j].p, i, sama7g5_plls[i][j].p, i,
&pll_characteristics, sama7g5_plls[i][j].c,
sama7g5_plls[i][j].l, sama7g5_plls[i][j].l,
sama7g5_plls[i][j].f); sama7g5_plls[i][j].f);
break; break;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment