[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <5f7063f4905184ee3bf0eea48f09b79df4518b81.1750182562.git.Ryan.Wanner@microchip.com>
Date: Tue, 24 Jun 2025 08:08:27 -0700
From: <Ryan.Wanner@...rochip.com>
To: <mturquette@...libre.com>, <sboyd@...nel.org>,
<nicolas.ferre@...rochip.com>, <alexandre.belloni@...tlin.com>,
<claudiu.beznea@...on.dev>
CC: <robh@...nel.org>, <linux-clk@...r.kernel.org>,
<linux-arm-kernel@...ts.infradead.org>, <linux-kernel@...r.kernel.org>,
<varshini.rajendran@...rochip.com>, Ryan Wanner <Ryan.Wanner@...rochip.com>
Subject: [PATCH v2 30/32] clk: at91: sam9x75: switch to parent_hw and parent_data
From: Ryan Wanner <Ryan.Wanner@...rochip.com>
Switch SAM9X75 clocks to use modern parent_hw and parent_data.
Signed-off-by: Ryan Wanner <Ryan.Wanner@...rochip.com>
---
drivers/clk/at91/sam9x7.c | 330 +++++++++++++++++++++-----------------
1 file changed, 186 insertions(+), 144 deletions(-)
diff --git a/drivers/clk/at91/sam9x7.c b/drivers/clk/at91/sam9x7.c
index cbb8b220f16b..cd0d5a0884b2 100644
--- a/drivers/clk/at91/sam9x7.c
+++ b/drivers/clk/at91/sam9x7.c
@@ -33,10 +33,22 @@ enum pll_ids {
PLL_ID_UPLL,
PLL_ID_AUDIO,
PLL_ID_LVDS,
- PLL_ID_PLLA_DIV2,
PLL_ID_MAX,
};
+/*
+ * PLL component identifier
+ * @PLL_COMPID_FRAC: Fractional PLL component identifier
+ * @PLL_COMPID_DIV0: 1st PLL divider component identifier
+ * @PLL_COMPID_DIV1: 2nd PLL divider component identifier
+ */
+enum pll_component_id {
+ PLL_COMPID_FRAC,
+ PLL_COMPID_DIV0,
+ PLL_COMPID_DIV1,
+ PLL_COMPID_MAX,
+};
+
/**
* enum pll_type - PLL type identifiers
* @PLL_TYPE_FRAC: fractional PLL identifier
@@ -180,6 +192,18 @@ static const struct clk_pll_layout pll_divio_layout = {
.endiv_shift = 30,
};
+/*
+ * SAM9X7 PLL possible parents
+ * @SAM9X7_PLL_PARENT_MAINCK: MAINCK is PLL a parent
+ * @SAM9X7_PLL_PARENT_MAIN_XTAL: MAIN XTAL is a PLL parent
+ * @SAM9X7_PLL_PARENT_FRACCK: Frac PLL is a PLL parent (for PLL dividers)
+ */
+enum sam9x7_pll_parent {
+ SAM9X7_PLL_PARENT_MAINCK,
+ SAM9X7_PLL_PARENT_MAIN_XTAL,
+ SAM9X7_PLL_PARENT_FRACCK
+};
+
/*
* PLL clocks description
* @n: clock name
@@ -187,22 +211,24 @@ static const struct clk_pll_layout pll_divio_layout = {
* @l: clock layout
* @t: clock type
* @c: pll characteristics
+ * @hw: pointer to clk_hw
* @f: clock flags
* @eid: export index in sam9x7->chws[] array
*/
-static const struct {
+static struct {
const char *n;
- const char *p;
const struct clk_pll_layout *l;
u8 t;
const struct clk_pll_characteristics *c;
+ struct clk_hw *hw;
unsigned long f;
+ enum sam9x7_pll_parent p;
u8 eid;
-} sam9x7_plls[][3] = {
+} sam9x7_plls[][PLL_COMPID_MAX] = {
[PLL_ID_PLLA] = {
- {
+ [PLL_COMPID_FRAC] = {
.n = "plla_fracck",
- .p = "mainck",
+ .p = SAM9X7_PLL_PARENT_MAINCK,
.l = &plla_frac_layout,
.t = PLL_TYPE_FRAC,
/*
@@ -213,9 +239,9 @@ static const struct {
.c = &plla_characteristics,
},
- {
+ [PLL_COMPID_DIV0] = {
.n = "plla_divpmcck",
- .p = "plla_fracck",
+ .p = SAM9X7_PLL_PARENT_FRACCK,
.l = &pll_divpmc_layout,
.t = PLL_TYPE_DIV,
/* This feeds CPU. It should not be disabled */
@@ -223,21 +249,35 @@ static const struct {
.eid = PMC_PLLACK,
.c = &plla_characteristics,
},
+
+ [PLL_COMPID_DIV1] = {
+ .n = "plla_div2pmcck",
+ .p = SAM9X7_PLL_PARENT_FRACCK,
+ .l = &plladiv2_divpmc_layout,
+ /*
+ * This may feed critical parts of the system like timers.
+ * It should not be disabled.
+ */
+ .f = CLK_IS_CRITICAL | CLK_SET_RATE_GATE,
+ .c = &plladiv2_characteristics,
+ .eid = PMC_PLLADIV2,
+ .t = PLL_TYPE_DIV,
+ },
},
[PLL_ID_UPLL] = {
- {
+ [PLL_COMPID_FRAC] = {
.n = "upll_fracck",
- .p = "main_osc",
+ .p = SAM9X7_PLL_PARENT_MAIN_XTAL,
.l = &pll_frac_layout,
.t = PLL_TYPE_FRAC,
.f = CLK_SET_RATE_GATE,
.c = &upll_characteristics,
},
- {
+ [PLL_COMPID_DIV0] = {
.n = "upll_divpmcck",
- .p = "upll_fracck",
+ .p = SAM9X7_PLL_PARENT_FRACCK,
.l = &pll_divpmc_layout,
.t = PLL_TYPE_DIV,
.f = CLK_SET_RATE_GATE | CLK_SET_PARENT_GATE |
@@ -248,18 +288,18 @@ static const struct {
},
[PLL_ID_AUDIO] = {
- {
+ [PLL_COMPID_FRAC] = {
.n = "audiopll_fracck",
- .p = "main_osc",
+ .p = SAM9X7_PLL_PARENT_MAIN_XTAL,
.l = &pll_frac_layout,
.f = CLK_SET_RATE_GATE,
.c = &audiopll_characteristics,
.t = PLL_TYPE_FRAC,
},
- {
+ [PLL_COMPID_DIV0] = {
.n = "audiopll_divpmcck",
- .p = "audiopll_fracck",
+ .p = SAM9X7_PLL_PARENT_FRACCK,
.l = &pll_divpmc_layout,
.f = CLK_SET_RATE_GATE | CLK_SET_PARENT_GATE |
CLK_SET_RATE_PARENT,
@@ -268,9 +308,9 @@ static const struct {
.t = PLL_TYPE_DIV,
},
- {
+ [PLL_COMPID_DIV1] = {
.n = "audiopll_diviock",
- .p = "audiopll_fracck",
+ .p = SAM9X7_PLL_PARENT_FRACCK,
.l = &pll_divio_layout,
.f = CLK_SET_RATE_GATE | CLK_SET_PARENT_GATE |
CLK_SET_RATE_PARENT,
@@ -281,18 +321,18 @@ static const struct {
},
[PLL_ID_LVDS] = {
- {
+ [PLL_COMPID_FRAC] = {
.n = "lvdspll_fracck",
- .p = "main_osc",
+ .p = SAM9X7_PLL_PARENT_MAIN_XTAL,
.l = &pll_frac_layout,
.f = CLK_SET_RATE_GATE,
.c = &lvdspll_characteristics,
.t = PLL_TYPE_FRAC,
},
- {
+ [PLL_COMPID_DIV0] = {
.n = "lvdspll_divpmcck",
- .p = "lvdspll_fracck",
+ .p = SAM9X7_PLL_PARENT_FRACCK,
.l = &pll_divpmc_layout,
.f = CLK_SET_RATE_GATE | CLK_SET_PARENT_GATE |
CLK_SET_RATE_PARENT,
@@ -301,22 +341,6 @@ static const struct {
.t = PLL_TYPE_DIV,
},
},
-
- [PLL_ID_PLLA_DIV2] = {
- {
- .n = "plla_div2pmcck",
- .p = "plla_fracck",
- .l = &plladiv2_divpmc_layout,
- /*
- * This may feed critical parts of the system like timers.
- * It should not be disabled.
- */
- .f = CLK_IS_CRITICAL | CLK_SET_RATE_GATE,
- .c = &plladiv2_characteristics,
- .eid = PMC_PLLADIV2,
- .t = PLL_TYPE_DIV,
- },
- },
};
static const struct clk_programmable_layout sam9x7_programmable_layout = {
@@ -334,9 +358,9 @@ static const struct clk_pcr_layout sam9x7_pcr_layout = {
.pid_mask = GENMASK(6, 0),
};
-static const struct {
+static struct {
char *n;
- char *p;
+ struct clk_hw *parent_hw;
u8 id;
unsigned long flags;
} sam9x7_systemck[] = {
@@ -344,10 +368,10 @@ static const struct {
* ddrck feeds DDR controller and is enabled by bootloader thus we need
* to keep it enabled in case there is no Linux consumer for it.
*/
- { .n = "ddrck", .p = "masterck_div", .id = 2, .flags = CLK_IS_CRITICAL },
- { .n = "uhpck", .p = "usbck", .id = 6 },
- { .n = "pck0", .p = "prog0", .id = 8 },
- { .n = "pck1", .p = "prog1", .id = 9 },
+ { .n = "ddrck", .id = 2, .flags = CLK_IS_CRITICAL },
+ { .n = "uhpck", .id = 6 },
+ { .n = "pck0", .id = 8 },
+ { .n = "pck1", .id = 9 },
};
/*
@@ -420,16 +444,21 @@ static const struct {
/*
* Generic clock description
* @n: clock name
- * @pp: PLL parents
+ * @pp: PLL parents (entry formed by PLL components identifiers
+ * (see enum pll_component_id))
* @pp_mux_table: PLL parents mux table
* @r: clock output range
* @pp_chg_id: id in parent array of changeable PLL parent
* @pp_count: PLL parents count
* @id: clock id
*/
+
static const struct {
const char *n;
- const char *pp[8];
+ struct {
+ int pll_id;
+ int pll_compid;
+ } pp[8];
const char pp_mux_table[8];
struct clk_range r;
int pp_chg_id;
@@ -439,7 +468,7 @@ static const struct {
{
.n = "flex0_gclk",
.id = 5,
- .pp = { "plla_div2pmcck", },
+ .pp = { PLL_IDS_TO_ARR_ENTRY(PLLA, DIV1), },
.pp_mux_table = { 8, },
.pp_count = 1,
.pp_chg_id = INT_MIN,
@@ -448,7 +477,7 @@ static const struct {
{
.n = "flex1_gclk",
.id = 6,
- .pp = { "plla_div2pmcck", },
+ .pp = { PLL_IDS_TO_ARR_ENTRY(PLLA, DIV1), },
.pp_mux_table = { 8, },
.pp_count = 1,
.pp_chg_id = INT_MIN,
@@ -457,7 +486,7 @@ static const struct {
{
.n = "flex2_gclk",
.id = 7,
- .pp = { "plla_div2pmcck", },
+ .pp = { PLL_IDS_TO_ARR_ENTRY(PLLA, DIV1), },
.pp_mux_table = { 8, },
.pp_count = 1,
.pp_chg_id = INT_MIN,
@@ -466,7 +495,7 @@ static const struct {
{
.n = "flex3_gclk",
.id = 8,
- .pp = { "plla_div2pmcck", },
+ .pp = { PLL_IDS_TO_ARR_ENTRY(PLLA, DIV1), },
.pp_mux_table = { 8, },
.pp_count = 1,
.pp_chg_id = INT_MIN,
@@ -475,7 +504,7 @@ static const struct {
{
.n = "flex6_gclk",
.id = 9,
- .pp = { "plla_div2pmcck", },
+ .pp = { PLL_IDS_TO_ARR_ENTRY(PLLA, DIV1), },
.pp_mux_table = { 8, },
.pp_count = 1,
.pp_chg_id = INT_MIN,
@@ -484,7 +513,7 @@ static const struct {
{
.n = "flex7_gclk",
.id = 10,
- .pp = { "plla_div2pmcck", },
+ .pp = { PLL_IDS_TO_ARR_ENTRY(PLLA, DIV1), },
.pp_mux_table = { 8, },
.pp_count = 1,
.pp_chg_id = INT_MIN,
@@ -493,7 +522,7 @@ static const struct {
{
.n = "flex8_gclk",
.id = 11,
- .pp = { "plla_div2pmcck", },
+ .pp = { PLL_IDS_TO_ARR_ENTRY(PLLA, DIV1), },
.pp_mux_table = { 8, },
.pp_count = 1,
.pp_chg_id = INT_MIN,
@@ -503,7 +532,7 @@ static const struct {
.n = "sdmmc0_gclk",
.id = 12,
.r = { .max = 105000000 },
- .pp = { "audiopll_divpmcck", "plla_div2pmcck", },
+ .pp = { PLL_IDS_TO_ARR_ENTRY(AUDIO, DIV0), PLL_IDS_TO_ARR_ENTRY(PLLA, DIV1), },
.pp_mux_table = { 6, 8, },
.pp_count = 2,
.pp_chg_id = INT_MIN,
@@ -512,7 +541,7 @@ static const struct {
{
.n = "flex4_gclk",
.id = 13,
- .pp = { "plla_div2pmcck", },
+ .pp = { PLL_IDS_TO_ARR_ENTRY(PLLA, DIV1), },
.pp_mux_table = { 8, },
.pp_count = 1,
.pp_chg_id = INT_MIN,
@@ -521,7 +550,7 @@ static const struct {
{
.n = "flex5_gclk",
.id = 14,
- .pp = { "plla_div2pmcck", },
+ .pp = { PLL_IDS_TO_ARR_ENTRY(PLLA, DIV1), },
.pp_mux_table = { 8, },
.pp_count = 1,
.pp_chg_id = INT_MIN,
@@ -530,7 +559,7 @@ static const struct {
{
.n = "flex9_gclk",
.id = 15,
- .pp = { "plla_div2pmcck", },
+ .pp = { PLL_IDS_TO_ARR_ENTRY(PLLA, DIV1), },
.pp_mux_table = { 8, },
.pp_count = 1,
.pp_chg_id = INT_MIN,
@@ -539,7 +568,7 @@ static const struct {
{
.n = "flex10_gclk",
.id = 16,
- .pp = { "plla_div2pmcck", },
+ .pp = { PLL_IDS_TO_ARR_ENTRY(PLLA, DIV1), },
.pp_mux_table = { 8, },
.pp_count = 1,
.pp_chg_id = INT_MIN,
@@ -548,7 +577,7 @@ static const struct {
{
.n = "tcb0_gclk",
.id = 17,
- .pp = { "audiopll_divpmcck", "plla_div2pmcck", },
+ .pp = { PLL_IDS_TO_ARR_ENTRY(AUDIO, DIV0), PLL_IDS_TO_ARR_ENTRY(PLLA, DIV1), },
.pp_mux_table = { 6, 8, },
.pp_count = 2,
.pp_chg_id = INT_MIN,
@@ -557,7 +586,7 @@ static const struct {
{
.n = "adc_gclk",
.id = 19,
- .pp = { "upll_divpmcck", "plla_div2pmcck", },
+ .pp = { PLL_IDS_TO_ARR_ENTRY(UPLL, DIV0), PLL_IDS_TO_ARR_ENTRY(PLLA, DIV1), },
.pp_mux_table = { 5, 8, },
.pp_count = 2,
.pp_chg_id = INT_MIN,
@@ -567,7 +596,7 @@ static const struct {
.n = "lcd_gclk",
.id = 25,
.r = { .max = 75000000 },
- .pp = { "audiopll_divpmcck", "plla_div2pmcck", },
+ .pp = { PLL_IDS_TO_ARR_ENTRY(AUDIO, DIV0), PLL_IDS_TO_ARR_ENTRY(PLLA, DIV1), },
.pp_mux_table = { 6, 8, },
.pp_count = 2,
.pp_chg_id = INT_MIN,
@@ -577,7 +606,7 @@ static const struct {
.n = "sdmmc1_gclk",
.id = 26,
.r = { .max = 105000000 },
- .pp = { "audiopll_divpmcck", "plla_div2pmcck", },
+ .pp = { PLL_IDS_TO_ARR_ENTRY(AUDIO, DIV0), PLL_IDS_TO_ARR_ENTRY(PLLA, DIV1), },
.pp_mux_table = { 6, 8, },
.pp_count = 2,
.pp_chg_id = INT_MIN,
@@ -587,7 +616,7 @@ static const struct {
.n = "mcan0_gclk",
.id = 29,
.r = { .max = 80000000 },
- .pp = { "upll_divpmcck", "plla_div2pmcck", },
+ .pp = { PLL_IDS_TO_ARR_ENTRY(UPLL, DIV0), PLL_IDS_TO_ARR_ENTRY(PLLA, DIV1), },
.pp_mux_table = { 5, 8, },
.pp_count = 2,
.pp_chg_id = INT_MIN,
@@ -597,7 +626,7 @@ static const struct {
.n = "mcan1_gclk",
.id = 30,
.r = { .max = 80000000 },
- .pp = { "upll_divpmcck", "plla_div2pmcck", },
+ .pp = { PLL_IDS_TO_ARR_ENTRY(UPLL, DIV0), PLL_IDS_TO_ARR_ENTRY(PLLA, DIV1), },
.pp_mux_table = { 5, 8, },
.pp_count = 2,
.pp_chg_id = INT_MIN,
@@ -606,7 +635,7 @@ static const struct {
{
.n = "flex11_gclk",
.id = 32,
- .pp = { "plla_div2pmcck", },
+ .pp = { PLL_IDS_TO_ARR_ENTRY(PLLA, DIV1), },
.pp_mux_table = { 8, },
.pp_count = 1,
.pp_chg_id = INT_MIN,
@@ -615,7 +644,7 @@ static const struct {
{
.n = "flex12_gclk",
.id = 33,
- .pp = { "plla_div2pmcck", },
+ .pp = { PLL_IDS_TO_ARR_ENTRY(PLLA, DIV1), },
.pp_mux_table = { 8, },
.pp_count = 1,
.pp_chg_id = INT_MIN,
@@ -625,7 +654,7 @@ static const struct {
.n = "i2s_gclk",
.id = 34,
.r = { .max = 100000000 },
- .pp = { "audiopll_divpmcck", "plla_div2pmcck", },
+ .pp = { PLL_IDS_TO_ARR_ENTRY(AUDIO, DIV0), PLL_IDS_TO_ARR_ENTRY(PLLA, DIV1), },
.pp_mux_table = { 6, 8, },
.pp_count = 2,
.pp_chg_id = INT_MIN,
@@ -635,7 +664,7 @@ static const struct {
.n = "qspi_gclk",
.id = 35,
.r = { .max = 200000000 },
- .pp = { "audiopll_divpmcck", "plla_div2pmcck", },
+ .pp = { PLL_IDS_TO_ARR_ENTRY(AUDIO, DIV0), PLL_IDS_TO_ARR_ENTRY(PLLA, DIV1), },
.pp_mux_table = { 6, 8, },
.pp_count = 2,
.pp_chg_id = INT_MIN,
@@ -644,7 +673,7 @@ static const struct {
{
.n = "pit64b0_gclk",
.id = 37,
- .pp = { "plla_div2pmcck", },
+ .pp = { PLL_IDS_TO_ARR_ENTRY(PLLA, DIV1), },
.pp_mux_table = { 8, },
.pp_count = 1,
.pp_chg_id = INT_MIN,
@@ -654,7 +683,7 @@ static const struct {
.n = "classd_gclk",
.id = 42,
.r = { .max = 100000000 },
- .pp = { "audiopll_divpmcck", "plla_div2pmcck", },
+ .pp = { PLL_IDS_TO_ARR_ENTRY(AUDIO, DIV0), PLL_IDS_TO_ARR_ENTRY(PLLA, DIV1), },
.pp_mux_table = { 6, 8, },
.pp_count = 2,
.pp_chg_id = INT_MIN,
@@ -663,7 +692,7 @@ static const struct {
{
.n = "tcb1_gclk",
.id = 45,
- .pp = { "audiopll_divpmcck", "plla_div2pmcck", },
+ .pp = { PLL_IDS_TO_ARR_ENTRY(AUDIO, DIV0), PLL_IDS_TO_ARR_ENTRY(PLLA, DIV1), },
.pp_mux_table = { 6, 8, },
.pp_count = 2,
.pp_chg_id = INT_MIN,
@@ -672,7 +701,7 @@ static const struct {
{
.n = "dbgu_gclk",
.id = 47,
- .pp = { "plla_div2pmcck", },
+ .pp = { PLL_IDS_TO_ARR_ENTRY(PLLA, DIV1), },
.pp_mux_table = { 8, },
.pp_count = 1,
.pp_chg_id = INT_MIN,
@@ -682,7 +711,7 @@ static const struct {
.n = "mipiphy_gclk",
.id = 55,
.r = { .max = 27000000 },
- .pp = { "plla_div2pmcck", },
+ .pp = { PLL_IDS_TO_ARR_ENTRY(PLLA, DIV1), },
.pp_mux_table = { 8, },
.pp_count = 1,
.pp_chg_id = INT_MIN,
@@ -691,7 +720,7 @@ static const struct {
{
.n = "pit64b1_gclk",
.id = 58,
- .pp = { "plla_div2pmcck", },
+ .pp = { PLL_IDS_TO_ARR_ENTRY(PLLA, DIV1), },
.pp_mux_table = { 8, },
.pp_count = 1,
.pp_chg_id = INT_MIN,
@@ -700,7 +729,7 @@ static const struct {
{
.n = "gmac_gclk",
.id = 67,
- .pp = { "audiopll_divpmcck", "plla_div2pmcck", },
+ .pp = { PLL_IDS_TO_ARR_ENTRY(AUDIO, DIV0), PLL_IDS_TO_ARR_ENTRY(PLLA, DIV1), },
.pp_mux_table = { 6, 8, },
.pp_count = 2,
.pp_chg_id = INT_MIN,
@@ -709,34 +738,25 @@ static const struct {
static void __init sam9x7_pmc_setup(struct device_node *np)
{
+ u8 td_slck_index = 0, md_slck_index = 1, main_xtal_index = 2;
+ const char * const main_xtal_name = "main_xtal";
+ const char * const td_slck_name = "td_slck";
+ const char * const md_slck_name = "md_slck";
+ struct clk_hw *hw, *main_rc_hw, *main_osc_hw;
+ struct clk_parent_data parent_data[9];
struct clk_range range = CLK_RANGE(0, 0);
- const char *td_slck_name, *md_slck_name, *mainxtal_name;
struct pmc_data *sam9x7_pmc;
- const char *parent_names[9];
void **clk_mux_buffer = NULL;
int clk_mux_buffer_size = 0;
- struct clk_hw *main_osc_hw;
+ struct clk *main_xtal;
struct regmap *regmap;
- struct clk_hw *hw;
+ struct clk_hw *usbck_hw;
int i, j;
- i = of_property_match_string(np, "clock-names", "td_slck");
- if (i < 0)
+ main_xtal = of_clk_get(np, main_xtal_index);
+ if (IS_ERR(main_xtal))
return;
- td_slck_name = of_clk_get_parent_name(np, i);
-
- i = of_property_match_string(np, "clock-names", "md_slck");
- if (i < 0)
- return;
-
- md_slck_name = of_clk_get_parent_name(np, i);
-
- i = of_property_match_string(np, "clock-names", "main_xtal");
- if (i < 0)
- return;
- mainxtal_name = of_clk_get_parent_name(np, i);
-
regmap = device_node_to_regmap(np);
if (IS_ERR(regmap))
return;
@@ -754,46 +774,55 @@ static void __init sam9x7_pmc_setup(struct device_node *np)
if (!clk_mux_buffer)
goto err_free;
- hw = at91_clk_register_main_rc_osc(regmap, "main_rc_osc", 12000000,
- 50000000);
- if (IS_ERR(hw))
+ main_rc_hw = at91_clk_register_main_rc_osc(regmap, "main_rc_osc", 12000000,
+ 50000000);
+ if (IS_ERR(main_rc_hw))
goto err_free;
- hw = at91_clk_register_main_osc(regmap, "main_osc", mainxtal_name, NULL, 0);
- if (IS_ERR(hw))
+ main_osc_hw = at91_clk_register_main_osc(regmap, "main_osc", NULL,
+ &AT91_CLK_PD_NAME(main_xtal_name, main_xtal_index), 0);
+ if (IS_ERR(main_osc_hw))
goto err_free;
- main_osc_hw = hw;
- parent_names[0] = "main_rc_osc";
- parent_names[1] = "main_osc";
- hw = at91_clk_register_sam9x5_main(regmap, "mainck", parent_names, NULL, 2);
+ parent_data[0] = AT91_CLK_PD_HW(main_rc_hw);
+ parent_data[1] = AT91_CLK_PD_HW(main_osc_hw);
+ hw = at91_clk_register_sam9x5_main(regmap, "mainck", NULL, parent_data, 2);
if (IS_ERR(hw))
goto err_free;
sam9x7_pmc->chws[PMC_MAIN] = hw;
for (i = 0; i < PLL_ID_MAX; i++) {
- for (j = 0; j < 3; j++) {
- struct clk_hw *parent_hw;
+ for (j = 0; j < PLL_COMPID_MAX; j++) {
+ unsigned long parent_rate = 0;
if (!sam9x7_plls[i][j].n)
continue;
switch (sam9x7_plls[i][j].t) {
case PLL_TYPE_FRAC:
- if (!strcmp(sam9x7_plls[i][j].p, "mainck"))
- parent_hw = sam9x7_pmc->chws[PMC_MAIN];
- else if (!strcmp(sam9x7_plls[i][j].p, "main_osc"))
- parent_hw = main_osc_hw;
- else
- parent_hw = __clk_get_hw(of_clk_get_by_name
- (np, sam9x7_plls[i][j].p));
-
+ switch (sam9x7_plls[i][j].p) {
+ case SAM9X7_PLL_PARENT_MAINCK:
+ parent_data[0] = AT91_CLK_PD_NAME("mainck", -1);
+ parent_rate = clk_hw_get_rate(sam9x7_pmc->chws[PMC_MAIN]);
+ break;
+ case SAM9X7_PLL_PARENT_MAIN_XTAL:
+ parent_data[0] = AT91_CLK_PD_NAME(main_xtal_name,
+ main_xtal_index);
+ parent_rate = clk_get_rate(main_xtal);
+ break;
+ default:
+ /* Should not happen. */
+ break;
+ }
+
+ if (!parent_rate)
+ return;
hw = sam9x60_clk_register_frac_pll(regmap,
&pmc_pll_lock,
sam9x7_plls[i][j].n,
- sam9x7_plls[i][j].p,
- parent_hw, i,
+ parent_data,
+ parent_rate, i,
sam9x7_plls[i][j].c,
sam9x7_plls[i][j].l,
sam9x7_plls[i][j].f);
@@ -803,7 +832,7 @@ static void __init sam9x7_pmc_setup(struct device_node *np)
hw = sam9x60_clk_register_div_pll(regmap,
&pmc_pll_lock,
sam9x7_plls[i][j].n,
- sam9x7_plls[i][j].p, NULL, i,
+ NULL, sam9x7_plls[i][0].hw, i,
sam9x7_plls[i][j].c,
sam9x7_plls[i][j].l,
sam9x7_plls[i][j].f, 0);
@@ -816,23 +845,24 @@ static void __init sam9x7_pmc_setup(struct device_node *np)
if (IS_ERR(hw))
goto err_free;
+ sam9x7_plls[i][j].hw = hw;
if (sam9x7_plls[i][j].eid)
sam9x7_pmc->chws[sam9x7_plls[i][j].eid] = hw;
}
}
- parent_names[0] = md_slck_name;
- parent_names[1] = "mainck";
- parent_names[2] = "plla_divpmcck";
- parent_names[3] = "upll_divpmcck";
+ parent_data[0] = AT91_CLK_PD_NAME(md_slck_name, md_slck_index);
+ parent_data[1] = AT91_CLK_PD_HW(sam9x7_pmc->chws[PMC_MAIN]);
+ parent_data[2] = AT91_CLK_PD_HW(sam9x7_plls[PLL_ID_PLLA][PLL_COMPID_DIV0].hw);
+ parent_data[3] = AT91_CLK_PD_HW(sam9x7_plls[PLL_ID_UPLL][PLL_COMPID_DIV0].hw);
hw = at91_clk_register_master_pres(regmap, "masterck_pres", 4,
- parent_names, NULL, &sam9x7_master_layout,
+ NULL, parent_data, &sam9x7_master_layout,
&mck_characteristics, &mck_lock);
if (IS_ERR(hw))
goto err_free;
hw = at91_clk_register_master_div(regmap, "masterck_div",
- "masterck_pres", NULL, &sam9x7_master_layout,
+ NULL, &AT91_CLK_PD_HW(hw), &sam9x7_master_layout,
&mck_characteristics, &mck_lock,
CLK_SET_RATE_GATE, 0);
if (IS_ERR(hw))
@@ -840,27 +870,27 @@ static void __init sam9x7_pmc_setup(struct device_node *np)
sam9x7_pmc->chws[PMC_MCK] = hw;
- parent_names[0] = "plla_divpmcck";
- parent_names[1] = "upll_divpmcck";
- parent_names[2] = "main_osc";
- hw = sam9x60_clk_register_usb(regmap, "usbck", parent_names, 3);
+ parent_data[0] = AT91_CLK_PD_HW(sam9x7_plls[PLL_ID_PLLA][PLL_COMPID_DIV0].hw);
+ parent_data[1] = AT91_CLK_PD_HW(sam9x7_plls[PLL_ID_UPLL][PLL_COMPID_DIV0].hw);
+ parent_data[2] = AT91_CLK_PD_HW(main_osc_hw);
+ usbck_hw = sam9x60_clk_register_usb(regmap, "usbck", NULL, parent_data, 3);
if (IS_ERR(hw))
goto err_free;
- parent_names[0] = md_slck_name;
- parent_names[1] = td_slck_name;
- parent_names[2] = "mainck";
- parent_names[3] = "masterck_div";
- parent_names[4] = "plla_divpmcck";
- parent_names[5] = "upll_divpmcck";
- parent_names[6] = "audiopll_divpmcck";
+ parent_data[0] = AT91_CLK_PD_NAME(md_slck_name, md_slck_index);
+ parent_data[1] = AT91_CLK_PD_NAME(td_slck_name, td_slck_index);
+ parent_data[2] = AT91_CLK_PD_HW(sam9x7_pmc->chws[PMC_MAIN]);
+ parent_data[3] = AT91_CLK_PD_HW(sam9x7_pmc->chws[PMC_MCK]);
+ parent_data[4] = AT91_CLK_PD_HW(sam9x7_plls[PLL_ID_PLLA][PLL_COMPID_DIV0].hw);
+ parent_data[5] = AT91_CLK_PD_HW(sam9x7_plls[PLL_ID_UPLL][PLL_COMPID_DIV0].hw);
+ parent_data[6] = AT91_CLK_PD_HW(sam9x7_plls[PLL_ID_AUDIO][PLL_COMPID_DIV0].hw);
for (i = 0; i < 2; i++) {
char name[6];
snprintf(name, sizeof(name), "prog%d", i);
hw = at91_clk_register_programmable(regmap, name,
- parent_names, NULL, 7, i,
+ NULL, parent_data, 7, i,
&sam9x7_programmable_layout,
NULL);
if (IS_ERR(hw))
@@ -869,9 +899,14 @@ static void __init sam9x7_pmc_setup(struct device_node *np)
sam9x7_pmc->pchws[i] = hw;
}
+ /* Set systemck parent hws. */
+ sam9x7_systemck[0].parent_hw = sam9x7_pmc->chws[PMC_MCK];
+ sam9x7_systemck[1].parent_hw = usbck_hw;
+ sam9x7_systemck[2].parent_hw = sam9x7_pmc->pchws[0];
+ sam9x7_systemck[3].parent_hw = sam9x7_pmc->pchws[1];
for (i = 0; i < ARRAY_SIZE(sam9x7_systemck); i++) {
hw = at91_clk_register_system(regmap, sam9x7_systemck[i].n,
- sam9x7_systemck[i].p, NULL,
+ NULL, &AT91_CLK_PD_HW(sam9x7_systemck[i].parent_hw),
sam9x7_systemck[i].id,
sam9x7_systemck[i].flags);
if (IS_ERR(hw))
@@ -884,7 +919,7 @@ static void __init sam9x7_pmc_setup(struct device_node *np)
hw = at91_clk_register_sam9x5_peripheral(regmap, &pmc_pcr_lock,
&sam9x7_pcr_layout,
sam9x7_periphck[i].n,
- "masterck_div", NULL,
+ NULL, &AT91_CLK_PD_HW(sam9x7_pmc->chws[PMC_MCK]),
sam9x7_periphck[i].id,
&range, INT_MIN,
sam9x7_periphck[i].f);
@@ -894,10 +929,10 @@ static void __init sam9x7_pmc_setup(struct device_node *np)
sam9x7_pmc->phws[sam9x7_periphck[i].id] = hw;
}
- parent_names[0] = md_slck_name;
- parent_names[1] = td_slck_name;
- parent_names[2] = "mainck";
- parent_names[3] = "masterck_div";
+ parent_data[0] = AT91_CLK_PD_NAME(md_slck_name, md_slck_index);
+ parent_data[1] = AT91_CLK_PD_NAME(td_slck_name, td_slck_index);
+ parent_data[2] = AT91_CLK_PD_HW(sam9x7_pmc->chws[PMC_MAIN]);
+ parent_data[3] = AT91_CLK_PD_HW(sam9x7_pmc->chws[PMC_MCK]);
for (i = 0; i < ARRAY_SIZE(sam9x7_gck); i++) {
u8 num_parents = 4 + sam9x7_gck[i].pp_count;
u32 *mux_table;
@@ -910,13 +945,18 @@ static void __init sam9x7_pmc_setup(struct device_node *np)
PMC_INIT_TABLE(mux_table, 4);
PMC_FILL_TABLE(&mux_table[4], sam9x7_gck[i].pp_mux_table,
sam9x7_gck[i].pp_count);
- PMC_FILL_TABLE(&parent_names[4], sam9x7_gck[i].pp,
- sam9x7_gck[i].pp_count);
+
+ for (j = 0; j < sam9x7_gck[i].pp_count; j++) {
+ u8 pll_id = sam9x7_gck[i].pp[j].pll_id;
+ u8 pll_compid = sam9x7_gck[i].pp[j].pll_compid;
+
+ parent_data[4 + j] = AT91_CLK_PD_HW(sam9x7_plls[pll_id][pll_compid].hw);
+ }
hw = at91_clk_register_generated(regmap, &pmc_pcr_lock,
&sam9x7_pcr_layout,
sam9x7_gck[i].n,
- parent_names, NULL, mux_table,
+ NULL, parent_data, mux_table,
num_parents,
sam9x7_gck[i].id,
&sam9x7_gck[i].r,
@@ -931,7 +971,7 @@ static void __init sam9x7_pmc_setup(struct device_node *np)
of_clk_add_hw_provider(np, of_clk_hw_pmc_get, sam9x7_pmc);
kfree(clk_mux_buffer);
- return;
+ goto put_main_xtal;
err_free:
if (clk_mux_buffer) {
@@ -940,6 +980,8 @@ static void __init sam9x7_pmc_setup(struct device_node *np)
kfree(clk_mux_buffer);
}
kfree(sam9x7_pmc);
+put_main_xtal:
+ clk_put(main_xtal);
}
/* Some clks are used for a clocksource */
--
2.43.0
Powered by blists - more mailing lists