This patch serie adds a new JZ4755 machine type and the
Clock Generation Unit (CGU) driver for the JZ4755 SoC.
Diffs from 1-st patchset:
- CGU patches splitted into its own patchset
- dual license for dt-bindings header
- acks collected
Siarhei Volkau (4):
MIPS: ingenic: add new machine type MACH_JZ4755
dt-bindings: ingenic: Add support for the JZ4755 CGU
dt-bindings: clock: Add Ingenic JZ4755 CGU header
clk: Add Ingenic JZ4755 CGU driver
.../bindings/clock/ingenic,cgu.yaml | 2 +
arch/mips/ingenic/Kconfig | 5 +
drivers/clk/ingenic/Kconfig | 10 +
drivers/clk/ingenic/Makefile | 1 +
drivers/clk/ingenic/jz4755-cgu.c | 350 ++++++++++++++++++
.../dt-bindings/clock/ingenic,jz4755-cgu.h | 49 +++
6 files changed, 417 insertions(+)
create mode 100644 drivers/clk/ingenic/jz4755-cgu.c
create mode 100644 include/dt-bindings/clock/ingenic,jz4755-cgu.h
--
2.36.1
which is close to jz4725b because it is actually a low price
successor of the jz4755.
It has the same MIPS32r1 core with Xburst(R) extension
MXU version 1 release 2.
Signed-off-by: Siarhei Volkau <[email protected]>
---
arch/mips/ingenic/Kconfig | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/arch/mips/ingenic/Kconfig b/arch/mips/ingenic/Kconfig
index f595b339a..edd84cf13 100644
--- a/arch/mips/ingenic/Kconfig
+++ b/arch/mips/ingenic/Kconfig
@@ -4,6 +4,7 @@ config MACH_INGENIC_GENERIC
bool
select MACH_INGENIC
select MACH_JZ4740
+ select MACH_JZ4755
select MACH_JZ4725B
select MACH_JZ4770
select MACH_JZ4780
@@ -53,6 +54,10 @@ config MACH_JZ4740
bool
select SYS_HAS_CPU_MIPS32_R1
+config MACH_JZ4755
+ bool
+ select SYS_HAS_CPU_MIPS32_R1
+
config MACH_JZ4770
bool
select MIPS_CPU_SCACHE
--
2.36.1
Add support for the clocks provided by the CGU in the Ingenic JZ4755
SoC.
Signed-off-by: Siarhei Volkau <[email protected]>
---
drivers/clk/ingenic/Kconfig | 10 +
drivers/clk/ingenic/Makefile | 1 +
drivers/clk/ingenic/jz4755-cgu.c | 350 +++++++++++++++++++++++++++++++
3 files changed, 361 insertions(+)
create mode 100644 drivers/clk/ingenic/jz4755-cgu.c
diff --git a/drivers/clk/ingenic/Kconfig b/drivers/clk/ingenic/Kconfig
index 898f1bc47..f80ac4f29 100644
--- a/drivers/clk/ingenic/Kconfig
+++ b/drivers/clk/ingenic/Kconfig
@@ -15,6 +15,16 @@ config INGENIC_CGU_JZ4740
If building for a JZ4740 SoC, you want to say Y here.
+config INGENIC_CGU_JZ4755
+ bool "Ingenic JZ4755 CGU driver"
+ default MACH_JZ4755
+ select INGENIC_CGU_COMMON
+ help
+ Support the clocks provided by the CGU hardware on Ingenic JZ4755
+ and compatible SoCs.
+
+ If building for a JZ4755 SoC, you want to say Y here.
+
config INGENIC_CGU_JZ4725B
bool "Ingenic JZ4725B CGU driver"
default MACH_JZ4725B
diff --git a/drivers/clk/ingenic/Makefile b/drivers/clk/ingenic/Makefile
index 9edfaf461..81d8e23c2 100644
--- a/drivers/clk/ingenic/Makefile
+++ b/drivers/clk/ingenic/Makefile
@@ -1,6 +1,7 @@
# SPDX-License-Identifier: GPL-2.0-only
obj-$(CONFIG_INGENIC_CGU_COMMON) += cgu.o pm.o
obj-$(CONFIG_INGENIC_CGU_JZ4740) += jz4740-cgu.o
+obj-$(CONFIG_INGENIC_CGU_JZ4755) += jz4755-cgu.o
obj-$(CONFIG_INGENIC_CGU_JZ4725B) += jz4725b-cgu.o
obj-$(CONFIG_INGENIC_CGU_JZ4760) += jz4760-cgu.o
obj-$(CONFIG_INGENIC_CGU_JZ4770) += jz4770-cgu.o
diff --git a/drivers/clk/ingenic/jz4755-cgu.c b/drivers/clk/ingenic/jz4755-cgu.c
new file mode 100644
index 000000000..16728546a
--- /dev/null
+++ b/drivers/clk/ingenic/jz4755-cgu.c
@@ -0,0 +1,350 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Ingenic JZ4755 SoC CGU driver
+ * Heavily based on JZ4725b CGU driver
+ *
+ * Copyright (C) 2022 Siarhei Volkau
+ * Author: Siarhei Volkau <[email protected]>
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/delay.h>
+#include <linux/of.h>
+
+#include <dt-bindings/clock/ingenic,jz4755-cgu.h>
+
+#include "cgu.h"
+#include "pm.h"
+
+/* CGU register offsets */
+#define CGU_REG_CPCCR 0x00
+#define CGU_REG_LCR 0x04
+#define CGU_REG_CPPCR 0x10
+#define CGU_REG_CLKGR 0x20
+#define CGU_REG_OPCR 0x24
+#define CGU_REG_I2SCDR 0x60
+#define CGU_REG_LPCDR 0x64
+#define CGU_REG_MSCCDR 0x68
+#define CGU_REG_SSICDR 0x74
+#define CGU_REG_CIMCDR 0x7C
+
+/* bits within the LCR register */
+#define LCR_SLEEP BIT(0)
+
+static struct ingenic_cgu *cgu;
+
+static const s8 pll_od_encoding[4] = {
+ 0x0, 0x1, -1, 0x3,
+};
+
+static const u8 jz4755_cgu_cpccr_div_table[] = {
+ 1, 2, 3, 4, 6, 8,
+};
+
+static const u8 jz4755_cgu_pll_half_div_table[] = {
+ 2, 1,
+};
+
+static const struct ingenic_cgu_clk_info jz4755_cgu_clocks[] = {
+
+ /* External clocks */
+
+ [JZ4755_CLK_EXT] = { "ext", CGU_CLK_EXT },
+ [JZ4755_CLK_OSC32K] = { "osc32k", CGU_CLK_EXT },
+
+ [JZ4755_CLK_PLL] = {
+ "pll", CGU_CLK_PLL,
+ .parents = { JZ4755_CLK_EXT, -1, -1, -1 },
+ .pll = {
+ .reg = CGU_REG_CPPCR,
+ .rate_multiplier = 1,
+ .m_shift = 23,
+ .m_bits = 9,
+ .m_offset = 2,
+ .n_shift = 18,
+ .n_bits = 5,
+ .n_offset = 2,
+ .od_shift = 16,
+ .od_bits = 2,
+ .od_max = 4,
+ .od_encoding = pll_od_encoding,
+ .stable_bit = 10,
+ .bypass_reg = CGU_REG_CPPCR,
+ .bypass_bit = 9,
+ .enable_bit = 8,
+ },
+ },
+
+ /* Muxes & dividers */
+
+ [JZ4755_CLK_PLL_HALF] = {
+ "pll half", CGU_CLK_DIV,
+ .parents = { JZ4755_CLK_PLL, -1, -1, -1 },
+ .div = {
+ CGU_REG_CPCCR, 21, 1, 1, -1, -1, -1, 0,
+ jz4755_cgu_pll_half_div_table,
+ },
+ },
+
+ [JZ4755_CLK_EXT_HALF] = {
+ "ext half", CGU_CLK_DIV,
+ .parents = { JZ4755_CLK_EXT, -1, -1, -1 },
+ .div = {
+ CGU_REG_CPCCR, 30, 1, 1, -1, -1, -1, 0,
+ NULL,
+ },
+ },
+
+ [JZ4755_CLK_CCLK] = {
+ "cclk", CGU_CLK_DIV,
+ .parents = { JZ4755_CLK_PLL, -1, -1, -1 },
+ .div = {
+ CGU_REG_CPCCR, 0, 1, 4, 22, -1, -1, 0,
+ jz4755_cgu_cpccr_div_table,
+ },
+ },
+
+ [JZ4755_CLK_H0CLK] = {
+ "hclk", CGU_CLK_DIV,
+ .parents = { JZ4755_CLK_PLL, -1, -1, -1 },
+ .div = {
+ CGU_REG_CPCCR, 4, 1, 4, 22, -1, -1, 0,
+ jz4755_cgu_cpccr_div_table,
+ },
+ },
+
+ [JZ4755_CLK_PCLK] = {
+ "pclk", CGU_CLK_DIV,
+ .parents = { JZ4755_CLK_PLL, -1, -1, -1 },
+ .div = {
+ CGU_REG_CPCCR, 8, 1, 4, 22, -1, -1, 0,
+ jz4755_cgu_cpccr_div_table,
+ },
+ },
+
+ [JZ4755_CLK_MCLK] = {
+ "mclk", CGU_CLK_DIV,
+ .parents = { JZ4755_CLK_PLL, -1, -1, -1 },
+ .div = {
+ CGU_REG_CPCCR, 12, 1, 4, 22, -1, -1, 0,
+ jz4755_cgu_cpccr_div_table,
+ },
+ },
+
+ [JZ4755_CLK_H1CLK] = {
+ "h1clk", CGU_CLK_DIV,
+ .parents = { JZ4755_CLK_PLL, -1, -1, -1 },
+ .div = {
+ CGU_REG_CPCCR, 16, 1, 4, 22, -1, -1, 0,
+ jz4755_cgu_cpccr_div_table,
+ },
+ },
+
+ [JZ4755_CLK_UDC] = {
+ "udc", CGU_CLK_MUX | CGU_CLK_DIV | CGU_CLK_GATE,
+ .parents = { JZ4755_CLK_EXT_HALF, JZ4755_CLK_PLL_HALF, -1, -1 },
+ .mux = { CGU_REG_CPCCR, 29, 1 },
+ .div = { CGU_REG_CPCCR, 23, 1, 6, -1, -1, -1 },
+ .gate = { CGU_REG_CLKGR, 10 },
+ },
+
+ [JZ4755_CLK_LCD] = {
+ "lcd", CGU_CLK_DIV | CGU_CLK_GATE,
+ .parents = { JZ4755_CLK_PLL_HALF, -1, -1, -1 },
+ .div = { CGU_REG_LPCDR, 0, 1, 11, -1, -1, -1 },
+ .gate = { CGU_REG_CLKGR, 9 },
+ },
+
+ [JZ4755_CLK_MMC] = {
+ "mmc", CGU_CLK_DIV,
+ .parents = { JZ4755_CLK_PLL_HALF, -1, -1, -1 },
+ .div = { CGU_REG_MSCCDR, 0, 1, 5, -1, -1, -1 },
+ },
+
+ [JZ4755_CLK_I2S] = {
+ "i2s", CGU_CLK_MUX | CGU_CLK_DIV,
+ .parents = { JZ4755_CLK_EXT_HALF, JZ4755_CLK_PLL_HALF, -1, -1 },
+ .mux = { CGU_REG_CPCCR, 31, 1 },
+ .div = { CGU_REG_I2SCDR, 0, 1, 9, -1, -1, -1 },
+ },
+
+ [JZ4755_CLK_SPI] = {
+ "spi", CGU_CLK_DIV | CGU_CLK_GATE,
+ .parents = { JZ4755_CLK_PLL_HALF, -1, -1, -1 },
+ .div = { CGU_REG_SSICDR, 0, 1, 4, -1, -1, -1 },
+ .gate = { CGU_REG_CLKGR, 4 },
+ },
+
+ [JZ4755_CLK_TVE] = {
+ "tve", CGU_CLK_MUX | CGU_CLK_GATE,
+ .parents = { JZ4755_CLK_LCD, JZ4755_CLK_EXT, -1, -1 },
+ .mux = { CGU_REG_LPCDR, 31, 1 },
+ .gate = { CGU_REG_CLKGR, 18 },
+ },
+
+ [JZ4755_CLK_RTC] = {
+ "rtc", CGU_CLK_MUX | CGU_CLK_GATE,
+ .parents = { JZ4755_CLK_EXT512, JZ4755_CLK_OSC32K, -1, -1 },
+ .mux = { CGU_REG_OPCR, 2, 1},
+ .gate = { CGU_REG_CLKGR, 2 },
+ },
+
+ [JZ4755_CLK_CIM] = {
+ "cim", CGU_CLK_DIV | CGU_CLK_GATE,
+ .parents = { JZ4755_CLK_PLL_HALF, -1, -1, -1 },
+ .div = { CGU_REG_CIMCDR, 0, 1, 8, -1, -1, -1 },
+ .gate = { CGU_REG_CLKGR, 8 },
+ },
+
+ /* Gate-only clocks */
+
+ [JZ4755_CLK_UART0] = {
+ "uart0", CGU_CLK_GATE,
+ .parents = { JZ4755_CLK_EXT_HALF, -1, -1, -1 },
+ .gate = { CGU_REG_CLKGR, 0 },
+ },
+
+ [JZ4755_CLK_UART1] = {
+ "uart1", CGU_CLK_GATE,
+ .parents = { JZ4755_CLK_EXT_HALF, -1, -1, -1 },
+ .gate = { CGU_REG_CLKGR, 14 },
+ },
+
+ [JZ4755_CLK_UART2] = {
+ "uart2", CGU_CLK_GATE,
+ .parents = { JZ4755_CLK_EXT_HALF, -1, -1, -1 },
+ .gate = { CGU_REG_CLKGR, 15 },
+ },
+
+ [JZ4755_CLK_ADC] = {
+ "adc", CGU_CLK_GATE,
+ .parents = { JZ4755_CLK_EXT_HALF, -1, -1, -1 },
+ .gate = { CGU_REG_CLKGR, 7 },
+ },
+
+ [JZ4755_CLK_AIC] = {
+ "aic", CGU_CLK_GATE,
+ .parents = { JZ4755_CLK_I2S, -1, -1, -1 },
+ .gate = { CGU_REG_CLKGR, 5 },
+ },
+
+ [JZ4755_CLK_I2C] = {
+ "i2c", CGU_CLK_GATE,
+ .parents = { JZ4755_CLK_EXT_HALF, -1, -1, -1 },
+ .gate = { CGU_REG_CLKGR, 3 },
+ },
+
+ [JZ4755_CLK_BCH] = {
+ "bch", CGU_CLK_GATE,
+ .parents = { JZ4755_CLK_MCLK/* not sure */, -1, -1, -1 },
+ .gate = { CGU_REG_CLKGR, 11 },
+ },
+
+ [JZ4755_CLK_TCU] = {
+ "tcu", CGU_CLK_GATE,
+ .parents = { JZ4755_CLK_EXT, -1, -1, -1 },
+ .gate = { CGU_REG_CLKGR, 1 },
+ },
+
+ [JZ4755_CLK_DMA] = {
+ "dma", CGU_CLK_GATE,
+ .parents = { JZ4755_CLK_PCLK, -1, -1, -1 },
+ .gate = { CGU_REG_CLKGR, 12 },
+ },
+
+ [JZ4755_CLK_MMC0] = {
+ "mmc0", CGU_CLK_GATE,
+ .parents = { JZ4755_CLK_MMC, -1, -1, -1 },
+ .gate = { CGU_REG_CLKGR, 6 },
+ },
+
+ [JZ4755_CLK_MMC1] = {
+ "mmc1", CGU_CLK_GATE,
+ .parents = { JZ4755_CLK_MMC, -1, -1, -1 },
+ .gate = { CGU_REG_CLKGR, 16 },
+ },
+
+ [JZ4755_CLK_AUX_CPU] = {
+ "aux_cpu", CGU_CLK_GATE,
+ .parents = { JZ4755_CLK_H1CLK, -1, -1, -1 },
+ .gate = { CGU_REG_CLKGR, 24 },
+ },
+
+ [JZ4755_CLK_AHB1] = {
+ "ahb1", CGU_CLK_GATE,
+ .parents = { JZ4755_CLK_H1CLK, -1, -1, -1 },
+ .gate = { CGU_REG_CLKGR, 23 },
+ },
+
+ [JZ4755_CLK_IDCT] = {
+ "idct", CGU_CLK_GATE,
+ .parents = { JZ4755_CLK_H1CLK, -1, -1, -1 },
+ .gate = { CGU_REG_CLKGR, 22 },
+ },
+
+ [JZ4755_CLK_DB] = {
+ "db", CGU_CLK_GATE,
+ .parents = { JZ4755_CLK_H1CLK, -1, -1, -1 },
+ .gate = { CGU_REG_CLKGR, 21 },
+ },
+
+ [JZ4755_CLK_ME] = {
+ "me", CGU_CLK_GATE,
+ .parents = { JZ4755_CLK_H1CLK, -1, -1, -1 },
+ .gate = { CGU_REG_CLKGR, 20 },
+ },
+
+ [JZ4755_CLK_MC] = {
+ "mc", CGU_CLK_GATE,
+ .parents = { JZ4755_CLK_H1CLK, -1, -1, -1 },
+ .gate = { CGU_REG_CLKGR, 19 },
+ },
+
+ [JZ4755_CLK_TSSI] = {
+ "tssi", CGU_CLK_GATE,
+ .parents = { JZ4755_CLK_EXT_HALF/* not sure */, -1, -1, -1 },
+ .gate = { CGU_REG_CLKGR, 17 },
+ },
+
+ [JZ4755_CLK_IPU] = {
+ "ipu", CGU_CLK_GATE,
+ .parents = { JZ4755_CLK_PLL_HALF/* not sure */, -1, -1, -1 },
+ .gate = { CGU_REG_CLKGR, 13 },
+ },
+
+ [JZ4755_CLK_EXT512] = {
+ "ext/512", CGU_CLK_FIXDIV,
+ .parents = { JZ4755_CLK_EXT },
+
+ /* JZ4725b doc calls it EXT512, but it seems to be /256...
+ * Not sure if it applied to JZ4755 too, and which actual
+ * source is used EXT or EXT_HALF
+ */
+ .fixdiv = { 256 },
+ },
+
+ [JZ4755_CLK_UDC_PHY] = {
+ "udc_phy", CGU_CLK_GATE,
+ .parents = { JZ4755_CLK_EXT_HALF, -1, -1, -1 },
+ .gate = { CGU_REG_OPCR, 6, true },
+ },
+};
+
+static void __init jz4755_cgu_init(struct device_node *np)
+{
+ int retval;
+
+ cgu = ingenic_cgu_new(jz4755_cgu_clocks,
+ ARRAY_SIZE(jz4755_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__);
+
+ ingenic_cgu_register_syscore_ops(cgu);
+}
+CLK_OF_DECLARE_DRIVER(jz4755_cgu, "ingenic,jz4755-cgu", jz4755_cgu_init);
--
2.36.1
This will be used from the devicetree bindings to specify the clocks
that should be obtained from the jz4755-cgu driver.
Signed-off-by: Siarhei Volkau <[email protected]>
---
.../dt-bindings/clock/ingenic,jz4755-cgu.h | 49 +++++++++++++++++++
1 file changed, 49 insertions(+)
create mode 100644 include/dt-bindings/clock/ingenic,jz4755-cgu.h
diff --git a/include/dt-bindings/clock/ingenic,jz4755-cgu.h b/include/dt-bindings/clock/ingenic,jz4755-cgu.h
new file mode 100644
index 000000000..1ac13d61b
--- /dev/null
+++ b/include/dt-bindings/clock/ingenic,jz4755-cgu.h
@@ -0,0 +1,49 @@
+/* SPDX-License-Identifier: (GPL-2.0+ OR BSD-2-Clause) */
+/*
+ * This header provides clock numbers for the ingenic,jz4755-cgu DT binding.
+ */
+
+#ifndef __DT_BINDINGS_CLOCK_JZ4755_CGU_H__
+#define __DT_BINDINGS_CLOCK_JZ4755_CGU_H__
+
+#define JZ4755_CLK_EXT 0
+#define JZ4755_CLK_OSC32K 1
+#define JZ4755_CLK_PLL 2
+#define JZ4755_CLK_PLL_HALF 3
+#define JZ4755_CLK_EXT_HALF 4
+#define JZ4755_CLK_CCLK 5
+#define JZ4755_CLK_H0CLK 6
+#define JZ4755_CLK_PCLK 7
+#define JZ4755_CLK_MCLK 8
+#define JZ4755_CLK_H1CLK 9
+#define JZ4755_CLK_UDC 10
+#define JZ4755_CLK_LCD 11
+#define JZ4755_CLK_UART0 12
+#define JZ4755_CLK_UART1 13
+#define JZ4755_CLK_UART2 14
+#define JZ4755_CLK_DMA 15
+#define JZ4755_CLK_MMC 16
+#define JZ4755_CLK_MMC0 17
+#define JZ4755_CLK_MMC1 18
+#define JZ4755_CLK_EXT512 19
+#define JZ4755_CLK_RTC 20
+#define JZ4755_CLK_UDC_PHY 21
+#define JZ4755_CLK_I2S 22
+#define JZ4755_CLK_SPI 23
+#define JZ4755_CLK_AIC 24
+#define JZ4755_CLK_ADC 25
+#define JZ4755_CLK_TCU 26
+#define JZ4755_CLK_BCH 27
+#define JZ4755_CLK_I2C 28
+#define JZ4755_CLK_TVE 29
+#define JZ4755_CLK_CIM 30
+#define JZ4755_CLK_AUX_CPU 31
+#define JZ4755_CLK_AHB1 32
+#define JZ4755_CLK_IDCT 33
+#define JZ4755_CLK_DB 34
+#define JZ4755_CLK_ME 35
+#define JZ4755_CLK_MC 36
+#define JZ4755_CLK_TSSI 37
+#define JZ4755_CLK_IPU 38
+
+#endif /* __DT_BINDINGS_CLOCK_JZ4755_CGU_H__ */
--
2.36.1
Hi Siarhei,
Le dim., oct. 16 2022 at 18:01:06 +0300, Siarhei Volkau
<[email protected]> a ?crit :
> which is close to jz4725b because it is actually a low price
> successor of the jz4755.
> It has the same MIPS32r1 core with Xburst(R) extension
> MXU version 1 release 2.
>
> Signed-off-by: Siarhei Volkau <[email protected]>
This patch doesn't really belong in the CGU patchset. It should go
through the MIPS tree.
I see why you include it, but you do not need to have the MACH_JZ4755
symbol defined anywhere for the "default MACH_JZ4755" to work, it will
just default to false until the patchset that adds JZ4755 support is
merged in the MIPS tree.
Cheers,
-Paul
> ---
> arch/mips/ingenic/Kconfig | 5 +++++
> 1 file changed, 5 insertions(+)
>
> diff --git a/arch/mips/ingenic/Kconfig b/arch/mips/ingenic/Kconfig
> index f595b339a..edd84cf13 100644
> --- a/arch/mips/ingenic/Kconfig
> +++ b/arch/mips/ingenic/Kconfig
> @@ -4,6 +4,7 @@ config MACH_INGENIC_GENERIC
> bool
> select MACH_INGENIC
> select MACH_JZ4740
> + select MACH_JZ4755
> select MACH_JZ4725B
> select MACH_JZ4770
> select MACH_JZ4780
> @@ -53,6 +54,10 @@ config MACH_JZ4740
> bool
> select SYS_HAS_CPU_MIPS32_R1
>
> +config MACH_JZ4755
> + bool
> + select SYS_HAS_CPU_MIPS32_R1
> +
> config MACH_JZ4770
> bool
> select MIPS_CPU_SCACHE
> --
> 2.36.1
>
Hi Siarhei,
Le dim., oct. 16 2022 at 18:01:09 +0300, Siarhei Volkau
<[email protected]> a ?crit :
> Add support for the clocks provided by the CGU in the Ingenic JZ4755
> SoC.
>
> Signed-off-by: Siarhei Volkau <[email protected]>
> ---
> drivers/clk/ingenic/Kconfig | 10 +
> drivers/clk/ingenic/Makefile | 1 +
> drivers/clk/ingenic/jz4755-cgu.c | 350
> +++++++++++++++++++++++++++++++
> 3 files changed, 361 insertions(+)
> create mode 100644 drivers/clk/ingenic/jz4755-cgu.c
>
> diff --git a/drivers/clk/ingenic/Kconfig b/drivers/clk/ingenic/Kconfig
> index 898f1bc47..f80ac4f29 100644
> --- a/drivers/clk/ingenic/Kconfig
> +++ b/drivers/clk/ingenic/Kconfig
> @@ -15,6 +15,16 @@ config INGENIC_CGU_JZ4740
>
> If building for a JZ4740 SoC, you want to say Y here.
>
> +config INGENIC_CGU_JZ4755
> + bool "Ingenic JZ4755 CGU driver"
> + default MACH_JZ4755
> + select INGENIC_CGU_COMMON
> + help
> + Support the clocks provided by the CGU hardware on Ingenic JZ4755
> + and compatible SoCs.
> +
> + If building for a JZ4755 SoC, you want to say Y here.
> +
> config INGENIC_CGU_JZ4725B
> bool "Ingenic JZ4725B CGU driver"
> default MACH_JZ4725B
> diff --git a/drivers/clk/ingenic/Makefile
> b/drivers/clk/ingenic/Makefile
> index 9edfaf461..81d8e23c2 100644
> --- a/drivers/clk/ingenic/Makefile
> +++ b/drivers/clk/ingenic/Makefile
> @@ -1,6 +1,7 @@
> # SPDX-License-Identifier: GPL-2.0-only
> obj-$(CONFIG_INGENIC_CGU_COMMON) += cgu.o pm.o
> obj-$(CONFIG_INGENIC_CGU_JZ4740) += jz4740-cgu.o
> +obj-$(CONFIG_INGENIC_CGU_JZ4755) += jz4755-cgu.o
> obj-$(CONFIG_INGENIC_CGU_JZ4725B) += jz4725b-cgu.o
> obj-$(CONFIG_INGENIC_CGU_JZ4760) += jz4760-cgu.o
> obj-$(CONFIG_INGENIC_CGU_JZ4770) += jz4770-cgu.o
> diff --git a/drivers/clk/ingenic/jz4755-cgu.c
> b/drivers/clk/ingenic/jz4755-cgu.c
> new file mode 100644
> index 000000000..16728546a
> --- /dev/null
> +++ b/drivers/clk/ingenic/jz4755-cgu.c
> @@ -0,0 +1,350 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Ingenic JZ4755 SoC CGU driver
> + * Heavily based on JZ4725b CGU driver
> + *
> + * Copyright (C) 2022 Siarhei Volkau
> + * Author: Siarhei Volkau <[email protected]>
> + */
> +
> +#include <linux/clk-provider.h>
> +#include <linux/delay.h>
> +#include <linux/of.h>
> +
> +#include <dt-bindings/clock/ingenic,jz4755-cgu.h>
> +
> +#include "cgu.h"
> +#include "pm.h"
> +
> +/* CGU register offsets */
> +#define CGU_REG_CPCCR 0x00
> +#define CGU_REG_LCR 0x04
> +#define CGU_REG_CPPCR 0x10
> +#define CGU_REG_CLKGR 0x20
> +#define CGU_REG_OPCR 0x24
> +#define CGU_REG_I2SCDR 0x60
> +#define CGU_REG_LPCDR 0x64
> +#define CGU_REG_MSCCDR 0x68
> +#define CGU_REG_SSICDR 0x74
> +#define CGU_REG_CIMCDR 0x7C
> +
> +/* bits within the LCR register */
> +#define LCR_SLEEP BIT(0)
> +
> +static struct ingenic_cgu *cgu;
> +
> +static const s8 pll_od_encoding[4] = {
> + 0x0, 0x1, -1, 0x3,
> +};
> +
> +static const u8 jz4755_cgu_cpccr_div_table[] = {
> + 1, 2, 3, 4, 6, 8,
> +};
> +
> +static const u8 jz4755_cgu_pll_half_div_table[] = {
> + 2, 1,
> +};
> +
> +static const struct ingenic_cgu_clk_info jz4755_cgu_clocks[] = {
> +
> + /* External clocks */
> +
> + [JZ4755_CLK_EXT] = { "ext", CGU_CLK_EXT },
> + [JZ4755_CLK_OSC32K] = { "osc32k", CGU_CLK_EXT },
> +
> + [JZ4755_CLK_PLL] = {
> + "pll", CGU_CLK_PLL,
> + .parents = { JZ4755_CLK_EXT, -1, -1, -1 },
> + .pll = {
> + .reg = CGU_REG_CPPCR,
> + .rate_multiplier = 1,
> + .m_shift = 23,
> + .m_bits = 9,
> + .m_offset = 2,
> + .n_shift = 18,
> + .n_bits = 5,
> + .n_offset = 2,
> + .od_shift = 16,
> + .od_bits = 2,
> + .od_max = 4,
> + .od_encoding = pll_od_encoding,
> + .stable_bit = 10,
> + .bypass_reg = CGU_REG_CPPCR,
> + .bypass_bit = 9,
> + .enable_bit = 8,
> + },
> + },
> +
> + /* Muxes & dividers */
> +
> + [JZ4755_CLK_PLL_HALF] = {
> + "pll half", CGU_CLK_DIV,
> + .parents = { JZ4755_CLK_PLL, -1, -1, -1 },
> + .div = {
> + CGU_REG_CPCCR, 21, 1, 1, -1, -1, -1, 0,
> + jz4755_cgu_pll_half_div_table,
> + },
> + },
> +
> + [JZ4755_CLK_EXT_HALF] = {
> + "ext half", CGU_CLK_DIV,
> + .parents = { JZ4755_CLK_EXT, -1, -1, -1 },
> + .div = {
> + CGU_REG_CPCCR, 30, 1, 1, -1, -1, -1, 0,
> + NULL,
> + },
> + },
> +
> + [JZ4755_CLK_CCLK] = {
> + "cclk", CGU_CLK_DIV,
> + .parents = { JZ4755_CLK_PLL, -1, -1, -1 },
> + .div = {
> + CGU_REG_CPCCR, 0, 1, 4, 22, -1, -1, 0,
> + jz4755_cgu_cpccr_div_table,
> + },
> + },
> +
> + [JZ4755_CLK_H0CLK] = {
> + "hclk", CGU_CLK_DIV,
> + .parents = { JZ4755_CLK_PLL, -1, -1, -1 },
> + .div = {
> + CGU_REG_CPCCR, 4, 1, 4, 22, -1, -1, 0,
> + jz4755_cgu_cpccr_div_table,
> + },
> + },
> +
> + [JZ4755_CLK_PCLK] = {
> + "pclk", CGU_CLK_DIV,
> + .parents = { JZ4755_CLK_PLL, -1, -1, -1 },
> + .div = {
> + CGU_REG_CPCCR, 8, 1, 4, 22, -1, -1, 0,
> + jz4755_cgu_cpccr_div_table,
> + },
> + },
> +
> + [JZ4755_CLK_MCLK] = {
> + "mclk", CGU_CLK_DIV,
> + .parents = { JZ4755_CLK_PLL, -1, -1, -1 },
> + .div = {
> + CGU_REG_CPCCR, 12, 1, 4, 22, -1, -1, 0,
> + jz4755_cgu_cpccr_div_table,
> + },
> + },
> +
> + [JZ4755_CLK_H1CLK] = {
> + "h1clk", CGU_CLK_DIV,
> + .parents = { JZ4755_CLK_PLL, -1, -1, -1 },
> + .div = {
> + CGU_REG_CPCCR, 16, 1, 4, 22, -1, -1, 0,
> + jz4755_cgu_cpccr_div_table,
> + },
> + },
> +
> + [JZ4755_CLK_UDC] = {
> + "udc", CGU_CLK_MUX | CGU_CLK_DIV | CGU_CLK_GATE,
> + .parents = { JZ4755_CLK_EXT_HALF, JZ4755_CLK_PLL_HALF, -1, -1 },
> + .mux = { CGU_REG_CPCCR, 29, 1 },
> + .div = { CGU_REG_CPCCR, 23, 1, 6, -1, -1, -1 },
> + .gate = { CGU_REG_CLKGR, 10 },
> + },
> +
> + [JZ4755_CLK_LCD] = {
> + "lcd", CGU_CLK_DIV | CGU_CLK_GATE,
> + .parents = { JZ4755_CLK_PLL_HALF, -1, -1, -1 },
> + .div = { CGU_REG_LPCDR, 0, 1, 11, -1, -1, -1 },
> + .gate = { CGU_REG_CLKGR, 9 },
> + },
> +
> + [JZ4755_CLK_MMC] = {
> + "mmc", CGU_CLK_DIV,
> + .parents = { JZ4755_CLK_PLL_HALF, -1, -1, -1 },
> + .div = { CGU_REG_MSCCDR, 0, 1, 5, -1, -1, -1 },
> + },
> +
> + [JZ4755_CLK_I2S] = {
> + "i2s", CGU_CLK_MUX | CGU_CLK_DIV,
> + .parents = { JZ4755_CLK_EXT_HALF, JZ4755_CLK_PLL_HALF, -1, -1 },
> + .mux = { CGU_REG_CPCCR, 31, 1 },
> + .div = { CGU_REG_I2SCDR, 0, 1, 9, -1, -1, -1 },
> + },
> +
> + [JZ4755_CLK_SPI] = {
> + "spi", CGU_CLK_DIV | CGU_CLK_GATE,
> + .parents = { JZ4755_CLK_PLL_HALF, -1, -1, -1 },
> + .div = { CGU_REG_SSICDR, 0, 1, 4, -1, -1, -1 },
> + .gate = { CGU_REG_CLKGR, 4 },
> + },
> +
> + [JZ4755_CLK_TVE] = {
> + "tve", CGU_CLK_MUX | CGU_CLK_GATE,
> + .parents = { JZ4755_CLK_LCD, JZ4755_CLK_EXT, -1, -1 },
> + .mux = { CGU_REG_LPCDR, 31, 1 },
> + .gate = { CGU_REG_CLKGR, 18 },
> + },
> +
> + [JZ4755_CLK_RTC] = {
> + "rtc", CGU_CLK_MUX | CGU_CLK_GATE,
> + .parents = { JZ4755_CLK_EXT512, JZ4755_CLK_OSC32K, -1, -1 },
> + .mux = { CGU_REG_OPCR, 2, 1},
> + .gate = { CGU_REG_CLKGR, 2 },
> + },
> +
> + [JZ4755_CLK_CIM] = {
> + "cim", CGU_CLK_DIV | CGU_CLK_GATE,
> + .parents = { JZ4755_CLK_PLL_HALF, -1, -1, -1 },
> + .div = { CGU_REG_CIMCDR, 0, 1, 8, -1, -1, -1 },
> + .gate = { CGU_REG_CLKGR, 8 },
> + },
> +
> + /* Gate-only clocks */
> +
> + [JZ4755_CLK_UART0] = {
> + "uart0", CGU_CLK_GATE,
> + .parents = { JZ4755_CLK_EXT_HALF, -1, -1, -1 },
> + .gate = { CGU_REG_CLKGR, 0 },
> + },
> +
> + [JZ4755_CLK_UART1] = {
> + "uart1", CGU_CLK_GATE,
> + .parents = { JZ4755_CLK_EXT_HALF, -1, -1, -1 },
> + .gate = { CGU_REG_CLKGR, 14 },
> + },
> +
> + [JZ4755_CLK_UART2] = {
> + "uart2", CGU_CLK_GATE,
> + .parents = { JZ4755_CLK_EXT_HALF, -1, -1, -1 },
> + .gate = { CGU_REG_CLKGR, 15 },
> + },
> +
> + [JZ4755_CLK_ADC] = {
> + "adc", CGU_CLK_GATE,
> + .parents = { JZ4755_CLK_EXT_HALF, -1, -1, -1 },
> + .gate = { CGU_REG_CLKGR, 7 },
> + },
> +
> + [JZ4755_CLK_AIC] = {
> + "aic", CGU_CLK_GATE,
> + .parents = { JZ4755_CLK_I2S, -1, -1, -1 },
Wrong parent here, should be JZ4755_CLK_EXT_HALF.
> + .gate = { CGU_REG_CLKGR, 5 },
> + },
> +
> + [JZ4755_CLK_I2C] = {
> + "i2c", CGU_CLK_GATE,
> + .parents = { JZ4755_CLK_EXT_HALF, -1, -1, -1 },
> + .gate = { CGU_REG_CLKGR, 3 },
> + },
> +
> + [JZ4755_CLK_BCH] = {
> + "bch", CGU_CLK_GATE,
> + .parents = { JZ4755_CLK_MCLK/* not sure */, -1, -1, -1 },
> + .gate = { CGU_REG_CLKGR, 11 },
> + },
> +
> + [JZ4755_CLK_TCU] = {
> + "tcu", CGU_CLK_GATE,
> + .parents = { JZ4755_CLK_EXT, -1, -1, -1 },
> + .gate = { CGU_REG_CLKGR, 1 },
> + },
> +
> + [JZ4755_CLK_DMA] = {
> + "dma", CGU_CLK_GATE,
> + .parents = { JZ4755_CLK_PCLK, -1, -1, -1 },
> + .gate = { CGU_REG_CLKGR, 12 },
> + },
> +
> + [JZ4755_CLK_MMC0] = {
> + "mmc0", CGU_CLK_GATE,
> + .parents = { JZ4755_CLK_MMC, -1, -1, -1 },
> + .gate = { CGU_REG_CLKGR, 6 },
> + },
> +
> + [JZ4755_CLK_MMC1] = {
> + "mmc1", CGU_CLK_GATE,
> + .parents = { JZ4755_CLK_MMC, -1, -1, -1 },
> + .gate = { CGU_REG_CLKGR, 16 },
> + },
> +
> + [JZ4755_CLK_AUX_CPU] = {
> + "aux_cpu", CGU_CLK_GATE,
> + .parents = { JZ4755_CLK_H1CLK, -1, -1, -1 },
> + .gate = { CGU_REG_CLKGR, 24 },
> + },
> +
> + [JZ4755_CLK_AHB1] = {
> + "ahb1", CGU_CLK_GATE,
> + .parents = { JZ4755_CLK_H1CLK, -1, -1, -1 },
> + .gate = { CGU_REG_CLKGR, 23 },
> + },
> +
> + [JZ4755_CLK_IDCT] = {
> + "idct", CGU_CLK_GATE,
> + .parents = { JZ4755_CLK_H1CLK, -1, -1, -1 },
> + .gate = { CGU_REG_CLKGR, 22 },
> + },
> +
> + [JZ4755_CLK_DB] = {
> + "db", CGU_CLK_GATE,
> + .parents = { JZ4755_CLK_H1CLK, -1, -1, -1 },
> + .gate = { CGU_REG_CLKGR, 21 },
> + },
> +
> + [JZ4755_CLK_ME] = {
> + "me", CGU_CLK_GATE,
> + .parents = { JZ4755_CLK_H1CLK, -1, -1, -1 },
> + .gate = { CGU_REG_CLKGR, 20 },
> + },
> +
> + [JZ4755_CLK_MC] = {
> + "mc", CGU_CLK_GATE,
> + .parents = { JZ4755_CLK_H1CLK, -1, -1, -1 },
> + .gate = { CGU_REG_CLKGR, 19 },
> + },
> +
> + [JZ4755_CLK_TSSI] = {
> + "tssi", CGU_CLK_GATE,
> + .parents = { JZ4755_CLK_EXT_HALF/* not sure */, -1, -1, -1 },
> + .gate = { CGU_REG_CLKGR, 17 },
> + },
> +
> + [JZ4755_CLK_IPU] = {
> + "ipu", CGU_CLK_GATE,
> + .parents = { JZ4755_CLK_PLL_HALF/* not sure */, -1, -1, -1 },
> + .gate = { CGU_REG_CLKGR, 13 },
> + },
> +
> + [JZ4755_CLK_EXT512] = {
> + "ext/512", CGU_CLK_FIXDIV,
> + .parents = { JZ4755_CLK_EXT },
> +
> + /* JZ4725b doc calls it EXT512, but it seems to be /256...
> + * Not sure if it applied to JZ4755 too, and which actual
> + * source is used EXT or EXT_HALF
> + */
Well it would be good to know. It's easy to verify though. Parent the
watchdog clock to EXT/512, configure it for e.g. 5 seconds, if it shuts
down in 10 seconds, it's a /256 divider.
Cheers,
-Paul
> + .fixdiv = { 256 },
> + },
> +
> + [JZ4755_CLK_UDC_PHY] = {
> + "udc_phy", CGU_CLK_GATE,
> + .parents = { JZ4755_CLK_EXT_HALF, -1, -1, -1 },
> + .gate = { CGU_REG_OPCR, 6, true },
> + },
> +};
> +
> +static void __init jz4755_cgu_init(struct device_node *np)
> +{
> + int retval;
> +
> + cgu = ingenic_cgu_new(jz4755_cgu_clocks,
> + ARRAY_SIZE(jz4755_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__);
> +
> + ingenic_cgu_register_syscore_ops(cgu);
> +}
> +CLK_OF_DECLARE_DRIVER(jz4755_cgu, "ingenic,jz4755-cgu",
> jz4755_cgu_init);
> --
> 2.36.1
>
пн, 17 окт. 2022 г. в 12:10, Paul Cercueil <[email protected]>:
> I see why you include it, but you do not need to have the MACH_JZ4755
> symbol defined anywhere for the "default MACH_JZ4755" to work, it will
> just default to false until the patchset that adds JZ4755 support is
> merged in the MIPS tree.
Thank you for the clarification, Paul.
Will be done in the next version.
пн, 17 окт. 2022 г. в 12:24, Paul Cercueil <[email protected]>:
> > + [JZ4755_CLK_AIC] = {
> > + "aic", CGU_CLK_GATE,
> > + .parents = { JZ4755_CLK_I2S, -1, -1, -1 },
>
> Wrong parent here, should be JZ4755_CLK_EXT_HALF.
I don't agree, see Figure 20-13 in the JZ4755 PM.
> Well it would be good to know...
Indeed, I will try to figure it out.
Le lun., oct. 17 2022 at 20:10:56 +0300, Siarhei Volkau
<[email protected]> a écrit :
> пн, 17 окт. 2022 г. в 12:24, Paul Cercueil
> <[email protected]>:
>
>> > + [JZ4755_CLK_AIC] = {
>> > + "aic", CGU_CLK_GATE,
>> > + .parents = { JZ4755_CLK_I2S, -1, -1, -1 },
>>
>> Wrong parent here, should be JZ4755_CLK_EXT_HALF.
>
> I don't agree, see Figure 20-13 in the JZ4755 PM.
20-13 describes the I2S clock, no?
AIC clock's parent is EXT/2 according to the diagram in 8.2.2.
>> Well it would be good to know...
>
> Indeed, I will try to figure it out.
Cheers,
-Paul
пн, 17 окт. 2022 г. в 20:24, Paul Cercueil <[email protected]>:
>
>
>
> Le lun., oct. 17 2022 at 20:10:56 +0300, Siarhei Volkau
> <[email protected]> a écrit :
> > пн, 17 окт. 2022 г. в 12:24, Paul Cercueil
> > <[email protected]>:
> >
> >> > + [JZ4755_CLK_AIC] = {
> >> > + "aic", CGU_CLK_GATE,
> >> > + .parents = { JZ4755_CLK_I2S, -1, -1, -1 },
> >>
> >> Wrong parent here, should be JZ4755_CLK_EXT_HALF.
> >
> > I don't agree, see Figure 20-13 in the JZ4755 PM.
>
> 20-13 describes the I2S clock, no?
See 20.4.9 Serial Audio Clocks and Sampling Frequencies.
It stated that: "For internal CODEC ... CODEC needs a 12MHz
clock from CPM called SYS_CLK ...", but SYS_CLK is described
only in the I2S Controller section. I assume it is the same clock.
>
> AIC clock's parent is EXT/2 according to the diagram in 8.2.2.
>
It's a bit cryptic manual, who knows how it's done in the HW.
I observed that codec runs on a desired sample rate only when PLL
equals 432 or 216 MHz, but SYS_CLK is definitely configured to be
12MHz - from EXTCLK. On other PLL frequencies it is lower by
2-4% than expected. That isn't observed on JZ4725B.
> >> Well it would be good to know...
> >
> > Indeed, I will try to figure it out.
>
> Cheers,
> -Paul
>
>
Hi Siarhei,
Le lun., oct. 17 2022 at 21:07:47 +0300, Siarhei Volkau
<[email protected]> a écrit :
> пн, 17 окт. 2022 г. в 20:24, Paul Cercueil
> <[email protected]>:
>>
>>
>>
>> Le lun., oct. 17 2022 at 20:10:56 +0300, Siarhei Volkau
>> <[email protected]> a écrit :
>> > пн, 17 окт. 2022 г. в 12:24, Paul Cercueil
>> > <[email protected]>:
>> >
>> >> > + [JZ4755_CLK_AIC] = {
>> >> > + "aic", CGU_CLK_GATE,
>> >> > + .parents = { JZ4755_CLK_I2S, -1, -1, -1 },
>> >>
>> >> Wrong parent here, should be JZ4755_CLK_EXT_HALF.
>> >
>> > I don't agree, see Figure 20-13 in the JZ4755 PM.
>>
>> 20-13 describes the I2S clock, no?
>
> See 20.4.9 Serial Audio Clocks and Sampling Frequencies.
> It stated that: "For internal CODEC ... CODEC needs a 12MHz
> clock from CPM called SYS_CLK ...", but SYS_CLK is described
> only in the I2S Controller section. I assume it is the same clock.
Yes, and your SYS_CLK is the I2S clock, not the AIC clock.
>>
>> AIC clock's parent is EXT/2 according to the diagram in 8.2.2.
>>
>
> It's a bit cryptic manual, who knows how it's done in the HW.
> I observed that codec runs on a desired sample rate only when PLL
> equals 432 or 216 MHz, but SYS_CLK is definitely configured to be
> 12MHz - from EXTCLK. On other PLL frequencies it is lower by
> 2-4% than expected. That isn't observed on JZ4725B.
The audio codec supplies SYS_CLK to the controller, not the other way
around. Parent the I2S clock to EXT/2 (which is 12 MHz) and it should
work fine, independently of the PLL.
The AIC clock does not drive anything, it only "powers" the AIC module.
It should be parented only to EXT/2, similar to what's done in every
other CGU driver.
Cheers,
-Paul