* Re: [PATCH v2 00/91] drm/vc4: Support BCM2711 Display Pipelin
From: Maxime Ripard @ 2020-05-27 9:13 UTC (permalink / raw)
To: Daniel Drake
Cc: Jian-Hong Pan, Nicolas Saenz Julienne, Eric Anholt, dri-devel,
linux-rpi-kernel, bcm-kernel-feedback-list, linux-arm-kernel,
Linux Kernel, devicetree, linux-clk, linux-i2c,
Linux Upstreaming Team
In-Reply-To: <CAD8Lp467DiYWLwH6T1Jeq-uyN4VEuef-gGWw0_bBTtmSPr00Ag@mail.gmail.com>
[-- Attachment #1: Type: text/plain, Size: 490 bytes --]
Hi Daniel,
On Wed, May 27, 2020 at 11:49:36AM +0800, Daniel Drake wrote:
> Hi Maxime,
>
> On Tue, May 26, 2020 at 6:20 PM Maxime Ripard <maxime@cerno.tech> wrote:
> > I gave it a try with U-Boot with my latest work and couldn't reproduce it, so it
> > seems that I fixed it along the way
>
> Is your latest work available in a git branch anywhere that we could
> test directly?
I'm about to send a v3 today or tomorrow, I can Cc you (and Jian-Hong) if you
want.
Maxime
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]
^ permalink raw reply
* [PATCH RESEND v11 1/7] clk: Ingenic: Remove unnecessary spinlock when reading registers.
From: 周琰杰 (Zhou Yanjie) @ 2020-05-27 9:04 UTC (permalink / raw)
To: linux-clk
Cc: linux-kernel, devicetree, sboyd, mturquette, robh+dt,
dongsheng.qiu, aric.pzqi, rick.tyliu, yanfei.li, sernia.zhou,
zhenwenjin, paul
In-Reply-To: <20200527090419.56213-1-zhouyanjie@wanyeetech.com>
It is not necessary to use spinlock when reading registers,
so remove it from cgu.c.
Suggested-by: Paul Cercueil <paul@crapouillou.net>
Suggested-by: Paul Burton <paulburton@kernel.org>
Signed-off-by: 周琰杰 (Zhou Yanjie) <zhouyanjie@wanyeetech.com>
Reviewed-by: Paul Cercueil <paul@crapouillou.net>
---
Notes:
v2:
New patch.
v2->v3:
Adjust order from [5/5] in v2 to [1/5] in v3.
v3->v4:
Remove the spinlock around ingenic_cgu_gate_get().
v4->v5:
Rebase on top of kernel 5.6-rc1.
v5->v6:
No change.
v6->v7:
No change.
v7->v8:
No change.
v8->v9:
No change.
v9->v10:
No change.
v10->v11:
No change.
drivers/clk/ingenic/cgu.c | 12 +-----------
1 file changed, 1 insertion(+), 11 deletions(-)
diff --git a/drivers/clk/ingenic/cgu.c b/drivers/clk/ingenic/cgu.c
index 6e963031cd87..ab1302ad1450 100644
--- a/drivers/clk/ingenic/cgu.c
+++ b/drivers/clk/ingenic/cgu.c
@@ -76,16 +76,13 @@ ingenic_pll_recalc_rate(struct clk_hw *hw, unsigned long parent_rate)
const struct ingenic_cgu_pll_info *pll_info;
unsigned m, n, od_enc, od;
bool bypass;
- unsigned long flags;
u32 ctl;
clk_info = &cgu->clock_info[ingenic_clk->idx];
BUG_ON(clk_info->type != CGU_CLK_PLL);
pll_info = &clk_info->pll;
- spin_lock_irqsave(&cgu->lock, flags);
ctl = readl(cgu->base + pll_info->reg);
- spin_unlock_irqrestore(&cgu->lock, flags);
m = (ctl >> pll_info->m_shift) & GENMASK(pll_info->m_bits - 1, 0);
m += pll_info->m_offset;
@@ -259,12 +256,9 @@ static int ingenic_pll_is_enabled(struct clk_hw *hw)
struct ingenic_cgu *cgu = ingenic_clk->cgu;
const struct ingenic_cgu_clk_info *clk_info = to_clk_info(ingenic_clk);
const struct ingenic_cgu_pll_info *pll_info = &clk_info->pll;
- unsigned long flags;
u32 ctl;
- spin_lock_irqsave(&cgu->lock, flags);
ctl = readl(cgu->base + pll_info->reg);
- spin_unlock_irqrestore(&cgu->lock, flags);
return !!(ctl & BIT(pll_info->enable_bit));
}
@@ -562,16 +556,12 @@ static int ingenic_clk_is_enabled(struct clk_hw *hw)
struct ingenic_clk *ingenic_clk = to_ingenic_clk(hw);
struct ingenic_cgu *cgu = ingenic_clk->cgu;
const struct ingenic_cgu_clk_info *clk_info;
- unsigned long flags;
int enabled = 1;
clk_info = &cgu->clock_info[ingenic_clk->idx];
- if (clk_info->type & CGU_CLK_GATE) {
- spin_lock_irqsave(&cgu->lock, flags);
+ if (clk_info->type & CGU_CLK_GATE)
enabled = !ingenic_cgu_gate_get(cgu, &clk_info->gate);
- spin_unlock_irqrestore(&cgu->lock, flags);
- }
return enabled;
}
--
2.11.0
^ permalink raw reply related
* [PATCH RESEND v11 3/7] dt-bindings: clock: Add documentation for X1830 bindings.
From: 周琰杰 (Zhou Yanjie) @ 2020-05-27 9:04 UTC (permalink / raw)
To: linux-clk
Cc: linux-kernel, devicetree, sboyd, mturquette, robh+dt,
dongsheng.qiu, aric.pzqi, rick.tyliu, yanfei.li, sernia.zhou,
zhenwenjin, paul
In-Reply-To: <20200527090419.56213-1-zhouyanjie@wanyeetech.com>
Add documentation for the clock bindings of the X1830 Soc from Ingenic.
Signed-off-by: 周琰杰 (Zhou Yanjie) <zhouyanjie@wanyeetech.com>
Reviewed-by: Rob Herring <robh@kernel.org>
---
Notes:
v11:
New patch, split from [3/6] in v10.
Documentation/devicetree/bindings/clock/ingenic,cgu.yaml | 2 ++
1 file changed, 2 insertions(+)
diff --git a/Documentation/devicetree/bindings/clock/ingenic,cgu.yaml b/Documentation/devicetree/bindings/clock/ingenic,cgu.yaml
index 0281cd1d7e1b..a952d5811823 100644
--- a/Documentation/devicetree/bindings/clock/ingenic,cgu.yaml
+++ b/Documentation/devicetree/bindings/clock/ingenic,cgu.yaml
@@ -25,6 +25,7 @@ select:
- ingenic,jz4770-cgu
- ingenic,jz4780-cgu
- ingenic,x1000-cgu
+ - ingenic,x1830-cgu
required:
- compatible
@@ -51,6 +52,7 @@ properties:
- ingenic,jz4770-cgu
- ingenic,jz4780-cgu
- ingenic,x1000-cgu
+ - ingenic,x1830-cgu
- const: simple-mfd
minItems: 1
--
2.11.0
^ permalink raw reply related
* [PATCH RESEND v11 4/7] dt-bindings: clock: Add X1830 clock bindings.
From: 周琰杰 (Zhou Yanjie) @ 2020-05-27 9:04 UTC (permalink / raw)
To: linux-clk
Cc: linux-kernel, devicetree, sboyd, mturquette, robh+dt,
dongsheng.qiu, aric.pzqi, rick.tyliu, yanfei.li, sernia.zhou,
zhenwenjin, paul
In-Reply-To: <20200527090419.56213-1-zhouyanjie@wanyeetech.com>
Add the clock bindings for the X1830 Soc from Ingenic.
Signed-off-by: 周琰杰 (Zhou Yanjie) <zhouyanjie@wanyeetech.com>
Reviewed-by: Rob Herring <robh@kernel.org>
---
Notes:
v11:
New patch, split from [3/6] in v10.
include/dt-bindings/clock/x1830-cgu.h | 55 +++++++++++++++++++++++++++++++++++
1 file changed, 55 insertions(+)
create mode 100644 include/dt-bindings/clock/x1830-cgu.h
diff --git a/include/dt-bindings/clock/x1830-cgu.h b/include/dt-bindings/clock/x1830-cgu.h
new file mode 100644
index 000000000000..801e1d09c881
--- /dev/null
+++ b/include/dt-bindings/clock/x1830-cgu.h
@@ -0,0 +1,55 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * This header provides clock numbers for the ingenic,x1830-cgu DT binding.
+ *
+ * They are roughly ordered as:
+ * - external clocks
+ * - PLLs
+ * - muxes/dividers in the order they appear in the x1830 programmers manual
+ * - gates in order of their bit in the CLKGR* registers
+ */
+
+#ifndef __DT_BINDINGS_CLOCK_X1830_CGU_H__
+#define __DT_BINDINGS_CLOCK_X1830_CGU_H__
+
+#define X1830_CLK_EXCLK 0
+#define X1830_CLK_RTCLK 1
+#define X1830_CLK_APLL 2
+#define X1830_CLK_MPLL 3
+#define X1830_CLK_EPLL 4
+#define X1830_CLK_VPLL 5
+#define X1830_CLK_OTGPHY 6
+#define X1830_CLK_SCLKA 7
+#define X1830_CLK_CPUMUX 8
+#define X1830_CLK_CPU 9
+#define X1830_CLK_L2CACHE 10
+#define X1830_CLK_AHB0 11
+#define X1830_CLK_AHB2PMUX 12
+#define X1830_CLK_AHB2 13
+#define X1830_CLK_PCLK 14
+#define X1830_CLK_DDR 15
+#define X1830_CLK_MAC 16
+#define X1830_CLK_LCD 17
+#define X1830_CLK_MSCMUX 18
+#define X1830_CLK_MSC0 19
+#define X1830_CLK_MSC1 20
+#define X1830_CLK_SSIPLL 21
+#define X1830_CLK_SSIPLL_DIV2 22
+#define X1830_CLK_SSIMUX 23
+#define X1830_CLK_EMC 24
+#define X1830_CLK_EFUSE 25
+#define X1830_CLK_OTG 26
+#define X1830_CLK_SSI0 27
+#define X1830_CLK_SMB0 28
+#define X1830_CLK_SMB1 29
+#define X1830_CLK_SMB2 30
+#define X1830_CLK_UART0 31
+#define X1830_CLK_UART1 32
+#define X1830_CLK_SSI1 33
+#define X1830_CLK_SFC 34
+#define X1830_CLK_PDMA 35
+#define X1830_CLK_TCU 36
+#define X1830_CLK_DTRNG 37
+#define X1830_CLK_OST 38
+
+#endif /* __DT_BINDINGS_CLOCK_X1830_CGU_H__ */
--
2.11.0
^ permalink raw reply related
* [PATCH RESEND v11 2/7] clk: Ingenic: Adjust cgu code to make it compatible with X1830.
From: 周琰杰 (Zhou Yanjie) @ 2020-05-27 9:04 UTC (permalink / raw)
To: linux-clk
Cc: linux-kernel, devicetree, sboyd, mturquette, robh+dt,
dongsheng.qiu, aric.pzqi, rick.tyliu, yanfei.li, sernia.zhou,
zhenwenjin, paul
In-Reply-To: <20200527090419.56213-1-zhouyanjie@wanyeetech.com>
The PLL of X1830 Soc from Ingenic has been greatly changed,
the bypass control is placed in another register, so now two
registers may needed to control the PLL. To this end, a new
"bypass_reg" was introduced. In addition, when calculating
rate, the PLL of X1830 introduced an extra 2x multiplier,
so a new "rate_multiplier" was introduced. And adjust the
code in jz47xx-cgu.c and x1000-cgu.c, make it to be
compatible with the new cgu code.
Signed-off-by: 周琰杰 (Zhou Yanjie) <zhouyanjie@wanyeetech.com>
Reviewed-by: Paul Cercueil <paul@crapouillou.net>
---
Notes:
v2->v3:
Adjust order from [1/5] in v2 to [2/5] in v3.
v3->v4:
Merge [3/5] in v3 into this patch.
v4->v5:
Rebase on top of kernel 5.6-rc1.
v5->v6:
Revert "pll_reg" to "reg" to minimize patch as Paul Cercueil's suggest.
v6->v7:
Update commit message.
v7->v8:
No change.
v8->v9:
No change.
v9->v10:
No change.
v10->v11:
No change.
drivers/clk/ingenic/cgu.c | 16 +++++++++++++---
drivers/clk/ingenic/cgu.h | 4 ++++
drivers/clk/ingenic/jz4725b-cgu.c | 4 ++++
drivers/clk/ingenic/jz4740-cgu.c | 4 ++++
drivers/clk/ingenic/jz4770-cgu.c | 8 +++++++-
drivers/clk/ingenic/jz4780-cgu.c | 3 +++
drivers/clk/ingenic/x1000-cgu.c | 6 ++++++
7 files changed, 41 insertions(+), 4 deletions(-)
diff --git a/drivers/clk/ingenic/cgu.c b/drivers/clk/ingenic/cgu.c
index ab1302ad1450..d7981b670221 100644
--- a/drivers/clk/ingenic/cgu.c
+++ b/drivers/clk/ingenic/cgu.c
@@ -90,6 +90,9 @@ ingenic_pll_recalc_rate(struct clk_hw *hw, unsigned long parent_rate)
n += pll_info->n_offset;
od_enc = ctl >> pll_info->od_shift;
od_enc &= GENMASK(pll_info->od_bits - 1, 0);
+
+ ctl = readl(cgu->base + pll_info->bypass_reg);
+
bypass = !pll_info->no_bypass_bit &&
!!(ctl & BIT(pll_info->bypass_bit));
@@ -103,7 +106,8 @@ ingenic_pll_recalc_rate(struct clk_hw *hw, unsigned long parent_rate)
BUG_ON(od == pll_info->od_max);
od++;
- return div_u64((u64)parent_rate * m, n * od);
+ return div_u64((u64)parent_rate * m * pll_info->rate_multiplier,
+ n * od);
}
static unsigned long
@@ -136,7 +140,8 @@ ingenic_pll_calc(const struct ingenic_cgu_clk_info *clk_info,
if (pod)
*pod = od;
- return div_u64((u64)parent_rate * m, n * od);
+ return div_u64((u64)parent_rate * m * pll_info->rate_multiplier,
+ n * od);
}
static inline const struct ingenic_cgu_clk_info *to_clk_info(
@@ -209,9 +214,14 @@ static int ingenic_pll_enable(struct clk_hw *hw)
u32 ctl;
spin_lock_irqsave(&cgu->lock, flags);
- ctl = readl(cgu->base + pll_info->reg);
+ ctl = readl(cgu->base + pll_info->bypass_reg);
ctl &= ~BIT(pll_info->bypass_bit);
+
+ writel(ctl, cgu->base + pll_info->bypass_reg);
+
+ ctl = readl(cgu->base + pll_info->reg);
+
ctl |= BIT(pll_info->enable_bit);
writel(ctl, cgu->base + pll_info->reg);
diff --git a/drivers/clk/ingenic/cgu.h b/drivers/clk/ingenic/cgu.h
index 0dc8004079ee..2c75ef4a36f5 100644
--- a/drivers/clk/ingenic/cgu.h
+++ b/drivers/clk/ingenic/cgu.h
@@ -17,6 +17,7 @@
/**
* struct ingenic_cgu_pll_info - information about a PLL
* @reg: the offset of the PLL's control register within the CGU
+ * @rate_multiplier: the multiplier needed by pll rate calculation
* @m_shift: the number of bits to shift the multiplier value by (ie. the
* index of the lowest bit of the multiplier value in the PLL's
* control register)
@@ -37,6 +38,7 @@
* @od_encoding: a pointer to an array mapping post-VCO divider values to
* their encoded values in the PLL control register, or -1 for
* unsupported values
+ * @bypass_reg: the offset of the bypass control register within the CGU
* @bypass_bit: the index of the bypass bit in the PLL control register
* @enable_bit: the index of the enable bit in the PLL control register
* @stable_bit: the index of the stable bit in the PLL control register
@@ -44,10 +46,12 @@
*/
struct ingenic_cgu_pll_info {
unsigned reg;
+ unsigned rate_multiplier;
const s8 *od_encoding;
u8 m_shift, m_bits, m_offset;
u8 n_shift, n_bits, n_offset;
u8 od_shift, od_bits, od_max;
+ unsigned bypass_reg;
u8 bypass_bit;
u8 enable_bit;
u8 stable_bit;
diff --git a/drivers/clk/ingenic/jz4725b-cgu.c b/drivers/clk/ingenic/jz4725b-cgu.c
index a3b4635f6278..8c38e72d14a7 100644
--- a/drivers/clk/ingenic/jz4725b-cgu.c
+++ b/drivers/clk/ingenic/jz4725b-cgu.c
@@ -9,7 +9,9 @@
#include <linux/clk-provider.h>
#include <linux/delay.h>
#include <linux/of.h>
+
#include <dt-bindings/clock/jz4725b-cgu.h>
+
#include "cgu.h"
#include "pm.h"
@@ -54,6 +56,7 @@ static const struct ingenic_cgu_clk_info jz4725b_cgu_clocks[] = {
.parents = { JZ4725B_CLK_EXT, -1, -1, -1 },
.pll = {
.reg = CGU_REG_CPPCR,
+ .rate_multiplier = 1,
.m_shift = 23,
.m_bits = 9,
.m_offset = 2,
@@ -65,6 +68,7 @@ static const struct ingenic_cgu_clk_info jz4725b_cgu_clocks[] = {
.od_max = 4,
.od_encoding = pll_od_encoding,
.stable_bit = 10,
+ .bypass_reg = CGU_REG_CPPCR,
.bypass_bit = 9,
.enable_bit = 8,
},
diff --git a/drivers/clk/ingenic/jz4740-cgu.c b/drivers/clk/ingenic/jz4740-cgu.c
index 4f0e92c877d6..c0ac9196a581 100644
--- a/drivers/clk/ingenic/jz4740-cgu.c
+++ b/drivers/clk/ingenic/jz4740-cgu.c
@@ -10,7 +10,9 @@
#include <linux/delay.h>
#include <linux/io.h>
#include <linux/of.h>
+
#include <dt-bindings/clock/jz4740-cgu.h>
+
#include "cgu.h"
#include "pm.h"
@@ -69,6 +71,7 @@ static const struct ingenic_cgu_clk_info jz4740_cgu_clocks[] = {
.parents = { JZ4740_CLK_EXT, -1, -1, -1 },
.pll = {
.reg = CGU_REG_CPPCR,
+ .rate_multiplier = 1,
.m_shift = 23,
.m_bits = 9,
.m_offset = 2,
@@ -80,6 +83,7 @@ static const struct ingenic_cgu_clk_info jz4740_cgu_clocks[] = {
.od_max = 4,
.od_encoding = pll_od_encoding,
.stable_bit = 10,
+ .bypass_reg = CGU_REG_CPPCR,
.bypass_bit = 9,
.enable_bit = 8,
},
diff --git a/drivers/clk/ingenic/jz4770-cgu.c b/drivers/clk/ingenic/jz4770-cgu.c
index c051ecba5cf8..9ea4490ecb7f 100644
--- a/drivers/clk/ingenic/jz4770-cgu.c
+++ b/drivers/clk/ingenic/jz4770-cgu.c
@@ -9,7 +9,9 @@
#include <linux/delay.h>
#include <linux/io.h>
#include <linux/of.h>
+
#include <dt-bindings/clock/jz4770-cgu.h>
+
#include "cgu.h"
#include "pm.h"
@@ -102,6 +104,7 @@ static const struct ingenic_cgu_clk_info jz4770_cgu_clocks[] = {
.parents = { JZ4770_CLK_EXT },
.pll = {
.reg = CGU_REG_CPPCR0,
+ .rate_multiplier = 1,
.m_shift = 24,
.m_bits = 7,
.m_offset = 1,
@@ -112,6 +115,7 @@ static const struct ingenic_cgu_clk_info jz4770_cgu_clocks[] = {
.od_bits = 2,
.od_max = 8,
.od_encoding = pll_od_encoding,
+ .bypass_reg = CGU_REG_CPPCR0,
.bypass_bit = 9,
.enable_bit = 8,
.stable_bit = 10,
@@ -124,6 +128,7 @@ static const struct ingenic_cgu_clk_info jz4770_cgu_clocks[] = {
.parents = { JZ4770_CLK_EXT },
.pll = {
.reg = CGU_REG_CPPCR1,
+ .rate_multiplier = 1,
.m_shift = 24,
.m_bits = 7,
.m_offset = 1,
@@ -134,9 +139,10 @@ static const struct ingenic_cgu_clk_info jz4770_cgu_clocks[] = {
.od_bits = 2,
.od_max = 8,
.od_encoding = pll_od_encoding,
+ .bypass_reg = CGU_REG_CPPCR1,
+ .no_bypass_bit = true,
.enable_bit = 7,
.stable_bit = 6,
- .no_bypass_bit = true,
},
},
diff --git a/drivers/clk/ingenic/jz4780-cgu.c b/drivers/clk/ingenic/jz4780-cgu.c
index c758f1643067..6c5b8029cc8a 100644
--- a/drivers/clk/ingenic/jz4780-cgu.c
+++ b/drivers/clk/ingenic/jz4780-cgu.c
@@ -13,6 +13,7 @@
#include <linux/of.h>
#include <dt-bindings/clock/jz4780-cgu.h>
+
#include "cgu.h"
#include "pm.h"
@@ -266,6 +267,7 @@ static const struct ingenic_cgu_clk_info jz4780_cgu_clocks[] = {
#define DEF_PLL(name) { \
.reg = CGU_REG_ ## name, \
+ .rate_multiplier = 1, \
.m_shift = 19, \
.m_bits = 13, \
.m_offset = 1, \
@@ -277,6 +279,7 @@ static const struct ingenic_cgu_clk_info jz4780_cgu_clocks[] = {
.od_max = 16, \
.od_encoding = pll_od_encoding, \
.stable_bit = 6, \
+ .bypass_reg = CGU_REG_ ## name, \
.bypass_bit = 1, \
.enable_bit = 0, \
}
diff --git a/drivers/clk/ingenic/x1000-cgu.c b/drivers/clk/ingenic/x1000-cgu.c
index b22d87b3f555..c33934d8ac14 100644
--- a/drivers/clk/ingenic/x1000-cgu.c
+++ b/drivers/clk/ingenic/x1000-cgu.c
@@ -7,7 +7,9 @@
#include <linux/clk-provider.h>
#include <linux/delay.h>
#include <linux/of.h>
+
#include <dt-bindings/clock/x1000-cgu.h>
+
#include "cgu.h"
#include "pm.h"
@@ -58,6 +60,7 @@ static const struct ingenic_cgu_clk_info x1000_cgu_clocks[] = {
.parents = { X1000_CLK_EXCLK, -1, -1, -1 },
.pll = {
.reg = CGU_REG_APLL,
+ .rate_multiplier = 1,
.m_shift = 24,
.m_bits = 7,
.m_offset = 1,
@@ -68,6 +71,7 @@ static const struct ingenic_cgu_clk_info x1000_cgu_clocks[] = {
.od_bits = 2,
.od_max = 8,
.od_encoding = pll_od_encoding,
+ .bypass_reg = CGU_REG_APLL,
.bypass_bit = 9,
.enable_bit = 8,
.stable_bit = 10,
@@ -79,6 +83,7 @@ static const struct ingenic_cgu_clk_info x1000_cgu_clocks[] = {
.parents = { X1000_CLK_EXCLK, -1, -1, -1 },
.pll = {
.reg = CGU_REG_MPLL,
+ .rate_multiplier = 1,
.m_shift = 24,
.m_bits = 7,
.m_offset = 1,
@@ -89,6 +94,7 @@ static const struct ingenic_cgu_clk_info x1000_cgu_clocks[] = {
.od_bits = 2,
.od_max = 8,
.od_encoding = pll_od_encoding,
+ .bypass_reg = CGU_REG_MPLL,
.bypass_bit = 6,
.enable_bit = 7,
.stable_bit = 0,
--
2.11.0
^ permalink raw reply related
* [PATCH RESEND v11 5/7] clk: Ingenic: Add CGU driver for X1830.
From: 周琰杰 (Zhou Yanjie) @ 2020-05-27 9:04 UTC (permalink / raw)
To: linux-clk
Cc: linux-kernel, devicetree, sboyd, mturquette, robh+dt,
dongsheng.qiu, aric.pzqi, rick.tyliu, yanfei.li, sernia.zhou,
zhenwenjin, paul
In-Reply-To: <20200527090419.56213-1-zhouyanjie@wanyeetech.com>
Add support for the clocks provided by the CGU in the Ingenic X1830
SoC, making use of the cgu code to do the heavy lifting.
Signed-off-by: 周琰杰 (Zhou Yanjie) <zhouyanjie@wanyeetech.com>
Reviewed-by: Paul Cercueil <paul@crapouillou.net>
---
Notes:
v1->v2:
1.Use two fields (pll_reg & bypass_reg) instead of the 2-values
array (reg[2]).
2.Remove the "pll_info->version" and add a "pll_info->rate_multiplier".
3.Change my Signed-off-by from "Zhou Yanjie <zhouyanjie@zoho.com>"
to "周琰杰 (Zhou Yanjie) <zhouyanjie@wanyeetech.com>" because
the old mailbox is in an unstable state.
v2->v3:
Adjust order from [4/5] in v2 to [5/5] in v3.
v3->v4:
Adjust order from [5/5] in v3 to [4/4] in v4.
v4->v5:
Rebase on top of kernel 5.6-rc1.
v5->v6:
Add missing part of X1830's CGU.
v6->v7:
1.Adjust includes, add blank line as Paul Cercueil's suggest.
2.Move "*cgu" into x1830_cgu_init() as a local variable.
v7->v8:
No change.
v8->v9:
Add Paul Cercueil's Reviewed-by, somehow his emails are not displayed
on the mailing list and patchwork of clock framework subsystem.
v9->v10:
1.Add missing "X1830_CLK_TCU".
2.Fix bugs in "X1830_CLK_OTGPHY".
v10->v11:
No change.
drivers/clk/ingenic/Kconfig | 10 +
drivers/clk/ingenic/Makefile | 1 +
drivers/clk/ingenic/x1830-cgu.c | 443 ++++++++++++++++++++++++++++++++++++++++
3 files changed, 454 insertions(+)
create mode 100644 drivers/clk/ingenic/x1830-cgu.c
diff --git a/drivers/clk/ingenic/Kconfig b/drivers/clk/ingenic/Kconfig
index b4555b465ea6..580b0cf69ed5 100644
--- a/drivers/clk/ingenic/Kconfig
+++ b/drivers/clk/ingenic/Kconfig
@@ -55,6 +55,16 @@ config INGENIC_CGU_X1000
If building for a X1000 SoC, you want to say Y here.
+config INGENIC_CGU_X1830
+ bool "Ingenic X1830 CGU driver"
+ default MACH_X1830
+ select INGENIC_CGU_COMMON
+ help
+ Support the clocks provided by the CGU hardware on Ingenic X1830
+ and compatible SoCs.
+
+ If building for a X1830 SoC, you want to say Y here.
+
config INGENIC_TCU_CLK
bool "Ingenic JZ47xx TCU clocks driver"
default MACH_INGENIC
diff --git a/drivers/clk/ingenic/Makefile b/drivers/clk/ingenic/Makefile
index 8b1dad9b74a7..aaa4bffe03c6 100644
--- a/drivers/clk/ingenic/Makefile
+++ b/drivers/clk/ingenic/Makefile
@@ -5,4 +5,5 @@ obj-$(CONFIG_INGENIC_CGU_JZ4725B) += jz4725b-cgu.o
obj-$(CONFIG_INGENIC_CGU_JZ4770) += jz4770-cgu.o
obj-$(CONFIG_INGENIC_CGU_JZ4780) += jz4780-cgu.o
obj-$(CONFIG_INGENIC_CGU_X1000) += x1000-cgu.o
+obj-$(CONFIG_INGENIC_CGU_X1830) += x1830-cgu.o
obj-$(CONFIG_INGENIC_TCU_CLK) += tcu.o
diff --git a/drivers/clk/ingenic/x1830-cgu.c b/drivers/clk/ingenic/x1830-cgu.c
new file mode 100644
index 000000000000..29a637f4a2cc
--- /dev/null
+++ b/drivers/clk/ingenic/x1830-cgu.c
@@ -0,0 +1,443 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * X1830 SoC CGU driver
+ * Copyright (c) 2019 周琰杰 (Zhou Yanjie) <zhouyanjie@wanyeetech.com>
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/delay.h>
+#include <linux/of.h>
+
+#include <dt-bindings/clock/x1830-cgu.h>
+
+#include "cgu.h"
+#include "pm.h"
+
+/* CGU register offsets */
+#define CGU_REG_CPCCR 0x00
+#define CGU_REG_CPPCR 0x0c
+#define CGU_REG_APLL 0x10
+#define CGU_REG_MPLL 0x14
+#define CGU_REG_CLKGR0 0x20
+#define CGU_REG_OPCR 0x24
+#define CGU_REG_CLKGR1 0x28
+#define CGU_REG_DDRCDR 0x2c
+#define CGU_REG_USBPCR 0x3c
+#define CGU_REG_USBRDT 0x40
+#define CGU_REG_USBVBFIL 0x44
+#define CGU_REG_USBPCR1 0x48
+#define CGU_REG_MACCDR 0x54
+#define CGU_REG_EPLL 0x58
+#define CGU_REG_I2SCDR 0x60
+#define CGU_REG_LPCDR 0x64
+#define CGU_REG_MSC0CDR 0x68
+#define CGU_REG_I2SCDR1 0x70
+#define CGU_REG_SSICDR 0x74
+#define CGU_REG_CIMCDR 0x7c
+#define CGU_REG_MSC1CDR 0xa4
+#define CGU_REG_CMP_INTR 0xb0
+#define CGU_REG_CMP_INTRE 0xb4
+#define CGU_REG_DRCG 0xd0
+#define CGU_REG_CPCSR 0xd4
+#define CGU_REG_VPLL 0xe0
+#define CGU_REG_MACPHYC 0xe8
+
+/* bits within the OPCR register */
+#define OPCR_GATE_USBPHYCLK BIT(23)
+#define OPCR_SPENDN0 BIT(7)
+#define OPCR_SPENDN1 BIT(6)
+
+/* bits within the USBPCR register */
+#define USBPCR_SIDDQ BIT(21)
+#define USBPCR_OTG_DISABLE BIT(20)
+
+static struct ingenic_cgu *cgu;
+
+static int x1830_usb_phy_enable(struct clk_hw *hw)
+{
+ void __iomem *reg_opcr = cgu->base + CGU_REG_OPCR;
+ void __iomem *reg_usbpcr = cgu->base + CGU_REG_USBPCR;
+
+ writel((readl(reg_opcr) | OPCR_SPENDN0) & ~OPCR_GATE_USBPHYCLK, reg_opcr);
+ writel(readl(reg_usbpcr) & ~USBPCR_OTG_DISABLE & ~USBPCR_SIDDQ, reg_usbpcr);
+ return 0;
+}
+
+static void x1830_usb_phy_disable(struct clk_hw *hw)
+{
+ void __iomem *reg_opcr = cgu->base + CGU_REG_OPCR;
+ void __iomem *reg_usbpcr = cgu->base + CGU_REG_USBPCR;
+
+ writel((readl(reg_opcr) & ~OPCR_SPENDN0) | OPCR_GATE_USBPHYCLK, reg_opcr);
+ writel(readl(reg_usbpcr) | USBPCR_OTG_DISABLE | USBPCR_SIDDQ, reg_usbpcr);
+}
+
+static int x1830_usb_phy_is_enabled(struct clk_hw *hw)
+{
+ void __iomem *reg_opcr = cgu->base + CGU_REG_OPCR;
+ void __iomem *reg_usbpcr = cgu->base + CGU_REG_USBPCR;
+
+ return (readl(reg_opcr) & OPCR_SPENDN0) &&
+ !(readl(reg_usbpcr) & USBPCR_SIDDQ) &&
+ !(readl(reg_usbpcr) & USBPCR_OTG_DISABLE);
+}
+
+static const struct clk_ops x1830_otg_phy_ops = {
+ .enable = x1830_usb_phy_enable,
+ .disable = x1830_usb_phy_disable,
+ .is_enabled = x1830_usb_phy_is_enabled,
+};
+
+static const s8 pll_od_encoding[64] = {
+ 0x0, 0x1, -1, 0x2, -1, -1, -1, 0x3,
+ -1, -1, -1, -1, -1, -1, -1, 0x4,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, 0x5,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, 0x6,
+};
+
+static const struct ingenic_cgu_clk_info x1830_cgu_clocks[] = {
+
+ /* External clocks */
+
+ [X1830_CLK_EXCLK] = { "ext", CGU_CLK_EXT },
+ [X1830_CLK_RTCLK] = { "rtc", CGU_CLK_EXT },
+
+ /* PLLs */
+
+ [X1830_CLK_APLL] = {
+ "apll", CGU_CLK_PLL,
+ .parents = { X1830_CLK_EXCLK, -1, -1, -1 },
+ .pll = {
+ .reg = CGU_REG_APLL,
+ .rate_multiplier = 2,
+ .m_shift = 20,
+ .m_bits = 9,
+ .m_offset = 1,
+ .n_shift = 14,
+ .n_bits = 6,
+ .n_offset = 1,
+ .od_shift = 11,
+ .od_bits = 3,
+ .od_max = 64,
+ .od_encoding = pll_od_encoding,
+ .bypass_reg = CGU_REG_CPPCR,
+ .bypass_bit = 30,
+ .enable_bit = 0,
+ .stable_bit = 3,
+ },
+ },
+
+ [X1830_CLK_MPLL] = {
+ "mpll", CGU_CLK_PLL,
+ .parents = { X1830_CLK_EXCLK, -1, -1, -1 },
+ .pll = {
+ .reg = CGU_REG_MPLL,
+ .rate_multiplier = 2,
+ .m_shift = 20,
+ .m_bits = 9,
+ .m_offset = 1,
+ .n_shift = 14,
+ .n_bits = 6,
+ .n_offset = 1,
+ .od_shift = 11,
+ .od_bits = 3,
+ .od_max = 64,
+ .od_encoding = pll_od_encoding,
+ .bypass_reg = CGU_REG_CPPCR,
+ .bypass_bit = 28,
+ .enable_bit = 0,
+ .stable_bit = 3,
+ },
+ },
+
+ [X1830_CLK_EPLL] = {
+ "epll", CGU_CLK_PLL,
+ .parents = { X1830_CLK_EXCLK, -1, -1, -1 },
+ .pll = {
+ .reg = CGU_REG_EPLL,
+ .rate_multiplier = 2,
+ .m_shift = 20,
+ .m_bits = 9,
+ .m_offset = 1,
+ .n_shift = 14,
+ .n_bits = 6,
+ .n_offset = 1,
+ .od_shift = 11,
+ .od_bits = 3,
+ .od_max = 64,
+ .od_encoding = pll_od_encoding,
+ .bypass_reg = CGU_REG_CPPCR,
+ .bypass_bit = 24,
+ .enable_bit = 0,
+ .stable_bit = 3,
+ },
+ },
+
+ [X1830_CLK_VPLL] = {
+ "vpll", CGU_CLK_PLL,
+ .parents = { X1830_CLK_EXCLK, -1, -1, -1 },
+ .pll = {
+ .reg = CGU_REG_VPLL,
+ .rate_multiplier = 2,
+ .m_shift = 20,
+ .m_bits = 9,
+ .m_offset = 1,
+ .n_shift = 14,
+ .n_bits = 6,
+ .n_offset = 1,
+ .od_shift = 11,
+ .od_bits = 3,
+ .od_max = 64,
+ .od_encoding = pll_od_encoding,
+ .bypass_reg = CGU_REG_CPPCR,
+ .bypass_bit = 26,
+ .enable_bit = 0,
+ .stable_bit = 3,
+ },
+ },
+
+ /* Custom (SoC-specific) OTG PHY */
+
+ [X1830_CLK_OTGPHY] = {
+ "otg_phy", CGU_CLK_CUSTOM,
+ .parents = { X1830_CLK_EXCLK, -1, -1, -1 },
+ .custom = { &x1830_otg_phy_ops },
+ },
+
+ /* Muxes & dividers */
+
+ [X1830_CLK_SCLKA] = {
+ "sclk_a", CGU_CLK_MUX,
+ .parents = { -1, X1830_CLK_EXCLK, X1830_CLK_APLL, -1 },
+ .mux = { CGU_REG_CPCCR, 30, 2 },
+ },
+
+ [X1830_CLK_CPUMUX] = {
+ "cpu_mux", CGU_CLK_MUX,
+ .parents = { -1, X1830_CLK_SCLKA, X1830_CLK_MPLL, -1 },
+ .mux = { CGU_REG_CPCCR, 28, 2 },
+ },
+
+ [X1830_CLK_CPU] = {
+ "cpu", CGU_CLK_DIV | CGU_CLK_GATE,
+ .parents = { X1830_CLK_CPUMUX, -1, -1, -1 },
+ .div = { CGU_REG_CPCCR, 0, 1, 4, 22, -1, -1 },
+ .gate = { CGU_REG_CLKGR1, 15 },
+ },
+
+ [X1830_CLK_L2CACHE] = {
+ "l2cache", CGU_CLK_DIV,
+ .parents = { X1830_CLK_CPUMUX, -1, -1, -1 },
+ .div = { CGU_REG_CPCCR, 4, 1, 4, 22, -1, -1 },
+ },
+
+ [X1830_CLK_AHB0] = {
+ "ahb0", CGU_CLK_MUX | CGU_CLK_DIV,
+ .parents = { -1, X1830_CLK_SCLKA, X1830_CLK_MPLL, -1 },
+ .mux = { CGU_REG_CPCCR, 26, 2 },
+ .div = { CGU_REG_CPCCR, 8, 1, 4, 21, -1, -1 },
+ },
+
+ [X1830_CLK_AHB2PMUX] = {
+ "ahb2_apb_mux", CGU_CLK_MUX,
+ .parents = { -1, X1830_CLK_SCLKA, X1830_CLK_MPLL, -1 },
+ .mux = { CGU_REG_CPCCR, 24, 2 },
+ },
+
+ [X1830_CLK_AHB2] = {
+ "ahb2", CGU_CLK_DIV,
+ .parents = { X1830_CLK_AHB2PMUX, -1, -1, -1 },
+ .div = { CGU_REG_CPCCR, 12, 1, 4, 20, -1, -1 },
+ },
+
+ [X1830_CLK_PCLK] = {
+ "pclk", CGU_CLK_DIV | CGU_CLK_GATE,
+ .parents = { X1830_CLK_AHB2PMUX, -1, -1, -1 },
+ .div = { CGU_REG_CPCCR, 16, 1, 4, 20, -1, -1 },
+ .gate = { CGU_REG_CLKGR1, 14 },
+ },
+
+ [X1830_CLK_DDR] = {
+ "ddr", CGU_CLK_MUX | CGU_CLK_DIV | CGU_CLK_GATE,
+ .parents = { -1, X1830_CLK_SCLKA, X1830_CLK_MPLL, -1 },
+ .mux = { CGU_REG_DDRCDR, 30, 2 },
+ .div = { CGU_REG_DDRCDR, 0, 1, 4, 29, 28, 27 },
+ .gate = { CGU_REG_CLKGR0, 31 },
+ },
+
+ [X1830_CLK_MAC] = {
+ "mac", CGU_CLK_MUX | CGU_CLK_DIV | CGU_CLK_GATE,
+ .parents = { X1830_CLK_SCLKA, X1830_CLK_MPLL,
+ X1830_CLK_VPLL, X1830_CLK_EPLL },
+ .mux = { CGU_REG_MACCDR, 30, 2 },
+ .div = { CGU_REG_MACCDR, 0, 1, 8, 29, 28, 27 },
+ .gate = { CGU_REG_CLKGR1, 4 },
+ },
+
+ [X1830_CLK_LCD] = {
+ "lcd", CGU_CLK_MUX | CGU_CLK_DIV | CGU_CLK_GATE,
+ .parents = { X1830_CLK_SCLKA, X1830_CLK_MPLL,
+ X1830_CLK_VPLL, X1830_CLK_EPLL },
+ .mux = { CGU_REG_LPCDR, 30, 2 },
+ .div = { CGU_REG_LPCDR, 0, 1, 8, 28, 27, 26 },
+ .gate = { CGU_REG_CLKGR1, 9 },
+ },
+
+ [X1830_CLK_MSCMUX] = {
+ "msc_mux", CGU_CLK_MUX,
+ .parents = { X1830_CLK_SCLKA, X1830_CLK_MPLL,
+ X1830_CLK_VPLL, X1830_CLK_EPLL },
+ .mux = { CGU_REG_MSC0CDR, 30, 2 },
+ },
+
+ [X1830_CLK_MSC0] = {
+ "msc0", CGU_CLK_DIV | CGU_CLK_GATE,
+ .parents = { X1830_CLK_MSCMUX, -1, -1, -1 },
+ .div = { CGU_REG_MSC0CDR, 0, 2, 8, 29, 28, 27 },
+ .gate = { CGU_REG_CLKGR0, 4 },
+ },
+
+ [X1830_CLK_MSC1] = {
+ "msc1", CGU_CLK_DIV | CGU_CLK_GATE,
+ .parents = { X1830_CLK_MSCMUX, -1, -1, -1 },
+ .div = { CGU_REG_MSC1CDR, 0, 2, 8, 29, 28, 27 },
+ .gate = { CGU_REG_CLKGR0, 5 },
+ },
+
+ [X1830_CLK_SSIPLL] = {
+ "ssi_pll", CGU_CLK_MUX | CGU_CLK_DIV,
+ .parents = { X1830_CLK_SCLKA, X1830_CLK_MPLL,
+ X1830_CLK_VPLL, X1830_CLK_EPLL },
+ .mux = { CGU_REG_SSICDR, 30, 2 },
+ .div = { CGU_REG_SSICDR, 0, 1, 8, 28, 27, 26 },
+ },
+
+ [X1830_CLK_SSIPLL_DIV2] = {
+ "ssi_pll_div2", CGU_CLK_FIXDIV,
+ .parents = { X1830_CLK_SSIPLL },
+ .fixdiv = { 2 },
+ },
+
+ [X1830_CLK_SSIMUX] = {
+ "ssi_mux", CGU_CLK_MUX,
+ .parents = { X1830_CLK_EXCLK, X1830_CLK_SSIPLL_DIV2, -1, -1 },
+ .mux = { CGU_REG_SSICDR, 29, 1 },
+ },
+
+ /* Gate-only clocks */
+
+ [X1830_CLK_EMC] = {
+ "emc", CGU_CLK_GATE,
+ .parents = { X1830_CLK_AHB2, -1, -1, -1 },
+ .gate = { CGU_REG_CLKGR0, 0 },
+ },
+
+ [X1830_CLK_EFUSE] = {
+ "efuse", CGU_CLK_GATE,
+ .parents = { X1830_CLK_AHB2, -1, -1, -1 },
+ .gate = { CGU_REG_CLKGR0, 1 },
+ },
+
+ [X1830_CLK_OTG] = {
+ "otg", CGU_CLK_GATE,
+ .parents = { X1830_CLK_EXCLK, -1, -1, -1 },
+ .gate = { CGU_REG_CLKGR0, 3 },
+ },
+
+ [X1830_CLK_SSI0] = {
+ "ssi0", CGU_CLK_GATE,
+ .parents = { X1830_CLK_SSIMUX, -1, -1, -1 },
+ .gate = { CGU_REG_CLKGR0, 6 },
+ },
+
+ [X1830_CLK_SMB0] = {
+ "smb0", CGU_CLK_GATE,
+ .parents = { X1830_CLK_PCLK, -1, -1, -1 },
+ .gate = { CGU_REG_CLKGR0, 7 },
+ },
+
+ [X1830_CLK_SMB1] = {
+ "smb1", CGU_CLK_GATE,
+ .parents = { X1830_CLK_PCLK, -1, -1, -1 },
+ .gate = { CGU_REG_CLKGR0, 8 },
+ },
+
+ [X1830_CLK_SMB2] = {
+ "smb2", CGU_CLK_GATE,
+ .parents = { X1830_CLK_PCLK, -1, -1, -1 },
+ .gate = { CGU_REG_CLKGR0, 9 },
+ },
+
+ [X1830_CLK_UART0] = {
+ "uart0", CGU_CLK_GATE,
+ .parents = { X1830_CLK_EXCLK, -1, -1, -1 },
+ .gate = { CGU_REG_CLKGR0, 14 },
+ },
+
+ [X1830_CLK_UART1] = {
+ "uart1", CGU_CLK_GATE,
+ .parents = { X1830_CLK_EXCLK, -1, -1, -1 },
+ .gate = { CGU_REG_CLKGR0, 15 },
+ },
+
+ [X1830_CLK_SSI1] = {
+ "ssi1", CGU_CLK_GATE,
+ .parents = { X1830_CLK_SSIMUX, -1, -1, -1 },
+ .gate = { CGU_REG_CLKGR0, 19 },
+ },
+
+ [X1830_CLK_SFC] = {
+ "sfc", CGU_CLK_GATE,
+ .parents = { X1830_CLK_SSIPLL, -1, -1, -1 },
+ .gate = { CGU_REG_CLKGR0, 20 },
+ },
+
+ [X1830_CLK_PDMA] = {
+ "pdma", CGU_CLK_GATE,
+ .parents = { X1830_CLK_EXCLK, -1, -1, -1 },
+ .gate = { CGU_REG_CLKGR0, 21 },
+ },
+
+ [X1830_CLK_TCU] = {
+ "tcu", CGU_CLK_GATE,
+ .parents = { X1830_CLK_EXCLK, -1, -1, -1 },
+ .gate = { CGU_REG_CLKGR0, 30 },
+ },
+
+ [X1830_CLK_DTRNG] = {
+ "dtrng", CGU_CLK_GATE,
+ .parents = { X1830_CLK_PCLK, -1, -1, -1 },
+ .gate = { CGU_REG_CLKGR1, 1 },
+ },
+
+ [X1830_CLK_OST] = {
+ "ost", CGU_CLK_GATE,
+ .parents = { X1830_CLK_EXCLK, -1, -1, -1 },
+ .gate = { CGU_REG_CLKGR1, 11 },
+ },
+};
+
+static void __init x1830_cgu_init(struct device_node *np)
+{
+ int retval;
+
+ cgu = ingenic_cgu_new(x1830_cgu_clocks,
+ ARRAY_SIZE(x1830_cgu_clocks), np);
+ if (!cgu) {
+ pr_err("%s: failed to initialise CGU\n", __func__);
+ return;
+ }
+
+ retval = ingenic_cgu_register_clocks(cgu);
+ if (retval) {
+ pr_err("%s: failed to register CGU Clocks\n", __func__);
+ return;
+ }
+
+ ingenic_cgu_register_syscore_ops(cgu);
+}
+CLK_OF_DECLARE_DRIVER(x1830_cgu, "ingenic,x1830-cgu", x1830_cgu_init);
--
2.11.0
^ permalink raw reply related
* [PATCH RESEND v11 7/7] clk: X1000: Add FIXDIV for SSI clock of X1000.
From: 周琰杰 (Zhou Yanjie) @ 2020-05-27 9:04 UTC (permalink / raw)
To: linux-clk
Cc: linux-kernel, devicetree, sboyd, mturquette, robh+dt,
dongsheng.qiu, aric.pzqi, rick.tyliu, yanfei.li, sernia.zhou,
zhenwenjin, paul
In-Reply-To: <20200527090419.56213-1-zhouyanjie@wanyeetech.com>
1.The SSI clock of X1000 not like JZ4770 and JZ4780, they are not
directly derived from the output of SSIPLL, but from the clock
obtained by dividing the frequency by 2. "X1000_CLK_SSIPLL_DIV2"
is added for this purpose, and ensure that it initialized before
"X1000_CLK_SSIMUX" when initializing the clocks.
2.Clocks of LCD, OTG, EMC, EFUSE, OST, TCU, and gates of CPU, PCLK
are also added.
3.Use "CLK_OF_DECLARE_DRIVER" like the other CGU drivers.
Signed-off-by: 周琰杰 (Zhou Yanjie) <zhouyanjie@wanyeetech.com>
Reviewed-by: Paul Cercueil <paul@crapouillou.net>
---
Notes:
v5:
New patch.
V5->v6:
Add missing part of X1000's CGU.
v6->v7:
Update commit message.
v7->v8:
No change.
v8->v9:
Add Paul Cercueil's Reviewed-by, somehow his emails are not displayed
on the mailing list and patchwork of clock framework subsystem.
v9->v10:
No change.
v10->v11:
No change.
drivers/clk/ingenic/x1000-cgu.c | 110 ++++++++++++++++++++++++++++++++++++++--
1 file changed, 105 insertions(+), 5 deletions(-)
diff --git a/drivers/clk/ingenic/x1000-cgu.c b/drivers/clk/ingenic/x1000-cgu.c
index c33934d8ac14..68c6e62457e1 100644
--- a/drivers/clk/ingenic/x1000-cgu.c
+++ b/drivers/clk/ingenic/x1000-cgu.c
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: GPL-2.0
/*
* X1000 SoC CGU driver
- * Copyright (c) 2019 Zhou Yanjie <zhouyanjie@zoho.com>
+ * Copyright (c) 2019 周琰杰 (Zhou Yanjie) <zhouyanjie@wanyeetech.com>
*/
#include <linux/clk-provider.h>
@@ -20,6 +20,9 @@
#define CGU_REG_CLKGR 0x20
#define CGU_REG_OPCR 0x24
#define CGU_REG_DDRCDR 0x2c
+#define CGU_REG_USBPCR 0x3c
+#define CGU_REG_USBPCR1 0x48
+#define CGU_REG_USBCDR 0x50
#define CGU_REG_MACCDR 0x54
#define CGU_REG_I2SCDR 0x60
#define CGU_REG_LPCDR 0x64
@@ -40,8 +43,47 @@
#define OPCR_SPENDN0 BIT(7)
#define OPCR_SPENDN1 BIT(6)
+/* bits within the USBPCR register */
+#define USBPCR_SIDDQ BIT(21)
+#define USBPCR_OTG_DISABLE BIT(20)
+
static struct ingenic_cgu *cgu;
+static int x1000_usb_phy_enable(struct clk_hw *hw)
+{
+ void __iomem *reg_opcr = cgu->base + CGU_REG_OPCR;
+ void __iomem *reg_usbpcr = cgu->base + CGU_REG_USBPCR;
+
+ writel(readl(reg_opcr) | OPCR_SPENDN0, reg_opcr);
+ writel(readl(reg_usbpcr) & ~USBPCR_OTG_DISABLE & ~USBPCR_SIDDQ, reg_usbpcr);
+ return 0;
+}
+
+static void x1000_usb_phy_disable(struct clk_hw *hw)
+{
+ void __iomem *reg_opcr = cgu->base + CGU_REG_OPCR;
+ void __iomem *reg_usbpcr = cgu->base + CGU_REG_USBPCR;
+
+ writel(readl(reg_opcr) & ~OPCR_SPENDN0, reg_opcr);
+ writel(readl(reg_usbpcr) | USBPCR_OTG_DISABLE | USBPCR_SIDDQ, reg_usbpcr);
+}
+
+static int x1000_usb_phy_is_enabled(struct clk_hw *hw)
+{
+ void __iomem *reg_opcr = cgu->base + CGU_REG_OPCR;
+ void __iomem *reg_usbpcr = cgu->base + CGU_REG_USBPCR;
+
+ return (readl(reg_opcr) & OPCR_SPENDN0) &&
+ !(readl(reg_usbpcr) & USBPCR_SIDDQ) &&
+ !(readl(reg_usbpcr) & USBPCR_OTG_DISABLE);
+}
+
+static const struct clk_ops x1000_otg_phy_ops = {
+ .enable = x1000_usb_phy_enable,
+ .disable = x1000_usb_phy_disable,
+ .is_enabled = x1000_usb_phy_is_enabled,
+};
+
static const s8 pll_od_encoding[8] = {
0x0, 0x1, -1, 0x2, -1, -1, -1, 0x3,
};
@@ -101,6 +143,15 @@ static const struct ingenic_cgu_clk_info x1000_cgu_clocks[] = {
},
},
+
+ /* Custom (SoC-specific) OTG PHY */
+
+ [X1000_CLK_OTGPHY] = {
+ "otg_phy", CGU_CLK_CUSTOM,
+ .parents = { -1, -1, X1000_CLK_EXCLK, -1 },
+ .custom = { &x1000_otg_phy_ops },
+ },
+
/* Muxes & dividers */
[X1000_CLK_SCLKA] = {
@@ -116,9 +167,10 @@ static const struct ingenic_cgu_clk_info x1000_cgu_clocks[] = {
},
[X1000_CLK_CPU] = {
- "cpu", CGU_CLK_DIV,
+ "cpu", CGU_CLK_DIV | CGU_CLK_GATE,
.parents = { X1000_CLK_CPUMUX, -1, -1, -1 },
.div = { CGU_REG_CPCCR, 0, 1, 4, 22, -1, -1 },
+ .gate = { CGU_REG_CLKGR, 30 },
},
[X1000_CLK_L2CACHE] = {
@@ -147,9 +199,10 @@ static const struct ingenic_cgu_clk_info x1000_cgu_clocks[] = {
},
[X1000_CLK_PCLK] = {
- "pclk", CGU_CLK_DIV,
+ "pclk", CGU_CLK_DIV | CGU_CLK_GATE,
.parents = { X1000_CLK_AHB2PMUX, -1, -1, -1 },
.div = { CGU_REG_CPCCR, 16, 1, 4, 20, -1, -1 },
+ .gate = { CGU_REG_CLKGR, 28 },
},
[X1000_CLK_DDR] = {
@@ -162,12 +215,20 @@ static const struct ingenic_cgu_clk_info x1000_cgu_clocks[] = {
[X1000_CLK_MAC] = {
"mac", CGU_CLK_MUX | CGU_CLK_DIV | CGU_CLK_GATE,
- .parents = { X1000_CLK_SCLKA, X1000_CLK_MPLL},
+ .parents = { X1000_CLK_SCLKA, X1000_CLK_MPLL },
.mux = { CGU_REG_MACCDR, 31, 1 },
.div = { CGU_REG_MACCDR, 0, 1, 8, 29, 28, 27 },
.gate = { CGU_REG_CLKGR, 25 },
},
+ [X1000_CLK_LCD] = {
+ "lcd", CGU_CLK_MUX | CGU_CLK_DIV | CGU_CLK_GATE,
+ .parents = { X1000_CLK_SCLKA, X1000_CLK_MPLL },
+ .mux = { CGU_REG_LPCDR, 31, 1 },
+ .div = { CGU_REG_LPCDR, 0, 1, 8, 28, 27, 26 },
+ .gate = { CGU_REG_CLKGR, 23 },
+ },
+
[X1000_CLK_MSCMUX] = {
"msc_mux", CGU_CLK_MUX,
.parents = { X1000_CLK_SCLKA, X1000_CLK_MPLL},
@@ -188,6 +249,15 @@ static const struct ingenic_cgu_clk_info x1000_cgu_clocks[] = {
.gate = { CGU_REG_CLKGR, 5 },
},
+ [X1000_CLK_OTG] = {
+ "otg", CGU_CLK_DIV | CGU_CLK_GATE | CGU_CLK_MUX,
+ .parents = { X1000_CLK_EXCLK, -1,
+ X1000_CLK_APLL, X1000_CLK_MPLL },
+ .mux = { CGU_REG_USBCDR, 30, 2 },
+ .div = { CGU_REG_USBCDR, 0, 1, 8, 29, 28, 27 },
+ .gate = { CGU_REG_CLKGR, 3 },
+ },
+
[X1000_CLK_SSIPLL] = {
"ssi_pll", CGU_CLK_MUX | CGU_CLK_DIV,
.parents = { X1000_CLK_SCLKA, X1000_CLK_MPLL, -1, -1 },
@@ -195,14 +265,32 @@ static const struct ingenic_cgu_clk_info x1000_cgu_clocks[] = {
.div = { CGU_REG_SSICDR, 0, 1, 8, 29, 28, 27 },
},
+ [X1000_CLK_SSIPLL_DIV2] = {
+ "ssi_pll_div2", CGU_CLK_FIXDIV,
+ .parents = { X1000_CLK_SSIPLL },
+ .fixdiv = { 2 },
+ },
+
[X1000_CLK_SSIMUX] = {
"ssi_mux", CGU_CLK_MUX,
- .parents = { X1000_CLK_EXCLK, X1000_CLK_SSIPLL, -1, -1 },
+ .parents = { X1000_CLK_EXCLK, X1000_CLK_SSIPLL_DIV2, -1, -1 },
.mux = { CGU_REG_SSICDR, 30, 1 },
},
/* Gate-only clocks */
+ [X1000_CLK_EMC] = {
+ "emc", CGU_CLK_GATE,
+ .parents = { X1000_CLK_AHB2, -1, -1, -1 },
+ .gate = { CGU_REG_CLKGR, 0 },
+ },
+
+ [X1000_CLK_EFUSE] = {
+ "efuse", CGU_CLK_GATE,
+ .parents = { X1000_CLK_AHB2, -1, -1, -1 },
+ .gate = { CGU_REG_CLKGR, 1 },
+ },
+
[X1000_CLK_SFC] = {
"sfc", CGU_CLK_GATE,
.parents = { X1000_CLK_SSIPLL, -1, -1, -1 },
@@ -245,12 +333,24 @@ static const struct ingenic_cgu_clk_info x1000_cgu_clocks[] = {
.gate = { CGU_REG_CLKGR, 16 },
},
+ [X1000_CLK_TCU] = {
+ "tcu", CGU_CLK_GATE,
+ .parents = { X1000_CLK_EXCLK, -1, -1, -1 },
+ .gate = { CGU_REG_CLKGR, 18 },
+ },
+
[X1000_CLK_SSI] = {
"ssi", CGU_CLK_GATE,
.parents = { X1000_CLK_SSIMUX, -1, -1, -1 },
.gate = { CGU_REG_CLKGR, 19 },
},
+ [X1000_CLK_OST] = {
+ "ost", CGU_CLK_GATE,
+ .parents = { X1000_CLK_EXCLK, -1, -1, -1 },
+ .gate = { CGU_REG_CLKGR, 20 },
+ },
+
[X1000_CLK_PDMA] = {
"pdma", CGU_CLK_GATE,
.parents = { X1000_CLK_EXCLK, -1, -1, -1 },
--
2.11.0
^ permalink raw reply related
* [PATCH RESEND v11 6/7] dt-bindings: clock: Add and reorder ABI for X1000.
From: 周琰杰 (Zhou Yanjie) @ 2020-05-27 9:04 UTC (permalink / raw)
To: linux-clk
Cc: linux-kernel, devicetree, sboyd, mturquette, robh+dt,
dongsheng.qiu, aric.pzqi, rick.tyliu, yanfei.li, sernia.zhou,
zhenwenjin, paul
In-Reply-To: <20200527090419.56213-1-zhouyanjie@wanyeetech.com>
1.The SSI clock of X1000 not like JZ4770 and JZ4780, they are not
directly derived from the output of SSIPLL, but from the clock
obtained by dividing the frequency by 2. "X1000_CLK_SSIPLL_DIV2"
is added for this purpose, it must between "X1000_CLK_SSIPLL"
and "X1000_CLK_SSIMUX", otherwise an error will occurs when
initializing the clock. These ABIs are only used for X1000, and
I'm sure that no other devicetree out there is using these ABIs,
so we should be able to reorder them.
2.Clocks of LCD, OTG, EMC, EFUSE, OST, TCU are also added.
Signed-off-by: 周琰杰 (Zhou Yanjie) <zhouyanjie@wanyeetech.com>
Acked-by: Rob Herring <robh@kernel.org>
---
Notes:
v5:
New patch.
v5->v6:
Add missing part of X1000's CGU.
v6->v7:
No change.
v7->v8:
No change.
v8->v9:
No change.
v9->v10:
No change.
v10->v11:
No change.
include/dt-bindings/clock/x1000-cgu.h | 64 ++++++++++++++++++++---------------
1 file changed, 36 insertions(+), 28 deletions(-)
diff --git a/include/dt-bindings/clock/x1000-cgu.h b/include/dt-bindings/clock/x1000-cgu.h
index bbaebaf7adb9..0367c8c02e16 100644
--- a/include/dt-bindings/clock/x1000-cgu.h
+++ b/include/dt-bindings/clock/x1000-cgu.h
@@ -12,33 +12,41 @@
#ifndef __DT_BINDINGS_CLOCK_X1000_CGU_H__
#define __DT_BINDINGS_CLOCK_X1000_CGU_H__
-#define X1000_CLK_EXCLK 0
-#define X1000_CLK_RTCLK 1
-#define X1000_CLK_APLL 2
-#define X1000_CLK_MPLL 3
-#define X1000_CLK_SCLKA 4
-#define X1000_CLK_CPUMUX 5
-#define X1000_CLK_CPU 6
-#define X1000_CLK_L2CACHE 7
-#define X1000_CLK_AHB0 8
-#define X1000_CLK_AHB2PMUX 9
-#define X1000_CLK_AHB2 10
-#define X1000_CLK_PCLK 11
-#define X1000_CLK_DDR 12
-#define X1000_CLK_MAC 13
-#define X1000_CLK_MSCMUX 14
-#define X1000_CLK_MSC0 15
-#define X1000_CLK_MSC1 16
-#define X1000_CLK_SSIPLL 17
-#define X1000_CLK_SSIMUX 18
-#define X1000_CLK_SFC 19
-#define X1000_CLK_I2C0 20
-#define X1000_CLK_I2C1 21
-#define X1000_CLK_I2C2 22
-#define X1000_CLK_UART0 23
-#define X1000_CLK_UART1 24
-#define X1000_CLK_UART2 25
-#define X1000_CLK_SSI 26
-#define X1000_CLK_PDMA 27
+#define X1000_CLK_EXCLK 0
+#define X1000_CLK_RTCLK 1
+#define X1000_CLK_APLL 2
+#define X1000_CLK_MPLL 3
+#define X1000_CLK_OTGPHY 4
+#define X1000_CLK_SCLKA 5
+#define X1000_CLK_CPUMUX 6
+#define X1000_CLK_CPU 7
+#define X1000_CLK_L2CACHE 8
+#define X1000_CLK_AHB0 9
+#define X1000_CLK_AHB2PMUX 10
+#define X1000_CLK_AHB2 11
+#define X1000_CLK_PCLK 12
+#define X1000_CLK_DDR 13
+#define X1000_CLK_MAC 14
+#define X1000_CLK_LCD 15
+#define X1000_CLK_MSCMUX 16
+#define X1000_CLK_MSC0 17
+#define X1000_CLK_MSC1 18
+#define X1000_CLK_OTG 19
+#define X1000_CLK_SSIPLL 20
+#define X1000_CLK_SSIPLL_DIV2 21
+#define X1000_CLK_SSIMUX 22
+#define X1000_CLK_EMC 23
+#define X1000_CLK_EFUSE 24
+#define X1000_CLK_SFC 25
+#define X1000_CLK_I2C0 26
+#define X1000_CLK_I2C1 27
+#define X1000_CLK_I2C2 28
+#define X1000_CLK_UART0 29
+#define X1000_CLK_UART1 30
+#define X1000_CLK_UART2 31
+#define X1000_CLK_TCU 32
+#define X1000_CLK_SSI 33
+#define X1000_CLK_OST 34
+#define X1000_CLK_PDMA 35
#endif /* __DT_BINDINGS_CLOCK_X1000_CGU_H__ */
--
2.11.0
^ permalink raw reply related
* [PATCH RESEND v11 0/7] Add support for the X1830 and fix bugs for X1000.
From: 周琰杰 (Zhou Yanjie) @ 2020-05-27 9:04 UTC (permalink / raw)
To: linux-clk
Cc: linux-kernel, devicetree, sboyd, mturquette, robh+dt,
dongsheng.qiu, aric.pzqi, rick.tyliu, yanfei.li, sernia.zhou,
zhenwenjin, paul
v10->v11:
Split [3/6] in v10 to [3/7] in v11 and [4/7] in v11.
周琰杰 (Zhou Yanjie) (7):
clk: Ingenic: Remove unnecessary spinlock when reading registers.
clk: Ingenic: Adjust cgu code to make it compatible with X1830.
dt-bindings: clock: Add documentation for X1830 bindings.
dt-bindings: clock: Add X1830 clock bindings.
clk: Ingenic: Add CGU driver for X1830.
dt-bindings: clock: Add and reorder ABI for X1000.
clk: X1000: Add FIXDIV for SSI clock of X1000.
.../devicetree/bindings/clock/ingenic,cgu.yaml | 2 +
drivers/clk/ingenic/Kconfig | 10 +
drivers/clk/ingenic/Makefile | 1 +
drivers/clk/ingenic/cgu.c | 28 +-
drivers/clk/ingenic/cgu.h | 4 +
drivers/clk/ingenic/jz4725b-cgu.c | 4 +
drivers/clk/ingenic/jz4740-cgu.c | 4 +
drivers/clk/ingenic/jz4770-cgu.c | 8 +-
drivers/clk/ingenic/jz4780-cgu.c | 3 +
drivers/clk/ingenic/x1000-cgu.c | 116 +++++-
drivers/clk/ingenic/x1830-cgu.c | 443 +++++++++++++++++++++
include/dt-bindings/clock/x1000-cgu.h | 64 +--
include/dt-bindings/clock/x1830-cgu.h | 55 +++
13 files changed, 694 insertions(+), 48 deletions(-)
create mode 100644 drivers/clk/ingenic/x1830-cgu.c
create mode 100644 include/dt-bindings/clock/x1830-cgu.h
--
2.11.0
^ permalink raw reply
* Re: [V6, 2/2] media: i2c: dw9768: Add DW9768 VCM driver
From: Dongchun Zhu @ 2020-05-27 9:01 UTC (permalink / raw)
To: Tomasz Figa
Cc: Linus Walleij, Bartosz Golaszewski, Mauro Carvalho Chehab,
Andy Shevchenko, Rob Herring, Mark Rutland, Sakari Ailus,
Nicolas Boichat, Matthias Brugger, Cao Bing Bu, srv_heupstream,
moderated list:ARM/Mediatek SoC support,
list@263.net:IOMMU DRIVERS <iommu@lists.linux-foundation.org>, Joerg Roedel <joro@8bytes.org>,,
Sj Huang, Linux Media Mailing List, linux-devicetree, Louis Kuo,
Shengnan Wang (王圣男), dongchun.zhu
In-Reply-To: <CAAFQd5CCsT_oM9aij_imV+NABzByi94RmCj97Dx0Tk3S0WDsTg@mail.gmail.com>
Hi Tomasz,
On Mon, 2020-05-25 at 13:45 +0200, Tomasz Figa wrote:
> On Fri, May 22, 2020 at 11:27 AM Dongchun Zhu <dongchun.zhu@mediatek.com> wrote:
> >
> > Hi Tomasz,
> >
> > Thanks for the review. My replies are as below.
> >
> > On Thu, 2020-05-21 at 19:51 +0000, Tomasz Figa wrote:
> > > Hi Dongchun, Sakari,
> > >
> > > On Mon, May 18, 2020 at 09:27:31PM +0800, Dongchun Zhu wrote:
> [snip]
> > > > + pm_runtime_enable(dev);
> > > > + if (!pm_runtime_enabled(dev)) {
> > > > + ret = dw9768_runtime_resume(dev);
> > > > + if (ret < 0) {
> > > > + dev_err(dev, "failed to power on: %d\n", ret);
> > > > + goto entity_cleanup;
> > > > + }
> > > > + }
> > > > +
> > > > + ret = v4l2_async_register_subdev(&dw9768->sd);
> > > > + if (ret < 0)
> > > > + goto entity_cleanup;
> > > > +
> > > > + return 0;
> > > > +
> > > > +entity_cleanup:
> > >
> > > Need to power off if the code above powered on.
> > >
> >
> > Thanks for the reminder.
> > If there is something wrong with runtime PM, actuator is to be powered
> > on via dw9768_runtime_resume() API.
> > When actuator sub-device is powered on completely and async registered
> > successfully, we shall power off it afterwards.
> >
>
> The code above calls dw9768_runtime_resume() if
> !pm_runtime_enabled(dev), but the clean-up code below the
> entity_cleanup label doesn't have the corresponding
> dw9768_runtime_suspend() call.
>
Did you mean the 'entity_cleanup' after v4l2_async_register_subdev()?
Actually I made some changes for OV02A V9, according to this comment.
Could you help review that change? Thanks.
> Best regards,
> Tomasz
^ permalink raw reply
* [PATCH v11 7/7] clk: X1000: Add FIXDIV for SSI clock of X1000.
From: 周琰杰 (Zhou Yanjie) @ 2020-05-27 8:54 UTC (permalink / raw)
To: linux-clk
Cc: linux-kernel, devicetree, sboyd, mturquette, robh+dt,
dongsheng.qiu, aric.pzqi, rick.tyliu, yanfei.li, sernia.zhou,
zhenwenjin, paul
In-Reply-To: <20200527085449.55573-1-zhouyanjie@wanyeetech.com>
1.The SSI clock of X1000 not like JZ4770 and JZ4780, they are not
directly derived from the output of SSIPLL, but from the clock
obtained by dividing the frequency by 2. "X1000_CLK_SSIPLL_DIV2"
is added for this purpose, and ensure that it initialized before
"X1000_CLK_SSIMUX" when initializing the clocks.
2.Clocks of LCD, OTG, EMC, EFUSE, OST, TCU, and gates of CPU, PCLK
are also added.
3.Use "CLK_OF_DECLARE_DRIVER" like the other CGU drivers.
Signed-off-by: 周琰杰 (Zhou Yanjie) <zhouyanjie@wanyeetech.com>
Reviewed-by: Paul Cercueil <paul@crapouillou.net>
---
Notes:
v5:
New patch.
V5->v6:
Add missing part of X1000's CGU.
v6->v7:
Update commit message.
v7->v8:
No change.
v8->v9:
Add Paul Cercueil's Reviewed-by, somehow his emails are not displayed
on the mailing list and patchwork of clock framework subsystem.
v9->v10:
No change.
v10->v11:
No change.
drivers/clk/ingenic/x1000-cgu.c | 110 ++++++++++++++++++++++++++++++++++++++--
1 file changed, 105 insertions(+), 5 deletions(-)
diff --git a/drivers/clk/ingenic/x1000-cgu.c b/drivers/clk/ingenic/x1000-cgu.c
index c33934d8ac14..68c6e62457e1 100644
--- a/drivers/clk/ingenic/x1000-cgu.c
+++ b/drivers/clk/ingenic/x1000-cgu.c
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: GPL-2.0
/*
* X1000 SoC CGU driver
- * Copyright (c) 2019 Zhou Yanjie <zhouyanjie@zoho.com>
+ * Copyright (c) 2019 周琰杰 (Zhou Yanjie) <zhouyanjie@wanyeetech.com>
*/
#include <linux/clk-provider.h>
@@ -20,6 +20,9 @@
#define CGU_REG_CLKGR 0x20
#define CGU_REG_OPCR 0x24
#define CGU_REG_DDRCDR 0x2c
+#define CGU_REG_USBPCR 0x3c
+#define CGU_REG_USBPCR1 0x48
+#define CGU_REG_USBCDR 0x50
#define CGU_REG_MACCDR 0x54
#define CGU_REG_I2SCDR 0x60
#define CGU_REG_LPCDR 0x64
@@ -40,8 +43,47 @@
#define OPCR_SPENDN0 BIT(7)
#define OPCR_SPENDN1 BIT(6)
+/* bits within the USBPCR register */
+#define USBPCR_SIDDQ BIT(21)
+#define USBPCR_OTG_DISABLE BIT(20)
+
static struct ingenic_cgu *cgu;
+static int x1000_usb_phy_enable(struct clk_hw *hw)
+{
+ void __iomem *reg_opcr = cgu->base + CGU_REG_OPCR;
+ void __iomem *reg_usbpcr = cgu->base + CGU_REG_USBPCR;
+
+ writel(readl(reg_opcr) | OPCR_SPENDN0, reg_opcr);
+ writel(readl(reg_usbpcr) & ~USBPCR_OTG_DISABLE & ~USBPCR_SIDDQ, reg_usbpcr);
+ return 0;
+}
+
+static void x1000_usb_phy_disable(struct clk_hw *hw)
+{
+ void __iomem *reg_opcr = cgu->base + CGU_REG_OPCR;
+ void __iomem *reg_usbpcr = cgu->base + CGU_REG_USBPCR;
+
+ writel(readl(reg_opcr) & ~OPCR_SPENDN0, reg_opcr);
+ writel(readl(reg_usbpcr) | USBPCR_OTG_DISABLE | USBPCR_SIDDQ, reg_usbpcr);
+}
+
+static int x1000_usb_phy_is_enabled(struct clk_hw *hw)
+{
+ void __iomem *reg_opcr = cgu->base + CGU_REG_OPCR;
+ void __iomem *reg_usbpcr = cgu->base + CGU_REG_USBPCR;
+
+ return (readl(reg_opcr) & OPCR_SPENDN0) &&
+ !(readl(reg_usbpcr) & USBPCR_SIDDQ) &&
+ !(readl(reg_usbpcr) & USBPCR_OTG_DISABLE);
+}
+
+static const struct clk_ops x1000_otg_phy_ops = {
+ .enable = x1000_usb_phy_enable,
+ .disable = x1000_usb_phy_disable,
+ .is_enabled = x1000_usb_phy_is_enabled,
+};
+
static const s8 pll_od_encoding[8] = {
0x0, 0x1, -1, 0x2, -1, -1, -1, 0x3,
};
@@ -101,6 +143,15 @@ static const struct ingenic_cgu_clk_info x1000_cgu_clocks[] = {
},
},
+
+ /* Custom (SoC-specific) OTG PHY */
+
+ [X1000_CLK_OTGPHY] = {
+ "otg_phy", CGU_CLK_CUSTOM,
+ .parents = { -1, -1, X1000_CLK_EXCLK, -1 },
+ .custom = { &x1000_otg_phy_ops },
+ },
+
/* Muxes & dividers */
[X1000_CLK_SCLKA] = {
@@ -116,9 +167,10 @@ static const struct ingenic_cgu_clk_info x1000_cgu_clocks[] = {
},
[X1000_CLK_CPU] = {
- "cpu", CGU_CLK_DIV,
+ "cpu", CGU_CLK_DIV | CGU_CLK_GATE,
.parents = { X1000_CLK_CPUMUX, -1, -1, -1 },
.div = { CGU_REG_CPCCR, 0, 1, 4, 22, -1, -1 },
+ .gate = { CGU_REG_CLKGR, 30 },
},
[X1000_CLK_L2CACHE] = {
@@ -147,9 +199,10 @@ static const struct ingenic_cgu_clk_info x1000_cgu_clocks[] = {
},
[X1000_CLK_PCLK] = {
- "pclk", CGU_CLK_DIV,
+ "pclk", CGU_CLK_DIV | CGU_CLK_GATE,
.parents = { X1000_CLK_AHB2PMUX, -1, -1, -1 },
.div = { CGU_REG_CPCCR, 16, 1, 4, 20, -1, -1 },
+ .gate = { CGU_REG_CLKGR, 28 },
},
[X1000_CLK_DDR] = {
@@ -162,12 +215,20 @@ static const struct ingenic_cgu_clk_info x1000_cgu_clocks[] = {
[X1000_CLK_MAC] = {
"mac", CGU_CLK_MUX | CGU_CLK_DIV | CGU_CLK_GATE,
- .parents = { X1000_CLK_SCLKA, X1000_CLK_MPLL},
+ .parents = { X1000_CLK_SCLKA, X1000_CLK_MPLL },
.mux = { CGU_REG_MACCDR, 31, 1 },
.div = { CGU_REG_MACCDR, 0, 1, 8, 29, 28, 27 },
.gate = { CGU_REG_CLKGR, 25 },
},
+ [X1000_CLK_LCD] = {
+ "lcd", CGU_CLK_MUX | CGU_CLK_DIV | CGU_CLK_GATE,
+ .parents = { X1000_CLK_SCLKA, X1000_CLK_MPLL },
+ .mux = { CGU_REG_LPCDR, 31, 1 },
+ .div = { CGU_REG_LPCDR, 0, 1, 8, 28, 27, 26 },
+ .gate = { CGU_REG_CLKGR, 23 },
+ },
+
[X1000_CLK_MSCMUX] = {
"msc_mux", CGU_CLK_MUX,
.parents = { X1000_CLK_SCLKA, X1000_CLK_MPLL},
@@ -188,6 +249,15 @@ static const struct ingenic_cgu_clk_info x1000_cgu_clocks[] = {
.gate = { CGU_REG_CLKGR, 5 },
},
+ [X1000_CLK_OTG] = {
+ "otg", CGU_CLK_DIV | CGU_CLK_GATE | CGU_CLK_MUX,
+ .parents = { X1000_CLK_EXCLK, -1,
+ X1000_CLK_APLL, X1000_CLK_MPLL },
+ .mux = { CGU_REG_USBCDR, 30, 2 },
+ .div = { CGU_REG_USBCDR, 0, 1, 8, 29, 28, 27 },
+ .gate = { CGU_REG_CLKGR, 3 },
+ },
+
[X1000_CLK_SSIPLL] = {
"ssi_pll", CGU_CLK_MUX | CGU_CLK_DIV,
.parents = { X1000_CLK_SCLKA, X1000_CLK_MPLL, -1, -1 },
@@ -195,14 +265,32 @@ static const struct ingenic_cgu_clk_info x1000_cgu_clocks[] = {
.div = { CGU_REG_SSICDR, 0, 1, 8, 29, 28, 27 },
},
+ [X1000_CLK_SSIPLL_DIV2] = {
+ "ssi_pll_div2", CGU_CLK_FIXDIV,
+ .parents = { X1000_CLK_SSIPLL },
+ .fixdiv = { 2 },
+ },
+
[X1000_CLK_SSIMUX] = {
"ssi_mux", CGU_CLK_MUX,
- .parents = { X1000_CLK_EXCLK, X1000_CLK_SSIPLL, -1, -1 },
+ .parents = { X1000_CLK_EXCLK, X1000_CLK_SSIPLL_DIV2, -1, -1 },
.mux = { CGU_REG_SSICDR, 30, 1 },
},
/* Gate-only clocks */
+ [X1000_CLK_EMC] = {
+ "emc", CGU_CLK_GATE,
+ .parents = { X1000_CLK_AHB2, -1, -1, -1 },
+ .gate = { CGU_REG_CLKGR, 0 },
+ },
+
+ [X1000_CLK_EFUSE] = {
+ "efuse", CGU_CLK_GATE,
+ .parents = { X1000_CLK_AHB2, -1, -1, -1 },
+ .gate = { CGU_REG_CLKGR, 1 },
+ },
+
[X1000_CLK_SFC] = {
"sfc", CGU_CLK_GATE,
.parents = { X1000_CLK_SSIPLL, -1, -1, -1 },
@@ -245,12 +333,24 @@ static const struct ingenic_cgu_clk_info x1000_cgu_clocks[] = {
.gate = { CGU_REG_CLKGR, 16 },
},
+ [X1000_CLK_TCU] = {
+ "tcu", CGU_CLK_GATE,
+ .parents = { X1000_CLK_EXCLK, -1, -1, -1 },
+ .gate = { CGU_REG_CLKGR, 18 },
+ },
+
[X1000_CLK_SSI] = {
"ssi", CGU_CLK_GATE,
.parents = { X1000_CLK_SSIMUX, -1, -1, -1 },
.gate = { CGU_REG_CLKGR, 19 },
},
+ [X1000_CLK_OST] = {
+ "ost", CGU_CLK_GATE,
+ .parents = { X1000_CLK_EXCLK, -1, -1, -1 },
+ .gate = { CGU_REG_CLKGR, 20 },
+ },
+
[X1000_CLK_PDMA] = {
"pdma", CGU_CLK_GATE,
.parents = { X1000_CLK_EXCLK, -1, -1, -1 },
--
2.11.0
^ permalink raw reply related
* [PATCH v11 0/7] Add support for the X1830 and fix bugs for X1000.
From: 周琰杰 (Zhou Yanjie) @ 2020-05-27 8:54 UTC (permalink / raw)
To: linux-clk
Cc: linux-kernel, devicetree, sboyd, mturquette, robh+dt,
dongsheng.qiu, aric.pzqi, rick.tyliu, yanfei.li, sernia.zhou,
zhenwenjin, paul
v10->v11:
Split [3/6] in v10 to [3/7] in v11 and [4/7] in v11.
周琰杰 (Zhou Yanjie) (7):
clk: Ingenic: Remove unnecessary spinlock when reading registers.
clk: Ingenic: Adjust cgu code to make it compatible with X1830.
dt-bindings: clock: Add documentation for X1830 bindings.
dt-bindings: clock: Add X1830 clock bindings.
clk: Ingenic: Add CGU driver for X1830.
dt-bindings: clock: Add and reorder ABI for X1000.
clk: X1000: Add FIXDIV for SSI clock of X1000.
.../devicetree/bindings/clock/ingenic,cgu.yaml | 2 +
drivers/clk/ingenic/Kconfig | 10 +
drivers/clk/ingenic/Makefile | 1 +
drivers/clk/ingenic/cgu.c | 28 +-
drivers/clk/ingenic/cgu.h | 4 +
drivers/clk/ingenic/jz4725b-cgu.c | 4 +
drivers/clk/ingenic/jz4740-cgu.c | 4 +
drivers/clk/ingenic/jz4770-cgu.c | 8 +-
drivers/clk/ingenic/jz4780-cgu.c | 3 +
drivers/clk/ingenic/x1000-cgu.c | 116 +++++-
drivers/clk/ingenic/x1830-cgu.c | 443 +++++++++++++++++++++
include/dt-bindings/clock/x1000-cgu.h | 64 +--
include/dt-bindings/clock/x1830-cgu.h | 55 +++
13 files changed, 694 insertions(+), 48 deletions(-)
create mode 100644 drivers/clk/ingenic/x1830-cgu.c
create mode 100644 include/dt-bindings/clock/x1830-cgu.h
--
2.11.0
^ permalink raw reply
* [PATCH v11 3/7] dt-bindings: clock: Add documentation for X1830 bindings.
From: 周琰杰 (Zhou Yanjie) @ 2020-05-27 8:54 UTC (permalink / raw)
To: linux-clk
Cc: linux-kernel, devicetree, sboyd, mturquette, robh+dt,
dongsheng.qiu, aric.pzqi, rick.tyliu, yanfei.li, sernia.zhou,
zhenwenjin, paul
In-Reply-To: <20200527085449.55573-1-zhouyanjie@wanyeetech.com>
Add documentation for the clock bindings of the X1830 Soc from Ingenic.
Signed-off-by: 周琰杰 (Zhou Yanjie) <zhouyanjie@wanyeetech.com>
---
Notes:
v11:
New patch, split from [3/6] in v10.
Documentation/devicetree/bindings/clock/ingenic,cgu.yaml | 2 ++
1 file changed, 2 insertions(+)
diff --git a/Documentation/devicetree/bindings/clock/ingenic,cgu.yaml b/Documentation/devicetree/bindings/clock/ingenic,cgu.yaml
index 0281cd1d7e1b..a952d5811823 100644
--- a/Documentation/devicetree/bindings/clock/ingenic,cgu.yaml
+++ b/Documentation/devicetree/bindings/clock/ingenic,cgu.yaml
@@ -25,6 +25,7 @@ select:
- ingenic,jz4770-cgu
- ingenic,jz4780-cgu
- ingenic,x1000-cgu
+ - ingenic,x1830-cgu
required:
- compatible
@@ -51,6 +52,7 @@ properties:
- ingenic,jz4770-cgu
- ingenic,jz4780-cgu
- ingenic,x1000-cgu
+ - ingenic,x1830-cgu
- const: simple-mfd
minItems: 1
--
2.11.0
^ permalink raw reply related
* [PATCH v11 2/7] clk: Ingenic: Adjust cgu code to make it compatible with X1830.
From: 周琰杰 (Zhou Yanjie) @ 2020-05-27 8:54 UTC (permalink / raw)
To: linux-clk
Cc: linux-kernel, devicetree, sboyd, mturquette, robh+dt,
dongsheng.qiu, aric.pzqi, rick.tyliu, yanfei.li, sernia.zhou,
zhenwenjin, paul
In-Reply-To: <20200527085449.55573-1-zhouyanjie@wanyeetech.com>
The PLL of X1830 Soc from Ingenic has been greatly changed,
the bypass control is placed in another register, so now two
registers may needed to control the PLL. To this end, a new
"bypass_reg" was introduced. In addition, when calculating
rate, the PLL of X1830 introduced an extra 2x multiplier,
so a new "rate_multiplier" was introduced. And adjust the
code in jz47xx-cgu.c and x1000-cgu.c, make it to be
compatible with the new cgu code.
Signed-off-by: 周琰杰 (Zhou Yanjie) <zhouyanjie@wanyeetech.com>
Reviewed-by: Paul Cercueil <paul@crapouillou.net>
---
Notes:
v2->v3:
Adjust order from [1/5] in v2 to [2/5] in v3.
v3->v4:
Merge [3/5] in v3 into this patch.
v4->v5:
Rebase on top of kernel 5.6-rc1.
v5->v6:
Revert "pll_reg" to "reg" to minimize patch as Paul Cercueil's suggest.
v6->v7:
Update commit message.
v7->v8:
No change.
v8->v9:
No change.
v9->v10:
No change.
v10->v11:
No change.
drivers/clk/ingenic/cgu.c | 16 +++++++++++++---
drivers/clk/ingenic/cgu.h | 4 ++++
drivers/clk/ingenic/jz4725b-cgu.c | 4 ++++
drivers/clk/ingenic/jz4740-cgu.c | 4 ++++
drivers/clk/ingenic/jz4770-cgu.c | 8 +++++++-
drivers/clk/ingenic/jz4780-cgu.c | 3 +++
drivers/clk/ingenic/x1000-cgu.c | 6 ++++++
7 files changed, 41 insertions(+), 4 deletions(-)
diff --git a/drivers/clk/ingenic/cgu.c b/drivers/clk/ingenic/cgu.c
index ab1302ad1450..d7981b670221 100644
--- a/drivers/clk/ingenic/cgu.c
+++ b/drivers/clk/ingenic/cgu.c
@@ -90,6 +90,9 @@ ingenic_pll_recalc_rate(struct clk_hw *hw, unsigned long parent_rate)
n += pll_info->n_offset;
od_enc = ctl >> pll_info->od_shift;
od_enc &= GENMASK(pll_info->od_bits - 1, 0);
+
+ ctl = readl(cgu->base + pll_info->bypass_reg);
+
bypass = !pll_info->no_bypass_bit &&
!!(ctl & BIT(pll_info->bypass_bit));
@@ -103,7 +106,8 @@ ingenic_pll_recalc_rate(struct clk_hw *hw, unsigned long parent_rate)
BUG_ON(od == pll_info->od_max);
od++;
- return div_u64((u64)parent_rate * m, n * od);
+ return div_u64((u64)parent_rate * m * pll_info->rate_multiplier,
+ n * od);
}
static unsigned long
@@ -136,7 +140,8 @@ ingenic_pll_calc(const struct ingenic_cgu_clk_info *clk_info,
if (pod)
*pod = od;
- return div_u64((u64)parent_rate * m, n * od);
+ return div_u64((u64)parent_rate * m * pll_info->rate_multiplier,
+ n * od);
}
static inline const struct ingenic_cgu_clk_info *to_clk_info(
@@ -209,9 +214,14 @@ static int ingenic_pll_enable(struct clk_hw *hw)
u32 ctl;
spin_lock_irqsave(&cgu->lock, flags);
- ctl = readl(cgu->base + pll_info->reg);
+ ctl = readl(cgu->base + pll_info->bypass_reg);
ctl &= ~BIT(pll_info->bypass_bit);
+
+ writel(ctl, cgu->base + pll_info->bypass_reg);
+
+ ctl = readl(cgu->base + pll_info->reg);
+
ctl |= BIT(pll_info->enable_bit);
writel(ctl, cgu->base + pll_info->reg);
diff --git a/drivers/clk/ingenic/cgu.h b/drivers/clk/ingenic/cgu.h
index 0dc8004079ee..2c75ef4a36f5 100644
--- a/drivers/clk/ingenic/cgu.h
+++ b/drivers/clk/ingenic/cgu.h
@@ -17,6 +17,7 @@
/**
* struct ingenic_cgu_pll_info - information about a PLL
* @reg: the offset of the PLL's control register within the CGU
+ * @rate_multiplier: the multiplier needed by pll rate calculation
* @m_shift: the number of bits to shift the multiplier value by (ie. the
* index of the lowest bit of the multiplier value in the PLL's
* control register)
@@ -37,6 +38,7 @@
* @od_encoding: a pointer to an array mapping post-VCO divider values to
* their encoded values in the PLL control register, or -1 for
* unsupported values
+ * @bypass_reg: the offset of the bypass control register within the CGU
* @bypass_bit: the index of the bypass bit in the PLL control register
* @enable_bit: the index of the enable bit in the PLL control register
* @stable_bit: the index of the stable bit in the PLL control register
@@ -44,10 +46,12 @@
*/
struct ingenic_cgu_pll_info {
unsigned reg;
+ unsigned rate_multiplier;
const s8 *od_encoding;
u8 m_shift, m_bits, m_offset;
u8 n_shift, n_bits, n_offset;
u8 od_shift, od_bits, od_max;
+ unsigned bypass_reg;
u8 bypass_bit;
u8 enable_bit;
u8 stable_bit;
diff --git a/drivers/clk/ingenic/jz4725b-cgu.c b/drivers/clk/ingenic/jz4725b-cgu.c
index a3b4635f6278..8c38e72d14a7 100644
--- a/drivers/clk/ingenic/jz4725b-cgu.c
+++ b/drivers/clk/ingenic/jz4725b-cgu.c
@@ -9,7 +9,9 @@
#include <linux/clk-provider.h>
#include <linux/delay.h>
#include <linux/of.h>
+
#include <dt-bindings/clock/jz4725b-cgu.h>
+
#include "cgu.h"
#include "pm.h"
@@ -54,6 +56,7 @@ static const struct ingenic_cgu_clk_info jz4725b_cgu_clocks[] = {
.parents = { JZ4725B_CLK_EXT, -1, -1, -1 },
.pll = {
.reg = CGU_REG_CPPCR,
+ .rate_multiplier = 1,
.m_shift = 23,
.m_bits = 9,
.m_offset = 2,
@@ -65,6 +68,7 @@ static const struct ingenic_cgu_clk_info jz4725b_cgu_clocks[] = {
.od_max = 4,
.od_encoding = pll_od_encoding,
.stable_bit = 10,
+ .bypass_reg = CGU_REG_CPPCR,
.bypass_bit = 9,
.enable_bit = 8,
},
diff --git a/drivers/clk/ingenic/jz4740-cgu.c b/drivers/clk/ingenic/jz4740-cgu.c
index 4f0e92c877d6..c0ac9196a581 100644
--- a/drivers/clk/ingenic/jz4740-cgu.c
+++ b/drivers/clk/ingenic/jz4740-cgu.c
@@ -10,7 +10,9 @@
#include <linux/delay.h>
#include <linux/io.h>
#include <linux/of.h>
+
#include <dt-bindings/clock/jz4740-cgu.h>
+
#include "cgu.h"
#include "pm.h"
@@ -69,6 +71,7 @@ static const struct ingenic_cgu_clk_info jz4740_cgu_clocks[] = {
.parents = { JZ4740_CLK_EXT, -1, -1, -1 },
.pll = {
.reg = CGU_REG_CPPCR,
+ .rate_multiplier = 1,
.m_shift = 23,
.m_bits = 9,
.m_offset = 2,
@@ -80,6 +83,7 @@ static const struct ingenic_cgu_clk_info jz4740_cgu_clocks[] = {
.od_max = 4,
.od_encoding = pll_od_encoding,
.stable_bit = 10,
+ .bypass_reg = CGU_REG_CPPCR,
.bypass_bit = 9,
.enable_bit = 8,
},
diff --git a/drivers/clk/ingenic/jz4770-cgu.c b/drivers/clk/ingenic/jz4770-cgu.c
index c051ecba5cf8..9ea4490ecb7f 100644
--- a/drivers/clk/ingenic/jz4770-cgu.c
+++ b/drivers/clk/ingenic/jz4770-cgu.c
@@ -9,7 +9,9 @@
#include <linux/delay.h>
#include <linux/io.h>
#include <linux/of.h>
+
#include <dt-bindings/clock/jz4770-cgu.h>
+
#include "cgu.h"
#include "pm.h"
@@ -102,6 +104,7 @@ static const struct ingenic_cgu_clk_info jz4770_cgu_clocks[] = {
.parents = { JZ4770_CLK_EXT },
.pll = {
.reg = CGU_REG_CPPCR0,
+ .rate_multiplier = 1,
.m_shift = 24,
.m_bits = 7,
.m_offset = 1,
@@ -112,6 +115,7 @@ static const struct ingenic_cgu_clk_info jz4770_cgu_clocks[] = {
.od_bits = 2,
.od_max = 8,
.od_encoding = pll_od_encoding,
+ .bypass_reg = CGU_REG_CPPCR0,
.bypass_bit = 9,
.enable_bit = 8,
.stable_bit = 10,
@@ -124,6 +128,7 @@ static const struct ingenic_cgu_clk_info jz4770_cgu_clocks[] = {
.parents = { JZ4770_CLK_EXT },
.pll = {
.reg = CGU_REG_CPPCR1,
+ .rate_multiplier = 1,
.m_shift = 24,
.m_bits = 7,
.m_offset = 1,
@@ -134,9 +139,10 @@ static const struct ingenic_cgu_clk_info jz4770_cgu_clocks[] = {
.od_bits = 2,
.od_max = 8,
.od_encoding = pll_od_encoding,
+ .bypass_reg = CGU_REG_CPPCR1,
+ .no_bypass_bit = true,
.enable_bit = 7,
.stable_bit = 6,
- .no_bypass_bit = true,
},
},
diff --git a/drivers/clk/ingenic/jz4780-cgu.c b/drivers/clk/ingenic/jz4780-cgu.c
index c758f1643067..6c5b8029cc8a 100644
--- a/drivers/clk/ingenic/jz4780-cgu.c
+++ b/drivers/clk/ingenic/jz4780-cgu.c
@@ -13,6 +13,7 @@
#include <linux/of.h>
#include <dt-bindings/clock/jz4780-cgu.h>
+
#include "cgu.h"
#include "pm.h"
@@ -266,6 +267,7 @@ static const struct ingenic_cgu_clk_info jz4780_cgu_clocks[] = {
#define DEF_PLL(name) { \
.reg = CGU_REG_ ## name, \
+ .rate_multiplier = 1, \
.m_shift = 19, \
.m_bits = 13, \
.m_offset = 1, \
@@ -277,6 +279,7 @@ static const struct ingenic_cgu_clk_info jz4780_cgu_clocks[] = {
.od_max = 16, \
.od_encoding = pll_od_encoding, \
.stable_bit = 6, \
+ .bypass_reg = CGU_REG_ ## name, \
.bypass_bit = 1, \
.enable_bit = 0, \
}
diff --git a/drivers/clk/ingenic/x1000-cgu.c b/drivers/clk/ingenic/x1000-cgu.c
index b22d87b3f555..c33934d8ac14 100644
--- a/drivers/clk/ingenic/x1000-cgu.c
+++ b/drivers/clk/ingenic/x1000-cgu.c
@@ -7,7 +7,9 @@
#include <linux/clk-provider.h>
#include <linux/delay.h>
#include <linux/of.h>
+
#include <dt-bindings/clock/x1000-cgu.h>
+
#include "cgu.h"
#include "pm.h"
@@ -58,6 +60,7 @@ static const struct ingenic_cgu_clk_info x1000_cgu_clocks[] = {
.parents = { X1000_CLK_EXCLK, -1, -1, -1 },
.pll = {
.reg = CGU_REG_APLL,
+ .rate_multiplier = 1,
.m_shift = 24,
.m_bits = 7,
.m_offset = 1,
@@ -68,6 +71,7 @@ static const struct ingenic_cgu_clk_info x1000_cgu_clocks[] = {
.od_bits = 2,
.od_max = 8,
.od_encoding = pll_od_encoding,
+ .bypass_reg = CGU_REG_APLL,
.bypass_bit = 9,
.enable_bit = 8,
.stable_bit = 10,
@@ -79,6 +83,7 @@ static const struct ingenic_cgu_clk_info x1000_cgu_clocks[] = {
.parents = { X1000_CLK_EXCLK, -1, -1, -1 },
.pll = {
.reg = CGU_REG_MPLL,
+ .rate_multiplier = 1,
.m_shift = 24,
.m_bits = 7,
.m_offset = 1,
@@ -89,6 +94,7 @@ static const struct ingenic_cgu_clk_info x1000_cgu_clocks[] = {
.od_bits = 2,
.od_max = 8,
.od_encoding = pll_od_encoding,
+ .bypass_reg = CGU_REG_MPLL,
.bypass_bit = 6,
.enable_bit = 7,
.stable_bit = 0,
--
2.11.0
^ permalink raw reply related
* [PATCH v11 6/7] dt-bindings: clock: Add and reorder ABI for X1000.
From: 周琰杰 (Zhou Yanjie) @ 2020-05-27 8:54 UTC (permalink / raw)
To: linux-clk
Cc: linux-kernel, devicetree, sboyd, mturquette, robh+dt,
dongsheng.qiu, aric.pzqi, rick.tyliu, yanfei.li, sernia.zhou,
zhenwenjin, paul
In-Reply-To: <20200527085449.55573-1-zhouyanjie@wanyeetech.com>
1.The SSI clock of X1000 not like JZ4770 and JZ4780, they are not
directly derived from the output of SSIPLL, but from the clock
obtained by dividing the frequency by 2. "X1000_CLK_SSIPLL_DIV2"
is added for this purpose, it must between "X1000_CLK_SSIPLL"
and "X1000_CLK_SSIMUX", otherwise an error will occurs when
initializing the clock. These ABIs are only used for X1000, and
I'm sure that no other devicetree out there is using these ABIs,
so we should be able to reorder them.
2.Clocks of LCD, OTG, EMC, EFUSE, OST, TCU are also added.
Signed-off-by: 周琰杰 (Zhou Yanjie) <zhouyanjie@wanyeetech.com>
Acked-by: Rob Herring <robh@kernel.org>
---
Notes:
v5:
New patch.
v5->v6:
Add missing part of X1000's CGU.
v6->v7:
No change.
v7->v8:
No change.
v8->v9:
No change.
v9->v10:
No change.
v10->v11:
No change.
include/dt-bindings/clock/x1000-cgu.h | 64 ++++++++++++++++++++---------------
1 file changed, 36 insertions(+), 28 deletions(-)
diff --git a/include/dt-bindings/clock/x1000-cgu.h b/include/dt-bindings/clock/x1000-cgu.h
index bbaebaf7adb9..0367c8c02e16 100644
--- a/include/dt-bindings/clock/x1000-cgu.h
+++ b/include/dt-bindings/clock/x1000-cgu.h
@@ -12,33 +12,41 @@
#ifndef __DT_BINDINGS_CLOCK_X1000_CGU_H__
#define __DT_BINDINGS_CLOCK_X1000_CGU_H__
-#define X1000_CLK_EXCLK 0
-#define X1000_CLK_RTCLK 1
-#define X1000_CLK_APLL 2
-#define X1000_CLK_MPLL 3
-#define X1000_CLK_SCLKA 4
-#define X1000_CLK_CPUMUX 5
-#define X1000_CLK_CPU 6
-#define X1000_CLK_L2CACHE 7
-#define X1000_CLK_AHB0 8
-#define X1000_CLK_AHB2PMUX 9
-#define X1000_CLK_AHB2 10
-#define X1000_CLK_PCLK 11
-#define X1000_CLK_DDR 12
-#define X1000_CLK_MAC 13
-#define X1000_CLK_MSCMUX 14
-#define X1000_CLK_MSC0 15
-#define X1000_CLK_MSC1 16
-#define X1000_CLK_SSIPLL 17
-#define X1000_CLK_SSIMUX 18
-#define X1000_CLK_SFC 19
-#define X1000_CLK_I2C0 20
-#define X1000_CLK_I2C1 21
-#define X1000_CLK_I2C2 22
-#define X1000_CLK_UART0 23
-#define X1000_CLK_UART1 24
-#define X1000_CLK_UART2 25
-#define X1000_CLK_SSI 26
-#define X1000_CLK_PDMA 27
+#define X1000_CLK_EXCLK 0
+#define X1000_CLK_RTCLK 1
+#define X1000_CLK_APLL 2
+#define X1000_CLK_MPLL 3
+#define X1000_CLK_OTGPHY 4
+#define X1000_CLK_SCLKA 5
+#define X1000_CLK_CPUMUX 6
+#define X1000_CLK_CPU 7
+#define X1000_CLK_L2CACHE 8
+#define X1000_CLK_AHB0 9
+#define X1000_CLK_AHB2PMUX 10
+#define X1000_CLK_AHB2 11
+#define X1000_CLK_PCLK 12
+#define X1000_CLK_DDR 13
+#define X1000_CLK_MAC 14
+#define X1000_CLK_LCD 15
+#define X1000_CLK_MSCMUX 16
+#define X1000_CLK_MSC0 17
+#define X1000_CLK_MSC1 18
+#define X1000_CLK_OTG 19
+#define X1000_CLK_SSIPLL 20
+#define X1000_CLK_SSIPLL_DIV2 21
+#define X1000_CLK_SSIMUX 22
+#define X1000_CLK_EMC 23
+#define X1000_CLK_EFUSE 24
+#define X1000_CLK_SFC 25
+#define X1000_CLK_I2C0 26
+#define X1000_CLK_I2C1 27
+#define X1000_CLK_I2C2 28
+#define X1000_CLK_UART0 29
+#define X1000_CLK_UART1 30
+#define X1000_CLK_UART2 31
+#define X1000_CLK_TCU 32
+#define X1000_CLK_SSI 33
+#define X1000_CLK_OST 34
+#define X1000_CLK_PDMA 35
#endif /* __DT_BINDINGS_CLOCK_X1000_CGU_H__ */
--
2.11.0
^ permalink raw reply related
* [PATCH v11 4/7] dt-bindings: clock: Add X1830 clock bindings.
From: 周琰杰 (Zhou Yanjie) @ 2020-05-27 8:54 UTC (permalink / raw)
To: linux-clk
Cc: linux-kernel, devicetree, sboyd, mturquette, robh+dt,
dongsheng.qiu, aric.pzqi, rick.tyliu, yanfei.li, sernia.zhou,
zhenwenjin, paul
In-Reply-To: <20200527085449.55573-1-zhouyanjie@wanyeetech.com>
Add the clock bindings for the X1830 Soc from Ingenic.
Signed-off-by: 周琰杰 (Zhou Yanjie) <zhouyanjie@wanyeetech.com>
---
Notes:
v11:
New patch, split from [3/6] in v10.
include/dt-bindings/clock/x1830-cgu.h | 55 +++++++++++++++++++++++++++++++++++
1 file changed, 55 insertions(+)
create mode 100644 include/dt-bindings/clock/x1830-cgu.h
diff --git a/include/dt-bindings/clock/x1830-cgu.h b/include/dt-bindings/clock/x1830-cgu.h
new file mode 100644
index 000000000000..801e1d09c881
--- /dev/null
+++ b/include/dt-bindings/clock/x1830-cgu.h
@@ -0,0 +1,55 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * This header provides clock numbers for the ingenic,x1830-cgu DT binding.
+ *
+ * They are roughly ordered as:
+ * - external clocks
+ * - PLLs
+ * - muxes/dividers in the order they appear in the x1830 programmers manual
+ * - gates in order of their bit in the CLKGR* registers
+ */
+
+#ifndef __DT_BINDINGS_CLOCK_X1830_CGU_H__
+#define __DT_BINDINGS_CLOCK_X1830_CGU_H__
+
+#define X1830_CLK_EXCLK 0
+#define X1830_CLK_RTCLK 1
+#define X1830_CLK_APLL 2
+#define X1830_CLK_MPLL 3
+#define X1830_CLK_EPLL 4
+#define X1830_CLK_VPLL 5
+#define X1830_CLK_OTGPHY 6
+#define X1830_CLK_SCLKA 7
+#define X1830_CLK_CPUMUX 8
+#define X1830_CLK_CPU 9
+#define X1830_CLK_L2CACHE 10
+#define X1830_CLK_AHB0 11
+#define X1830_CLK_AHB2PMUX 12
+#define X1830_CLK_AHB2 13
+#define X1830_CLK_PCLK 14
+#define X1830_CLK_DDR 15
+#define X1830_CLK_MAC 16
+#define X1830_CLK_LCD 17
+#define X1830_CLK_MSCMUX 18
+#define X1830_CLK_MSC0 19
+#define X1830_CLK_MSC1 20
+#define X1830_CLK_SSIPLL 21
+#define X1830_CLK_SSIPLL_DIV2 22
+#define X1830_CLK_SSIMUX 23
+#define X1830_CLK_EMC 24
+#define X1830_CLK_EFUSE 25
+#define X1830_CLK_OTG 26
+#define X1830_CLK_SSI0 27
+#define X1830_CLK_SMB0 28
+#define X1830_CLK_SMB1 29
+#define X1830_CLK_SMB2 30
+#define X1830_CLK_UART0 31
+#define X1830_CLK_UART1 32
+#define X1830_CLK_SSI1 33
+#define X1830_CLK_SFC 34
+#define X1830_CLK_PDMA 35
+#define X1830_CLK_TCU 36
+#define X1830_CLK_DTRNG 37
+#define X1830_CLK_OST 38
+
+#endif /* __DT_BINDINGS_CLOCK_X1830_CGU_H__ */
--
2.11.0
^ permalink raw reply related
* [PATCH v11 5/7] clk: Ingenic: Add CGU driver for X1830.
From: 周琰杰 (Zhou Yanjie) @ 2020-05-27 8:54 UTC (permalink / raw)
To: linux-clk
Cc: linux-kernel, devicetree, sboyd, mturquette, robh+dt,
dongsheng.qiu, aric.pzqi, rick.tyliu, yanfei.li, sernia.zhou,
zhenwenjin, paul
In-Reply-To: <20200527085449.55573-1-zhouyanjie@wanyeetech.com>
Add support for the clocks provided by the CGU in the Ingenic X1830
SoC, making use of the cgu code to do the heavy lifting.
Signed-off-by: 周琰杰 (Zhou Yanjie) <zhouyanjie@wanyeetech.com>
Reviewed-by: Paul Cercueil <paul@crapouillou.net>
---
Notes:
v1->v2:
1.Use two fields (pll_reg & bypass_reg) instead of the 2-values
array (reg[2]).
2.Remove the "pll_info->version" and add a "pll_info->rate_multiplier".
3.Change my Signed-off-by from "Zhou Yanjie <zhouyanjie@zoho.com>"
to "周琰杰 (Zhou Yanjie) <zhouyanjie@wanyeetech.com>" because
the old mailbox is in an unstable state.
v2->v3:
Adjust order from [4/5] in v2 to [5/5] in v3.
v3->v4:
Adjust order from [5/5] in v3 to [4/4] in v4.
v4->v5:
Rebase on top of kernel 5.6-rc1.
v5->v6:
Add missing part of X1830's CGU.
v6->v7:
1.Adjust includes, add blank line as Paul Cercueil's suggest.
2.Move "*cgu" into x1830_cgu_init() as a local variable.
v7->v8:
No change.
v8->v9:
Add Paul Cercueil's Reviewed-by, somehow his emails are not displayed
on the mailing list and patchwork of clock framework subsystem.
v9->v10:
1.Add missing "X1830_CLK_TCU".
2.Fix bugs in "X1830_CLK_OTGPHY".
v10->v11:
No change.
drivers/clk/ingenic/Kconfig | 10 +
drivers/clk/ingenic/Makefile | 1 +
drivers/clk/ingenic/x1830-cgu.c | 443 ++++++++++++++++++++++++++++++++++++++++
3 files changed, 454 insertions(+)
create mode 100644 drivers/clk/ingenic/x1830-cgu.c
diff --git a/drivers/clk/ingenic/Kconfig b/drivers/clk/ingenic/Kconfig
index b4555b465ea6..580b0cf69ed5 100644
--- a/drivers/clk/ingenic/Kconfig
+++ b/drivers/clk/ingenic/Kconfig
@@ -55,6 +55,16 @@ config INGENIC_CGU_X1000
If building for a X1000 SoC, you want to say Y here.
+config INGENIC_CGU_X1830
+ bool "Ingenic X1830 CGU driver"
+ default MACH_X1830
+ select INGENIC_CGU_COMMON
+ help
+ Support the clocks provided by the CGU hardware on Ingenic X1830
+ and compatible SoCs.
+
+ If building for a X1830 SoC, you want to say Y here.
+
config INGENIC_TCU_CLK
bool "Ingenic JZ47xx TCU clocks driver"
default MACH_INGENIC
diff --git a/drivers/clk/ingenic/Makefile b/drivers/clk/ingenic/Makefile
index 8b1dad9b74a7..aaa4bffe03c6 100644
--- a/drivers/clk/ingenic/Makefile
+++ b/drivers/clk/ingenic/Makefile
@@ -5,4 +5,5 @@ obj-$(CONFIG_INGENIC_CGU_JZ4725B) += jz4725b-cgu.o
obj-$(CONFIG_INGENIC_CGU_JZ4770) += jz4770-cgu.o
obj-$(CONFIG_INGENIC_CGU_JZ4780) += jz4780-cgu.o
obj-$(CONFIG_INGENIC_CGU_X1000) += x1000-cgu.o
+obj-$(CONFIG_INGENIC_CGU_X1830) += x1830-cgu.o
obj-$(CONFIG_INGENIC_TCU_CLK) += tcu.o
diff --git a/drivers/clk/ingenic/x1830-cgu.c b/drivers/clk/ingenic/x1830-cgu.c
new file mode 100644
index 000000000000..29a637f4a2cc
--- /dev/null
+++ b/drivers/clk/ingenic/x1830-cgu.c
@@ -0,0 +1,443 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * X1830 SoC CGU driver
+ * Copyright (c) 2019 周琰杰 (Zhou Yanjie) <zhouyanjie@wanyeetech.com>
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/delay.h>
+#include <linux/of.h>
+
+#include <dt-bindings/clock/x1830-cgu.h>
+
+#include "cgu.h"
+#include "pm.h"
+
+/* CGU register offsets */
+#define CGU_REG_CPCCR 0x00
+#define CGU_REG_CPPCR 0x0c
+#define CGU_REG_APLL 0x10
+#define CGU_REG_MPLL 0x14
+#define CGU_REG_CLKGR0 0x20
+#define CGU_REG_OPCR 0x24
+#define CGU_REG_CLKGR1 0x28
+#define CGU_REG_DDRCDR 0x2c
+#define CGU_REG_USBPCR 0x3c
+#define CGU_REG_USBRDT 0x40
+#define CGU_REG_USBVBFIL 0x44
+#define CGU_REG_USBPCR1 0x48
+#define CGU_REG_MACCDR 0x54
+#define CGU_REG_EPLL 0x58
+#define CGU_REG_I2SCDR 0x60
+#define CGU_REG_LPCDR 0x64
+#define CGU_REG_MSC0CDR 0x68
+#define CGU_REG_I2SCDR1 0x70
+#define CGU_REG_SSICDR 0x74
+#define CGU_REG_CIMCDR 0x7c
+#define CGU_REG_MSC1CDR 0xa4
+#define CGU_REG_CMP_INTR 0xb0
+#define CGU_REG_CMP_INTRE 0xb4
+#define CGU_REG_DRCG 0xd0
+#define CGU_REG_CPCSR 0xd4
+#define CGU_REG_VPLL 0xe0
+#define CGU_REG_MACPHYC 0xe8
+
+/* bits within the OPCR register */
+#define OPCR_GATE_USBPHYCLK BIT(23)
+#define OPCR_SPENDN0 BIT(7)
+#define OPCR_SPENDN1 BIT(6)
+
+/* bits within the USBPCR register */
+#define USBPCR_SIDDQ BIT(21)
+#define USBPCR_OTG_DISABLE BIT(20)
+
+static struct ingenic_cgu *cgu;
+
+static int x1830_usb_phy_enable(struct clk_hw *hw)
+{
+ void __iomem *reg_opcr = cgu->base + CGU_REG_OPCR;
+ void __iomem *reg_usbpcr = cgu->base + CGU_REG_USBPCR;
+
+ writel((readl(reg_opcr) | OPCR_SPENDN0) & ~OPCR_GATE_USBPHYCLK, reg_opcr);
+ writel(readl(reg_usbpcr) & ~USBPCR_OTG_DISABLE & ~USBPCR_SIDDQ, reg_usbpcr);
+ return 0;
+}
+
+static void x1830_usb_phy_disable(struct clk_hw *hw)
+{
+ void __iomem *reg_opcr = cgu->base + CGU_REG_OPCR;
+ void __iomem *reg_usbpcr = cgu->base + CGU_REG_USBPCR;
+
+ writel((readl(reg_opcr) & ~OPCR_SPENDN0) | OPCR_GATE_USBPHYCLK, reg_opcr);
+ writel(readl(reg_usbpcr) | USBPCR_OTG_DISABLE | USBPCR_SIDDQ, reg_usbpcr);
+}
+
+static int x1830_usb_phy_is_enabled(struct clk_hw *hw)
+{
+ void __iomem *reg_opcr = cgu->base + CGU_REG_OPCR;
+ void __iomem *reg_usbpcr = cgu->base + CGU_REG_USBPCR;
+
+ return (readl(reg_opcr) & OPCR_SPENDN0) &&
+ !(readl(reg_usbpcr) & USBPCR_SIDDQ) &&
+ !(readl(reg_usbpcr) & USBPCR_OTG_DISABLE);
+}
+
+static const struct clk_ops x1830_otg_phy_ops = {
+ .enable = x1830_usb_phy_enable,
+ .disable = x1830_usb_phy_disable,
+ .is_enabled = x1830_usb_phy_is_enabled,
+};
+
+static const s8 pll_od_encoding[64] = {
+ 0x0, 0x1, -1, 0x2, -1, -1, -1, 0x3,
+ -1, -1, -1, -1, -1, -1, -1, 0x4,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, 0x5,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, 0x6,
+};
+
+static const struct ingenic_cgu_clk_info x1830_cgu_clocks[] = {
+
+ /* External clocks */
+
+ [X1830_CLK_EXCLK] = { "ext", CGU_CLK_EXT },
+ [X1830_CLK_RTCLK] = { "rtc", CGU_CLK_EXT },
+
+ /* PLLs */
+
+ [X1830_CLK_APLL] = {
+ "apll", CGU_CLK_PLL,
+ .parents = { X1830_CLK_EXCLK, -1, -1, -1 },
+ .pll = {
+ .reg = CGU_REG_APLL,
+ .rate_multiplier = 2,
+ .m_shift = 20,
+ .m_bits = 9,
+ .m_offset = 1,
+ .n_shift = 14,
+ .n_bits = 6,
+ .n_offset = 1,
+ .od_shift = 11,
+ .od_bits = 3,
+ .od_max = 64,
+ .od_encoding = pll_od_encoding,
+ .bypass_reg = CGU_REG_CPPCR,
+ .bypass_bit = 30,
+ .enable_bit = 0,
+ .stable_bit = 3,
+ },
+ },
+
+ [X1830_CLK_MPLL] = {
+ "mpll", CGU_CLK_PLL,
+ .parents = { X1830_CLK_EXCLK, -1, -1, -1 },
+ .pll = {
+ .reg = CGU_REG_MPLL,
+ .rate_multiplier = 2,
+ .m_shift = 20,
+ .m_bits = 9,
+ .m_offset = 1,
+ .n_shift = 14,
+ .n_bits = 6,
+ .n_offset = 1,
+ .od_shift = 11,
+ .od_bits = 3,
+ .od_max = 64,
+ .od_encoding = pll_od_encoding,
+ .bypass_reg = CGU_REG_CPPCR,
+ .bypass_bit = 28,
+ .enable_bit = 0,
+ .stable_bit = 3,
+ },
+ },
+
+ [X1830_CLK_EPLL] = {
+ "epll", CGU_CLK_PLL,
+ .parents = { X1830_CLK_EXCLK, -1, -1, -1 },
+ .pll = {
+ .reg = CGU_REG_EPLL,
+ .rate_multiplier = 2,
+ .m_shift = 20,
+ .m_bits = 9,
+ .m_offset = 1,
+ .n_shift = 14,
+ .n_bits = 6,
+ .n_offset = 1,
+ .od_shift = 11,
+ .od_bits = 3,
+ .od_max = 64,
+ .od_encoding = pll_od_encoding,
+ .bypass_reg = CGU_REG_CPPCR,
+ .bypass_bit = 24,
+ .enable_bit = 0,
+ .stable_bit = 3,
+ },
+ },
+
+ [X1830_CLK_VPLL] = {
+ "vpll", CGU_CLK_PLL,
+ .parents = { X1830_CLK_EXCLK, -1, -1, -1 },
+ .pll = {
+ .reg = CGU_REG_VPLL,
+ .rate_multiplier = 2,
+ .m_shift = 20,
+ .m_bits = 9,
+ .m_offset = 1,
+ .n_shift = 14,
+ .n_bits = 6,
+ .n_offset = 1,
+ .od_shift = 11,
+ .od_bits = 3,
+ .od_max = 64,
+ .od_encoding = pll_od_encoding,
+ .bypass_reg = CGU_REG_CPPCR,
+ .bypass_bit = 26,
+ .enable_bit = 0,
+ .stable_bit = 3,
+ },
+ },
+
+ /* Custom (SoC-specific) OTG PHY */
+
+ [X1830_CLK_OTGPHY] = {
+ "otg_phy", CGU_CLK_CUSTOM,
+ .parents = { X1830_CLK_EXCLK, -1, -1, -1 },
+ .custom = { &x1830_otg_phy_ops },
+ },
+
+ /* Muxes & dividers */
+
+ [X1830_CLK_SCLKA] = {
+ "sclk_a", CGU_CLK_MUX,
+ .parents = { -1, X1830_CLK_EXCLK, X1830_CLK_APLL, -1 },
+ .mux = { CGU_REG_CPCCR, 30, 2 },
+ },
+
+ [X1830_CLK_CPUMUX] = {
+ "cpu_mux", CGU_CLK_MUX,
+ .parents = { -1, X1830_CLK_SCLKA, X1830_CLK_MPLL, -1 },
+ .mux = { CGU_REG_CPCCR, 28, 2 },
+ },
+
+ [X1830_CLK_CPU] = {
+ "cpu", CGU_CLK_DIV | CGU_CLK_GATE,
+ .parents = { X1830_CLK_CPUMUX, -1, -1, -1 },
+ .div = { CGU_REG_CPCCR, 0, 1, 4, 22, -1, -1 },
+ .gate = { CGU_REG_CLKGR1, 15 },
+ },
+
+ [X1830_CLK_L2CACHE] = {
+ "l2cache", CGU_CLK_DIV,
+ .parents = { X1830_CLK_CPUMUX, -1, -1, -1 },
+ .div = { CGU_REG_CPCCR, 4, 1, 4, 22, -1, -1 },
+ },
+
+ [X1830_CLK_AHB0] = {
+ "ahb0", CGU_CLK_MUX | CGU_CLK_DIV,
+ .parents = { -1, X1830_CLK_SCLKA, X1830_CLK_MPLL, -1 },
+ .mux = { CGU_REG_CPCCR, 26, 2 },
+ .div = { CGU_REG_CPCCR, 8, 1, 4, 21, -1, -1 },
+ },
+
+ [X1830_CLK_AHB2PMUX] = {
+ "ahb2_apb_mux", CGU_CLK_MUX,
+ .parents = { -1, X1830_CLK_SCLKA, X1830_CLK_MPLL, -1 },
+ .mux = { CGU_REG_CPCCR, 24, 2 },
+ },
+
+ [X1830_CLK_AHB2] = {
+ "ahb2", CGU_CLK_DIV,
+ .parents = { X1830_CLK_AHB2PMUX, -1, -1, -1 },
+ .div = { CGU_REG_CPCCR, 12, 1, 4, 20, -1, -1 },
+ },
+
+ [X1830_CLK_PCLK] = {
+ "pclk", CGU_CLK_DIV | CGU_CLK_GATE,
+ .parents = { X1830_CLK_AHB2PMUX, -1, -1, -1 },
+ .div = { CGU_REG_CPCCR, 16, 1, 4, 20, -1, -1 },
+ .gate = { CGU_REG_CLKGR1, 14 },
+ },
+
+ [X1830_CLK_DDR] = {
+ "ddr", CGU_CLK_MUX | CGU_CLK_DIV | CGU_CLK_GATE,
+ .parents = { -1, X1830_CLK_SCLKA, X1830_CLK_MPLL, -1 },
+ .mux = { CGU_REG_DDRCDR, 30, 2 },
+ .div = { CGU_REG_DDRCDR, 0, 1, 4, 29, 28, 27 },
+ .gate = { CGU_REG_CLKGR0, 31 },
+ },
+
+ [X1830_CLK_MAC] = {
+ "mac", CGU_CLK_MUX | CGU_CLK_DIV | CGU_CLK_GATE,
+ .parents = { X1830_CLK_SCLKA, X1830_CLK_MPLL,
+ X1830_CLK_VPLL, X1830_CLK_EPLL },
+ .mux = { CGU_REG_MACCDR, 30, 2 },
+ .div = { CGU_REG_MACCDR, 0, 1, 8, 29, 28, 27 },
+ .gate = { CGU_REG_CLKGR1, 4 },
+ },
+
+ [X1830_CLK_LCD] = {
+ "lcd", CGU_CLK_MUX | CGU_CLK_DIV | CGU_CLK_GATE,
+ .parents = { X1830_CLK_SCLKA, X1830_CLK_MPLL,
+ X1830_CLK_VPLL, X1830_CLK_EPLL },
+ .mux = { CGU_REG_LPCDR, 30, 2 },
+ .div = { CGU_REG_LPCDR, 0, 1, 8, 28, 27, 26 },
+ .gate = { CGU_REG_CLKGR1, 9 },
+ },
+
+ [X1830_CLK_MSCMUX] = {
+ "msc_mux", CGU_CLK_MUX,
+ .parents = { X1830_CLK_SCLKA, X1830_CLK_MPLL,
+ X1830_CLK_VPLL, X1830_CLK_EPLL },
+ .mux = { CGU_REG_MSC0CDR, 30, 2 },
+ },
+
+ [X1830_CLK_MSC0] = {
+ "msc0", CGU_CLK_DIV | CGU_CLK_GATE,
+ .parents = { X1830_CLK_MSCMUX, -1, -1, -1 },
+ .div = { CGU_REG_MSC0CDR, 0, 2, 8, 29, 28, 27 },
+ .gate = { CGU_REG_CLKGR0, 4 },
+ },
+
+ [X1830_CLK_MSC1] = {
+ "msc1", CGU_CLK_DIV | CGU_CLK_GATE,
+ .parents = { X1830_CLK_MSCMUX, -1, -1, -1 },
+ .div = { CGU_REG_MSC1CDR, 0, 2, 8, 29, 28, 27 },
+ .gate = { CGU_REG_CLKGR0, 5 },
+ },
+
+ [X1830_CLK_SSIPLL] = {
+ "ssi_pll", CGU_CLK_MUX | CGU_CLK_DIV,
+ .parents = { X1830_CLK_SCLKA, X1830_CLK_MPLL,
+ X1830_CLK_VPLL, X1830_CLK_EPLL },
+ .mux = { CGU_REG_SSICDR, 30, 2 },
+ .div = { CGU_REG_SSICDR, 0, 1, 8, 28, 27, 26 },
+ },
+
+ [X1830_CLK_SSIPLL_DIV2] = {
+ "ssi_pll_div2", CGU_CLK_FIXDIV,
+ .parents = { X1830_CLK_SSIPLL },
+ .fixdiv = { 2 },
+ },
+
+ [X1830_CLK_SSIMUX] = {
+ "ssi_mux", CGU_CLK_MUX,
+ .parents = { X1830_CLK_EXCLK, X1830_CLK_SSIPLL_DIV2, -1, -1 },
+ .mux = { CGU_REG_SSICDR, 29, 1 },
+ },
+
+ /* Gate-only clocks */
+
+ [X1830_CLK_EMC] = {
+ "emc", CGU_CLK_GATE,
+ .parents = { X1830_CLK_AHB2, -1, -1, -1 },
+ .gate = { CGU_REG_CLKGR0, 0 },
+ },
+
+ [X1830_CLK_EFUSE] = {
+ "efuse", CGU_CLK_GATE,
+ .parents = { X1830_CLK_AHB2, -1, -1, -1 },
+ .gate = { CGU_REG_CLKGR0, 1 },
+ },
+
+ [X1830_CLK_OTG] = {
+ "otg", CGU_CLK_GATE,
+ .parents = { X1830_CLK_EXCLK, -1, -1, -1 },
+ .gate = { CGU_REG_CLKGR0, 3 },
+ },
+
+ [X1830_CLK_SSI0] = {
+ "ssi0", CGU_CLK_GATE,
+ .parents = { X1830_CLK_SSIMUX, -1, -1, -1 },
+ .gate = { CGU_REG_CLKGR0, 6 },
+ },
+
+ [X1830_CLK_SMB0] = {
+ "smb0", CGU_CLK_GATE,
+ .parents = { X1830_CLK_PCLK, -1, -1, -1 },
+ .gate = { CGU_REG_CLKGR0, 7 },
+ },
+
+ [X1830_CLK_SMB1] = {
+ "smb1", CGU_CLK_GATE,
+ .parents = { X1830_CLK_PCLK, -1, -1, -1 },
+ .gate = { CGU_REG_CLKGR0, 8 },
+ },
+
+ [X1830_CLK_SMB2] = {
+ "smb2", CGU_CLK_GATE,
+ .parents = { X1830_CLK_PCLK, -1, -1, -1 },
+ .gate = { CGU_REG_CLKGR0, 9 },
+ },
+
+ [X1830_CLK_UART0] = {
+ "uart0", CGU_CLK_GATE,
+ .parents = { X1830_CLK_EXCLK, -1, -1, -1 },
+ .gate = { CGU_REG_CLKGR0, 14 },
+ },
+
+ [X1830_CLK_UART1] = {
+ "uart1", CGU_CLK_GATE,
+ .parents = { X1830_CLK_EXCLK, -1, -1, -1 },
+ .gate = { CGU_REG_CLKGR0, 15 },
+ },
+
+ [X1830_CLK_SSI1] = {
+ "ssi1", CGU_CLK_GATE,
+ .parents = { X1830_CLK_SSIMUX, -1, -1, -1 },
+ .gate = { CGU_REG_CLKGR0, 19 },
+ },
+
+ [X1830_CLK_SFC] = {
+ "sfc", CGU_CLK_GATE,
+ .parents = { X1830_CLK_SSIPLL, -1, -1, -1 },
+ .gate = { CGU_REG_CLKGR0, 20 },
+ },
+
+ [X1830_CLK_PDMA] = {
+ "pdma", CGU_CLK_GATE,
+ .parents = { X1830_CLK_EXCLK, -1, -1, -1 },
+ .gate = { CGU_REG_CLKGR0, 21 },
+ },
+
+ [X1830_CLK_TCU] = {
+ "tcu", CGU_CLK_GATE,
+ .parents = { X1830_CLK_EXCLK, -1, -1, -1 },
+ .gate = { CGU_REG_CLKGR0, 30 },
+ },
+
+ [X1830_CLK_DTRNG] = {
+ "dtrng", CGU_CLK_GATE,
+ .parents = { X1830_CLK_PCLK, -1, -1, -1 },
+ .gate = { CGU_REG_CLKGR1, 1 },
+ },
+
+ [X1830_CLK_OST] = {
+ "ost", CGU_CLK_GATE,
+ .parents = { X1830_CLK_EXCLK, -1, -1, -1 },
+ .gate = { CGU_REG_CLKGR1, 11 },
+ },
+};
+
+static void __init x1830_cgu_init(struct device_node *np)
+{
+ int retval;
+
+ cgu = ingenic_cgu_new(x1830_cgu_clocks,
+ ARRAY_SIZE(x1830_cgu_clocks), np);
+ if (!cgu) {
+ pr_err("%s: failed to initialise CGU\n", __func__);
+ return;
+ }
+
+ retval = ingenic_cgu_register_clocks(cgu);
+ if (retval) {
+ pr_err("%s: failed to register CGU Clocks\n", __func__);
+ return;
+ }
+
+ ingenic_cgu_register_syscore_ops(cgu);
+}
+CLK_OF_DECLARE_DRIVER(x1830_cgu, "ingenic,x1830-cgu", x1830_cgu_init);
--
2.11.0
^ permalink raw reply related
* [PATCH v11 1/7] clk: Ingenic: Remove unnecessary spinlock when reading registers.
From: 周琰杰 (Zhou Yanjie) @ 2020-05-27 8:54 UTC (permalink / raw)
To: linux-clk
Cc: linux-kernel, devicetree, sboyd, mturquette, robh+dt,
dongsheng.qiu, aric.pzqi, rick.tyliu, yanfei.li, sernia.zhou,
zhenwenjin, paul
In-Reply-To: <20200527085449.55573-1-zhouyanjie@wanyeetech.com>
It is not necessary to use spinlock when reading registers,
so remove it from cgu.c.
Suggested-by: Paul Cercueil <paul@crapouillou.net>
Suggested-by: Paul Burton <paulburton@kernel.org>
Signed-off-by: 周琰杰 (Zhou Yanjie) <zhouyanjie@wanyeetech.com>
Reviewed-by: Paul Cercueil <paul@crapouillou.net>
---
Notes:
v2:
New patch.
v2->v3:
Adjust order from [5/5] in v2 to [1/5] in v3.
v3->v4:
Remove the spinlock around ingenic_cgu_gate_get().
v4->v5:
Rebase on top of kernel 5.6-rc1.
v5->v6:
No change.
v6->v7:
No change.
v7->v8:
No change.
v8->v9:
No change.
v9->v10:
No change.
v10->v11:
No change.
drivers/clk/ingenic/cgu.c | 12 +-----------
1 file changed, 1 insertion(+), 11 deletions(-)
diff --git a/drivers/clk/ingenic/cgu.c b/drivers/clk/ingenic/cgu.c
index 6e963031cd87..ab1302ad1450 100644
--- a/drivers/clk/ingenic/cgu.c
+++ b/drivers/clk/ingenic/cgu.c
@@ -76,16 +76,13 @@ ingenic_pll_recalc_rate(struct clk_hw *hw, unsigned long parent_rate)
const struct ingenic_cgu_pll_info *pll_info;
unsigned m, n, od_enc, od;
bool bypass;
- unsigned long flags;
u32 ctl;
clk_info = &cgu->clock_info[ingenic_clk->idx];
BUG_ON(clk_info->type != CGU_CLK_PLL);
pll_info = &clk_info->pll;
- spin_lock_irqsave(&cgu->lock, flags);
ctl = readl(cgu->base + pll_info->reg);
- spin_unlock_irqrestore(&cgu->lock, flags);
m = (ctl >> pll_info->m_shift) & GENMASK(pll_info->m_bits - 1, 0);
m += pll_info->m_offset;
@@ -259,12 +256,9 @@ static int ingenic_pll_is_enabled(struct clk_hw *hw)
struct ingenic_cgu *cgu = ingenic_clk->cgu;
const struct ingenic_cgu_clk_info *clk_info = to_clk_info(ingenic_clk);
const struct ingenic_cgu_pll_info *pll_info = &clk_info->pll;
- unsigned long flags;
u32 ctl;
- spin_lock_irqsave(&cgu->lock, flags);
ctl = readl(cgu->base + pll_info->reg);
- spin_unlock_irqrestore(&cgu->lock, flags);
return !!(ctl & BIT(pll_info->enable_bit));
}
@@ -562,16 +556,12 @@ static int ingenic_clk_is_enabled(struct clk_hw *hw)
struct ingenic_clk *ingenic_clk = to_ingenic_clk(hw);
struct ingenic_cgu *cgu = ingenic_clk->cgu;
const struct ingenic_cgu_clk_info *clk_info;
- unsigned long flags;
int enabled = 1;
clk_info = &cgu->clock_info[ingenic_clk->idx];
- if (clk_info->type & CGU_CLK_GATE) {
- spin_lock_irqsave(&cgu->lock, flags);
+ if (clk_info->type & CGU_CLK_GATE)
enabled = !ingenic_cgu_gate_get(cgu, &clk_info->gate);
- spin_unlock_irqrestore(&cgu->lock, flags);
- }
return enabled;
}
--
2.11.0
^ permalink raw reply related
* Re: [V9, 1/2] media: dt-bindings: media: i2c: Document OV02A10 bindings
From: Dongchun Zhu @ 2020-05-27 8:49 UTC (permalink / raw)
To: Rob Herring
Cc: linus.walleij, bgolaszewski, mchehab, andriy.shevchenko,
mark.rutland, sakari.ailus, drinkcat, tfiga, matthias.bgg,
bingbu.cao, srv_heupstream, linux-mediatek, linux-arm-kernel,
sj.huang, linux-media, devicetree, louis.kuo, shengnan.wang,
dongchun.zhu
In-Reply-To: <20200526182847.GA92449@bogus>
Hi Rob,
Thanks for the review. Please see my replies below.
On Tue, 2020-05-26 at 12:28 -0600, Rob Herring wrote:
> On Sat, May 23, 2020 at 04:41:02PM +0800, Dongchun Zhu wrote:
> > Add DT bindings documentation for Omnivision OV02A10 image sensor.
> >
> > Signed-off-by: Dongchun Zhu <dongchun.zhu@mediatek.com>
> > ---
> > .../bindings/media/i2c/ovti,ov02a10.yaml | 172 +++++++++++++++++++++
> > MAINTAINERS | 7 +
> > 2 files changed, 179 insertions(+)
> > create mode 100644 Documentation/devicetree/bindings/media/i2c/ovti,ov02a10.yaml
> >
> > diff --git a/Documentation/devicetree/bindings/media/i2c/ovti,ov02a10.yaml b/Documentation/devicetree/bindings/media/i2c/ovti,ov02a10.yaml
> > new file mode 100644
> > index 0000000..56f31b5
> > --- /dev/null
> > +++ b/Documentation/devicetree/bindings/media/i2c/ovti,ov02a10.yaml
> > @@ -0,0 +1,172 @@
> > +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
> > +# Copyright (c) 2020 MediaTek Inc.
> > +%YAML 1.2
> > +---
> > +$id: http://devicetree.org/schemas/media/i2c/ovti,ov02a10.yaml#
> > +$schema: http://devicetree.org/meta-schemas/core.yaml#
> > +
> > +title: Omnivision OV02A10 CMOS Sensor Device Tree Bindings
> > +
> > +maintainers:
> > + - Dongchun Zhu <dongchun.zhu@mediatek.com>
> > +
> > +description: |-
> > + The Omnivision OV02A10 is a low-cost, high performance, 1/5-inch, 2 megapixel
> > + image sensor, which is the latest production derived from Omnivision's CMOS
> > + image sensor technology. Ihis chip supports high frame rate speeds up to 30fps
> > + @ 1600x1200 (UXGA) resolution transferred over a 1-lane MIPI interface. The
> > + sensor output is available via CSI-2 serial data output.
> > +
> > +properties:
> > + compatible:
> > + const: ovti,ov02a10
> > +
> > + reg:
> > + maxItems: 1
> > +
> > + clocks:
> > + items:
> > + - description: top mux camtg clock
> > + - description: divider clock
> > +
> > + clock-names:
> > + items:
> > + - const: eclk
> > + - const: freq_mux
> > +
> > + clock-frequency:
> > + description:
> > + Frequency of the eclk clock in Hertz.
> > +
Rob, shall we use 'maxItems: 1' to constrain property: clock-frequency?
Or could we adopt 'clock-frequency: true' directly here?
> > + dovdd-supply:
> > + description:
> > + Definition of the regulator used as Digital I/O voltage supply.
> > +
Shall we add 'maxItems: 1' here?
> > + avdd-supply:
> > + description:
> > + Definition of the regulator used as Analog voltage supply.
> > +
Ditto.
> > + dvdd-supply:
> > + description:
> > + Definition of the regulator used as Digital core voltage supply.
> > +
Ditto.
> > + powerdown-gpios:
> > + description:
> > + Must be the device tree identifier of the GPIO connected to the
> > + PD_PAD pin. This pin is used to place the OV02A10 into Standby mode
> > + or Shutdown mode. As the line is active low, it should be
> > + marked GPIO_ACTIVE_LOW.
>
> Need to define how many GPIOs ('maxItems: 1')
>
It would be fixed like this in next release.
powerdown-gpios:
maxItems: 1
description:
Must be the device tree identifier of the GPIO connected to the
PD_PAD pin. This pin is used to place the OV02A10 into Standby mode
or Shutdown mode. As the line is active low, it should be
marked GPIO_ACTIVE_LOW.
> > +
> > + reset-gpios:
> > + description:
> > + Must be the device tree identifier of the GPIO connected to the
> > + RST_PD pin. If specified, it will be asserted during driver probe.
> > + As the line is active high, it should be marked GPIO_ACTIVE_HIGH.
>
> Here too.
>
Similar as 'powerdown-gpios'.
Fixed in next release.
> > +
> > + rotation:
> > + description:
> > + Definition of the sensor's placement.
> > + allOf:
> > + - $ref: "/schemas/types.yaml#/definitions/uint32"
> > + - enum:
> > + - 0 # Sensor Mounted Upright
> > + - 180 # Sensor Mounted Upside Down
> > + default: 0
> > +
> > + ovti,mipi-tx-speed:
> > + description:
> > + Indication of MIPI transmission speed select, which is to control D-PHY
> > + timing setting by adjusting MIPI clock voltage to improve the clock
> > + driver capability.
> > + allOf:
> > + - $ref: "/schemas/types.yaml#/definitions/uint32"
> > + - enum:
> > + - 0 # 20MHz - 30MHz
> > + - 1 # 30MHz - 50MHz
> > + - 2 # 50MHz - 75MHz
> > + - 3 # 75MHz - 100MHz
> > + - 4 # 100MHz - 130MHz
> > + default: 3
> > +
> > + # See ../video-interfaces.txt for details
> > + port:
> > + type: object
> > + additionalProperties: false
>
> Should have a description of what data the port has.
>
It would be updated as below in next release.
port:
type: object
additionalProperties: false
description:
Input port node, single endpoint describing the CSI-2 transmitter.
> > +
> > + properties:
> > + endpoint:
> > + type: object
> > + additionalProperties: false
> > +
> > + properties:
Actually I wonder whether we need to declare 'clock-lanes' here?
> > + data-lanes:
> > + maxItems: 1
> > +
> > + link-frequencies: true
> > + remote-endpoint: true
> > +
> > + required:
Ditto.
> > + - data-lanes
> > + - link-frequencies
> > + - remote-endpoint
> > +
> > + required:
> > + - endpoint
> > +
> > +required:
> > + - compatible
> > + - reg
> > + - clocks
> > + - clock-names
> > + - clock-frequency
> > + - dovdd-supply
> > + - avdd-supply
> > + - dvdd-supply
> > + - powerdown-gpios
> > + - reset-gpios
> > + - port
> > +
> > +additionalProperties: false
> > +
> > +examples:
> > + - |
> > +
> > + #include <dt-bindings/clock/mt8183-clk.h>
> > + #include <dt-bindings/gpio/gpio.h>
> > +
> > + i2c {
> > + #address-cells = <1>;
> > + #size-cells = <0>;
> > +
> > + ov02a10: camera-sensor@3d {
> > + compatible = "ovti,ov02a10";
> > + reg = <0x3d>;
> > + pinctrl-names = "default";
> > + pinctrl-0 = <&clk_24m_cam>;
> > +
> > + clocks = <&topckgen CLK_TOP_MUX_CAMTG>,
> > + <&topckgen CLK_TOP_UNIVP_192M_D8>;
> > + clock-names = "eclk", "freq_mux";
> > + clock-frequency = <24000000>;
> > +
> > + rotation = <180>;
> > + ovti,mipi-tx-speed = <4>;
> > +
> > + dovdd-supply = <&mt6358_vcamio_reg>;
> > + avdd-supply = <&mt6358_vcama1_reg>;
> > + dvdd-supply = <&mt6358_vcn18_reg>;
> > +
> > + powerdown-gpios = <&pio 107 GPIO_ACTIVE_LOW>;
> > + reset-gpios = <&pio 109 GPIO_ACTIVE_HIGH>;
> > +
> > + port {
> > + wcam_out: endpoint {
> > + data-lanes = <1>;
> > + link-frequencies = /bits/ 64 <390000000>;
> > + remote-endpoint = <&mipi_in_wcam>;
> > + };
> > + };
> > + };
> > + };
> > +
> > +...
> > diff --git a/MAINTAINERS b/MAINTAINERS
> > index e64e5db..63a2335 100644
> > --- a/MAINTAINERS
> > +++ b/MAINTAINERS
> > @@ -12389,6 +12389,13 @@ M: Harald Welte <laforge@gnumonks.org>
> > S: Maintained
> > F: drivers/char/pcmcia/cm4040_cs.*
> >
> > +OMNIVISION OV02A10 SENSOR DRIVER
> > +M: Dongchun Zhu <dongchun.zhu@mediatek.com>
> > +L: linux-media@vger.kernel.org
> > +S: Maintained
> > +T: git git://linuxtv.org/media_tree.git
> > +F: Documentation/devicetree/bindings/media/i2c/ovti,ov02a10.yaml
> > +
> > OMNIVISION OV13858 SENSOR DRIVER
> > M: Sakari Ailus <sakari.ailus@linux.intel.com>
> > L: linux-media@vger.kernel.org
> > --
> > 2.9.2
^ permalink raw reply
* Re: [RESEND v5 09/21] mtd: rawnand: Create a new enumeration to describe properly ECC types
From: Boris Brezillon @ 2020-05-27 8:50 UTC (permalink / raw)
To: Miquel Raynal
Cc: Richard Weinberger, Vignesh Raghavendra, Tudor Ambarus, linux-mtd,
Rob Herring, Mark Rutland, devicetree
In-Reply-To: <20200527104430.187e5feb@collabora.com>
On Wed, 27 May 2020 10:44:30 +0200
Boris Brezillon <boris.brezillon@collabora.com> wrote:
> On Wed, 27 May 2020 10:33:56 +0200
> Miquel Raynal <miquel.raynal@bootlin.com> wrote:
>
> > Boris Brezillon <boris.brezillon@collabora.com> wrote on Wed, 27 May
> > 2020 00:59:28 +0200:
> >
> > > On Tue, 26 May 2020 21:56:21 +0200
> > > Miquel Raynal <miquel.raynal@bootlin.com> wrote:
> > >
> > > > Now that the misleading mix between ECC engine type and OOB placement
> > > > has been addressed, add a new enumeration to properly define ECC types
> > > > (also called provider or mode).
> > > >
> > > > Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
> > > > Reviewed-by: Boris Brezillon <boris.brezillon@collabora.com>
> > > > ---
> > > > drivers/mtd/nand/raw/nand_base.c | 7 +++++++
> > > > include/linux/mtd/rawnand.h | 16 ++++++++++++++++
> > > > 2 files changed, 23 insertions(+)
> > > >
> > > > diff --git a/drivers/mtd/nand/raw/nand_base.c b/drivers/mtd/nand/raw/nand_base.c
> > > > index 515cd4681660..5c6ab5b93270 100644
> > > > --- a/drivers/mtd/nand/raw/nand_base.c
> > > > +++ b/drivers/mtd/nand/raw/nand_base.c
> > > > @@ -5018,6 +5018,13 @@ static const char * const nand_ecc_modes[] = {
> > > > [NAND_ECC_ON_DIE] = "on-die",
> > > > };
> > > >
> > > > +static const char * const nand_ecc_engine_providers[] = {
> > >
> > > This table is not used here, are you sure it should be introduced now?
> > >
> > > > + [NAND_ECC_ENGINE_NONE] = "none",
> > > > + [NAND_ECC_ENGINE_SOFT] = "soft",
> > > > + [NAND_ECC_ENGINE_CONTROLLER] = "hw",
> > >
> > > ^ "on-controller" ?
> >
> > This would break DT backward compatibility, I am afraid I cannot do
> > that.
>
> You can always keep a translation table for the old prop
> (nand-ecc-mode) and have a new one for the new prop
> (nand-ecc-engine-type). But maybe you're not introducing a new property
> in this series, in which case the translation table here is just fine.
BTW, this DT prop is more a way to select among several ECC engines when
you have a choice, so maybe it should be named
nand-use-ecc-engine-type/nand-select-ecc-engine-type instead of
nand-ecc-provider/nand-ecc-engine-type.
^ permalink raw reply
* Re: [Freedreno] [PATCH 5/6] drm: msm: a6xx: use dev_pm_opp_set_bw to set DDR bandwidth
From: Sharat Masetty @ 2020-05-27 8:47 UTC (permalink / raw)
To: Rob Clark, freedreno,
open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
dri-devel, linux-arm-msm, Linux Kernel Mailing List,
Georgi Djakov, Matthias Kaehlcke
Cc: viresh.kumar, saravanak, sibis, rnayak
In-Reply-To: <CAF6AEGtoNwUGX-r7QytGn5hSU-VD4RJZyhcb3WdgAgAFR5BK4A@mail.gmail.com>
+ more folks
On 5/18/2020 9:55 PM, Rob Clark wrote:
> On Mon, May 18, 2020 at 7:23 AM Jordan Crouse <jcrouse@codeaurora.org> wrote:
>> On Thu, May 14, 2020 at 04:24:18PM +0530, Sharat Masetty wrote:
>>> This patches replaces the previously used static DDR vote and uses
>>> dev_pm_opp_set_bw() to scale GPU->DDR bandwidth along with scaling
>>> GPU frequency.
>>>
>>> Signed-off-by: Sharat Masetty <smasetty@codeaurora.org>
>>> ---
>>> drivers/gpu/drm/msm/adreno/a6xx_gmu.c | 6 +-----
>>> 1 file changed, 1 insertion(+), 5 deletions(-)
>>>
>>> diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c
>>> index 2d8124b..79433d3 100644
>>> --- a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c
>>> +++ b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c
>>> @@ -141,11 +141,7 @@ void a6xx_gmu_set_freq(struct msm_gpu *gpu, struct dev_pm_opp *opp)
>>>
>>> gmu->freq = gmu->gpu_freqs[perf_index];
>>>
>>> - /*
>>> - * Eventually we will want to scale the path vote with the frequency but
>>> - * for now leave it at max so that the performance is nominal.
>>> - */
>>> - icc_set_bw(gpu->icc_path, 0, MBps_to_icc(7216));
>>> + dev_pm_opp_set_bw(&gpu->pdev->dev, opp);
>>> }
>> This adds an implicit requirement that all targets need bandwidth settings
>> defined in the OPP or they won't get a bus vote at all. I would prefer that
>> there be an default escape valve but if not you'll need to add
>> bandwidth values for the sdm845 OPP that target doesn't regress.
>>
> it looks like we could maybe do something like:
>
> ret = dev_pm_opp_set_bw(...);
> if (ret) {
> dev_warn_once(dev, "no bandwidth settings");
> icc_set_bw(...);
> }
>
> ?
>
> BR,
> -R
There is a bit of an issue here - Looks like its not possible to two icc
handles to the same path. Its causing double enumeration of the paths
in the icc core and messing up path votes. With [1] Since opp/core
already gets a handle to the icc path as part of table add, drm/msm
could do either
a) Conditionally enumerate gpu->icc_path handle only when pm/opp core
has not got the icc path handle. I could use something like [2] to
determine if should initialize gpu->icc_path*
b) Add peak-opp-configs in 845 dt and mandate all future versions to use
this bindings. With this, I can remove gpu->icc_path from msm/drm
completely and only rely on opp/core for bw voting.
[1] - https://lore.kernel.org/patchwork/cover/1240687/
[2] - https://patchwork.kernel.org/patch/11527573/
Let me know your thoughts
Sharat
>
>> Jordan
>>
>>> unsigned long a6xx_gmu_get_freq(struct msm_gpu *gpu)
>>> --
>>> 2.7.4
>>>
>> --
>> The Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
>> a Linux Foundation Collaborative Project
>> _______________________________________________
>> Freedreno mailing list
>> Freedreno@lists.freedesktop.org
>> https://lists.freedesktop.org/mailman/listinfo/freedreno
^ permalink raw reply
* Re: [PATCH V7 5/7] tty: serial: qcom_geni_serial: Add interconnect support
From: Greg KH @ 2020-05-27 8:46 UTC (permalink / raw)
To: Akash Asthana
Cc: agross, bjorn.andersson, wsa, broonie, mark.rutland, robh+dt,
linux-i2c, linux-spi, devicetree, swboyd, mgautam, linux-arm-msm,
linux-serial, mka, dianders, msavaliy, evgreen
In-Reply-To: <1590497690-29035-6-git-send-email-akashast@codeaurora.org>
On Tue, May 26, 2020 at 06:24:48PM +0530, Akash Asthana wrote:
> Get the interconnect paths for Uart based Serial Engine device
> and vote according to the baud rate requirement of the driver.
>
> Signed-off-by: Akash Asthana <akashast@codeaurora.org>
> Reviewed-by: Matthias Kaehlcke <mka@chromium.org>
Acked-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
^ permalink raw reply
* Re: [PATCH v5 06/11] net: ethernet: mtk-star-emac: new driver
From: Bartosz Golaszewski @ 2020-05-27 8:46 UTC (permalink / raw)
To: Nathan Chancellor
Cc: Rob Herring, David S . Miller, Matthias Brugger, John Crispin,
Sean Wang, Mark Lee, Jakub Kicinski, Arnd Bergmann, Fabien Parent,
Heiner Kallweit, Edwin Peer, devicetree,
Linux Kernel Mailing List, netdev, Linux ARM,
moderated list:ARM/Mediatek SoC..., Stephane Le Provost,
Pedro Tsai, Andrew Perepech, Bartosz Golaszewski,
clang-built-linux
In-Reply-To: <20200527073150.GA3384158@ubuntu-s3-xlarge-x86>
śr., 27 maj 2020 o 09:31 Nathan Chancellor <natechancellor@gmail.com>
napisał(a):
>
> On Fri, May 22, 2020 at 02:06:55PM +0200, Bartosz Golaszewski wrote:
>
> <snip>
>
> > diff --git a/drivers/net/ethernet/mediatek/mtk_star_emac.c b/drivers/net/ethernet/mediatek/mtk_star_emac.c
> > new file mode 100644
> > index 000000000000..789c77af501f
> > --- /dev/null
> > +++ b/drivers/net/ethernet/mediatek/mtk_star_emac.c
> > @@ -0,0 +1,1678 @@
>
> <snip>
>
> I've searched netdev and I cannot find any reports from others but this
> function introduces a clang warning:
>
> drivers/net/ethernet/mediatek/mtk_star_emac.c:1296:6: warning: variable 'new_dma_addr' is used uninitialized whenever 'if' condition is true [-Wsometimes-uninitialized]
> if (!new_skb) {
> ^~~~~~~~
> drivers/net/ethernet/mediatek/mtk_star_emac.c:1321:23: note: uninitialized use occurs here
> desc_data.dma_addr = new_dma_addr;
> ^~~~~~~~~~~~
> drivers/net/ethernet/mediatek/mtk_star_emac.c:1296:2: note: remove the 'if' if its condition is always false
> if (!new_skb) {
> ^~~~~~~~~~~~~~~
> drivers/net/ethernet/mediatek/mtk_star_emac.c:1285:6: warning: variable 'new_dma_addr' is used uninitialized whenever 'if' condition is true [-Wsometimes-uninitialized]
> if ((desc_data.flags & MTK_STAR_DESC_BIT_RX_CRCE) ||
> ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> drivers/net/ethernet/mediatek/mtk_star_emac.c:1321:23: note: uninitialized use occurs here
> desc_data.dma_addr = new_dma_addr;
> ^~~~~~~~~~~~
> drivers/net/ethernet/mediatek/mtk_star_emac.c:1285:2: note: remove the 'if' if its condition is always false
> if ((desc_data.flags & MTK_STAR_DESC_BIT_RX_CRCE) ||
> ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> drivers/net/ethernet/mediatek/mtk_star_emac.c:1285:6: warning: variable 'new_dma_addr' is used uninitialized whenever '||' condition is true [-Wsometimes-uninitialized]
> if ((desc_data.flags & MTK_STAR_DESC_BIT_RX_CRCE) ||
> ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> drivers/net/ethernet/mediatek/mtk_star_emac.c:1321:23: note: uninitialized use occurs here
> desc_data.dma_addr = new_dma_addr;
> ^~~~~~~~~~~~
> drivers/net/ethernet/mediatek/mtk_star_emac.c:1285:6: note: remove the '||' if its condition is always false
> if ((desc_data.flags & MTK_STAR_DESC_BIT_RX_CRCE) ||
> ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> drivers/net/ethernet/mediatek/mtk_star_emac.c:1274:25: note: initialize the variable 'new_dma_addr' to silence this warning
> dma_addr_t new_dma_addr;
> ^
> = 0
> 3 warnings generated.
>
> > +static int mtk_star_receive_packet(struct mtk_star_priv *priv)
> > +{
> > + struct mtk_star_ring *ring = &priv->rx_ring;
> > + struct device *dev = mtk_star_get_dev(priv);
> > + struct mtk_star_ring_desc_data desc_data;
> > + struct net_device *ndev = priv->ndev;
> > + struct sk_buff *curr_skb, *new_skb;
> > + dma_addr_t new_dma_addr;
>
> Uninitialized here
>
> > + int ret;
> > +
> > + spin_lock(&priv->lock);
> > + ret = mtk_star_ring_pop_tail(ring, &desc_data);
> > + spin_unlock(&priv->lock);
> > + if (ret)
> > + return -1;
> > +
> > + curr_skb = desc_data.skb;
> > +
> > + if ((desc_data.flags & MTK_STAR_DESC_BIT_RX_CRCE) ||
> > + (desc_data.flags & MTK_STAR_DESC_BIT_RX_OSIZE)) {
> > + /* Error packet -> drop and reuse skb. */
> > + new_skb = curr_skb;
> > + goto push_new_skb;
>
> this goto
>
> > + }
> > +
> > + /* Prepare new skb before receiving the current one. Reuse the current
> > + * skb if we fail at any point.
> > + */
> > + new_skb = mtk_star_alloc_skb(ndev);
> > + if (!new_skb) {
> > + ndev->stats.rx_dropped++;
> > + new_skb = curr_skb;
> > + goto push_new_skb;
>
> and this goto
>
> > + }
> > +
> > + new_dma_addr = mtk_star_dma_map_rx(priv, new_skb);
> > + if (dma_mapping_error(dev, new_dma_addr)) {
> > + ndev->stats.rx_dropped++;
> > + dev_kfree_skb(new_skb);
> > + new_skb = curr_skb;
> > + netdev_err(ndev, "DMA mapping error of RX descriptor\n");
> > + goto push_new_skb;
> > + }
> > +
> > + /* We can't fail anymore at this point: it's safe to unmap the skb. */
> > + mtk_star_dma_unmap_rx(priv, &desc_data);
> > +
> > + skb_put(desc_data.skb, desc_data.len);
> > + desc_data.skb->ip_summed = CHECKSUM_NONE;
> > + desc_data.skb->protocol = eth_type_trans(desc_data.skb, ndev);
> > + desc_data.skb->dev = ndev;
> > + netif_receive_skb(desc_data.skb);
> > +
> > +push_new_skb:
> > + desc_data.dma_addr = new_dma_addr;
>
> assign it uninitialized here.
>
> > + desc_data.len = skb_tailroom(new_skb);
> > + desc_data.skb = new_skb;
> > +
> > + spin_lock(&priv->lock);
> > + mtk_star_ring_push_head_rx(ring, &desc_data);
> > + spin_unlock(&priv->lock);
> > +
> > + return 0;
> > +}
>
> I don't know if there should be a new label that excludes that
> assignment for those particular gotos or if new_dma_addr should
> be initialized to something at the top. Please take a look at
> addressing this when you get a chance.
>
> Cheers,
> Nathan
Hi Nathan,
Thanks for reporting this! I have a fix ready and will send it shortly.
Bartosz
^ permalink raw reply
* Re: [RESEND v5 09/21] mtd: rawnand: Create a new enumeration to describe properly ECC types
From: Boris Brezillon @ 2020-05-27 8:44 UTC (permalink / raw)
To: Miquel Raynal
Cc: Richard Weinberger, Vignesh Raghavendra, Tudor Ambarus, linux-mtd,
Rob Herring, Mark Rutland, devicetree
In-Reply-To: <20200527103356.56e145a9@xps13>
On Wed, 27 May 2020 10:33:56 +0200
Miquel Raynal <miquel.raynal@bootlin.com> wrote:
> Boris Brezillon <boris.brezillon@collabora.com> wrote on Wed, 27 May
> 2020 00:59:28 +0200:
>
> > On Tue, 26 May 2020 21:56:21 +0200
> > Miquel Raynal <miquel.raynal@bootlin.com> wrote:
> >
> > > Now that the misleading mix between ECC engine type and OOB placement
> > > has been addressed, add a new enumeration to properly define ECC types
> > > (also called provider or mode).
> > >
> > > Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
> > > Reviewed-by: Boris Brezillon <boris.brezillon@collabora.com>
> > > ---
> > > drivers/mtd/nand/raw/nand_base.c | 7 +++++++
> > > include/linux/mtd/rawnand.h | 16 ++++++++++++++++
> > > 2 files changed, 23 insertions(+)
> > >
> > > diff --git a/drivers/mtd/nand/raw/nand_base.c b/drivers/mtd/nand/raw/nand_base.c
> > > index 515cd4681660..5c6ab5b93270 100644
> > > --- a/drivers/mtd/nand/raw/nand_base.c
> > > +++ b/drivers/mtd/nand/raw/nand_base.c
> > > @@ -5018,6 +5018,13 @@ static const char * const nand_ecc_modes[] = {
> > > [NAND_ECC_ON_DIE] = "on-die",
> > > };
> > >
> > > +static const char * const nand_ecc_engine_providers[] = {
> >
> > This table is not used here, are you sure it should be introduced now?
> >
> > > + [NAND_ECC_ENGINE_NONE] = "none",
> > > + [NAND_ECC_ENGINE_SOFT] = "soft",
> > > + [NAND_ECC_ENGINE_CONTROLLER] = "hw",
> >
> > ^ "on-controller" ?
>
> This would break DT backward compatibility, I am afraid I cannot do
> that.
You can always keep a translation table for the old prop
(nand-ecc-mode) and have a new one for the new prop
(nand-ecc-engine-type). But maybe you're not introducing a new property
in this series, in which case the translation table here is just fine.
> Honnestly, I find "hw" good enough because "on-controller" is
> also too restrictive.
How about "on-host", it doesn't say anything about where the engine is
on the host (can be embedded in the controller, or an external block),
yet clearly describe the fact that it's not on-die ECC.
> What about an external (non-pipelined) engine
> like the one I am about to introduce?
>
> >
> > > + [NAND_ECC_ENGINE_ON_DIE] = "on-die",
Well, this one is also a HW engine, and that's the problem I have with
the "hw" string.
> > > +};
> > > +
> > > static const char * const nand_ecc_placement[] = {
> > > [NAND_ECC_PLACEMENT_INTERLEAVED] = "interleaved",
> > > };
> > > diff --git a/include/linux/mtd/rawnand.h b/include/linux/mtd/rawnand.h
> > > index dc909fb977c7..a2078c5f3d21 100644
> > > --- a/include/linux/mtd/rawnand.h
> > > +++ b/include/linux/mtd/rawnand.h
> > > @@ -92,6 +92,22 @@ enum nand_ecc_mode {
> > > NAND_ECC_ON_DIE,
> > > };
> > >
> > > +/**
> > > + * enum nand_ecc_engine_type - NAND ECC engine type/provider
> > > + * @NAND_ECC_ENGINE_INVALID: Invalid value
> > > + * @NAND_ECC_ENGINE_NONE: No ECC correction
> > > + * @NAND_ECC_ENGINE_SOFT: Software ECC correction
> > > + * @NAND_ECC_ENGINE_CONTROLLER: Hardware controller ECC correction
> > > + * @NAND_ECC_ENGINE_ON_DIE: On chip hardware ECC correction
> > > + */
> > > +enum nand_ecc_engine_type {
> > > + NAND_ECC_ENGINE_INVALID,
> > > + NAND_ECC_ENGINE_NONE,
> > > + NAND_ECC_ENGINE_SOFT,
> > > + NAND_ECC_ENGINE_CONTROLLER,
> > > + NAND_ECC_ENGINE_ON_DIE,
> > > +};
> > > +
> > > /**
> > > * enum nand_ecc_placement - NAND ECC placement
> > > * @NAND_ECC_PLACEMENT_FREE: The driver can decide where to put ECC bytes.
> >
^ permalink raw reply
* Re: [RESEND v5 12/21] mtd: rawnand: Deprecate nand-ecc-mode in favor of nand-ecc-provider
From: Miquel Raynal @ 2020-05-27 8:42 UTC (permalink / raw)
To: Boris Brezillon
Cc: Richard Weinberger, Vignesh Raghavendra, Tudor Ambarus, linux-mtd,
Rob Herring, Mark Rutland, devicetree
In-Reply-To: <20200527010325.0e7213b2@collabora.com>
Boris Brezillon <boris.brezillon@collabora.com> wrote on Wed, 27 May
2020 01:03:25 +0200:
> On Tue, 26 May 2020 21:56:24 +0200
> Miquel Raynal <miquel.raynal@bootlin.com> wrote:
>
> > Use nand-ecc-provider as the provider DT property. Fallback to
> > nand-ecc-mode if the property does not exist.
> >
> > Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
> > ---
> > drivers/mtd/nand/raw/nand_base.c | 4 +++-
> > 1 file changed, 3 insertions(+), 1 deletion(-)
> >
> > diff --git a/drivers/mtd/nand/raw/nand_base.c b/drivers/mtd/nand/raw/nand_base.c
> > index 69c1b7ab938e..7d17d52cdd34 100644
> > --- a/drivers/mtd/nand/raw/nand_base.c
> > +++ b/drivers/mtd/nand/raw/nand_base.c
> > @@ -5036,7 +5036,9 @@ of_get_nand_ecc_engine_type(struct device_node *np)
> > const char *pm;
> > int err;
> >
> > - err = of_property_read_string(np, "nand-ecc-mode", &pm);
> > + err = of_property_read_string(np, "nand-ecc-provider", &pm);
>
> "nand-ecc-engine-type"
>
> And I'd prefer to have a different string table for that one, so we get
> rid of the confusing "hw" type (which is actually "on-controller").
So this means
* keeping a legacy table
* supporting both tables
* with both DT properties
* eventually refuse the legacy entries in spi-nand
Sounds like a lot of burden to me for a minor improvement. If we rename
"hw" into "on-controller" we must also add "off-controller" then, but
again, I find it confusing.
I am a bit lost on what is the "right" direction right now.
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox