linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v3 0/3] clk: at91: support configuring more clock parents via DT
@ 2020-03-21 21:18 Michał Mirosław
  2020-03-21 21:18 ` [PATCH v3 1/3] clk: at91: optimize pmc data allocation Michał Mirosław
                   ` (2 more replies)
  0 siblings, 3 replies; 7+ messages in thread
From: Michał Mirosław @ 2020-03-21 21:18 UTC (permalink / raw)
  To: Alexandre Belloni, Ludovic Desroches, Michael Turquette,
	Nicolas Ferre, Stephen Boyd
  Cc: linux-clk, linux-kernel

This series extends AT91 with clock references to PCKx and
PLLA/AUDIOPLL (for sama5d2).

First patch simplifies clock table allocation. Next two update the table
with missing clock pointers and IDs.

---
v2: rebased against current clk/clk-at91 tree
v3: non-functional changes + rebase
---
Michał Mirosław (3):
  clk: at91: optimize pmc data allocation
  clk: at91: allow setting PCKx parent via DT
  clk: at91: sama5d2: allow setting all PMC clock parents via DT

 drivers/clk/at91/at91rm9200.c    |  6 +++--
 drivers/clk/at91/at91sam9260.c   |  7 +++--
 drivers/clk/at91/at91sam9g45.c   |  6 +++--
 drivers/clk/at91/at91sam9n12.c   |  6 +++--
 drivers/clk/at91/at91sam9rl.c    |  6 +++--
 drivers/clk/at91/at91sam9x5.c    |  6 +++--
 drivers/clk/at91/pmc.c           | 44 ++++++++++++--------------------
 drivers/clk/at91/pmc.h           |  8 ++++--
 drivers/clk/at91/sam9x60.c       |  6 +++--
 drivers/clk/at91/sama5d2.c       | 12 ++++++---
 drivers/clk/at91/sama5d3.c       |  6 +++--
 drivers/clk/at91/sama5d4.c       |  6 +++--
 include/dt-bindings/clock/at91.h |  3 +++
 13 files changed, 72 insertions(+), 50 deletions(-)

-- 
2.20.1


^ permalink raw reply	[flat|nested] 7+ messages in thread

* [PATCH v3 1/3] clk: at91: optimize pmc data allocation
  2020-03-21 21:18 [PATCH v3 0/3] clk: at91: support configuring more clock parents via DT Michał Mirosław
@ 2020-03-21 21:18 ` Michał Mirosław
  2020-03-25  9:37   ` Alexandre Belloni
  2020-03-21 21:18 ` [PATCH v3 2/3] clk: at91: allow setting PCKx parent via DT Michał Mirosław
  2020-03-21 21:18 ` [PATCH v3 3/3] clk: at91: sama5d2: allow setting all PMC clock parents " Michał Mirosław
  2 siblings, 1 reply; 7+ messages in thread
From: Michał Mirosław @ 2020-03-21 21:18 UTC (permalink / raw)
  To: Ludovic Desroches, Alexandre Belloni, Michael Turquette,
	Nicolas Ferre, Stephen Boyd
  Cc: linux-clk, linux-kernel

Alloc whole data structure in one block. This makes the code shorter,
more efficient and easier to extend in following patch.

Signed-off-by: Michał Mirosław <mirq-linux@rere.qmqm.pl
---
v2: rebase and update to clk/clk-at91 branch
v3: use struct_size() and C99 trailing array
    as suggested by Stephen Boyd
---
 drivers/clk/at91/at91rm9200.c  |  2 +-
 drivers/clk/at91/at91sam9260.c |  2 +-
 drivers/clk/at91/at91sam9g45.c |  2 +-
 drivers/clk/at91/at91sam9n12.c |  2 +-
 drivers/clk/at91/at91sam9rl.c  |  2 +-
 drivers/clk/at91/at91sam9x5.c  |  2 +-
 drivers/clk/at91/pmc.c         | 34 ++++++++--------------------------
 drivers/clk/at91/pmc.h         |  3 ++-
 drivers/clk/at91/sam9x60.c     |  2 +-
 drivers/clk/at91/sama5d2.c     |  2 +-
 drivers/clk/at91/sama5d3.c     |  2 +-
 drivers/clk/at91/sama5d4.c     |  2 +-
 12 files changed, 20 insertions(+), 37 deletions(-)

diff --git a/drivers/clk/at91/at91rm9200.c b/drivers/clk/at91/at91rm9200.c
index c44a431b6c97..6f4e1151553d 100644
--- a/drivers/clk/at91/at91rm9200.c
+++ b/drivers/clk/at91/at91rm9200.c
@@ -187,7 +187,7 @@ static void __init at91rm9200_pmc_setup(struct device_node *np)
 	return;
 
 err_free:
-	pmc_data_free(at91rm9200_pmc);
+	kfree(at91rm9200_pmc);
 }
 /*
  * While the TCB can be used as the clocksource, the system timer is most likely
diff --git a/drivers/clk/at91/at91sam9260.c b/drivers/clk/at91/at91sam9260.c
index a9d4234758d7..946f03a09858 100644
--- a/drivers/clk/at91/at91sam9260.c
+++ b/drivers/clk/at91/at91sam9260.c
@@ -462,7 +462,7 @@ static void __init at91sam926x_pmc_setup(struct device_node *np,
 	return;
 
 err_free:
-	pmc_data_free(at91sam9260_pmc);
+	kfree(at91sam9260_pmc);
 }
 
 static void __init at91sam9260_pmc_setup(struct device_node *np)
diff --git a/drivers/clk/at91/at91sam9g45.c b/drivers/clk/at91/at91sam9g45.c
index 38a7d2d2df0c..53e8252b8a63 100644
--- a/drivers/clk/at91/at91sam9g45.c
+++ b/drivers/clk/at91/at91sam9g45.c
@@ -210,7 +210,7 @@ static void __init at91sam9g45_pmc_setup(struct device_node *np)
 	return;
 
 err_free:
-	pmc_data_free(at91sam9g45_pmc);
+	kfree(at91sam9g45_pmc);
 }
 /*
  * The TCB is used as the clocksource so its clock is needed early. This means
diff --git a/drivers/clk/at91/at91sam9n12.c b/drivers/clk/at91/at91sam9n12.c
index 8bb39d2ba84b..f3ae1cd3cb8d 100644
--- a/drivers/clk/at91/at91sam9n12.c
+++ b/drivers/clk/at91/at91sam9n12.c
@@ -228,7 +228,7 @@ static void __init at91sam9n12_pmc_setup(struct device_node *np)
 	return;
 
 err_free:
-	pmc_data_free(at91sam9n12_pmc);
+	kfree(at91sam9n12_pmc);
 }
 /*
  * The TCB is used as the clocksource so its clock is needed early. This means
diff --git a/drivers/clk/at91/at91sam9rl.c b/drivers/clk/at91/at91sam9rl.c
index 77fe83a73bf4..cc739d214ae3 100644
--- a/drivers/clk/at91/at91sam9rl.c
+++ b/drivers/clk/at91/at91sam9rl.c
@@ -166,6 +166,6 @@ static void __init at91sam9rl_pmc_setup(struct device_node *np)
 	return;
 
 err_free:
-	pmc_data_free(at91sam9rl_pmc);
+	kfree(at91sam9rl_pmc);
 }
 CLK_OF_DECLARE_DRIVER(at91sam9rl_pmc, "atmel,at91sam9rl-pmc", at91sam9rl_pmc_setup);
diff --git a/drivers/clk/at91/at91sam9x5.c b/drivers/clk/at91/at91sam9x5.c
index 086cf0b4955c..aac99d699568 100644
--- a/drivers/clk/at91/at91sam9x5.c
+++ b/drivers/clk/at91/at91sam9x5.c
@@ -278,7 +278,7 @@ static void __init at91sam9x5_pmc_setup(struct device_node *np,
 	return;
 
 err_free:
-	pmc_data_free(at91sam9x5_pmc);
+	kfree(at91sam9x5_pmc);
 }
 
 static void __init at91sam9g15_pmc_setup(struct device_node *np)
diff --git a/drivers/clk/at91/pmc.c b/drivers/clk/at91/pmc.c
index b71515acdec1..ac46ea1b9fda 100644
--- a/drivers/clk/at91/pmc.c
+++ b/drivers/clk/at91/pmc.c
@@ -76,48 +76,30 @@ struct clk_hw *of_clk_hw_pmc_get(struct of_phandle_args *clkspec, void *data)
 	return ERR_PTR(-EINVAL);
 }
 
-void pmc_data_free(struct pmc_data *pmc_data)
-{
-	kfree(pmc_data->chws);
-	kfree(pmc_data->shws);
-	kfree(pmc_data->phws);
-	kfree(pmc_data->ghws);
-}
-
 struct pmc_data *pmc_data_allocate(unsigned int ncore, unsigned int nsystem,
 				   unsigned int nperiph, unsigned int ngck)
 {
-	struct pmc_data *pmc_data = kzalloc(sizeof(*pmc_data), GFP_KERNEL);
+	unsigned int num_clks = ncore + nsystem + nperiph + ngck;
+	struct pmc_data *pmc_data;
 
+	pmc_data = kzalloc(struct_size(pmc_data, hwtable, num_clks),
+			   GFP_KERNEL);
 	if (!pmc_data)
 		return NULL;
 
 	pmc_data->ncore = ncore;
-	pmc_data->chws = kcalloc(ncore, sizeof(struct clk_hw *), GFP_KERNEL);
-	if (!pmc_data->chws)
-		goto err;
+	pmc_data->chws = pmc_data->hwtable;
 
 	pmc_data->nsystem = nsystem;
-	pmc_data->shws = kcalloc(nsystem, sizeof(struct clk_hw *), GFP_KERNEL);
-	if (!pmc_data->shws)
-		goto err;
+	pmc_data->shws = pmc_data->chws + ncore;
 
 	pmc_data->nperiph = nperiph;
-	pmc_data->phws = kcalloc(nperiph, sizeof(struct clk_hw *), GFP_KERNEL);
-	if (!pmc_data->phws)
-		goto err;
+	pmc_data->phws = pmc_data->shws + nsystem;
 
 	pmc_data->ngck = ngck;
-	pmc_data->ghws = kcalloc(ngck, sizeof(struct clk_hw *), GFP_KERNEL);
-	if (!pmc_data->ghws)
-		goto err;
+	pmc_data->ghws = pmc_data->phws + nperiph;
 
 	return pmc_data;
-
-err:
-	pmc_data_free(pmc_data);
-
-	return NULL;
 }
 
 #ifdef CONFIG_PM
diff --git a/drivers/clk/at91/pmc.h b/drivers/clk/at91/pmc.h
index 9b8db9cdcda5..fc3ef772b9d9 100644
--- a/drivers/clk/at91/pmc.h
+++ b/drivers/clk/at91/pmc.h
@@ -24,6 +24,8 @@ struct pmc_data {
 	struct clk_hw **phws;
 	unsigned int ngck;
 	struct clk_hw **ghws;
+
+	struct clk_hw *hwtable[];
 };
 
 struct clk_range {
@@ -95,7 +97,6 @@ struct clk_pcr_layout {
 #define nck(a) (a[ARRAY_SIZE(a) - 1].id + 1)
 struct pmc_data *pmc_data_allocate(unsigned int ncore, unsigned int nsystem,
 				   unsigned int nperiph, unsigned int ngck);
-void pmc_data_free(struct pmc_data *pmc_data);
 
 int of_at91_get_clk_range(struct device_node *np, const char *propname,
 			  struct clk_range *range);
diff --git a/drivers/clk/at91/sam9x60.c b/drivers/clk/at91/sam9x60.c
index cc19e8fb83be..a7d4f648db26 100644
--- a/drivers/clk/at91/sam9x60.c
+++ b/drivers/clk/at91/sam9x60.c
@@ -299,7 +299,7 @@ static void __init sam9x60_pmc_setup(struct device_node *np)
 	return;
 
 err_free:
-	pmc_data_free(sam9x60_pmc);
+	kfree(sam9x60_pmc);
 }
 /* Some clks are used for a clocksource */
 CLK_OF_DECLARE(sam9x60_pmc, "microchip,sam9x60-pmc", sam9x60_pmc_setup);
diff --git a/drivers/clk/at91/sama5d2.c b/drivers/clk/at91/sama5d2.c
index ff7e3f727082..b2560670e5af 100644
--- a/drivers/clk/at91/sama5d2.c
+++ b/drivers/clk/at91/sama5d2.c
@@ -350,6 +350,6 @@ static void __init sama5d2_pmc_setup(struct device_node *np)
 	return;
 
 err_free:
-	pmc_data_free(sama5d2_pmc);
+	kfree(sama5d2_pmc);
 }
 CLK_OF_DECLARE_DRIVER(sama5d2_pmc, "atmel,sama5d2-pmc", sama5d2_pmc_setup);
diff --git a/drivers/clk/at91/sama5d3.c b/drivers/clk/at91/sama5d3.c
index 88506f909c08..914e6f225510 100644
--- a/drivers/clk/at91/sama5d3.c
+++ b/drivers/clk/at91/sama5d3.c
@@ -231,7 +231,7 @@ static void __init sama5d3_pmc_setup(struct device_node *np)
 	return;
 
 err_free:
-	pmc_data_free(sama5d3_pmc);
+	kfree(sama5d3_pmc);
 }
 /*
  * The TCB is used as the clocksource so its clock is needed early. This means
diff --git a/drivers/clk/at91/sama5d4.c b/drivers/clk/at91/sama5d4.c
index a6dee4a3b6e4..4ca9a4619500 100644
--- a/drivers/clk/at91/sama5d4.c
+++ b/drivers/clk/at91/sama5d4.c
@@ -267,6 +267,6 @@ static void __init sama5d4_pmc_setup(struct device_node *np)
 	return;
 
 err_free:
-	pmc_data_free(sama5d4_pmc);
+	kfree(sama5d4_pmc);
 }
 CLK_OF_DECLARE_DRIVER(sama5d4_pmc, "atmel,sama5d4-pmc", sama5d4_pmc_setup);
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH v3 2/3] clk: at91: allow setting PCKx parent via DT
  2020-03-21 21:18 [PATCH v3 0/3] clk: at91: support configuring more clock parents via DT Michał Mirosław
  2020-03-21 21:18 ` [PATCH v3 1/3] clk: at91: optimize pmc data allocation Michał Mirosław
@ 2020-03-21 21:18 ` Michał Mirosław
  2020-03-25  9:54   ` Alexandre Belloni
  2020-03-21 21:18 ` [PATCH v3 3/3] clk: at91: sama5d2: allow setting all PMC clock parents " Michał Mirosław
  2 siblings, 1 reply; 7+ messages in thread
From: Michał Mirosław @ 2020-03-21 21:18 UTC (permalink / raw)
  To: Alexandre Belloni, Ludovic Desroches, Michael Turquette,
	Nicolas Ferre, Stephen Boyd
  Cc: linux-clk, linux-kernel

This exposes PROGx clocks for use in assigned-clocks DeviceTree property
for selecting PCKx parent clock.

Signed-off-by: Michał Mirosław <mirq-linux@rere.qmqm.pl>
---
v2: rebase and update to clk/clk-at91 branch
v3: rebase
---
 drivers/clk/at91/at91rm9200.c    |  4 +++-
 drivers/clk/at91/at91sam9260.c   |  5 ++++-
 drivers/clk/at91/at91sam9g45.c   |  4 +++-
 drivers/clk/at91/at91sam9n12.c   |  4 +++-
 drivers/clk/at91/at91sam9rl.c    |  4 +++-
 drivers/clk/at91/at91sam9x5.c    |  4 +++-
 drivers/clk/at91/pmc.c           | 12 ++++++++++--
 drivers/clk/at91/pmc.h           |  5 ++++-
 drivers/clk/at91/sam9x60.c       |  4 +++-
 drivers/clk/at91/sama5d2.c       |  4 +++-
 drivers/clk/at91/sama5d3.c       |  4 +++-
 drivers/clk/at91/sama5d4.c       |  4 +++-
 include/dt-bindings/clock/at91.h |  1 +
 13 files changed, 46 insertions(+), 13 deletions(-)

diff --git a/drivers/clk/at91/at91rm9200.c b/drivers/clk/at91/at91rm9200.c
index 6f4e1151553d..8da88e9a95d8 100644
--- a/drivers/clk/at91/at91rm9200.c
+++ b/drivers/clk/at91/at91rm9200.c
@@ -100,7 +100,7 @@ static void __init at91rm9200_pmc_setup(struct device_node *np)
 
 	at91rm9200_pmc = pmc_data_allocate(PMC_MAIN + 1,
 					    nck(at91rm9200_systemck),
-					    nck(at91rm9200_periphck), 0);
+					    nck(at91rm9200_periphck), 0, 4);
 	if (!at91rm9200_pmc)
 		return;
 
@@ -159,6 +159,8 @@ static void __init at91rm9200_pmc_setup(struct device_node *np)
 						    &at91rm9200_programmable_layout);
 		if (IS_ERR(hw))
 			goto err_free;
+
+		at91rm9200_pmc->pchws[i] = hw;
 	}
 
 	for (i = 0; i < ARRAY_SIZE(at91rm9200_systemck); i++) {
diff --git a/drivers/clk/at91/at91sam9260.c b/drivers/clk/at91/at91sam9260.c
index 946f03a09858..7e5ff252fffc 100644
--- a/drivers/clk/at91/at91sam9260.c
+++ b/drivers/clk/at91/at91sam9260.c
@@ -354,7 +354,8 @@ static void __init at91sam926x_pmc_setup(struct device_node *np,
 
 	at91sam9260_pmc = pmc_data_allocate(PMC_MAIN + 1,
 					    ndck(data->sck, data->num_sck),
-					    ndck(data->pck, data->num_pck), 0);
+					    ndck(data->pck, data->num_pck),
+					    0, data->num_progck);
 	if (!at91sam9260_pmc)
 		return;
 
@@ -434,6 +435,8 @@ static void __init at91sam926x_pmc_setup(struct device_node *np,
 						    &at91rm9200_programmable_layout);
 		if (IS_ERR(hw))
 			goto err_free;
+
+		at91sam9260_pmc->pchws[i] = hw;
 	}
 
 	for (i = 0; i < data->num_sck; i++) {
diff --git a/drivers/clk/at91/at91sam9g45.c b/drivers/clk/at91/at91sam9g45.c
index 53e8252b8a63..5d18eb04c218 100644
--- a/drivers/clk/at91/at91sam9g45.c
+++ b/drivers/clk/at91/at91sam9g45.c
@@ -117,7 +117,7 @@ static void __init at91sam9g45_pmc_setup(struct device_node *np)
 
 	at91sam9g45_pmc = pmc_data_allocate(PMC_MAIN + 1,
 					    nck(at91sam9g45_systemck),
-					    nck(at91sam9g45_periphck), 0);
+					    nck(at91sam9g45_periphck), 0, 2);
 	if (!at91sam9g45_pmc)
 		return;
 
@@ -182,6 +182,8 @@ static void __init at91sam9g45_pmc_setup(struct device_node *np)
 						    &at91sam9g45_programmable_layout);
 		if (IS_ERR(hw))
 			goto err_free;
+
+		at91sam9g45_pmc->pchws[i] = hw;
 	}
 
 	for (i = 0; i < ARRAY_SIZE(at91sam9g45_systemck); i++) {
diff --git a/drivers/clk/at91/at91sam9n12.c b/drivers/clk/at91/at91sam9n12.c
index f3ae1cd3cb8d..3a2564c2f724 100644
--- a/drivers/clk/at91/at91sam9n12.c
+++ b/drivers/clk/at91/at91sam9n12.c
@@ -129,7 +129,7 @@ static void __init at91sam9n12_pmc_setup(struct device_node *np)
 		return;
 
 	at91sam9n12_pmc = pmc_data_allocate(PMC_MAIN + 1,
-					   nck(at91sam9n12_systemck), 31, 0);
+					   nck(at91sam9n12_systemck), 31, 0, 2);
 	if (!at91sam9n12_pmc)
 		return;
 
@@ -198,6 +198,8 @@ static void __init at91sam9n12_pmc_setup(struct device_node *np)
 						    &at91sam9x5_programmable_layout);
 		if (IS_ERR(hw))
 			goto err_free;
+
+		at91sam9n12_pmc->pchws[i] = hw;
 	}
 
 	for (i = 0; i < ARRAY_SIZE(at91sam9n12_systemck); i++) {
diff --git a/drivers/clk/at91/at91sam9rl.c b/drivers/clk/at91/at91sam9rl.c
index cc739d214ae3..bcf07f6a0e0e 100644
--- a/drivers/clk/at91/at91sam9rl.c
+++ b/drivers/clk/at91/at91sam9rl.c
@@ -89,7 +89,7 @@ static void __init at91sam9rl_pmc_setup(struct device_node *np)
 
 	at91sam9rl_pmc = pmc_data_allocate(PMC_MAIN + 1,
 					   nck(at91sam9rl_systemck),
-					   nck(at91sam9rl_periphck), 0);
+					   nck(at91sam9rl_periphck), 0, 2);
 	if (!at91sam9rl_pmc)
 		return;
 
@@ -138,6 +138,8 @@ static void __init at91sam9rl_pmc_setup(struct device_node *np)
 						    &at91rm9200_programmable_layout);
 		if (IS_ERR(hw))
 			goto err_free;
+
+		at91sam9rl_pmc->pchws[i] = hw;
 	}
 
 	for (i = 0; i < ARRAY_SIZE(at91sam9rl_systemck); i++) {
diff --git a/drivers/clk/at91/at91sam9x5.c b/drivers/clk/at91/at91sam9x5.c
index aac99d699568..f13756b407e2 100644
--- a/drivers/clk/at91/at91sam9x5.c
+++ b/drivers/clk/at91/at91sam9x5.c
@@ -151,7 +151,7 @@ static void __init at91sam9x5_pmc_setup(struct device_node *np,
 		return;
 
 	at91sam9x5_pmc = pmc_data_allocate(PMC_MAIN + 1,
-					   nck(at91sam9x5_systemck), 31, 0);
+					   nck(at91sam9x5_systemck), 31, 0, 2);
 	if (!at91sam9x5_pmc)
 		return;
 
@@ -227,6 +227,8 @@ static void __init at91sam9x5_pmc_setup(struct device_node *np,
 						    &at91sam9x5_programmable_layout);
 		if (IS_ERR(hw))
 			goto err_free;
+
+		at91sam9x5_pmc->pchws[i] = hw;
 	}
 
 	for (i = 0; i < ARRAY_SIZE(at91sam9x5_systemck); i++) {
diff --git a/drivers/clk/at91/pmc.c b/drivers/clk/at91/pmc.c
index ac46ea1b9fda..8a1577e2c2fd 100644
--- a/drivers/clk/at91/pmc.c
+++ b/drivers/clk/at91/pmc.c
@@ -67,6 +67,10 @@ struct clk_hw *of_clk_hw_pmc_get(struct of_phandle_args *clkspec, void *data)
 		if (idx < pmc_data->ngck)
 			return pmc_data->ghws[idx];
 		break;
+	case PMC_TYPE_PROGRAMMABLE:
+		if (idx < pmc_data->npck)
+			return pmc_data->pchws[idx];
+		break;
 	default:
 		break;
 	}
@@ -77,9 +81,10 @@ struct clk_hw *of_clk_hw_pmc_get(struct of_phandle_args *clkspec, void *data)
 }
 
 struct pmc_data *pmc_data_allocate(unsigned int ncore, unsigned int nsystem,
-				   unsigned int nperiph, unsigned int ngck)
+				   unsigned int nperiph, unsigned int ngck,
+				   unsigned int npck)
 {
-	unsigned int num_clks = ncore + nsystem + nperiph + ngck;
+	unsigned int num_clks = ncore + nsystem + nperiph + ngck + npck;
 	struct pmc_data *pmc_data;
 
 	pmc_data = kzalloc(struct_size(pmc_data, hwtable, num_clks),
@@ -99,6 +104,9 @@ struct pmc_data *pmc_data_allocate(unsigned int ncore, unsigned int nsystem,
 	pmc_data->ngck = ngck;
 	pmc_data->ghws = pmc_data->phws + nperiph;
 
+	pmc_data->npck = npck;
+	pmc_data->pchws = pmc_data->ghws + ngck;
+
 	return pmc_data;
 }
 
diff --git a/drivers/clk/at91/pmc.h b/drivers/clk/at91/pmc.h
index fc3ef772b9d9..df616f2937e7 100644
--- a/drivers/clk/at91/pmc.h
+++ b/drivers/clk/at91/pmc.h
@@ -24,6 +24,8 @@ struct pmc_data {
 	struct clk_hw **phws;
 	unsigned int ngck;
 	struct clk_hw **ghws;
+	unsigned int npck;
+	struct clk_hw **pchws;
 
 	struct clk_hw *hwtable[];
 };
@@ -96,7 +98,8 @@ struct clk_pcr_layout {
 #define ndck(a, s) (a[s - 1].id + 1)
 #define nck(a) (a[ARRAY_SIZE(a) - 1].id + 1)
 struct pmc_data *pmc_data_allocate(unsigned int ncore, unsigned int nsystem,
-				   unsigned int nperiph, unsigned int ngck);
+				   unsigned int nperiph, unsigned int ngck,
+				   unsigned int npck);
 
 int of_at91_get_clk_range(struct device_node *np, const char *propname,
 			  struct clk_range *range);
diff --git a/drivers/clk/at91/sam9x60.c b/drivers/clk/at91/sam9x60.c
index a7d4f648db26..db14e0427c7f 100644
--- a/drivers/clk/at91/sam9x60.c
+++ b/drivers/clk/at91/sam9x60.c
@@ -185,7 +185,7 @@ static void __init sam9x60_pmc_setup(struct device_node *np)
 	sam9x60_pmc = pmc_data_allocate(PMC_MAIN + 1,
 					nck(sam9x60_systemck),
 					nck(sam9x60_periphck),
-					nck(sam9x60_gck));
+					nck(sam9x60_gck), 8);
 	if (!sam9x60_pmc)
 		return;
 
@@ -255,6 +255,8 @@ static void __init sam9x60_pmc_setup(struct device_node *np)
 						    &sam9x60_programmable_layout);
 		if (IS_ERR(hw))
 			goto err_free;
+
+		sam9x60_pmc->pchws[i] = hw;
 	}
 
 	for (i = 0; i < ARRAY_SIZE(sam9x60_systemck); i++) {
diff --git a/drivers/clk/at91/sama5d2.c b/drivers/clk/at91/sama5d2.c
index b2560670e5af..ae5e83cadb3d 100644
--- a/drivers/clk/at91/sama5d2.c
+++ b/drivers/clk/at91/sama5d2.c
@@ -169,7 +169,7 @@ static void __init sama5d2_pmc_setup(struct device_node *np)
 	sama5d2_pmc = pmc_data_allocate(PMC_I2S1_MUX + 1,
 					nck(sama5d2_systemck),
 					nck(sama5d2_periph32ck),
-					nck(sama5d2_gck));
+					nck(sama5d2_gck), 3);
 	if (!sama5d2_pmc)
 		return;
 
@@ -267,6 +267,8 @@ static void __init sama5d2_pmc_setup(struct device_node *np)
 						    &sama5d2_programmable_layout);
 		if (IS_ERR(hw))
 			goto err_free;
+
+		sama5d2_pmc->pchws[i] = hw;
 	}
 
 	for (i = 0; i < ARRAY_SIZE(sama5d2_systemck); i++) {
diff --git a/drivers/clk/at91/sama5d3.c b/drivers/clk/at91/sama5d3.c
index 914e6f225510..507eef6797f1 100644
--- a/drivers/clk/at91/sama5d3.c
+++ b/drivers/clk/at91/sama5d3.c
@@ -127,7 +127,7 @@ static void __init sama5d3_pmc_setup(struct device_node *np)
 
 	sama5d3_pmc = pmc_data_allocate(PMC_MAIN + 1,
 					nck(sama5d3_systemck),
-					nck(sama5d3_periphck), 0);
+					nck(sama5d3_periphck), 0, 3);
 	if (!sama5d3_pmc)
 		return;
 
@@ -201,6 +201,8 @@ static void __init sama5d3_pmc_setup(struct device_node *np)
 						    &at91sam9x5_programmable_layout);
 		if (IS_ERR(hw))
 			goto err_free;
+
+		sama5d3_pmc->pchws[i] = hw;
 	}
 
 	for (i = 0; i < ARRAY_SIZE(sama5d3_systemck); i++) {
diff --git a/drivers/clk/at91/sama5d4.c b/drivers/clk/at91/sama5d4.c
index 4ca9a4619500..80692902b4e4 100644
--- a/drivers/clk/at91/sama5d4.c
+++ b/drivers/clk/at91/sama5d4.c
@@ -142,7 +142,7 @@ static void __init sama5d4_pmc_setup(struct device_node *np)
 
 	sama5d4_pmc = pmc_data_allocate(PMC_MCK2 + 1,
 					nck(sama5d4_systemck),
-					nck(sama5d4_periph32ck), 0);
+					nck(sama5d4_periph32ck), 0, 3);
 	if (!sama5d4_pmc)
 		return;
 
@@ -224,6 +224,8 @@ static void __init sama5d4_pmc_setup(struct device_node *np)
 						    &at91sam9x5_programmable_layout);
 		if (IS_ERR(hw))
 			goto err_free;
+
+		sama5d4_pmc->pchws[i] = hw;
 	}
 
 	for (i = 0; i < ARRAY_SIZE(sama5d4_systemck); i++) {
diff --git a/include/dt-bindings/clock/at91.h b/include/dt-bindings/clock/at91.h
index 38b5554153c8..c3f4aa6a2d29 100644
--- a/include/dt-bindings/clock/at91.h
+++ b/include/dt-bindings/clock/at91.h
@@ -12,6 +12,7 @@
 #define PMC_TYPE_SYSTEM		1
 #define PMC_TYPE_PERIPHERAL	2
 #define PMC_TYPE_GCK		3
+#define PMC_TYPE_PROGRAMMABLE	4
 
 #define PMC_SLOW		0
 #define PMC_MCK			1
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH v3 3/3] clk: at91: sama5d2: allow setting all PMC clock parents via DT
  2020-03-21 21:18 [PATCH v3 0/3] clk: at91: support configuring more clock parents via DT Michał Mirosław
  2020-03-21 21:18 ` [PATCH v3 1/3] clk: at91: optimize pmc data allocation Michał Mirosław
  2020-03-21 21:18 ` [PATCH v3 2/3] clk: at91: allow setting PCKx parent via DT Michał Mirosław
@ 2020-03-21 21:18 ` Michał Mirosław
  2020-03-25  9:55   ` Alexandre Belloni
  2 siblings, 1 reply; 7+ messages in thread
From: Michał Mirosław @ 2020-03-21 21:18 UTC (permalink / raw)
  To: Alexandre Belloni, Ludovic Desroches, Michael Turquette,
	Nicolas Ferre, Stephen Boyd
  Cc: linux-clk, linux-kernel

We need to have clocks accessible via phandle to select them
as peripheral clock parent using assigned-clock-parents in DT.
PLLACK and AUDIOPLLCK were missing for sama5d2. Add them.

Signed-off-by: Michał Mirosław <mirq-linux@rere.qmqm.pl>
---
v2: rebase to clk/clk-at91 branch
v3: no changes
---
 drivers/clk/at91/sama5d2.c       | 6 +++++-
 include/dt-bindings/clock/at91.h | 2 ++
 2 files changed, 7 insertions(+), 1 deletion(-)

diff --git a/drivers/clk/at91/sama5d2.c b/drivers/clk/at91/sama5d2.c
index ae5e83cadb3d..b3fa2291ccd8 100644
--- a/drivers/clk/at91/sama5d2.c
+++ b/drivers/clk/at91/sama5d2.c
@@ -166,7 +166,7 @@ static void __init sama5d2_pmc_setup(struct device_node *np)
 	if (IS_ERR(regmap))
 		return;
 
-	sama5d2_pmc = pmc_data_allocate(PMC_I2S1_MUX + 1,
+	sama5d2_pmc = pmc_data_allocate(PMC_AUDIOPLLCK + 1,
 					nck(sama5d2_systemck),
 					nck(sama5d2_periph32ck),
 					nck(sama5d2_gck), 3);
@@ -202,6 +202,8 @@ static void __init sama5d2_pmc_setup(struct device_node *np)
 	if (IS_ERR(hw))
 		goto err_free;
 
+	sama5d2_pmc->chws[PMC_PLLACK] = hw;
+
 	hw = at91_clk_register_audio_pll_frac(regmap, "audiopll_fracck",
 					      "mainck");
 	if (IS_ERR(hw))
@@ -217,6 +219,8 @@ static void __init sama5d2_pmc_setup(struct device_node *np)
 	if (IS_ERR(hw))
 		goto err_free;
 
+	sama5d2_pmc->chws[PMC_AUDIOPLLCK] = hw;
+
 	regmap_sfr = syscon_regmap_lookup_by_compatible("atmel,sama5d2-sfr");
 	if (IS_ERR(regmap_sfr))
 		regmap_sfr = NULL;
diff --git a/include/dt-bindings/clock/at91.h b/include/dt-bindings/clock/at91.h
index c3f4aa6a2d29..e57362e98129 100644
--- a/include/dt-bindings/clock/at91.h
+++ b/include/dt-bindings/clock/at91.h
@@ -21,6 +21,8 @@
 #define PMC_MCK2		4
 #define PMC_I2S0_MUX		5
 #define PMC_I2S1_MUX		6
+#define PMC_PLLACK		7
+#define PMC_AUDIOPLLCK		8
 
 #ifndef AT91_PMC_MOSCS
 #define AT91_PMC_MOSCS		0		/* MOSCS Flag */
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* Re: [PATCH v3 1/3] clk: at91: optimize pmc data allocation
  2020-03-21 21:18 ` [PATCH v3 1/3] clk: at91: optimize pmc data allocation Michał Mirosław
@ 2020-03-25  9:37   ` Alexandre Belloni
  0 siblings, 0 replies; 7+ messages in thread
From: Alexandre Belloni @ 2020-03-25  9:37 UTC (permalink / raw)
  To: Michał Mirosław
  Cc: Ludovic Desroches, Michael Turquette, Nicolas Ferre,
	Stephen Boyd, linux-clk, linux-kernel

Hi,

On 21/03/2020 22:18:03+0100, Michał Mirosław wrote:
> Alloc whole data structure in one block. This makes the code shorter,
> more efficient and easier to extend in following patch.
> 
> Signed-off-by: Michał Mirosław <mirq-linux@rere.qmqm.pl

You are missing a '>'

Acked-by: Alexandre Belloni <alexandre.belloni@bootlin.com>

> ---
> v2: rebase and update to clk/clk-at91 branch
> v3: use struct_size() and C99 trailing array
>     as suggested by Stephen Boyd
> ---
>  drivers/clk/at91/at91rm9200.c  |  2 +-
>  drivers/clk/at91/at91sam9260.c |  2 +-
>  drivers/clk/at91/at91sam9g45.c |  2 +-
>  drivers/clk/at91/at91sam9n12.c |  2 +-
>  drivers/clk/at91/at91sam9rl.c  |  2 +-
>  drivers/clk/at91/at91sam9x5.c  |  2 +-
>  drivers/clk/at91/pmc.c         | 34 ++++++++--------------------------
>  drivers/clk/at91/pmc.h         |  3 ++-
>  drivers/clk/at91/sam9x60.c     |  2 +-
>  drivers/clk/at91/sama5d2.c     |  2 +-
>  drivers/clk/at91/sama5d3.c     |  2 +-
>  drivers/clk/at91/sama5d4.c     |  2 +-
>  12 files changed, 20 insertions(+), 37 deletions(-)
> 
> diff --git a/drivers/clk/at91/at91rm9200.c b/drivers/clk/at91/at91rm9200.c
> index c44a431b6c97..6f4e1151553d 100644
> --- a/drivers/clk/at91/at91rm9200.c
> +++ b/drivers/clk/at91/at91rm9200.c
> @@ -187,7 +187,7 @@ static void __init at91rm9200_pmc_setup(struct device_node *np)
>  	return;
>  
>  err_free:
> -	pmc_data_free(at91rm9200_pmc);
> +	kfree(at91rm9200_pmc);
>  }
>  /*
>   * While the TCB can be used as the clocksource, the system timer is most likely
> diff --git a/drivers/clk/at91/at91sam9260.c b/drivers/clk/at91/at91sam9260.c
> index a9d4234758d7..946f03a09858 100644
> --- a/drivers/clk/at91/at91sam9260.c
> +++ b/drivers/clk/at91/at91sam9260.c
> @@ -462,7 +462,7 @@ static void __init at91sam926x_pmc_setup(struct device_node *np,
>  	return;
>  
>  err_free:
> -	pmc_data_free(at91sam9260_pmc);
> +	kfree(at91sam9260_pmc);
>  }
>  
>  static void __init at91sam9260_pmc_setup(struct device_node *np)
> diff --git a/drivers/clk/at91/at91sam9g45.c b/drivers/clk/at91/at91sam9g45.c
> index 38a7d2d2df0c..53e8252b8a63 100644
> --- a/drivers/clk/at91/at91sam9g45.c
> +++ b/drivers/clk/at91/at91sam9g45.c
> @@ -210,7 +210,7 @@ static void __init at91sam9g45_pmc_setup(struct device_node *np)
>  	return;
>  
>  err_free:
> -	pmc_data_free(at91sam9g45_pmc);
> +	kfree(at91sam9g45_pmc);
>  }
>  /*
>   * The TCB is used as the clocksource so its clock is needed early. This means
> diff --git a/drivers/clk/at91/at91sam9n12.c b/drivers/clk/at91/at91sam9n12.c
> index 8bb39d2ba84b..f3ae1cd3cb8d 100644
> --- a/drivers/clk/at91/at91sam9n12.c
> +++ b/drivers/clk/at91/at91sam9n12.c
> @@ -228,7 +228,7 @@ static void __init at91sam9n12_pmc_setup(struct device_node *np)
>  	return;
>  
>  err_free:
> -	pmc_data_free(at91sam9n12_pmc);
> +	kfree(at91sam9n12_pmc);
>  }
>  /*
>   * The TCB is used as the clocksource so its clock is needed early. This means
> diff --git a/drivers/clk/at91/at91sam9rl.c b/drivers/clk/at91/at91sam9rl.c
> index 77fe83a73bf4..cc739d214ae3 100644
> --- a/drivers/clk/at91/at91sam9rl.c
> +++ b/drivers/clk/at91/at91sam9rl.c
> @@ -166,6 +166,6 @@ static void __init at91sam9rl_pmc_setup(struct device_node *np)
>  	return;
>  
>  err_free:
> -	pmc_data_free(at91sam9rl_pmc);
> +	kfree(at91sam9rl_pmc);
>  }
>  CLK_OF_DECLARE_DRIVER(at91sam9rl_pmc, "atmel,at91sam9rl-pmc", at91sam9rl_pmc_setup);
> diff --git a/drivers/clk/at91/at91sam9x5.c b/drivers/clk/at91/at91sam9x5.c
> index 086cf0b4955c..aac99d699568 100644
> --- a/drivers/clk/at91/at91sam9x5.c
> +++ b/drivers/clk/at91/at91sam9x5.c
> @@ -278,7 +278,7 @@ static void __init at91sam9x5_pmc_setup(struct device_node *np,
>  	return;
>  
>  err_free:
> -	pmc_data_free(at91sam9x5_pmc);
> +	kfree(at91sam9x5_pmc);
>  }
>  
>  static void __init at91sam9g15_pmc_setup(struct device_node *np)
> diff --git a/drivers/clk/at91/pmc.c b/drivers/clk/at91/pmc.c
> index b71515acdec1..ac46ea1b9fda 100644
> --- a/drivers/clk/at91/pmc.c
> +++ b/drivers/clk/at91/pmc.c
> @@ -76,48 +76,30 @@ struct clk_hw *of_clk_hw_pmc_get(struct of_phandle_args *clkspec, void *data)
>  	return ERR_PTR(-EINVAL);
>  }
>  
> -void pmc_data_free(struct pmc_data *pmc_data)
> -{
> -	kfree(pmc_data->chws);
> -	kfree(pmc_data->shws);
> -	kfree(pmc_data->phws);
> -	kfree(pmc_data->ghws);
> -}
> -
>  struct pmc_data *pmc_data_allocate(unsigned int ncore, unsigned int nsystem,
>  				   unsigned int nperiph, unsigned int ngck)
>  {
> -	struct pmc_data *pmc_data = kzalloc(sizeof(*pmc_data), GFP_KERNEL);
> +	unsigned int num_clks = ncore + nsystem + nperiph + ngck;
> +	struct pmc_data *pmc_data;
>  
> +	pmc_data = kzalloc(struct_size(pmc_data, hwtable, num_clks),
> +			   GFP_KERNEL);
>  	if (!pmc_data)
>  		return NULL;
>  
>  	pmc_data->ncore = ncore;
> -	pmc_data->chws = kcalloc(ncore, sizeof(struct clk_hw *), GFP_KERNEL);
> -	if (!pmc_data->chws)
> -		goto err;
> +	pmc_data->chws = pmc_data->hwtable;
>  
>  	pmc_data->nsystem = nsystem;
> -	pmc_data->shws = kcalloc(nsystem, sizeof(struct clk_hw *), GFP_KERNEL);
> -	if (!pmc_data->shws)
> -		goto err;
> +	pmc_data->shws = pmc_data->chws + ncore;
>  
>  	pmc_data->nperiph = nperiph;
> -	pmc_data->phws = kcalloc(nperiph, sizeof(struct clk_hw *), GFP_KERNEL);
> -	if (!pmc_data->phws)
> -		goto err;
> +	pmc_data->phws = pmc_data->shws + nsystem;
>  
>  	pmc_data->ngck = ngck;
> -	pmc_data->ghws = kcalloc(ngck, sizeof(struct clk_hw *), GFP_KERNEL);
> -	if (!pmc_data->ghws)
> -		goto err;
> +	pmc_data->ghws = pmc_data->phws + nperiph;
>  
>  	return pmc_data;
> -
> -err:
> -	pmc_data_free(pmc_data);
> -
> -	return NULL;
>  }
>  
>  #ifdef CONFIG_PM
> diff --git a/drivers/clk/at91/pmc.h b/drivers/clk/at91/pmc.h
> index 9b8db9cdcda5..fc3ef772b9d9 100644
> --- a/drivers/clk/at91/pmc.h
> +++ b/drivers/clk/at91/pmc.h
> @@ -24,6 +24,8 @@ struct pmc_data {
>  	struct clk_hw **phws;
>  	unsigned int ngck;
>  	struct clk_hw **ghws;
> +
> +	struct clk_hw *hwtable[];
>  };
>  
>  struct clk_range {
> @@ -95,7 +97,6 @@ struct clk_pcr_layout {
>  #define nck(a) (a[ARRAY_SIZE(a) - 1].id + 1)
>  struct pmc_data *pmc_data_allocate(unsigned int ncore, unsigned int nsystem,
>  				   unsigned int nperiph, unsigned int ngck);
> -void pmc_data_free(struct pmc_data *pmc_data);
>  
>  int of_at91_get_clk_range(struct device_node *np, const char *propname,
>  			  struct clk_range *range);
> diff --git a/drivers/clk/at91/sam9x60.c b/drivers/clk/at91/sam9x60.c
> index cc19e8fb83be..a7d4f648db26 100644
> --- a/drivers/clk/at91/sam9x60.c
> +++ b/drivers/clk/at91/sam9x60.c
> @@ -299,7 +299,7 @@ static void __init sam9x60_pmc_setup(struct device_node *np)
>  	return;
>  
>  err_free:
> -	pmc_data_free(sam9x60_pmc);
> +	kfree(sam9x60_pmc);
>  }
>  /* Some clks are used for a clocksource */
>  CLK_OF_DECLARE(sam9x60_pmc, "microchip,sam9x60-pmc", sam9x60_pmc_setup);
> diff --git a/drivers/clk/at91/sama5d2.c b/drivers/clk/at91/sama5d2.c
> index ff7e3f727082..b2560670e5af 100644
> --- a/drivers/clk/at91/sama5d2.c
> +++ b/drivers/clk/at91/sama5d2.c
> @@ -350,6 +350,6 @@ static void __init sama5d2_pmc_setup(struct device_node *np)
>  	return;
>  
>  err_free:
> -	pmc_data_free(sama5d2_pmc);
> +	kfree(sama5d2_pmc);
>  }
>  CLK_OF_DECLARE_DRIVER(sama5d2_pmc, "atmel,sama5d2-pmc", sama5d2_pmc_setup);
> diff --git a/drivers/clk/at91/sama5d3.c b/drivers/clk/at91/sama5d3.c
> index 88506f909c08..914e6f225510 100644
> --- a/drivers/clk/at91/sama5d3.c
> +++ b/drivers/clk/at91/sama5d3.c
> @@ -231,7 +231,7 @@ static void __init sama5d3_pmc_setup(struct device_node *np)
>  	return;
>  
>  err_free:
> -	pmc_data_free(sama5d3_pmc);
> +	kfree(sama5d3_pmc);
>  }
>  /*
>   * The TCB is used as the clocksource so its clock is needed early. This means
> diff --git a/drivers/clk/at91/sama5d4.c b/drivers/clk/at91/sama5d4.c
> index a6dee4a3b6e4..4ca9a4619500 100644
> --- a/drivers/clk/at91/sama5d4.c
> +++ b/drivers/clk/at91/sama5d4.c
> @@ -267,6 +267,6 @@ static void __init sama5d4_pmc_setup(struct device_node *np)
>  	return;
>  
>  err_free:
> -	pmc_data_free(sama5d4_pmc);
> +	kfree(sama5d4_pmc);
>  }
>  CLK_OF_DECLARE_DRIVER(sama5d4_pmc, "atmel,sama5d4-pmc", sama5d4_pmc_setup);
> -- 
> 2.20.1
> 

-- 
Alexandre Belloni, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH v3 2/3] clk: at91: allow setting PCKx parent via DT
  2020-03-21 21:18 ` [PATCH v3 2/3] clk: at91: allow setting PCKx parent via DT Michał Mirosław
@ 2020-03-25  9:54   ` Alexandre Belloni
  0 siblings, 0 replies; 7+ messages in thread
From: Alexandre Belloni @ 2020-03-25  9:54 UTC (permalink / raw)
  To: Michał Mirosław
  Cc: Ludovic Desroches, Michael Turquette, Nicolas Ferre,
	Stephen Boyd, linux-clk, linux-kernel

On 21/03/2020 22:18:03+0100, Michał Mirosław wrote:
> This exposes PROGx clocks for use in assigned-clocks DeviceTree property
> for selecting PCKx parent clock.
> 

I'm wondering whether this is really necessary, you could assign the
clock rate to the PCK and the parent end prescaler selection would be
done properly. That was my reasoning behind not exposing the internal
clocks of the PMC.

> Signed-off-by: Michał Mirosław <mirq-linux@rere.qmqm.pl>
> ---
> v2: rebase and update to clk/clk-at91 branch
> v3: rebase
> ---
>  drivers/clk/at91/at91rm9200.c    |  4 +++-
>  drivers/clk/at91/at91sam9260.c   |  5 ++++-
>  drivers/clk/at91/at91sam9g45.c   |  4 +++-
>  drivers/clk/at91/at91sam9n12.c   |  4 +++-
>  drivers/clk/at91/at91sam9rl.c    |  4 +++-
>  drivers/clk/at91/at91sam9x5.c    |  4 +++-
>  drivers/clk/at91/pmc.c           | 12 ++++++++++--
>  drivers/clk/at91/pmc.h           |  5 ++++-
>  drivers/clk/at91/sam9x60.c       |  4 +++-
>  drivers/clk/at91/sama5d2.c       |  4 +++-
>  drivers/clk/at91/sama5d3.c       |  4 +++-
>  drivers/clk/at91/sama5d4.c       |  4 +++-
>  include/dt-bindings/clock/at91.h |  1 +
>  13 files changed, 46 insertions(+), 13 deletions(-)
> 
> diff --git a/drivers/clk/at91/at91rm9200.c b/drivers/clk/at91/at91rm9200.c
> index 6f4e1151553d..8da88e9a95d8 100644
> --- a/drivers/clk/at91/at91rm9200.c
> +++ b/drivers/clk/at91/at91rm9200.c
> @@ -100,7 +100,7 @@ static void __init at91rm9200_pmc_setup(struct device_node *np)
>  
>  	at91rm9200_pmc = pmc_data_allocate(PMC_MAIN + 1,
>  					    nck(at91rm9200_systemck),
> -					    nck(at91rm9200_periphck), 0);
> +					    nck(at91rm9200_periphck), 0, 4);
>  	if (!at91rm9200_pmc)
>  		return;
>  
> @@ -159,6 +159,8 @@ static void __init at91rm9200_pmc_setup(struct device_node *np)
>  						    &at91rm9200_programmable_layout);
>  		if (IS_ERR(hw))
>  			goto err_free;
> +
> +		at91rm9200_pmc->pchws[i] = hw;
>  	}
>  
>  	for (i = 0; i < ARRAY_SIZE(at91rm9200_systemck); i++) {
> diff --git a/drivers/clk/at91/at91sam9260.c b/drivers/clk/at91/at91sam9260.c
> index 946f03a09858..7e5ff252fffc 100644
> --- a/drivers/clk/at91/at91sam9260.c
> +++ b/drivers/clk/at91/at91sam9260.c
> @@ -354,7 +354,8 @@ static void __init at91sam926x_pmc_setup(struct device_node *np,
>  
>  	at91sam9260_pmc = pmc_data_allocate(PMC_MAIN + 1,
>  					    ndck(data->sck, data->num_sck),
> -					    ndck(data->pck, data->num_pck), 0);
> +					    ndck(data->pck, data->num_pck),
> +					    0, data->num_progck);
>  	if (!at91sam9260_pmc)
>  		return;
>  
> @@ -434,6 +435,8 @@ static void __init at91sam926x_pmc_setup(struct device_node *np,
>  						    &at91rm9200_programmable_layout);
>  		if (IS_ERR(hw))
>  			goto err_free;
> +
> +		at91sam9260_pmc->pchws[i] = hw;
>  	}
>  
>  	for (i = 0; i < data->num_sck; i++) {
> diff --git a/drivers/clk/at91/at91sam9g45.c b/drivers/clk/at91/at91sam9g45.c
> index 53e8252b8a63..5d18eb04c218 100644
> --- a/drivers/clk/at91/at91sam9g45.c
> +++ b/drivers/clk/at91/at91sam9g45.c
> @@ -117,7 +117,7 @@ static void __init at91sam9g45_pmc_setup(struct device_node *np)
>  
>  	at91sam9g45_pmc = pmc_data_allocate(PMC_MAIN + 1,
>  					    nck(at91sam9g45_systemck),
> -					    nck(at91sam9g45_periphck), 0);
> +					    nck(at91sam9g45_periphck), 0, 2);
>  	if (!at91sam9g45_pmc)
>  		return;
>  
> @@ -182,6 +182,8 @@ static void __init at91sam9g45_pmc_setup(struct device_node *np)
>  						    &at91sam9g45_programmable_layout);
>  		if (IS_ERR(hw))
>  			goto err_free;
> +
> +		at91sam9g45_pmc->pchws[i] = hw;
>  	}
>  
>  	for (i = 0; i < ARRAY_SIZE(at91sam9g45_systemck); i++) {
> diff --git a/drivers/clk/at91/at91sam9n12.c b/drivers/clk/at91/at91sam9n12.c
> index f3ae1cd3cb8d..3a2564c2f724 100644
> --- a/drivers/clk/at91/at91sam9n12.c
> +++ b/drivers/clk/at91/at91sam9n12.c
> @@ -129,7 +129,7 @@ static void __init at91sam9n12_pmc_setup(struct device_node *np)
>  		return;
>  
>  	at91sam9n12_pmc = pmc_data_allocate(PMC_MAIN + 1,
> -					   nck(at91sam9n12_systemck), 31, 0);
> +					   nck(at91sam9n12_systemck), 31, 0, 2);
>  	if (!at91sam9n12_pmc)
>  		return;
>  
> @@ -198,6 +198,8 @@ static void __init at91sam9n12_pmc_setup(struct device_node *np)
>  						    &at91sam9x5_programmable_layout);
>  		if (IS_ERR(hw))
>  			goto err_free;
> +
> +		at91sam9n12_pmc->pchws[i] = hw;
>  	}
>  
>  	for (i = 0; i < ARRAY_SIZE(at91sam9n12_systemck); i++) {
> diff --git a/drivers/clk/at91/at91sam9rl.c b/drivers/clk/at91/at91sam9rl.c
> index cc739d214ae3..bcf07f6a0e0e 100644
> --- a/drivers/clk/at91/at91sam9rl.c
> +++ b/drivers/clk/at91/at91sam9rl.c
> @@ -89,7 +89,7 @@ static void __init at91sam9rl_pmc_setup(struct device_node *np)
>  
>  	at91sam9rl_pmc = pmc_data_allocate(PMC_MAIN + 1,
>  					   nck(at91sam9rl_systemck),
> -					   nck(at91sam9rl_periphck), 0);
> +					   nck(at91sam9rl_periphck), 0, 2);
>  	if (!at91sam9rl_pmc)
>  		return;
>  
> @@ -138,6 +138,8 @@ static void __init at91sam9rl_pmc_setup(struct device_node *np)
>  						    &at91rm9200_programmable_layout);
>  		if (IS_ERR(hw))
>  			goto err_free;
> +
> +		at91sam9rl_pmc->pchws[i] = hw;
>  	}
>  
>  	for (i = 0; i < ARRAY_SIZE(at91sam9rl_systemck); i++) {
> diff --git a/drivers/clk/at91/at91sam9x5.c b/drivers/clk/at91/at91sam9x5.c
> index aac99d699568..f13756b407e2 100644
> --- a/drivers/clk/at91/at91sam9x5.c
> +++ b/drivers/clk/at91/at91sam9x5.c
> @@ -151,7 +151,7 @@ static void __init at91sam9x5_pmc_setup(struct device_node *np,
>  		return;
>  
>  	at91sam9x5_pmc = pmc_data_allocate(PMC_MAIN + 1,
> -					   nck(at91sam9x5_systemck), 31, 0);
> +					   nck(at91sam9x5_systemck), 31, 0, 2);
>  	if (!at91sam9x5_pmc)
>  		return;
>  
> @@ -227,6 +227,8 @@ static void __init at91sam9x5_pmc_setup(struct device_node *np,
>  						    &at91sam9x5_programmable_layout);
>  		if (IS_ERR(hw))
>  			goto err_free;
> +
> +		at91sam9x5_pmc->pchws[i] = hw;
>  	}
>  
>  	for (i = 0; i < ARRAY_SIZE(at91sam9x5_systemck); i++) {
> diff --git a/drivers/clk/at91/pmc.c b/drivers/clk/at91/pmc.c
> index ac46ea1b9fda..8a1577e2c2fd 100644
> --- a/drivers/clk/at91/pmc.c
> +++ b/drivers/clk/at91/pmc.c
> @@ -67,6 +67,10 @@ struct clk_hw *of_clk_hw_pmc_get(struct of_phandle_args *clkspec, void *data)
>  		if (idx < pmc_data->ngck)
>  			return pmc_data->ghws[idx];
>  		break;
> +	case PMC_TYPE_PROGRAMMABLE:
> +		if (idx < pmc_data->npck)
> +			return pmc_data->pchws[idx];
> +		break;
>  	default:
>  		break;
>  	}
> @@ -77,9 +81,10 @@ struct clk_hw *of_clk_hw_pmc_get(struct of_phandle_args *clkspec, void *data)
>  }
>  
>  struct pmc_data *pmc_data_allocate(unsigned int ncore, unsigned int nsystem,
> -				   unsigned int nperiph, unsigned int ngck)
> +				   unsigned int nperiph, unsigned int ngck,
> +				   unsigned int npck)
>  {
> -	unsigned int num_clks = ncore + nsystem + nperiph + ngck;
> +	unsigned int num_clks = ncore + nsystem + nperiph + ngck + npck;
>  	struct pmc_data *pmc_data;
>  
>  	pmc_data = kzalloc(struct_size(pmc_data, hwtable, num_clks),
> @@ -99,6 +104,9 @@ struct pmc_data *pmc_data_allocate(unsigned int ncore, unsigned int nsystem,
>  	pmc_data->ngck = ngck;
>  	pmc_data->ghws = pmc_data->phws + nperiph;
>  
> +	pmc_data->npck = npck;
> +	pmc_data->pchws = pmc_data->ghws + ngck;
> +
>  	return pmc_data;
>  }
>  
> diff --git a/drivers/clk/at91/pmc.h b/drivers/clk/at91/pmc.h
> index fc3ef772b9d9..df616f2937e7 100644
> --- a/drivers/clk/at91/pmc.h
> +++ b/drivers/clk/at91/pmc.h
> @@ -24,6 +24,8 @@ struct pmc_data {
>  	struct clk_hw **phws;
>  	unsigned int ngck;
>  	struct clk_hw **ghws;
> +	unsigned int npck;
> +	struct clk_hw **pchws;
>  
>  	struct clk_hw *hwtable[];
>  };
> @@ -96,7 +98,8 @@ struct clk_pcr_layout {
>  #define ndck(a, s) (a[s - 1].id + 1)
>  #define nck(a) (a[ARRAY_SIZE(a) - 1].id + 1)
>  struct pmc_data *pmc_data_allocate(unsigned int ncore, unsigned int nsystem,
> -				   unsigned int nperiph, unsigned int ngck);
> +				   unsigned int nperiph, unsigned int ngck,
> +				   unsigned int npck);
>  
>  int of_at91_get_clk_range(struct device_node *np, const char *propname,
>  			  struct clk_range *range);
> diff --git a/drivers/clk/at91/sam9x60.c b/drivers/clk/at91/sam9x60.c
> index a7d4f648db26..db14e0427c7f 100644
> --- a/drivers/clk/at91/sam9x60.c
> +++ b/drivers/clk/at91/sam9x60.c
> @@ -185,7 +185,7 @@ static void __init sam9x60_pmc_setup(struct device_node *np)
>  	sam9x60_pmc = pmc_data_allocate(PMC_MAIN + 1,
>  					nck(sam9x60_systemck),
>  					nck(sam9x60_periphck),
> -					nck(sam9x60_gck));
> +					nck(sam9x60_gck), 8);
>  	if (!sam9x60_pmc)
>  		return;
>  
> @@ -255,6 +255,8 @@ static void __init sam9x60_pmc_setup(struct device_node *np)
>  						    &sam9x60_programmable_layout);
>  		if (IS_ERR(hw))
>  			goto err_free;
> +
> +		sam9x60_pmc->pchws[i] = hw;
>  	}
>  
>  	for (i = 0; i < ARRAY_SIZE(sam9x60_systemck); i++) {
> diff --git a/drivers/clk/at91/sama5d2.c b/drivers/clk/at91/sama5d2.c
> index b2560670e5af..ae5e83cadb3d 100644
> --- a/drivers/clk/at91/sama5d2.c
> +++ b/drivers/clk/at91/sama5d2.c
> @@ -169,7 +169,7 @@ static void __init sama5d2_pmc_setup(struct device_node *np)
>  	sama5d2_pmc = pmc_data_allocate(PMC_I2S1_MUX + 1,
>  					nck(sama5d2_systemck),
>  					nck(sama5d2_periph32ck),
> -					nck(sama5d2_gck));
> +					nck(sama5d2_gck), 3);
>  	if (!sama5d2_pmc)
>  		return;
>  
> @@ -267,6 +267,8 @@ static void __init sama5d2_pmc_setup(struct device_node *np)
>  						    &sama5d2_programmable_layout);
>  		if (IS_ERR(hw))
>  			goto err_free;
> +
> +		sama5d2_pmc->pchws[i] = hw;
>  	}
>  
>  	for (i = 0; i < ARRAY_SIZE(sama5d2_systemck); i++) {
> diff --git a/drivers/clk/at91/sama5d3.c b/drivers/clk/at91/sama5d3.c
> index 914e6f225510..507eef6797f1 100644
> --- a/drivers/clk/at91/sama5d3.c
> +++ b/drivers/clk/at91/sama5d3.c
> @@ -127,7 +127,7 @@ static void __init sama5d3_pmc_setup(struct device_node *np)
>  
>  	sama5d3_pmc = pmc_data_allocate(PMC_MAIN + 1,
>  					nck(sama5d3_systemck),
> -					nck(sama5d3_periphck), 0);
> +					nck(sama5d3_periphck), 0, 3);
>  	if (!sama5d3_pmc)
>  		return;
>  
> @@ -201,6 +201,8 @@ static void __init sama5d3_pmc_setup(struct device_node *np)
>  						    &at91sam9x5_programmable_layout);
>  		if (IS_ERR(hw))
>  			goto err_free;
> +
> +		sama5d3_pmc->pchws[i] = hw;
>  	}
>  
>  	for (i = 0; i < ARRAY_SIZE(sama5d3_systemck); i++) {
> diff --git a/drivers/clk/at91/sama5d4.c b/drivers/clk/at91/sama5d4.c
> index 4ca9a4619500..80692902b4e4 100644
> --- a/drivers/clk/at91/sama5d4.c
> +++ b/drivers/clk/at91/sama5d4.c
> @@ -142,7 +142,7 @@ static void __init sama5d4_pmc_setup(struct device_node *np)
>  
>  	sama5d4_pmc = pmc_data_allocate(PMC_MCK2 + 1,
>  					nck(sama5d4_systemck),
> -					nck(sama5d4_periph32ck), 0);
> +					nck(sama5d4_periph32ck), 0, 3);
>  	if (!sama5d4_pmc)
>  		return;
>  
> @@ -224,6 +224,8 @@ static void __init sama5d4_pmc_setup(struct device_node *np)
>  						    &at91sam9x5_programmable_layout);
>  		if (IS_ERR(hw))
>  			goto err_free;
> +
> +		sama5d4_pmc->pchws[i] = hw;
>  	}
>  
>  	for (i = 0; i < ARRAY_SIZE(sama5d4_systemck); i++) {
> diff --git a/include/dt-bindings/clock/at91.h b/include/dt-bindings/clock/at91.h
> index 38b5554153c8..c3f4aa6a2d29 100644
> --- a/include/dt-bindings/clock/at91.h
> +++ b/include/dt-bindings/clock/at91.h
> @@ -12,6 +12,7 @@
>  #define PMC_TYPE_SYSTEM		1
>  #define PMC_TYPE_PERIPHERAL	2
>  #define PMC_TYPE_GCK		3
> +#define PMC_TYPE_PROGRAMMABLE	4
>  
>  #define PMC_SLOW		0
>  #define PMC_MCK			1
> -- 
> 2.20.1
> 

-- 
Alexandre Belloni, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH v3 3/3] clk: at91: sama5d2: allow setting all PMC clock parents via DT
  2020-03-21 21:18 ` [PATCH v3 3/3] clk: at91: sama5d2: allow setting all PMC clock parents " Michał Mirosław
@ 2020-03-25  9:55   ` Alexandre Belloni
  0 siblings, 0 replies; 7+ messages in thread
From: Alexandre Belloni @ 2020-03-25  9:55 UTC (permalink / raw)
  To: Michał Mirosław
  Cc: Ludovic Desroches, Michael Turquette, Nicolas Ferre,
	Stephen Boyd, linux-clk, linux-kernel

On 21/03/2020 22:18:04+0100, Michał Mirosław wrote:
> We need to have clocks accessible via phandle to select them
> as peripheral clock parent using assigned-clock-parents in DT.
> PLLACK and AUDIOPLLCK were missing for sama5d2. Add them.
> 

If we go this route, because PLLA is available on all the SoC then it
makes sense adding it in all the PMC drivers instead of just the
sama5d2.

> Signed-off-by: Michał Mirosław <mirq-linux@rere.qmqm.pl>
> ---
> v2: rebase to clk/clk-at91 branch
> v3: no changes
> ---
>  drivers/clk/at91/sama5d2.c       | 6 +++++-
>  include/dt-bindings/clock/at91.h | 2 ++
>  2 files changed, 7 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/clk/at91/sama5d2.c b/drivers/clk/at91/sama5d2.c
> index ae5e83cadb3d..b3fa2291ccd8 100644
> --- a/drivers/clk/at91/sama5d2.c
> +++ b/drivers/clk/at91/sama5d2.c
> @@ -166,7 +166,7 @@ static void __init sama5d2_pmc_setup(struct device_node *np)
>  	if (IS_ERR(regmap))
>  		return;
>  
> -	sama5d2_pmc = pmc_data_allocate(PMC_I2S1_MUX + 1,
> +	sama5d2_pmc = pmc_data_allocate(PMC_AUDIOPLLCK + 1,
>  					nck(sama5d2_systemck),
>  					nck(sama5d2_periph32ck),
>  					nck(sama5d2_gck), 3);
> @@ -202,6 +202,8 @@ static void __init sama5d2_pmc_setup(struct device_node *np)
>  	if (IS_ERR(hw))
>  		goto err_free;
>  
> +	sama5d2_pmc->chws[PMC_PLLACK] = hw;
> +
>  	hw = at91_clk_register_audio_pll_frac(regmap, "audiopll_fracck",
>  					      "mainck");
>  	if (IS_ERR(hw))
> @@ -217,6 +219,8 @@ static void __init sama5d2_pmc_setup(struct device_node *np)
>  	if (IS_ERR(hw))
>  		goto err_free;
>  
> +	sama5d2_pmc->chws[PMC_AUDIOPLLCK] = hw;
> +
>  	regmap_sfr = syscon_regmap_lookup_by_compatible("atmel,sama5d2-sfr");
>  	if (IS_ERR(regmap_sfr))
>  		regmap_sfr = NULL;
> diff --git a/include/dt-bindings/clock/at91.h b/include/dt-bindings/clock/at91.h
> index c3f4aa6a2d29..e57362e98129 100644
> --- a/include/dt-bindings/clock/at91.h
> +++ b/include/dt-bindings/clock/at91.h
> @@ -21,6 +21,8 @@
>  #define PMC_MCK2		4
>  #define PMC_I2S0_MUX		5
>  #define PMC_I2S1_MUX		6
> +#define PMC_PLLACK		7
> +#define PMC_AUDIOPLLCK		8
>  
>  #ifndef AT91_PMC_MOSCS
>  #define AT91_PMC_MOSCS		0		/* MOSCS Flag */
> -- 
> 2.20.1
> 

-- 
Alexandre Belloni, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2020-03-25  9:55 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-03-21 21:18 [PATCH v3 0/3] clk: at91: support configuring more clock parents via DT Michał Mirosław
2020-03-21 21:18 ` [PATCH v3 1/3] clk: at91: optimize pmc data allocation Michał Mirosław
2020-03-25  9:37   ` Alexandre Belloni
2020-03-21 21:18 ` [PATCH v3 2/3] clk: at91: allow setting PCKx parent via DT Michał Mirosław
2020-03-25  9:54   ` Alexandre Belloni
2020-03-21 21:18 ` [PATCH v3 3/3] clk: at91: sama5d2: allow setting all PMC clock parents " Michał Mirosław
2020-03-25  9:55   ` Alexandre Belloni

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).