linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 00/10] clk: mmp2: Enable Audio and GPU on MMP2 and MMP3
@ 2020-04-19 17:27 Lubomir Rintel
  2020-04-19 17:27 ` [PATCH 01/10] clk: mmp: frac: Do not lose last 4 digits of precision Lubomir Rintel
                   ` (9 more replies)
  0 siblings, 10 replies; 14+ messages in thread
From: Lubomir Rintel @ 2020-04-19 17:27 UTC (permalink / raw)
  To: Michael Turquette
  Cc: Stephen Boyd, Rob Herring, linux-clk, linux-kernel, devicetree

Hi,

please consider applying this patch set for 5.8.

The goal is to add support for various clocks used by the GPUs and Audio
subsystem MMP2 and MMP3-based machines.

Probably the most significant part is that this adds support for runtime
PM domains which is managed by the same PMU hardware as the clocks.

Tested the GPUs on MMP2 and MMP3 as well as audio on MMP2. (I don't have
an audio codec hooked up on MMP3, nor a camera on a MMP3 machine, so
those remain untested for now).

Thank you
Lubo



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

* [PATCH 01/10] clk: mmp: frac: Do not lose last 4 digits of precision
  2020-04-19 17:27 [PATCH 00/10] clk: mmp2: Enable Audio and GPU on MMP2 and MMP3 Lubomir Rintel
@ 2020-04-19 17:27 ` Lubomir Rintel
  2020-04-19 17:27 ` [PATCH 02/10] clk: mmp: frac: Allow setting bits other than the numerator/denominator Lubomir Rintel
                   ` (8 subsequent siblings)
  9 siblings, 0 replies; 14+ messages in thread
From: Lubomir Rintel @ 2020-04-19 17:27 UTC (permalink / raw)
  To: Michael Turquette
  Cc: Stephen Boyd, Rob Herring, linux-clk, linux-kernel, devicetree,
	Lubomir Rintel

While calculating the output rate of a fractional divider clock, the
value is divided and multipled by 10000, discarding the least
significant digits -- presumably to fit the intermediate value within 32
bits.

The precision we're losing is, however, not insignificant for things like
I2S clock. Maybe also elsewhere, now that since commit ea56ad60260e ("clk:
mmp2: Stop pretending PLL outputs are constant") the parent rates are more
precise and no longer rounded to 10000s.

Signed-off-by: Lubomir Rintel <lkundrak@v3.sk>
---
 drivers/clk/mmp/clk-frac.c | 24 ++++++++++++++++--------
 1 file changed, 16 insertions(+), 8 deletions(-)

diff --git a/drivers/clk/mmp/clk-frac.c b/drivers/clk/mmp/clk-frac.c
index fabc09aca6c46..ed9928f5bdc7f 100644
--- a/drivers/clk/mmp/clk-frac.c
+++ b/drivers/clk/mmp/clk-frac.c
@@ -28,13 +28,15 @@ static long clk_factor_round_rate(struct clk_hw *hw, unsigned long drate,
 		unsigned long *prate)
 {
 	struct mmp_clk_factor *factor = to_clk_factor(hw);
-	unsigned long rate = 0, prev_rate;
+	u64 rate = 0, prev_rate;
 	int i;
 
 	for (i = 0; i < factor->ftbl_cnt; i++) {
 		prev_rate = rate;
-		rate = (((*prate / 10000) * factor->ftbl[i].den) /
-			(factor->ftbl[i].num * factor->masks->factor)) * 10000;
+		rate = *prate;
+		rate *= factor->ftbl[i].den;
+		do_div(rate, factor->ftbl[i].num * factor->masks->factor);
+
 		if (rate > drate)
 			break;
 	}
@@ -54,6 +56,7 @@ static unsigned long clk_factor_recalc_rate(struct clk_hw *hw,
 	struct mmp_clk_factor *factor = to_clk_factor(hw);
 	struct mmp_clk_factor_masks *masks = factor->masks;
 	unsigned int val, num, den;
+	u64 rate;
 
 	val = readl_relaxed(factor->base);
 
@@ -66,8 +69,11 @@ static unsigned long clk_factor_recalc_rate(struct clk_hw *hw,
 	if (!den)
 		return 0;
 
-	return (((parent_rate / 10000)  * den) /
-			(num * factor->masks->factor)) * 10000;
+	rate = parent_rate;
+	rate *= den;
+	do_div(rate, num * factor->masks->factor);
+
+	return rate;
 }
 
 /* Configures new clock rate*/
@@ -78,12 +84,14 @@ static int clk_factor_set_rate(struct clk_hw *hw, unsigned long drate,
 	struct mmp_clk_factor_masks *masks = factor->masks;
 	int i;
 	unsigned long val;
-	unsigned long rate = 0;
 	unsigned long flags = 0;
+	u64 rate = 0;
 
 	for (i = 0; i < factor->ftbl_cnt; i++) {
-		rate = (((prate / 10000) * factor->ftbl[i].den) /
-			(factor->ftbl[i].num * factor->masks->factor)) * 10000;
+		rate = prate;
+		rate *= factor->ftbl[i].den;
+		do_div(rate, factor->ftbl[i].num * factor->masks->factor);
+
 		if (rate > drate)
 			break;
 	}
-- 
2.26.0


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

* [PATCH 02/10] clk: mmp: frac: Allow setting bits other than the numerator/denominator
  2020-04-19 17:27 [PATCH 00/10] clk: mmp2: Enable Audio and GPU on MMP2 and MMP3 Lubomir Rintel
  2020-04-19 17:27 ` [PATCH 01/10] clk: mmp: frac: Do not lose last 4 digits of precision Lubomir Rintel
@ 2020-04-19 17:27 ` Lubomir Rintel
  2020-04-19 17:27 ` [PATCH 03/10] dt-bindings: marvell,mmp2: Add clock id for the I2S clocks Lubomir Rintel
                   ` (7 subsequent siblings)
  9 siblings, 0 replies; 14+ messages in thread
From: Lubomir Rintel @ 2020-04-19 17:27 UTC (permalink / raw)
  To: Michael Turquette
  Cc: Stephen Boyd, Rob Herring, linux-clk, linux-kernel, devicetree,
	Lubomir Rintel

For the I2S fractional clocks, there are more bits that need to be set
for the clock to run. Their actual meaning is unknown.

Signed-off-by: Lubomir Rintel <lkundrak@v3.sk>
---
 drivers/clk/mmp/clk-frac.c | 3 +++
 drivers/clk/mmp/clk.h      | 1 +
 2 files changed, 4 insertions(+)

diff --git a/drivers/clk/mmp/clk-frac.c b/drivers/clk/mmp/clk-frac.c
index ed9928f5bdc7f..48f592bd633df 100644
--- a/drivers/clk/mmp/clk-frac.c
+++ b/drivers/clk/mmp/clk-frac.c
@@ -148,7 +148,10 @@ static int clk_factor_init(struct clk_hw *hw)
 		val &= ~(masks->den_mask << masks->den_shift);
 		val |= (factor->ftbl[0].den & masks->den_mask) <<
 			masks->den_shift;
+	}
 
+	if (!(val & masks->enable_mask) || i >= factor->ftbl_cnt) {
+		val |= masks->enable_mask;
 		writel(val, factor->base);
 	}
 
diff --git a/drivers/clk/mmp/clk.h b/drivers/clk/mmp/clk.h
index 971b4d6d992fb..0efd5b0b2f01b 100644
--- a/drivers/clk/mmp/clk.h
+++ b/drivers/clk/mmp/clk.h
@@ -16,6 +16,7 @@ struct mmp_clk_factor_masks {
 	unsigned int den_mask;
 	unsigned int num_shift;
 	unsigned int den_shift;
+	unsigned int enable_mask;
 };
 
 struct mmp_clk_factor_tbl {
-- 
2.26.0


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

* [PATCH 03/10] dt-bindings: marvell,mmp2: Add clock id for the I2S clocks
  2020-04-19 17:27 [PATCH 00/10] clk: mmp2: Enable Audio and GPU on MMP2 and MMP3 Lubomir Rintel
  2020-04-19 17:27 ` [PATCH 01/10] clk: mmp: frac: Do not lose last 4 digits of precision Lubomir Rintel
  2020-04-19 17:27 ` [PATCH 02/10] clk: mmp: frac: Allow setting bits other than the numerator/denominator Lubomir Rintel
@ 2020-04-19 17:27 ` Lubomir Rintel
  2020-04-30 14:12   ` Rob Herring
  2020-04-19 17:27 ` [PATCH 04/10] dt-bindings: marvell,mmp2: Add clock id for the Audio clock Lubomir Rintel
                   ` (6 subsequent siblings)
  9 siblings, 1 reply; 14+ messages in thread
From: Lubomir Rintel @ 2020-04-19 17:27 UTC (permalink / raw)
  To: Michael Turquette
  Cc: Stephen Boyd, Rob Herring, linux-clk, linux-kernel, devicetree,
	Lubomir Rintel

There are two of these on a MMP2.

Signed-off-by: Lubomir Rintel <lkundrak@v3.sk>
---
 include/dt-bindings/clock/marvell,mmp2.h | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/include/dt-bindings/clock/marvell,mmp2.h b/include/dt-bindings/clock/marvell,mmp2.h
index 06bb7fe4c62f4..5b083f42811e5 100644
--- a/include/dt-bindings/clock/marvell,mmp2.h
+++ b/include/dt-bindings/clock/marvell,mmp2.h
@@ -29,6 +29,8 @@
 #define MMP3_CLK_PLL1_P			28
 #define MMP3_CLK_PLL2_P			29
 #define MMP3_CLK_PLL3			30
+#define MMP2_CLK_I2S0			31
+#define MMP2_CLK_I2S1			32
 
 /* apb periphrals */
 #define MMP2_CLK_TWSI0			60
-- 
2.26.0


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

* [PATCH 04/10] dt-bindings: marvell,mmp2: Add clock id for the Audio clock
  2020-04-19 17:27 [PATCH 00/10] clk: mmp2: Enable Audio and GPU on MMP2 and MMP3 Lubomir Rintel
                   ` (2 preceding siblings ...)
  2020-04-19 17:27 ` [PATCH 03/10] dt-bindings: marvell,mmp2: Add clock id for the I2S clocks Lubomir Rintel
@ 2020-04-19 17:27 ` Lubomir Rintel
  2020-04-30 14:12   ` Rob Herring
  2020-04-19 17:27 ` [PATCH 05/10] clk: mmp2: Move thermal register defines up a bit Lubomir Rintel
                   ` (5 subsequent siblings)
  9 siblings, 1 reply; 14+ messages in thread
From: Lubomir Rintel @ 2020-04-19 17:27 UTC (permalink / raw)
  To: Michael Turquette
  Cc: Stephen Boyd, Rob Herring, linux-clk, linux-kernel, devicetree,
	Lubomir Rintel

This clocks the Audio block.

Signed-off-by: Lubomir Rintel <lkundrak@v3.sk>
---
 include/dt-bindings/clock/marvell,mmp2.h | 1 +
 1 file changed, 1 insertion(+)

diff --git a/include/dt-bindings/clock/marvell,mmp2.h b/include/dt-bindings/clock/marvell,mmp2.h
index 5b083f42811e5..87f5ad5df72f4 100644
--- a/include/dt-bindings/clock/marvell,mmp2.h
+++ b/include/dt-bindings/clock/marvell,mmp2.h
@@ -89,6 +89,7 @@
 #define MMP3_CLK_GPU_3D			MMP2_CLK_GPU_3D
 #define MMP3_CLK_GPU_2D			125
 #define MMP3_CLK_SDH4			126
+#define MMP2_CLK_AUDIO			127
 
 #define MMP2_NR_CLKS			200
 #endif
-- 
2.26.0


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

* [PATCH 05/10] clk: mmp2: Move thermal register defines up a bit
  2020-04-19 17:27 [PATCH 00/10] clk: mmp2: Enable Audio and GPU on MMP2 and MMP3 Lubomir Rintel
                   ` (3 preceding siblings ...)
  2020-04-19 17:27 ` [PATCH 04/10] dt-bindings: marvell,mmp2: Add clock id for the Audio clock Lubomir Rintel
@ 2020-04-19 17:27 ` Lubomir Rintel
  2020-04-19 17:27 ` [PATCH 06/10] clk: mmp2: Rename mmp2_pll_init() to mmp2_main_clk_init() Lubomir Rintel
                   ` (4 subsequent siblings)
  9 siblings, 0 replies; 14+ messages in thread
From: Lubomir Rintel @ 2020-04-19 17:27 UTC (permalink / raw)
  To: Michael Turquette
  Cc: Stephen Boyd, Rob Herring, linux-clk, linux-kernel, devicetree,
	Lubomir Rintel

A trivial change to keep the sorting sane. The APBC registers are happier
when they are grouped together, instead of mixed with the APMU ones.

Signed-off-by: Lubomir Rintel <lkundrak@v3.sk>
---
 drivers/clk/mmp/clk-of-mmp2.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/clk/mmp/clk-of-mmp2.c b/drivers/clk/mmp/clk-of-mmp2.c
index 52dc8b43acd9a..524574187c17a 100644
--- a/drivers/clk/mmp/clk-of-mmp2.c
+++ b/drivers/clk/mmp/clk-of-mmp2.c
@@ -45,6 +45,10 @@
 #define APBC_SSP1	0x54
 #define APBC_SSP2	0x58
 #define APBC_SSP3	0x5c
+#define APBC_THERMAL0	0x90
+#define APBC_THERMAL1	0x98
+#define APBC_THERMAL2	0x9c
+#define APBC_THERMAL3	0xa0
 #define APMU_SDH0	0x54
 #define APMU_SDH1	0x58
 #define APMU_SDH2	0xe8
@@ -55,10 +59,6 @@
 #define APMU_DISP1	0x110
 #define APMU_CCIC0	0x50
 #define APMU_CCIC1	0xf4
-#define APBC_THERMAL0	0x90
-#define APBC_THERMAL1	0x98
-#define APBC_THERMAL2	0x9c
-#define APBC_THERMAL3	0xa0
 #define APMU_USBHSIC0	0xf8
 #define APMU_USBHSIC1	0xfc
 #define APMU_GPU	0xcc
-- 
2.26.0


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

* [PATCH 06/10] clk: mmp2: Rename mmp2_pll_init() to mmp2_main_clk_init()
  2020-04-19 17:27 [PATCH 00/10] clk: mmp2: Enable Audio and GPU on MMP2 and MMP3 Lubomir Rintel
                   ` (4 preceding siblings ...)
  2020-04-19 17:27 ` [PATCH 05/10] clk: mmp2: Move thermal register defines up a bit Lubomir Rintel
@ 2020-04-19 17:27 ` Lubomir Rintel
  2020-04-19 17:27 ` [PATCH 07/10] clk: mmp2: Add the I2C clocks Lubomir Rintel
                   ` (3 subsequent siblings)
  9 siblings, 0 replies; 14+ messages in thread
From: Lubomir Rintel @ 2020-04-19 17:27 UTC (permalink / raw)
  To: Michael Turquette
  Cc: Stephen Boyd, Rob Herring, linux-clk, linux-kernel, devicetree,
	Lubomir Rintel

This is a trivial rename for a routine that registers more clock sources
than the PLLs -- there's also a XO.

Signed-off-by: Lubomir Rintel <lkundrak@v3.sk>
---
 drivers/clk/mmp/clk-of-mmp2.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/clk/mmp/clk-of-mmp2.c b/drivers/clk/mmp/clk-of-mmp2.c
index 524574187c17a..ac88ea99b7c68 100644
--- a/drivers/clk/mmp/clk-of-mmp2.c
+++ b/drivers/clk/mmp/clk-of-mmp2.c
@@ -139,7 +139,7 @@ static struct mmp_clk_factor_tbl uart_factor_tbl[] = {
 	{.num = 3521, .den = 689},	/*19.23MHZ */
 };
 
-static void mmp2_pll_init(struct mmp2_clk_unit *pxa_unit)
+static void mmp2_main_clk_init(struct mmp2_clk_unit *pxa_unit)
 {
 	struct clk *clk;
 	struct mmp_clk_unit *unit = &pxa_unit->unit;
@@ -456,7 +456,7 @@ static void __init mmp2_clk_init(struct device_node *np)
 
 	mmp_clk_init(np, &pxa_unit->unit, MMP2_NR_CLKS);
 
-	mmp2_pll_init(pxa_unit);
+	mmp2_main_clk_init(pxa_unit);
 
 	mmp2_apb_periph_clk_init(pxa_unit);
 
-- 
2.26.0


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

* [PATCH 07/10] clk: mmp2: Add the I2C clocks
  2020-04-19 17:27 [PATCH 00/10] clk: mmp2: Enable Audio and GPU on MMP2 and MMP3 Lubomir Rintel
                   ` (5 preceding siblings ...)
  2020-04-19 17:27 ` [PATCH 06/10] clk: mmp2: Rename mmp2_pll_init() to mmp2_main_clk_init() Lubomir Rintel
@ 2020-04-19 17:27 ` Lubomir Rintel
  2020-04-19 17:27 ` [PATCH 08/10] clk: mmp2: Add the audio clock Lubomir Rintel
                   ` (2 subsequent siblings)
  9 siblings, 0 replies; 14+ messages in thread
From: Lubomir Rintel @ 2020-04-19 17:27 UTC (permalink / raw)
  To: Michael Turquette
  Cc: Stephen Boyd, Rob Herring, linux-clk, linux-kernel, devicetree,
	Lubomir Rintel

A pair of fractional clock sources for PLLs and gates.

Signed-off-by: Lubomir Rintel <lkundrak@v3.sk>
---
 drivers/clk/mmp/clk-of-mmp2.c | 46 +++++++++++++++++++++++++++++++++++
 1 file changed, 46 insertions(+)

diff --git a/drivers/clk/mmp/clk-of-mmp2.c b/drivers/clk/mmp/clk-of-mmp2.c
index ac88ea99b7c68..dcdff06a698ac 100644
--- a/drivers/clk/mmp/clk-of-mmp2.c
+++ b/drivers/clk/mmp/clk-of-mmp2.c
@@ -67,6 +67,9 @@
 #define MPMU_POSR		0x10
 #define MPMU_UART_PLL		0x14
 #define MPMU_PLL2_CR		0x34
+#define MPMU_I2S0_PLL		0x40
+#define MPMU_I2S1_PLL		0x44
+#define MPMU_ACGR		0x1024
 /* MMP3 specific below */
 #define MPMU_PLL3_CR		0x50
 #define MPMU_PLL3_CTRL1		0x58
@@ -91,6 +94,7 @@ static struct mmp_param_fixed_rate_clk fixed_rate_clks[] = {
 	{MMP2_CLK_CLK32, "clk32", NULL, 0, 32768},
 	{MMP2_CLK_VCTCXO, "vctcxo", NULL, 0, 26000000},
 	{MMP2_CLK_USB_PLL, "usb_pll", NULL, 0, 480000000},
+	{0, "i2s_pll", NULL, 0, 99666667},
 };
 
 static struct mmp_param_pll_clk pll_clks[] = {
@@ -139,6 +143,34 @@ static struct mmp_clk_factor_tbl uart_factor_tbl[] = {
 	{.num = 3521, .den = 689},	/*19.23MHZ */
 };
 
+static struct mmp_clk_factor_masks i2s_factor_masks = {
+	.factor = 2,
+	.num_mask = 0x7fff,
+	.den_mask = 0x1fff,
+	.num_shift = 0,
+	.den_shift = 15,
+	.enable_mask = 0xd0000000,
+};
+
+static struct mmp_clk_factor_tbl i2s_factor_tbl[] = {
+	{.num = 24868, .den =  511},	/*  2.0480 MHz */
+	{.num = 28003, .den =  793},	/*  2.8224 MHz */
+	{.num = 24941, .den = 1025},	/*  4.0960 MHz */
+	{.num = 28003, .den = 1586},	/*  5.6448 MHz */
+	{.num = 31158, .den = 2561},	/*  8.1920 MHz */
+	{.num = 16288, .den = 1845},	/* 11.2896 MHz */
+	{.num = 20772, .den = 2561},	/* 12.2880 MHz */
+	{.num =  8144, .den = 1845},	/* 22.5792 MHz */
+	{.num = 10386, .den = 2561},	/* 24.5760 MHz */
+};
+
+static DEFINE_SPINLOCK(acgr_lock);
+
+static struct mmp_param_gate_clk mpmu_gate_clks[] = {
+	{MMP2_CLK_I2S0, "i2s0_clk", "i2s0_pll", CLK_SET_RATE_PARENT, MPMU_ACGR, 0x200000, 0x200000, 0x0, 0, &acgr_lock},
+	{MMP2_CLK_I2S1, "i2s1_clk", "i2s1_pll", CLK_SET_RATE_PARENT, MPMU_ACGR, 0x100000, 0x100000, 0x0, 0, &acgr_lock},
+};
+
 static void mmp2_main_clk_init(struct mmp2_clk_unit *pxa_unit)
 {
 	struct clk *clk;
@@ -166,6 +198,20 @@ static void mmp2_main_clk_init(struct mmp2_clk_unit *pxa_unit)
 				&uart_factor_masks, uart_factor_tbl,
 				ARRAY_SIZE(uart_factor_tbl), NULL);
 	mmp_clk_add(unit, MMP2_CLK_UART_PLL, clk);
+
+	mmp_clk_register_factor("i2s0_pll", "pll1_4",
+				CLK_SET_RATE_PARENT,
+				pxa_unit->mpmu_base + MPMU_I2S0_PLL,
+				&i2s_factor_masks, i2s_factor_tbl,
+				ARRAY_SIZE(i2s_factor_tbl), NULL);
+	mmp_clk_register_factor("i2s1_pll", "pll1_4",
+				CLK_SET_RATE_PARENT,
+				pxa_unit->mpmu_base + MPMU_I2S1_PLL,
+				&i2s_factor_masks, i2s_factor_tbl,
+				ARRAY_SIZE(i2s_factor_tbl), NULL);
+
+	mmp_register_gate_clks(unit, mpmu_gate_clks, pxa_unit->mpmu_base,
+				ARRAY_SIZE(mpmu_gate_clks));
 }
 
 static DEFINE_SPINLOCK(uart0_lock);
-- 
2.26.0


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

* [PATCH 08/10] clk: mmp2: Add the audio clock
  2020-04-19 17:27 [PATCH 00/10] clk: mmp2: Enable Audio and GPU on MMP2 and MMP3 Lubomir Rintel
                   ` (6 preceding siblings ...)
  2020-04-19 17:27 ` [PATCH 07/10] clk: mmp2: Add the I2C clocks Lubomir Rintel
@ 2020-04-19 17:27 ` Lubomir Rintel
  2020-04-19 17:27 ` [PATCH 09/10] dt-bindings: marvell,mmp2: Add ids for the power domains Lubomir Rintel
  2020-04-19 17:27 ` [PATCH 10/10] clk: mmp2: Add support for power islands Lubomir Rintel
  9 siblings, 0 replies; 14+ messages in thread
From: Lubomir Rintel @ 2020-04-19 17:27 UTC (permalink / raw)
  To: Michael Turquette
  Cc: Stephen Boyd, Rob Herring, linux-clk, linux-kernel, devicetree,
	Lubomir Rintel

This clocks the Audio block.

Signed-off-by: Lubomir Rintel <lkundrak@v3.sk>
---
 drivers/clk/mmp/clk-of-mmp2.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/drivers/clk/mmp/clk-of-mmp2.c b/drivers/clk/mmp/clk-of-mmp2.c
index dcdff06a698ac..c686c16fca82b 100644
--- a/drivers/clk/mmp/clk-of-mmp2.c
+++ b/drivers/clk/mmp/clk-of-mmp2.c
@@ -62,6 +62,7 @@
 #define APMU_USBHSIC0	0xf8
 #define APMU_USBHSIC1	0xfc
 #define APMU_GPU	0xcc
+#define APMU_AUDIO	0x10c
 
 #define MPMU_FCCR		0x8
 #define MPMU_POSR		0x10
@@ -317,6 +318,8 @@ static u32 mmp2_gpu_bus_parent_table[] =         { 0x0000,   0x0020,   0x0030,
 static const char * const mmp3_gpu_bus_parent_names[] = {"pll1_4", "pll1_6", "pll1_2", "pll2_2"};
 static const char * const mmp3_gpu_gc_parent_names[] =  {"pll1",   "pll2",   "pll1_p", "pll2_p"};
 
+static DEFINE_SPINLOCK(audio_lock);
+
 static struct mmp_clk_mix_config ccic0_mix_config = {
 	.reg_info = DEFINE_MIX_REG_INFO(4, 17, 2, 6, 32),
 };
@@ -372,6 +375,7 @@ static struct mmp_param_gate_clk apmu_gate_clks[] = {
 	{MMP2_CLK_CCIC1_PHY, "ccic1_phy_clk", "ccic1_mix_clk", CLK_SET_RATE_PARENT, APMU_CCIC1, 0x24, 0x24, 0x0, 0, &ccic1_lock},
 	{MMP2_CLK_CCIC1_SPHY, "ccic1_sphy_clk", "ccic1_sphy_div", CLK_SET_RATE_PARENT, APMU_CCIC1, 0x300, 0x300, 0x0, 0, &ccic1_lock},
 	{MMP2_CLK_GPU_BUS, "gpu_bus_clk", "gpu_bus_mux", CLK_SET_RATE_PARENT, APMU_GPU, 0xa, 0xa, 0x0, MMP_CLK_GATE_NEED_DELAY, &gpu_lock},
+	{MMP2_CLK_AUDIO, "audio_clk", "audio_mix_clk", CLK_SET_RATE_PARENT, APMU_AUDIO, 0x12, 0x12, 0x0, 0, &audio_lock},
 };
 
 static struct mmp_param_gate_clk mmp2_apmu_gate_clks[] = {
-- 
2.26.0


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

* [PATCH 09/10] dt-bindings: marvell,mmp2: Add ids for the power domains
  2020-04-19 17:27 [PATCH 00/10] clk: mmp2: Enable Audio and GPU on MMP2 and MMP3 Lubomir Rintel
                   ` (7 preceding siblings ...)
  2020-04-19 17:27 ` [PATCH 08/10] clk: mmp2: Add the audio clock Lubomir Rintel
@ 2020-04-19 17:27 ` Lubomir Rintel
  2020-04-30 14:13   ` Rob Herring
  2020-04-19 17:27 ` [PATCH 10/10] clk: mmp2: Add support for power islands Lubomir Rintel
  9 siblings, 1 reply; 14+ messages in thread
From: Lubomir Rintel @ 2020-04-19 17:27 UTC (permalink / raw)
  To: Michael Turquette
  Cc: Stephen Boyd, Rob Herring, linux-clk, linux-kernel, devicetree,
	Lubomir Rintel

On MMP2 the audio and GPU blocks are on separate power islands. On MMP3
the camera block's power is also controlled separately.

Add the numbers that we could use to refer to the power domains for
respective power islands from the device tree.

Signed-off-by: Lubomir Rintel <lkundrak@v3.sk>
---
 include/dt-bindings/power/marvell,mmp2.h | 11 +++++++++++
 1 file changed, 11 insertions(+)
 create mode 100644 include/dt-bindings/power/marvell,mmp2.h

diff --git a/include/dt-bindings/power/marvell,mmp2.h b/include/dt-bindings/power/marvell,mmp2.h
new file mode 100644
index 0000000000000..c53d2b3e10574
--- /dev/null
+++ b/include/dt-bindings/power/marvell,mmp2.h
@@ -0,0 +1,11 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef __DTS_MARVELL_MMP2_POWER_H
+#define __DTS_MARVELL_MMP2_POWER_H
+
+#define MMP2_POWER_DOMAIN_GPU		0
+#define MMP2_POWER_DOMAIN_AUDIO		1
+#define MMP3_POWER_DOMAIN_CAMERA	2
+
+#define MMP2_NR_POWER_DOMAINS		3
+
+#endif
-- 
2.26.0


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

* [PATCH 10/10] clk: mmp2: Add support for power islands
  2020-04-19 17:27 [PATCH 00/10] clk: mmp2: Enable Audio and GPU on MMP2 and MMP3 Lubomir Rintel
                   ` (8 preceding siblings ...)
  2020-04-19 17:27 ` [PATCH 09/10] dt-bindings: marvell,mmp2: Add ids for the power domains Lubomir Rintel
@ 2020-04-19 17:27 ` Lubomir Rintel
  9 siblings, 0 replies; 14+ messages in thread
From: Lubomir Rintel @ 2020-04-19 17:27 UTC (permalink / raw)
  To: Michael Turquette
  Cc: Stephen Boyd, Rob Herring, linux-clk, linux-kernel, devicetree,
	Lubomir Rintel

Apart from the clocks and resets, the PMU hardware also controls power
to peripherals that are on separate power islands. On MMP2, that's the
GC860 GPU and the SSPA audio interface, while on MMP3 also the camera
interface is on a separate island, along with the pair of GC2000 and GC300
GPUs and the SSPA.

Signed-off-by: Lubomir Rintel <lkundrak@v3.sk>
---
 arch/arm/mach-mmp/Kconfig     |   2 +
 drivers/clk/mmp/Makefile      |   2 +-
 drivers/clk/mmp/clk-of-mmp2.c |  42 +++++++++++++
 drivers/clk/mmp/clk.h         |  10 +++
 drivers/clk/mmp/pwr-island.c  | 115 ++++++++++++++++++++++++++++++++++
 5 files changed, 170 insertions(+), 1 deletion(-)
 create mode 100644 drivers/clk/mmp/pwr-island.c

diff --git a/arch/arm/mach-mmp/Kconfig b/arch/arm/mach-mmp/Kconfig
index b58a03b18bdef..8a1519e6be6f9 100644
--- a/arch/arm/mach-mmp/Kconfig
+++ b/arch/arm/mach-mmp/Kconfig
@@ -125,6 +125,8 @@ config MACH_MMP2_DT
 	select PINCTRL_SINGLE
 	select ARCH_HAS_RESET_CONTROLLER
 	select CPU_PJ4
+	select PM_GENERIC_DOMAINS if PM
+	select PM_GENERIC_DOMAINS_OF if PM && OF
 	help
 	  Include support for Marvell MMP2 based platforms using
 	  the device tree.
diff --git a/drivers/clk/mmp/Makefile b/drivers/clk/mmp/Makefile
index 14dc8a8a9d087..f9fab883a13b2 100644
--- a/drivers/clk/mmp/Makefile
+++ b/drivers/clk/mmp/Makefile
@@ -8,7 +8,7 @@ obj-y += clk-apbc.o clk-apmu.o clk-frac.o clk-mix.o clk-gate.o clk.o
 obj-$(CONFIG_RESET_CONTROLLER) += reset.o
 
 obj-$(CONFIG_MACH_MMP_DT) += clk-of-pxa168.o clk-of-pxa910.o
-obj-$(CONFIG_COMMON_CLK_MMP2) += clk-of-mmp2.o clk-pll.o
+obj-$(CONFIG_COMMON_CLK_MMP2) += clk-of-mmp2.o clk-pll.o pwr-island.o
 
 obj-$(CONFIG_CPU_PXA168) += clk-pxa168.o
 obj-$(CONFIG_CPU_PXA910) += clk-pxa910.o
diff --git a/drivers/clk/mmp/clk-of-mmp2.c b/drivers/clk/mmp/clk-of-mmp2.c
index c686c16fca82b..84498d1c3544f 100644
--- a/drivers/clk/mmp/clk-of-mmp2.c
+++ b/drivers/clk/mmp/clk-of-mmp2.c
@@ -17,8 +17,10 @@
 #include <linux/delay.h>
 #include <linux/err.h>
 #include <linux/of_address.h>
+#include <linux/clk.h>
 
 #include <dt-bindings/clock/marvell,mmp2.h>
+#include <dt-bindings/power/marvell,mmp2.h>
 
 #include "clk.h"
 #include "reset.h"
@@ -63,6 +65,7 @@
 #define APMU_USBHSIC1	0xfc
 #define APMU_GPU	0xcc
 #define APMU_AUDIO	0x10c
+#define APMU_CAMERA	0x1fc
 
 #define MPMU_FCCR		0x8
 #define MPMU_POSR		0x10
@@ -86,6 +89,8 @@ enum mmp2_clk_model {
 struct mmp2_clk_unit {
 	struct mmp_clk_unit unit;
 	enum mmp2_clk_model model;
+	struct genpd_onecell_data pd_data;
+	struct generic_pm_domain *pm_domains[MMP2_NR_POWER_DOMAINS];
 	void __iomem *mpmu_base;
 	void __iomem *apmu_base;
 	void __iomem *apbc_base;
@@ -473,6 +478,41 @@ static void mmp2_clk_reset_init(struct device_node *np,
 	mmp_clk_reset_register(np, cells, nr_resets);
 }
 
+static void mmp2_pm_domain_init(struct device_node *np,
+				struct mmp2_clk_unit *pxa_unit)
+{
+	if (pxa_unit->model == CLK_MODEL_MMP3) {
+		pxa_unit->pm_domains[MMP2_POWER_DOMAIN_GPU]
+			= mmp_pm_domain_register("GPU",
+				pxa_unit->apmu_base + APMU_GPU,
+				0x0600, 0x40003, 0x18000c, 0, &gpu_lock);
+	} else {
+		pxa_unit->pm_domains[MMP2_POWER_DOMAIN_GPU]
+			= mmp_pm_domain_register("GPU",
+				pxa_unit->apmu_base + APMU_GPU,
+				0x8600, 0x00003, 0x00000c,
+				MMP_PM_DOMAIN_NO_DISABLE, &gpu_lock);
+	}
+	pxa_unit->pd_data.num_domains++;
+
+	pxa_unit->pm_domains[MMP2_POWER_DOMAIN_AUDIO]
+		= mmp_pm_domain_register("Audio",
+			pxa_unit->apmu_base + APMU_AUDIO,
+			0x600, 0, 0, 0, &audio_lock);
+	pxa_unit->pd_data.num_domains++;
+
+	if (pxa_unit->model == CLK_MODEL_MMP3) {
+		pxa_unit->pm_domains[MMP3_POWER_DOMAIN_CAMERA]
+			= mmp_pm_domain_register("Camera",
+				pxa_unit->apmu_base + APMU_CAMERA,
+				0x600, 0, 0, 0, NULL);
+		pxa_unit->pd_data.num_domains++;
+	}
+
+	pxa_unit->pd_data.domains = pxa_unit->pm_domains;
+	of_genpd_add_provider_onecell(np, &pxa_unit->pd_data);
+}
+
 static void __init mmp2_clk_init(struct device_node *np)
 {
 	struct mmp2_clk_unit *pxa_unit;
@@ -504,6 +544,8 @@ static void __init mmp2_clk_init(struct device_node *np)
 		goto unmap_apmu_region;
 	}
 
+	mmp2_pm_domain_init(np, pxa_unit);
+
 	mmp_clk_init(np, &pxa_unit->unit, MMP2_NR_CLKS);
 
 	mmp2_main_clk_init(pxa_unit);
diff --git a/drivers/clk/mmp/clk.h b/drivers/clk/mmp/clk.h
index 0efd5b0b2f01b..bfa2adc24a7cc 100644
--- a/drivers/clk/mmp/clk.h
+++ b/drivers/clk/mmp/clk.h
@@ -3,6 +3,7 @@
 #define __MACH_MMP_CLK_H
 
 #include <linux/clk-provider.h>
+#include <linux/pm_domain.h>
 #include <linux/clkdev.h>
 
 #define APBC_NO_BUS_CTRL	BIT(0)
@@ -259,4 +260,13 @@ void mmp_clk_init(struct device_node *np, struct mmp_clk_unit *unit,
 		int nr_clks);
 void mmp_clk_add(struct mmp_clk_unit *unit, unsigned int id,
 		struct clk *clk);
+
+/* Power islands */
+#define MMP_PM_DOMAIN_NO_DISABLE		BIT(0)
+
+struct generic_pm_domain *mmp_pm_domain_register(const char *name,
+		void __iomem *reg,
+		u32 power_on, u32 reset, u32 clock_enable,
+		unsigned int flags, spinlock_t *lock);
+
 #endif
diff --git a/drivers/clk/mmp/pwr-island.c b/drivers/clk/mmp/pwr-island.c
new file mode 100644
index 0000000000000..ab57c0e995c1d
--- /dev/null
+++ b/drivers/clk/mmp/pwr-island.c
@@ -0,0 +1,115 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * MMP PMU power island support
+ *
+ * Copyright (C) 2020 Lubomir Rintel <lkundrak@v3.sk>
+ */
+
+#include <linux/pm_domain.h>
+#include <linux/slab.h>
+#include <linux/io.h>
+
+#include "clk.h"
+
+#define to_mmp_pm_domain(genpd) container_of(genpd, struct mmp_pm_domain, genpd)
+
+struct mmp_pm_domain {
+	struct generic_pm_domain genpd;
+	void __iomem *reg;
+	spinlock_t *lock;
+	u32 power_on;
+	u32 reset;
+	u32 clock_enable;
+	unsigned int flags;
+};
+
+static int mmp_pm_domain_power_on(struct generic_pm_domain *genpd)
+{
+	struct mmp_pm_domain *pm_domain = to_mmp_pm_domain(genpd);
+	unsigned long flags = 0;
+	u32 val;
+
+	if (pm_domain->lock)
+		spin_lock_irqsave(pm_domain->lock, flags);
+
+	val = readl(pm_domain->reg);
+
+	/* Turn on the power island */
+	val |= pm_domain->power_on;
+	writel(val, pm_domain->reg);
+
+	/* Disable isolation */
+	val |= 0x100;
+	writel(val, pm_domain->reg);
+
+	/* Some blocks need to be reset after a power up */
+	if (pm_domain->reset || pm_domain->clock_enable) {
+		u32 after_power_on = val;
+
+		val &= ~pm_domain->reset;
+		writel(val, pm_domain->reg);
+
+		val |= pm_domain->clock_enable;
+		writel(val, pm_domain->reg);
+
+		val |= pm_domain->reset;
+		writel(val, pm_domain->reg);
+
+		writel(after_power_on, pm_domain->reg);
+	}
+
+	if (pm_domain->lock)
+		spin_unlock_irqrestore(pm_domain->lock, flags);
+
+	return 0;
+}
+
+static int mmp_pm_domain_power_off(struct generic_pm_domain *genpd)
+{
+	struct mmp_pm_domain *pm_domain = to_mmp_pm_domain(genpd);
+	unsigned long flags = 0;
+	u32 val;
+
+	if (pm_domain->flags & MMP_PM_DOMAIN_NO_DISABLE)
+		return 0;
+
+	if (pm_domain->lock)
+		spin_lock_irqsave(pm_domain->lock, flags);
+
+	/* Turn off and isolate the the power island. */
+	val = readl(pm_domain->reg);
+	val &= ~pm_domain->power_on;
+	val &= ~0x100;
+	writel(val, pm_domain->reg);
+
+	if (pm_domain->lock)
+		spin_unlock_irqrestore(pm_domain->lock, flags);
+
+	return 0;
+}
+
+struct generic_pm_domain *mmp_pm_domain_register(const char *name,
+		void __iomem *reg,
+		u32 power_on, u32 reset, u32 clock_enable,
+		unsigned int flags, spinlock_t *lock)
+{
+	struct mmp_pm_domain *pm_domain;
+
+	pm_domain = kzalloc(sizeof(*pm_domain), GFP_KERNEL);
+	if (!pm_domain)
+		return ERR_PTR(-ENOMEM);
+
+	pm_domain->reg = reg;
+	pm_domain->power_on = power_on;
+	pm_domain->reset = reset;
+	pm_domain->clock_enable = clock_enable;
+	pm_domain->flags = flags;
+	pm_domain->lock = lock;
+
+	pm_genpd_init(&pm_domain->genpd, NULL, true);
+	pm_domain->genpd.name = name;
+	pm_domain->genpd.power_on = mmp_pm_domain_power_on;
+	pm_domain->genpd.power_off = mmp_pm_domain_power_off;
+
+	return &pm_domain->genpd;
+}
-- 
2.26.0


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

* Re: [PATCH 03/10] dt-bindings: marvell,mmp2: Add clock id for the I2S clocks
  2020-04-19 17:27 ` [PATCH 03/10] dt-bindings: marvell,mmp2: Add clock id for the I2S clocks Lubomir Rintel
@ 2020-04-30 14:12   ` Rob Herring
  0 siblings, 0 replies; 14+ messages in thread
From: Rob Herring @ 2020-04-30 14:12 UTC (permalink / raw)
  To: Lubomir Rintel
  Cc: Michael Turquette, Stephen Boyd, linux-clk, linux-kernel,
	devicetree, Lubomir Rintel

On Sun, 19 Apr 2020 19:27:35 +0200, Lubomir Rintel wrote:
> There are two of these on a MMP2.
> 
> Signed-off-by: Lubomir Rintel <lkundrak@v3.sk>
> ---
>  include/dt-bindings/clock/marvell,mmp2.h | 2 ++
>  1 file changed, 2 insertions(+)
> 

Acked-by: Rob Herring <robh@kernel.org>

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

* Re: [PATCH 04/10] dt-bindings: marvell,mmp2: Add clock id for the Audio clock
  2020-04-19 17:27 ` [PATCH 04/10] dt-bindings: marvell,mmp2: Add clock id for the Audio clock Lubomir Rintel
@ 2020-04-30 14:12   ` Rob Herring
  0 siblings, 0 replies; 14+ messages in thread
From: Rob Herring @ 2020-04-30 14:12 UTC (permalink / raw)
  To: Lubomir Rintel
  Cc: Michael Turquette, Stephen Boyd, linux-clk, linux-kernel,
	devicetree, Lubomir Rintel

On Sun, 19 Apr 2020 19:27:36 +0200, Lubomir Rintel wrote:
> This clocks the Audio block.
> 
> Signed-off-by: Lubomir Rintel <lkundrak@v3.sk>
> ---
>  include/dt-bindings/clock/marvell,mmp2.h | 1 +
>  1 file changed, 1 insertion(+)
> 

Acked-by: Rob Herring <robh@kernel.org>

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

* Re: [PATCH 09/10] dt-bindings: marvell,mmp2: Add ids for the power domains
  2020-04-19 17:27 ` [PATCH 09/10] dt-bindings: marvell,mmp2: Add ids for the power domains Lubomir Rintel
@ 2020-04-30 14:13   ` Rob Herring
  0 siblings, 0 replies; 14+ messages in thread
From: Rob Herring @ 2020-04-30 14:13 UTC (permalink / raw)
  To: Lubomir Rintel
  Cc: Michael Turquette, Stephen Boyd, linux-clk, linux-kernel,
	devicetree, Lubomir Rintel

On Sun, 19 Apr 2020 19:27:41 +0200, Lubomir Rintel wrote:
> On MMP2 the audio and GPU blocks are on separate power islands. On MMP3
> the camera block's power is also controlled separately.
> 
> Add the numbers that we could use to refer to the power domains for
> respective power islands from the device tree.
> 
> Signed-off-by: Lubomir Rintel <lkundrak@v3.sk>
> ---
>  include/dt-bindings/power/marvell,mmp2.h | 11 +++++++++++
>  1 file changed, 11 insertions(+)
>  create mode 100644 include/dt-bindings/power/marvell,mmp2.h
> 

Acked-by: Rob Herring <robh@kernel.org>

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

end of thread, other threads:[~2020-04-30 14:14 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-04-19 17:27 [PATCH 00/10] clk: mmp2: Enable Audio and GPU on MMP2 and MMP3 Lubomir Rintel
2020-04-19 17:27 ` [PATCH 01/10] clk: mmp: frac: Do not lose last 4 digits of precision Lubomir Rintel
2020-04-19 17:27 ` [PATCH 02/10] clk: mmp: frac: Allow setting bits other than the numerator/denominator Lubomir Rintel
2020-04-19 17:27 ` [PATCH 03/10] dt-bindings: marvell,mmp2: Add clock id for the I2S clocks Lubomir Rintel
2020-04-30 14:12   ` Rob Herring
2020-04-19 17:27 ` [PATCH 04/10] dt-bindings: marvell,mmp2: Add clock id for the Audio clock Lubomir Rintel
2020-04-30 14:12   ` Rob Herring
2020-04-19 17:27 ` [PATCH 05/10] clk: mmp2: Move thermal register defines up a bit Lubomir Rintel
2020-04-19 17:27 ` [PATCH 06/10] clk: mmp2: Rename mmp2_pll_init() to mmp2_main_clk_init() Lubomir Rintel
2020-04-19 17:27 ` [PATCH 07/10] clk: mmp2: Add the I2C clocks Lubomir Rintel
2020-04-19 17:27 ` [PATCH 08/10] clk: mmp2: Add the audio clock Lubomir Rintel
2020-04-19 17:27 ` [PATCH 09/10] dt-bindings: marvell,mmp2: Add ids for the power domains Lubomir Rintel
2020-04-30 14:13   ` Rob Herring
2020-04-19 17:27 ` [PATCH 10/10] clk: mmp2: Add support for power islands Lubomir Rintel

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).