linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/1] clk: mmp2: Enable the 3D GPU clock alongside the 2D clock
@ 2021-02-04  2:01 Lubomir Rintel
  2021-02-04  2:01 ` [PATCH 1/1] " Lubomir Rintel
  0 siblings, 1 reply; 2+ messages in thread
From: Lubomir Rintel @ 2021-02-04  2:01 UTC (permalink / raw)
  To: Stephen Boyd
  Cc: Michael Turquette, Ivan Najdanovic, Lucas Stach, linux-clk, linux-kernel

Hi,

Please consider applying the sad little patch chained to this message. It
is a workaround that makes the 2D GPU work on MMP3 when the 3D GPU is not
used.

It's been observed that the 2D GPU won't work when what is understood to be
the 3D GPU clock is turned off. The etnaviv developers suggest [1][2] that
perhaps said understanding is wrong and they may be right. Unfortunately no
documentation is available, all we know is the register names.

In any case it seems to make more sense to put the workaround in the MMP
clock driver instead of to the etnaviv driver.

[1] https://lists.freedesktop.org/archives/etnaviv/2020-November/003442.html
[2] https://lists.freedesktop.org/archives/etnaviv/2020-December/003445.html

Thanks
Lubo



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

* [PATCH 1/1] clk: mmp2: Enable the 3D GPU clock alongside the 2D clock
  2021-02-04  2:01 [PATCH 0/1] clk: mmp2: Enable the 3D GPU clock alongside the 2D clock Lubomir Rintel
@ 2021-02-04  2:01 ` Lubomir Rintel
  0 siblings, 0 replies; 2+ messages in thread
From: Lubomir Rintel @ 2021-02-04  2:01 UTC (permalink / raw)
  To: Stephen Boyd
  Cc: Michael Turquette, Ivan Najdanovic, Lucas Stach, linux-clk,
	linux-kernel, Lubomir Rintel

The bits intended to control the 3D GPU clock need to be enabled for the
2D GPU to work. It is not clear why this needs to be done.

Forcing the 3D clock on when the etnaviv driver requests a 2D clock
works around the problem.

Signed-off-by: Lubomir Rintel <lkundrak@v3.sk>
---
 drivers/clk/mmp/clk-gate.c    |  9 ++++++++-
 drivers/clk/mmp/clk-of-mmp2.c |  2 +-
 drivers/clk/mmp/clk.c         |  3 ++-
 drivers/clk/mmp/clk.h         | 10 +++++++++-
 4 files changed, 20 insertions(+), 4 deletions(-)

diff --git a/drivers/clk/mmp/clk-gate.c b/drivers/clk/mmp/clk-gate.c
index 1755916ddef2d..bf93ffb258667 100644
--- a/drivers/clk/mmp/clk-gate.c
+++ b/drivers/clk/mmp/clk-gate.c
@@ -9,6 +9,7 @@
  * warranty of any kind, whether express or implied.
  */
 
+#include <linux/clk.h>
 #include <linux/clk-provider.h>
 #include <linux/slab.h>
 #include <linux/io.h>
@@ -31,6 +32,8 @@ static int mmp_clk_gate_enable(struct clk_hw *hw)
 	unsigned long rate;
 	u32 tmp;
 
+	clk_prepare_enable(gate->companion);
+
 	if (gate->lock)
 		spin_lock_irqsave(gate->lock, flags);
 
@@ -67,6 +70,8 @@ static void mmp_clk_gate_disable(struct clk_hw *hw)
 
 	if (gate->lock)
 		spin_unlock_irqrestore(gate->lock, flags);
+
+	clk_disable_unprepare(gate->companion);
 }
 
 static int mmp_clk_gate_is_enabled(struct clk_hw *hw)
@@ -95,7 +100,8 @@ const struct clk_ops mmp_clk_gate_ops = {
 struct clk *mmp_clk_register_gate(struct device *dev, const char *name,
 		const char *parent_name, unsigned long flags,
 		void __iomem *reg, u32 mask, u32 val_enable, u32 val_disable,
-		unsigned int gate_flags, spinlock_t *lock)
+		unsigned int gate_flags, spinlock_t *lock,
+		struct clk *companion)
 {
 	struct mmp_clk_gate *gate;
 	struct clk *clk;
@@ -119,6 +125,7 @@ struct clk *mmp_clk_register_gate(struct device *dev, const char *name,
 	gate->val_disable = val_disable;
 	gate->flags = gate_flags;
 	gate->lock = lock;
+	gate->companion = companion;
 	gate->hw.init = &init;
 
 	clk = clk_register(dev, &gate->hw);
diff --git a/drivers/clk/mmp/clk-of-mmp2.c b/drivers/clk/mmp/clk-of-mmp2.c
index 8b2eb989980bf..7ac96a1dcd60c 100644
--- a/drivers/clk/mmp/clk-of-mmp2.c
+++ b/drivers/clk/mmp/clk-of-mmp2.c
@@ -394,7 +394,7 @@ static struct mmp_param_gate_clk mmp2_apmu_gate_clks[] = {
 static struct mmp_param_gate_clk mmp3_apmu_gate_clks[] = {
 	{MMP3_CLK_SDH4, "sdh4_clk", "sdh_mix_clk", CLK_SET_RATE_PARENT, APMU_SDH4, 0x1b, 0x1b, 0x0, 0, &sdh_lock},
 	{MMP3_CLK_GPU_3D, "gpu_3d_clk", "gpu_3d_div", CLK_SET_RATE_PARENT, APMU_GPU, 0x5, 0x5, 0x0, MMP_CLK_GATE_NEED_DELAY, &gpu_lock},
-	{MMP3_CLK_GPU_2D, "gpu_2d_clk", "gpu_2d_div", CLK_SET_RATE_PARENT, APMU_GPU, 0x1c0000, 0x1c0000, 0x0, MMP_CLK_GATE_NEED_DELAY, &gpu_lock},
+	{MMP3_CLK_GPU_2D, "gpu_2d_clk", "gpu_2d_div", CLK_SET_RATE_PARENT, APMU_GPU, 0x1c0000, 0x1c0000, 0x0, MMP_CLK_GATE_NEED_DELAY, &gpu_lock, MMP3_CLK_GPU_3D},
 };
 
 static void mmp2_axi_periph_clk_init(struct mmp2_clk_unit *pxa_unit)
diff --git a/drivers/clk/mmp/clk.c b/drivers/clk/mmp/clk.c
index ca7d37e2c7be6..05d2b901cae5f 100644
--- a/drivers/clk/mmp/clk.c
+++ b/drivers/clk/mmp/clk.c
@@ -109,7 +109,8 @@ void mmp_register_gate_clks(struct mmp_clk_unit *unit,
 					clks[i].val_enable,
 					clks[i].val_disable,
 					clks[i].gate_flags,
-					clks[i].lock);
+					clks[i].lock,
+					unit->clk_table[clks[i].companion_id]);
 
 		if (IS_ERR(clk)) {
 			pr_err("%s: failed to register clock %s\n",
diff --git a/drivers/clk/mmp/clk.h b/drivers/clk/mmp/clk.h
index 55ac053797819..385b74e671c31 100644
--- a/drivers/clk/mmp/clk.h
+++ b/drivers/clk/mmp/clk.h
@@ -117,6 +117,13 @@ struct mmp_clk_gate {
 	u32 val_disable;
 	unsigned int flags;
 	spinlock_t *lock;
+
+	/*
+	 * The sole purpose of this is to make sure the 3D GPU clock gets
+	 * enabled alongside 2D GPU clock, otherwise the 2D unit wouldn't
+	 * work. It is not know why this needs to be done.
+	 */
+	struct clk *companion;
 };
 
 extern const struct clk_ops mmp_clk_gate_ops;
@@ -124,7 +131,7 @@ extern struct clk *mmp_clk_register_gate(struct device *dev, const char *name,
 			const char *parent_name, unsigned long flags,
 			void __iomem *reg, u32 mask, u32 val_enable,
 			u32 val_disable, unsigned int gate_flags,
-			spinlock_t *lock);
+			spinlock_t *lock, struct clk *companion);
 
 extern struct clk *mmp_clk_register_apbc(const char *name,
 		const char *parent_name, void __iomem *base,
@@ -187,6 +194,7 @@ struct mmp_param_gate_clk {
 	u32 val_disable;
 	unsigned int gate_flags;
 	spinlock_t *lock;
+	unsigned int companion_id;
 };
 void mmp_register_gate_clks(struct mmp_clk_unit *unit,
 			struct mmp_param_gate_clk *clks,
-- 
2.29.2


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

end of thread, other threads:[~2021-02-04  2:03 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-02-04  2:01 [PATCH 0/1] clk: mmp2: Enable the 3D GPU clock alongside the 2D clock Lubomir Rintel
2021-02-04  2:01 ` [PATCH 1/1] " 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).