All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/4] clk: meson: axg: add clocks for MIPI-DSI support
@ 2020-09-07  9:38 ` Neil Armstrong
  0 siblings, 0 replies; 30+ messages in thread
From: Neil Armstrong @ 2020-09-07  9:38 UTC (permalink / raw)
  To: jbrunet
  Cc: linux-amlogic, linux-clk, linux-arm-kernel, linux-kernel, Neil Armstrong

This adds the VPU & VAPB clocks along the MIPI DSI Host clock.

The clock scheme is based on the GXBB & G12A VPU clocks, with a different CTS
clock output used for MIPI-DSI.

Neil Armstrong (4):
  dt-bindings: clk: axg-clkc: add Video Clocks
  dt-bindings: clk: axg-clkc: add MIPI DSI Host clock binding
  clk: meson: axg: add Video Clocks
  clk: meson: axg: add MIPI DSI Host clock

 drivers/clk/meson/axg.c              | 840 +++++++++++++++++++++++++++
 drivers/clk/meson/axg.h              |  23 +-
 include/dt-bindings/clock/axg-clkc.h |  25 +
 3 files changed, 887 insertions(+), 1 deletion(-)

-- 
2.22.0


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

* [PATCH 0/4] clk: meson: axg: add clocks for MIPI-DSI support
@ 2020-09-07  9:38 ` Neil Armstrong
  0 siblings, 0 replies; 30+ messages in thread
From: Neil Armstrong @ 2020-09-07  9:38 UTC (permalink / raw)
  To: jbrunet
  Cc: linux-amlogic, Neil Armstrong, linux-clk, linux-arm-kernel, linux-kernel

This adds the VPU & VAPB clocks along the MIPI DSI Host clock.

The clock scheme is based on the GXBB & G12A VPU clocks, with a different CTS
clock output used for MIPI-DSI.

Neil Armstrong (4):
  dt-bindings: clk: axg-clkc: add Video Clocks
  dt-bindings: clk: axg-clkc: add MIPI DSI Host clock binding
  clk: meson: axg: add Video Clocks
  clk: meson: axg: add MIPI DSI Host clock

 drivers/clk/meson/axg.c              | 840 +++++++++++++++++++++++++++
 drivers/clk/meson/axg.h              |  23 +-
 include/dt-bindings/clock/axg-clkc.h |  25 +
 3 files changed, 887 insertions(+), 1 deletion(-)

-- 
2.22.0


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [PATCH 0/4] clk: meson: axg: add clocks for MIPI-DSI support
@ 2020-09-07  9:38 ` Neil Armstrong
  0 siblings, 0 replies; 30+ messages in thread
From: Neil Armstrong @ 2020-09-07  9:38 UTC (permalink / raw)
  To: jbrunet
  Cc: linux-amlogic, Neil Armstrong, linux-clk, linux-arm-kernel, linux-kernel

This adds the VPU & VAPB clocks along the MIPI DSI Host clock.

The clock scheme is based on the GXBB & G12A VPU clocks, with a different CTS
clock output used for MIPI-DSI.

Neil Armstrong (4):
  dt-bindings: clk: axg-clkc: add Video Clocks
  dt-bindings: clk: axg-clkc: add MIPI DSI Host clock binding
  clk: meson: axg: add Video Clocks
  clk: meson: axg: add MIPI DSI Host clock

 drivers/clk/meson/axg.c              | 840 +++++++++++++++++++++++++++
 drivers/clk/meson/axg.h              |  23 +-
 include/dt-bindings/clock/axg-clkc.h |  25 +
 3 files changed, 887 insertions(+), 1 deletion(-)

-- 
2.22.0


_______________________________________________
linux-amlogic mailing list
linux-amlogic@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-amlogic

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

* [PATCH 1/4] dt-bindings: clk: axg-clkc: add Video Clocks
  2020-09-07  9:38 ` Neil Armstrong
  (?)
@ 2020-09-07  9:38   ` Neil Armstrong
  -1 siblings, 0 replies; 30+ messages in thread
From: Neil Armstrong @ 2020-09-07  9:38 UTC (permalink / raw)
  To: jbrunet, devicetree
  Cc: linux-amlogic, linux-clk, linux-arm-kernel, linux-kernel, Neil Armstrong

Add clock IDs for the video clocks.

Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
---
 include/dt-bindings/clock/axg-clkc.h | 24 ++++++++++++++++++++++++
 1 file changed, 24 insertions(+)

diff --git a/include/dt-bindings/clock/axg-clkc.h b/include/dt-bindings/clock/axg-clkc.h
index fd1f938c38d1..281df3e0f131 100644
--- a/include/dt-bindings/clock/axg-clkc.h
+++ b/include/dt-bindings/clock/axg-clkc.h
@@ -72,5 +72,29 @@
 #define CLKID_PCIE_CML_EN1			80
 #define CLKID_MIPI_ENABLE			81
 #define CLKID_GEN_CLK				84
+#define CLKID_VPU_0_SEL				92
+#define CLKID_VPU_0				93
+#define CLKID_VPU_1_SEL				95
+#define CLKID_VPU_1				96
+#define CLKID_VPU				97
+#define CLKID_VAPB_0_SEL			99
+#define CLKID_VAPB_0				100
+#define CLKID_VAPB_1_SEL			102
+#define CLKID_VAPB_1				103
+#define CLKID_VAPB_SEL				104
+#define CLKID_VAPB				105
+#define CLKID_VCLK				106
+#define CLKID_VCLK2				107
+#define CLKID_VCLK_DIV1				122
+#define CLKID_VCLK_DIV2				123
+#define CLKID_VCLK_DIV4				124
+#define CLKID_VCLK_DIV6				125
+#define CLKID_VCLK_DIV12			126
+#define CLKID_VCLK2_DIV1			127
+#define CLKID_VCLK2_DIV2			128
+#define CLKID_VCLK2_DIV4			129
+#define CLKID_VCLK2_DIV6			130
+#define CLKID_VCLK2_DIV12			131
+#define CLKID_CTS_ENCL				133
 
 #endif /* __AXG_CLKC_H */
-- 
2.22.0


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

* [PATCH 1/4] dt-bindings: clk: axg-clkc: add Video Clocks
@ 2020-09-07  9:38   ` Neil Armstrong
  0 siblings, 0 replies; 30+ messages in thread
From: Neil Armstrong @ 2020-09-07  9:38 UTC (permalink / raw)
  To: jbrunet, devicetree
  Cc: linux-amlogic, Neil Armstrong, linux-clk, linux-arm-kernel, linux-kernel

Add clock IDs for the video clocks.

Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
---
 include/dt-bindings/clock/axg-clkc.h | 24 ++++++++++++++++++++++++
 1 file changed, 24 insertions(+)

diff --git a/include/dt-bindings/clock/axg-clkc.h b/include/dt-bindings/clock/axg-clkc.h
index fd1f938c38d1..281df3e0f131 100644
--- a/include/dt-bindings/clock/axg-clkc.h
+++ b/include/dt-bindings/clock/axg-clkc.h
@@ -72,5 +72,29 @@
 #define CLKID_PCIE_CML_EN1			80
 #define CLKID_MIPI_ENABLE			81
 #define CLKID_GEN_CLK				84
+#define CLKID_VPU_0_SEL				92
+#define CLKID_VPU_0				93
+#define CLKID_VPU_1_SEL				95
+#define CLKID_VPU_1				96
+#define CLKID_VPU				97
+#define CLKID_VAPB_0_SEL			99
+#define CLKID_VAPB_0				100
+#define CLKID_VAPB_1_SEL			102
+#define CLKID_VAPB_1				103
+#define CLKID_VAPB_SEL				104
+#define CLKID_VAPB				105
+#define CLKID_VCLK				106
+#define CLKID_VCLK2				107
+#define CLKID_VCLK_DIV1				122
+#define CLKID_VCLK_DIV2				123
+#define CLKID_VCLK_DIV4				124
+#define CLKID_VCLK_DIV6				125
+#define CLKID_VCLK_DIV12			126
+#define CLKID_VCLK2_DIV1			127
+#define CLKID_VCLK2_DIV2			128
+#define CLKID_VCLK2_DIV4			129
+#define CLKID_VCLK2_DIV6			130
+#define CLKID_VCLK2_DIV12			131
+#define CLKID_CTS_ENCL				133
 
 #endif /* __AXG_CLKC_H */
-- 
2.22.0


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [PATCH 1/4] dt-bindings: clk: axg-clkc: add Video Clocks
@ 2020-09-07  9:38   ` Neil Armstrong
  0 siblings, 0 replies; 30+ messages in thread
From: Neil Armstrong @ 2020-09-07  9:38 UTC (permalink / raw)
  To: jbrunet, devicetree
  Cc: linux-amlogic, Neil Armstrong, linux-clk, linux-arm-kernel, linux-kernel

Add clock IDs for the video clocks.

Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
---
 include/dt-bindings/clock/axg-clkc.h | 24 ++++++++++++++++++++++++
 1 file changed, 24 insertions(+)

diff --git a/include/dt-bindings/clock/axg-clkc.h b/include/dt-bindings/clock/axg-clkc.h
index fd1f938c38d1..281df3e0f131 100644
--- a/include/dt-bindings/clock/axg-clkc.h
+++ b/include/dt-bindings/clock/axg-clkc.h
@@ -72,5 +72,29 @@
 #define CLKID_PCIE_CML_EN1			80
 #define CLKID_MIPI_ENABLE			81
 #define CLKID_GEN_CLK				84
+#define CLKID_VPU_0_SEL				92
+#define CLKID_VPU_0				93
+#define CLKID_VPU_1_SEL				95
+#define CLKID_VPU_1				96
+#define CLKID_VPU				97
+#define CLKID_VAPB_0_SEL			99
+#define CLKID_VAPB_0				100
+#define CLKID_VAPB_1_SEL			102
+#define CLKID_VAPB_1				103
+#define CLKID_VAPB_SEL				104
+#define CLKID_VAPB				105
+#define CLKID_VCLK				106
+#define CLKID_VCLK2				107
+#define CLKID_VCLK_DIV1				122
+#define CLKID_VCLK_DIV2				123
+#define CLKID_VCLK_DIV4				124
+#define CLKID_VCLK_DIV6				125
+#define CLKID_VCLK_DIV12			126
+#define CLKID_VCLK2_DIV1			127
+#define CLKID_VCLK2_DIV2			128
+#define CLKID_VCLK2_DIV4			129
+#define CLKID_VCLK2_DIV6			130
+#define CLKID_VCLK2_DIV12			131
+#define CLKID_CTS_ENCL				133
 
 #endif /* __AXG_CLKC_H */
-- 
2.22.0


_______________________________________________
linux-amlogic mailing list
linux-amlogic@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-amlogic

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

* [PATCH 2/4] dt-bindings: clk: axg-clkc: add MIPI DSI Host clock binding
  2020-09-07  9:38 ` Neil Armstrong
  (?)
@ 2020-09-07  9:38   ` Neil Armstrong
  -1 siblings, 0 replies; 30+ messages in thread
From: Neil Armstrong @ 2020-09-07  9:38 UTC (permalink / raw)
  To: jbrunet, devicetree
  Cc: linux-amlogic, linux-clk, linux-arm-kernel, linux-kernel, Neil Armstrong

Add the clock ID for the MIPI DSI Host clock.

Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
---
 include/dt-bindings/clock/axg-clkc.h | 1 +
 1 file changed, 1 insertion(+)

diff --git a/include/dt-bindings/clock/axg-clkc.h b/include/dt-bindings/clock/axg-clkc.h
index 281df3e0f131..e2749dbc74b8 100644
--- a/include/dt-bindings/clock/axg-clkc.h
+++ b/include/dt-bindings/clock/axg-clkc.h
@@ -96,5 +96,6 @@
 #define CLKID_VCLK2_DIV6			130
 #define CLKID_VCLK2_DIV12			131
 #define CLKID_CTS_ENCL				133
+#define CLKID_VDIN_MEAS				136
 
 #endif /* __AXG_CLKC_H */
-- 
2.22.0


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

* [PATCH 2/4] dt-bindings: clk: axg-clkc: add MIPI DSI Host clock binding
@ 2020-09-07  9:38   ` Neil Armstrong
  0 siblings, 0 replies; 30+ messages in thread
From: Neil Armstrong @ 2020-09-07  9:38 UTC (permalink / raw)
  To: jbrunet, devicetree
  Cc: linux-amlogic, Neil Armstrong, linux-clk, linux-arm-kernel, linux-kernel

Add the clock ID for the MIPI DSI Host clock.

Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
---
 include/dt-bindings/clock/axg-clkc.h | 1 +
 1 file changed, 1 insertion(+)

diff --git a/include/dt-bindings/clock/axg-clkc.h b/include/dt-bindings/clock/axg-clkc.h
index 281df3e0f131..e2749dbc74b8 100644
--- a/include/dt-bindings/clock/axg-clkc.h
+++ b/include/dt-bindings/clock/axg-clkc.h
@@ -96,5 +96,6 @@
 #define CLKID_VCLK2_DIV6			130
 #define CLKID_VCLK2_DIV12			131
 #define CLKID_CTS_ENCL				133
+#define CLKID_VDIN_MEAS				136
 
 #endif /* __AXG_CLKC_H */
-- 
2.22.0


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [PATCH 2/4] dt-bindings: clk: axg-clkc: add MIPI DSI Host clock binding
@ 2020-09-07  9:38   ` Neil Armstrong
  0 siblings, 0 replies; 30+ messages in thread
From: Neil Armstrong @ 2020-09-07  9:38 UTC (permalink / raw)
  To: jbrunet, devicetree
  Cc: linux-amlogic, Neil Armstrong, linux-clk, linux-arm-kernel, linux-kernel

Add the clock ID for the MIPI DSI Host clock.

Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
---
 include/dt-bindings/clock/axg-clkc.h | 1 +
 1 file changed, 1 insertion(+)

diff --git a/include/dt-bindings/clock/axg-clkc.h b/include/dt-bindings/clock/axg-clkc.h
index 281df3e0f131..e2749dbc74b8 100644
--- a/include/dt-bindings/clock/axg-clkc.h
+++ b/include/dt-bindings/clock/axg-clkc.h
@@ -96,5 +96,6 @@
 #define CLKID_VCLK2_DIV6			130
 #define CLKID_VCLK2_DIV12			131
 #define CLKID_CTS_ENCL				133
+#define CLKID_VDIN_MEAS				136
 
 #endif /* __AXG_CLKC_H */
-- 
2.22.0


_______________________________________________
linux-amlogic mailing list
linux-amlogic@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-amlogic

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

* [PATCH 3/4] clk: meson: axg: add Video Clocks
  2020-09-07  9:38 ` Neil Armstrong
  (?)
@ 2020-09-07  9:38   ` Neil Armstrong
  -1 siblings, 0 replies; 30+ messages in thread
From: Neil Armstrong @ 2020-09-07  9:38 UTC (permalink / raw)
  To: jbrunet
  Cc: linux-amlogic, linux-clk, linux-arm-kernel, linux-kernel, Neil Armstrong

Add the Video Clocks present on the Amlogic AXg SoCs.

The AXG only has a single ENCL CTS clock and even if VCLK exist along VCLK2,
only VCLK2 is used since it clocks the MIPI DSI IP directly.

Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
---
 drivers/clk/meson/axg.c | 774 ++++++++++++++++++++++++++++++++++++++++
 drivers/clk/meson/axg.h |  21 +-
 2 files changed, 794 insertions(+), 1 deletion(-)

diff --git a/drivers/clk/meson/axg.c b/drivers/clk/meson/axg.c
index 13fc0006f63d..2550616c14b0 100644
--- a/drivers/clk/meson/axg.c
+++ b/drivers/clk/meson/axg.c
@@ -1026,6 +1026,704 @@ static struct clk_regmap axg_sd_emmc_c_clk0 = {
 	},
 };
 
+/* VPU Clock */
+
+static const struct clk_hw *axg_vpu_parent_hws[] = {
+	&axg_fclk_div4.hw,
+	&axg_fclk_div3.hw,
+	&axg_fclk_div5.hw,
+	&axg_fclk_div7.hw,
+};
+
+static struct clk_regmap axg_vpu_0_sel = {
+	.data = &(struct clk_regmap_mux_data){
+		.offset = HHI_VPU_CLK_CNTL,
+		.mask = 0x3,
+		.shift = 9,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "vpu_0_sel",
+		.ops = &clk_regmap_mux_ops,
+		/*
+		 * bits 9:10 selects from 4 possible parents:
+		 * fclk_div4, fclk_div3, fclk_div5, fclk_div7,
+		 */
+		.parent_hws = axg_vpu_parent_hws,
+		.num_parents = ARRAY_SIZE(axg_vpu_parent_hws),
+		.flags = CLK_SET_RATE_NO_REPARENT,
+	},
+};
+
+static struct clk_regmap axg_vpu_0_div = {
+	.data = &(struct clk_regmap_div_data){
+		.offset = HHI_VPU_CLK_CNTL,
+		.shift = 0,
+		.width = 7,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "vpu_0_div",
+		.ops = &clk_regmap_divider_ops,
+		.parent_hws = (const struct clk_hw *[]) { &axg_vpu_0_sel.hw },
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap axg_vpu_0 = {
+	.data = &(struct clk_regmap_gate_data){
+		.offset = HHI_VPU_CLK_CNTL,
+		.bit_idx = 8,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "vpu_0",
+		.ops = &clk_regmap_gate_ops,
+		.parent_hws = (const struct clk_hw *[]) { &axg_vpu_0_div.hw },
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
+	},
+};
+
+static struct clk_regmap axg_vpu_1_sel = {
+	.data = &(struct clk_regmap_mux_data){
+		.offset = HHI_VPU_CLK_CNTL,
+		.mask = 0x3,
+		.shift = 25,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "vpu_1_sel",
+		.ops = &clk_regmap_mux_ops,
+		/*
+		 * bits 25:26 selects from 4 possible parents:
+		 * fclk_div4, fclk_div3, fclk_div5, fclk_div7,
+		 */
+		.parent_hws = axg_vpu_parent_hws,
+		.num_parents = ARRAY_SIZE(axg_vpu_parent_hws),
+		.flags = CLK_SET_RATE_NO_REPARENT,
+	},
+};
+
+static struct clk_regmap axg_vpu_1_div = {
+	.data = &(struct clk_regmap_div_data){
+		.offset = HHI_VPU_CLK_CNTL,
+		.shift = 16,
+		.width = 7,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "vpu_1_div",
+		.ops = &clk_regmap_divider_ops,
+		.parent_hws = (const struct clk_hw *[]) { &axg_vpu_1_sel.hw },
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap axg_vpu_1 = {
+	.data = &(struct clk_regmap_gate_data){
+		.offset = HHI_VPU_CLK_CNTL,
+		.bit_idx = 24,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "vpu_1",
+		.ops = &clk_regmap_gate_ops,
+		.parent_hws = (const struct clk_hw *[]) { &axg_vpu_1_div.hw },
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
+	},
+};
+
+static struct clk_regmap axg_vpu = {
+	.data = &(struct clk_regmap_mux_data){
+		.offset = HHI_VPU_CLK_CNTL,
+		.mask = 1,
+		.shift = 31,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "vpu",
+		.ops = &clk_regmap_mux_ops,
+		/*
+		 * bit 31 selects from 2 possible parents:
+		 * vpu_0 or vpu_1
+		 */
+		.parent_hws = (const struct clk_hw *[]) {
+			&axg_vpu_0.hw,
+			&axg_vpu_1.hw
+		},
+		.num_parents = 2,
+		.flags = CLK_SET_RATE_NO_REPARENT,
+	},
+};
+
+/* VAPB Clock */
+
+static const struct clk_hw *axg_vapb_parent_hws[] = {
+	&axg_fclk_div4.hw,
+	&axg_fclk_div3.hw,
+	&axg_fclk_div5.hw,
+	&axg_fclk_div7.hw,
+};
+
+static struct clk_regmap axg_vapb_0_sel = {
+	.data = &(struct clk_regmap_mux_data){
+		.offset = HHI_VAPBCLK_CNTL,
+		.mask = 0x3,
+		.shift = 9,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "vapb_0_sel",
+		.ops = &clk_regmap_mux_ops,
+		/*
+		 * bits 9:10 selects from 4 possible parents:
+		 * fclk_div4, fclk_div3, fclk_div5, fclk_div7,
+		 */
+		.parent_hws = axg_vapb_parent_hws,
+		.num_parents = ARRAY_SIZE(axg_vapb_parent_hws),
+		.flags = CLK_SET_RATE_NO_REPARENT,
+	},
+};
+
+static struct clk_regmap axg_vapb_0_div = {
+	.data = &(struct clk_regmap_div_data){
+		.offset = HHI_VAPBCLK_CNTL,
+		.shift = 0,
+		.width = 7,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "vapb_0_div",
+		.ops = &clk_regmap_divider_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&axg_vapb_0_sel.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap axg_vapb_0 = {
+	.data = &(struct clk_regmap_gate_data){
+		.offset = HHI_VAPBCLK_CNTL,
+		.bit_idx = 8,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "vapb_0",
+		.ops = &clk_regmap_gate_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&axg_vapb_0_div.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
+	},
+};
+
+static struct clk_regmap axg_vapb_1_sel = {
+	.data = &(struct clk_regmap_mux_data){
+		.offset = HHI_VAPBCLK_CNTL,
+		.mask = 0x3,
+		.shift = 25,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "vapb_1_sel",
+		.ops = &clk_regmap_mux_ops,
+		/*
+		 * bits 25:26 selects from 4 possible parents:
+		 * fclk_div4, fclk_div3, fclk_div5, fclk_div7,
+		 */
+		.parent_hws = axg_vapb_parent_hws,
+		.num_parents = ARRAY_SIZE(axg_vapb_parent_hws),
+		.flags = CLK_SET_RATE_NO_REPARENT,
+	},
+};
+
+static struct clk_regmap axg_vapb_1_div = {
+	.data = &(struct clk_regmap_div_data){
+		.offset = HHI_VAPBCLK_CNTL,
+		.shift = 16,
+		.width = 7,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "vapb_1_div",
+		.ops = &clk_regmap_divider_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&axg_vapb_1_sel.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap axg_vapb_1 = {
+	.data = &(struct clk_regmap_gate_data){
+		.offset = HHI_VAPBCLK_CNTL,
+		.bit_idx = 24,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "vapb_1",
+		.ops = &clk_regmap_gate_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&axg_vapb_1_div.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
+	},
+};
+
+static struct clk_regmap axg_vapb_sel = {
+	.data = &(struct clk_regmap_mux_data){
+		.offset = HHI_VAPBCLK_CNTL,
+		.mask = 1,
+		.shift = 31,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "vapb_sel",
+		.ops = &clk_regmap_mux_ops,
+		/*
+		 * bit 31 selects from 2 possible parents:
+		 * vapb_0 or vapb_1
+		 */
+		.parent_hws = (const struct clk_hw *[]) {
+			&axg_vapb_0.hw,
+			&axg_vapb_1.hw
+		},
+		.num_parents = 2,
+		.flags = CLK_SET_RATE_NO_REPARENT,
+	},
+};
+
+static struct clk_regmap axg_vapb = {
+	.data = &(struct clk_regmap_gate_data){
+		.offset = HHI_VAPBCLK_CNTL,
+		.bit_idx = 30,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "vapb",
+		.ops = &clk_regmap_gate_ops,
+		.parent_hws = (const struct clk_hw *[]) { &axg_vapb_sel.hw },
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
+	},
+};
+
+/* Video Clocks */
+
+static const struct clk_hw *axg_vclk_parent_hws[] = {
+	&axg_gp0_pll.hw,
+	&axg_fclk_div4.hw,
+	&axg_fclk_div3.hw,
+	&axg_fclk_div5.hw,
+	&axg_fclk_div2.hw,
+	&axg_fclk_div7.hw,
+	&axg_mpll1.hw,
+};
+
+static struct clk_regmap axg_vclk_sel = {
+	.data = &(struct clk_regmap_mux_data){
+		.offset = HHI_VID_CLK_CNTL,
+		.mask = 0x7,
+		.shift = 16,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "vclk_sel",
+		.ops = &clk_regmap_mux_ops,
+		.parent_hws = axg_vclk_parent_hws,
+		.num_parents = ARRAY_SIZE(axg_vclk_parent_hws),
+		.flags = CLK_SET_RATE_NO_REPARENT | CLK_GET_RATE_NOCACHE,
+	},
+};
+
+static struct clk_regmap axg_vclk2_sel = {
+	.data = &(struct clk_regmap_mux_data){
+		.offset = HHI_VIID_CLK_CNTL,
+		.mask = 0x7,
+		.shift = 16,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "vclk2_sel",
+		.ops = &clk_regmap_mux_ops,
+		.parent_hws = axg_vclk_parent_hws,
+		.num_parents = ARRAY_SIZE(axg_vclk_parent_hws),
+		.flags = CLK_SET_RATE_NO_REPARENT | CLK_GET_RATE_NOCACHE,
+	},
+};
+
+static struct clk_regmap axg_vclk_input = {
+	.data = &(struct clk_regmap_gate_data){
+		.offset = HHI_VID_CLK_DIV,
+		.bit_idx = 16,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "vclk_input",
+		.ops = &clk_regmap_gate_ops,
+		.parent_hws = (const struct clk_hw *[]) { &axg_vclk_sel.hw },
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
+	},
+};
+
+static struct clk_regmap axg_vclk2_input = {
+	.data = &(struct clk_regmap_gate_data){
+		.offset = HHI_VIID_CLK_DIV,
+		.bit_idx = 16,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "vclk2_input",
+		.ops = &clk_regmap_gate_ops,
+		.parent_hws = (const struct clk_hw *[]) { &axg_vclk2_sel.hw },
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
+	},
+};
+
+static struct clk_regmap axg_vclk_div = {
+	.data = &(struct clk_regmap_div_data){
+		.offset = HHI_VID_CLK_DIV,
+		.shift = 0,
+		.width = 8,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "vclk_div",
+		.ops = &clk_regmap_divider_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&axg_vclk_input.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_GET_RATE_NOCACHE,
+	},
+};
+
+static struct clk_regmap axg_vclk2_div = {
+	.data = &(struct clk_regmap_div_data){
+		.offset = HHI_VIID_CLK_DIV,
+		.shift = 0,
+		.width = 8,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "vclk2_div",
+		.ops = &clk_regmap_divider_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&axg_vclk2_input.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_GET_RATE_NOCACHE,
+	},
+};
+
+static struct clk_regmap axg_vclk = {
+	.data = &(struct clk_regmap_gate_data){
+		.offset = HHI_VID_CLK_CNTL,
+		.bit_idx = 19,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "vclk",
+		.ops = &clk_regmap_gate_ops,
+		.parent_hws = (const struct clk_hw *[]) { &axg_vclk_div.hw },
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
+	},
+};
+
+static struct clk_regmap axg_vclk2 = {
+	.data = &(struct clk_regmap_gate_data){
+		.offset = HHI_VIID_CLK_CNTL,
+		.bit_idx = 19,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "vclk2",
+		.ops = &clk_regmap_gate_ops,
+		.parent_hws = (const struct clk_hw *[]) { &axg_vclk2_div.hw },
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
+	},
+};
+
+static struct clk_regmap axg_vclk_div1 = {
+	.data = &(struct clk_regmap_gate_data){
+		.offset = HHI_VID_CLK_CNTL,
+		.bit_idx = 0,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "vclk_div1",
+		.ops = &clk_regmap_gate_ops,
+		.parent_hws = (const struct clk_hw *[]) { &axg_vclk.hw },
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
+	},
+};
+
+static struct clk_regmap axg_vclk_div2_en = {
+	.data = &(struct clk_regmap_gate_data){
+		.offset = HHI_VID_CLK_CNTL,
+		.bit_idx = 1,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "vclk_div2_en",
+		.ops = &clk_regmap_gate_ops,
+		.parent_hws = (const struct clk_hw *[]) { &axg_vclk.hw },
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
+	},
+};
+
+static struct clk_regmap axg_vclk_div4_en = {
+	.data = &(struct clk_regmap_gate_data){
+		.offset = HHI_VID_CLK_CNTL,
+		.bit_idx = 2,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "vclk_div4_en",
+		.ops = &clk_regmap_gate_ops,
+		.parent_hws = (const struct clk_hw *[]) { &axg_vclk.hw },
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
+	},
+};
+
+static struct clk_regmap axg_vclk_div6_en = {
+	.data = &(struct clk_regmap_gate_data){
+		.offset = HHI_VID_CLK_CNTL,
+		.bit_idx = 3,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "vclk_div6_en",
+		.ops = &clk_regmap_gate_ops,
+		.parent_hws = (const struct clk_hw *[]) { &axg_vclk.hw },
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
+	},
+};
+
+static struct clk_regmap axg_vclk_div12_en = {
+	.data = &(struct clk_regmap_gate_data){
+		.offset = HHI_VID_CLK_CNTL,
+		.bit_idx = 4,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "vclk_div12_en",
+		.ops = &clk_regmap_gate_ops,
+		.parent_hws = (const struct clk_hw *[]) { &axg_vclk.hw },
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
+	},
+};
+
+static struct clk_regmap axg_vclk2_div1 = {
+	.data = &(struct clk_regmap_gate_data){
+		.offset = HHI_VIID_CLK_CNTL,
+		.bit_idx = 0,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "vclk2_div1",
+		.ops = &clk_regmap_gate_ops,
+		.parent_hws = (const struct clk_hw *[]) { &axg_vclk2.hw },
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
+	},
+};
+
+static struct clk_regmap axg_vclk2_div2_en = {
+	.data = &(struct clk_regmap_gate_data){
+		.offset = HHI_VIID_CLK_CNTL,
+		.bit_idx = 1,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "vclk2_div2_en",
+		.ops = &clk_regmap_gate_ops,
+		.parent_hws = (const struct clk_hw *[]) { &axg_vclk2.hw },
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
+	},
+};
+
+static struct clk_regmap axg_vclk2_div4_en = {
+	.data = &(struct clk_regmap_gate_data){
+		.offset = HHI_VIID_CLK_CNTL,
+		.bit_idx = 2,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "vclk2_div4_en",
+		.ops = &clk_regmap_gate_ops,
+		.parent_hws = (const struct clk_hw *[]) { &axg_vclk2.hw },
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
+	},
+};
+
+static struct clk_regmap axg_vclk2_div6_en = {
+	.data = &(struct clk_regmap_gate_data){
+		.offset = HHI_VIID_CLK_CNTL,
+		.bit_idx = 3,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "vclk2_div6_en",
+		.ops = &clk_regmap_gate_ops,
+		.parent_hws = (const struct clk_hw *[]) { &axg_vclk2.hw },
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
+	},
+};
+
+static struct clk_regmap axg_vclk2_div12_en = {
+	.data = &(struct clk_regmap_gate_data){
+		.offset = HHI_VIID_CLK_CNTL,
+		.bit_idx = 4,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "vclk2_div12_en",
+		.ops = &clk_regmap_gate_ops,
+		.parent_hws = (const struct clk_hw *[]) { &axg_vclk2.hw },
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
+	},
+};
+
+static struct clk_fixed_factor axg_vclk_div2 = {
+	.mult = 1,
+	.div = 2,
+	.hw.init = &(struct clk_init_data){
+		.name = "vclk_div2",
+		.ops = &clk_fixed_factor_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&axg_vclk_div2_en.hw
+		},
+		.num_parents = 1,
+	},
+};
+
+static struct clk_fixed_factor axg_vclk_div4 = {
+	.mult = 1,
+	.div = 4,
+	.hw.init = &(struct clk_init_data){
+		.name = "vclk_div4",
+		.ops = &clk_fixed_factor_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&axg_vclk_div4_en.hw
+		},
+		.num_parents = 1,
+	},
+};
+
+static struct clk_fixed_factor axg_vclk_div6 = {
+	.mult = 1,
+	.div = 6,
+	.hw.init = &(struct clk_init_data){
+		.name = "vclk_div6",
+		.ops = &clk_fixed_factor_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&axg_vclk_div6_en.hw
+		},
+		.num_parents = 1,
+	},
+};
+
+static struct clk_fixed_factor axg_vclk_div12 = {
+	.mult = 1,
+	.div = 12,
+	.hw.init = &(struct clk_init_data){
+		.name = "vclk_div12",
+		.ops = &clk_fixed_factor_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&axg_vclk_div12_en.hw
+		},
+		.num_parents = 1,
+	},
+};
+
+static struct clk_fixed_factor axg_vclk2_div2 = {
+	.mult = 1,
+	.div = 2,
+	.hw.init = &(struct clk_init_data){
+		.name = "vclk2_div2",
+		.ops = &clk_fixed_factor_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&axg_vclk2_div2_en.hw
+		},
+		.num_parents = 1,
+	},
+};
+
+static struct clk_fixed_factor axg_vclk2_div4 = {
+	.mult = 1,
+	.div = 4,
+	.hw.init = &(struct clk_init_data){
+		.name = "vclk2_div4",
+		.ops = &clk_fixed_factor_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&axg_vclk2_div4_en.hw
+		},
+		.num_parents = 1,
+	},
+};
+
+static struct clk_fixed_factor axg_vclk2_div6 = {
+	.mult = 1,
+	.div = 6,
+	.hw.init = &(struct clk_init_data){
+		.name = "vclk2_div6",
+		.ops = &clk_fixed_factor_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&axg_vclk2_div6_en.hw
+		},
+		.num_parents = 1,
+	},
+};
+
+static struct clk_fixed_factor axg_vclk2_div12 = {
+	.mult = 1,
+	.div = 12,
+	.hw.init = &(struct clk_init_data){
+		.name = "vclk2_div12",
+		.ops = &clk_fixed_factor_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&axg_vclk2_div12_en.hw
+		},
+		.num_parents = 1,
+	},
+};
+
+static u32 mux_table_cts_sel[] = { 0, 1, 2, 3, 4, 8, 9, 10, 11, 12 };
+static const struct clk_hw *axg_cts_parent_hws[] = {
+	&axg_vclk_div1.hw,
+	&axg_vclk_div2.hw,
+	&axg_vclk_div4.hw,
+	&axg_vclk_div6.hw,
+	&axg_vclk_div12.hw,
+	&axg_vclk2_div1.hw,
+	&axg_vclk2_div2.hw,
+	&axg_vclk2_div4.hw,
+	&axg_vclk2_div6.hw,
+	&axg_vclk2_div12.hw,
+};
+
+static struct clk_regmap axg_cts_encl_sel = {
+	.data = &(struct clk_regmap_mux_data){
+		.offset = HHI_VIID_CLK_DIV,
+		.mask = 0xf,
+		.shift = 12,
+		.table = mux_table_cts_sel,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "cts_encl_sel",
+		.ops = &clk_regmap_mux_ops,
+		.parent_hws = axg_cts_parent_hws,
+		.num_parents = ARRAY_SIZE(axg_cts_parent_hws),
+		.flags = CLK_SET_RATE_NO_REPARENT | CLK_GET_RATE_NOCACHE,
+	},
+};
+
+static struct clk_regmap axg_cts_encl = {
+	.data = &(struct clk_regmap_gate_data){
+		.offset = HHI_VID_CLK_CNTL2,
+		.bit_idx = 3,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "cts_encl",
+		.ops = &clk_regmap_gate_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&axg_cts_encl_sel.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
+	},
+};
+
 static u32 mux_table_gen_clk[]	= { 0, 4, 5, 6, 7, 8,
 				    9, 10, 11, 13, 14, };
 static const struct clk_parent_data gen_clk_parent_data[] = {
@@ -1246,6 +1944,49 @@ static struct clk_hw_onecell_data axg_hw_onecell_data = {
 		[CLKID_HIFI_PLL_DCO]		= &axg_hifi_pll_dco.hw,
 		[CLKID_PCIE_PLL_DCO]		= &axg_pcie_pll_dco.hw,
 		[CLKID_PCIE_PLL_OD]		= &axg_pcie_pll_od.hw,
+		[CLKID_VPU_0_DIV]		= &axg_vpu_0_div.hw,
+		[CLKID_VPU_0_SEL]		= &axg_vpu_0_sel.hw,
+		[CLKID_VPU_0]			= &axg_vpu_0.hw,
+		[CLKID_VPU_1_DIV]		= &axg_vpu_1_div.hw,
+		[CLKID_VPU_1_SEL]		= &axg_vpu_1_sel.hw,
+		[CLKID_VPU_1]			= &axg_vpu_1.hw,
+		[CLKID_VPU]			= &axg_vpu.hw,
+		[CLKID_VAPB_0_DIV]		= &axg_vapb_0_div.hw,
+		[CLKID_VAPB_0_SEL]		= &axg_vapb_0_sel.hw,
+		[CLKID_VAPB_0]			= &axg_vapb_0.hw,
+		[CLKID_VAPB_1_DIV]		= &axg_vapb_1_div.hw,
+		[CLKID_VAPB_1_SEL]		= &axg_vapb_1_sel.hw,
+		[CLKID_VAPB_1]			= &axg_vapb_1.hw,
+		[CLKID_VAPB_SEL]		= &axg_vapb_sel.hw,
+		[CLKID_VAPB]			= &axg_vapb.hw,
+		[CLKID_VCLK]			= &axg_vclk.hw,
+		[CLKID_VCLK2]			= &axg_vclk2.hw,
+		[CLKID_VCLK_SEL]		= &axg_vclk_sel.hw,
+		[CLKID_VCLK2_SEL]		= &axg_vclk2_sel.hw,
+		[CLKID_VCLK_INPUT]		= &axg_vclk_input.hw,
+		[CLKID_VCLK2_INPUT]		= &axg_vclk2_input.hw,
+		[CLKID_VCLK_DIV]		= &axg_vclk_div.hw,
+		[CLKID_VCLK2_DIV]		= &axg_vclk2_div.hw,
+		[CLKID_VCLK_DIV2_EN]		= &axg_vclk_div2_en.hw,
+		[CLKID_VCLK_DIV4_EN]		= &axg_vclk_div4_en.hw,
+		[CLKID_VCLK_DIV6_EN]		= &axg_vclk_div6_en.hw,
+		[CLKID_VCLK_DIV12_EN]		= &axg_vclk_div12_en.hw,
+		[CLKID_VCLK2_DIV2_EN]		= &axg_vclk2_div2_en.hw,
+		[CLKID_VCLK2_DIV4_EN]		= &axg_vclk2_div4_en.hw,
+		[CLKID_VCLK2_DIV6_EN]		= &axg_vclk2_div6_en.hw,
+		[CLKID_VCLK2_DIV12_EN]		= &axg_vclk2_div12_en.hw,
+		[CLKID_VCLK_DIV1]		= &axg_vclk_div1.hw,
+		[CLKID_VCLK_DIV2]		= &axg_vclk_div2.hw,
+		[CLKID_VCLK_DIV4]		= &axg_vclk_div4.hw,
+		[CLKID_VCLK_DIV6]		= &axg_vclk_div6.hw,
+		[CLKID_VCLK_DIV12]		= &axg_vclk_div12.hw,
+		[CLKID_VCLK2_DIV1]		= &axg_vclk2_div1.hw,
+		[CLKID_VCLK2_DIV2]		= &axg_vclk2_div2.hw,
+		[CLKID_VCLK2_DIV4]		= &axg_vclk2_div4.hw,
+		[CLKID_VCLK2_DIV6]		= &axg_vclk2_div6.hw,
+		[CLKID_VCLK2_DIV12]		= &axg_vclk2_div12.hw,
+		[CLKID_CTS_ENCL_SEL]		= &axg_cts_encl_sel.hw,
+		[CLKID_CTS_ENCL]		= &axg_cts_encl.hw,
 		[NR_CLKS]			= NULL,
 	},
 	.num = NR_CLKS,
@@ -1341,6 +2082,39 @@ static struct clk_regmap *const axg_clk_regmaps[] = {
 	&axg_hifi_pll_dco,
 	&axg_pcie_pll_dco,
 	&axg_pcie_pll_od,
+	&axg_vpu_0_div,
+	&axg_vpu_0_sel,
+	&axg_vpu_0,
+	&axg_vpu_1_div,
+	&axg_vpu_1_sel,
+	&axg_vpu_1,
+	&axg_vpu,
+	&axg_vapb_0_div,
+	&axg_vapb_0_sel,
+	&axg_vapb_0,
+	&axg_vapb_1_div,
+	&axg_vapb_1_sel,
+	&axg_vapb_1,
+	&axg_vapb_sel,
+	&axg_vapb,
+	&axg_vclk,
+	&axg_vclk2,
+	&axg_vclk_sel,
+	&axg_vclk2_sel,
+	&axg_vclk_input,
+	&axg_vclk2_input,
+	&axg_vclk_div,
+	&axg_vclk2_div,
+	&axg_vclk_div2_en,
+	&axg_vclk_div4_en,
+	&axg_vclk_div6_en,
+	&axg_vclk_div12_en,
+	&axg_vclk2_div2_en,
+	&axg_vclk2_div4_en,
+	&axg_vclk2_div6_en,
+	&axg_vclk2_div12_en,
+	&axg_cts_encl_sel,
+	&axg_cts_encl,
 };
 
 static const struct meson_eeclkc_data axg_clkc_data = {
diff --git a/drivers/clk/meson/axg.h b/drivers/clk/meson/axg.h
index 0431dabac629..a8787b394a47 100644
--- a/drivers/clk/meson/axg.h
+++ b/drivers/clk/meson/axg.h
@@ -139,8 +139,27 @@
 #define CLKID_HIFI_PLL_DCO			88
 #define CLKID_PCIE_PLL_DCO			89
 #define CLKID_PCIE_PLL_OD			90
+#define CLKID_VPU_0_DIV				91
+#define CLKID_VPU_1_DIV				94
+#define CLKID_VAPB_0_DIV			98
+#define CLKID_VAPB_1_DIV			101
+#define CLKID_VCLK_SEL				108
+#define CLKID_VCLK2_SEL				109
+#define CLKID_VCLK_INPUT			110
+#define CLKID_VCLK2_INPUT			111
+#define CLKID_VCLK_DIV				112
+#define CLKID_VCLK2_DIV				113
+#define CLKID_VCLK_DIV2_EN			114
+#define CLKID_VCLK_DIV4_EN			115
+#define CLKID_VCLK_DIV6_EN			116
+#define CLKID_VCLK_DIV12_EN			117
+#define CLKID_VCLK2_DIV2_EN			118
+#define CLKID_VCLK2_DIV4_EN			119
+#define CLKID_VCLK2_DIV6_EN			120
+#define CLKID_VCLK2_DIV12_EN			121
+#define CLKID_CTS_ENCL_SEL			132
 
-#define NR_CLKS					91
+#define NR_CLKS					134
 
 /* include the CLKIDs that have been made part of the DT binding */
 #include <dt-bindings/clock/axg-clkc.h>
-- 
2.22.0


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

* [PATCH 3/4] clk: meson: axg: add Video Clocks
@ 2020-09-07  9:38   ` Neil Armstrong
  0 siblings, 0 replies; 30+ messages in thread
From: Neil Armstrong @ 2020-09-07  9:38 UTC (permalink / raw)
  To: jbrunet
  Cc: linux-amlogic, Neil Armstrong, linux-clk, linux-arm-kernel, linux-kernel

Add the Video Clocks present on the Amlogic AXg SoCs.

The AXG only has a single ENCL CTS clock and even if VCLK exist along VCLK2,
only VCLK2 is used since it clocks the MIPI DSI IP directly.

Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
---
 drivers/clk/meson/axg.c | 774 ++++++++++++++++++++++++++++++++++++++++
 drivers/clk/meson/axg.h |  21 +-
 2 files changed, 794 insertions(+), 1 deletion(-)

diff --git a/drivers/clk/meson/axg.c b/drivers/clk/meson/axg.c
index 13fc0006f63d..2550616c14b0 100644
--- a/drivers/clk/meson/axg.c
+++ b/drivers/clk/meson/axg.c
@@ -1026,6 +1026,704 @@ static struct clk_regmap axg_sd_emmc_c_clk0 = {
 	},
 };
 
+/* VPU Clock */
+
+static const struct clk_hw *axg_vpu_parent_hws[] = {
+	&axg_fclk_div4.hw,
+	&axg_fclk_div3.hw,
+	&axg_fclk_div5.hw,
+	&axg_fclk_div7.hw,
+};
+
+static struct clk_regmap axg_vpu_0_sel = {
+	.data = &(struct clk_regmap_mux_data){
+		.offset = HHI_VPU_CLK_CNTL,
+		.mask = 0x3,
+		.shift = 9,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "vpu_0_sel",
+		.ops = &clk_regmap_mux_ops,
+		/*
+		 * bits 9:10 selects from 4 possible parents:
+		 * fclk_div4, fclk_div3, fclk_div5, fclk_div7,
+		 */
+		.parent_hws = axg_vpu_parent_hws,
+		.num_parents = ARRAY_SIZE(axg_vpu_parent_hws),
+		.flags = CLK_SET_RATE_NO_REPARENT,
+	},
+};
+
+static struct clk_regmap axg_vpu_0_div = {
+	.data = &(struct clk_regmap_div_data){
+		.offset = HHI_VPU_CLK_CNTL,
+		.shift = 0,
+		.width = 7,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "vpu_0_div",
+		.ops = &clk_regmap_divider_ops,
+		.parent_hws = (const struct clk_hw *[]) { &axg_vpu_0_sel.hw },
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap axg_vpu_0 = {
+	.data = &(struct clk_regmap_gate_data){
+		.offset = HHI_VPU_CLK_CNTL,
+		.bit_idx = 8,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "vpu_0",
+		.ops = &clk_regmap_gate_ops,
+		.parent_hws = (const struct clk_hw *[]) { &axg_vpu_0_div.hw },
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
+	},
+};
+
+static struct clk_regmap axg_vpu_1_sel = {
+	.data = &(struct clk_regmap_mux_data){
+		.offset = HHI_VPU_CLK_CNTL,
+		.mask = 0x3,
+		.shift = 25,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "vpu_1_sel",
+		.ops = &clk_regmap_mux_ops,
+		/*
+		 * bits 25:26 selects from 4 possible parents:
+		 * fclk_div4, fclk_div3, fclk_div5, fclk_div7,
+		 */
+		.parent_hws = axg_vpu_parent_hws,
+		.num_parents = ARRAY_SIZE(axg_vpu_parent_hws),
+		.flags = CLK_SET_RATE_NO_REPARENT,
+	},
+};
+
+static struct clk_regmap axg_vpu_1_div = {
+	.data = &(struct clk_regmap_div_data){
+		.offset = HHI_VPU_CLK_CNTL,
+		.shift = 16,
+		.width = 7,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "vpu_1_div",
+		.ops = &clk_regmap_divider_ops,
+		.parent_hws = (const struct clk_hw *[]) { &axg_vpu_1_sel.hw },
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap axg_vpu_1 = {
+	.data = &(struct clk_regmap_gate_data){
+		.offset = HHI_VPU_CLK_CNTL,
+		.bit_idx = 24,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "vpu_1",
+		.ops = &clk_regmap_gate_ops,
+		.parent_hws = (const struct clk_hw *[]) { &axg_vpu_1_div.hw },
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
+	},
+};
+
+static struct clk_regmap axg_vpu = {
+	.data = &(struct clk_regmap_mux_data){
+		.offset = HHI_VPU_CLK_CNTL,
+		.mask = 1,
+		.shift = 31,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "vpu",
+		.ops = &clk_regmap_mux_ops,
+		/*
+		 * bit 31 selects from 2 possible parents:
+		 * vpu_0 or vpu_1
+		 */
+		.parent_hws = (const struct clk_hw *[]) {
+			&axg_vpu_0.hw,
+			&axg_vpu_1.hw
+		},
+		.num_parents = 2,
+		.flags = CLK_SET_RATE_NO_REPARENT,
+	},
+};
+
+/* VAPB Clock */
+
+static const struct clk_hw *axg_vapb_parent_hws[] = {
+	&axg_fclk_div4.hw,
+	&axg_fclk_div3.hw,
+	&axg_fclk_div5.hw,
+	&axg_fclk_div7.hw,
+};
+
+static struct clk_regmap axg_vapb_0_sel = {
+	.data = &(struct clk_regmap_mux_data){
+		.offset = HHI_VAPBCLK_CNTL,
+		.mask = 0x3,
+		.shift = 9,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "vapb_0_sel",
+		.ops = &clk_regmap_mux_ops,
+		/*
+		 * bits 9:10 selects from 4 possible parents:
+		 * fclk_div4, fclk_div3, fclk_div5, fclk_div7,
+		 */
+		.parent_hws = axg_vapb_parent_hws,
+		.num_parents = ARRAY_SIZE(axg_vapb_parent_hws),
+		.flags = CLK_SET_RATE_NO_REPARENT,
+	},
+};
+
+static struct clk_regmap axg_vapb_0_div = {
+	.data = &(struct clk_regmap_div_data){
+		.offset = HHI_VAPBCLK_CNTL,
+		.shift = 0,
+		.width = 7,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "vapb_0_div",
+		.ops = &clk_regmap_divider_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&axg_vapb_0_sel.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap axg_vapb_0 = {
+	.data = &(struct clk_regmap_gate_data){
+		.offset = HHI_VAPBCLK_CNTL,
+		.bit_idx = 8,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "vapb_0",
+		.ops = &clk_regmap_gate_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&axg_vapb_0_div.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
+	},
+};
+
+static struct clk_regmap axg_vapb_1_sel = {
+	.data = &(struct clk_regmap_mux_data){
+		.offset = HHI_VAPBCLK_CNTL,
+		.mask = 0x3,
+		.shift = 25,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "vapb_1_sel",
+		.ops = &clk_regmap_mux_ops,
+		/*
+		 * bits 25:26 selects from 4 possible parents:
+		 * fclk_div4, fclk_div3, fclk_div5, fclk_div7,
+		 */
+		.parent_hws = axg_vapb_parent_hws,
+		.num_parents = ARRAY_SIZE(axg_vapb_parent_hws),
+		.flags = CLK_SET_RATE_NO_REPARENT,
+	},
+};
+
+static struct clk_regmap axg_vapb_1_div = {
+	.data = &(struct clk_regmap_div_data){
+		.offset = HHI_VAPBCLK_CNTL,
+		.shift = 16,
+		.width = 7,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "vapb_1_div",
+		.ops = &clk_regmap_divider_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&axg_vapb_1_sel.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap axg_vapb_1 = {
+	.data = &(struct clk_regmap_gate_data){
+		.offset = HHI_VAPBCLK_CNTL,
+		.bit_idx = 24,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "vapb_1",
+		.ops = &clk_regmap_gate_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&axg_vapb_1_div.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
+	},
+};
+
+static struct clk_regmap axg_vapb_sel = {
+	.data = &(struct clk_regmap_mux_data){
+		.offset = HHI_VAPBCLK_CNTL,
+		.mask = 1,
+		.shift = 31,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "vapb_sel",
+		.ops = &clk_regmap_mux_ops,
+		/*
+		 * bit 31 selects from 2 possible parents:
+		 * vapb_0 or vapb_1
+		 */
+		.parent_hws = (const struct clk_hw *[]) {
+			&axg_vapb_0.hw,
+			&axg_vapb_1.hw
+		},
+		.num_parents = 2,
+		.flags = CLK_SET_RATE_NO_REPARENT,
+	},
+};
+
+static struct clk_regmap axg_vapb = {
+	.data = &(struct clk_regmap_gate_data){
+		.offset = HHI_VAPBCLK_CNTL,
+		.bit_idx = 30,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "vapb",
+		.ops = &clk_regmap_gate_ops,
+		.parent_hws = (const struct clk_hw *[]) { &axg_vapb_sel.hw },
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
+	},
+};
+
+/* Video Clocks */
+
+static const struct clk_hw *axg_vclk_parent_hws[] = {
+	&axg_gp0_pll.hw,
+	&axg_fclk_div4.hw,
+	&axg_fclk_div3.hw,
+	&axg_fclk_div5.hw,
+	&axg_fclk_div2.hw,
+	&axg_fclk_div7.hw,
+	&axg_mpll1.hw,
+};
+
+static struct clk_regmap axg_vclk_sel = {
+	.data = &(struct clk_regmap_mux_data){
+		.offset = HHI_VID_CLK_CNTL,
+		.mask = 0x7,
+		.shift = 16,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "vclk_sel",
+		.ops = &clk_regmap_mux_ops,
+		.parent_hws = axg_vclk_parent_hws,
+		.num_parents = ARRAY_SIZE(axg_vclk_parent_hws),
+		.flags = CLK_SET_RATE_NO_REPARENT | CLK_GET_RATE_NOCACHE,
+	},
+};
+
+static struct clk_regmap axg_vclk2_sel = {
+	.data = &(struct clk_regmap_mux_data){
+		.offset = HHI_VIID_CLK_CNTL,
+		.mask = 0x7,
+		.shift = 16,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "vclk2_sel",
+		.ops = &clk_regmap_mux_ops,
+		.parent_hws = axg_vclk_parent_hws,
+		.num_parents = ARRAY_SIZE(axg_vclk_parent_hws),
+		.flags = CLK_SET_RATE_NO_REPARENT | CLK_GET_RATE_NOCACHE,
+	},
+};
+
+static struct clk_regmap axg_vclk_input = {
+	.data = &(struct clk_regmap_gate_data){
+		.offset = HHI_VID_CLK_DIV,
+		.bit_idx = 16,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "vclk_input",
+		.ops = &clk_regmap_gate_ops,
+		.parent_hws = (const struct clk_hw *[]) { &axg_vclk_sel.hw },
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
+	},
+};
+
+static struct clk_regmap axg_vclk2_input = {
+	.data = &(struct clk_regmap_gate_data){
+		.offset = HHI_VIID_CLK_DIV,
+		.bit_idx = 16,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "vclk2_input",
+		.ops = &clk_regmap_gate_ops,
+		.parent_hws = (const struct clk_hw *[]) { &axg_vclk2_sel.hw },
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
+	},
+};
+
+static struct clk_regmap axg_vclk_div = {
+	.data = &(struct clk_regmap_div_data){
+		.offset = HHI_VID_CLK_DIV,
+		.shift = 0,
+		.width = 8,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "vclk_div",
+		.ops = &clk_regmap_divider_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&axg_vclk_input.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_GET_RATE_NOCACHE,
+	},
+};
+
+static struct clk_regmap axg_vclk2_div = {
+	.data = &(struct clk_regmap_div_data){
+		.offset = HHI_VIID_CLK_DIV,
+		.shift = 0,
+		.width = 8,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "vclk2_div",
+		.ops = &clk_regmap_divider_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&axg_vclk2_input.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_GET_RATE_NOCACHE,
+	},
+};
+
+static struct clk_regmap axg_vclk = {
+	.data = &(struct clk_regmap_gate_data){
+		.offset = HHI_VID_CLK_CNTL,
+		.bit_idx = 19,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "vclk",
+		.ops = &clk_regmap_gate_ops,
+		.parent_hws = (const struct clk_hw *[]) { &axg_vclk_div.hw },
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
+	},
+};
+
+static struct clk_regmap axg_vclk2 = {
+	.data = &(struct clk_regmap_gate_data){
+		.offset = HHI_VIID_CLK_CNTL,
+		.bit_idx = 19,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "vclk2",
+		.ops = &clk_regmap_gate_ops,
+		.parent_hws = (const struct clk_hw *[]) { &axg_vclk2_div.hw },
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
+	},
+};
+
+static struct clk_regmap axg_vclk_div1 = {
+	.data = &(struct clk_regmap_gate_data){
+		.offset = HHI_VID_CLK_CNTL,
+		.bit_idx = 0,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "vclk_div1",
+		.ops = &clk_regmap_gate_ops,
+		.parent_hws = (const struct clk_hw *[]) { &axg_vclk.hw },
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
+	},
+};
+
+static struct clk_regmap axg_vclk_div2_en = {
+	.data = &(struct clk_regmap_gate_data){
+		.offset = HHI_VID_CLK_CNTL,
+		.bit_idx = 1,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "vclk_div2_en",
+		.ops = &clk_regmap_gate_ops,
+		.parent_hws = (const struct clk_hw *[]) { &axg_vclk.hw },
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
+	},
+};
+
+static struct clk_regmap axg_vclk_div4_en = {
+	.data = &(struct clk_regmap_gate_data){
+		.offset = HHI_VID_CLK_CNTL,
+		.bit_idx = 2,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "vclk_div4_en",
+		.ops = &clk_regmap_gate_ops,
+		.parent_hws = (const struct clk_hw *[]) { &axg_vclk.hw },
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
+	},
+};
+
+static struct clk_regmap axg_vclk_div6_en = {
+	.data = &(struct clk_regmap_gate_data){
+		.offset = HHI_VID_CLK_CNTL,
+		.bit_idx = 3,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "vclk_div6_en",
+		.ops = &clk_regmap_gate_ops,
+		.parent_hws = (const struct clk_hw *[]) { &axg_vclk.hw },
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
+	},
+};
+
+static struct clk_regmap axg_vclk_div12_en = {
+	.data = &(struct clk_regmap_gate_data){
+		.offset = HHI_VID_CLK_CNTL,
+		.bit_idx = 4,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "vclk_div12_en",
+		.ops = &clk_regmap_gate_ops,
+		.parent_hws = (const struct clk_hw *[]) { &axg_vclk.hw },
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
+	},
+};
+
+static struct clk_regmap axg_vclk2_div1 = {
+	.data = &(struct clk_regmap_gate_data){
+		.offset = HHI_VIID_CLK_CNTL,
+		.bit_idx = 0,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "vclk2_div1",
+		.ops = &clk_regmap_gate_ops,
+		.parent_hws = (const struct clk_hw *[]) { &axg_vclk2.hw },
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
+	},
+};
+
+static struct clk_regmap axg_vclk2_div2_en = {
+	.data = &(struct clk_regmap_gate_data){
+		.offset = HHI_VIID_CLK_CNTL,
+		.bit_idx = 1,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "vclk2_div2_en",
+		.ops = &clk_regmap_gate_ops,
+		.parent_hws = (const struct clk_hw *[]) { &axg_vclk2.hw },
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
+	},
+};
+
+static struct clk_regmap axg_vclk2_div4_en = {
+	.data = &(struct clk_regmap_gate_data){
+		.offset = HHI_VIID_CLK_CNTL,
+		.bit_idx = 2,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "vclk2_div4_en",
+		.ops = &clk_regmap_gate_ops,
+		.parent_hws = (const struct clk_hw *[]) { &axg_vclk2.hw },
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
+	},
+};
+
+static struct clk_regmap axg_vclk2_div6_en = {
+	.data = &(struct clk_regmap_gate_data){
+		.offset = HHI_VIID_CLK_CNTL,
+		.bit_idx = 3,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "vclk2_div6_en",
+		.ops = &clk_regmap_gate_ops,
+		.parent_hws = (const struct clk_hw *[]) { &axg_vclk2.hw },
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
+	},
+};
+
+static struct clk_regmap axg_vclk2_div12_en = {
+	.data = &(struct clk_regmap_gate_data){
+		.offset = HHI_VIID_CLK_CNTL,
+		.bit_idx = 4,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "vclk2_div12_en",
+		.ops = &clk_regmap_gate_ops,
+		.parent_hws = (const struct clk_hw *[]) { &axg_vclk2.hw },
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
+	},
+};
+
+static struct clk_fixed_factor axg_vclk_div2 = {
+	.mult = 1,
+	.div = 2,
+	.hw.init = &(struct clk_init_data){
+		.name = "vclk_div2",
+		.ops = &clk_fixed_factor_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&axg_vclk_div2_en.hw
+		},
+		.num_parents = 1,
+	},
+};
+
+static struct clk_fixed_factor axg_vclk_div4 = {
+	.mult = 1,
+	.div = 4,
+	.hw.init = &(struct clk_init_data){
+		.name = "vclk_div4",
+		.ops = &clk_fixed_factor_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&axg_vclk_div4_en.hw
+		},
+		.num_parents = 1,
+	},
+};
+
+static struct clk_fixed_factor axg_vclk_div6 = {
+	.mult = 1,
+	.div = 6,
+	.hw.init = &(struct clk_init_data){
+		.name = "vclk_div6",
+		.ops = &clk_fixed_factor_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&axg_vclk_div6_en.hw
+		},
+		.num_parents = 1,
+	},
+};
+
+static struct clk_fixed_factor axg_vclk_div12 = {
+	.mult = 1,
+	.div = 12,
+	.hw.init = &(struct clk_init_data){
+		.name = "vclk_div12",
+		.ops = &clk_fixed_factor_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&axg_vclk_div12_en.hw
+		},
+		.num_parents = 1,
+	},
+};
+
+static struct clk_fixed_factor axg_vclk2_div2 = {
+	.mult = 1,
+	.div = 2,
+	.hw.init = &(struct clk_init_data){
+		.name = "vclk2_div2",
+		.ops = &clk_fixed_factor_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&axg_vclk2_div2_en.hw
+		},
+		.num_parents = 1,
+	},
+};
+
+static struct clk_fixed_factor axg_vclk2_div4 = {
+	.mult = 1,
+	.div = 4,
+	.hw.init = &(struct clk_init_data){
+		.name = "vclk2_div4",
+		.ops = &clk_fixed_factor_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&axg_vclk2_div4_en.hw
+		},
+		.num_parents = 1,
+	},
+};
+
+static struct clk_fixed_factor axg_vclk2_div6 = {
+	.mult = 1,
+	.div = 6,
+	.hw.init = &(struct clk_init_data){
+		.name = "vclk2_div6",
+		.ops = &clk_fixed_factor_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&axg_vclk2_div6_en.hw
+		},
+		.num_parents = 1,
+	},
+};
+
+static struct clk_fixed_factor axg_vclk2_div12 = {
+	.mult = 1,
+	.div = 12,
+	.hw.init = &(struct clk_init_data){
+		.name = "vclk2_div12",
+		.ops = &clk_fixed_factor_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&axg_vclk2_div12_en.hw
+		},
+		.num_parents = 1,
+	},
+};
+
+static u32 mux_table_cts_sel[] = { 0, 1, 2, 3, 4, 8, 9, 10, 11, 12 };
+static const struct clk_hw *axg_cts_parent_hws[] = {
+	&axg_vclk_div1.hw,
+	&axg_vclk_div2.hw,
+	&axg_vclk_div4.hw,
+	&axg_vclk_div6.hw,
+	&axg_vclk_div12.hw,
+	&axg_vclk2_div1.hw,
+	&axg_vclk2_div2.hw,
+	&axg_vclk2_div4.hw,
+	&axg_vclk2_div6.hw,
+	&axg_vclk2_div12.hw,
+};
+
+static struct clk_regmap axg_cts_encl_sel = {
+	.data = &(struct clk_regmap_mux_data){
+		.offset = HHI_VIID_CLK_DIV,
+		.mask = 0xf,
+		.shift = 12,
+		.table = mux_table_cts_sel,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "cts_encl_sel",
+		.ops = &clk_regmap_mux_ops,
+		.parent_hws = axg_cts_parent_hws,
+		.num_parents = ARRAY_SIZE(axg_cts_parent_hws),
+		.flags = CLK_SET_RATE_NO_REPARENT | CLK_GET_RATE_NOCACHE,
+	},
+};
+
+static struct clk_regmap axg_cts_encl = {
+	.data = &(struct clk_regmap_gate_data){
+		.offset = HHI_VID_CLK_CNTL2,
+		.bit_idx = 3,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "cts_encl",
+		.ops = &clk_regmap_gate_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&axg_cts_encl_sel.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
+	},
+};
+
 static u32 mux_table_gen_clk[]	= { 0, 4, 5, 6, 7, 8,
 				    9, 10, 11, 13, 14, };
 static const struct clk_parent_data gen_clk_parent_data[] = {
@@ -1246,6 +1944,49 @@ static struct clk_hw_onecell_data axg_hw_onecell_data = {
 		[CLKID_HIFI_PLL_DCO]		= &axg_hifi_pll_dco.hw,
 		[CLKID_PCIE_PLL_DCO]		= &axg_pcie_pll_dco.hw,
 		[CLKID_PCIE_PLL_OD]		= &axg_pcie_pll_od.hw,
+		[CLKID_VPU_0_DIV]		= &axg_vpu_0_div.hw,
+		[CLKID_VPU_0_SEL]		= &axg_vpu_0_sel.hw,
+		[CLKID_VPU_0]			= &axg_vpu_0.hw,
+		[CLKID_VPU_1_DIV]		= &axg_vpu_1_div.hw,
+		[CLKID_VPU_1_SEL]		= &axg_vpu_1_sel.hw,
+		[CLKID_VPU_1]			= &axg_vpu_1.hw,
+		[CLKID_VPU]			= &axg_vpu.hw,
+		[CLKID_VAPB_0_DIV]		= &axg_vapb_0_div.hw,
+		[CLKID_VAPB_0_SEL]		= &axg_vapb_0_sel.hw,
+		[CLKID_VAPB_0]			= &axg_vapb_0.hw,
+		[CLKID_VAPB_1_DIV]		= &axg_vapb_1_div.hw,
+		[CLKID_VAPB_1_SEL]		= &axg_vapb_1_sel.hw,
+		[CLKID_VAPB_1]			= &axg_vapb_1.hw,
+		[CLKID_VAPB_SEL]		= &axg_vapb_sel.hw,
+		[CLKID_VAPB]			= &axg_vapb.hw,
+		[CLKID_VCLK]			= &axg_vclk.hw,
+		[CLKID_VCLK2]			= &axg_vclk2.hw,
+		[CLKID_VCLK_SEL]		= &axg_vclk_sel.hw,
+		[CLKID_VCLK2_SEL]		= &axg_vclk2_sel.hw,
+		[CLKID_VCLK_INPUT]		= &axg_vclk_input.hw,
+		[CLKID_VCLK2_INPUT]		= &axg_vclk2_input.hw,
+		[CLKID_VCLK_DIV]		= &axg_vclk_div.hw,
+		[CLKID_VCLK2_DIV]		= &axg_vclk2_div.hw,
+		[CLKID_VCLK_DIV2_EN]		= &axg_vclk_div2_en.hw,
+		[CLKID_VCLK_DIV4_EN]		= &axg_vclk_div4_en.hw,
+		[CLKID_VCLK_DIV6_EN]		= &axg_vclk_div6_en.hw,
+		[CLKID_VCLK_DIV12_EN]		= &axg_vclk_div12_en.hw,
+		[CLKID_VCLK2_DIV2_EN]		= &axg_vclk2_div2_en.hw,
+		[CLKID_VCLK2_DIV4_EN]		= &axg_vclk2_div4_en.hw,
+		[CLKID_VCLK2_DIV6_EN]		= &axg_vclk2_div6_en.hw,
+		[CLKID_VCLK2_DIV12_EN]		= &axg_vclk2_div12_en.hw,
+		[CLKID_VCLK_DIV1]		= &axg_vclk_div1.hw,
+		[CLKID_VCLK_DIV2]		= &axg_vclk_div2.hw,
+		[CLKID_VCLK_DIV4]		= &axg_vclk_div4.hw,
+		[CLKID_VCLK_DIV6]		= &axg_vclk_div6.hw,
+		[CLKID_VCLK_DIV12]		= &axg_vclk_div12.hw,
+		[CLKID_VCLK2_DIV1]		= &axg_vclk2_div1.hw,
+		[CLKID_VCLK2_DIV2]		= &axg_vclk2_div2.hw,
+		[CLKID_VCLK2_DIV4]		= &axg_vclk2_div4.hw,
+		[CLKID_VCLK2_DIV6]		= &axg_vclk2_div6.hw,
+		[CLKID_VCLK2_DIV12]		= &axg_vclk2_div12.hw,
+		[CLKID_CTS_ENCL_SEL]		= &axg_cts_encl_sel.hw,
+		[CLKID_CTS_ENCL]		= &axg_cts_encl.hw,
 		[NR_CLKS]			= NULL,
 	},
 	.num = NR_CLKS,
@@ -1341,6 +2082,39 @@ static struct clk_regmap *const axg_clk_regmaps[] = {
 	&axg_hifi_pll_dco,
 	&axg_pcie_pll_dco,
 	&axg_pcie_pll_od,
+	&axg_vpu_0_div,
+	&axg_vpu_0_sel,
+	&axg_vpu_0,
+	&axg_vpu_1_div,
+	&axg_vpu_1_sel,
+	&axg_vpu_1,
+	&axg_vpu,
+	&axg_vapb_0_div,
+	&axg_vapb_0_sel,
+	&axg_vapb_0,
+	&axg_vapb_1_div,
+	&axg_vapb_1_sel,
+	&axg_vapb_1,
+	&axg_vapb_sel,
+	&axg_vapb,
+	&axg_vclk,
+	&axg_vclk2,
+	&axg_vclk_sel,
+	&axg_vclk2_sel,
+	&axg_vclk_input,
+	&axg_vclk2_input,
+	&axg_vclk_div,
+	&axg_vclk2_div,
+	&axg_vclk_div2_en,
+	&axg_vclk_div4_en,
+	&axg_vclk_div6_en,
+	&axg_vclk_div12_en,
+	&axg_vclk2_div2_en,
+	&axg_vclk2_div4_en,
+	&axg_vclk2_div6_en,
+	&axg_vclk2_div12_en,
+	&axg_cts_encl_sel,
+	&axg_cts_encl,
 };
 
 static const struct meson_eeclkc_data axg_clkc_data = {
diff --git a/drivers/clk/meson/axg.h b/drivers/clk/meson/axg.h
index 0431dabac629..a8787b394a47 100644
--- a/drivers/clk/meson/axg.h
+++ b/drivers/clk/meson/axg.h
@@ -139,8 +139,27 @@
 #define CLKID_HIFI_PLL_DCO			88
 #define CLKID_PCIE_PLL_DCO			89
 #define CLKID_PCIE_PLL_OD			90
+#define CLKID_VPU_0_DIV				91
+#define CLKID_VPU_1_DIV				94
+#define CLKID_VAPB_0_DIV			98
+#define CLKID_VAPB_1_DIV			101
+#define CLKID_VCLK_SEL				108
+#define CLKID_VCLK2_SEL				109
+#define CLKID_VCLK_INPUT			110
+#define CLKID_VCLK2_INPUT			111
+#define CLKID_VCLK_DIV				112
+#define CLKID_VCLK2_DIV				113
+#define CLKID_VCLK_DIV2_EN			114
+#define CLKID_VCLK_DIV4_EN			115
+#define CLKID_VCLK_DIV6_EN			116
+#define CLKID_VCLK_DIV12_EN			117
+#define CLKID_VCLK2_DIV2_EN			118
+#define CLKID_VCLK2_DIV4_EN			119
+#define CLKID_VCLK2_DIV6_EN			120
+#define CLKID_VCLK2_DIV12_EN			121
+#define CLKID_CTS_ENCL_SEL			132
 
-#define NR_CLKS					91
+#define NR_CLKS					134
 
 /* include the CLKIDs that have been made part of the DT binding */
 #include <dt-bindings/clock/axg-clkc.h>
-- 
2.22.0


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [PATCH 3/4] clk: meson: axg: add Video Clocks
@ 2020-09-07  9:38   ` Neil Armstrong
  0 siblings, 0 replies; 30+ messages in thread
From: Neil Armstrong @ 2020-09-07  9:38 UTC (permalink / raw)
  To: jbrunet
  Cc: linux-amlogic, Neil Armstrong, linux-clk, linux-arm-kernel, linux-kernel

Add the Video Clocks present on the Amlogic AXg SoCs.

The AXG only has a single ENCL CTS clock and even if VCLK exist along VCLK2,
only VCLK2 is used since it clocks the MIPI DSI IP directly.

Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
---
 drivers/clk/meson/axg.c | 774 ++++++++++++++++++++++++++++++++++++++++
 drivers/clk/meson/axg.h |  21 +-
 2 files changed, 794 insertions(+), 1 deletion(-)

diff --git a/drivers/clk/meson/axg.c b/drivers/clk/meson/axg.c
index 13fc0006f63d..2550616c14b0 100644
--- a/drivers/clk/meson/axg.c
+++ b/drivers/clk/meson/axg.c
@@ -1026,6 +1026,704 @@ static struct clk_regmap axg_sd_emmc_c_clk0 = {
 	},
 };
 
+/* VPU Clock */
+
+static const struct clk_hw *axg_vpu_parent_hws[] = {
+	&axg_fclk_div4.hw,
+	&axg_fclk_div3.hw,
+	&axg_fclk_div5.hw,
+	&axg_fclk_div7.hw,
+};
+
+static struct clk_regmap axg_vpu_0_sel = {
+	.data = &(struct clk_regmap_mux_data){
+		.offset = HHI_VPU_CLK_CNTL,
+		.mask = 0x3,
+		.shift = 9,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "vpu_0_sel",
+		.ops = &clk_regmap_mux_ops,
+		/*
+		 * bits 9:10 selects from 4 possible parents:
+		 * fclk_div4, fclk_div3, fclk_div5, fclk_div7,
+		 */
+		.parent_hws = axg_vpu_parent_hws,
+		.num_parents = ARRAY_SIZE(axg_vpu_parent_hws),
+		.flags = CLK_SET_RATE_NO_REPARENT,
+	},
+};
+
+static struct clk_regmap axg_vpu_0_div = {
+	.data = &(struct clk_regmap_div_data){
+		.offset = HHI_VPU_CLK_CNTL,
+		.shift = 0,
+		.width = 7,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "vpu_0_div",
+		.ops = &clk_regmap_divider_ops,
+		.parent_hws = (const struct clk_hw *[]) { &axg_vpu_0_sel.hw },
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap axg_vpu_0 = {
+	.data = &(struct clk_regmap_gate_data){
+		.offset = HHI_VPU_CLK_CNTL,
+		.bit_idx = 8,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "vpu_0",
+		.ops = &clk_regmap_gate_ops,
+		.parent_hws = (const struct clk_hw *[]) { &axg_vpu_0_div.hw },
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
+	},
+};
+
+static struct clk_regmap axg_vpu_1_sel = {
+	.data = &(struct clk_regmap_mux_data){
+		.offset = HHI_VPU_CLK_CNTL,
+		.mask = 0x3,
+		.shift = 25,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "vpu_1_sel",
+		.ops = &clk_regmap_mux_ops,
+		/*
+		 * bits 25:26 selects from 4 possible parents:
+		 * fclk_div4, fclk_div3, fclk_div5, fclk_div7,
+		 */
+		.parent_hws = axg_vpu_parent_hws,
+		.num_parents = ARRAY_SIZE(axg_vpu_parent_hws),
+		.flags = CLK_SET_RATE_NO_REPARENT,
+	},
+};
+
+static struct clk_regmap axg_vpu_1_div = {
+	.data = &(struct clk_regmap_div_data){
+		.offset = HHI_VPU_CLK_CNTL,
+		.shift = 16,
+		.width = 7,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "vpu_1_div",
+		.ops = &clk_regmap_divider_ops,
+		.parent_hws = (const struct clk_hw *[]) { &axg_vpu_1_sel.hw },
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap axg_vpu_1 = {
+	.data = &(struct clk_regmap_gate_data){
+		.offset = HHI_VPU_CLK_CNTL,
+		.bit_idx = 24,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "vpu_1",
+		.ops = &clk_regmap_gate_ops,
+		.parent_hws = (const struct clk_hw *[]) { &axg_vpu_1_div.hw },
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
+	},
+};
+
+static struct clk_regmap axg_vpu = {
+	.data = &(struct clk_regmap_mux_data){
+		.offset = HHI_VPU_CLK_CNTL,
+		.mask = 1,
+		.shift = 31,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "vpu",
+		.ops = &clk_regmap_mux_ops,
+		/*
+		 * bit 31 selects from 2 possible parents:
+		 * vpu_0 or vpu_1
+		 */
+		.parent_hws = (const struct clk_hw *[]) {
+			&axg_vpu_0.hw,
+			&axg_vpu_1.hw
+		},
+		.num_parents = 2,
+		.flags = CLK_SET_RATE_NO_REPARENT,
+	},
+};
+
+/* VAPB Clock */
+
+static const struct clk_hw *axg_vapb_parent_hws[] = {
+	&axg_fclk_div4.hw,
+	&axg_fclk_div3.hw,
+	&axg_fclk_div5.hw,
+	&axg_fclk_div7.hw,
+};
+
+static struct clk_regmap axg_vapb_0_sel = {
+	.data = &(struct clk_regmap_mux_data){
+		.offset = HHI_VAPBCLK_CNTL,
+		.mask = 0x3,
+		.shift = 9,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "vapb_0_sel",
+		.ops = &clk_regmap_mux_ops,
+		/*
+		 * bits 9:10 selects from 4 possible parents:
+		 * fclk_div4, fclk_div3, fclk_div5, fclk_div7,
+		 */
+		.parent_hws = axg_vapb_parent_hws,
+		.num_parents = ARRAY_SIZE(axg_vapb_parent_hws),
+		.flags = CLK_SET_RATE_NO_REPARENT,
+	},
+};
+
+static struct clk_regmap axg_vapb_0_div = {
+	.data = &(struct clk_regmap_div_data){
+		.offset = HHI_VAPBCLK_CNTL,
+		.shift = 0,
+		.width = 7,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "vapb_0_div",
+		.ops = &clk_regmap_divider_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&axg_vapb_0_sel.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap axg_vapb_0 = {
+	.data = &(struct clk_regmap_gate_data){
+		.offset = HHI_VAPBCLK_CNTL,
+		.bit_idx = 8,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "vapb_0",
+		.ops = &clk_regmap_gate_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&axg_vapb_0_div.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
+	},
+};
+
+static struct clk_regmap axg_vapb_1_sel = {
+	.data = &(struct clk_regmap_mux_data){
+		.offset = HHI_VAPBCLK_CNTL,
+		.mask = 0x3,
+		.shift = 25,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "vapb_1_sel",
+		.ops = &clk_regmap_mux_ops,
+		/*
+		 * bits 25:26 selects from 4 possible parents:
+		 * fclk_div4, fclk_div3, fclk_div5, fclk_div7,
+		 */
+		.parent_hws = axg_vapb_parent_hws,
+		.num_parents = ARRAY_SIZE(axg_vapb_parent_hws),
+		.flags = CLK_SET_RATE_NO_REPARENT,
+	},
+};
+
+static struct clk_regmap axg_vapb_1_div = {
+	.data = &(struct clk_regmap_div_data){
+		.offset = HHI_VAPBCLK_CNTL,
+		.shift = 16,
+		.width = 7,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "vapb_1_div",
+		.ops = &clk_regmap_divider_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&axg_vapb_1_sel.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap axg_vapb_1 = {
+	.data = &(struct clk_regmap_gate_data){
+		.offset = HHI_VAPBCLK_CNTL,
+		.bit_idx = 24,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "vapb_1",
+		.ops = &clk_regmap_gate_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&axg_vapb_1_div.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
+	},
+};
+
+static struct clk_regmap axg_vapb_sel = {
+	.data = &(struct clk_regmap_mux_data){
+		.offset = HHI_VAPBCLK_CNTL,
+		.mask = 1,
+		.shift = 31,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "vapb_sel",
+		.ops = &clk_regmap_mux_ops,
+		/*
+		 * bit 31 selects from 2 possible parents:
+		 * vapb_0 or vapb_1
+		 */
+		.parent_hws = (const struct clk_hw *[]) {
+			&axg_vapb_0.hw,
+			&axg_vapb_1.hw
+		},
+		.num_parents = 2,
+		.flags = CLK_SET_RATE_NO_REPARENT,
+	},
+};
+
+static struct clk_regmap axg_vapb = {
+	.data = &(struct clk_regmap_gate_data){
+		.offset = HHI_VAPBCLK_CNTL,
+		.bit_idx = 30,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "vapb",
+		.ops = &clk_regmap_gate_ops,
+		.parent_hws = (const struct clk_hw *[]) { &axg_vapb_sel.hw },
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
+	},
+};
+
+/* Video Clocks */
+
+static const struct clk_hw *axg_vclk_parent_hws[] = {
+	&axg_gp0_pll.hw,
+	&axg_fclk_div4.hw,
+	&axg_fclk_div3.hw,
+	&axg_fclk_div5.hw,
+	&axg_fclk_div2.hw,
+	&axg_fclk_div7.hw,
+	&axg_mpll1.hw,
+};
+
+static struct clk_regmap axg_vclk_sel = {
+	.data = &(struct clk_regmap_mux_data){
+		.offset = HHI_VID_CLK_CNTL,
+		.mask = 0x7,
+		.shift = 16,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "vclk_sel",
+		.ops = &clk_regmap_mux_ops,
+		.parent_hws = axg_vclk_parent_hws,
+		.num_parents = ARRAY_SIZE(axg_vclk_parent_hws),
+		.flags = CLK_SET_RATE_NO_REPARENT | CLK_GET_RATE_NOCACHE,
+	},
+};
+
+static struct clk_regmap axg_vclk2_sel = {
+	.data = &(struct clk_regmap_mux_data){
+		.offset = HHI_VIID_CLK_CNTL,
+		.mask = 0x7,
+		.shift = 16,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "vclk2_sel",
+		.ops = &clk_regmap_mux_ops,
+		.parent_hws = axg_vclk_parent_hws,
+		.num_parents = ARRAY_SIZE(axg_vclk_parent_hws),
+		.flags = CLK_SET_RATE_NO_REPARENT | CLK_GET_RATE_NOCACHE,
+	},
+};
+
+static struct clk_regmap axg_vclk_input = {
+	.data = &(struct clk_regmap_gate_data){
+		.offset = HHI_VID_CLK_DIV,
+		.bit_idx = 16,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "vclk_input",
+		.ops = &clk_regmap_gate_ops,
+		.parent_hws = (const struct clk_hw *[]) { &axg_vclk_sel.hw },
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
+	},
+};
+
+static struct clk_regmap axg_vclk2_input = {
+	.data = &(struct clk_regmap_gate_data){
+		.offset = HHI_VIID_CLK_DIV,
+		.bit_idx = 16,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "vclk2_input",
+		.ops = &clk_regmap_gate_ops,
+		.parent_hws = (const struct clk_hw *[]) { &axg_vclk2_sel.hw },
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
+	},
+};
+
+static struct clk_regmap axg_vclk_div = {
+	.data = &(struct clk_regmap_div_data){
+		.offset = HHI_VID_CLK_DIV,
+		.shift = 0,
+		.width = 8,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "vclk_div",
+		.ops = &clk_regmap_divider_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&axg_vclk_input.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_GET_RATE_NOCACHE,
+	},
+};
+
+static struct clk_regmap axg_vclk2_div = {
+	.data = &(struct clk_regmap_div_data){
+		.offset = HHI_VIID_CLK_DIV,
+		.shift = 0,
+		.width = 8,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "vclk2_div",
+		.ops = &clk_regmap_divider_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&axg_vclk2_input.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_GET_RATE_NOCACHE,
+	},
+};
+
+static struct clk_regmap axg_vclk = {
+	.data = &(struct clk_regmap_gate_data){
+		.offset = HHI_VID_CLK_CNTL,
+		.bit_idx = 19,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "vclk",
+		.ops = &clk_regmap_gate_ops,
+		.parent_hws = (const struct clk_hw *[]) { &axg_vclk_div.hw },
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
+	},
+};
+
+static struct clk_regmap axg_vclk2 = {
+	.data = &(struct clk_regmap_gate_data){
+		.offset = HHI_VIID_CLK_CNTL,
+		.bit_idx = 19,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "vclk2",
+		.ops = &clk_regmap_gate_ops,
+		.parent_hws = (const struct clk_hw *[]) { &axg_vclk2_div.hw },
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
+	},
+};
+
+static struct clk_regmap axg_vclk_div1 = {
+	.data = &(struct clk_regmap_gate_data){
+		.offset = HHI_VID_CLK_CNTL,
+		.bit_idx = 0,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "vclk_div1",
+		.ops = &clk_regmap_gate_ops,
+		.parent_hws = (const struct clk_hw *[]) { &axg_vclk.hw },
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
+	},
+};
+
+static struct clk_regmap axg_vclk_div2_en = {
+	.data = &(struct clk_regmap_gate_data){
+		.offset = HHI_VID_CLK_CNTL,
+		.bit_idx = 1,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "vclk_div2_en",
+		.ops = &clk_regmap_gate_ops,
+		.parent_hws = (const struct clk_hw *[]) { &axg_vclk.hw },
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
+	},
+};
+
+static struct clk_regmap axg_vclk_div4_en = {
+	.data = &(struct clk_regmap_gate_data){
+		.offset = HHI_VID_CLK_CNTL,
+		.bit_idx = 2,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "vclk_div4_en",
+		.ops = &clk_regmap_gate_ops,
+		.parent_hws = (const struct clk_hw *[]) { &axg_vclk.hw },
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
+	},
+};
+
+static struct clk_regmap axg_vclk_div6_en = {
+	.data = &(struct clk_regmap_gate_data){
+		.offset = HHI_VID_CLK_CNTL,
+		.bit_idx = 3,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "vclk_div6_en",
+		.ops = &clk_regmap_gate_ops,
+		.parent_hws = (const struct clk_hw *[]) { &axg_vclk.hw },
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
+	},
+};
+
+static struct clk_regmap axg_vclk_div12_en = {
+	.data = &(struct clk_regmap_gate_data){
+		.offset = HHI_VID_CLK_CNTL,
+		.bit_idx = 4,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "vclk_div12_en",
+		.ops = &clk_regmap_gate_ops,
+		.parent_hws = (const struct clk_hw *[]) { &axg_vclk.hw },
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
+	},
+};
+
+static struct clk_regmap axg_vclk2_div1 = {
+	.data = &(struct clk_regmap_gate_data){
+		.offset = HHI_VIID_CLK_CNTL,
+		.bit_idx = 0,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "vclk2_div1",
+		.ops = &clk_regmap_gate_ops,
+		.parent_hws = (const struct clk_hw *[]) { &axg_vclk2.hw },
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
+	},
+};
+
+static struct clk_regmap axg_vclk2_div2_en = {
+	.data = &(struct clk_regmap_gate_data){
+		.offset = HHI_VIID_CLK_CNTL,
+		.bit_idx = 1,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "vclk2_div2_en",
+		.ops = &clk_regmap_gate_ops,
+		.parent_hws = (const struct clk_hw *[]) { &axg_vclk2.hw },
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
+	},
+};
+
+static struct clk_regmap axg_vclk2_div4_en = {
+	.data = &(struct clk_regmap_gate_data){
+		.offset = HHI_VIID_CLK_CNTL,
+		.bit_idx = 2,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "vclk2_div4_en",
+		.ops = &clk_regmap_gate_ops,
+		.parent_hws = (const struct clk_hw *[]) { &axg_vclk2.hw },
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
+	},
+};
+
+static struct clk_regmap axg_vclk2_div6_en = {
+	.data = &(struct clk_regmap_gate_data){
+		.offset = HHI_VIID_CLK_CNTL,
+		.bit_idx = 3,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "vclk2_div6_en",
+		.ops = &clk_regmap_gate_ops,
+		.parent_hws = (const struct clk_hw *[]) { &axg_vclk2.hw },
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
+	},
+};
+
+static struct clk_regmap axg_vclk2_div12_en = {
+	.data = &(struct clk_regmap_gate_data){
+		.offset = HHI_VIID_CLK_CNTL,
+		.bit_idx = 4,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "vclk2_div12_en",
+		.ops = &clk_regmap_gate_ops,
+		.parent_hws = (const struct clk_hw *[]) { &axg_vclk2.hw },
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
+	},
+};
+
+static struct clk_fixed_factor axg_vclk_div2 = {
+	.mult = 1,
+	.div = 2,
+	.hw.init = &(struct clk_init_data){
+		.name = "vclk_div2",
+		.ops = &clk_fixed_factor_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&axg_vclk_div2_en.hw
+		},
+		.num_parents = 1,
+	},
+};
+
+static struct clk_fixed_factor axg_vclk_div4 = {
+	.mult = 1,
+	.div = 4,
+	.hw.init = &(struct clk_init_data){
+		.name = "vclk_div4",
+		.ops = &clk_fixed_factor_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&axg_vclk_div4_en.hw
+		},
+		.num_parents = 1,
+	},
+};
+
+static struct clk_fixed_factor axg_vclk_div6 = {
+	.mult = 1,
+	.div = 6,
+	.hw.init = &(struct clk_init_data){
+		.name = "vclk_div6",
+		.ops = &clk_fixed_factor_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&axg_vclk_div6_en.hw
+		},
+		.num_parents = 1,
+	},
+};
+
+static struct clk_fixed_factor axg_vclk_div12 = {
+	.mult = 1,
+	.div = 12,
+	.hw.init = &(struct clk_init_data){
+		.name = "vclk_div12",
+		.ops = &clk_fixed_factor_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&axg_vclk_div12_en.hw
+		},
+		.num_parents = 1,
+	},
+};
+
+static struct clk_fixed_factor axg_vclk2_div2 = {
+	.mult = 1,
+	.div = 2,
+	.hw.init = &(struct clk_init_data){
+		.name = "vclk2_div2",
+		.ops = &clk_fixed_factor_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&axg_vclk2_div2_en.hw
+		},
+		.num_parents = 1,
+	},
+};
+
+static struct clk_fixed_factor axg_vclk2_div4 = {
+	.mult = 1,
+	.div = 4,
+	.hw.init = &(struct clk_init_data){
+		.name = "vclk2_div4",
+		.ops = &clk_fixed_factor_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&axg_vclk2_div4_en.hw
+		},
+		.num_parents = 1,
+	},
+};
+
+static struct clk_fixed_factor axg_vclk2_div6 = {
+	.mult = 1,
+	.div = 6,
+	.hw.init = &(struct clk_init_data){
+		.name = "vclk2_div6",
+		.ops = &clk_fixed_factor_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&axg_vclk2_div6_en.hw
+		},
+		.num_parents = 1,
+	},
+};
+
+static struct clk_fixed_factor axg_vclk2_div12 = {
+	.mult = 1,
+	.div = 12,
+	.hw.init = &(struct clk_init_data){
+		.name = "vclk2_div12",
+		.ops = &clk_fixed_factor_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&axg_vclk2_div12_en.hw
+		},
+		.num_parents = 1,
+	},
+};
+
+static u32 mux_table_cts_sel[] = { 0, 1, 2, 3, 4, 8, 9, 10, 11, 12 };
+static const struct clk_hw *axg_cts_parent_hws[] = {
+	&axg_vclk_div1.hw,
+	&axg_vclk_div2.hw,
+	&axg_vclk_div4.hw,
+	&axg_vclk_div6.hw,
+	&axg_vclk_div12.hw,
+	&axg_vclk2_div1.hw,
+	&axg_vclk2_div2.hw,
+	&axg_vclk2_div4.hw,
+	&axg_vclk2_div6.hw,
+	&axg_vclk2_div12.hw,
+};
+
+static struct clk_regmap axg_cts_encl_sel = {
+	.data = &(struct clk_regmap_mux_data){
+		.offset = HHI_VIID_CLK_DIV,
+		.mask = 0xf,
+		.shift = 12,
+		.table = mux_table_cts_sel,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "cts_encl_sel",
+		.ops = &clk_regmap_mux_ops,
+		.parent_hws = axg_cts_parent_hws,
+		.num_parents = ARRAY_SIZE(axg_cts_parent_hws),
+		.flags = CLK_SET_RATE_NO_REPARENT | CLK_GET_RATE_NOCACHE,
+	},
+};
+
+static struct clk_regmap axg_cts_encl = {
+	.data = &(struct clk_regmap_gate_data){
+		.offset = HHI_VID_CLK_CNTL2,
+		.bit_idx = 3,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "cts_encl",
+		.ops = &clk_regmap_gate_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&axg_cts_encl_sel.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
+	},
+};
+
 static u32 mux_table_gen_clk[]	= { 0, 4, 5, 6, 7, 8,
 				    9, 10, 11, 13, 14, };
 static const struct clk_parent_data gen_clk_parent_data[] = {
@@ -1246,6 +1944,49 @@ static struct clk_hw_onecell_data axg_hw_onecell_data = {
 		[CLKID_HIFI_PLL_DCO]		= &axg_hifi_pll_dco.hw,
 		[CLKID_PCIE_PLL_DCO]		= &axg_pcie_pll_dco.hw,
 		[CLKID_PCIE_PLL_OD]		= &axg_pcie_pll_od.hw,
+		[CLKID_VPU_0_DIV]		= &axg_vpu_0_div.hw,
+		[CLKID_VPU_0_SEL]		= &axg_vpu_0_sel.hw,
+		[CLKID_VPU_0]			= &axg_vpu_0.hw,
+		[CLKID_VPU_1_DIV]		= &axg_vpu_1_div.hw,
+		[CLKID_VPU_1_SEL]		= &axg_vpu_1_sel.hw,
+		[CLKID_VPU_1]			= &axg_vpu_1.hw,
+		[CLKID_VPU]			= &axg_vpu.hw,
+		[CLKID_VAPB_0_DIV]		= &axg_vapb_0_div.hw,
+		[CLKID_VAPB_0_SEL]		= &axg_vapb_0_sel.hw,
+		[CLKID_VAPB_0]			= &axg_vapb_0.hw,
+		[CLKID_VAPB_1_DIV]		= &axg_vapb_1_div.hw,
+		[CLKID_VAPB_1_SEL]		= &axg_vapb_1_sel.hw,
+		[CLKID_VAPB_1]			= &axg_vapb_1.hw,
+		[CLKID_VAPB_SEL]		= &axg_vapb_sel.hw,
+		[CLKID_VAPB]			= &axg_vapb.hw,
+		[CLKID_VCLK]			= &axg_vclk.hw,
+		[CLKID_VCLK2]			= &axg_vclk2.hw,
+		[CLKID_VCLK_SEL]		= &axg_vclk_sel.hw,
+		[CLKID_VCLK2_SEL]		= &axg_vclk2_sel.hw,
+		[CLKID_VCLK_INPUT]		= &axg_vclk_input.hw,
+		[CLKID_VCLK2_INPUT]		= &axg_vclk2_input.hw,
+		[CLKID_VCLK_DIV]		= &axg_vclk_div.hw,
+		[CLKID_VCLK2_DIV]		= &axg_vclk2_div.hw,
+		[CLKID_VCLK_DIV2_EN]		= &axg_vclk_div2_en.hw,
+		[CLKID_VCLK_DIV4_EN]		= &axg_vclk_div4_en.hw,
+		[CLKID_VCLK_DIV6_EN]		= &axg_vclk_div6_en.hw,
+		[CLKID_VCLK_DIV12_EN]		= &axg_vclk_div12_en.hw,
+		[CLKID_VCLK2_DIV2_EN]		= &axg_vclk2_div2_en.hw,
+		[CLKID_VCLK2_DIV4_EN]		= &axg_vclk2_div4_en.hw,
+		[CLKID_VCLK2_DIV6_EN]		= &axg_vclk2_div6_en.hw,
+		[CLKID_VCLK2_DIV12_EN]		= &axg_vclk2_div12_en.hw,
+		[CLKID_VCLK_DIV1]		= &axg_vclk_div1.hw,
+		[CLKID_VCLK_DIV2]		= &axg_vclk_div2.hw,
+		[CLKID_VCLK_DIV4]		= &axg_vclk_div4.hw,
+		[CLKID_VCLK_DIV6]		= &axg_vclk_div6.hw,
+		[CLKID_VCLK_DIV12]		= &axg_vclk_div12.hw,
+		[CLKID_VCLK2_DIV1]		= &axg_vclk2_div1.hw,
+		[CLKID_VCLK2_DIV2]		= &axg_vclk2_div2.hw,
+		[CLKID_VCLK2_DIV4]		= &axg_vclk2_div4.hw,
+		[CLKID_VCLK2_DIV6]		= &axg_vclk2_div6.hw,
+		[CLKID_VCLK2_DIV12]		= &axg_vclk2_div12.hw,
+		[CLKID_CTS_ENCL_SEL]		= &axg_cts_encl_sel.hw,
+		[CLKID_CTS_ENCL]		= &axg_cts_encl.hw,
 		[NR_CLKS]			= NULL,
 	},
 	.num = NR_CLKS,
@@ -1341,6 +2082,39 @@ static struct clk_regmap *const axg_clk_regmaps[] = {
 	&axg_hifi_pll_dco,
 	&axg_pcie_pll_dco,
 	&axg_pcie_pll_od,
+	&axg_vpu_0_div,
+	&axg_vpu_0_sel,
+	&axg_vpu_0,
+	&axg_vpu_1_div,
+	&axg_vpu_1_sel,
+	&axg_vpu_1,
+	&axg_vpu,
+	&axg_vapb_0_div,
+	&axg_vapb_0_sel,
+	&axg_vapb_0,
+	&axg_vapb_1_div,
+	&axg_vapb_1_sel,
+	&axg_vapb_1,
+	&axg_vapb_sel,
+	&axg_vapb,
+	&axg_vclk,
+	&axg_vclk2,
+	&axg_vclk_sel,
+	&axg_vclk2_sel,
+	&axg_vclk_input,
+	&axg_vclk2_input,
+	&axg_vclk_div,
+	&axg_vclk2_div,
+	&axg_vclk_div2_en,
+	&axg_vclk_div4_en,
+	&axg_vclk_div6_en,
+	&axg_vclk_div12_en,
+	&axg_vclk2_div2_en,
+	&axg_vclk2_div4_en,
+	&axg_vclk2_div6_en,
+	&axg_vclk2_div12_en,
+	&axg_cts_encl_sel,
+	&axg_cts_encl,
 };
 
 static const struct meson_eeclkc_data axg_clkc_data = {
diff --git a/drivers/clk/meson/axg.h b/drivers/clk/meson/axg.h
index 0431dabac629..a8787b394a47 100644
--- a/drivers/clk/meson/axg.h
+++ b/drivers/clk/meson/axg.h
@@ -139,8 +139,27 @@
 #define CLKID_HIFI_PLL_DCO			88
 #define CLKID_PCIE_PLL_DCO			89
 #define CLKID_PCIE_PLL_OD			90
+#define CLKID_VPU_0_DIV				91
+#define CLKID_VPU_1_DIV				94
+#define CLKID_VAPB_0_DIV			98
+#define CLKID_VAPB_1_DIV			101
+#define CLKID_VCLK_SEL				108
+#define CLKID_VCLK2_SEL				109
+#define CLKID_VCLK_INPUT			110
+#define CLKID_VCLK2_INPUT			111
+#define CLKID_VCLK_DIV				112
+#define CLKID_VCLK2_DIV				113
+#define CLKID_VCLK_DIV2_EN			114
+#define CLKID_VCLK_DIV4_EN			115
+#define CLKID_VCLK_DIV6_EN			116
+#define CLKID_VCLK_DIV12_EN			117
+#define CLKID_VCLK2_DIV2_EN			118
+#define CLKID_VCLK2_DIV4_EN			119
+#define CLKID_VCLK2_DIV6_EN			120
+#define CLKID_VCLK2_DIV12_EN			121
+#define CLKID_CTS_ENCL_SEL			132
 
-#define NR_CLKS					91
+#define NR_CLKS					134
 
 /* include the CLKIDs that have been made part of the DT binding */
 #include <dt-bindings/clock/axg-clkc.h>
-- 
2.22.0


_______________________________________________
linux-amlogic mailing list
linux-amlogic@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-amlogic

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

* [PATCH 4/4] clk: meson: axg: add MIPI DSI Host clock
  2020-09-07  9:38 ` Neil Armstrong
  (?)
@ 2020-09-07  9:38   ` Neil Armstrong
  -1 siblings, 0 replies; 30+ messages in thread
From: Neil Armstrong @ 2020-09-07  9:38 UTC (permalink / raw)
  To: jbrunet
  Cc: linux-amlogic, linux-clk, linux-arm-kernel, linux-kernel, Neil Armstrong

This adds the MIPI DSI Host clock, used to measure the signal timings (ENC VSYNC or
DW-MIPI-DSI eDPI timings).

Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
---
 drivers/clk/meson/axg.c | 66 +++++++++++++++++++++++++++++++++++++++++
 drivers/clk/meson/axg.h |  4 ++-
 2 files changed, 69 insertions(+), 1 deletion(-)

diff --git a/drivers/clk/meson/axg.c b/drivers/clk/meson/axg.c
index 2550616c14b0..0094ca6388d8 100644
--- a/drivers/clk/meson/axg.c
+++ b/drivers/clk/meson/axg.c
@@ -1724,6 +1724,66 @@ static struct clk_regmap axg_cts_encl = {
 	},
 };
 
+/* MIPI DSI Host Clock */
+
+static const struct clk_parent_data axg_vdin_meas_parent_data[] = {
+	{ .fw_name = "xtal", },
+	{ .hw = &axg_fclk_div4.hw },
+	{ .hw = &axg_fclk_div3.hw },
+	{ .hw = &axg_fclk_div5.hw },
+	{ },
+	{ },
+	{ .hw = &axg_fclk_div2.hw },
+	{ .hw = &axg_fclk_div7.hw },
+};
+
+static struct clk_regmap axg_vdin_meas_sel = {
+	.data = &(struct clk_regmap_mux_data){
+		.offset = HHI_VDIN_MEAS_CLK_CNTL,
+		.mask = 0x7,
+		.shift = 21,
+		.flags = CLK_MUX_ROUND_CLOSEST,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "vdin_meas_sel",
+		.ops = &clk_regmap_mux_ops,
+		.parent_data = axg_vdin_meas_parent_data,
+		.num_parents = ARRAY_SIZE(axg_vdin_meas_parent_data),
+		.flags = CLK_SET_RATE_NO_REPARENT,
+	},
+};
+
+static struct clk_regmap axg_vdin_meas_div = {
+	.data = &(struct clk_regmap_div_data){
+		.offset = HHI_VDIN_MEAS_CLK_CNTL,
+		.shift = 12,
+		.width = 7,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "vdin_meas_div",
+		.ops = &clk_regmap_divider_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&axg_vdin_meas_sel.hw },
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap axg_vdin_meas = {
+	.data = &(struct clk_regmap_gate_data){
+		.offset = HHI_VDIN_MEAS_CLK_CNTL,
+		.bit_idx = 20,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "vdin_meas",
+		.ops = &clk_regmap_gate_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&axg_vdin_meas_div.hw },
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
 static u32 mux_table_gen_clk[]	= { 0, 4, 5, 6, 7, 8,
 				    9, 10, 11, 13, 14, };
 static const struct clk_parent_data gen_clk_parent_data[] = {
@@ -1987,6 +2047,9 @@ static struct clk_hw_onecell_data axg_hw_onecell_data = {
 		[CLKID_VCLK2_DIV12]		= &axg_vclk2_div12.hw,
 		[CLKID_CTS_ENCL_SEL]		= &axg_cts_encl_sel.hw,
 		[CLKID_CTS_ENCL]		= &axg_cts_encl.hw,
+		[CLKID_VDIN_MEAS_SEL]		= &axg_vdin_meas_sel.hw,
+		[CLKID_VDIN_MEAS_DIV]		= &axg_vdin_meas_div.hw,
+		[CLKID_VDIN_MEAS]		= &axg_vdin_meas.hw,
 		[NR_CLKS]			= NULL,
 	},
 	.num = NR_CLKS,
@@ -2115,6 +2178,9 @@ static struct clk_regmap *const axg_clk_regmaps[] = {
 	&axg_vclk2_div12_en,
 	&axg_cts_encl_sel,
 	&axg_cts_encl,
+	&axg_vdin_meas_sel,
+	&axg_vdin_meas_div,
+	&axg_vdin_meas,
 };
 
 static const struct meson_eeclkc_data axg_clkc_data = {
diff --git a/drivers/clk/meson/axg.h b/drivers/clk/meson/axg.h
index a8787b394a47..481b307ea3cb 100644
--- a/drivers/clk/meson/axg.h
+++ b/drivers/clk/meson/axg.h
@@ -158,8 +158,10 @@
 #define CLKID_VCLK2_DIV6_EN			120
 #define CLKID_VCLK2_DIV12_EN			121
 #define CLKID_CTS_ENCL_SEL			132
+#define CLKID_VDIN_MEAS_SEL			134
+#define CLKID_VDIN_MEAS_DIV			135
 
-#define NR_CLKS					134
+#define NR_CLKS					137
 
 /* include the CLKIDs that have been made part of the DT binding */
 #include <dt-bindings/clock/axg-clkc.h>
-- 
2.22.0


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

* [PATCH 4/4] clk: meson: axg: add MIPI DSI Host clock
@ 2020-09-07  9:38   ` Neil Armstrong
  0 siblings, 0 replies; 30+ messages in thread
From: Neil Armstrong @ 2020-09-07  9:38 UTC (permalink / raw)
  To: jbrunet
  Cc: linux-amlogic, Neil Armstrong, linux-clk, linux-arm-kernel, linux-kernel

This adds the MIPI DSI Host clock, used to measure the signal timings (ENC VSYNC or
DW-MIPI-DSI eDPI timings).

Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
---
 drivers/clk/meson/axg.c | 66 +++++++++++++++++++++++++++++++++++++++++
 drivers/clk/meson/axg.h |  4 ++-
 2 files changed, 69 insertions(+), 1 deletion(-)

diff --git a/drivers/clk/meson/axg.c b/drivers/clk/meson/axg.c
index 2550616c14b0..0094ca6388d8 100644
--- a/drivers/clk/meson/axg.c
+++ b/drivers/clk/meson/axg.c
@@ -1724,6 +1724,66 @@ static struct clk_regmap axg_cts_encl = {
 	},
 };
 
+/* MIPI DSI Host Clock */
+
+static const struct clk_parent_data axg_vdin_meas_parent_data[] = {
+	{ .fw_name = "xtal", },
+	{ .hw = &axg_fclk_div4.hw },
+	{ .hw = &axg_fclk_div3.hw },
+	{ .hw = &axg_fclk_div5.hw },
+	{ },
+	{ },
+	{ .hw = &axg_fclk_div2.hw },
+	{ .hw = &axg_fclk_div7.hw },
+};
+
+static struct clk_regmap axg_vdin_meas_sel = {
+	.data = &(struct clk_regmap_mux_data){
+		.offset = HHI_VDIN_MEAS_CLK_CNTL,
+		.mask = 0x7,
+		.shift = 21,
+		.flags = CLK_MUX_ROUND_CLOSEST,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "vdin_meas_sel",
+		.ops = &clk_regmap_mux_ops,
+		.parent_data = axg_vdin_meas_parent_data,
+		.num_parents = ARRAY_SIZE(axg_vdin_meas_parent_data),
+		.flags = CLK_SET_RATE_NO_REPARENT,
+	},
+};
+
+static struct clk_regmap axg_vdin_meas_div = {
+	.data = &(struct clk_regmap_div_data){
+		.offset = HHI_VDIN_MEAS_CLK_CNTL,
+		.shift = 12,
+		.width = 7,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "vdin_meas_div",
+		.ops = &clk_regmap_divider_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&axg_vdin_meas_sel.hw },
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap axg_vdin_meas = {
+	.data = &(struct clk_regmap_gate_data){
+		.offset = HHI_VDIN_MEAS_CLK_CNTL,
+		.bit_idx = 20,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "vdin_meas",
+		.ops = &clk_regmap_gate_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&axg_vdin_meas_div.hw },
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
 static u32 mux_table_gen_clk[]	= { 0, 4, 5, 6, 7, 8,
 				    9, 10, 11, 13, 14, };
 static const struct clk_parent_data gen_clk_parent_data[] = {
@@ -1987,6 +2047,9 @@ static struct clk_hw_onecell_data axg_hw_onecell_data = {
 		[CLKID_VCLK2_DIV12]		= &axg_vclk2_div12.hw,
 		[CLKID_CTS_ENCL_SEL]		= &axg_cts_encl_sel.hw,
 		[CLKID_CTS_ENCL]		= &axg_cts_encl.hw,
+		[CLKID_VDIN_MEAS_SEL]		= &axg_vdin_meas_sel.hw,
+		[CLKID_VDIN_MEAS_DIV]		= &axg_vdin_meas_div.hw,
+		[CLKID_VDIN_MEAS]		= &axg_vdin_meas.hw,
 		[NR_CLKS]			= NULL,
 	},
 	.num = NR_CLKS,
@@ -2115,6 +2178,9 @@ static struct clk_regmap *const axg_clk_regmaps[] = {
 	&axg_vclk2_div12_en,
 	&axg_cts_encl_sel,
 	&axg_cts_encl,
+	&axg_vdin_meas_sel,
+	&axg_vdin_meas_div,
+	&axg_vdin_meas,
 };
 
 static const struct meson_eeclkc_data axg_clkc_data = {
diff --git a/drivers/clk/meson/axg.h b/drivers/clk/meson/axg.h
index a8787b394a47..481b307ea3cb 100644
--- a/drivers/clk/meson/axg.h
+++ b/drivers/clk/meson/axg.h
@@ -158,8 +158,10 @@
 #define CLKID_VCLK2_DIV6_EN			120
 #define CLKID_VCLK2_DIV12_EN			121
 #define CLKID_CTS_ENCL_SEL			132
+#define CLKID_VDIN_MEAS_SEL			134
+#define CLKID_VDIN_MEAS_DIV			135
 
-#define NR_CLKS					134
+#define NR_CLKS					137
 
 /* include the CLKIDs that have been made part of the DT binding */
 #include <dt-bindings/clock/axg-clkc.h>
-- 
2.22.0


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [PATCH 4/4] clk: meson: axg: add MIPI DSI Host clock
@ 2020-09-07  9:38   ` Neil Armstrong
  0 siblings, 0 replies; 30+ messages in thread
From: Neil Armstrong @ 2020-09-07  9:38 UTC (permalink / raw)
  To: jbrunet
  Cc: linux-amlogic, Neil Armstrong, linux-clk, linux-arm-kernel, linux-kernel

This adds the MIPI DSI Host clock, used to measure the signal timings (ENC VSYNC or
DW-MIPI-DSI eDPI timings).

Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
---
 drivers/clk/meson/axg.c | 66 +++++++++++++++++++++++++++++++++++++++++
 drivers/clk/meson/axg.h |  4 ++-
 2 files changed, 69 insertions(+), 1 deletion(-)

diff --git a/drivers/clk/meson/axg.c b/drivers/clk/meson/axg.c
index 2550616c14b0..0094ca6388d8 100644
--- a/drivers/clk/meson/axg.c
+++ b/drivers/clk/meson/axg.c
@@ -1724,6 +1724,66 @@ static struct clk_regmap axg_cts_encl = {
 	},
 };
 
+/* MIPI DSI Host Clock */
+
+static const struct clk_parent_data axg_vdin_meas_parent_data[] = {
+	{ .fw_name = "xtal", },
+	{ .hw = &axg_fclk_div4.hw },
+	{ .hw = &axg_fclk_div3.hw },
+	{ .hw = &axg_fclk_div5.hw },
+	{ },
+	{ },
+	{ .hw = &axg_fclk_div2.hw },
+	{ .hw = &axg_fclk_div7.hw },
+};
+
+static struct clk_regmap axg_vdin_meas_sel = {
+	.data = &(struct clk_regmap_mux_data){
+		.offset = HHI_VDIN_MEAS_CLK_CNTL,
+		.mask = 0x7,
+		.shift = 21,
+		.flags = CLK_MUX_ROUND_CLOSEST,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "vdin_meas_sel",
+		.ops = &clk_regmap_mux_ops,
+		.parent_data = axg_vdin_meas_parent_data,
+		.num_parents = ARRAY_SIZE(axg_vdin_meas_parent_data),
+		.flags = CLK_SET_RATE_NO_REPARENT,
+	},
+};
+
+static struct clk_regmap axg_vdin_meas_div = {
+	.data = &(struct clk_regmap_div_data){
+		.offset = HHI_VDIN_MEAS_CLK_CNTL,
+		.shift = 12,
+		.width = 7,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "vdin_meas_div",
+		.ops = &clk_regmap_divider_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&axg_vdin_meas_sel.hw },
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap axg_vdin_meas = {
+	.data = &(struct clk_regmap_gate_data){
+		.offset = HHI_VDIN_MEAS_CLK_CNTL,
+		.bit_idx = 20,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "vdin_meas",
+		.ops = &clk_regmap_gate_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&axg_vdin_meas_div.hw },
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
 static u32 mux_table_gen_clk[]	= { 0, 4, 5, 6, 7, 8,
 				    9, 10, 11, 13, 14, };
 static const struct clk_parent_data gen_clk_parent_data[] = {
@@ -1987,6 +2047,9 @@ static struct clk_hw_onecell_data axg_hw_onecell_data = {
 		[CLKID_VCLK2_DIV12]		= &axg_vclk2_div12.hw,
 		[CLKID_CTS_ENCL_SEL]		= &axg_cts_encl_sel.hw,
 		[CLKID_CTS_ENCL]		= &axg_cts_encl.hw,
+		[CLKID_VDIN_MEAS_SEL]		= &axg_vdin_meas_sel.hw,
+		[CLKID_VDIN_MEAS_DIV]		= &axg_vdin_meas_div.hw,
+		[CLKID_VDIN_MEAS]		= &axg_vdin_meas.hw,
 		[NR_CLKS]			= NULL,
 	},
 	.num = NR_CLKS,
@@ -2115,6 +2178,9 @@ static struct clk_regmap *const axg_clk_regmaps[] = {
 	&axg_vclk2_div12_en,
 	&axg_cts_encl_sel,
 	&axg_cts_encl,
+	&axg_vdin_meas_sel,
+	&axg_vdin_meas_div,
+	&axg_vdin_meas,
 };
 
 static const struct meson_eeclkc_data axg_clkc_data = {
diff --git a/drivers/clk/meson/axg.h b/drivers/clk/meson/axg.h
index a8787b394a47..481b307ea3cb 100644
--- a/drivers/clk/meson/axg.h
+++ b/drivers/clk/meson/axg.h
@@ -158,8 +158,10 @@
 #define CLKID_VCLK2_DIV6_EN			120
 #define CLKID_VCLK2_DIV12_EN			121
 #define CLKID_CTS_ENCL_SEL			132
+#define CLKID_VDIN_MEAS_SEL			134
+#define CLKID_VDIN_MEAS_DIV			135
 
-#define NR_CLKS					134
+#define NR_CLKS					137
 
 /* include the CLKIDs that have been made part of the DT binding */
 #include <dt-bindings/clock/axg-clkc.h>
-- 
2.22.0


_______________________________________________
linux-amlogic mailing list
linux-amlogic@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-amlogic

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

* Re: [PATCH 3/4] clk: meson: axg: add Video Clocks
  2020-09-07  9:38   ` Neil Armstrong
  (?)
@ 2020-09-10 10:13     ` Jerome Brunet
  -1 siblings, 0 replies; 30+ messages in thread
From: Jerome Brunet @ 2020-09-10 10:13 UTC (permalink / raw)
  To: Neil Armstrong; +Cc: linux-amlogic, linux-clk, linux-arm-kernel, linux-kernel


On Mon 07 Sep 2020 at 11:38, Neil Armstrong <narmstrong@baylibre.com> wrote:

> Add the Video Clocks present on the Amlogic AXg SoCs.
>
> The AXG only has a single ENCL CTS clock and even if VCLK exist along VCLK2,
> only VCLK2 is used since it clocks the MIPI DSI IP directly.
>
> Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
> ---
>  drivers/clk/meson/axg.c | 774 ++++++++++++++++++++++++++++++++++++++++
>  drivers/clk/meson/axg.h |  21 +-
>  2 files changed, 794 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/clk/meson/axg.c b/drivers/clk/meson/axg.c
> index 13fc0006f63d..2550616c14b0 100644
> --- a/drivers/clk/meson/axg.c
> +++ b/drivers/clk/meson/axg.c
> @@ -1026,6 +1026,704 @@ static struct clk_regmap axg_sd_emmc_c_clk0 = {
>  	},
>  };
>  
> +/* VPU Clock */
> +
> +static const struct clk_hw *axg_vpu_parent_hws[] = {
> +	&axg_fclk_div4.hw,
> +	&axg_fclk_div3.hw,
> +	&axg_fclk_div5.hw,
> +	&axg_fclk_div7.hw,
> +};
> +
> +static struct clk_regmap axg_vpu_0_sel = {
> +	.data = &(struct clk_regmap_mux_data){
> +		.offset = HHI_VPU_CLK_CNTL,
> +		.mask = 0x3,
> +		.shift = 9,
> +	},
> +	.hw.init = &(struct clk_init_data){
> +		.name = "vpu_0_sel",
> +		.ops = &clk_regmap_mux_ops,
> +		/*
> +		 * bits 9:10 selects from 4 possible parents:
> +		 * fclk_div4, fclk_div3, fclk_div5, fclk_div7,
> +		 */

These comments (and the same bellow) are not very useful

> +		.parent_hws = axg_vpu_parent_hws,
> +		.num_parents = ARRAY_SIZE(axg_vpu_parent_hws),

Could you add a comment here explaining why parenting needs to be
manually controlled ?

> +		.flags = CLK_SET_RATE_NO_REPARENT,
> +	},
> +};
> +
> +static struct clk_regmap axg_vpu_0_div = {
> +	.data = &(struct clk_regmap_div_data){
> +		.offset = HHI_VPU_CLK_CNTL,
> +		.shift = 0,
> +		.width = 7,
> +	},
> +	.hw.init = &(struct clk_init_data){
> +		.name = "vpu_0_div",
> +		.ops = &clk_regmap_divider_ops,
> +		.parent_hws = (const struct clk_hw *[]) { &axg_vpu_0_sel.hw },
> +		.num_parents = 1,
> +		.flags = CLK_SET_RATE_PARENT,
> +	},
> +};
> +
> +static struct clk_regmap axg_vpu_0 = {
> +	.data = &(struct clk_regmap_gate_data){
> +		.offset = HHI_VPU_CLK_CNTL,
> +		.bit_idx = 8,
> +	},
> +	.hw.init = &(struct clk_init_data) {
> +		.name = "vpu_0",
> +		.ops = &clk_regmap_gate_ops,
> +		.parent_hws = (const struct clk_hw *[]) { &axg_vpu_0_div.hw },
> +		.num_parents = 1,
> +		.flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,

Why is UNUSED required ?

> +	},
> +};
> +
> +static struct clk_regmap axg_vpu_1_sel = {
> +	.data = &(struct clk_regmap_mux_data){
> +		.offset = HHI_VPU_CLK_CNTL,
> +		.mask = 0x3,
> +		.shift = 25,
> +	},
> +	.hw.init = &(struct clk_init_data){
> +		.name = "vpu_1_sel",
> +		.ops = &clk_regmap_mux_ops,
> +		/*
> +		 * bits 25:26 selects from 4 possible parents:
> +		 * fclk_div4, fclk_div3, fclk_div5, fclk_div7,
> +		 */
> +		.parent_hws = axg_vpu_parent_hws,
> +		.num_parents = ARRAY_SIZE(axg_vpu_parent_hws),
> +		.flags = CLK_SET_RATE_NO_REPARENT,
> +	},
> +};
> +
> +static struct clk_regmap axg_vpu_1_div = {
> +	.data = &(struct clk_regmap_div_data){
> +		.offset = HHI_VPU_CLK_CNTL,
> +		.shift = 16,
> +		.width = 7,
> +	},
> +	.hw.init = &(struct clk_init_data){
> +		.name = "vpu_1_div",
> +		.ops = &clk_regmap_divider_ops,
> +		.parent_hws = (const struct clk_hw *[]) { &axg_vpu_1_sel.hw },
> +		.num_parents = 1,
> +		.flags = CLK_SET_RATE_PARENT,
> +	},
> +};
> +
> +static struct clk_regmap axg_vpu_1 = {
> +	.data = &(struct clk_regmap_gate_data){
> +		.offset = HHI_VPU_CLK_CNTL,
> +		.bit_idx = 24,
> +	},
> +	.hw.init = &(struct clk_init_data) {
> +		.name = "vpu_1",
> +		.ops = &clk_regmap_gate_ops,
> +		.parent_hws = (const struct clk_hw *[]) { &axg_vpu_1_div.hw },
> +		.num_parents = 1,
> +		.flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
> +	},
> +};
> +
> +static struct clk_regmap axg_vpu = {
> +	.data = &(struct clk_regmap_mux_data){
> +		.offset = HHI_VPU_CLK_CNTL,
> +		.mask = 1,
> +		.shift = 31,
> +	},
> +	.hw.init = &(struct clk_init_data){
> +		.name = "vpu",
> +		.ops = &clk_regmap_mux_ops,
> +		/*
> +		 * bit 31 selects from 2 possible parents:
> +		 * vpu_0 or vpu_1
> +		 */
> +		.parent_hws = (const struct clk_hw *[]) {
> +			&axg_vpu_0.hw,
> +			&axg_vpu_1.hw
> +		},
> +		.num_parents = 2,
> +		.flags = CLK_SET_RATE_NO_REPARENT,
> +	},
> +};
> +
> +/* VAPB Clock */
> +
> +static const struct clk_hw *axg_vapb_parent_hws[] = {
> +	&axg_fclk_div4.hw,
> +	&axg_fclk_div3.hw,
> +	&axg_fclk_div5.hw,
> +	&axg_fclk_div7.hw,
> +};

This is the same as the vpu table. Could they share a single table ?

> +
> +static struct clk_regmap axg_vapb_0_sel = {
> +	.data = &(struct clk_regmap_mux_data){
> +		.offset = HHI_VAPBCLK_CNTL,
> +		.mask = 0x3,
> +		.shift = 9,
> +	},
> +	.hw.init = &(struct clk_init_data){
> +		.name = "vapb_0_sel",
> +		.ops = &clk_regmap_mux_ops,
> +		/*
> +		 * bits 9:10 selects from 4 possible parents:
> +		 * fclk_div4, fclk_div3, fclk_div5, fclk_div7,
> +		 */
> +		.parent_hws = axg_vapb_parent_hws,
> +		.num_parents = ARRAY_SIZE(axg_vapb_parent_hws),
> +		.flags = CLK_SET_RATE_NO_REPARENT,
> +	},
> +};
> +
> +static struct clk_regmap axg_vapb_0_div = {
> +	.data = &(struct clk_regmap_div_data){
> +		.offset = HHI_VAPBCLK_CNTL,
> +		.shift = 0,
> +		.width = 7,
> +	},
> +	.hw.init = &(struct clk_init_data){
> +		.name = "vapb_0_div",
> +		.ops = &clk_regmap_divider_ops,
> +		.parent_hws = (const struct clk_hw *[]) {
> +			&axg_vapb_0_sel.hw
> +		},
> +		.num_parents = 1,
> +		.flags = CLK_SET_RATE_PARENT,
> +	},
> +};
> +
> +static struct clk_regmap axg_vapb_0 = {
> +	.data = &(struct clk_regmap_gate_data){
> +		.offset = HHI_VAPBCLK_CNTL,
> +		.bit_idx = 8,
> +	},
> +	.hw.init = &(struct clk_init_data) {
> +		.name = "vapb_0",
> +		.ops = &clk_regmap_gate_ops,
> +		.parent_hws = (const struct clk_hw *[]) {
> +			&axg_vapb_0_div.hw
> +		},
> +		.num_parents = 1,
> +		.flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
> +	},
> +};
> +
> +static struct clk_regmap axg_vapb_1_sel = {
> +	.data = &(struct clk_regmap_mux_data){
> +		.offset = HHI_VAPBCLK_CNTL,
> +		.mask = 0x3,
> +		.shift = 25,
> +	},
> +	.hw.init = &(struct clk_init_data){
> +		.name = "vapb_1_sel",
> +		.ops = &clk_regmap_mux_ops,
> +		/*
> +		 * bits 25:26 selects from 4 possible parents:
> +		 * fclk_div4, fclk_div3, fclk_div5, fclk_div7,
> +		 */
> +		.parent_hws = axg_vapb_parent_hws,
> +		.num_parents = ARRAY_SIZE(axg_vapb_parent_hws),
> +		.flags = CLK_SET_RATE_NO_REPARENT,
> +	},
> +};
> +
> +static struct clk_regmap axg_vapb_1_div = {
> +	.data = &(struct clk_regmap_div_data){
> +		.offset = HHI_VAPBCLK_CNTL,
> +		.shift = 16,
> +		.width = 7,
> +	},
> +	.hw.init = &(struct clk_init_data){
> +		.name = "vapb_1_div",
> +		.ops = &clk_regmap_divider_ops,
> +		.parent_hws = (const struct clk_hw *[]) {
> +			&axg_vapb_1_sel.hw
> +		},
> +		.num_parents = 1,
> +		.flags = CLK_SET_RATE_PARENT,
> +	},
> +};
> +
> +static struct clk_regmap axg_vapb_1 = {
> +	.data = &(struct clk_regmap_gate_data){
> +		.offset = HHI_VAPBCLK_CNTL,
> +		.bit_idx = 24,
> +	},
> +	.hw.init = &(struct clk_init_data) {
> +		.name = "vapb_1",
> +		.ops = &clk_regmap_gate_ops,
> +		.parent_hws = (const struct clk_hw *[]) {
> +			&axg_vapb_1_div.hw
> +		},
> +		.num_parents = 1,
> +		.flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
> +	},
> +};
> +
> +static struct clk_regmap axg_vapb_sel = {
> +	.data = &(struct clk_regmap_mux_data){
> +		.offset = HHI_VAPBCLK_CNTL,
> +		.mask = 1,
> +		.shift = 31,
> +	},
> +	.hw.init = &(struct clk_init_data){
> +		.name = "vapb_sel",
> +		.ops = &clk_regmap_mux_ops,
> +		/*
> +		 * bit 31 selects from 2 possible parents:
> +		 * vapb_0 or vapb_1
> +		 */
> +		.parent_hws = (const struct clk_hw *[]) {
> +			&axg_vapb_0.hw,
> +			&axg_vapb_1.hw
> +		},
> +		.num_parents = 2,
> +		.flags = CLK_SET_RATE_NO_REPARENT,
> +	},
> +};
> +
> +static struct clk_regmap axg_vapb = {
> +	.data = &(struct clk_regmap_gate_data){
> +		.offset = HHI_VAPBCLK_CNTL,
> +		.bit_idx = 30,
> +	},
> +	.hw.init = &(struct clk_init_data) {
> +		.name = "vapb",
> +		.ops = &clk_regmap_gate_ops,
> +		.parent_hws = (const struct clk_hw *[]) { &axg_vapb_sel.hw },
> +		.num_parents = 1,
> +		.flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
> +	},
> +};
> +
> +/* Video Clocks */
> +
> +static const struct clk_hw *axg_vclk_parent_hws[] = {
> +	&axg_gp0_pll.hw,
> +	&axg_fclk_div4.hw,
> +	&axg_fclk_div3.hw,
> +	&axg_fclk_div5.hw,
> +	&axg_fclk_div2.hw,
> +	&axg_fclk_div7.hw,
> +	&axg_mpll1.hw,
> +};
> +
> +static struct clk_regmap axg_vclk_sel = {
> +	.data = &(struct clk_regmap_mux_data){
> +		.offset = HHI_VID_CLK_CNTL,
> +		.mask = 0x7,
> +		.shift = 16,
> +	},
> +	.hw.init = &(struct clk_init_data){
> +		.name = "vclk_sel",
> +		.ops = &clk_regmap_mux_ops,
> +		.parent_hws = axg_vclk_parent_hws,
> +		.num_parents = ARRAY_SIZE(axg_vclk_parent_hws),
> +		.flags = CLK_SET_RATE_NO_REPARENT | CLK_GET_RATE_NOCACHE,
> +	},

Why is NOCACHE ? Is there something poking behind CCF back ? if yes, why
is this required ?

> +};
> +
> +static struct clk_regmap axg_vclk2_sel = {
> +	.data = &(struct clk_regmap_mux_data){
> +		.offset = HHI_VIID_CLK_CNTL,
> +		.mask = 0x7,
> +		.shift = 16,
> +	},
> +	.hw.init = &(struct clk_init_data){
> +		.name = "vclk2_sel",
> +		.ops = &clk_regmap_mux_ops,
> +		.parent_hws = axg_vclk_parent_hws,
> +		.num_parents = ARRAY_SIZE(axg_vclk_parent_hws),
> +		.flags = CLK_SET_RATE_NO_REPARENT | CLK_GET_RATE_NOCACHE,
> +	},
> +};
> +
> +static struct clk_regmap axg_vclk_input = {
> +	.data = &(struct clk_regmap_gate_data){
> +		.offset = HHI_VID_CLK_DIV,
> +		.bit_idx = 16,
> +	},
> +	.hw.init = &(struct clk_init_data) {
> +		.name = "vclk_input",
> +		.ops = &clk_regmap_gate_ops,
> +		.parent_hws = (const struct clk_hw *[]) { &axg_vclk_sel.hw },
> +		.num_parents = 1,
> +		.flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
> +	},
> +};
> +
> +static struct clk_regmap axg_vclk2_input = {
> +	.data = &(struct clk_regmap_gate_data){
> +		.offset = HHI_VIID_CLK_DIV,
> +		.bit_idx = 16,
> +	},
> +	.hw.init = &(struct clk_init_data) {
> +		.name = "vclk2_input",
> +		.ops = &clk_regmap_gate_ops,
> +		.parent_hws = (const struct clk_hw *[]) { &axg_vclk2_sel.hw },
> +		.num_parents = 1,
> +		.flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
> +	},
> +};
> +
> +static struct clk_regmap axg_vclk_div = {
> +	.data = &(struct clk_regmap_div_data){
> +		.offset = HHI_VID_CLK_DIV,
> +		.shift = 0,
> +		.width = 8,
> +	},
> +	.hw.init = &(struct clk_init_data){
> +		.name = "vclk_div",
> +		.ops = &clk_regmap_divider_ops,
> +		.parent_hws = (const struct clk_hw *[]) {
> +			&axg_vclk_input.hw
> +		},
> +		.num_parents = 1,
> +		.flags = CLK_GET_RATE_NOCACHE,
> +	},
> +};
> +
> +static struct clk_regmap axg_vclk2_div = {
> +	.data = &(struct clk_regmap_div_data){
> +		.offset = HHI_VIID_CLK_DIV,
> +		.shift = 0,
> +		.width = 8,
> +	},
> +	.hw.init = &(struct clk_init_data){
> +		.name = "vclk2_div",
> +		.ops = &clk_regmap_divider_ops,
> +		.parent_hws = (const struct clk_hw *[]) {
> +			&axg_vclk2_input.hw
> +		},
> +		.num_parents = 1,
> +		.flags = CLK_GET_RATE_NOCACHE,
> +	},
> +};
> +
> +static struct clk_regmap axg_vclk = {
> +	.data = &(struct clk_regmap_gate_data){
> +		.offset = HHI_VID_CLK_CNTL,
> +		.bit_idx = 19,
> +	},
> +	.hw.init = &(struct clk_init_data) {
> +		.name = "vclk",
> +		.ops = &clk_regmap_gate_ops,
> +		.parent_hws = (const struct clk_hw *[]) { &axg_vclk_div.hw },
> +		.num_parents = 1,
> +		.flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
> +	},
> +};
> +
> +static struct clk_regmap axg_vclk2 = {
> +	.data = &(struct clk_regmap_gate_data){
> +		.offset = HHI_VIID_CLK_CNTL,
> +		.bit_idx = 19,
> +	},
> +	.hw.init = &(struct clk_init_data) {
> +		.name = "vclk2",
> +		.ops = &clk_regmap_gate_ops,
> +		.parent_hws = (const struct clk_hw *[]) { &axg_vclk2_div.hw },
> +		.num_parents = 1,
> +		.flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
> +	},
> +};
> +
> +static struct clk_regmap axg_vclk_div1 = {
> +	.data = &(struct clk_regmap_gate_data){
> +		.offset = HHI_VID_CLK_CNTL,
> +		.bit_idx = 0,
> +	},
> +	.hw.init = &(struct clk_init_data) {
> +		.name = "vclk_div1",
> +		.ops = &clk_regmap_gate_ops,
> +		.parent_hws = (const struct clk_hw *[]) { &axg_vclk.hw },
> +		.num_parents = 1,
> +		.flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
> +	},
> +};
> +
> +static struct clk_regmap axg_vclk_div2_en = {
> +	.data = &(struct clk_regmap_gate_data){
> +		.offset = HHI_VID_CLK_CNTL,
> +		.bit_idx = 1,
> +	},
> +	.hw.init = &(struct clk_init_data) {
> +		.name = "vclk_div2_en",
> +		.ops = &clk_regmap_gate_ops,
> +		.parent_hws = (const struct clk_hw *[]) { &axg_vclk.hw },
> +		.num_parents = 1,
> +		.flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
> +	},
> +};
> +
> +static struct clk_regmap axg_vclk_div4_en = {
> +	.data = &(struct clk_regmap_gate_data){
> +		.offset = HHI_VID_CLK_CNTL,
> +		.bit_idx = 2,
> +	},
> +	.hw.init = &(struct clk_init_data) {
> +		.name = "vclk_div4_en",
> +		.ops = &clk_regmap_gate_ops,
> +		.parent_hws = (const struct clk_hw *[]) { &axg_vclk.hw },
> +		.num_parents = 1,
> +		.flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
> +	},
> +};
> +
> +static struct clk_regmap axg_vclk_div6_en = {
> +	.data = &(struct clk_regmap_gate_data){
> +		.offset = HHI_VID_CLK_CNTL,
> +		.bit_idx = 3,
> +	},
> +	.hw.init = &(struct clk_init_data) {
> +		.name = "vclk_div6_en",
> +		.ops = &clk_regmap_gate_ops,
> +		.parent_hws = (const struct clk_hw *[]) { &axg_vclk.hw },
> +		.num_parents = 1,
> +		.flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
> +	},
> +};
> +
> +static struct clk_regmap axg_vclk_div12_en = {
> +	.data = &(struct clk_regmap_gate_data){
> +		.offset = HHI_VID_CLK_CNTL,
> +		.bit_idx = 4,
> +	},
> +	.hw.init = &(struct clk_init_data) {
> +		.name = "vclk_div12_en",
> +		.ops = &clk_regmap_gate_ops,
> +		.parent_hws = (const struct clk_hw *[]) { &axg_vclk.hw },
> +		.num_parents = 1,
> +		.flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
> +	},
> +};
> +
> +static struct clk_regmap axg_vclk2_div1 = {
> +	.data = &(struct clk_regmap_gate_data){
> +		.offset = HHI_VIID_CLK_CNTL,
> +		.bit_idx = 0,
> +	},
> +	.hw.init = &(struct clk_init_data) {
> +		.name = "vclk2_div1",
> +		.ops = &clk_regmap_gate_ops,
> +		.parent_hws = (const struct clk_hw *[]) { &axg_vclk2.hw },
> +		.num_parents = 1,
> +		.flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
> +	},
> +};
> +
> +static struct clk_regmap axg_vclk2_div2_en = {
> +	.data = &(struct clk_regmap_gate_data){
> +		.offset = HHI_VIID_CLK_CNTL,
> +		.bit_idx = 1,
> +	},
> +	.hw.init = &(struct clk_init_data) {
> +		.name = "vclk2_div2_en",
> +		.ops = &clk_regmap_gate_ops,
> +		.parent_hws = (const struct clk_hw *[]) { &axg_vclk2.hw },
> +		.num_parents = 1,
> +		.flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
> +	},
> +};
> +
> +static struct clk_regmap axg_vclk2_div4_en = {
> +	.data = &(struct clk_regmap_gate_data){
> +		.offset = HHI_VIID_CLK_CNTL,
> +		.bit_idx = 2,
> +	},
> +	.hw.init = &(struct clk_init_data) {
> +		.name = "vclk2_div4_en",
> +		.ops = &clk_regmap_gate_ops,
> +		.parent_hws = (const struct clk_hw *[]) { &axg_vclk2.hw },
> +		.num_parents = 1,
> +		.flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
> +	},
> +};
> +
> +static struct clk_regmap axg_vclk2_div6_en = {
> +	.data = &(struct clk_regmap_gate_data){
> +		.offset = HHI_VIID_CLK_CNTL,
> +		.bit_idx = 3,
> +	},
> +	.hw.init = &(struct clk_init_data) {
> +		.name = "vclk2_div6_en",
> +		.ops = &clk_regmap_gate_ops,
> +		.parent_hws = (const struct clk_hw *[]) { &axg_vclk2.hw },
> +		.num_parents = 1,
> +		.flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
> +	},
> +};
> +
> +static struct clk_regmap axg_vclk2_div12_en = {
> +	.data = &(struct clk_regmap_gate_data){
> +		.offset = HHI_VIID_CLK_CNTL,
> +		.bit_idx = 4,
> +	},
> +	.hw.init = &(struct clk_init_data) {
> +		.name = "vclk2_div12_en",
> +		.ops = &clk_regmap_gate_ops,
> +		.parent_hws = (const struct clk_hw *[]) { &axg_vclk2.hw },
> +		.num_parents = 1,
> +		.flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
> +	},
> +};
> +
> +static struct clk_fixed_factor axg_vclk_div2 = {
> +	.mult = 1,
> +	.div = 2,
> +	.hw.init = &(struct clk_init_data){
> +		.name = "vclk_div2",
> +		.ops = &clk_fixed_factor_ops,
> +		.parent_hws = (const struct clk_hw *[]) {
> +			&axg_vclk_div2_en.hw
> +		},
> +		.num_parents = 1,
> +	},
> +};
> +
> +static struct clk_fixed_factor axg_vclk_div4 = {
> +	.mult = 1,
> +	.div = 4,
> +	.hw.init = &(struct clk_init_data){
> +		.name = "vclk_div4",
> +		.ops = &clk_fixed_factor_ops,
> +		.parent_hws = (const struct clk_hw *[]) {
> +			&axg_vclk_div4_en.hw
> +		},
> +		.num_parents = 1,
> +	},
> +};
> +
> +static struct clk_fixed_factor axg_vclk_div6 = {
> +	.mult = 1,
> +	.div = 6,
> +	.hw.init = &(struct clk_init_data){
> +		.name = "vclk_div6",
> +		.ops = &clk_fixed_factor_ops,
> +		.parent_hws = (const struct clk_hw *[]) {
> +			&axg_vclk_div6_en.hw
> +		},
> +		.num_parents = 1,
> +	},
> +};
> +
> +static struct clk_fixed_factor axg_vclk_div12 = {
> +	.mult = 1,
> +	.div = 12,
> +	.hw.init = &(struct clk_init_data){
> +		.name = "vclk_div12",
> +		.ops = &clk_fixed_factor_ops,
> +		.parent_hws = (const struct clk_hw *[]) {
> +			&axg_vclk_div12_en.hw
> +		},
> +		.num_parents = 1,
> +	},
> +};
> +
> +static struct clk_fixed_factor axg_vclk2_div2 = {
> +	.mult = 1,
> +	.div = 2,
> +	.hw.init = &(struct clk_init_data){
> +		.name = "vclk2_div2",
> +		.ops = &clk_fixed_factor_ops,
> +		.parent_hws = (const struct clk_hw *[]) {
> +			&axg_vclk2_div2_en.hw
> +		},
> +		.num_parents = 1,
> +	},
> +};
> +
> +static struct clk_fixed_factor axg_vclk2_div4 = {
> +	.mult = 1,
> +	.div = 4,
> +	.hw.init = &(struct clk_init_data){
> +		.name = "vclk2_div4",
> +		.ops = &clk_fixed_factor_ops,
> +		.parent_hws = (const struct clk_hw *[]) {
> +			&axg_vclk2_div4_en.hw
> +		},
> +		.num_parents = 1,
> +	},
> +};
> +
> +static struct clk_fixed_factor axg_vclk2_div6 = {
> +	.mult = 1,
> +	.div = 6,
> +	.hw.init = &(struct clk_init_data){
> +		.name = "vclk2_div6",
> +		.ops = &clk_fixed_factor_ops,
> +		.parent_hws = (const struct clk_hw *[]) {
> +			&axg_vclk2_div6_en.hw
> +		},
> +		.num_parents = 1,
> +	},
> +};
> +
> +static struct clk_fixed_factor axg_vclk2_div12 = {
> +	.mult = 1,
> +	.div = 12,
> +	.hw.init = &(struct clk_init_data){
> +		.name = "vclk2_div12",
> +		.ops = &clk_fixed_factor_ops,
> +		.parent_hws = (const struct clk_hw *[]) {
> +			&axg_vclk2_div12_en.hw
> +		},
> +		.num_parents = 1,
> +	},
> +};
> +
> +static u32 mux_table_cts_sel[] = { 0, 1, 2, 3, 4, 8, 9, 10, 11, 12 };
> +static const struct clk_hw *axg_cts_parent_hws[] = {
> +	&axg_vclk_div1.hw,
> +	&axg_vclk_div2.hw,
> +	&axg_vclk_div4.hw,
> +	&axg_vclk_div6.hw,
> +	&axg_vclk_div12.hw,
> +	&axg_vclk2_div1.hw,
> +	&axg_vclk2_div2.hw,
> +	&axg_vclk2_div4.hw,
> +	&axg_vclk2_div6.hw,
> +	&axg_vclk2_div12.hw,
> +};
> +
> +static struct clk_regmap axg_cts_encl_sel = {
> +	.data = &(struct clk_regmap_mux_data){
> +		.offset = HHI_VIID_CLK_DIV,
> +		.mask = 0xf,
> +		.shift = 12,
> +		.table = mux_table_cts_sel,
> +	},
> +	.hw.init = &(struct clk_init_data){
> +		.name = "cts_encl_sel",
> +		.ops = &clk_regmap_mux_ops,
> +		.parent_hws = axg_cts_parent_hws,
> +		.num_parents = ARRAY_SIZE(axg_cts_parent_hws),
> +		.flags = CLK_SET_RATE_NO_REPARENT | CLK_GET_RATE_NOCACHE,
> +	},
> +};
> +
> +static struct clk_regmap axg_cts_encl = {
> +	.data = &(struct clk_regmap_gate_data){
> +		.offset = HHI_VID_CLK_CNTL2,
> +		.bit_idx = 3,
> +	},
> +	.hw.init = &(struct clk_init_data) {
> +		.name = "cts_encl",
> +		.ops = &clk_regmap_gate_ops,
> +		.parent_hws = (const struct clk_hw *[]) {
> +			&axg_cts_encl_sel.hw
> +		},
> +		.num_parents = 1,
> +		.flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
> +	},
> +};
> +
>  static u32 mux_table_gen_clk[]	= { 0, 4, 5, 6, 7, 8,
>  				    9, 10, 11, 13, 14, };
>  static const struct clk_parent_data gen_clk_parent_data[] = {
> @@ -1246,6 +1944,49 @@ static struct clk_hw_onecell_data axg_hw_onecell_data = {
>  		[CLKID_HIFI_PLL_DCO]		= &axg_hifi_pll_dco.hw,
>  		[CLKID_PCIE_PLL_DCO]		= &axg_pcie_pll_dco.hw,
>  		[CLKID_PCIE_PLL_OD]		= &axg_pcie_pll_od.hw,
> +		[CLKID_VPU_0_DIV]		= &axg_vpu_0_div.hw,
> +		[CLKID_VPU_0_SEL]		= &axg_vpu_0_sel.hw,
> +		[CLKID_VPU_0]			= &axg_vpu_0.hw,
> +		[CLKID_VPU_1_DIV]		= &axg_vpu_1_div.hw,
> +		[CLKID_VPU_1_SEL]		= &axg_vpu_1_sel.hw,
> +		[CLKID_VPU_1]			= &axg_vpu_1.hw,
> +		[CLKID_VPU]			= &axg_vpu.hw,
> +		[CLKID_VAPB_0_DIV]		= &axg_vapb_0_div.hw,
> +		[CLKID_VAPB_0_SEL]		= &axg_vapb_0_sel.hw,
> +		[CLKID_VAPB_0]			= &axg_vapb_0.hw,
> +		[CLKID_VAPB_1_DIV]		= &axg_vapb_1_div.hw,
> +		[CLKID_VAPB_1_SEL]		= &axg_vapb_1_sel.hw,
> +		[CLKID_VAPB_1]			= &axg_vapb_1.hw,
> +		[CLKID_VAPB_SEL]		= &axg_vapb_sel.hw,
> +		[CLKID_VAPB]			= &axg_vapb.hw,
> +		[CLKID_VCLK]			= &axg_vclk.hw,
> +		[CLKID_VCLK2]			= &axg_vclk2.hw,
> +		[CLKID_VCLK_SEL]		= &axg_vclk_sel.hw,
> +		[CLKID_VCLK2_SEL]		= &axg_vclk2_sel.hw,
> +		[CLKID_VCLK_INPUT]		= &axg_vclk_input.hw,
> +		[CLKID_VCLK2_INPUT]		= &axg_vclk2_input.hw,
> +		[CLKID_VCLK_DIV]		= &axg_vclk_div.hw,
> +		[CLKID_VCLK2_DIV]		= &axg_vclk2_div.hw,
> +		[CLKID_VCLK_DIV2_EN]		= &axg_vclk_div2_en.hw,
> +		[CLKID_VCLK_DIV4_EN]		= &axg_vclk_div4_en.hw,
> +		[CLKID_VCLK_DIV6_EN]		= &axg_vclk_div6_en.hw,
> +		[CLKID_VCLK_DIV12_EN]		= &axg_vclk_div12_en.hw,
> +		[CLKID_VCLK2_DIV2_EN]		= &axg_vclk2_div2_en.hw,
> +		[CLKID_VCLK2_DIV4_EN]		= &axg_vclk2_div4_en.hw,
> +		[CLKID_VCLK2_DIV6_EN]		= &axg_vclk2_div6_en.hw,
> +		[CLKID_VCLK2_DIV12_EN]		= &axg_vclk2_div12_en.hw,
> +		[CLKID_VCLK_DIV1]		= &axg_vclk_div1.hw,
> +		[CLKID_VCLK_DIV2]		= &axg_vclk_div2.hw,
> +		[CLKID_VCLK_DIV4]		= &axg_vclk_div4.hw,
> +		[CLKID_VCLK_DIV6]		= &axg_vclk_div6.hw,
> +		[CLKID_VCLK_DIV12]		= &axg_vclk_div12.hw,
> +		[CLKID_VCLK2_DIV1]		= &axg_vclk2_div1.hw,
> +		[CLKID_VCLK2_DIV2]		= &axg_vclk2_div2.hw,
> +		[CLKID_VCLK2_DIV4]		= &axg_vclk2_div4.hw,
> +		[CLKID_VCLK2_DIV6]		= &axg_vclk2_div6.hw,
> +		[CLKID_VCLK2_DIV12]		= &axg_vclk2_div12.hw,
> +		[CLKID_CTS_ENCL_SEL]		= &axg_cts_encl_sel.hw,
> +		[CLKID_CTS_ENCL]		= &axg_cts_encl.hw,
>  		[NR_CLKS]			= NULL,
>  	},
>  	.num = NR_CLKS,
> @@ -1341,6 +2082,39 @@ static struct clk_regmap *const axg_clk_regmaps[] = {
>  	&axg_hifi_pll_dco,
>  	&axg_pcie_pll_dco,
>  	&axg_pcie_pll_od,
> +	&axg_vpu_0_div,
> +	&axg_vpu_0_sel,
> +	&axg_vpu_0,
> +	&axg_vpu_1_div,
> +	&axg_vpu_1_sel,
> +	&axg_vpu_1,
> +	&axg_vpu,
> +	&axg_vapb_0_div,
> +	&axg_vapb_0_sel,
> +	&axg_vapb_0,
> +	&axg_vapb_1_div,
> +	&axg_vapb_1_sel,
> +	&axg_vapb_1,
> +	&axg_vapb_sel,
> +	&axg_vapb,
> +	&axg_vclk,
> +	&axg_vclk2,
> +	&axg_vclk_sel,
> +	&axg_vclk2_sel,
> +	&axg_vclk_input,
> +	&axg_vclk2_input,
> +	&axg_vclk_div,
> +	&axg_vclk2_div,
> +	&axg_vclk_div2_en,
> +	&axg_vclk_div4_en,
> +	&axg_vclk_div6_en,
> +	&axg_vclk_div12_en,
> +	&axg_vclk2_div2_en,
> +	&axg_vclk2_div4_en,
> +	&axg_vclk2_div6_en,
> +	&axg_vclk2_div12_en,
> +	&axg_cts_encl_sel,
> +	&axg_cts_encl,
>  };
>  
>  static const struct meson_eeclkc_data axg_clkc_data = {
> diff --git a/drivers/clk/meson/axg.h b/drivers/clk/meson/axg.h
> index 0431dabac629..a8787b394a47 100644
> --- a/drivers/clk/meson/axg.h
> +++ b/drivers/clk/meson/axg.h
> @@ -139,8 +139,27 @@
>  #define CLKID_HIFI_PLL_DCO			88
>  #define CLKID_PCIE_PLL_DCO			89
>  #define CLKID_PCIE_PLL_OD			90
> +#define CLKID_VPU_0_DIV				91
> +#define CLKID_VPU_1_DIV				94
> +#define CLKID_VAPB_0_DIV			98
> +#define CLKID_VAPB_1_DIV			101
> +#define CLKID_VCLK_SEL				108
> +#define CLKID_VCLK2_SEL				109
> +#define CLKID_VCLK_INPUT			110
> +#define CLKID_VCLK2_INPUT			111
> +#define CLKID_VCLK_DIV				112
> +#define CLKID_VCLK2_DIV				113
> +#define CLKID_VCLK_DIV2_EN			114
> +#define CLKID_VCLK_DIV4_EN			115
> +#define CLKID_VCLK_DIV6_EN			116
> +#define CLKID_VCLK_DIV12_EN			117
> +#define CLKID_VCLK2_DIV2_EN			118
> +#define CLKID_VCLK2_DIV4_EN			119
> +#define CLKID_VCLK2_DIV6_EN			120
> +#define CLKID_VCLK2_DIV12_EN			121
> +#define CLKID_CTS_ENCL_SEL			132
>  
> -#define NR_CLKS					91
> +#define NR_CLKS					134
>  
>  /* include the CLKIDs that have been made part of the DT binding */
>  #include <dt-bindings/clock/axg-clkc.h>

Overall, there is quite an heavy use of CLK_IGNORE_USED and
CLK_GET_RATE_NOCACHE which seems to indicate that something else is
poking around in the clocks registers

Details about why it should be done this way, and not through CCF API,
should be provided.

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

* Re: [PATCH 3/4] clk: meson: axg: add Video Clocks
@ 2020-09-10 10:13     ` Jerome Brunet
  0 siblings, 0 replies; 30+ messages in thread
From: Jerome Brunet @ 2020-09-10 10:13 UTC (permalink / raw)
  To: Neil Armstrong; +Cc: linux-amlogic, linux-clk, linux-arm-kernel, linux-kernel


On Mon 07 Sep 2020 at 11:38, Neil Armstrong <narmstrong@baylibre.com> wrote:

> Add the Video Clocks present on the Amlogic AXg SoCs.
>
> The AXG only has a single ENCL CTS clock and even if VCLK exist along VCLK2,
> only VCLK2 is used since it clocks the MIPI DSI IP directly.
>
> Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
> ---
>  drivers/clk/meson/axg.c | 774 ++++++++++++++++++++++++++++++++++++++++
>  drivers/clk/meson/axg.h |  21 +-
>  2 files changed, 794 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/clk/meson/axg.c b/drivers/clk/meson/axg.c
> index 13fc0006f63d..2550616c14b0 100644
> --- a/drivers/clk/meson/axg.c
> +++ b/drivers/clk/meson/axg.c
> @@ -1026,6 +1026,704 @@ static struct clk_regmap axg_sd_emmc_c_clk0 = {
>  	},
>  };
>  
> +/* VPU Clock */
> +
> +static const struct clk_hw *axg_vpu_parent_hws[] = {
> +	&axg_fclk_div4.hw,
> +	&axg_fclk_div3.hw,
> +	&axg_fclk_div5.hw,
> +	&axg_fclk_div7.hw,
> +};
> +
> +static struct clk_regmap axg_vpu_0_sel = {
> +	.data = &(struct clk_regmap_mux_data){
> +		.offset = HHI_VPU_CLK_CNTL,
> +		.mask = 0x3,
> +		.shift = 9,
> +	},
> +	.hw.init = &(struct clk_init_data){
> +		.name = "vpu_0_sel",
> +		.ops = &clk_regmap_mux_ops,
> +		/*
> +		 * bits 9:10 selects from 4 possible parents:
> +		 * fclk_div4, fclk_div3, fclk_div5, fclk_div7,
> +		 */

These comments (and the same bellow) are not very useful

> +		.parent_hws = axg_vpu_parent_hws,
> +		.num_parents = ARRAY_SIZE(axg_vpu_parent_hws),

Could you add a comment here explaining why parenting needs to be
manually controlled ?

> +		.flags = CLK_SET_RATE_NO_REPARENT,
> +	},
> +};
> +
> +static struct clk_regmap axg_vpu_0_div = {
> +	.data = &(struct clk_regmap_div_data){
> +		.offset = HHI_VPU_CLK_CNTL,
> +		.shift = 0,
> +		.width = 7,
> +	},
> +	.hw.init = &(struct clk_init_data){
> +		.name = "vpu_0_div",
> +		.ops = &clk_regmap_divider_ops,
> +		.parent_hws = (const struct clk_hw *[]) { &axg_vpu_0_sel.hw },
> +		.num_parents = 1,
> +		.flags = CLK_SET_RATE_PARENT,
> +	},
> +};
> +
> +static struct clk_regmap axg_vpu_0 = {
> +	.data = &(struct clk_regmap_gate_data){
> +		.offset = HHI_VPU_CLK_CNTL,
> +		.bit_idx = 8,
> +	},
> +	.hw.init = &(struct clk_init_data) {
> +		.name = "vpu_0",
> +		.ops = &clk_regmap_gate_ops,
> +		.parent_hws = (const struct clk_hw *[]) { &axg_vpu_0_div.hw },
> +		.num_parents = 1,
> +		.flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,

Why is UNUSED required ?

> +	},
> +};
> +
> +static struct clk_regmap axg_vpu_1_sel = {
> +	.data = &(struct clk_regmap_mux_data){
> +		.offset = HHI_VPU_CLK_CNTL,
> +		.mask = 0x3,
> +		.shift = 25,
> +	},
> +	.hw.init = &(struct clk_init_data){
> +		.name = "vpu_1_sel",
> +		.ops = &clk_regmap_mux_ops,
> +		/*
> +		 * bits 25:26 selects from 4 possible parents:
> +		 * fclk_div4, fclk_div3, fclk_div5, fclk_div7,
> +		 */
> +		.parent_hws = axg_vpu_parent_hws,
> +		.num_parents = ARRAY_SIZE(axg_vpu_parent_hws),
> +		.flags = CLK_SET_RATE_NO_REPARENT,
> +	},
> +};
> +
> +static struct clk_regmap axg_vpu_1_div = {
> +	.data = &(struct clk_regmap_div_data){
> +		.offset = HHI_VPU_CLK_CNTL,
> +		.shift = 16,
> +		.width = 7,
> +	},
> +	.hw.init = &(struct clk_init_data){
> +		.name = "vpu_1_div",
> +		.ops = &clk_regmap_divider_ops,
> +		.parent_hws = (const struct clk_hw *[]) { &axg_vpu_1_sel.hw },
> +		.num_parents = 1,
> +		.flags = CLK_SET_RATE_PARENT,
> +	},
> +};
> +
> +static struct clk_regmap axg_vpu_1 = {
> +	.data = &(struct clk_regmap_gate_data){
> +		.offset = HHI_VPU_CLK_CNTL,
> +		.bit_idx = 24,
> +	},
> +	.hw.init = &(struct clk_init_data) {
> +		.name = "vpu_1",
> +		.ops = &clk_regmap_gate_ops,
> +		.parent_hws = (const struct clk_hw *[]) { &axg_vpu_1_div.hw },
> +		.num_parents = 1,
> +		.flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
> +	},
> +};
> +
> +static struct clk_regmap axg_vpu = {
> +	.data = &(struct clk_regmap_mux_data){
> +		.offset = HHI_VPU_CLK_CNTL,
> +		.mask = 1,
> +		.shift = 31,
> +	},
> +	.hw.init = &(struct clk_init_data){
> +		.name = "vpu",
> +		.ops = &clk_regmap_mux_ops,
> +		/*
> +		 * bit 31 selects from 2 possible parents:
> +		 * vpu_0 or vpu_1
> +		 */
> +		.parent_hws = (const struct clk_hw *[]) {
> +			&axg_vpu_0.hw,
> +			&axg_vpu_1.hw
> +		},
> +		.num_parents = 2,
> +		.flags = CLK_SET_RATE_NO_REPARENT,
> +	},
> +};
> +
> +/* VAPB Clock */
> +
> +static const struct clk_hw *axg_vapb_parent_hws[] = {
> +	&axg_fclk_div4.hw,
> +	&axg_fclk_div3.hw,
> +	&axg_fclk_div5.hw,
> +	&axg_fclk_div7.hw,
> +};

This is the same as the vpu table. Could they share a single table ?

> +
> +static struct clk_regmap axg_vapb_0_sel = {
> +	.data = &(struct clk_regmap_mux_data){
> +		.offset = HHI_VAPBCLK_CNTL,
> +		.mask = 0x3,
> +		.shift = 9,
> +	},
> +	.hw.init = &(struct clk_init_data){
> +		.name = "vapb_0_sel",
> +		.ops = &clk_regmap_mux_ops,
> +		/*
> +		 * bits 9:10 selects from 4 possible parents:
> +		 * fclk_div4, fclk_div3, fclk_div5, fclk_div7,
> +		 */
> +		.parent_hws = axg_vapb_parent_hws,
> +		.num_parents = ARRAY_SIZE(axg_vapb_parent_hws),
> +		.flags = CLK_SET_RATE_NO_REPARENT,
> +	},
> +};
> +
> +static struct clk_regmap axg_vapb_0_div = {
> +	.data = &(struct clk_regmap_div_data){
> +		.offset = HHI_VAPBCLK_CNTL,
> +		.shift = 0,
> +		.width = 7,
> +	},
> +	.hw.init = &(struct clk_init_data){
> +		.name = "vapb_0_div",
> +		.ops = &clk_regmap_divider_ops,
> +		.parent_hws = (const struct clk_hw *[]) {
> +			&axg_vapb_0_sel.hw
> +		},
> +		.num_parents = 1,
> +		.flags = CLK_SET_RATE_PARENT,
> +	},
> +};
> +
> +static struct clk_regmap axg_vapb_0 = {
> +	.data = &(struct clk_regmap_gate_data){
> +		.offset = HHI_VAPBCLK_CNTL,
> +		.bit_idx = 8,
> +	},
> +	.hw.init = &(struct clk_init_data) {
> +		.name = "vapb_0",
> +		.ops = &clk_regmap_gate_ops,
> +		.parent_hws = (const struct clk_hw *[]) {
> +			&axg_vapb_0_div.hw
> +		},
> +		.num_parents = 1,
> +		.flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
> +	},
> +};
> +
> +static struct clk_regmap axg_vapb_1_sel = {
> +	.data = &(struct clk_regmap_mux_data){
> +		.offset = HHI_VAPBCLK_CNTL,
> +		.mask = 0x3,
> +		.shift = 25,
> +	},
> +	.hw.init = &(struct clk_init_data){
> +		.name = "vapb_1_sel",
> +		.ops = &clk_regmap_mux_ops,
> +		/*
> +		 * bits 25:26 selects from 4 possible parents:
> +		 * fclk_div4, fclk_div3, fclk_div5, fclk_div7,
> +		 */
> +		.parent_hws = axg_vapb_parent_hws,
> +		.num_parents = ARRAY_SIZE(axg_vapb_parent_hws),
> +		.flags = CLK_SET_RATE_NO_REPARENT,
> +	},
> +};
> +
> +static struct clk_regmap axg_vapb_1_div = {
> +	.data = &(struct clk_regmap_div_data){
> +		.offset = HHI_VAPBCLK_CNTL,
> +		.shift = 16,
> +		.width = 7,
> +	},
> +	.hw.init = &(struct clk_init_data){
> +		.name = "vapb_1_div",
> +		.ops = &clk_regmap_divider_ops,
> +		.parent_hws = (const struct clk_hw *[]) {
> +			&axg_vapb_1_sel.hw
> +		},
> +		.num_parents = 1,
> +		.flags = CLK_SET_RATE_PARENT,
> +	},
> +};
> +
> +static struct clk_regmap axg_vapb_1 = {
> +	.data = &(struct clk_regmap_gate_data){
> +		.offset = HHI_VAPBCLK_CNTL,
> +		.bit_idx = 24,
> +	},
> +	.hw.init = &(struct clk_init_data) {
> +		.name = "vapb_1",
> +		.ops = &clk_regmap_gate_ops,
> +		.parent_hws = (const struct clk_hw *[]) {
> +			&axg_vapb_1_div.hw
> +		},
> +		.num_parents = 1,
> +		.flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
> +	},
> +};
> +
> +static struct clk_regmap axg_vapb_sel = {
> +	.data = &(struct clk_regmap_mux_data){
> +		.offset = HHI_VAPBCLK_CNTL,
> +		.mask = 1,
> +		.shift = 31,
> +	},
> +	.hw.init = &(struct clk_init_data){
> +		.name = "vapb_sel",
> +		.ops = &clk_regmap_mux_ops,
> +		/*
> +		 * bit 31 selects from 2 possible parents:
> +		 * vapb_0 or vapb_1
> +		 */
> +		.parent_hws = (const struct clk_hw *[]) {
> +			&axg_vapb_0.hw,
> +			&axg_vapb_1.hw
> +		},
> +		.num_parents = 2,
> +		.flags = CLK_SET_RATE_NO_REPARENT,
> +	},
> +};
> +
> +static struct clk_regmap axg_vapb = {
> +	.data = &(struct clk_regmap_gate_data){
> +		.offset = HHI_VAPBCLK_CNTL,
> +		.bit_idx = 30,
> +	},
> +	.hw.init = &(struct clk_init_data) {
> +		.name = "vapb",
> +		.ops = &clk_regmap_gate_ops,
> +		.parent_hws = (const struct clk_hw *[]) { &axg_vapb_sel.hw },
> +		.num_parents = 1,
> +		.flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
> +	},
> +};
> +
> +/* Video Clocks */
> +
> +static const struct clk_hw *axg_vclk_parent_hws[] = {
> +	&axg_gp0_pll.hw,
> +	&axg_fclk_div4.hw,
> +	&axg_fclk_div3.hw,
> +	&axg_fclk_div5.hw,
> +	&axg_fclk_div2.hw,
> +	&axg_fclk_div7.hw,
> +	&axg_mpll1.hw,
> +};
> +
> +static struct clk_regmap axg_vclk_sel = {
> +	.data = &(struct clk_regmap_mux_data){
> +		.offset = HHI_VID_CLK_CNTL,
> +		.mask = 0x7,
> +		.shift = 16,
> +	},
> +	.hw.init = &(struct clk_init_data){
> +		.name = "vclk_sel",
> +		.ops = &clk_regmap_mux_ops,
> +		.parent_hws = axg_vclk_parent_hws,
> +		.num_parents = ARRAY_SIZE(axg_vclk_parent_hws),
> +		.flags = CLK_SET_RATE_NO_REPARENT | CLK_GET_RATE_NOCACHE,
> +	},

Why is NOCACHE ? Is there something poking behind CCF back ? if yes, why
is this required ?

> +};
> +
> +static struct clk_regmap axg_vclk2_sel = {
> +	.data = &(struct clk_regmap_mux_data){
> +		.offset = HHI_VIID_CLK_CNTL,
> +		.mask = 0x7,
> +		.shift = 16,
> +	},
> +	.hw.init = &(struct clk_init_data){
> +		.name = "vclk2_sel",
> +		.ops = &clk_regmap_mux_ops,
> +		.parent_hws = axg_vclk_parent_hws,
> +		.num_parents = ARRAY_SIZE(axg_vclk_parent_hws),
> +		.flags = CLK_SET_RATE_NO_REPARENT | CLK_GET_RATE_NOCACHE,
> +	},
> +};
> +
> +static struct clk_regmap axg_vclk_input = {
> +	.data = &(struct clk_regmap_gate_data){
> +		.offset = HHI_VID_CLK_DIV,
> +		.bit_idx = 16,
> +	},
> +	.hw.init = &(struct clk_init_data) {
> +		.name = "vclk_input",
> +		.ops = &clk_regmap_gate_ops,
> +		.parent_hws = (const struct clk_hw *[]) { &axg_vclk_sel.hw },
> +		.num_parents = 1,
> +		.flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
> +	},
> +};
> +
> +static struct clk_regmap axg_vclk2_input = {
> +	.data = &(struct clk_regmap_gate_data){
> +		.offset = HHI_VIID_CLK_DIV,
> +		.bit_idx = 16,
> +	},
> +	.hw.init = &(struct clk_init_data) {
> +		.name = "vclk2_input",
> +		.ops = &clk_regmap_gate_ops,
> +		.parent_hws = (const struct clk_hw *[]) { &axg_vclk2_sel.hw },
> +		.num_parents = 1,
> +		.flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
> +	},
> +};
> +
> +static struct clk_regmap axg_vclk_div = {
> +	.data = &(struct clk_regmap_div_data){
> +		.offset = HHI_VID_CLK_DIV,
> +		.shift = 0,
> +		.width = 8,
> +	},
> +	.hw.init = &(struct clk_init_data){
> +		.name = "vclk_div",
> +		.ops = &clk_regmap_divider_ops,
> +		.parent_hws = (const struct clk_hw *[]) {
> +			&axg_vclk_input.hw
> +		},
> +		.num_parents = 1,
> +		.flags = CLK_GET_RATE_NOCACHE,
> +	},
> +};
> +
> +static struct clk_regmap axg_vclk2_div = {
> +	.data = &(struct clk_regmap_div_data){
> +		.offset = HHI_VIID_CLK_DIV,
> +		.shift = 0,
> +		.width = 8,
> +	},
> +	.hw.init = &(struct clk_init_data){
> +		.name = "vclk2_div",
> +		.ops = &clk_regmap_divider_ops,
> +		.parent_hws = (const struct clk_hw *[]) {
> +			&axg_vclk2_input.hw
> +		},
> +		.num_parents = 1,
> +		.flags = CLK_GET_RATE_NOCACHE,
> +	},
> +};
> +
> +static struct clk_regmap axg_vclk = {
> +	.data = &(struct clk_regmap_gate_data){
> +		.offset = HHI_VID_CLK_CNTL,
> +		.bit_idx = 19,
> +	},
> +	.hw.init = &(struct clk_init_data) {
> +		.name = "vclk",
> +		.ops = &clk_regmap_gate_ops,
> +		.parent_hws = (const struct clk_hw *[]) { &axg_vclk_div.hw },
> +		.num_parents = 1,
> +		.flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
> +	},
> +};
> +
> +static struct clk_regmap axg_vclk2 = {
> +	.data = &(struct clk_regmap_gate_data){
> +		.offset = HHI_VIID_CLK_CNTL,
> +		.bit_idx = 19,
> +	},
> +	.hw.init = &(struct clk_init_data) {
> +		.name = "vclk2",
> +		.ops = &clk_regmap_gate_ops,
> +		.parent_hws = (const struct clk_hw *[]) { &axg_vclk2_div.hw },
> +		.num_parents = 1,
> +		.flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
> +	},
> +};
> +
> +static struct clk_regmap axg_vclk_div1 = {
> +	.data = &(struct clk_regmap_gate_data){
> +		.offset = HHI_VID_CLK_CNTL,
> +		.bit_idx = 0,
> +	},
> +	.hw.init = &(struct clk_init_data) {
> +		.name = "vclk_div1",
> +		.ops = &clk_regmap_gate_ops,
> +		.parent_hws = (const struct clk_hw *[]) { &axg_vclk.hw },
> +		.num_parents = 1,
> +		.flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
> +	},
> +};
> +
> +static struct clk_regmap axg_vclk_div2_en = {
> +	.data = &(struct clk_regmap_gate_data){
> +		.offset = HHI_VID_CLK_CNTL,
> +		.bit_idx = 1,
> +	},
> +	.hw.init = &(struct clk_init_data) {
> +		.name = "vclk_div2_en",
> +		.ops = &clk_regmap_gate_ops,
> +		.parent_hws = (const struct clk_hw *[]) { &axg_vclk.hw },
> +		.num_parents = 1,
> +		.flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
> +	},
> +};
> +
> +static struct clk_regmap axg_vclk_div4_en = {
> +	.data = &(struct clk_regmap_gate_data){
> +		.offset = HHI_VID_CLK_CNTL,
> +		.bit_idx = 2,
> +	},
> +	.hw.init = &(struct clk_init_data) {
> +		.name = "vclk_div4_en",
> +		.ops = &clk_regmap_gate_ops,
> +		.parent_hws = (const struct clk_hw *[]) { &axg_vclk.hw },
> +		.num_parents = 1,
> +		.flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
> +	},
> +};
> +
> +static struct clk_regmap axg_vclk_div6_en = {
> +	.data = &(struct clk_regmap_gate_data){
> +		.offset = HHI_VID_CLK_CNTL,
> +		.bit_idx = 3,
> +	},
> +	.hw.init = &(struct clk_init_data) {
> +		.name = "vclk_div6_en",
> +		.ops = &clk_regmap_gate_ops,
> +		.parent_hws = (const struct clk_hw *[]) { &axg_vclk.hw },
> +		.num_parents = 1,
> +		.flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
> +	},
> +};
> +
> +static struct clk_regmap axg_vclk_div12_en = {
> +	.data = &(struct clk_regmap_gate_data){
> +		.offset = HHI_VID_CLK_CNTL,
> +		.bit_idx = 4,
> +	},
> +	.hw.init = &(struct clk_init_data) {
> +		.name = "vclk_div12_en",
> +		.ops = &clk_regmap_gate_ops,
> +		.parent_hws = (const struct clk_hw *[]) { &axg_vclk.hw },
> +		.num_parents = 1,
> +		.flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
> +	},
> +};
> +
> +static struct clk_regmap axg_vclk2_div1 = {
> +	.data = &(struct clk_regmap_gate_data){
> +		.offset = HHI_VIID_CLK_CNTL,
> +		.bit_idx = 0,
> +	},
> +	.hw.init = &(struct clk_init_data) {
> +		.name = "vclk2_div1",
> +		.ops = &clk_regmap_gate_ops,
> +		.parent_hws = (const struct clk_hw *[]) { &axg_vclk2.hw },
> +		.num_parents = 1,
> +		.flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
> +	},
> +};
> +
> +static struct clk_regmap axg_vclk2_div2_en = {
> +	.data = &(struct clk_regmap_gate_data){
> +		.offset = HHI_VIID_CLK_CNTL,
> +		.bit_idx = 1,
> +	},
> +	.hw.init = &(struct clk_init_data) {
> +		.name = "vclk2_div2_en",
> +		.ops = &clk_regmap_gate_ops,
> +		.parent_hws = (const struct clk_hw *[]) { &axg_vclk2.hw },
> +		.num_parents = 1,
> +		.flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
> +	},
> +};
> +
> +static struct clk_regmap axg_vclk2_div4_en = {
> +	.data = &(struct clk_regmap_gate_data){
> +		.offset = HHI_VIID_CLK_CNTL,
> +		.bit_idx = 2,
> +	},
> +	.hw.init = &(struct clk_init_data) {
> +		.name = "vclk2_div4_en",
> +		.ops = &clk_regmap_gate_ops,
> +		.parent_hws = (const struct clk_hw *[]) { &axg_vclk2.hw },
> +		.num_parents = 1,
> +		.flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
> +	},
> +};
> +
> +static struct clk_regmap axg_vclk2_div6_en = {
> +	.data = &(struct clk_regmap_gate_data){
> +		.offset = HHI_VIID_CLK_CNTL,
> +		.bit_idx = 3,
> +	},
> +	.hw.init = &(struct clk_init_data) {
> +		.name = "vclk2_div6_en",
> +		.ops = &clk_regmap_gate_ops,
> +		.parent_hws = (const struct clk_hw *[]) { &axg_vclk2.hw },
> +		.num_parents = 1,
> +		.flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
> +	},
> +};
> +
> +static struct clk_regmap axg_vclk2_div12_en = {
> +	.data = &(struct clk_regmap_gate_data){
> +		.offset = HHI_VIID_CLK_CNTL,
> +		.bit_idx = 4,
> +	},
> +	.hw.init = &(struct clk_init_data) {
> +		.name = "vclk2_div12_en",
> +		.ops = &clk_regmap_gate_ops,
> +		.parent_hws = (const struct clk_hw *[]) { &axg_vclk2.hw },
> +		.num_parents = 1,
> +		.flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
> +	},
> +};
> +
> +static struct clk_fixed_factor axg_vclk_div2 = {
> +	.mult = 1,
> +	.div = 2,
> +	.hw.init = &(struct clk_init_data){
> +		.name = "vclk_div2",
> +		.ops = &clk_fixed_factor_ops,
> +		.parent_hws = (const struct clk_hw *[]) {
> +			&axg_vclk_div2_en.hw
> +		},
> +		.num_parents = 1,
> +	},
> +};
> +
> +static struct clk_fixed_factor axg_vclk_div4 = {
> +	.mult = 1,
> +	.div = 4,
> +	.hw.init = &(struct clk_init_data){
> +		.name = "vclk_div4",
> +		.ops = &clk_fixed_factor_ops,
> +		.parent_hws = (const struct clk_hw *[]) {
> +			&axg_vclk_div4_en.hw
> +		},
> +		.num_parents = 1,
> +	},
> +};
> +
> +static struct clk_fixed_factor axg_vclk_div6 = {
> +	.mult = 1,
> +	.div = 6,
> +	.hw.init = &(struct clk_init_data){
> +		.name = "vclk_div6",
> +		.ops = &clk_fixed_factor_ops,
> +		.parent_hws = (const struct clk_hw *[]) {
> +			&axg_vclk_div6_en.hw
> +		},
> +		.num_parents = 1,
> +	},
> +};
> +
> +static struct clk_fixed_factor axg_vclk_div12 = {
> +	.mult = 1,
> +	.div = 12,
> +	.hw.init = &(struct clk_init_data){
> +		.name = "vclk_div12",
> +		.ops = &clk_fixed_factor_ops,
> +		.parent_hws = (const struct clk_hw *[]) {
> +			&axg_vclk_div12_en.hw
> +		},
> +		.num_parents = 1,
> +	},
> +};
> +
> +static struct clk_fixed_factor axg_vclk2_div2 = {
> +	.mult = 1,
> +	.div = 2,
> +	.hw.init = &(struct clk_init_data){
> +		.name = "vclk2_div2",
> +		.ops = &clk_fixed_factor_ops,
> +		.parent_hws = (const struct clk_hw *[]) {
> +			&axg_vclk2_div2_en.hw
> +		},
> +		.num_parents = 1,
> +	},
> +};
> +
> +static struct clk_fixed_factor axg_vclk2_div4 = {
> +	.mult = 1,
> +	.div = 4,
> +	.hw.init = &(struct clk_init_data){
> +		.name = "vclk2_div4",
> +		.ops = &clk_fixed_factor_ops,
> +		.parent_hws = (const struct clk_hw *[]) {
> +			&axg_vclk2_div4_en.hw
> +		},
> +		.num_parents = 1,
> +	},
> +};
> +
> +static struct clk_fixed_factor axg_vclk2_div6 = {
> +	.mult = 1,
> +	.div = 6,
> +	.hw.init = &(struct clk_init_data){
> +		.name = "vclk2_div6",
> +		.ops = &clk_fixed_factor_ops,
> +		.parent_hws = (const struct clk_hw *[]) {
> +			&axg_vclk2_div6_en.hw
> +		},
> +		.num_parents = 1,
> +	},
> +};
> +
> +static struct clk_fixed_factor axg_vclk2_div12 = {
> +	.mult = 1,
> +	.div = 12,
> +	.hw.init = &(struct clk_init_data){
> +		.name = "vclk2_div12",
> +		.ops = &clk_fixed_factor_ops,
> +		.parent_hws = (const struct clk_hw *[]) {
> +			&axg_vclk2_div12_en.hw
> +		},
> +		.num_parents = 1,
> +	},
> +};
> +
> +static u32 mux_table_cts_sel[] = { 0, 1, 2, 3, 4, 8, 9, 10, 11, 12 };
> +static const struct clk_hw *axg_cts_parent_hws[] = {
> +	&axg_vclk_div1.hw,
> +	&axg_vclk_div2.hw,
> +	&axg_vclk_div4.hw,
> +	&axg_vclk_div6.hw,
> +	&axg_vclk_div12.hw,
> +	&axg_vclk2_div1.hw,
> +	&axg_vclk2_div2.hw,
> +	&axg_vclk2_div4.hw,
> +	&axg_vclk2_div6.hw,
> +	&axg_vclk2_div12.hw,
> +};
> +
> +static struct clk_regmap axg_cts_encl_sel = {
> +	.data = &(struct clk_regmap_mux_data){
> +		.offset = HHI_VIID_CLK_DIV,
> +		.mask = 0xf,
> +		.shift = 12,
> +		.table = mux_table_cts_sel,
> +	},
> +	.hw.init = &(struct clk_init_data){
> +		.name = "cts_encl_sel",
> +		.ops = &clk_regmap_mux_ops,
> +		.parent_hws = axg_cts_parent_hws,
> +		.num_parents = ARRAY_SIZE(axg_cts_parent_hws),
> +		.flags = CLK_SET_RATE_NO_REPARENT | CLK_GET_RATE_NOCACHE,
> +	},
> +};
> +
> +static struct clk_regmap axg_cts_encl = {
> +	.data = &(struct clk_regmap_gate_data){
> +		.offset = HHI_VID_CLK_CNTL2,
> +		.bit_idx = 3,
> +	},
> +	.hw.init = &(struct clk_init_data) {
> +		.name = "cts_encl",
> +		.ops = &clk_regmap_gate_ops,
> +		.parent_hws = (const struct clk_hw *[]) {
> +			&axg_cts_encl_sel.hw
> +		},
> +		.num_parents = 1,
> +		.flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
> +	},
> +};
> +
>  static u32 mux_table_gen_clk[]	= { 0, 4, 5, 6, 7, 8,
>  				    9, 10, 11, 13, 14, };
>  static const struct clk_parent_data gen_clk_parent_data[] = {
> @@ -1246,6 +1944,49 @@ static struct clk_hw_onecell_data axg_hw_onecell_data = {
>  		[CLKID_HIFI_PLL_DCO]		= &axg_hifi_pll_dco.hw,
>  		[CLKID_PCIE_PLL_DCO]		= &axg_pcie_pll_dco.hw,
>  		[CLKID_PCIE_PLL_OD]		= &axg_pcie_pll_od.hw,
> +		[CLKID_VPU_0_DIV]		= &axg_vpu_0_div.hw,
> +		[CLKID_VPU_0_SEL]		= &axg_vpu_0_sel.hw,
> +		[CLKID_VPU_0]			= &axg_vpu_0.hw,
> +		[CLKID_VPU_1_DIV]		= &axg_vpu_1_div.hw,
> +		[CLKID_VPU_1_SEL]		= &axg_vpu_1_sel.hw,
> +		[CLKID_VPU_1]			= &axg_vpu_1.hw,
> +		[CLKID_VPU]			= &axg_vpu.hw,
> +		[CLKID_VAPB_0_DIV]		= &axg_vapb_0_div.hw,
> +		[CLKID_VAPB_0_SEL]		= &axg_vapb_0_sel.hw,
> +		[CLKID_VAPB_0]			= &axg_vapb_0.hw,
> +		[CLKID_VAPB_1_DIV]		= &axg_vapb_1_div.hw,
> +		[CLKID_VAPB_1_SEL]		= &axg_vapb_1_sel.hw,
> +		[CLKID_VAPB_1]			= &axg_vapb_1.hw,
> +		[CLKID_VAPB_SEL]		= &axg_vapb_sel.hw,
> +		[CLKID_VAPB]			= &axg_vapb.hw,
> +		[CLKID_VCLK]			= &axg_vclk.hw,
> +		[CLKID_VCLK2]			= &axg_vclk2.hw,
> +		[CLKID_VCLK_SEL]		= &axg_vclk_sel.hw,
> +		[CLKID_VCLK2_SEL]		= &axg_vclk2_sel.hw,
> +		[CLKID_VCLK_INPUT]		= &axg_vclk_input.hw,
> +		[CLKID_VCLK2_INPUT]		= &axg_vclk2_input.hw,
> +		[CLKID_VCLK_DIV]		= &axg_vclk_div.hw,
> +		[CLKID_VCLK2_DIV]		= &axg_vclk2_div.hw,
> +		[CLKID_VCLK_DIV2_EN]		= &axg_vclk_div2_en.hw,
> +		[CLKID_VCLK_DIV4_EN]		= &axg_vclk_div4_en.hw,
> +		[CLKID_VCLK_DIV6_EN]		= &axg_vclk_div6_en.hw,
> +		[CLKID_VCLK_DIV12_EN]		= &axg_vclk_div12_en.hw,
> +		[CLKID_VCLK2_DIV2_EN]		= &axg_vclk2_div2_en.hw,
> +		[CLKID_VCLK2_DIV4_EN]		= &axg_vclk2_div4_en.hw,
> +		[CLKID_VCLK2_DIV6_EN]		= &axg_vclk2_div6_en.hw,
> +		[CLKID_VCLK2_DIV12_EN]		= &axg_vclk2_div12_en.hw,
> +		[CLKID_VCLK_DIV1]		= &axg_vclk_div1.hw,
> +		[CLKID_VCLK_DIV2]		= &axg_vclk_div2.hw,
> +		[CLKID_VCLK_DIV4]		= &axg_vclk_div4.hw,
> +		[CLKID_VCLK_DIV6]		= &axg_vclk_div6.hw,
> +		[CLKID_VCLK_DIV12]		= &axg_vclk_div12.hw,
> +		[CLKID_VCLK2_DIV1]		= &axg_vclk2_div1.hw,
> +		[CLKID_VCLK2_DIV2]		= &axg_vclk2_div2.hw,
> +		[CLKID_VCLK2_DIV4]		= &axg_vclk2_div4.hw,
> +		[CLKID_VCLK2_DIV6]		= &axg_vclk2_div6.hw,
> +		[CLKID_VCLK2_DIV12]		= &axg_vclk2_div12.hw,
> +		[CLKID_CTS_ENCL_SEL]		= &axg_cts_encl_sel.hw,
> +		[CLKID_CTS_ENCL]		= &axg_cts_encl.hw,
>  		[NR_CLKS]			= NULL,
>  	},
>  	.num = NR_CLKS,
> @@ -1341,6 +2082,39 @@ static struct clk_regmap *const axg_clk_regmaps[] = {
>  	&axg_hifi_pll_dco,
>  	&axg_pcie_pll_dco,
>  	&axg_pcie_pll_od,
> +	&axg_vpu_0_div,
> +	&axg_vpu_0_sel,
> +	&axg_vpu_0,
> +	&axg_vpu_1_div,
> +	&axg_vpu_1_sel,
> +	&axg_vpu_1,
> +	&axg_vpu,
> +	&axg_vapb_0_div,
> +	&axg_vapb_0_sel,
> +	&axg_vapb_0,
> +	&axg_vapb_1_div,
> +	&axg_vapb_1_sel,
> +	&axg_vapb_1,
> +	&axg_vapb_sel,
> +	&axg_vapb,
> +	&axg_vclk,
> +	&axg_vclk2,
> +	&axg_vclk_sel,
> +	&axg_vclk2_sel,
> +	&axg_vclk_input,
> +	&axg_vclk2_input,
> +	&axg_vclk_div,
> +	&axg_vclk2_div,
> +	&axg_vclk_div2_en,
> +	&axg_vclk_div4_en,
> +	&axg_vclk_div6_en,
> +	&axg_vclk_div12_en,
> +	&axg_vclk2_div2_en,
> +	&axg_vclk2_div4_en,
> +	&axg_vclk2_div6_en,
> +	&axg_vclk2_div12_en,
> +	&axg_cts_encl_sel,
> +	&axg_cts_encl,
>  };
>  
>  static const struct meson_eeclkc_data axg_clkc_data = {
> diff --git a/drivers/clk/meson/axg.h b/drivers/clk/meson/axg.h
> index 0431dabac629..a8787b394a47 100644
> --- a/drivers/clk/meson/axg.h
> +++ b/drivers/clk/meson/axg.h
> @@ -139,8 +139,27 @@
>  #define CLKID_HIFI_PLL_DCO			88
>  #define CLKID_PCIE_PLL_DCO			89
>  #define CLKID_PCIE_PLL_OD			90
> +#define CLKID_VPU_0_DIV				91
> +#define CLKID_VPU_1_DIV				94
> +#define CLKID_VAPB_0_DIV			98
> +#define CLKID_VAPB_1_DIV			101
> +#define CLKID_VCLK_SEL				108
> +#define CLKID_VCLK2_SEL				109
> +#define CLKID_VCLK_INPUT			110
> +#define CLKID_VCLK2_INPUT			111
> +#define CLKID_VCLK_DIV				112
> +#define CLKID_VCLK2_DIV				113
> +#define CLKID_VCLK_DIV2_EN			114
> +#define CLKID_VCLK_DIV4_EN			115
> +#define CLKID_VCLK_DIV6_EN			116
> +#define CLKID_VCLK_DIV12_EN			117
> +#define CLKID_VCLK2_DIV2_EN			118
> +#define CLKID_VCLK2_DIV4_EN			119
> +#define CLKID_VCLK2_DIV6_EN			120
> +#define CLKID_VCLK2_DIV12_EN			121
> +#define CLKID_CTS_ENCL_SEL			132
>  
> -#define NR_CLKS					91
> +#define NR_CLKS					134
>  
>  /* include the CLKIDs that have been made part of the DT binding */
>  #include <dt-bindings/clock/axg-clkc.h>

Overall, there is quite an heavy use of CLK_IGNORE_USED and
CLK_GET_RATE_NOCACHE which seems to indicate that something else is
poking around in the clocks registers

Details about why it should be done this way, and not through CCF API,
should be provided.

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH 3/4] clk: meson: axg: add Video Clocks
@ 2020-09-10 10:13     ` Jerome Brunet
  0 siblings, 0 replies; 30+ messages in thread
From: Jerome Brunet @ 2020-09-10 10:13 UTC (permalink / raw)
  To: Neil Armstrong; +Cc: linux-amlogic, linux-clk, linux-arm-kernel, linux-kernel


On Mon 07 Sep 2020 at 11:38, Neil Armstrong <narmstrong@baylibre.com> wrote:

> Add the Video Clocks present on the Amlogic AXg SoCs.
>
> The AXG only has a single ENCL CTS clock and even if VCLK exist along VCLK2,
> only VCLK2 is used since it clocks the MIPI DSI IP directly.
>
> Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
> ---
>  drivers/clk/meson/axg.c | 774 ++++++++++++++++++++++++++++++++++++++++
>  drivers/clk/meson/axg.h |  21 +-
>  2 files changed, 794 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/clk/meson/axg.c b/drivers/clk/meson/axg.c
> index 13fc0006f63d..2550616c14b0 100644
> --- a/drivers/clk/meson/axg.c
> +++ b/drivers/clk/meson/axg.c
> @@ -1026,6 +1026,704 @@ static struct clk_regmap axg_sd_emmc_c_clk0 = {
>  	},
>  };
>  
> +/* VPU Clock */
> +
> +static const struct clk_hw *axg_vpu_parent_hws[] = {
> +	&axg_fclk_div4.hw,
> +	&axg_fclk_div3.hw,
> +	&axg_fclk_div5.hw,
> +	&axg_fclk_div7.hw,
> +};
> +
> +static struct clk_regmap axg_vpu_0_sel = {
> +	.data = &(struct clk_regmap_mux_data){
> +		.offset = HHI_VPU_CLK_CNTL,
> +		.mask = 0x3,
> +		.shift = 9,
> +	},
> +	.hw.init = &(struct clk_init_data){
> +		.name = "vpu_0_sel",
> +		.ops = &clk_regmap_mux_ops,
> +		/*
> +		 * bits 9:10 selects from 4 possible parents:
> +		 * fclk_div4, fclk_div3, fclk_div5, fclk_div7,
> +		 */

These comments (and the same bellow) are not very useful

> +		.parent_hws = axg_vpu_parent_hws,
> +		.num_parents = ARRAY_SIZE(axg_vpu_parent_hws),

Could you add a comment here explaining why parenting needs to be
manually controlled ?

> +		.flags = CLK_SET_RATE_NO_REPARENT,
> +	},
> +};
> +
> +static struct clk_regmap axg_vpu_0_div = {
> +	.data = &(struct clk_regmap_div_data){
> +		.offset = HHI_VPU_CLK_CNTL,
> +		.shift = 0,
> +		.width = 7,
> +	},
> +	.hw.init = &(struct clk_init_data){
> +		.name = "vpu_0_div",
> +		.ops = &clk_regmap_divider_ops,
> +		.parent_hws = (const struct clk_hw *[]) { &axg_vpu_0_sel.hw },
> +		.num_parents = 1,
> +		.flags = CLK_SET_RATE_PARENT,
> +	},
> +};
> +
> +static struct clk_regmap axg_vpu_0 = {
> +	.data = &(struct clk_regmap_gate_data){
> +		.offset = HHI_VPU_CLK_CNTL,
> +		.bit_idx = 8,
> +	},
> +	.hw.init = &(struct clk_init_data) {
> +		.name = "vpu_0",
> +		.ops = &clk_regmap_gate_ops,
> +		.parent_hws = (const struct clk_hw *[]) { &axg_vpu_0_div.hw },
> +		.num_parents = 1,
> +		.flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,

Why is UNUSED required ?

> +	},
> +};
> +
> +static struct clk_regmap axg_vpu_1_sel = {
> +	.data = &(struct clk_regmap_mux_data){
> +		.offset = HHI_VPU_CLK_CNTL,
> +		.mask = 0x3,
> +		.shift = 25,
> +	},
> +	.hw.init = &(struct clk_init_data){
> +		.name = "vpu_1_sel",
> +		.ops = &clk_regmap_mux_ops,
> +		/*
> +		 * bits 25:26 selects from 4 possible parents:
> +		 * fclk_div4, fclk_div3, fclk_div5, fclk_div7,
> +		 */
> +		.parent_hws = axg_vpu_parent_hws,
> +		.num_parents = ARRAY_SIZE(axg_vpu_parent_hws),
> +		.flags = CLK_SET_RATE_NO_REPARENT,
> +	},
> +};
> +
> +static struct clk_regmap axg_vpu_1_div = {
> +	.data = &(struct clk_regmap_div_data){
> +		.offset = HHI_VPU_CLK_CNTL,
> +		.shift = 16,
> +		.width = 7,
> +	},
> +	.hw.init = &(struct clk_init_data){
> +		.name = "vpu_1_div",
> +		.ops = &clk_regmap_divider_ops,
> +		.parent_hws = (const struct clk_hw *[]) { &axg_vpu_1_sel.hw },
> +		.num_parents = 1,
> +		.flags = CLK_SET_RATE_PARENT,
> +	},
> +};
> +
> +static struct clk_regmap axg_vpu_1 = {
> +	.data = &(struct clk_regmap_gate_data){
> +		.offset = HHI_VPU_CLK_CNTL,
> +		.bit_idx = 24,
> +	},
> +	.hw.init = &(struct clk_init_data) {
> +		.name = "vpu_1",
> +		.ops = &clk_regmap_gate_ops,
> +		.parent_hws = (const struct clk_hw *[]) { &axg_vpu_1_div.hw },
> +		.num_parents = 1,
> +		.flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
> +	},
> +};
> +
> +static struct clk_regmap axg_vpu = {
> +	.data = &(struct clk_regmap_mux_data){
> +		.offset = HHI_VPU_CLK_CNTL,
> +		.mask = 1,
> +		.shift = 31,
> +	},
> +	.hw.init = &(struct clk_init_data){
> +		.name = "vpu",
> +		.ops = &clk_regmap_mux_ops,
> +		/*
> +		 * bit 31 selects from 2 possible parents:
> +		 * vpu_0 or vpu_1
> +		 */
> +		.parent_hws = (const struct clk_hw *[]) {
> +			&axg_vpu_0.hw,
> +			&axg_vpu_1.hw
> +		},
> +		.num_parents = 2,
> +		.flags = CLK_SET_RATE_NO_REPARENT,
> +	},
> +};
> +
> +/* VAPB Clock */
> +
> +static const struct clk_hw *axg_vapb_parent_hws[] = {
> +	&axg_fclk_div4.hw,
> +	&axg_fclk_div3.hw,
> +	&axg_fclk_div5.hw,
> +	&axg_fclk_div7.hw,
> +};

This is the same as the vpu table. Could they share a single table ?

> +
> +static struct clk_regmap axg_vapb_0_sel = {
> +	.data = &(struct clk_regmap_mux_data){
> +		.offset = HHI_VAPBCLK_CNTL,
> +		.mask = 0x3,
> +		.shift = 9,
> +	},
> +	.hw.init = &(struct clk_init_data){
> +		.name = "vapb_0_sel",
> +		.ops = &clk_regmap_mux_ops,
> +		/*
> +		 * bits 9:10 selects from 4 possible parents:
> +		 * fclk_div4, fclk_div3, fclk_div5, fclk_div7,
> +		 */
> +		.parent_hws = axg_vapb_parent_hws,
> +		.num_parents = ARRAY_SIZE(axg_vapb_parent_hws),
> +		.flags = CLK_SET_RATE_NO_REPARENT,
> +	},
> +};
> +
> +static struct clk_regmap axg_vapb_0_div = {
> +	.data = &(struct clk_regmap_div_data){
> +		.offset = HHI_VAPBCLK_CNTL,
> +		.shift = 0,
> +		.width = 7,
> +	},
> +	.hw.init = &(struct clk_init_data){
> +		.name = "vapb_0_div",
> +		.ops = &clk_regmap_divider_ops,
> +		.parent_hws = (const struct clk_hw *[]) {
> +			&axg_vapb_0_sel.hw
> +		},
> +		.num_parents = 1,
> +		.flags = CLK_SET_RATE_PARENT,
> +	},
> +};
> +
> +static struct clk_regmap axg_vapb_0 = {
> +	.data = &(struct clk_regmap_gate_data){
> +		.offset = HHI_VAPBCLK_CNTL,
> +		.bit_idx = 8,
> +	},
> +	.hw.init = &(struct clk_init_data) {
> +		.name = "vapb_0",
> +		.ops = &clk_regmap_gate_ops,
> +		.parent_hws = (const struct clk_hw *[]) {
> +			&axg_vapb_0_div.hw
> +		},
> +		.num_parents = 1,
> +		.flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
> +	},
> +};
> +
> +static struct clk_regmap axg_vapb_1_sel = {
> +	.data = &(struct clk_regmap_mux_data){
> +		.offset = HHI_VAPBCLK_CNTL,
> +		.mask = 0x3,
> +		.shift = 25,
> +	},
> +	.hw.init = &(struct clk_init_data){
> +		.name = "vapb_1_sel",
> +		.ops = &clk_regmap_mux_ops,
> +		/*
> +		 * bits 25:26 selects from 4 possible parents:
> +		 * fclk_div4, fclk_div3, fclk_div5, fclk_div7,
> +		 */
> +		.parent_hws = axg_vapb_parent_hws,
> +		.num_parents = ARRAY_SIZE(axg_vapb_parent_hws),
> +		.flags = CLK_SET_RATE_NO_REPARENT,
> +	},
> +};
> +
> +static struct clk_regmap axg_vapb_1_div = {
> +	.data = &(struct clk_regmap_div_data){
> +		.offset = HHI_VAPBCLK_CNTL,
> +		.shift = 16,
> +		.width = 7,
> +	},
> +	.hw.init = &(struct clk_init_data){
> +		.name = "vapb_1_div",
> +		.ops = &clk_regmap_divider_ops,
> +		.parent_hws = (const struct clk_hw *[]) {
> +			&axg_vapb_1_sel.hw
> +		},
> +		.num_parents = 1,
> +		.flags = CLK_SET_RATE_PARENT,
> +	},
> +};
> +
> +static struct clk_regmap axg_vapb_1 = {
> +	.data = &(struct clk_regmap_gate_data){
> +		.offset = HHI_VAPBCLK_CNTL,
> +		.bit_idx = 24,
> +	},
> +	.hw.init = &(struct clk_init_data) {
> +		.name = "vapb_1",
> +		.ops = &clk_regmap_gate_ops,
> +		.parent_hws = (const struct clk_hw *[]) {
> +			&axg_vapb_1_div.hw
> +		},
> +		.num_parents = 1,
> +		.flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
> +	},
> +};
> +
> +static struct clk_regmap axg_vapb_sel = {
> +	.data = &(struct clk_regmap_mux_data){
> +		.offset = HHI_VAPBCLK_CNTL,
> +		.mask = 1,
> +		.shift = 31,
> +	},
> +	.hw.init = &(struct clk_init_data){
> +		.name = "vapb_sel",
> +		.ops = &clk_regmap_mux_ops,
> +		/*
> +		 * bit 31 selects from 2 possible parents:
> +		 * vapb_0 or vapb_1
> +		 */
> +		.parent_hws = (const struct clk_hw *[]) {
> +			&axg_vapb_0.hw,
> +			&axg_vapb_1.hw
> +		},
> +		.num_parents = 2,
> +		.flags = CLK_SET_RATE_NO_REPARENT,
> +	},
> +};
> +
> +static struct clk_regmap axg_vapb = {
> +	.data = &(struct clk_regmap_gate_data){
> +		.offset = HHI_VAPBCLK_CNTL,
> +		.bit_idx = 30,
> +	},
> +	.hw.init = &(struct clk_init_data) {
> +		.name = "vapb",
> +		.ops = &clk_regmap_gate_ops,
> +		.parent_hws = (const struct clk_hw *[]) { &axg_vapb_sel.hw },
> +		.num_parents = 1,
> +		.flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
> +	},
> +};
> +
> +/* Video Clocks */
> +
> +static const struct clk_hw *axg_vclk_parent_hws[] = {
> +	&axg_gp0_pll.hw,
> +	&axg_fclk_div4.hw,
> +	&axg_fclk_div3.hw,
> +	&axg_fclk_div5.hw,
> +	&axg_fclk_div2.hw,
> +	&axg_fclk_div7.hw,
> +	&axg_mpll1.hw,
> +};
> +
> +static struct clk_regmap axg_vclk_sel = {
> +	.data = &(struct clk_regmap_mux_data){
> +		.offset = HHI_VID_CLK_CNTL,
> +		.mask = 0x7,
> +		.shift = 16,
> +	},
> +	.hw.init = &(struct clk_init_data){
> +		.name = "vclk_sel",
> +		.ops = &clk_regmap_mux_ops,
> +		.parent_hws = axg_vclk_parent_hws,
> +		.num_parents = ARRAY_SIZE(axg_vclk_parent_hws),
> +		.flags = CLK_SET_RATE_NO_REPARENT | CLK_GET_RATE_NOCACHE,
> +	},

Why is NOCACHE ? Is there something poking behind CCF back ? if yes, why
is this required ?

> +};
> +
> +static struct clk_regmap axg_vclk2_sel = {
> +	.data = &(struct clk_regmap_mux_data){
> +		.offset = HHI_VIID_CLK_CNTL,
> +		.mask = 0x7,
> +		.shift = 16,
> +	},
> +	.hw.init = &(struct clk_init_data){
> +		.name = "vclk2_sel",
> +		.ops = &clk_regmap_mux_ops,
> +		.parent_hws = axg_vclk_parent_hws,
> +		.num_parents = ARRAY_SIZE(axg_vclk_parent_hws),
> +		.flags = CLK_SET_RATE_NO_REPARENT | CLK_GET_RATE_NOCACHE,
> +	},
> +};
> +
> +static struct clk_regmap axg_vclk_input = {
> +	.data = &(struct clk_regmap_gate_data){
> +		.offset = HHI_VID_CLK_DIV,
> +		.bit_idx = 16,
> +	},
> +	.hw.init = &(struct clk_init_data) {
> +		.name = "vclk_input",
> +		.ops = &clk_regmap_gate_ops,
> +		.parent_hws = (const struct clk_hw *[]) { &axg_vclk_sel.hw },
> +		.num_parents = 1,
> +		.flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
> +	},
> +};
> +
> +static struct clk_regmap axg_vclk2_input = {
> +	.data = &(struct clk_regmap_gate_data){
> +		.offset = HHI_VIID_CLK_DIV,
> +		.bit_idx = 16,
> +	},
> +	.hw.init = &(struct clk_init_data) {
> +		.name = "vclk2_input",
> +		.ops = &clk_regmap_gate_ops,
> +		.parent_hws = (const struct clk_hw *[]) { &axg_vclk2_sel.hw },
> +		.num_parents = 1,
> +		.flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
> +	},
> +};
> +
> +static struct clk_regmap axg_vclk_div = {
> +	.data = &(struct clk_regmap_div_data){
> +		.offset = HHI_VID_CLK_DIV,
> +		.shift = 0,
> +		.width = 8,
> +	},
> +	.hw.init = &(struct clk_init_data){
> +		.name = "vclk_div",
> +		.ops = &clk_regmap_divider_ops,
> +		.parent_hws = (const struct clk_hw *[]) {
> +			&axg_vclk_input.hw
> +		},
> +		.num_parents = 1,
> +		.flags = CLK_GET_RATE_NOCACHE,
> +	},
> +};
> +
> +static struct clk_regmap axg_vclk2_div = {
> +	.data = &(struct clk_regmap_div_data){
> +		.offset = HHI_VIID_CLK_DIV,
> +		.shift = 0,
> +		.width = 8,
> +	},
> +	.hw.init = &(struct clk_init_data){
> +		.name = "vclk2_div",
> +		.ops = &clk_regmap_divider_ops,
> +		.parent_hws = (const struct clk_hw *[]) {
> +			&axg_vclk2_input.hw
> +		},
> +		.num_parents = 1,
> +		.flags = CLK_GET_RATE_NOCACHE,
> +	},
> +};
> +
> +static struct clk_regmap axg_vclk = {
> +	.data = &(struct clk_regmap_gate_data){
> +		.offset = HHI_VID_CLK_CNTL,
> +		.bit_idx = 19,
> +	},
> +	.hw.init = &(struct clk_init_data) {
> +		.name = "vclk",
> +		.ops = &clk_regmap_gate_ops,
> +		.parent_hws = (const struct clk_hw *[]) { &axg_vclk_div.hw },
> +		.num_parents = 1,
> +		.flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
> +	},
> +};
> +
> +static struct clk_regmap axg_vclk2 = {
> +	.data = &(struct clk_regmap_gate_data){
> +		.offset = HHI_VIID_CLK_CNTL,
> +		.bit_idx = 19,
> +	},
> +	.hw.init = &(struct clk_init_data) {
> +		.name = "vclk2",
> +		.ops = &clk_regmap_gate_ops,
> +		.parent_hws = (const struct clk_hw *[]) { &axg_vclk2_div.hw },
> +		.num_parents = 1,
> +		.flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
> +	},
> +};
> +
> +static struct clk_regmap axg_vclk_div1 = {
> +	.data = &(struct clk_regmap_gate_data){
> +		.offset = HHI_VID_CLK_CNTL,
> +		.bit_idx = 0,
> +	},
> +	.hw.init = &(struct clk_init_data) {
> +		.name = "vclk_div1",
> +		.ops = &clk_regmap_gate_ops,
> +		.parent_hws = (const struct clk_hw *[]) { &axg_vclk.hw },
> +		.num_parents = 1,
> +		.flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
> +	},
> +};
> +
> +static struct clk_regmap axg_vclk_div2_en = {
> +	.data = &(struct clk_regmap_gate_data){
> +		.offset = HHI_VID_CLK_CNTL,
> +		.bit_idx = 1,
> +	},
> +	.hw.init = &(struct clk_init_data) {
> +		.name = "vclk_div2_en",
> +		.ops = &clk_regmap_gate_ops,
> +		.parent_hws = (const struct clk_hw *[]) { &axg_vclk.hw },
> +		.num_parents = 1,
> +		.flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
> +	},
> +};
> +
> +static struct clk_regmap axg_vclk_div4_en = {
> +	.data = &(struct clk_regmap_gate_data){
> +		.offset = HHI_VID_CLK_CNTL,
> +		.bit_idx = 2,
> +	},
> +	.hw.init = &(struct clk_init_data) {
> +		.name = "vclk_div4_en",
> +		.ops = &clk_regmap_gate_ops,
> +		.parent_hws = (const struct clk_hw *[]) { &axg_vclk.hw },
> +		.num_parents = 1,
> +		.flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
> +	},
> +};
> +
> +static struct clk_regmap axg_vclk_div6_en = {
> +	.data = &(struct clk_regmap_gate_data){
> +		.offset = HHI_VID_CLK_CNTL,
> +		.bit_idx = 3,
> +	},
> +	.hw.init = &(struct clk_init_data) {
> +		.name = "vclk_div6_en",
> +		.ops = &clk_regmap_gate_ops,
> +		.parent_hws = (const struct clk_hw *[]) { &axg_vclk.hw },
> +		.num_parents = 1,
> +		.flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
> +	},
> +};
> +
> +static struct clk_regmap axg_vclk_div12_en = {
> +	.data = &(struct clk_regmap_gate_data){
> +		.offset = HHI_VID_CLK_CNTL,
> +		.bit_idx = 4,
> +	},
> +	.hw.init = &(struct clk_init_data) {
> +		.name = "vclk_div12_en",
> +		.ops = &clk_regmap_gate_ops,
> +		.parent_hws = (const struct clk_hw *[]) { &axg_vclk.hw },
> +		.num_parents = 1,
> +		.flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
> +	},
> +};
> +
> +static struct clk_regmap axg_vclk2_div1 = {
> +	.data = &(struct clk_regmap_gate_data){
> +		.offset = HHI_VIID_CLK_CNTL,
> +		.bit_idx = 0,
> +	},
> +	.hw.init = &(struct clk_init_data) {
> +		.name = "vclk2_div1",
> +		.ops = &clk_regmap_gate_ops,
> +		.parent_hws = (const struct clk_hw *[]) { &axg_vclk2.hw },
> +		.num_parents = 1,
> +		.flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
> +	},
> +};
> +
> +static struct clk_regmap axg_vclk2_div2_en = {
> +	.data = &(struct clk_regmap_gate_data){
> +		.offset = HHI_VIID_CLK_CNTL,
> +		.bit_idx = 1,
> +	},
> +	.hw.init = &(struct clk_init_data) {
> +		.name = "vclk2_div2_en",
> +		.ops = &clk_regmap_gate_ops,
> +		.parent_hws = (const struct clk_hw *[]) { &axg_vclk2.hw },
> +		.num_parents = 1,
> +		.flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
> +	},
> +};
> +
> +static struct clk_regmap axg_vclk2_div4_en = {
> +	.data = &(struct clk_regmap_gate_data){
> +		.offset = HHI_VIID_CLK_CNTL,
> +		.bit_idx = 2,
> +	},
> +	.hw.init = &(struct clk_init_data) {
> +		.name = "vclk2_div4_en",
> +		.ops = &clk_regmap_gate_ops,
> +		.parent_hws = (const struct clk_hw *[]) { &axg_vclk2.hw },
> +		.num_parents = 1,
> +		.flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
> +	},
> +};
> +
> +static struct clk_regmap axg_vclk2_div6_en = {
> +	.data = &(struct clk_regmap_gate_data){
> +		.offset = HHI_VIID_CLK_CNTL,
> +		.bit_idx = 3,
> +	},
> +	.hw.init = &(struct clk_init_data) {
> +		.name = "vclk2_div6_en",
> +		.ops = &clk_regmap_gate_ops,
> +		.parent_hws = (const struct clk_hw *[]) { &axg_vclk2.hw },
> +		.num_parents = 1,
> +		.flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
> +	},
> +};
> +
> +static struct clk_regmap axg_vclk2_div12_en = {
> +	.data = &(struct clk_regmap_gate_data){
> +		.offset = HHI_VIID_CLK_CNTL,
> +		.bit_idx = 4,
> +	},
> +	.hw.init = &(struct clk_init_data) {
> +		.name = "vclk2_div12_en",
> +		.ops = &clk_regmap_gate_ops,
> +		.parent_hws = (const struct clk_hw *[]) { &axg_vclk2.hw },
> +		.num_parents = 1,
> +		.flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
> +	},
> +};
> +
> +static struct clk_fixed_factor axg_vclk_div2 = {
> +	.mult = 1,
> +	.div = 2,
> +	.hw.init = &(struct clk_init_data){
> +		.name = "vclk_div2",
> +		.ops = &clk_fixed_factor_ops,
> +		.parent_hws = (const struct clk_hw *[]) {
> +			&axg_vclk_div2_en.hw
> +		},
> +		.num_parents = 1,
> +	},
> +};
> +
> +static struct clk_fixed_factor axg_vclk_div4 = {
> +	.mult = 1,
> +	.div = 4,
> +	.hw.init = &(struct clk_init_data){
> +		.name = "vclk_div4",
> +		.ops = &clk_fixed_factor_ops,
> +		.parent_hws = (const struct clk_hw *[]) {
> +			&axg_vclk_div4_en.hw
> +		},
> +		.num_parents = 1,
> +	},
> +};
> +
> +static struct clk_fixed_factor axg_vclk_div6 = {
> +	.mult = 1,
> +	.div = 6,
> +	.hw.init = &(struct clk_init_data){
> +		.name = "vclk_div6",
> +		.ops = &clk_fixed_factor_ops,
> +		.parent_hws = (const struct clk_hw *[]) {
> +			&axg_vclk_div6_en.hw
> +		},
> +		.num_parents = 1,
> +	},
> +};
> +
> +static struct clk_fixed_factor axg_vclk_div12 = {
> +	.mult = 1,
> +	.div = 12,
> +	.hw.init = &(struct clk_init_data){
> +		.name = "vclk_div12",
> +		.ops = &clk_fixed_factor_ops,
> +		.parent_hws = (const struct clk_hw *[]) {
> +			&axg_vclk_div12_en.hw
> +		},
> +		.num_parents = 1,
> +	},
> +};
> +
> +static struct clk_fixed_factor axg_vclk2_div2 = {
> +	.mult = 1,
> +	.div = 2,
> +	.hw.init = &(struct clk_init_data){
> +		.name = "vclk2_div2",
> +		.ops = &clk_fixed_factor_ops,
> +		.parent_hws = (const struct clk_hw *[]) {
> +			&axg_vclk2_div2_en.hw
> +		},
> +		.num_parents = 1,
> +	},
> +};
> +
> +static struct clk_fixed_factor axg_vclk2_div4 = {
> +	.mult = 1,
> +	.div = 4,
> +	.hw.init = &(struct clk_init_data){
> +		.name = "vclk2_div4",
> +		.ops = &clk_fixed_factor_ops,
> +		.parent_hws = (const struct clk_hw *[]) {
> +			&axg_vclk2_div4_en.hw
> +		},
> +		.num_parents = 1,
> +	},
> +};
> +
> +static struct clk_fixed_factor axg_vclk2_div6 = {
> +	.mult = 1,
> +	.div = 6,
> +	.hw.init = &(struct clk_init_data){
> +		.name = "vclk2_div6",
> +		.ops = &clk_fixed_factor_ops,
> +		.parent_hws = (const struct clk_hw *[]) {
> +			&axg_vclk2_div6_en.hw
> +		},
> +		.num_parents = 1,
> +	},
> +};
> +
> +static struct clk_fixed_factor axg_vclk2_div12 = {
> +	.mult = 1,
> +	.div = 12,
> +	.hw.init = &(struct clk_init_data){
> +		.name = "vclk2_div12",
> +		.ops = &clk_fixed_factor_ops,
> +		.parent_hws = (const struct clk_hw *[]) {
> +			&axg_vclk2_div12_en.hw
> +		},
> +		.num_parents = 1,
> +	},
> +};
> +
> +static u32 mux_table_cts_sel[] = { 0, 1, 2, 3, 4, 8, 9, 10, 11, 12 };
> +static const struct clk_hw *axg_cts_parent_hws[] = {
> +	&axg_vclk_div1.hw,
> +	&axg_vclk_div2.hw,
> +	&axg_vclk_div4.hw,
> +	&axg_vclk_div6.hw,
> +	&axg_vclk_div12.hw,
> +	&axg_vclk2_div1.hw,
> +	&axg_vclk2_div2.hw,
> +	&axg_vclk2_div4.hw,
> +	&axg_vclk2_div6.hw,
> +	&axg_vclk2_div12.hw,
> +};
> +
> +static struct clk_regmap axg_cts_encl_sel = {
> +	.data = &(struct clk_regmap_mux_data){
> +		.offset = HHI_VIID_CLK_DIV,
> +		.mask = 0xf,
> +		.shift = 12,
> +		.table = mux_table_cts_sel,
> +	},
> +	.hw.init = &(struct clk_init_data){
> +		.name = "cts_encl_sel",
> +		.ops = &clk_regmap_mux_ops,
> +		.parent_hws = axg_cts_parent_hws,
> +		.num_parents = ARRAY_SIZE(axg_cts_parent_hws),
> +		.flags = CLK_SET_RATE_NO_REPARENT | CLK_GET_RATE_NOCACHE,
> +	},
> +};
> +
> +static struct clk_regmap axg_cts_encl = {
> +	.data = &(struct clk_regmap_gate_data){
> +		.offset = HHI_VID_CLK_CNTL2,
> +		.bit_idx = 3,
> +	},
> +	.hw.init = &(struct clk_init_data) {
> +		.name = "cts_encl",
> +		.ops = &clk_regmap_gate_ops,
> +		.parent_hws = (const struct clk_hw *[]) {
> +			&axg_cts_encl_sel.hw
> +		},
> +		.num_parents = 1,
> +		.flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
> +	},
> +};
> +
>  static u32 mux_table_gen_clk[]	= { 0, 4, 5, 6, 7, 8,
>  				    9, 10, 11, 13, 14, };
>  static const struct clk_parent_data gen_clk_parent_data[] = {
> @@ -1246,6 +1944,49 @@ static struct clk_hw_onecell_data axg_hw_onecell_data = {
>  		[CLKID_HIFI_PLL_DCO]		= &axg_hifi_pll_dco.hw,
>  		[CLKID_PCIE_PLL_DCO]		= &axg_pcie_pll_dco.hw,
>  		[CLKID_PCIE_PLL_OD]		= &axg_pcie_pll_od.hw,
> +		[CLKID_VPU_0_DIV]		= &axg_vpu_0_div.hw,
> +		[CLKID_VPU_0_SEL]		= &axg_vpu_0_sel.hw,
> +		[CLKID_VPU_0]			= &axg_vpu_0.hw,
> +		[CLKID_VPU_1_DIV]		= &axg_vpu_1_div.hw,
> +		[CLKID_VPU_1_SEL]		= &axg_vpu_1_sel.hw,
> +		[CLKID_VPU_1]			= &axg_vpu_1.hw,
> +		[CLKID_VPU]			= &axg_vpu.hw,
> +		[CLKID_VAPB_0_DIV]		= &axg_vapb_0_div.hw,
> +		[CLKID_VAPB_0_SEL]		= &axg_vapb_0_sel.hw,
> +		[CLKID_VAPB_0]			= &axg_vapb_0.hw,
> +		[CLKID_VAPB_1_DIV]		= &axg_vapb_1_div.hw,
> +		[CLKID_VAPB_1_SEL]		= &axg_vapb_1_sel.hw,
> +		[CLKID_VAPB_1]			= &axg_vapb_1.hw,
> +		[CLKID_VAPB_SEL]		= &axg_vapb_sel.hw,
> +		[CLKID_VAPB]			= &axg_vapb.hw,
> +		[CLKID_VCLK]			= &axg_vclk.hw,
> +		[CLKID_VCLK2]			= &axg_vclk2.hw,
> +		[CLKID_VCLK_SEL]		= &axg_vclk_sel.hw,
> +		[CLKID_VCLK2_SEL]		= &axg_vclk2_sel.hw,
> +		[CLKID_VCLK_INPUT]		= &axg_vclk_input.hw,
> +		[CLKID_VCLK2_INPUT]		= &axg_vclk2_input.hw,
> +		[CLKID_VCLK_DIV]		= &axg_vclk_div.hw,
> +		[CLKID_VCLK2_DIV]		= &axg_vclk2_div.hw,
> +		[CLKID_VCLK_DIV2_EN]		= &axg_vclk_div2_en.hw,
> +		[CLKID_VCLK_DIV4_EN]		= &axg_vclk_div4_en.hw,
> +		[CLKID_VCLK_DIV6_EN]		= &axg_vclk_div6_en.hw,
> +		[CLKID_VCLK_DIV12_EN]		= &axg_vclk_div12_en.hw,
> +		[CLKID_VCLK2_DIV2_EN]		= &axg_vclk2_div2_en.hw,
> +		[CLKID_VCLK2_DIV4_EN]		= &axg_vclk2_div4_en.hw,
> +		[CLKID_VCLK2_DIV6_EN]		= &axg_vclk2_div6_en.hw,
> +		[CLKID_VCLK2_DIV12_EN]		= &axg_vclk2_div12_en.hw,
> +		[CLKID_VCLK_DIV1]		= &axg_vclk_div1.hw,
> +		[CLKID_VCLK_DIV2]		= &axg_vclk_div2.hw,
> +		[CLKID_VCLK_DIV4]		= &axg_vclk_div4.hw,
> +		[CLKID_VCLK_DIV6]		= &axg_vclk_div6.hw,
> +		[CLKID_VCLK_DIV12]		= &axg_vclk_div12.hw,
> +		[CLKID_VCLK2_DIV1]		= &axg_vclk2_div1.hw,
> +		[CLKID_VCLK2_DIV2]		= &axg_vclk2_div2.hw,
> +		[CLKID_VCLK2_DIV4]		= &axg_vclk2_div4.hw,
> +		[CLKID_VCLK2_DIV6]		= &axg_vclk2_div6.hw,
> +		[CLKID_VCLK2_DIV12]		= &axg_vclk2_div12.hw,
> +		[CLKID_CTS_ENCL_SEL]		= &axg_cts_encl_sel.hw,
> +		[CLKID_CTS_ENCL]		= &axg_cts_encl.hw,
>  		[NR_CLKS]			= NULL,
>  	},
>  	.num = NR_CLKS,
> @@ -1341,6 +2082,39 @@ static struct clk_regmap *const axg_clk_regmaps[] = {
>  	&axg_hifi_pll_dco,
>  	&axg_pcie_pll_dco,
>  	&axg_pcie_pll_od,
> +	&axg_vpu_0_div,
> +	&axg_vpu_0_sel,
> +	&axg_vpu_0,
> +	&axg_vpu_1_div,
> +	&axg_vpu_1_sel,
> +	&axg_vpu_1,
> +	&axg_vpu,
> +	&axg_vapb_0_div,
> +	&axg_vapb_0_sel,
> +	&axg_vapb_0,
> +	&axg_vapb_1_div,
> +	&axg_vapb_1_sel,
> +	&axg_vapb_1,
> +	&axg_vapb_sel,
> +	&axg_vapb,
> +	&axg_vclk,
> +	&axg_vclk2,
> +	&axg_vclk_sel,
> +	&axg_vclk2_sel,
> +	&axg_vclk_input,
> +	&axg_vclk2_input,
> +	&axg_vclk_div,
> +	&axg_vclk2_div,
> +	&axg_vclk_div2_en,
> +	&axg_vclk_div4_en,
> +	&axg_vclk_div6_en,
> +	&axg_vclk_div12_en,
> +	&axg_vclk2_div2_en,
> +	&axg_vclk2_div4_en,
> +	&axg_vclk2_div6_en,
> +	&axg_vclk2_div12_en,
> +	&axg_cts_encl_sel,
> +	&axg_cts_encl,
>  };
>  
>  static const struct meson_eeclkc_data axg_clkc_data = {
> diff --git a/drivers/clk/meson/axg.h b/drivers/clk/meson/axg.h
> index 0431dabac629..a8787b394a47 100644
> --- a/drivers/clk/meson/axg.h
> +++ b/drivers/clk/meson/axg.h
> @@ -139,8 +139,27 @@
>  #define CLKID_HIFI_PLL_DCO			88
>  #define CLKID_PCIE_PLL_DCO			89
>  #define CLKID_PCIE_PLL_OD			90
> +#define CLKID_VPU_0_DIV				91
> +#define CLKID_VPU_1_DIV				94
> +#define CLKID_VAPB_0_DIV			98
> +#define CLKID_VAPB_1_DIV			101
> +#define CLKID_VCLK_SEL				108
> +#define CLKID_VCLK2_SEL				109
> +#define CLKID_VCLK_INPUT			110
> +#define CLKID_VCLK2_INPUT			111
> +#define CLKID_VCLK_DIV				112
> +#define CLKID_VCLK2_DIV				113
> +#define CLKID_VCLK_DIV2_EN			114
> +#define CLKID_VCLK_DIV4_EN			115
> +#define CLKID_VCLK_DIV6_EN			116
> +#define CLKID_VCLK_DIV12_EN			117
> +#define CLKID_VCLK2_DIV2_EN			118
> +#define CLKID_VCLK2_DIV4_EN			119
> +#define CLKID_VCLK2_DIV6_EN			120
> +#define CLKID_VCLK2_DIV12_EN			121
> +#define CLKID_CTS_ENCL_SEL			132
>  
> -#define NR_CLKS					91
> +#define NR_CLKS					134
>  
>  /* include the CLKIDs that have been made part of the DT binding */
>  #include <dt-bindings/clock/axg-clkc.h>

Overall, there is quite an heavy use of CLK_IGNORE_USED and
CLK_GET_RATE_NOCACHE which seems to indicate that something else is
poking around in the clocks registers

Details about why it should be done this way, and not through CCF API,
should be provided.

_______________________________________________
linux-amlogic mailing list
linux-amlogic@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-amlogic

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

* Re: [PATCH 4/4] clk: meson: axg: add MIPI DSI Host clock
  2020-09-07  9:38   ` Neil Armstrong
  (?)
@ 2020-09-10 10:15     ` Jerome Brunet
  -1 siblings, 0 replies; 30+ messages in thread
From: Jerome Brunet @ 2020-09-10 10:15 UTC (permalink / raw)
  To: Neil Armstrong; +Cc: linux-amlogic, linux-clk, linux-arm-kernel, linux-kernel


On Mon 07 Sep 2020 at 11:38, Neil Armstrong <narmstrong@baylibre.com> wrote:

> This adds the MIPI DSI Host clock, used to measure the signal timings (ENC VSYNC or
> DW-MIPI-DSI eDPI timings).
>
> Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
> ---
>  drivers/clk/meson/axg.c | 66 +++++++++++++++++++++++++++++++++++++++++
>  drivers/clk/meson/axg.h |  4 ++-
>  2 files changed, 69 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/clk/meson/axg.c b/drivers/clk/meson/axg.c
> index 2550616c14b0..0094ca6388d8 100644
> --- a/drivers/clk/meson/axg.c
> +++ b/drivers/clk/meson/axg.c
> @@ -1724,6 +1724,66 @@ static struct clk_regmap axg_cts_encl = {
>  	},
>  };
>  
> +/* MIPI DSI Host Clock */
> +
> +static const struct clk_parent_data axg_vdin_meas_parent_data[] = {
> +	{ .fw_name = "xtal", },
> +	{ .hw = &axg_fclk_div4.hw },
> +	{ .hw = &axg_fclk_div3.hw },
> +	{ .hw = &axg_fclk_div5.hw },
> +	{ },
> +	{ },

As you've done in other patches, I'd prefer if you used an index table
instead of having empty entries.

> +	{ .hw = &axg_fclk_div2.hw },
> +	{ .hw = &axg_fclk_div7.hw },
> +};
> +
> +static struct clk_regmap axg_vdin_meas_sel = {
> +	.data = &(struct clk_regmap_mux_data){
> +		.offset = HHI_VDIN_MEAS_CLK_CNTL,
> +		.mask = 0x7,
> +		.shift = 21,
> +		.flags = CLK_MUX_ROUND_CLOSEST,
> +	},
> +	.hw.init = &(struct clk_init_data){
> +		.name = "vdin_meas_sel",
> +		.ops = &clk_regmap_mux_ops,
> +		.parent_data = axg_vdin_meas_parent_data,
> +		.num_parents = ARRAY_SIZE(axg_vdin_meas_parent_data),
> +		.flags = CLK_SET_RATE_NO_REPARENT,

A comment about why manual control is required would be nice.

> +	},
> +};
> +
> +static struct clk_regmap axg_vdin_meas_div = {
> +	.data = &(struct clk_regmap_div_data){
> +		.offset = HHI_VDIN_MEAS_CLK_CNTL,
> +		.shift = 12,
> +		.width = 7,
> +	},
> +	.hw.init = &(struct clk_init_data){
> +		.name = "vdin_meas_div",
> +		.ops = &clk_regmap_divider_ops,
> +		.parent_hws = (const struct clk_hw *[]) {
> +			&axg_vdin_meas_sel.hw },
> +		.num_parents = 1,
> +		.flags = CLK_SET_RATE_PARENT,
> +	},
> +};
> +
> +static struct clk_regmap axg_vdin_meas = {
> +	.data = &(struct clk_regmap_gate_data){
> +		.offset = HHI_VDIN_MEAS_CLK_CNTL,
> +		.bit_idx = 20,
> +	},
> +	.hw.init = &(struct clk_init_data) {
> +		.name = "vdin_meas",
> +		.ops = &clk_regmap_gate_ops,
> +		.parent_hws = (const struct clk_hw *[]) {
> +			&axg_vdin_meas_div.hw },
> +		.num_parents = 1,
> +		.flags = CLK_SET_RATE_PARENT,
> +	},
> +};
> +
>  static u32 mux_table_gen_clk[]	= { 0, 4, 5, 6, 7, 8,
>  				    9, 10, 11, 13, 14, };
>  static const struct clk_parent_data gen_clk_parent_data[] = {
> @@ -1987,6 +2047,9 @@ static struct clk_hw_onecell_data axg_hw_onecell_data = {
>  		[CLKID_VCLK2_DIV12]		= &axg_vclk2_div12.hw,
>  		[CLKID_CTS_ENCL_SEL]		= &axg_cts_encl_sel.hw,
>  		[CLKID_CTS_ENCL]		= &axg_cts_encl.hw,
> +		[CLKID_VDIN_MEAS_SEL]		= &axg_vdin_meas_sel.hw,
> +		[CLKID_VDIN_MEAS_DIV]		= &axg_vdin_meas_div.hw,
> +		[CLKID_VDIN_MEAS]		= &axg_vdin_meas.hw,
>  		[NR_CLKS]			= NULL,
>  	},
>  	.num = NR_CLKS,
> @@ -2115,6 +2178,9 @@ static struct clk_regmap *const axg_clk_regmaps[] = {
>  	&axg_vclk2_div12_en,
>  	&axg_cts_encl_sel,
>  	&axg_cts_encl,
> +	&axg_vdin_meas_sel,
> +	&axg_vdin_meas_div,
> +	&axg_vdin_meas,
>  };
>  
>  static const struct meson_eeclkc_data axg_clkc_data = {
> diff --git a/drivers/clk/meson/axg.h b/drivers/clk/meson/axg.h
> index a8787b394a47..481b307ea3cb 100644
> --- a/drivers/clk/meson/axg.h
> +++ b/drivers/clk/meson/axg.h
> @@ -158,8 +158,10 @@
>  #define CLKID_VCLK2_DIV6_EN			120
>  #define CLKID_VCLK2_DIV12_EN			121
>  #define CLKID_CTS_ENCL_SEL			132
> +#define CLKID_VDIN_MEAS_SEL			134
> +#define CLKID_VDIN_MEAS_DIV			135
>  
> -#define NR_CLKS					134
> +#define NR_CLKS					137
>  
>  /* include the CLKIDs that have been made part of the DT binding */
>  #include <dt-bindings/clock/axg-clkc.h>


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

* Re: [PATCH 4/4] clk: meson: axg: add MIPI DSI Host clock
@ 2020-09-10 10:15     ` Jerome Brunet
  0 siblings, 0 replies; 30+ messages in thread
From: Jerome Brunet @ 2020-09-10 10:15 UTC (permalink / raw)
  To: Neil Armstrong; +Cc: linux-amlogic, linux-clk, linux-arm-kernel, linux-kernel


On Mon 07 Sep 2020 at 11:38, Neil Armstrong <narmstrong@baylibre.com> wrote:

> This adds the MIPI DSI Host clock, used to measure the signal timings (ENC VSYNC or
> DW-MIPI-DSI eDPI timings).
>
> Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
> ---
>  drivers/clk/meson/axg.c | 66 +++++++++++++++++++++++++++++++++++++++++
>  drivers/clk/meson/axg.h |  4 ++-
>  2 files changed, 69 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/clk/meson/axg.c b/drivers/clk/meson/axg.c
> index 2550616c14b0..0094ca6388d8 100644
> --- a/drivers/clk/meson/axg.c
> +++ b/drivers/clk/meson/axg.c
> @@ -1724,6 +1724,66 @@ static struct clk_regmap axg_cts_encl = {
>  	},
>  };
>  
> +/* MIPI DSI Host Clock */
> +
> +static const struct clk_parent_data axg_vdin_meas_parent_data[] = {
> +	{ .fw_name = "xtal", },
> +	{ .hw = &axg_fclk_div4.hw },
> +	{ .hw = &axg_fclk_div3.hw },
> +	{ .hw = &axg_fclk_div5.hw },
> +	{ },
> +	{ },

As you've done in other patches, I'd prefer if you used an index table
instead of having empty entries.

> +	{ .hw = &axg_fclk_div2.hw },
> +	{ .hw = &axg_fclk_div7.hw },
> +};
> +
> +static struct clk_regmap axg_vdin_meas_sel = {
> +	.data = &(struct clk_regmap_mux_data){
> +		.offset = HHI_VDIN_MEAS_CLK_CNTL,
> +		.mask = 0x7,
> +		.shift = 21,
> +		.flags = CLK_MUX_ROUND_CLOSEST,
> +	},
> +	.hw.init = &(struct clk_init_data){
> +		.name = "vdin_meas_sel",
> +		.ops = &clk_regmap_mux_ops,
> +		.parent_data = axg_vdin_meas_parent_data,
> +		.num_parents = ARRAY_SIZE(axg_vdin_meas_parent_data),
> +		.flags = CLK_SET_RATE_NO_REPARENT,

A comment about why manual control is required would be nice.

> +	},
> +};
> +
> +static struct clk_regmap axg_vdin_meas_div = {
> +	.data = &(struct clk_regmap_div_data){
> +		.offset = HHI_VDIN_MEAS_CLK_CNTL,
> +		.shift = 12,
> +		.width = 7,
> +	},
> +	.hw.init = &(struct clk_init_data){
> +		.name = "vdin_meas_div",
> +		.ops = &clk_regmap_divider_ops,
> +		.parent_hws = (const struct clk_hw *[]) {
> +			&axg_vdin_meas_sel.hw },
> +		.num_parents = 1,
> +		.flags = CLK_SET_RATE_PARENT,
> +	},
> +};
> +
> +static struct clk_regmap axg_vdin_meas = {
> +	.data = &(struct clk_regmap_gate_data){
> +		.offset = HHI_VDIN_MEAS_CLK_CNTL,
> +		.bit_idx = 20,
> +	},
> +	.hw.init = &(struct clk_init_data) {
> +		.name = "vdin_meas",
> +		.ops = &clk_regmap_gate_ops,
> +		.parent_hws = (const struct clk_hw *[]) {
> +			&axg_vdin_meas_div.hw },
> +		.num_parents = 1,
> +		.flags = CLK_SET_RATE_PARENT,
> +	},
> +};
> +
>  static u32 mux_table_gen_clk[]	= { 0, 4, 5, 6, 7, 8,
>  				    9, 10, 11, 13, 14, };
>  static const struct clk_parent_data gen_clk_parent_data[] = {
> @@ -1987,6 +2047,9 @@ static struct clk_hw_onecell_data axg_hw_onecell_data = {
>  		[CLKID_VCLK2_DIV12]		= &axg_vclk2_div12.hw,
>  		[CLKID_CTS_ENCL_SEL]		= &axg_cts_encl_sel.hw,
>  		[CLKID_CTS_ENCL]		= &axg_cts_encl.hw,
> +		[CLKID_VDIN_MEAS_SEL]		= &axg_vdin_meas_sel.hw,
> +		[CLKID_VDIN_MEAS_DIV]		= &axg_vdin_meas_div.hw,
> +		[CLKID_VDIN_MEAS]		= &axg_vdin_meas.hw,
>  		[NR_CLKS]			= NULL,
>  	},
>  	.num = NR_CLKS,
> @@ -2115,6 +2178,9 @@ static struct clk_regmap *const axg_clk_regmaps[] = {
>  	&axg_vclk2_div12_en,
>  	&axg_cts_encl_sel,
>  	&axg_cts_encl,
> +	&axg_vdin_meas_sel,
> +	&axg_vdin_meas_div,
> +	&axg_vdin_meas,
>  };
>  
>  static const struct meson_eeclkc_data axg_clkc_data = {
> diff --git a/drivers/clk/meson/axg.h b/drivers/clk/meson/axg.h
> index a8787b394a47..481b307ea3cb 100644
> --- a/drivers/clk/meson/axg.h
> +++ b/drivers/clk/meson/axg.h
> @@ -158,8 +158,10 @@
>  #define CLKID_VCLK2_DIV6_EN			120
>  #define CLKID_VCLK2_DIV12_EN			121
>  #define CLKID_CTS_ENCL_SEL			132
> +#define CLKID_VDIN_MEAS_SEL			134
> +#define CLKID_VDIN_MEAS_DIV			135
>  
> -#define NR_CLKS					134
> +#define NR_CLKS					137
>  
>  /* include the CLKIDs that have been made part of the DT binding */
>  #include <dt-bindings/clock/axg-clkc.h>


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH 4/4] clk: meson: axg: add MIPI DSI Host clock
@ 2020-09-10 10:15     ` Jerome Brunet
  0 siblings, 0 replies; 30+ messages in thread
From: Jerome Brunet @ 2020-09-10 10:15 UTC (permalink / raw)
  To: Neil Armstrong; +Cc: linux-amlogic, linux-clk, linux-arm-kernel, linux-kernel


On Mon 07 Sep 2020 at 11:38, Neil Armstrong <narmstrong@baylibre.com> wrote:

> This adds the MIPI DSI Host clock, used to measure the signal timings (ENC VSYNC or
> DW-MIPI-DSI eDPI timings).
>
> Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
> ---
>  drivers/clk/meson/axg.c | 66 +++++++++++++++++++++++++++++++++++++++++
>  drivers/clk/meson/axg.h |  4 ++-
>  2 files changed, 69 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/clk/meson/axg.c b/drivers/clk/meson/axg.c
> index 2550616c14b0..0094ca6388d8 100644
> --- a/drivers/clk/meson/axg.c
> +++ b/drivers/clk/meson/axg.c
> @@ -1724,6 +1724,66 @@ static struct clk_regmap axg_cts_encl = {
>  	},
>  };
>  
> +/* MIPI DSI Host Clock */
> +
> +static const struct clk_parent_data axg_vdin_meas_parent_data[] = {
> +	{ .fw_name = "xtal", },
> +	{ .hw = &axg_fclk_div4.hw },
> +	{ .hw = &axg_fclk_div3.hw },
> +	{ .hw = &axg_fclk_div5.hw },
> +	{ },
> +	{ },

As you've done in other patches, I'd prefer if you used an index table
instead of having empty entries.

> +	{ .hw = &axg_fclk_div2.hw },
> +	{ .hw = &axg_fclk_div7.hw },
> +};
> +
> +static struct clk_regmap axg_vdin_meas_sel = {
> +	.data = &(struct clk_regmap_mux_data){
> +		.offset = HHI_VDIN_MEAS_CLK_CNTL,
> +		.mask = 0x7,
> +		.shift = 21,
> +		.flags = CLK_MUX_ROUND_CLOSEST,
> +	},
> +	.hw.init = &(struct clk_init_data){
> +		.name = "vdin_meas_sel",
> +		.ops = &clk_regmap_mux_ops,
> +		.parent_data = axg_vdin_meas_parent_data,
> +		.num_parents = ARRAY_SIZE(axg_vdin_meas_parent_data),
> +		.flags = CLK_SET_RATE_NO_REPARENT,

A comment about why manual control is required would be nice.

> +	},
> +};
> +
> +static struct clk_regmap axg_vdin_meas_div = {
> +	.data = &(struct clk_regmap_div_data){
> +		.offset = HHI_VDIN_MEAS_CLK_CNTL,
> +		.shift = 12,
> +		.width = 7,
> +	},
> +	.hw.init = &(struct clk_init_data){
> +		.name = "vdin_meas_div",
> +		.ops = &clk_regmap_divider_ops,
> +		.parent_hws = (const struct clk_hw *[]) {
> +			&axg_vdin_meas_sel.hw },
> +		.num_parents = 1,
> +		.flags = CLK_SET_RATE_PARENT,
> +	},
> +};
> +
> +static struct clk_regmap axg_vdin_meas = {
> +	.data = &(struct clk_regmap_gate_data){
> +		.offset = HHI_VDIN_MEAS_CLK_CNTL,
> +		.bit_idx = 20,
> +	},
> +	.hw.init = &(struct clk_init_data) {
> +		.name = "vdin_meas",
> +		.ops = &clk_regmap_gate_ops,
> +		.parent_hws = (const struct clk_hw *[]) {
> +			&axg_vdin_meas_div.hw },
> +		.num_parents = 1,
> +		.flags = CLK_SET_RATE_PARENT,
> +	},
> +};
> +
>  static u32 mux_table_gen_clk[]	= { 0, 4, 5, 6, 7, 8,
>  				    9, 10, 11, 13, 14, };
>  static const struct clk_parent_data gen_clk_parent_data[] = {
> @@ -1987,6 +2047,9 @@ static struct clk_hw_onecell_data axg_hw_onecell_data = {
>  		[CLKID_VCLK2_DIV12]		= &axg_vclk2_div12.hw,
>  		[CLKID_CTS_ENCL_SEL]		= &axg_cts_encl_sel.hw,
>  		[CLKID_CTS_ENCL]		= &axg_cts_encl.hw,
> +		[CLKID_VDIN_MEAS_SEL]		= &axg_vdin_meas_sel.hw,
> +		[CLKID_VDIN_MEAS_DIV]		= &axg_vdin_meas_div.hw,
> +		[CLKID_VDIN_MEAS]		= &axg_vdin_meas.hw,
>  		[NR_CLKS]			= NULL,
>  	},
>  	.num = NR_CLKS,
> @@ -2115,6 +2178,9 @@ static struct clk_regmap *const axg_clk_regmaps[] = {
>  	&axg_vclk2_div12_en,
>  	&axg_cts_encl_sel,
>  	&axg_cts_encl,
> +	&axg_vdin_meas_sel,
> +	&axg_vdin_meas_div,
> +	&axg_vdin_meas,
>  };
>  
>  static const struct meson_eeclkc_data axg_clkc_data = {
> diff --git a/drivers/clk/meson/axg.h b/drivers/clk/meson/axg.h
> index a8787b394a47..481b307ea3cb 100644
> --- a/drivers/clk/meson/axg.h
> +++ b/drivers/clk/meson/axg.h
> @@ -158,8 +158,10 @@
>  #define CLKID_VCLK2_DIV6_EN			120
>  #define CLKID_VCLK2_DIV12_EN			121
>  #define CLKID_CTS_ENCL_SEL			132
> +#define CLKID_VDIN_MEAS_SEL			134
> +#define CLKID_VDIN_MEAS_DIV			135
>  
> -#define NR_CLKS					134
> +#define NR_CLKS					137
>  
>  /* include the CLKIDs that have been made part of the DT binding */
>  #include <dt-bindings/clock/axg-clkc.h>


_______________________________________________
linux-amlogic mailing list
linux-amlogic@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-amlogic

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

* Re: [PATCH 3/4] clk: meson: axg: add Video Clocks
  2020-09-10 10:13     ` Jerome Brunet
  (?)
@ 2020-09-10 11:47       ` Neil Armstrong
  -1 siblings, 0 replies; 30+ messages in thread
From: Neil Armstrong @ 2020-09-10 11:47 UTC (permalink / raw)
  To: Jerome Brunet; +Cc: linux-amlogic, linux-clk, linux-arm-kernel, linux-kernel

Hi,

On 10/09/2020 12:13, Jerome Brunet wrote:
> 
> On Mon 07 Sep 2020 at 11:38, Neil Armstrong <narmstrong@baylibre.com> wrote:
> 
>> Add the Video Clocks present on the Amlogic AXg SoCs.
>>
>> The AXG only has a single ENCL CTS clock and even if VCLK exist along VCLK2,
>> only VCLK2 is used since it clocks the MIPI DSI IP directly.
>>
>> Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
>> ---
>>  drivers/clk/meson/axg.c | 774 ++++++++++++++++++++++++++++++++++++++++
>>  drivers/clk/meson/axg.h |  21 +-
>>  2 files changed, 794 insertions(+), 1 deletion(-)
>>
>> diff --git a/drivers/clk/meson/axg.c b/drivers/clk/meson/axg.c
>> index 13fc0006f63d..2550616c14b0 100644
>> --- a/drivers/clk/meson/axg.c
>> +++ b/drivers/clk/meson/axg.c
>> @@ -1026,6 +1026,704 @@ static struct clk_regmap axg_sd_emmc_c_clk0 = {
>>  	},
>>  };
>>  
>> +/* VPU Clock */
>> +
>> +static const struct clk_hw *axg_vpu_parent_hws[] = {
>> +	&axg_fclk_div4.hw,
>> +	&axg_fclk_div3.hw,
>> +	&axg_fclk_div5.hw,
>> +	&axg_fclk_div7.hw,
>> +};
>> +
>> +static struct clk_regmap axg_vpu_0_sel = {
>> +	.data = &(struct clk_regmap_mux_data){
>> +		.offset = HHI_VPU_CLK_CNTL,
>> +		.mask = 0x3,
>> +		.shift = 9,
>> +	},
>> +	.hw.init = &(struct clk_init_data){
>> +		.name = "vpu_0_sel",
>> +		.ops = &clk_regmap_mux_ops,
>> +		/*
>> +		 * bits 9:10 selects from 4 possible parents:
>> +		 * fclk_div4, fclk_div3, fclk_div5, fclk_div7,
>> +		 */
> 
> These comments (and the same bellow) are not very useful

Ok, these are copy/paste from gxbb.c and g12a.c, I wonder why these are now useless.

> 
>> +		.parent_hws = axg_vpu_parent_hws,
>> +		.num_parents = ARRAY_SIZE(axg_vpu_parent_hws),
> 
> Could you add a comment here explaining why parenting needs to be
> manually controlled ?

Ditto, this was already explained for GXBB & G12A.
The VPU clock needs a specific clock parenting defined in DT to
achieve the frequency used by the vendor.

> 
>> +		.flags = CLK_SET_RATE_NO_REPARENT,
>> +	},
>> +};
>> +
>> +static struct clk_regmap axg_vpu_0_div = {
>> +	.data = &(struct clk_regmap_div_data){
>> +		.offset = HHI_VPU_CLK_CNTL,
>> +		.shift = 0,
>> +		.width = 7,
>> +	},
>> +	.hw.init = &(struct clk_init_data){
>> +		.name = "vpu_0_div",
>> +		.ops = &clk_regmap_divider_ops,
>> +		.parent_hws = (const struct clk_hw *[]) { &axg_vpu_0_sel.hw },
>> +		.num_parents = 1,
>> +		.flags = CLK_SET_RATE_PARENT,
>> +	},
>> +};
>> +
>> +static struct clk_regmap axg_vpu_0 = {
>> +	.data = &(struct clk_regmap_gate_data){
>> +		.offset = HHI_VPU_CLK_CNTL,
>> +		.bit_idx = 8,
>> +	},
>> +	.hw.init = &(struct clk_init_data) {
>> +		.name = "vpu_0",
>> +		.ops = &clk_regmap_gate_ops,
>> +		.parent_hws = (const struct clk_hw *[]) { &axg_vpu_0_div.hw },
>> +		.num_parents = 1,
>> +		.flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
> 
> Why is UNUSED required ?

It's UNUSED until we have a mechanism to keep a clock enabled until the proper
module is loaded, and it was already discussed for GXBB & G12A.

> 
>> +	},
>> +};
>> +
>> +static struct clk_regmap axg_vpu_1_sel = {
>> +	.data = &(struct clk_regmap_mux_data){
>> +		.offset = HHI_VPU_CLK_CNTL,
>> +		.mask = 0x3,
>> +		.shift = 25,
>> +	},
>> +	.hw.init = &(struct clk_init_data){
>> +		.name = "vpu_1_sel",
>> +		.ops = &clk_regmap_mux_ops,
>> +		/*
>> +		 * bits 25:26 selects from 4 possible parents:
>> +		 * fclk_div4, fclk_div3, fclk_div5, fclk_div7,
>> +		 */
>> +		.parent_hws = axg_vpu_parent_hws,
>> +		.num_parents = ARRAY_SIZE(axg_vpu_parent_hws),
>> +		.flags = CLK_SET_RATE_NO_REPARENT,
>> +	},
>> +};
>> +
>> +static struct clk_regmap axg_vpu_1_div = {
>> +	.data = &(struct clk_regmap_div_data){
>> +		.offset = HHI_VPU_CLK_CNTL,
>> +		.shift = 16,
>> +		.width = 7,
>> +	},
>> +	.hw.init = &(struct clk_init_data){
>> +		.name = "vpu_1_div",
>> +		.ops = &clk_regmap_divider_ops,
>> +		.parent_hws = (const struct clk_hw *[]) { &axg_vpu_1_sel.hw },
>> +		.num_parents = 1,
>> +		.flags = CLK_SET_RATE_PARENT,
>> +	},
>> +};
>> +
>> +static struct clk_regmap axg_vpu_1 = {
>> +	.data = &(struct clk_regmap_gate_data){
>> +		.offset = HHI_VPU_CLK_CNTL,
>> +		.bit_idx = 24,
>> +	},
>> +	.hw.init = &(struct clk_init_data) {
>> +		.name = "vpu_1",
>> +		.ops = &clk_regmap_gate_ops,
>> +		.parent_hws = (const struct clk_hw *[]) { &axg_vpu_1_div.hw },
>> +		.num_parents = 1,
>> +		.flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
>> +	},
>> +};
>> +
>> +static struct clk_regmap axg_vpu = {
>> +	.data = &(struct clk_regmap_mux_data){
>> +		.offset = HHI_VPU_CLK_CNTL,
>> +		.mask = 1,
>> +		.shift = 31,
>> +	},
>> +	.hw.init = &(struct clk_init_data){
>> +		.name = "vpu",
>> +		.ops = &clk_regmap_mux_ops,
>> +		/*
>> +		 * bit 31 selects from 2 possible parents:
>> +		 * vpu_0 or vpu_1
>> +		 */
>> +		.parent_hws = (const struct clk_hw *[]) {
>> +			&axg_vpu_0.hw,
>> +			&axg_vpu_1.hw
>> +		},
>> +		.num_parents = 2,
>> +		.flags = CLK_SET_RATE_NO_REPARENT,
>> +	},
>> +};
>> +
>> +/* VAPB Clock */
>> +
>> +static const struct clk_hw *axg_vapb_parent_hws[] = {
>> +	&axg_fclk_div4.hw,
>> +	&axg_fclk_div3.hw,
>> +	&axg_fclk_div5.hw,
>> +	&axg_fclk_div7.hw,
>> +};
> 
> This is the same as the vpu table. Could they share a single table ?

Yes, will do

> 
>> +
>> +static struct clk_regmap axg_vapb_0_sel = {
>> +	.data = &(struct clk_regmap_mux_data){
>> +		.offset = HHI_VAPBCLK_CNTL,
>> +		.mask = 0x3,
>> +		.shift = 9,
>> +	},
>> +	.hw.init = &(struct clk_init_data){
>> +		.name = "vapb_0_sel",
>> +		.ops = &clk_regmap_mux_ops,
>> +		/*
>> +		 * bits 9:10 selects from 4 possible parents:
>> +		 * fclk_div4, fclk_div3, fclk_div5, fclk_div7,
>> +		 */
>> +		.parent_hws = axg_vapb_parent_hws,
>> +		.num_parents = ARRAY_SIZE(axg_vapb_parent_hws),
>> +		.flags = CLK_SET_RATE_NO_REPARENT,
>> +	},
>> +};
>> +
>> +static struct clk_regmap axg_vapb_0_div = {
>> +	.data = &(struct clk_regmap_div_data){
>> +		.offset = HHI_VAPBCLK_CNTL,
>> +		.shift = 0,
>> +		.width = 7,
>> +	},
>> +	.hw.init = &(struct clk_init_data){
>> +		.name = "vapb_0_div",
>> +		.ops = &clk_regmap_divider_ops,
>> +		.parent_hws = (const struct clk_hw *[]) {
>> +			&axg_vapb_0_sel.hw
>> +		},
>> +		.num_parents = 1,
>> +		.flags = CLK_SET_RATE_PARENT,
>> +	},
>> +};
>> +
>> +static struct clk_regmap axg_vapb_0 = {
>> +	.data = &(struct clk_regmap_gate_data){
>> +		.offset = HHI_VAPBCLK_CNTL,
>> +		.bit_idx = 8,
>> +	},
>> +	.hw.init = &(struct clk_init_data) {
>> +		.name = "vapb_0",
>> +		.ops = &clk_regmap_gate_ops,
>> +		.parent_hws = (const struct clk_hw *[]) {
>> +			&axg_vapb_0_div.hw
>> +		},
>> +		.num_parents = 1,
>> +		.flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
>> +	},
>> +};
>> +
>> +static struct clk_regmap axg_vapb_1_sel = {
>> +	.data = &(struct clk_regmap_mux_data){
>> +		.offset = HHI_VAPBCLK_CNTL,
>> +		.mask = 0x3,
>> +		.shift = 25,
>> +	},
>> +	.hw.init = &(struct clk_init_data){
>> +		.name = "vapb_1_sel",
>> +		.ops = &clk_regmap_mux_ops,
>> +		/*
>> +		 * bits 25:26 selects from 4 possible parents:
>> +		 * fclk_div4, fclk_div3, fclk_div5, fclk_div7,
>> +		 */
>> +		.parent_hws = axg_vapb_parent_hws,
>> +		.num_parents = ARRAY_SIZE(axg_vapb_parent_hws),
>> +		.flags = CLK_SET_RATE_NO_REPARENT,
>> +	},
>> +};
>> +
>> +static struct clk_regmap axg_vapb_1_div = {
>> +	.data = &(struct clk_regmap_div_data){
>> +		.offset = HHI_VAPBCLK_CNTL,
>> +		.shift = 16,
>> +		.width = 7,
>> +	},
>> +	.hw.init = &(struct clk_init_data){
>> +		.name = "vapb_1_div",
>> +		.ops = &clk_regmap_divider_ops,
>> +		.parent_hws = (const struct clk_hw *[]) {
>> +			&axg_vapb_1_sel.hw
>> +		},
>> +		.num_parents = 1,
>> +		.flags = CLK_SET_RATE_PARENT,
>> +	},
>> +};
>> +
>> +static struct clk_regmap axg_vapb_1 = {
>> +	.data = &(struct clk_regmap_gate_data){
>> +		.offset = HHI_VAPBCLK_CNTL,
>> +		.bit_idx = 24,
>> +	},
>> +	.hw.init = &(struct clk_init_data) {
>> +		.name = "vapb_1",
>> +		.ops = &clk_regmap_gate_ops,
>> +		.parent_hws = (const struct clk_hw *[]) {
>> +			&axg_vapb_1_div.hw
>> +		},
>> +		.num_parents = 1,
>> +		.flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
>> +	},
>> +};
>> +
>> +static struct clk_regmap axg_vapb_sel = {
>> +	.data = &(struct clk_regmap_mux_data){
>> +		.offset = HHI_VAPBCLK_CNTL,
>> +		.mask = 1,
>> +		.shift = 31,
>> +	},
>> +	.hw.init = &(struct clk_init_data){
>> +		.name = "vapb_sel",
>> +		.ops = &clk_regmap_mux_ops,
>> +		/*
>> +		 * bit 31 selects from 2 possible parents:
>> +		 * vapb_0 or vapb_1
>> +		 */
>> +		.parent_hws = (const struct clk_hw *[]) {
>> +			&axg_vapb_0.hw,
>> +			&axg_vapb_1.hw
>> +		},
>> +		.num_parents = 2,
>> +		.flags = CLK_SET_RATE_NO_REPARENT,
>> +	},
>> +};
>> +
>> +static struct clk_regmap axg_vapb = {
>> +	.data = &(struct clk_regmap_gate_data){
>> +		.offset = HHI_VAPBCLK_CNTL,
>> +		.bit_idx = 30,
>> +	},
>> +	.hw.init = &(struct clk_init_data) {
>> +		.name = "vapb",
>> +		.ops = &clk_regmap_gate_ops,
>> +		.parent_hws = (const struct clk_hw *[]) { &axg_vapb_sel.hw },
>> +		.num_parents = 1,
>> +		.flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
>> +	},
>> +};
>> +
>> +/* Video Clocks */
>> +
>> +static const struct clk_hw *axg_vclk_parent_hws[] = {
>> +	&axg_gp0_pll.hw,
>> +	&axg_fclk_div4.hw,
>> +	&axg_fclk_div3.hw,
>> +	&axg_fclk_div5.hw,
>> +	&axg_fclk_div2.hw,
>> +	&axg_fclk_div7.hw,
>> +	&axg_mpll1.hw,
>> +};
>> +
>> +static struct clk_regmap axg_vclk_sel = {
>> +	.data = &(struct clk_regmap_mux_data){
>> +		.offset = HHI_VID_CLK_CNTL,
>> +		.mask = 0x7,
>> +		.shift = 16,
>> +	},
>> +	.hw.init = &(struct clk_init_data){
>> +		.name = "vclk_sel",
>> +		.ops = &clk_regmap_mux_ops,
>> +		.parent_hws = axg_vclk_parent_hws,
>> +		.num_parents = ARRAY_SIZE(axg_vclk_parent_hws),
>> +		.flags = CLK_SET_RATE_NO_REPARENT | CLK_GET_RATE_NOCACHE,
>> +	},
> 
> Why is NOCACHE ? Is there something poking behind CCF back ? if yes, why
> is this required ?

I'm surprised you ask this since the situation hasn't changed since I pushed the
video clock for GXBB, then G12A.

The switch to CCF for the VPU is still planned, but until now I was unable to allocate enough
time for this huge rework.

Since I'm the single DRM driver contributor and lacking any other reviewers, I must deal
with new features & bugfixing before moving to CCF.

The clock situation is far from perfect, and I'd also like it to be solved at some point.

I'll add the same explanation I gave for GXBB in https://lkml.kernel.org/r/1541516257-16157-5-git-send-email-narmstrong@baylibre.com

> 
>> +};
>> +
>> +static struct clk_regmap axg_vclk2_sel = {
>> +	.data = &(struct clk_regmap_mux_data){
>> +		.offset = HHI_VIID_CLK_CNTL,
>> +		.mask = 0x7,
>> +		.shift = 16,
>> +	},
>> +	.hw.init = &(struct clk_init_data){
>> +		.name = "vclk2_sel",
>> +		.ops = &clk_regmap_mux_ops,
>> +		.parent_hws = axg_vclk_parent_hws,
>> +		.num_parents = ARRAY_SIZE(axg_vclk_parent_hws),
>> +		.flags = CLK_SET_RATE_NO_REPARENT | CLK_GET_RATE_NOCACHE,
>> +	},
>> +};
>> +
>> +static struct clk_regmap axg_vclk_input = {
>> +	.data = &(struct clk_regmap_gate_data){
>> +		.offset = HHI_VID_CLK_DIV,
>> +		.bit_idx = 16,
>> +	},
>> +	.hw.init = &(struct clk_init_data) {
>> +		.name = "vclk_input",
>> +		.ops = &clk_regmap_gate_ops,
>> +		.parent_hws = (const struct clk_hw *[]) { &axg_vclk_sel.hw },
>> +		.num_parents = 1,
>> +		.flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
>> +	},
>> +};
>> +
>> +static struct clk_regmap axg_vclk2_input = {
>> +	.data = &(struct clk_regmap_gate_data){
>> +		.offset = HHI_VIID_CLK_DIV,
>> +		.bit_idx = 16,
>> +	},
>> +	.hw.init = &(struct clk_init_data) {
>> +		.name = "vclk2_input",
>> +		.ops = &clk_regmap_gate_ops,
>> +		.parent_hws = (const struct clk_hw *[]) { &axg_vclk2_sel.hw },
>> +		.num_parents = 1,
>> +		.flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
>> +	},
>> +};
>> +
>> +static struct clk_regmap axg_vclk_div = {
>> +	.data = &(struct clk_regmap_div_data){
>> +		.offset = HHI_VID_CLK_DIV,
>> +		.shift = 0,
>> +		.width = 8,
>> +	},
>> +	.hw.init = &(struct clk_init_data){
>> +		.name = "vclk_div",
>> +		.ops = &clk_regmap_divider_ops,
>> +		.parent_hws = (const struct clk_hw *[]) {
>> +			&axg_vclk_input.hw
>> +		},
>> +		.num_parents = 1,
>> +		.flags = CLK_GET_RATE_NOCACHE,
>> +	},
>> +};
>> +
>> +static struct clk_regmap axg_vclk2_div = {
>> +	.data = &(struct clk_regmap_div_data){
>> +		.offset = HHI_VIID_CLK_DIV,
>> +		.shift = 0,
>> +		.width = 8,
>> +	},
>> +	.hw.init = &(struct clk_init_data){
>> +		.name = "vclk2_div",
>> +		.ops = &clk_regmap_divider_ops,
>> +		.parent_hws = (const struct clk_hw *[]) {
>> +			&axg_vclk2_input.hw
>> +		},
>> +		.num_parents = 1,
>> +		.flags = CLK_GET_RATE_NOCACHE,
>> +	},
>> +};
>> +
>> +static struct clk_regmap axg_vclk = {
>> +	.data = &(struct clk_regmap_gate_data){
>> +		.offset = HHI_VID_CLK_CNTL,
>> +		.bit_idx = 19,
>> +	},
>> +	.hw.init = &(struct clk_init_data) {
>> +		.name = "vclk",
>> +		.ops = &clk_regmap_gate_ops,
>> +		.parent_hws = (const struct clk_hw *[]) { &axg_vclk_div.hw },
>> +		.num_parents = 1,
>> +		.flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
>> +	},
>> +};
>> +
>> +static struct clk_regmap axg_vclk2 = {
>> +	.data = &(struct clk_regmap_gate_data){
>> +		.offset = HHI_VIID_CLK_CNTL,
>> +		.bit_idx = 19,
>> +	},
>> +	.hw.init = &(struct clk_init_data) {
>> +		.name = "vclk2",
>> +		.ops = &clk_regmap_gate_ops,
>> +		.parent_hws = (const struct clk_hw *[]) { &axg_vclk2_div.hw },
>> +		.num_parents = 1,
>> +		.flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
>> +	},
>> +};
>> +
>> +static struct clk_regmap axg_vclk_div1 = {
>> +	.data = &(struct clk_regmap_gate_data){
>> +		.offset = HHI_VID_CLK_CNTL,
>> +		.bit_idx = 0,
>> +	},
>> +	.hw.init = &(struct clk_init_data) {
>> +		.name = "vclk_div1",
>> +		.ops = &clk_regmap_gate_ops,
>> +		.parent_hws = (const struct clk_hw *[]) { &axg_vclk.hw },
>> +		.num_parents = 1,
>> +		.flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
>> +	},
>> +};
>> +
>> +static struct clk_regmap axg_vclk_div2_en = {
>> +	.data = &(struct clk_regmap_gate_data){
>> +		.offset = HHI_VID_CLK_CNTL,
>> +		.bit_idx = 1,
>> +	},
>> +	.hw.init = &(struct clk_init_data) {
>> +		.name = "vclk_div2_en",
>> +		.ops = &clk_regmap_gate_ops,
>> +		.parent_hws = (const struct clk_hw *[]) { &axg_vclk.hw },
>> +		.num_parents = 1,
>> +		.flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
>> +	},
>> +};
>> +
>> +static struct clk_regmap axg_vclk_div4_en = {
>> +	.data = &(struct clk_regmap_gate_data){
>> +		.offset = HHI_VID_CLK_CNTL,
>> +		.bit_idx = 2,
>> +	},
>> +	.hw.init = &(struct clk_init_data) {
>> +		.name = "vclk_div4_en",
>> +		.ops = &clk_regmap_gate_ops,
>> +		.parent_hws = (const struct clk_hw *[]) { &axg_vclk.hw },
>> +		.num_parents = 1,
>> +		.flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
>> +	},
>> +};
>> +
>> +static struct clk_regmap axg_vclk_div6_en = {
>> +	.data = &(struct clk_regmap_gate_data){
>> +		.offset = HHI_VID_CLK_CNTL,
>> +		.bit_idx = 3,
>> +	},
>> +	.hw.init = &(struct clk_init_data) {
>> +		.name = "vclk_div6_en",
>> +		.ops = &clk_regmap_gate_ops,
>> +		.parent_hws = (const struct clk_hw *[]) { &axg_vclk.hw },
>> +		.num_parents = 1,
>> +		.flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
>> +	},
>> +};
>> +
>> +static struct clk_regmap axg_vclk_div12_en = {
>> +	.data = &(struct clk_regmap_gate_data){
>> +		.offset = HHI_VID_CLK_CNTL,
>> +		.bit_idx = 4,
>> +	},
>> +	.hw.init = &(struct clk_init_data) {
>> +		.name = "vclk_div12_en",
>> +		.ops = &clk_regmap_gate_ops,
>> +		.parent_hws = (const struct clk_hw *[]) { &axg_vclk.hw },
>> +		.num_parents = 1,
>> +		.flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
>> +	},
>> +};
>> +
>> +static struct clk_regmap axg_vclk2_div1 = {
>> +	.data = &(struct clk_regmap_gate_data){
>> +		.offset = HHI_VIID_CLK_CNTL,
>> +		.bit_idx = 0,
>> +	},
>> +	.hw.init = &(struct clk_init_data) {
>> +		.name = "vclk2_div1",
>> +		.ops = &clk_regmap_gate_ops,
>> +		.parent_hws = (const struct clk_hw *[]) { &axg_vclk2.hw },
>> +		.num_parents = 1,
>> +		.flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
>> +	},
>> +};
>> +
>> +static struct clk_regmap axg_vclk2_div2_en = {
>> +	.data = &(struct clk_regmap_gate_data){
>> +		.offset = HHI_VIID_CLK_CNTL,
>> +		.bit_idx = 1,
>> +	},
>> +	.hw.init = &(struct clk_init_data) {
>> +		.name = "vclk2_div2_en",
>> +		.ops = &clk_regmap_gate_ops,
>> +		.parent_hws = (const struct clk_hw *[]) { &axg_vclk2.hw },
>> +		.num_parents = 1,
>> +		.flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
>> +	},
>> +};
>> +
>> +static struct clk_regmap axg_vclk2_div4_en = {
>> +	.data = &(struct clk_regmap_gate_data){
>> +		.offset = HHI_VIID_CLK_CNTL,
>> +		.bit_idx = 2,
>> +	},
>> +	.hw.init = &(struct clk_init_data) {
>> +		.name = "vclk2_div4_en",
>> +		.ops = &clk_regmap_gate_ops,
>> +		.parent_hws = (const struct clk_hw *[]) { &axg_vclk2.hw },
>> +		.num_parents = 1,
>> +		.flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
>> +	},
>> +};
>> +
>> +static struct clk_regmap axg_vclk2_div6_en = {
>> +	.data = &(struct clk_regmap_gate_data){
>> +		.offset = HHI_VIID_CLK_CNTL,
>> +		.bit_idx = 3,
>> +	},
>> +	.hw.init = &(struct clk_init_data) {
>> +		.name = "vclk2_div6_en",
>> +		.ops = &clk_regmap_gate_ops,
>> +		.parent_hws = (const struct clk_hw *[]) { &axg_vclk2.hw },
>> +		.num_parents = 1,
>> +		.flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
>> +	},
>> +};
>> +
>> +static struct clk_regmap axg_vclk2_div12_en = {
>> +	.data = &(struct clk_regmap_gate_data){
>> +		.offset = HHI_VIID_CLK_CNTL,
>> +		.bit_idx = 4,
>> +	},
>> +	.hw.init = &(struct clk_init_data) {
>> +		.name = "vclk2_div12_en",
>> +		.ops = &clk_regmap_gate_ops,
>> +		.parent_hws = (const struct clk_hw *[]) { &axg_vclk2.hw },
>> +		.num_parents = 1,
>> +		.flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
>> +	},
>> +};
>> +
>> +static struct clk_fixed_factor axg_vclk_div2 = {
>> +	.mult = 1,
>> +	.div = 2,
>> +	.hw.init = &(struct clk_init_data){
>> +		.name = "vclk_div2",
>> +		.ops = &clk_fixed_factor_ops,
>> +		.parent_hws = (const struct clk_hw *[]) {
>> +			&axg_vclk_div2_en.hw
>> +		},
>> +		.num_parents = 1,
>> +	},
>> +};
>> +
>> +static struct clk_fixed_factor axg_vclk_div4 = {
>> +	.mult = 1,
>> +	.div = 4,
>> +	.hw.init = &(struct clk_init_data){
>> +		.name = "vclk_div4",
>> +		.ops = &clk_fixed_factor_ops,
>> +		.parent_hws = (const struct clk_hw *[]) {
>> +			&axg_vclk_div4_en.hw
>> +		},
>> +		.num_parents = 1,
>> +	},
>> +};
>> +
>> +static struct clk_fixed_factor axg_vclk_div6 = {
>> +	.mult = 1,
>> +	.div = 6,
>> +	.hw.init = &(struct clk_init_data){
>> +		.name = "vclk_div6",
>> +		.ops = &clk_fixed_factor_ops,
>> +		.parent_hws = (const struct clk_hw *[]) {
>> +			&axg_vclk_div6_en.hw
>> +		},
>> +		.num_parents = 1,
>> +	},
>> +};
>> +
>> +static struct clk_fixed_factor axg_vclk_div12 = {
>> +	.mult = 1,
>> +	.div = 12,
>> +	.hw.init = &(struct clk_init_data){
>> +		.name = "vclk_div12",
>> +		.ops = &clk_fixed_factor_ops,
>> +		.parent_hws = (const struct clk_hw *[]) {
>> +			&axg_vclk_div12_en.hw
>> +		},
>> +		.num_parents = 1,
>> +	},
>> +};
>> +
>> +static struct clk_fixed_factor axg_vclk2_div2 = {
>> +	.mult = 1,
>> +	.div = 2,
>> +	.hw.init = &(struct clk_init_data){
>> +		.name = "vclk2_div2",
>> +		.ops = &clk_fixed_factor_ops,
>> +		.parent_hws = (const struct clk_hw *[]) {
>> +			&axg_vclk2_div2_en.hw
>> +		},
>> +		.num_parents = 1,
>> +	},
>> +};
>> +
>> +static struct clk_fixed_factor axg_vclk2_div4 = {
>> +	.mult = 1,
>> +	.div = 4,
>> +	.hw.init = &(struct clk_init_data){
>> +		.name = "vclk2_div4",
>> +		.ops = &clk_fixed_factor_ops,
>> +		.parent_hws = (const struct clk_hw *[]) {
>> +			&axg_vclk2_div4_en.hw
>> +		},
>> +		.num_parents = 1,
>> +	},
>> +};
>> +
>> +static struct clk_fixed_factor axg_vclk2_div6 = {
>> +	.mult = 1,
>> +	.div = 6,
>> +	.hw.init = &(struct clk_init_data){
>> +		.name = "vclk2_div6",
>> +		.ops = &clk_fixed_factor_ops,
>> +		.parent_hws = (const struct clk_hw *[]) {
>> +			&axg_vclk2_div6_en.hw
>> +		},
>> +		.num_parents = 1,
>> +	},
>> +};
>> +
>> +static struct clk_fixed_factor axg_vclk2_div12 = {
>> +	.mult = 1,
>> +	.div = 12,
>> +	.hw.init = &(struct clk_init_data){
>> +		.name = "vclk2_div12",
>> +		.ops = &clk_fixed_factor_ops,
>> +		.parent_hws = (const struct clk_hw *[]) {
>> +			&axg_vclk2_div12_en.hw
>> +		},
>> +		.num_parents = 1,
>> +	},
>> +};
>> +
>> +static u32 mux_table_cts_sel[] = { 0, 1, 2, 3, 4, 8, 9, 10, 11, 12 };
>> +static const struct clk_hw *axg_cts_parent_hws[] = {
>> +	&axg_vclk_div1.hw,
>> +	&axg_vclk_div2.hw,
>> +	&axg_vclk_div4.hw,
>> +	&axg_vclk_div6.hw,
>> +	&axg_vclk_div12.hw,
>> +	&axg_vclk2_div1.hw,
>> +	&axg_vclk2_div2.hw,
>> +	&axg_vclk2_div4.hw,
>> +	&axg_vclk2_div6.hw,
>> +	&axg_vclk2_div12.hw,
>> +};
>> +
>> +static struct clk_regmap axg_cts_encl_sel = {
>> +	.data = &(struct clk_regmap_mux_data){
>> +		.offset = HHI_VIID_CLK_DIV,
>> +		.mask = 0xf,
>> +		.shift = 12,
>> +		.table = mux_table_cts_sel,
>> +	},
>> +	.hw.init = &(struct clk_init_data){
>> +		.name = "cts_encl_sel",
>> +		.ops = &clk_regmap_mux_ops,
>> +		.parent_hws = axg_cts_parent_hws,
>> +		.num_parents = ARRAY_SIZE(axg_cts_parent_hws),
>> +		.flags = CLK_SET_RATE_NO_REPARENT | CLK_GET_RATE_NOCACHE,
>> +	},
>> +};
>> +
>> +static struct clk_regmap axg_cts_encl = {
>> +	.data = &(struct clk_regmap_gate_data){
>> +		.offset = HHI_VID_CLK_CNTL2,
>> +		.bit_idx = 3,
>> +	},
>> +	.hw.init = &(struct clk_init_data) {
>> +		.name = "cts_encl",
>> +		.ops = &clk_regmap_gate_ops,
>> +		.parent_hws = (const struct clk_hw *[]) {
>> +			&axg_cts_encl_sel.hw
>> +		},
>> +		.num_parents = 1,
>> +		.flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
>> +	},
>> +};
>> +
>>  static u32 mux_table_gen_clk[]	= { 0, 4, 5, 6, 7, 8,
>>  				    9, 10, 11, 13, 14, };
>>  static const struct clk_parent_data gen_clk_parent_data[] = {
>> @@ -1246,6 +1944,49 @@ static struct clk_hw_onecell_data axg_hw_onecell_data = {
>>  		[CLKID_HIFI_PLL_DCO]		= &axg_hifi_pll_dco.hw,
>>  		[CLKID_PCIE_PLL_DCO]		= &axg_pcie_pll_dco.hw,
>>  		[CLKID_PCIE_PLL_OD]		= &axg_pcie_pll_od.hw,
>> +		[CLKID_VPU_0_DIV]		= &axg_vpu_0_div.hw,
>> +		[CLKID_VPU_0_SEL]		= &axg_vpu_0_sel.hw,
>> +		[CLKID_VPU_0]			= &axg_vpu_0.hw,
>> +		[CLKID_VPU_1_DIV]		= &axg_vpu_1_div.hw,
>> +		[CLKID_VPU_1_SEL]		= &axg_vpu_1_sel.hw,
>> +		[CLKID_VPU_1]			= &axg_vpu_1.hw,
>> +		[CLKID_VPU]			= &axg_vpu.hw,
>> +		[CLKID_VAPB_0_DIV]		= &axg_vapb_0_div.hw,
>> +		[CLKID_VAPB_0_SEL]		= &axg_vapb_0_sel.hw,
>> +		[CLKID_VAPB_0]			= &axg_vapb_0.hw,
>> +		[CLKID_VAPB_1_DIV]		= &axg_vapb_1_div.hw,
>> +		[CLKID_VAPB_1_SEL]		= &axg_vapb_1_sel.hw,
>> +		[CLKID_VAPB_1]			= &axg_vapb_1.hw,
>> +		[CLKID_VAPB_SEL]		= &axg_vapb_sel.hw,
>> +		[CLKID_VAPB]			= &axg_vapb.hw,
>> +		[CLKID_VCLK]			= &axg_vclk.hw,
>> +		[CLKID_VCLK2]			= &axg_vclk2.hw,
>> +		[CLKID_VCLK_SEL]		= &axg_vclk_sel.hw,
>> +		[CLKID_VCLK2_SEL]		= &axg_vclk2_sel.hw,
>> +		[CLKID_VCLK_INPUT]		= &axg_vclk_input.hw,
>> +		[CLKID_VCLK2_INPUT]		= &axg_vclk2_input.hw,
>> +		[CLKID_VCLK_DIV]		= &axg_vclk_div.hw,
>> +		[CLKID_VCLK2_DIV]		= &axg_vclk2_div.hw,
>> +		[CLKID_VCLK_DIV2_EN]		= &axg_vclk_div2_en.hw,
>> +		[CLKID_VCLK_DIV4_EN]		= &axg_vclk_div4_en.hw,
>> +		[CLKID_VCLK_DIV6_EN]		= &axg_vclk_div6_en.hw,
>> +		[CLKID_VCLK_DIV12_EN]		= &axg_vclk_div12_en.hw,
>> +		[CLKID_VCLK2_DIV2_EN]		= &axg_vclk2_div2_en.hw,
>> +		[CLKID_VCLK2_DIV4_EN]		= &axg_vclk2_div4_en.hw,
>> +		[CLKID_VCLK2_DIV6_EN]		= &axg_vclk2_div6_en.hw,
>> +		[CLKID_VCLK2_DIV12_EN]		= &axg_vclk2_div12_en.hw,
>> +		[CLKID_VCLK_DIV1]		= &axg_vclk_div1.hw,
>> +		[CLKID_VCLK_DIV2]		= &axg_vclk_div2.hw,
>> +		[CLKID_VCLK_DIV4]		= &axg_vclk_div4.hw,
>> +		[CLKID_VCLK_DIV6]		= &axg_vclk_div6.hw,
>> +		[CLKID_VCLK_DIV12]		= &axg_vclk_div12.hw,
>> +		[CLKID_VCLK2_DIV1]		= &axg_vclk2_div1.hw,
>> +		[CLKID_VCLK2_DIV2]		= &axg_vclk2_div2.hw,
>> +		[CLKID_VCLK2_DIV4]		= &axg_vclk2_div4.hw,
>> +		[CLKID_VCLK2_DIV6]		= &axg_vclk2_div6.hw,
>> +		[CLKID_VCLK2_DIV12]		= &axg_vclk2_div12.hw,
>> +		[CLKID_CTS_ENCL_SEL]		= &axg_cts_encl_sel.hw,
>> +		[CLKID_CTS_ENCL]		= &axg_cts_encl.hw,
>>  		[NR_CLKS]			= NULL,
>>  	},
>>  	.num = NR_CLKS,
>> @@ -1341,6 +2082,39 @@ static struct clk_regmap *const axg_clk_regmaps[] = {
>>  	&axg_hifi_pll_dco,
>>  	&axg_pcie_pll_dco,
>>  	&axg_pcie_pll_od,
>> +	&axg_vpu_0_div,
>> +	&axg_vpu_0_sel,
>> +	&axg_vpu_0,
>> +	&axg_vpu_1_div,
>> +	&axg_vpu_1_sel,
>> +	&axg_vpu_1,
>> +	&axg_vpu,
>> +	&axg_vapb_0_div,
>> +	&axg_vapb_0_sel,
>> +	&axg_vapb_0,
>> +	&axg_vapb_1_div,
>> +	&axg_vapb_1_sel,
>> +	&axg_vapb_1,
>> +	&axg_vapb_sel,
>> +	&axg_vapb,
>> +	&axg_vclk,
>> +	&axg_vclk2,
>> +	&axg_vclk_sel,
>> +	&axg_vclk2_sel,
>> +	&axg_vclk_input,
>> +	&axg_vclk2_input,
>> +	&axg_vclk_div,
>> +	&axg_vclk2_div,
>> +	&axg_vclk_div2_en,
>> +	&axg_vclk_div4_en,
>> +	&axg_vclk_div6_en,
>> +	&axg_vclk_div12_en,
>> +	&axg_vclk2_div2_en,
>> +	&axg_vclk2_div4_en,
>> +	&axg_vclk2_div6_en,
>> +	&axg_vclk2_div12_en,
>> +	&axg_cts_encl_sel,
>> +	&axg_cts_encl,
>>  };
>>  
>>  static const struct meson_eeclkc_data axg_clkc_data = {
>> diff --git a/drivers/clk/meson/axg.h b/drivers/clk/meson/axg.h
>> index 0431dabac629..a8787b394a47 100644
>> --- a/drivers/clk/meson/axg.h
>> +++ b/drivers/clk/meson/axg.h
>> @@ -139,8 +139,27 @@
>>  #define CLKID_HIFI_PLL_DCO			88
>>  #define CLKID_PCIE_PLL_DCO			89
>>  #define CLKID_PCIE_PLL_OD			90
>> +#define CLKID_VPU_0_DIV				91
>> +#define CLKID_VPU_1_DIV				94
>> +#define CLKID_VAPB_0_DIV			98
>> +#define CLKID_VAPB_1_DIV			101
>> +#define CLKID_VCLK_SEL				108
>> +#define CLKID_VCLK2_SEL				109
>> +#define CLKID_VCLK_INPUT			110
>> +#define CLKID_VCLK2_INPUT			111
>> +#define CLKID_VCLK_DIV				112
>> +#define CLKID_VCLK2_DIV				113
>> +#define CLKID_VCLK_DIV2_EN			114
>> +#define CLKID_VCLK_DIV4_EN			115
>> +#define CLKID_VCLK_DIV6_EN			116
>> +#define CLKID_VCLK_DIV12_EN			117
>> +#define CLKID_VCLK2_DIV2_EN			118
>> +#define CLKID_VCLK2_DIV4_EN			119
>> +#define CLKID_VCLK2_DIV6_EN			120
>> +#define CLKID_VCLK2_DIV12_EN			121
>> +#define CLKID_CTS_ENCL_SEL			132
>>  
>> -#define NR_CLKS					91
>> +#define NR_CLKS					134
>>  
>>  /* include the CLKIDs that have been made part of the DT binding */
>>  #include <dt-bindings/clock/axg-clkc.h>
> 
> Overall, there is quite an heavy use of CLK_IGNORE_USED and
> CLK_GET_RATE_NOCACHE which seems to indicate that something else is
> poking around in the clocks registers
> 
> Details about why it should be done this way, and not through CCF API,
> should be provided.
>
Thanks,
Neil

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

* Re: [PATCH 3/4] clk: meson: axg: add Video Clocks
@ 2020-09-10 11:47       ` Neil Armstrong
  0 siblings, 0 replies; 30+ messages in thread
From: Neil Armstrong @ 2020-09-10 11:47 UTC (permalink / raw)
  To: Jerome Brunet; +Cc: linux-amlogic, linux-clk, linux-arm-kernel, linux-kernel

Hi,

On 10/09/2020 12:13, Jerome Brunet wrote:
> 
> On Mon 07 Sep 2020 at 11:38, Neil Armstrong <narmstrong@baylibre.com> wrote:
> 
>> Add the Video Clocks present on the Amlogic AXg SoCs.
>>
>> The AXG only has a single ENCL CTS clock and even if VCLK exist along VCLK2,
>> only VCLK2 is used since it clocks the MIPI DSI IP directly.
>>
>> Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
>> ---
>>  drivers/clk/meson/axg.c | 774 ++++++++++++++++++++++++++++++++++++++++
>>  drivers/clk/meson/axg.h |  21 +-
>>  2 files changed, 794 insertions(+), 1 deletion(-)
>>
>> diff --git a/drivers/clk/meson/axg.c b/drivers/clk/meson/axg.c
>> index 13fc0006f63d..2550616c14b0 100644
>> --- a/drivers/clk/meson/axg.c
>> +++ b/drivers/clk/meson/axg.c
>> @@ -1026,6 +1026,704 @@ static struct clk_regmap axg_sd_emmc_c_clk0 = {
>>  	},
>>  };
>>  
>> +/* VPU Clock */
>> +
>> +static const struct clk_hw *axg_vpu_parent_hws[] = {
>> +	&axg_fclk_div4.hw,
>> +	&axg_fclk_div3.hw,
>> +	&axg_fclk_div5.hw,
>> +	&axg_fclk_div7.hw,
>> +};
>> +
>> +static struct clk_regmap axg_vpu_0_sel = {
>> +	.data = &(struct clk_regmap_mux_data){
>> +		.offset = HHI_VPU_CLK_CNTL,
>> +		.mask = 0x3,
>> +		.shift = 9,
>> +	},
>> +	.hw.init = &(struct clk_init_data){
>> +		.name = "vpu_0_sel",
>> +		.ops = &clk_regmap_mux_ops,
>> +		/*
>> +		 * bits 9:10 selects from 4 possible parents:
>> +		 * fclk_div4, fclk_div3, fclk_div5, fclk_div7,
>> +		 */
> 
> These comments (and the same bellow) are not very useful

Ok, these are copy/paste from gxbb.c and g12a.c, I wonder why these are now useless.

> 
>> +		.parent_hws = axg_vpu_parent_hws,
>> +		.num_parents = ARRAY_SIZE(axg_vpu_parent_hws),
> 
> Could you add a comment here explaining why parenting needs to be
> manually controlled ?

Ditto, this was already explained for GXBB & G12A.
The VPU clock needs a specific clock parenting defined in DT to
achieve the frequency used by the vendor.

> 
>> +		.flags = CLK_SET_RATE_NO_REPARENT,
>> +	},
>> +};
>> +
>> +static struct clk_regmap axg_vpu_0_div = {
>> +	.data = &(struct clk_regmap_div_data){
>> +		.offset = HHI_VPU_CLK_CNTL,
>> +		.shift = 0,
>> +		.width = 7,
>> +	},
>> +	.hw.init = &(struct clk_init_data){
>> +		.name = "vpu_0_div",
>> +		.ops = &clk_regmap_divider_ops,
>> +		.parent_hws = (const struct clk_hw *[]) { &axg_vpu_0_sel.hw },
>> +		.num_parents = 1,
>> +		.flags = CLK_SET_RATE_PARENT,
>> +	},
>> +};
>> +
>> +static struct clk_regmap axg_vpu_0 = {
>> +	.data = &(struct clk_regmap_gate_data){
>> +		.offset = HHI_VPU_CLK_CNTL,
>> +		.bit_idx = 8,
>> +	},
>> +	.hw.init = &(struct clk_init_data) {
>> +		.name = "vpu_0",
>> +		.ops = &clk_regmap_gate_ops,
>> +		.parent_hws = (const struct clk_hw *[]) { &axg_vpu_0_div.hw },
>> +		.num_parents = 1,
>> +		.flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
> 
> Why is UNUSED required ?

It's UNUSED until we have a mechanism to keep a clock enabled until the proper
module is loaded, and it was already discussed for GXBB & G12A.

> 
>> +	},
>> +};
>> +
>> +static struct clk_regmap axg_vpu_1_sel = {
>> +	.data = &(struct clk_regmap_mux_data){
>> +		.offset = HHI_VPU_CLK_CNTL,
>> +		.mask = 0x3,
>> +		.shift = 25,
>> +	},
>> +	.hw.init = &(struct clk_init_data){
>> +		.name = "vpu_1_sel",
>> +		.ops = &clk_regmap_mux_ops,
>> +		/*
>> +		 * bits 25:26 selects from 4 possible parents:
>> +		 * fclk_div4, fclk_div3, fclk_div5, fclk_div7,
>> +		 */
>> +		.parent_hws = axg_vpu_parent_hws,
>> +		.num_parents = ARRAY_SIZE(axg_vpu_parent_hws),
>> +		.flags = CLK_SET_RATE_NO_REPARENT,
>> +	},
>> +};
>> +
>> +static struct clk_regmap axg_vpu_1_div = {
>> +	.data = &(struct clk_regmap_div_data){
>> +		.offset = HHI_VPU_CLK_CNTL,
>> +		.shift = 16,
>> +		.width = 7,
>> +	},
>> +	.hw.init = &(struct clk_init_data){
>> +		.name = "vpu_1_div",
>> +		.ops = &clk_regmap_divider_ops,
>> +		.parent_hws = (const struct clk_hw *[]) { &axg_vpu_1_sel.hw },
>> +		.num_parents = 1,
>> +		.flags = CLK_SET_RATE_PARENT,
>> +	},
>> +};
>> +
>> +static struct clk_regmap axg_vpu_1 = {
>> +	.data = &(struct clk_regmap_gate_data){
>> +		.offset = HHI_VPU_CLK_CNTL,
>> +		.bit_idx = 24,
>> +	},
>> +	.hw.init = &(struct clk_init_data) {
>> +		.name = "vpu_1",
>> +		.ops = &clk_regmap_gate_ops,
>> +		.parent_hws = (const struct clk_hw *[]) { &axg_vpu_1_div.hw },
>> +		.num_parents = 1,
>> +		.flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
>> +	},
>> +};
>> +
>> +static struct clk_regmap axg_vpu = {
>> +	.data = &(struct clk_regmap_mux_data){
>> +		.offset = HHI_VPU_CLK_CNTL,
>> +		.mask = 1,
>> +		.shift = 31,
>> +	},
>> +	.hw.init = &(struct clk_init_data){
>> +		.name = "vpu",
>> +		.ops = &clk_regmap_mux_ops,
>> +		/*
>> +		 * bit 31 selects from 2 possible parents:
>> +		 * vpu_0 or vpu_1
>> +		 */
>> +		.parent_hws = (const struct clk_hw *[]) {
>> +			&axg_vpu_0.hw,
>> +			&axg_vpu_1.hw
>> +		},
>> +		.num_parents = 2,
>> +		.flags = CLK_SET_RATE_NO_REPARENT,
>> +	},
>> +};
>> +
>> +/* VAPB Clock */
>> +
>> +static const struct clk_hw *axg_vapb_parent_hws[] = {
>> +	&axg_fclk_div4.hw,
>> +	&axg_fclk_div3.hw,
>> +	&axg_fclk_div5.hw,
>> +	&axg_fclk_div7.hw,
>> +};
> 
> This is the same as the vpu table. Could they share a single table ?

Yes, will do

> 
>> +
>> +static struct clk_regmap axg_vapb_0_sel = {
>> +	.data = &(struct clk_regmap_mux_data){
>> +		.offset = HHI_VAPBCLK_CNTL,
>> +		.mask = 0x3,
>> +		.shift = 9,
>> +	},
>> +	.hw.init = &(struct clk_init_data){
>> +		.name = "vapb_0_sel",
>> +		.ops = &clk_regmap_mux_ops,
>> +		/*
>> +		 * bits 9:10 selects from 4 possible parents:
>> +		 * fclk_div4, fclk_div3, fclk_div5, fclk_div7,
>> +		 */
>> +		.parent_hws = axg_vapb_parent_hws,
>> +		.num_parents = ARRAY_SIZE(axg_vapb_parent_hws),
>> +		.flags = CLK_SET_RATE_NO_REPARENT,
>> +	},
>> +};
>> +
>> +static struct clk_regmap axg_vapb_0_div = {
>> +	.data = &(struct clk_regmap_div_data){
>> +		.offset = HHI_VAPBCLK_CNTL,
>> +		.shift = 0,
>> +		.width = 7,
>> +	},
>> +	.hw.init = &(struct clk_init_data){
>> +		.name = "vapb_0_div",
>> +		.ops = &clk_regmap_divider_ops,
>> +		.parent_hws = (const struct clk_hw *[]) {
>> +			&axg_vapb_0_sel.hw
>> +		},
>> +		.num_parents = 1,
>> +		.flags = CLK_SET_RATE_PARENT,
>> +	},
>> +};
>> +
>> +static struct clk_regmap axg_vapb_0 = {
>> +	.data = &(struct clk_regmap_gate_data){
>> +		.offset = HHI_VAPBCLK_CNTL,
>> +		.bit_idx = 8,
>> +	},
>> +	.hw.init = &(struct clk_init_data) {
>> +		.name = "vapb_0",
>> +		.ops = &clk_regmap_gate_ops,
>> +		.parent_hws = (const struct clk_hw *[]) {
>> +			&axg_vapb_0_div.hw
>> +		},
>> +		.num_parents = 1,
>> +		.flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
>> +	},
>> +};
>> +
>> +static struct clk_regmap axg_vapb_1_sel = {
>> +	.data = &(struct clk_regmap_mux_data){
>> +		.offset = HHI_VAPBCLK_CNTL,
>> +		.mask = 0x3,
>> +		.shift = 25,
>> +	},
>> +	.hw.init = &(struct clk_init_data){
>> +		.name = "vapb_1_sel",
>> +		.ops = &clk_regmap_mux_ops,
>> +		/*
>> +		 * bits 25:26 selects from 4 possible parents:
>> +		 * fclk_div4, fclk_div3, fclk_div5, fclk_div7,
>> +		 */
>> +		.parent_hws = axg_vapb_parent_hws,
>> +		.num_parents = ARRAY_SIZE(axg_vapb_parent_hws),
>> +		.flags = CLK_SET_RATE_NO_REPARENT,
>> +	},
>> +};
>> +
>> +static struct clk_regmap axg_vapb_1_div = {
>> +	.data = &(struct clk_regmap_div_data){
>> +		.offset = HHI_VAPBCLK_CNTL,
>> +		.shift = 16,
>> +		.width = 7,
>> +	},
>> +	.hw.init = &(struct clk_init_data){
>> +		.name = "vapb_1_div",
>> +		.ops = &clk_regmap_divider_ops,
>> +		.parent_hws = (const struct clk_hw *[]) {
>> +			&axg_vapb_1_sel.hw
>> +		},
>> +		.num_parents = 1,
>> +		.flags = CLK_SET_RATE_PARENT,
>> +	},
>> +};
>> +
>> +static struct clk_regmap axg_vapb_1 = {
>> +	.data = &(struct clk_regmap_gate_data){
>> +		.offset = HHI_VAPBCLK_CNTL,
>> +		.bit_idx = 24,
>> +	},
>> +	.hw.init = &(struct clk_init_data) {
>> +		.name = "vapb_1",
>> +		.ops = &clk_regmap_gate_ops,
>> +		.parent_hws = (const struct clk_hw *[]) {
>> +			&axg_vapb_1_div.hw
>> +		},
>> +		.num_parents = 1,
>> +		.flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
>> +	},
>> +};
>> +
>> +static struct clk_regmap axg_vapb_sel = {
>> +	.data = &(struct clk_regmap_mux_data){
>> +		.offset = HHI_VAPBCLK_CNTL,
>> +		.mask = 1,
>> +		.shift = 31,
>> +	},
>> +	.hw.init = &(struct clk_init_data){
>> +		.name = "vapb_sel",
>> +		.ops = &clk_regmap_mux_ops,
>> +		/*
>> +		 * bit 31 selects from 2 possible parents:
>> +		 * vapb_0 or vapb_1
>> +		 */
>> +		.parent_hws = (const struct clk_hw *[]) {
>> +			&axg_vapb_0.hw,
>> +			&axg_vapb_1.hw
>> +		},
>> +		.num_parents = 2,
>> +		.flags = CLK_SET_RATE_NO_REPARENT,
>> +	},
>> +};
>> +
>> +static struct clk_regmap axg_vapb = {
>> +	.data = &(struct clk_regmap_gate_data){
>> +		.offset = HHI_VAPBCLK_CNTL,
>> +		.bit_idx = 30,
>> +	},
>> +	.hw.init = &(struct clk_init_data) {
>> +		.name = "vapb",
>> +		.ops = &clk_regmap_gate_ops,
>> +		.parent_hws = (const struct clk_hw *[]) { &axg_vapb_sel.hw },
>> +		.num_parents = 1,
>> +		.flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
>> +	},
>> +};
>> +
>> +/* Video Clocks */
>> +
>> +static const struct clk_hw *axg_vclk_parent_hws[] = {
>> +	&axg_gp0_pll.hw,
>> +	&axg_fclk_div4.hw,
>> +	&axg_fclk_div3.hw,
>> +	&axg_fclk_div5.hw,
>> +	&axg_fclk_div2.hw,
>> +	&axg_fclk_div7.hw,
>> +	&axg_mpll1.hw,
>> +};
>> +
>> +static struct clk_regmap axg_vclk_sel = {
>> +	.data = &(struct clk_regmap_mux_data){
>> +		.offset = HHI_VID_CLK_CNTL,
>> +		.mask = 0x7,
>> +		.shift = 16,
>> +	},
>> +	.hw.init = &(struct clk_init_data){
>> +		.name = "vclk_sel",
>> +		.ops = &clk_regmap_mux_ops,
>> +		.parent_hws = axg_vclk_parent_hws,
>> +		.num_parents = ARRAY_SIZE(axg_vclk_parent_hws),
>> +		.flags = CLK_SET_RATE_NO_REPARENT | CLK_GET_RATE_NOCACHE,
>> +	},
> 
> Why is NOCACHE ? Is there something poking behind CCF back ? if yes, why
> is this required ?

I'm surprised you ask this since the situation hasn't changed since I pushed the
video clock for GXBB, then G12A.

The switch to CCF for the VPU is still planned, but until now I was unable to allocate enough
time for this huge rework.

Since I'm the single DRM driver contributor and lacking any other reviewers, I must deal
with new features & bugfixing before moving to CCF.

The clock situation is far from perfect, and I'd also like it to be solved at some point.

I'll add the same explanation I gave for GXBB in https://lkml.kernel.org/r/1541516257-16157-5-git-send-email-narmstrong@baylibre.com

> 
>> +};
>> +
>> +static struct clk_regmap axg_vclk2_sel = {
>> +	.data = &(struct clk_regmap_mux_data){
>> +		.offset = HHI_VIID_CLK_CNTL,
>> +		.mask = 0x7,
>> +		.shift = 16,
>> +	},
>> +	.hw.init = &(struct clk_init_data){
>> +		.name = "vclk2_sel",
>> +		.ops = &clk_regmap_mux_ops,
>> +		.parent_hws = axg_vclk_parent_hws,
>> +		.num_parents = ARRAY_SIZE(axg_vclk_parent_hws),
>> +		.flags = CLK_SET_RATE_NO_REPARENT | CLK_GET_RATE_NOCACHE,
>> +	},
>> +};
>> +
>> +static struct clk_regmap axg_vclk_input = {
>> +	.data = &(struct clk_regmap_gate_data){
>> +		.offset = HHI_VID_CLK_DIV,
>> +		.bit_idx = 16,
>> +	},
>> +	.hw.init = &(struct clk_init_data) {
>> +		.name = "vclk_input",
>> +		.ops = &clk_regmap_gate_ops,
>> +		.parent_hws = (const struct clk_hw *[]) { &axg_vclk_sel.hw },
>> +		.num_parents = 1,
>> +		.flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
>> +	},
>> +};
>> +
>> +static struct clk_regmap axg_vclk2_input = {
>> +	.data = &(struct clk_regmap_gate_data){
>> +		.offset = HHI_VIID_CLK_DIV,
>> +		.bit_idx = 16,
>> +	},
>> +	.hw.init = &(struct clk_init_data) {
>> +		.name = "vclk2_input",
>> +		.ops = &clk_regmap_gate_ops,
>> +		.parent_hws = (const struct clk_hw *[]) { &axg_vclk2_sel.hw },
>> +		.num_parents = 1,
>> +		.flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
>> +	},
>> +};
>> +
>> +static struct clk_regmap axg_vclk_div = {
>> +	.data = &(struct clk_regmap_div_data){
>> +		.offset = HHI_VID_CLK_DIV,
>> +		.shift = 0,
>> +		.width = 8,
>> +	},
>> +	.hw.init = &(struct clk_init_data){
>> +		.name = "vclk_div",
>> +		.ops = &clk_regmap_divider_ops,
>> +		.parent_hws = (const struct clk_hw *[]) {
>> +			&axg_vclk_input.hw
>> +		},
>> +		.num_parents = 1,
>> +		.flags = CLK_GET_RATE_NOCACHE,
>> +	},
>> +};
>> +
>> +static struct clk_regmap axg_vclk2_div = {
>> +	.data = &(struct clk_regmap_div_data){
>> +		.offset = HHI_VIID_CLK_DIV,
>> +		.shift = 0,
>> +		.width = 8,
>> +	},
>> +	.hw.init = &(struct clk_init_data){
>> +		.name = "vclk2_div",
>> +		.ops = &clk_regmap_divider_ops,
>> +		.parent_hws = (const struct clk_hw *[]) {
>> +			&axg_vclk2_input.hw
>> +		},
>> +		.num_parents = 1,
>> +		.flags = CLK_GET_RATE_NOCACHE,
>> +	},
>> +};
>> +
>> +static struct clk_regmap axg_vclk = {
>> +	.data = &(struct clk_regmap_gate_data){
>> +		.offset = HHI_VID_CLK_CNTL,
>> +		.bit_idx = 19,
>> +	},
>> +	.hw.init = &(struct clk_init_data) {
>> +		.name = "vclk",
>> +		.ops = &clk_regmap_gate_ops,
>> +		.parent_hws = (const struct clk_hw *[]) { &axg_vclk_div.hw },
>> +		.num_parents = 1,
>> +		.flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
>> +	},
>> +};
>> +
>> +static struct clk_regmap axg_vclk2 = {
>> +	.data = &(struct clk_regmap_gate_data){
>> +		.offset = HHI_VIID_CLK_CNTL,
>> +		.bit_idx = 19,
>> +	},
>> +	.hw.init = &(struct clk_init_data) {
>> +		.name = "vclk2",
>> +		.ops = &clk_regmap_gate_ops,
>> +		.parent_hws = (const struct clk_hw *[]) { &axg_vclk2_div.hw },
>> +		.num_parents = 1,
>> +		.flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
>> +	},
>> +};
>> +
>> +static struct clk_regmap axg_vclk_div1 = {
>> +	.data = &(struct clk_regmap_gate_data){
>> +		.offset = HHI_VID_CLK_CNTL,
>> +		.bit_idx = 0,
>> +	},
>> +	.hw.init = &(struct clk_init_data) {
>> +		.name = "vclk_div1",
>> +		.ops = &clk_regmap_gate_ops,
>> +		.parent_hws = (const struct clk_hw *[]) { &axg_vclk.hw },
>> +		.num_parents = 1,
>> +		.flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
>> +	},
>> +};
>> +
>> +static struct clk_regmap axg_vclk_div2_en = {
>> +	.data = &(struct clk_regmap_gate_data){
>> +		.offset = HHI_VID_CLK_CNTL,
>> +		.bit_idx = 1,
>> +	},
>> +	.hw.init = &(struct clk_init_data) {
>> +		.name = "vclk_div2_en",
>> +		.ops = &clk_regmap_gate_ops,
>> +		.parent_hws = (const struct clk_hw *[]) { &axg_vclk.hw },
>> +		.num_parents = 1,
>> +		.flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
>> +	},
>> +};
>> +
>> +static struct clk_regmap axg_vclk_div4_en = {
>> +	.data = &(struct clk_regmap_gate_data){
>> +		.offset = HHI_VID_CLK_CNTL,
>> +		.bit_idx = 2,
>> +	},
>> +	.hw.init = &(struct clk_init_data) {
>> +		.name = "vclk_div4_en",
>> +		.ops = &clk_regmap_gate_ops,
>> +		.parent_hws = (const struct clk_hw *[]) { &axg_vclk.hw },
>> +		.num_parents = 1,
>> +		.flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
>> +	},
>> +};
>> +
>> +static struct clk_regmap axg_vclk_div6_en = {
>> +	.data = &(struct clk_regmap_gate_data){
>> +		.offset = HHI_VID_CLK_CNTL,
>> +		.bit_idx = 3,
>> +	},
>> +	.hw.init = &(struct clk_init_data) {
>> +		.name = "vclk_div6_en",
>> +		.ops = &clk_regmap_gate_ops,
>> +		.parent_hws = (const struct clk_hw *[]) { &axg_vclk.hw },
>> +		.num_parents = 1,
>> +		.flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
>> +	},
>> +};
>> +
>> +static struct clk_regmap axg_vclk_div12_en = {
>> +	.data = &(struct clk_regmap_gate_data){
>> +		.offset = HHI_VID_CLK_CNTL,
>> +		.bit_idx = 4,
>> +	},
>> +	.hw.init = &(struct clk_init_data) {
>> +		.name = "vclk_div12_en",
>> +		.ops = &clk_regmap_gate_ops,
>> +		.parent_hws = (const struct clk_hw *[]) { &axg_vclk.hw },
>> +		.num_parents = 1,
>> +		.flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
>> +	},
>> +};
>> +
>> +static struct clk_regmap axg_vclk2_div1 = {
>> +	.data = &(struct clk_regmap_gate_data){
>> +		.offset = HHI_VIID_CLK_CNTL,
>> +		.bit_idx = 0,
>> +	},
>> +	.hw.init = &(struct clk_init_data) {
>> +		.name = "vclk2_div1",
>> +		.ops = &clk_regmap_gate_ops,
>> +		.parent_hws = (const struct clk_hw *[]) { &axg_vclk2.hw },
>> +		.num_parents = 1,
>> +		.flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
>> +	},
>> +};
>> +
>> +static struct clk_regmap axg_vclk2_div2_en = {
>> +	.data = &(struct clk_regmap_gate_data){
>> +		.offset = HHI_VIID_CLK_CNTL,
>> +		.bit_idx = 1,
>> +	},
>> +	.hw.init = &(struct clk_init_data) {
>> +		.name = "vclk2_div2_en",
>> +		.ops = &clk_regmap_gate_ops,
>> +		.parent_hws = (const struct clk_hw *[]) { &axg_vclk2.hw },
>> +		.num_parents = 1,
>> +		.flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
>> +	},
>> +};
>> +
>> +static struct clk_regmap axg_vclk2_div4_en = {
>> +	.data = &(struct clk_regmap_gate_data){
>> +		.offset = HHI_VIID_CLK_CNTL,
>> +		.bit_idx = 2,
>> +	},
>> +	.hw.init = &(struct clk_init_data) {
>> +		.name = "vclk2_div4_en",
>> +		.ops = &clk_regmap_gate_ops,
>> +		.parent_hws = (const struct clk_hw *[]) { &axg_vclk2.hw },
>> +		.num_parents = 1,
>> +		.flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
>> +	},
>> +};
>> +
>> +static struct clk_regmap axg_vclk2_div6_en = {
>> +	.data = &(struct clk_regmap_gate_data){
>> +		.offset = HHI_VIID_CLK_CNTL,
>> +		.bit_idx = 3,
>> +	},
>> +	.hw.init = &(struct clk_init_data) {
>> +		.name = "vclk2_div6_en",
>> +		.ops = &clk_regmap_gate_ops,
>> +		.parent_hws = (const struct clk_hw *[]) { &axg_vclk2.hw },
>> +		.num_parents = 1,
>> +		.flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
>> +	},
>> +};
>> +
>> +static struct clk_regmap axg_vclk2_div12_en = {
>> +	.data = &(struct clk_regmap_gate_data){
>> +		.offset = HHI_VIID_CLK_CNTL,
>> +		.bit_idx = 4,
>> +	},
>> +	.hw.init = &(struct clk_init_data) {
>> +		.name = "vclk2_div12_en",
>> +		.ops = &clk_regmap_gate_ops,
>> +		.parent_hws = (const struct clk_hw *[]) { &axg_vclk2.hw },
>> +		.num_parents = 1,
>> +		.flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
>> +	},
>> +};
>> +
>> +static struct clk_fixed_factor axg_vclk_div2 = {
>> +	.mult = 1,
>> +	.div = 2,
>> +	.hw.init = &(struct clk_init_data){
>> +		.name = "vclk_div2",
>> +		.ops = &clk_fixed_factor_ops,
>> +		.parent_hws = (const struct clk_hw *[]) {
>> +			&axg_vclk_div2_en.hw
>> +		},
>> +		.num_parents = 1,
>> +	},
>> +};
>> +
>> +static struct clk_fixed_factor axg_vclk_div4 = {
>> +	.mult = 1,
>> +	.div = 4,
>> +	.hw.init = &(struct clk_init_data){
>> +		.name = "vclk_div4",
>> +		.ops = &clk_fixed_factor_ops,
>> +		.parent_hws = (const struct clk_hw *[]) {
>> +			&axg_vclk_div4_en.hw
>> +		},
>> +		.num_parents = 1,
>> +	},
>> +};
>> +
>> +static struct clk_fixed_factor axg_vclk_div6 = {
>> +	.mult = 1,
>> +	.div = 6,
>> +	.hw.init = &(struct clk_init_data){
>> +		.name = "vclk_div6",
>> +		.ops = &clk_fixed_factor_ops,
>> +		.parent_hws = (const struct clk_hw *[]) {
>> +			&axg_vclk_div6_en.hw
>> +		},
>> +		.num_parents = 1,
>> +	},
>> +};
>> +
>> +static struct clk_fixed_factor axg_vclk_div12 = {
>> +	.mult = 1,
>> +	.div = 12,
>> +	.hw.init = &(struct clk_init_data){
>> +		.name = "vclk_div12",
>> +		.ops = &clk_fixed_factor_ops,
>> +		.parent_hws = (const struct clk_hw *[]) {
>> +			&axg_vclk_div12_en.hw
>> +		},
>> +		.num_parents = 1,
>> +	},
>> +};
>> +
>> +static struct clk_fixed_factor axg_vclk2_div2 = {
>> +	.mult = 1,
>> +	.div = 2,
>> +	.hw.init = &(struct clk_init_data){
>> +		.name = "vclk2_div2",
>> +		.ops = &clk_fixed_factor_ops,
>> +		.parent_hws = (const struct clk_hw *[]) {
>> +			&axg_vclk2_div2_en.hw
>> +		},
>> +		.num_parents = 1,
>> +	},
>> +};
>> +
>> +static struct clk_fixed_factor axg_vclk2_div4 = {
>> +	.mult = 1,
>> +	.div = 4,
>> +	.hw.init = &(struct clk_init_data){
>> +		.name = "vclk2_div4",
>> +		.ops = &clk_fixed_factor_ops,
>> +		.parent_hws = (const struct clk_hw *[]) {
>> +			&axg_vclk2_div4_en.hw
>> +		},
>> +		.num_parents = 1,
>> +	},
>> +};
>> +
>> +static struct clk_fixed_factor axg_vclk2_div6 = {
>> +	.mult = 1,
>> +	.div = 6,
>> +	.hw.init = &(struct clk_init_data){
>> +		.name = "vclk2_div6",
>> +		.ops = &clk_fixed_factor_ops,
>> +		.parent_hws = (const struct clk_hw *[]) {
>> +			&axg_vclk2_div6_en.hw
>> +		},
>> +		.num_parents = 1,
>> +	},
>> +};
>> +
>> +static struct clk_fixed_factor axg_vclk2_div12 = {
>> +	.mult = 1,
>> +	.div = 12,
>> +	.hw.init = &(struct clk_init_data){
>> +		.name = "vclk2_div12",
>> +		.ops = &clk_fixed_factor_ops,
>> +		.parent_hws = (const struct clk_hw *[]) {
>> +			&axg_vclk2_div12_en.hw
>> +		},
>> +		.num_parents = 1,
>> +	},
>> +};
>> +
>> +static u32 mux_table_cts_sel[] = { 0, 1, 2, 3, 4, 8, 9, 10, 11, 12 };
>> +static const struct clk_hw *axg_cts_parent_hws[] = {
>> +	&axg_vclk_div1.hw,
>> +	&axg_vclk_div2.hw,
>> +	&axg_vclk_div4.hw,
>> +	&axg_vclk_div6.hw,
>> +	&axg_vclk_div12.hw,
>> +	&axg_vclk2_div1.hw,
>> +	&axg_vclk2_div2.hw,
>> +	&axg_vclk2_div4.hw,
>> +	&axg_vclk2_div6.hw,
>> +	&axg_vclk2_div12.hw,
>> +};
>> +
>> +static struct clk_regmap axg_cts_encl_sel = {
>> +	.data = &(struct clk_regmap_mux_data){
>> +		.offset = HHI_VIID_CLK_DIV,
>> +		.mask = 0xf,
>> +		.shift = 12,
>> +		.table = mux_table_cts_sel,
>> +	},
>> +	.hw.init = &(struct clk_init_data){
>> +		.name = "cts_encl_sel",
>> +		.ops = &clk_regmap_mux_ops,
>> +		.parent_hws = axg_cts_parent_hws,
>> +		.num_parents = ARRAY_SIZE(axg_cts_parent_hws),
>> +		.flags = CLK_SET_RATE_NO_REPARENT | CLK_GET_RATE_NOCACHE,
>> +	},
>> +};
>> +
>> +static struct clk_regmap axg_cts_encl = {
>> +	.data = &(struct clk_regmap_gate_data){
>> +		.offset = HHI_VID_CLK_CNTL2,
>> +		.bit_idx = 3,
>> +	},
>> +	.hw.init = &(struct clk_init_data) {
>> +		.name = "cts_encl",
>> +		.ops = &clk_regmap_gate_ops,
>> +		.parent_hws = (const struct clk_hw *[]) {
>> +			&axg_cts_encl_sel.hw
>> +		},
>> +		.num_parents = 1,
>> +		.flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
>> +	},
>> +};
>> +
>>  static u32 mux_table_gen_clk[]	= { 0, 4, 5, 6, 7, 8,
>>  				    9, 10, 11, 13, 14, };
>>  static const struct clk_parent_data gen_clk_parent_data[] = {
>> @@ -1246,6 +1944,49 @@ static struct clk_hw_onecell_data axg_hw_onecell_data = {
>>  		[CLKID_HIFI_PLL_DCO]		= &axg_hifi_pll_dco.hw,
>>  		[CLKID_PCIE_PLL_DCO]		= &axg_pcie_pll_dco.hw,
>>  		[CLKID_PCIE_PLL_OD]		= &axg_pcie_pll_od.hw,
>> +		[CLKID_VPU_0_DIV]		= &axg_vpu_0_div.hw,
>> +		[CLKID_VPU_0_SEL]		= &axg_vpu_0_sel.hw,
>> +		[CLKID_VPU_0]			= &axg_vpu_0.hw,
>> +		[CLKID_VPU_1_DIV]		= &axg_vpu_1_div.hw,
>> +		[CLKID_VPU_1_SEL]		= &axg_vpu_1_sel.hw,
>> +		[CLKID_VPU_1]			= &axg_vpu_1.hw,
>> +		[CLKID_VPU]			= &axg_vpu.hw,
>> +		[CLKID_VAPB_0_DIV]		= &axg_vapb_0_div.hw,
>> +		[CLKID_VAPB_0_SEL]		= &axg_vapb_0_sel.hw,
>> +		[CLKID_VAPB_0]			= &axg_vapb_0.hw,
>> +		[CLKID_VAPB_1_DIV]		= &axg_vapb_1_div.hw,
>> +		[CLKID_VAPB_1_SEL]		= &axg_vapb_1_sel.hw,
>> +		[CLKID_VAPB_1]			= &axg_vapb_1.hw,
>> +		[CLKID_VAPB_SEL]		= &axg_vapb_sel.hw,
>> +		[CLKID_VAPB]			= &axg_vapb.hw,
>> +		[CLKID_VCLK]			= &axg_vclk.hw,
>> +		[CLKID_VCLK2]			= &axg_vclk2.hw,
>> +		[CLKID_VCLK_SEL]		= &axg_vclk_sel.hw,
>> +		[CLKID_VCLK2_SEL]		= &axg_vclk2_sel.hw,
>> +		[CLKID_VCLK_INPUT]		= &axg_vclk_input.hw,
>> +		[CLKID_VCLK2_INPUT]		= &axg_vclk2_input.hw,
>> +		[CLKID_VCLK_DIV]		= &axg_vclk_div.hw,
>> +		[CLKID_VCLK2_DIV]		= &axg_vclk2_div.hw,
>> +		[CLKID_VCLK_DIV2_EN]		= &axg_vclk_div2_en.hw,
>> +		[CLKID_VCLK_DIV4_EN]		= &axg_vclk_div4_en.hw,
>> +		[CLKID_VCLK_DIV6_EN]		= &axg_vclk_div6_en.hw,
>> +		[CLKID_VCLK_DIV12_EN]		= &axg_vclk_div12_en.hw,
>> +		[CLKID_VCLK2_DIV2_EN]		= &axg_vclk2_div2_en.hw,
>> +		[CLKID_VCLK2_DIV4_EN]		= &axg_vclk2_div4_en.hw,
>> +		[CLKID_VCLK2_DIV6_EN]		= &axg_vclk2_div6_en.hw,
>> +		[CLKID_VCLK2_DIV12_EN]		= &axg_vclk2_div12_en.hw,
>> +		[CLKID_VCLK_DIV1]		= &axg_vclk_div1.hw,
>> +		[CLKID_VCLK_DIV2]		= &axg_vclk_div2.hw,
>> +		[CLKID_VCLK_DIV4]		= &axg_vclk_div4.hw,
>> +		[CLKID_VCLK_DIV6]		= &axg_vclk_div6.hw,
>> +		[CLKID_VCLK_DIV12]		= &axg_vclk_div12.hw,
>> +		[CLKID_VCLK2_DIV1]		= &axg_vclk2_div1.hw,
>> +		[CLKID_VCLK2_DIV2]		= &axg_vclk2_div2.hw,
>> +		[CLKID_VCLK2_DIV4]		= &axg_vclk2_div4.hw,
>> +		[CLKID_VCLK2_DIV6]		= &axg_vclk2_div6.hw,
>> +		[CLKID_VCLK2_DIV12]		= &axg_vclk2_div12.hw,
>> +		[CLKID_CTS_ENCL_SEL]		= &axg_cts_encl_sel.hw,
>> +		[CLKID_CTS_ENCL]		= &axg_cts_encl.hw,
>>  		[NR_CLKS]			= NULL,
>>  	},
>>  	.num = NR_CLKS,
>> @@ -1341,6 +2082,39 @@ static struct clk_regmap *const axg_clk_regmaps[] = {
>>  	&axg_hifi_pll_dco,
>>  	&axg_pcie_pll_dco,
>>  	&axg_pcie_pll_od,
>> +	&axg_vpu_0_div,
>> +	&axg_vpu_0_sel,
>> +	&axg_vpu_0,
>> +	&axg_vpu_1_div,
>> +	&axg_vpu_1_sel,
>> +	&axg_vpu_1,
>> +	&axg_vpu,
>> +	&axg_vapb_0_div,
>> +	&axg_vapb_0_sel,
>> +	&axg_vapb_0,
>> +	&axg_vapb_1_div,
>> +	&axg_vapb_1_sel,
>> +	&axg_vapb_1,
>> +	&axg_vapb_sel,
>> +	&axg_vapb,
>> +	&axg_vclk,
>> +	&axg_vclk2,
>> +	&axg_vclk_sel,
>> +	&axg_vclk2_sel,
>> +	&axg_vclk_input,
>> +	&axg_vclk2_input,
>> +	&axg_vclk_div,
>> +	&axg_vclk2_div,
>> +	&axg_vclk_div2_en,
>> +	&axg_vclk_div4_en,
>> +	&axg_vclk_div6_en,
>> +	&axg_vclk_div12_en,
>> +	&axg_vclk2_div2_en,
>> +	&axg_vclk2_div4_en,
>> +	&axg_vclk2_div6_en,
>> +	&axg_vclk2_div12_en,
>> +	&axg_cts_encl_sel,
>> +	&axg_cts_encl,
>>  };
>>  
>>  static const struct meson_eeclkc_data axg_clkc_data = {
>> diff --git a/drivers/clk/meson/axg.h b/drivers/clk/meson/axg.h
>> index 0431dabac629..a8787b394a47 100644
>> --- a/drivers/clk/meson/axg.h
>> +++ b/drivers/clk/meson/axg.h
>> @@ -139,8 +139,27 @@
>>  #define CLKID_HIFI_PLL_DCO			88
>>  #define CLKID_PCIE_PLL_DCO			89
>>  #define CLKID_PCIE_PLL_OD			90
>> +#define CLKID_VPU_0_DIV				91
>> +#define CLKID_VPU_1_DIV				94
>> +#define CLKID_VAPB_0_DIV			98
>> +#define CLKID_VAPB_1_DIV			101
>> +#define CLKID_VCLK_SEL				108
>> +#define CLKID_VCLK2_SEL				109
>> +#define CLKID_VCLK_INPUT			110
>> +#define CLKID_VCLK2_INPUT			111
>> +#define CLKID_VCLK_DIV				112
>> +#define CLKID_VCLK2_DIV				113
>> +#define CLKID_VCLK_DIV2_EN			114
>> +#define CLKID_VCLK_DIV4_EN			115
>> +#define CLKID_VCLK_DIV6_EN			116
>> +#define CLKID_VCLK_DIV12_EN			117
>> +#define CLKID_VCLK2_DIV2_EN			118
>> +#define CLKID_VCLK2_DIV4_EN			119
>> +#define CLKID_VCLK2_DIV6_EN			120
>> +#define CLKID_VCLK2_DIV12_EN			121
>> +#define CLKID_CTS_ENCL_SEL			132
>>  
>> -#define NR_CLKS					91
>> +#define NR_CLKS					134
>>  
>>  /* include the CLKIDs that have been made part of the DT binding */
>>  #include <dt-bindings/clock/axg-clkc.h>
> 
> Overall, there is quite an heavy use of CLK_IGNORE_USED and
> CLK_GET_RATE_NOCACHE which seems to indicate that something else is
> poking around in the clocks registers
> 
> Details about why it should be done this way, and not through CCF API,
> should be provided.
>
Thanks,
Neil

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH 3/4] clk: meson: axg: add Video Clocks
@ 2020-09-10 11:47       ` Neil Armstrong
  0 siblings, 0 replies; 30+ messages in thread
From: Neil Armstrong @ 2020-09-10 11:47 UTC (permalink / raw)
  To: Jerome Brunet; +Cc: linux-amlogic, linux-clk, linux-arm-kernel, linux-kernel

Hi,

On 10/09/2020 12:13, Jerome Brunet wrote:
> 
> On Mon 07 Sep 2020 at 11:38, Neil Armstrong <narmstrong@baylibre.com> wrote:
> 
>> Add the Video Clocks present on the Amlogic AXg SoCs.
>>
>> The AXG only has a single ENCL CTS clock and even if VCLK exist along VCLK2,
>> only VCLK2 is used since it clocks the MIPI DSI IP directly.
>>
>> Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
>> ---
>>  drivers/clk/meson/axg.c | 774 ++++++++++++++++++++++++++++++++++++++++
>>  drivers/clk/meson/axg.h |  21 +-
>>  2 files changed, 794 insertions(+), 1 deletion(-)
>>
>> diff --git a/drivers/clk/meson/axg.c b/drivers/clk/meson/axg.c
>> index 13fc0006f63d..2550616c14b0 100644
>> --- a/drivers/clk/meson/axg.c
>> +++ b/drivers/clk/meson/axg.c
>> @@ -1026,6 +1026,704 @@ static struct clk_regmap axg_sd_emmc_c_clk0 = {
>>  	},
>>  };
>>  
>> +/* VPU Clock */
>> +
>> +static const struct clk_hw *axg_vpu_parent_hws[] = {
>> +	&axg_fclk_div4.hw,
>> +	&axg_fclk_div3.hw,
>> +	&axg_fclk_div5.hw,
>> +	&axg_fclk_div7.hw,
>> +};
>> +
>> +static struct clk_regmap axg_vpu_0_sel = {
>> +	.data = &(struct clk_regmap_mux_data){
>> +		.offset = HHI_VPU_CLK_CNTL,
>> +		.mask = 0x3,
>> +		.shift = 9,
>> +	},
>> +	.hw.init = &(struct clk_init_data){
>> +		.name = "vpu_0_sel",
>> +		.ops = &clk_regmap_mux_ops,
>> +		/*
>> +		 * bits 9:10 selects from 4 possible parents:
>> +		 * fclk_div4, fclk_div3, fclk_div5, fclk_div7,
>> +		 */
> 
> These comments (and the same bellow) are not very useful

Ok, these are copy/paste from gxbb.c and g12a.c, I wonder why these are now useless.

> 
>> +		.parent_hws = axg_vpu_parent_hws,
>> +		.num_parents = ARRAY_SIZE(axg_vpu_parent_hws),
> 
> Could you add a comment here explaining why parenting needs to be
> manually controlled ?

Ditto, this was already explained for GXBB & G12A.
The VPU clock needs a specific clock parenting defined in DT to
achieve the frequency used by the vendor.

> 
>> +		.flags = CLK_SET_RATE_NO_REPARENT,
>> +	},
>> +};
>> +
>> +static struct clk_regmap axg_vpu_0_div = {
>> +	.data = &(struct clk_regmap_div_data){
>> +		.offset = HHI_VPU_CLK_CNTL,
>> +		.shift = 0,
>> +		.width = 7,
>> +	},
>> +	.hw.init = &(struct clk_init_data){
>> +		.name = "vpu_0_div",
>> +		.ops = &clk_regmap_divider_ops,
>> +		.parent_hws = (const struct clk_hw *[]) { &axg_vpu_0_sel.hw },
>> +		.num_parents = 1,
>> +		.flags = CLK_SET_RATE_PARENT,
>> +	},
>> +};
>> +
>> +static struct clk_regmap axg_vpu_0 = {
>> +	.data = &(struct clk_regmap_gate_data){
>> +		.offset = HHI_VPU_CLK_CNTL,
>> +		.bit_idx = 8,
>> +	},
>> +	.hw.init = &(struct clk_init_data) {
>> +		.name = "vpu_0",
>> +		.ops = &clk_regmap_gate_ops,
>> +		.parent_hws = (const struct clk_hw *[]) { &axg_vpu_0_div.hw },
>> +		.num_parents = 1,
>> +		.flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
> 
> Why is UNUSED required ?

It's UNUSED until we have a mechanism to keep a clock enabled until the proper
module is loaded, and it was already discussed for GXBB & G12A.

> 
>> +	},
>> +};
>> +
>> +static struct clk_regmap axg_vpu_1_sel = {
>> +	.data = &(struct clk_regmap_mux_data){
>> +		.offset = HHI_VPU_CLK_CNTL,
>> +		.mask = 0x3,
>> +		.shift = 25,
>> +	},
>> +	.hw.init = &(struct clk_init_data){
>> +		.name = "vpu_1_sel",
>> +		.ops = &clk_regmap_mux_ops,
>> +		/*
>> +		 * bits 25:26 selects from 4 possible parents:
>> +		 * fclk_div4, fclk_div3, fclk_div5, fclk_div7,
>> +		 */
>> +		.parent_hws = axg_vpu_parent_hws,
>> +		.num_parents = ARRAY_SIZE(axg_vpu_parent_hws),
>> +		.flags = CLK_SET_RATE_NO_REPARENT,
>> +	},
>> +};
>> +
>> +static struct clk_regmap axg_vpu_1_div = {
>> +	.data = &(struct clk_regmap_div_data){
>> +		.offset = HHI_VPU_CLK_CNTL,
>> +		.shift = 16,
>> +		.width = 7,
>> +	},
>> +	.hw.init = &(struct clk_init_data){
>> +		.name = "vpu_1_div",
>> +		.ops = &clk_regmap_divider_ops,
>> +		.parent_hws = (const struct clk_hw *[]) { &axg_vpu_1_sel.hw },
>> +		.num_parents = 1,
>> +		.flags = CLK_SET_RATE_PARENT,
>> +	},
>> +};
>> +
>> +static struct clk_regmap axg_vpu_1 = {
>> +	.data = &(struct clk_regmap_gate_data){
>> +		.offset = HHI_VPU_CLK_CNTL,
>> +		.bit_idx = 24,
>> +	},
>> +	.hw.init = &(struct clk_init_data) {
>> +		.name = "vpu_1",
>> +		.ops = &clk_regmap_gate_ops,
>> +		.parent_hws = (const struct clk_hw *[]) { &axg_vpu_1_div.hw },
>> +		.num_parents = 1,
>> +		.flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
>> +	},
>> +};
>> +
>> +static struct clk_regmap axg_vpu = {
>> +	.data = &(struct clk_regmap_mux_data){
>> +		.offset = HHI_VPU_CLK_CNTL,
>> +		.mask = 1,
>> +		.shift = 31,
>> +	},
>> +	.hw.init = &(struct clk_init_data){
>> +		.name = "vpu",
>> +		.ops = &clk_regmap_mux_ops,
>> +		/*
>> +		 * bit 31 selects from 2 possible parents:
>> +		 * vpu_0 or vpu_1
>> +		 */
>> +		.parent_hws = (const struct clk_hw *[]) {
>> +			&axg_vpu_0.hw,
>> +			&axg_vpu_1.hw
>> +		},
>> +		.num_parents = 2,
>> +		.flags = CLK_SET_RATE_NO_REPARENT,
>> +	},
>> +};
>> +
>> +/* VAPB Clock */
>> +
>> +static const struct clk_hw *axg_vapb_parent_hws[] = {
>> +	&axg_fclk_div4.hw,
>> +	&axg_fclk_div3.hw,
>> +	&axg_fclk_div5.hw,
>> +	&axg_fclk_div7.hw,
>> +};
> 
> This is the same as the vpu table. Could they share a single table ?

Yes, will do

> 
>> +
>> +static struct clk_regmap axg_vapb_0_sel = {
>> +	.data = &(struct clk_regmap_mux_data){
>> +		.offset = HHI_VAPBCLK_CNTL,
>> +		.mask = 0x3,
>> +		.shift = 9,
>> +	},
>> +	.hw.init = &(struct clk_init_data){
>> +		.name = "vapb_0_sel",
>> +		.ops = &clk_regmap_mux_ops,
>> +		/*
>> +		 * bits 9:10 selects from 4 possible parents:
>> +		 * fclk_div4, fclk_div3, fclk_div5, fclk_div7,
>> +		 */
>> +		.parent_hws = axg_vapb_parent_hws,
>> +		.num_parents = ARRAY_SIZE(axg_vapb_parent_hws),
>> +		.flags = CLK_SET_RATE_NO_REPARENT,
>> +	},
>> +};
>> +
>> +static struct clk_regmap axg_vapb_0_div = {
>> +	.data = &(struct clk_regmap_div_data){
>> +		.offset = HHI_VAPBCLK_CNTL,
>> +		.shift = 0,
>> +		.width = 7,
>> +	},
>> +	.hw.init = &(struct clk_init_data){
>> +		.name = "vapb_0_div",
>> +		.ops = &clk_regmap_divider_ops,
>> +		.parent_hws = (const struct clk_hw *[]) {
>> +			&axg_vapb_0_sel.hw
>> +		},
>> +		.num_parents = 1,
>> +		.flags = CLK_SET_RATE_PARENT,
>> +	},
>> +};
>> +
>> +static struct clk_regmap axg_vapb_0 = {
>> +	.data = &(struct clk_regmap_gate_data){
>> +		.offset = HHI_VAPBCLK_CNTL,
>> +		.bit_idx = 8,
>> +	},
>> +	.hw.init = &(struct clk_init_data) {
>> +		.name = "vapb_0",
>> +		.ops = &clk_regmap_gate_ops,
>> +		.parent_hws = (const struct clk_hw *[]) {
>> +			&axg_vapb_0_div.hw
>> +		},
>> +		.num_parents = 1,
>> +		.flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
>> +	},
>> +};
>> +
>> +static struct clk_regmap axg_vapb_1_sel = {
>> +	.data = &(struct clk_regmap_mux_data){
>> +		.offset = HHI_VAPBCLK_CNTL,
>> +		.mask = 0x3,
>> +		.shift = 25,
>> +	},
>> +	.hw.init = &(struct clk_init_data){
>> +		.name = "vapb_1_sel",
>> +		.ops = &clk_regmap_mux_ops,
>> +		/*
>> +		 * bits 25:26 selects from 4 possible parents:
>> +		 * fclk_div4, fclk_div3, fclk_div5, fclk_div7,
>> +		 */
>> +		.parent_hws = axg_vapb_parent_hws,
>> +		.num_parents = ARRAY_SIZE(axg_vapb_parent_hws),
>> +		.flags = CLK_SET_RATE_NO_REPARENT,
>> +	},
>> +};
>> +
>> +static struct clk_regmap axg_vapb_1_div = {
>> +	.data = &(struct clk_regmap_div_data){
>> +		.offset = HHI_VAPBCLK_CNTL,
>> +		.shift = 16,
>> +		.width = 7,
>> +	},
>> +	.hw.init = &(struct clk_init_data){
>> +		.name = "vapb_1_div",
>> +		.ops = &clk_regmap_divider_ops,
>> +		.parent_hws = (const struct clk_hw *[]) {
>> +			&axg_vapb_1_sel.hw
>> +		},
>> +		.num_parents = 1,
>> +		.flags = CLK_SET_RATE_PARENT,
>> +	},
>> +};
>> +
>> +static struct clk_regmap axg_vapb_1 = {
>> +	.data = &(struct clk_regmap_gate_data){
>> +		.offset = HHI_VAPBCLK_CNTL,
>> +		.bit_idx = 24,
>> +	},
>> +	.hw.init = &(struct clk_init_data) {
>> +		.name = "vapb_1",
>> +		.ops = &clk_regmap_gate_ops,
>> +		.parent_hws = (const struct clk_hw *[]) {
>> +			&axg_vapb_1_div.hw
>> +		},
>> +		.num_parents = 1,
>> +		.flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
>> +	},
>> +};
>> +
>> +static struct clk_regmap axg_vapb_sel = {
>> +	.data = &(struct clk_regmap_mux_data){
>> +		.offset = HHI_VAPBCLK_CNTL,
>> +		.mask = 1,
>> +		.shift = 31,
>> +	},
>> +	.hw.init = &(struct clk_init_data){
>> +		.name = "vapb_sel",
>> +		.ops = &clk_regmap_mux_ops,
>> +		/*
>> +		 * bit 31 selects from 2 possible parents:
>> +		 * vapb_0 or vapb_1
>> +		 */
>> +		.parent_hws = (const struct clk_hw *[]) {
>> +			&axg_vapb_0.hw,
>> +			&axg_vapb_1.hw
>> +		},
>> +		.num_parents = 2,
>> +		.flags = CLK_SET_RATE_NO_REPARENT,
>> +	},
>> +};
>> +
>> +static struct clk_regmap axg_vapb = {
>> +	.data = &(struct clk_regmap_gate_data){
>> +		.offset = HHI_VAPBCLK_CNTL,
>> +		.bit_idx = 30,
>> +	},
>> +	.hw.init = &(struct clk_init_data) {
>> +		.name = "vapb",
>> +		.ops = &clk_regmap_gate_ops,
>> +		.parent_hws = (const struct clk_hw *[]) { &axg_vapb_sel.hw },
>> +		.num_parents = 1,
>> +		.flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
>> +	},
>> +};
>> +
>> +/* Video Clocks */
>> +
>> +static const struct clk_hw *axg_vclk_parent_hws[] = {
>> +	&axg_gp0_pll.hw,
>> +	&axg_fclk_div4.hw,
>> +	&axg_fclk_div3.hw,
>> +	&axg_fclk_div5.hw,
>> +	&axg_fclk_div2.hw,
>> +	&axg_fclk_div7.hw,
>> +	&axg_mpll1.hw,
>> +};
>> +
>> +static struct clk_regmap axg_vclk_sel = {
>> +	.data = &(struct clk_regmap_mux_data){
>> +		.offset = HHI_VID_CLK_CNTL,
>> +		.mask = 0x7,
>> +		.shift = 16,
>> +	},
>> +	.hw.init = &(struct clk_init_data){
>> +		.name = "vclk_sel",
>> +		.ops = &clk_regmap_mux_ops,
>> +		.parent_hws = axg_vclk_parent_hws,
>> +		.num_parents = ARRAY_SIZE(axg_vclk_parent_hws),
>> +		.flags = CLK_SET_RATE_NO_REPARENT | CLK_GET_RATE_NOCACHE,
>> +	},
> 
> Why is NOCACHE ? Is there something poking behind CCF back ? if yes, why
> is this required ?

I'm surprised you ask this since the situation hasn't changed since I pushed the
video clock for GXBB, then G12A.

The switch to CCF for the VPU is still planned, but until now I was unable to allocate enough
time for this huge rework.

Since I'm the single DRM driver contributor and lacking any other reviewers, I must deal
with new features & bugfixing before moving to CCF.

The clock situation is far from perfect, and I'd also like it to be solved at some point.

I'll add the same explanation I gave for GXBB in https://lkml.kernel.org/r/1541516257-16157-5-git-send-email-narmstrong@baylibre.com

> 
>> +};
>> +
>> +static struct clk_regmap axg_vclk2_sel = {
>> +	.data = &(struct clk_regmap_mux_data){
>> +		.offset = HHI_VIID_CLK_CNTL,
>> +		.mask = 0x7,
>> +		.shift = 16,
>> +	},
>> +	.hw.init = &(struct clk_init_data){
>> +		.name = "vclk2_sel",
>> +		.ops = &clk_regmap_mux_ops,
>> +		.parent_hws = axg_vclk_parent_hws,
>> +		.num_parents = ARRAY_SIZE(axg_vclk_parent_hws),
>> +		.flags = CLK_SET_RATE_NO_REPARENT | CLK_GET_RATE_NOCACHE,
>> +	},
>> +};
>> +
>> +static struct clk_regmap axg_vclk_input = {
>> +	.data = &(struct clk_regmap_gate_data){
>> +		.offset = HHI_VID_CLK_DIV,
>> +		.bit_idx = 16,
>> +	},
>> +	.hw.init = &(struct clk_init_data) {
>> +		.name = "vclk_input",
>> +		.ops = &clk_regmap_gate_ops,
>> +		.parent_hws = (const struct clk_hw *[]) { &axg_vclk_sel.hw },
>> +		.num_parents = 1,
>> +		.flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
>> +	},
>> +};
>> +
>> +static struct clk_regmap axg_vclk2_input = {
>> +	.data = &(struct clk_regmap_gate_data){
>> +		.offset = HHI_VIID_CLK_DIV,
>> +		.bit_idx = 16,
>> +	},
>> +	.hw.init = &(struct clk_init_data) {
>> +		.name = "vclk2_input",
>> +		.ops = &clk_regmap_gate_ops,
>> +		.parent_hws = (const struct clk_hw *[]) { &axg_vclk2_sel.hw },
>> +		.num_parents = 1,
>> +		.flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
>> +	},
>> +};
>> +
>> +static struct clk_regmap axg_vclk_div = {
>> +	.data = &(struct clk_regmap_div_data){
>> +		.offset = HHI_VID_CLK_DIV,
>> +		.shift = 0,
>> +		.width = 8,
>> +	},
>> +	.hw.init = &(struct clk_init_data){
>> +		.name = "vclk_div",
>> +		.ops = &clk_regmap_divider_ops,
>> +		.parent_hws = (const struct clk_hw *[]) {
>> +			&axg_vclk_input.hw
>> +		},
>> +		.num_parents = 1,
>> +		.flags = CLK_GET_RATE_NOCACHE,
>> +	},
>> +};
>> +
>> +static struct clk_regmap axg_vclk2_div = {
>> +	.data = &(struct clk_regmap_div_data){
>> +		.offset = HHI_VIID_CLK_DIV,
>> +		.shift = 0,
>> +		.width = 8,
>> +	},
>> +	.hw.init = &(struct clk_init_data){
>> +		.name = "vclk2_div",
>> +		.ops = &clk_regmap_divider_ops,
>> +		.parent_hws = (const struct clk_hw *[]) {
>> +			&axg_vclk2_input.hw
>> +		},
>> +		.num_parents = 1,
>> +		.flags = CLK_GET_RATE_NOCACHE,
>> +	},
>> +};
>> +
>> +static struct clk_regmap axg_vclk = {
>> +	.data = &(struct clk_regmap_gate_data){
>> +		.offset = HHI_VID_CLK_CNTL,
>> +		.bit_idx = 19,
>> +	},
>> +	.hw.init = &(struct clk_init_data) {
>> +		.name = "vclk",
>> +		.ops = &clk_regmap_gate_ops,
>> +		.parent_hws = (const struct clk_hw *[]) { &axg_vclk_div.hw },
>> +		.num_parents = 1,
>> +		.flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
>> +	},
>> +};
>> +
>> +static struct clk_regmap axg_vclk2 = {
>> +	.data = &(struct clk_regmap_gate_data){
>> +		.offset = HHI_VIID_CLK_CNTL,
>> +		.bit_idx = 19,
>> +	},
>> +	.hw.init = &(struct clk_init_data) {
>> +		.name = "vclk2",
>> +		.ops = &clk_regmap_gate_ops,
>> +		.parent_hws = (const struct clk_hw *[]) { &axg_vclk2_div.hw },
>> +		.num_parents = 1,
>> +		.flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
>> +	},
>> +};
>> +
>> +static struct clk_regmap axg_vclk_div1 = {
>> +	.data = &(struct clk_regmap_gate_data){
>> +		.offset = HHI_VID_CLK_CNTL,
>> +		.bit_idx = 0,
>> +	},
>> +	.hw.init = &(struct clk_init_data) {
>> +		.name = "vclk_div1",
>> +		.ops = &clk_regmap_gate_ops,
>> +		.parent_hws = (const struct clk_hw *[]) { &axg_vclk.hw },
>> +		.num_parents = 1,
>> +		.flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
>> +	},
>> +};
>> +
>> +static struct clk_regmap axg_vclk_div2_en = {
>> +	.data = &(struct clk_regmap_gate_data){
>> +		.offset = HHI_VID_CLK_CNTL,
>> +		.bit_idx = 1,
>> +	},
>> +	.hw.init = &(struct clk_init_data) {
>> +		.name = "vclk_div2_en",
>> +		.ops = &clk_regmap_gate_ops,
>> +		.parent_hws = (const struct clk_hw *[]) { &axg_vclk.hw },
>> +		.num_parents = 1,
>> +		.flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
>> +	},
>> +};
>> +
>> +static struct clk_regmap axg_vclk_div4_en = {
>> +	.data = &(struct clk_regmap_gate_data){
>> +		.offset = HHI_VID_CLK_CNTL,
>> +		.bit_idx = 2,
>> +	},
>> +	.hw.init = &(struct clk_init_data) {
>> +		.name = "vclk_div4_en",
>> +		.ops = &clk_regmap_gate_ops,
>> +		.parent_hws = (const struct clk_hw *[]) { &axg_vclk.hw },
>> +		.num_parents = 1,
>> +		.flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
>> +	},
>> +};
>> +
>> +static struct clk_regmap axg_vclk_div6_en = {
>> +	.data = &(struct clk_regmap_gate_data){
>> +		.offset = HHI_VID_CLK_CNTL,
>> +		.bit_idx = 3,
>> +	},
>> +	.hw.init = &(struct clk_init_data) {
>> +		.name = "vclk_div6_en",
>> +		.ops = &clk_regmap_gate_ops,
>> +		.parent_hws = (const struct clk_hw *[]) { &axg_vclk.hw },
>> +		.num_parents = 1,
>> +		.flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
>> +	},
>> +};
>> +
>> +static struct clk_regmap axg_vclk_div12_en = {
>> +	.data = &(struct clk_regmap_gate_data){
>> +		.offset = HHI_VID_CLK_CNTL,
>> +		.bit_idx = 4,
>> +	},
>> +	.hw.init = &(struct clk_init_data) {
>> +		.name = "vclk_div12_en",
>> +		.ops = &clk_regmap_gate_ops,
>> +		.parent_hws = (const struct clk_hw *[]) { &axg_vclk.hw },
>> +		.num_parents = 1,
>> +		.flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
>> +	},
>> +};
>> +
>> +static struct clk_regmap axg_vclk2_div1 = {
>> +	.data = &(struct clk_regmap_gate_data){
>> +		.offset = HHI_VIID_CLK_CNTL,
>> +		.bit_idx = 0,
>> +	},
>> +	.hw.init = &(struct clk_init_data) {
>> +		.name = "vclk2_div1",
>> +		.ops = &clk_regmap_gate_ops,
>> +		.parent_hws = (const struct clk_hw *[]) { &axg_vclk2.hw },
>> +		.num_parents = 1,
>> +		.flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
>> +	},
>> +};
>> +
>> +static struct clk_regmap axg_vclk2_div2_en = {
>> +	.data = &(struct clk_regmap_gate_data){
>> +		.offset = HHI_VIID_CLK_CNTL,
>> +		.bit_idx = 1,
>> +	},
>> +	.hw.init = &(struct clk_init_data) {
>> +		.name = "vclk2_div2_en",
>> +		.ops = &clk_regmap_gate_ops,
>> +		.parent_hws = (const struct clk_hw *[]) { &axg_vclk2.hw },
>> +		.num_parents = 1,
>> +		.flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
>> +	},
>> +};
>> +
>> +static struct clk_regmap axg_vclk2_div4_en = {
>> +	.data = &(struct clk_regmap_gate_data){
>> +		.offset = HHI_VIID_CLK_CNTL,
>> +		.bit_idx = 2,
>> +	},
>> +	.hw.init = &(struct clk_init_data) {
>> +		.name = "vclk2_div4_en",
>> +		.ops = &clk_regmap_gate_ops,
>> +		.parent_hws = (const struct clk_hw *[]) { &axg_vclk2.hw },
>> +		.num_parents = 1,
>> +		.flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
>> +	},
>> +};
>> +
>> +static struct clk_regmap axg_vclk2_div6_en = {
>> +	.data = &(struct clk_regmap_gate_data){
>> +		.offset = HHI_VIID_CLK_CNTL,
>> +		.bit_idx = 3,
>> +	},
>> +	.hw.init = &(struct clk_init_data) {
>> +		.name = "vclk2_div6_en",
>> +		.ops = &clk_regmap_gate_ops,
>> +		.parent_hws = (const struct clk_hw *[]) { &axg_vclk2.hw },
>> +		.num_parents = 1,
>> +		.flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
>> +	},
>> +};
>> +
>> +static struct clk_regmap axg_vclk2_div12_en = {
>> +	.data = &(struct clk_regmap_gate_data){
>> +		.offset = HHI_VIID_CLK_CNTL,
>> +		.bit_idx = 4,
>> +	},
>> +	.hw.init = &(struct clk_init_data) {
>> +		.name = "vclk2_div12_en",
>> +		.ops = &clk_regmap_gate_ops,
>> +		.parent_hws = (const struct clk_hw *[]) { &axg_vclk2.hw },
>> +		.num_parents = 1,
>> +		.flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
>> +	},
>> +};
>> +
>> +static struct clk_fixed_factor axg_vclk_div2 = {
>> +	.mult = 1,
>> +	.div = 2,
>> +	.hw.init = &(struct clk_init_data){
>> +		.name = "vclk_div2",
>> +		.ops = &clk_fixed_factor_ops,
>> +		.parent_hws = (const struct clk_hw *[]) {
>> +			&axg_vclk_div2_en.hw
>> +		},
>> +		.num_parents = 1,
>> +	},
>> +};
>> +
>> +static struct clk_fixed_factor axg_vclk_div4 = {
>> +	.mult = 1,
>> +	.div = 4,
>> +	.hw.init = &(struct clk_init_data){
>> +		.name = "vclk_div4",
>> +		.ops = &clk_fixed_factor_ops,
>> +		.parent_hws = (const struct clk_hw *[]) {
>> +			&axg_vclk_div4_en.hw
>> +		},
>> +		.num_parents = 1,
>> +	},
>> +};
>> +
>> +static struct clk_fixed_factor axg_vclk_div6 = {
>> +	.mult = 1,
>> +	.div = 6,
>> +	.hw.init = &(struct clk_init_data){
>> +		.name = "vclk_div6",
>> +		.ops = &clk_fixed_factor_ops,
>> +		.parent_hws = (const struct clk_hw *[]) {
>> +			&axg_vclk_div6_en.hw
>> +		},
>> +		.num_parents = 1,
>> +	},
>> +};
>> +
>> +static struct clk_fixed_factor axg_vclk_div12 = {
>> +	.mult = 1,
>> +	.div = 12,
>> +	.hw.init = &(struct clk_init_data){
>> +		.name = "vclk_div12",
>> +		.ops = &clk_fixed_factor_ops,
>> +		.parent_hws = (const struct clk_hw *[]) {
>> +			&axg_vclk_div12_en.hw
>> +		},
>> +		.num_parents = 1,
>> +	},
>> +};
>> +
>> +static struct clk_fixed_factor axg_vclk2_div2 = {
>> +	.mult = 1,
>> +	.div = 2,
>> +	.hw.init = &(struct clk_init_data){
>> +		.name = "vclk2_div2",
>> +		.ops = &clk_fixed_factor_ops,
>> +		.parent_hws = (const struct clk_hw *[]) {
>> +			&axg_vclk2_div2_en.hw
>> +		},
>> +		.num_parents = 1,
>> +	},
>> +};
>> +
>> +static struct clk_fixed_factor axg_vclk2_div4 = {
>> +	.mult = 1,
>> +	.div = 4,
>> +	.hw.init = &(struct clk_init_data){
>> +		.name = "vclk2_div4",
>> +		.ops = &clk_fixed_factor_ops,
>> +		.parent_hws = (const struct clk_hw *[]) {
>> +			&axg_vclk2_div4_en.hw
>> +		},
>> +		.num_parents = 1,
>> +	},
>> +};
>> +
>> +static struct clk_fixed_factor axg_vclk2_div6 = {
>> +	.mult = 1,
>> +	.div = 6,
>> +	.hw.init = &(struct clk_init_data){
>> +		.name = "vclk2_div6",
>> +		.ops = &clk_fixed_factor_ops,
>> +		.parent_hws = (const struct clk_hw *[]) {
>> +			&axg_vclk2_div6_en.hw
>> +		},
>> +		.num_parents = 1,
>> +	},
>> +};
>> +
>> +static struct clk_fixed_factor axg_vclk2_div12 = {
>> +	.mult = 1,
>> +	.div = 12,
>> +	.hw.init = &(struct clk_init_data){
>> +		.name = "vclk2_div12",
>> +		.ops = &clk_fixed_factor_ops,
>> +		.parent_hws = (const struct clk_hw *[]) {
>> +			&axg_vclk2_div12_en.hw
>> +		},
>> +		.num_parents = 1,
>> +	},
>> +};
>> +
>> +static u32 mux_table_cts_sel[] = { 0, 1, 2, 3, 4, 8, 9, 10, 11, 12 };
>> +static const struct clk_hw *axg_cts_parent_hws[] = {
>> +	&axg_vclk_div1.hw,
>> +	&axg_vclk_div2.hw,
>> +	&axg_vclk_div4.hw,
>> +	&axg_vclk_div6.hw,
>> +	&axg_vclk_div12.hw,
>> +	&axg_vclk2_div1.hw,
>> +	&axg_vclk2_div2.hw,
>> +	&axg_vclk2_div4.hw,
>> +	&axg_vclk2_div6.hw,
>> +	&axg_vclk2_div12.hw,
>> +};
>> +
>> +static struct clk_regmap axg_cts_encl_sel = {
>> +	.data = &(struct clk_regmap_mux_data){
>> +		.offset = HHI_VIID_CLK_DIV,
>> +		.mask = 0xf,
>> +		.shift = 12,
>> +		.table = mux_table_cts_sel,
>> +	},
>> +	.hw.init = &(struct clk_init_data){
>> +		.name = "cts_encl_sel",
>> +		.ops = &clk_regmap_mux_ops,
>> +		.parent_hws = axg_cts_parent_hws,
>> +		.num_parents = ARRAY_SIZE(axg_cts_parent_hws),
>> +		.flags = CLK_SET_RATE_NO_REPARENT | CLK_GET_RATE_NOCACHE,
>> +	},
>> +};
>> +
>> +static struct clk_regmap axg_cts_encl = {
>> +	.data = &(struct clk_regmap_gate_data){
>> +		.offset = HHI_VID_CLK_CNTL2,
>> +		.bit_idx = 3,
>> +	},
>> +	.hw.init = &(struct clk_init_data) {
>> +		.name = "cts_encl",
>> +		.ops = &clk_regmap_gate_ops,
>> +		.parent_hws = (const struct clk_hw *[]) {
>> +			&axg_cts_encl_sel.hw
>> +		},
>> +		.num_parents = 1,
>> +		.flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
>> +	},
>> +};
>> +
>>  static u32 mux_table_gen_clk[]	= { 0, 4, 5, 6, 7, 8,
>>  				    9, 10, 11, 13, 14, };
>>  static const struct clk_parent_data gen_clk_parent_data[] = {
>> @@ -1246,6 +1944,49 @@ static struct clk_hw_onecell_data axg_hw_onecell_data = {
>>  		[CLKID_HIFI_PLL_DCO]		= &axg_hifi_pll_dco.hw,
>>  		[CLKID_PCIE_PLL_DCO]		= &axg_pcie_pll_dco.hw,
>>  		[CLKID_PCIE_PLL_OD]		= &axg_pcie_pll_od.hw,
>> +		[CLKID_VPU_0_DIV]		= &axg_vpu_0_div.hw,
>> +		[CLKID_VPU_0_SEL]		= &axg_vpu_0_sel.hw,
>> +		[CLKID_VPU_0]			= &axg_vpu_0.hw,
>> +		[CLKID_VPU_1_DIV]		= &axg_vpu_1_div.hw,
>> +		[CLKID_VPU_1_SEL]		= &axg_vpu_1_sel.hw,
>> +		[CLKID_VPU_1]			= &axg_vpu_1.hw,
>> +		[CLKID_VPU]			= &axg_vpu.hw,
>> +		[CLKID_VAPB_0_DIV]		= &axg_vapb_0_div.hw,
>> +		[CLKID_VAPB_0_SEL]		= &axg_vapb_0_sel.hw,
>> +		[CLKID_VAPB_0]			= &axg_vapb_0.hw,
>> +		[CLKID_VAPB_1_DIV]		= &axg_vapb_1_div.hw,
>> +		[CLKID_VAPB_1_SEL]		= &axg_vapb_1_sel.hw,
>> +		[CLKID_VAPB_1]			= &axg_vapb_1.hw,
>> +		[CLKID_VAPB_SEL]		= &axg_vapb_sel.hw,
>> +		[CLKID_VAPB]			= &axg_vapb.hw,
>> +		[CLKID_VCLK]			= &axg_vclk.hw,
>> +		[CLKID_VCLK2]			= &axg_vclk2.hw,
>> +		[CLKID_VCLK_SEL]		= &axg_vclk_sel.hw,
>> +		[CLKID_VCLK2_SEL]		= &axg_vclk2_sel.hw,
>> +		[CLKID_VCLK_INPUT]		= &axg_vclk_input.hw,
>> +		[CLKID_VCLK2_INPUT]		= &axg_vclk2_input.hw,
>> +		[CLKID_VCLK_DIV]		= &axg_vclk_div.hw,
>> +		[CLKID_VCLK2_DIV]		= &axg_vclk2_div.hw,
>> +		[CLKID_VCLK_DIV2_EN]		= &axg_vclk_div2_en.hw,
>> +		[CLKID_VCLK_DIV4_EN]		= &axg_vclk_div4_en.hw,
>> +		[CLKID_VCLK_DIV6_EN]		= &axg_vclk_div6_en.hw,
>> +		[CLKID_VCLK_DIV12_EN]		= &axg_vclk_div12_en.hw,
>> +		[CLKID_VCLK2_DIV2_EN]		= &axg_vclk2_div2_en.hw,
>> +		[CLKID_VCLK2_DIV4_EN]		= &axg_vclk2_div4_en.hw,
>> +		[CLKID_VCLK2_DIV6_EN]		= &axg_vclk2_div6_en.hw,
>> +		[CLKID_VCLK2_DIV12_EN]		= &axg_vclk2_div12_en.hw,
>> +		[CLKID_VCLK_DIV1]		= &axg_vclk_div1.hw,
>> +		[CLKID_VCLK_DIV2]		= &axg_vclk_div2.hw,
>> +		[CLKID_VCLK_DIV4]		= &axg_vclk_div4.hw,
>> +		[CLKID_VCLK_DIV6]		= &axg_vclk_div6.hw,
>> +		[CLKID_VCLK_DIV12]		= &axg_vclk_div12.hw,
>> +		[CLKID_VCLK2_DIV1]		= &axg_vclk2_div1.hw,
>> +		[CLKID_VCLK2_DIV2]		= &axg_vclk2_div2.hw,
>> +		[CLKID_VCLK2_DIV4]		= &axg_vclk2_div4.hw,
>> +		[CLKID_VCLK2_DIV6]		= &axg_vclk2_div6.hw,
>> +		[CLKID_VCLK2_DIV12]		= &axg_vclk2_div12.hw,
>> +		[CLKID_CTS_ENCL_SEL]		= &axg_cts_encl_sel.hw,
>> +		[CLKID_CTS_ENCL]		= &axg_cts_encl.hw,
>>  		[NR_CLKS]			= NULL,
>>  	},
>>  	.num = NR_CLKS,
>> @@ -1341,6 +2082,39 @@ static struct clk_regmap *const axg_clk_regmaps[] = {
>>  	&axg_hifi_pll_dco,
>>  	&axg_pcie_pll_dco,
>>  	&axg_pcie_pll_od,
>> +	&axg_vpu_0_div,
>> +	&axg_vpu_0_sel,
>> +	&axg_vpu_0,
>> +	&axg_vpu_1_div,
>> +	&axg_vpu_1_sel,
>> +	&axg_vpu_1,
>> +	&axg_vpu,
>> +	&axg_vapb_0_div,
>> +	&axg_vapb_0_sel,
>> +	&axg_vapb_0,
>> +	&axg_vapb_1_div,
>> +	&axg_vapb_1_sel,
>> +	&axg_vapb_1,
>> +	&axg_vapb_sel,
>> +	&axg_vapb,
>> +	&axg_vclk,
>> +	&axg_vclk2,
>> +	&axg_vclk_sel,
>> +	&axg_vclk2_sel,
>> +	&axg_vclk_input,
>> +	&axg_vclk2_input,
>> +	&axg_vclk_div,
>> +	&axg_vclk2_div,
>> +	&axg_vclk_div2_en,
>> +	&axg_vclk_div4_en,
>> +	&axg_vclk_div6_en,
>> +	&axg_vclk_div12_en,
>> +	&axg_vclk2_div2_en,
>> +	&axg_vclk2_div4_en,
>> +	&axg_vclk2_div6_en,
>> +	&axg_vclk2_div12_en,
>> +	&axg_cts_encl_sel,
>> +	&axg_cts_encl,
>>  };
>>  
>>  static const struct meson_eeclkc_data axg_clkc_data = {
>> diff --git a/drivers/clk/meson/axg.h b/drivers/clk/meson/axg.h
>> index 0431dabac629..a8787b394a47 100644
>> --- a/drivers/clk/meson/axg.h
>> +++ b/drivers/clk/meson/axg.h
>> @@ -139,8 +139,27 @@
>>  #define CLKID_HIFI_PLL_DCO			88
>>  #define CLKID_PCIE_PLL_DCO			89
>>  #define CLKID_PCIE_PLL_OD			90
>> +#define CLKID_VPU_0_DIV				91
>> +#define CLKID_VPU_1_DIV				94
>> +#define CLKID_VAPB_0_DIV			98
>> +#define CLKID_VAPB_1_DIV			101
>> +#define CLKID_VCLK_SEL				108
>> +#define CLKID_VCLK2_SEL				109
>> +#define CLKID_VCLK_INPUT			110
>> +#define CLKID_VCLK2_INPUT			111
>> +#define CLKID_VCLK_DIV				112
>> +#define CLKID_VCLK2_DIV				113
>> +#define CLKID_VCLK_DIV2_EN			114
>> +#define CLKID_VCLK_DIV4_EN			115
>> +#define CLKID_VCLK_DIV6_EN			116
>> +#define CLKID_VCLK_DIV12_EN			117
>> +#define CLKID_VCLK2_DIV2_EN			118
>> +#define CLKID_VCLK2_DIV4_EN			119
>> +#define CLKID_VCLK2_DIV6_EN			120
>> +#define CLKID_VCLK2_DIV12_EN			121
>> +#define CLKID_CTS_ENCL_SEL			132
>>  
>> -#define NR_CLKS					91
>> +#define NR_CLKS					134
>>  
>>  /* include the CLKIDs that have been made part of the DT binding */
>>  #include <dt-bindings/clock/axg-clkc.h>
> 
> Overall, there is quite an heavy use of CLK_IGNORE_USED and
> CLK_GET_RATE_NOCACHE which seems to indicate that something else is
> poking around in the clocks registers
> 
> Details about why it should be done this way, and not through CCF API,
> should be provided.
>
Thanks,
Neil

_______________________________________________
linux-amlogic mailing list
linux-amlogic@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-amlogic

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

* Re: [PATCH 4/4] clk: meson: axg: add MIPI DSI Host clock
  2020-09-10 10:15     ` Jerome Brunet
  (?)
@ 2020-09-10 11:48       ` Neil Armstrong
  -1 siblings, 0 replies; 30+ messages in thread
From: Neil Armstrong @ 2020-09-10 11:48 UTC (permalink / raw)
  To: Jerome Brunet; +Cc: linux-amlogic, linux-clk, linux-arm-kernel, linux-kernel

On 10/09/2020 12:15, Jerome Brunet wrote:
> 
> On Mon 07 Sep 2020 at 11:38, Neil Armstrong <narmstrong@baylibre.com> wrote:
> 
>> This adds the MIPI DSI Host clock, used to measure the signal timings (ENC VSYNC or
>> DW-MIPI-DSI eDPI timings).
>>
>> Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
>> ---
>>  drivers/clk/meson/axg.c | 66 +++++++++++++++++++++++++++++++++++++++++
>>  drivers/clk/meson/axg.h |  4 ++-
>>  2 files changed, 69 insertions(+), 1 deletion(-)
>>
>> diff --git a/drivers/clk/meson/axg.c b/drivers/clk/meson/axg.c
>> index 2550616c14b0..0094ca6388d8 100644
>> --- a/drivers/clk/meson/axg.c
>> +++ b/drivers/clk/meson/axg.c
>> @@ -1724,6 +1724,66 @@ static struct clk_regmap axg_cts_encl = {
>>  	},
>>  };
>>  
>> +/* MIPI DSI Host Clock */
>> +
>> +static const struct clk_parent_data axg_vdin_meas_parent_data[] = {
>> +	{ .fw_name = "xtal", },
>> +	{ .hw = &axg_fclk_div4.hw },
>> +	{ .hw = &axg_fclk_div3.hw },
>> +	{ .hw = &axg_fclk_div5.hw },
>> +	{ },
>> +	{ },
> 
> As you've done in other patches, I'd prefer if you used an index table
> instead of having empty entries.
> 
>> +	{ .hw = &axg_fclk_div2.hw },
>> +	{ .hw = &axg_fclk_div7.hw },
>> +};

OK, will do

>> +
>> +static struct clk_regmap axg_vdin_meas_sel = {
>> +	.data = &(struct clk_regmap_mux_data){
>> +		.offset = HHI_VDIN_MEAS_CLK_CNTL,
>> +		.mask = 0x7,
>> +		.shift = 21,
>> +		.flags = CLK_MUX_ROUND_CLOSEST,
>> +	},
>> +	.hw.init = &(struct clk_init_data){
>> +		.name = "vdin_meas_sel",
>> +		.ops = &clk_regmap_mux_ops,
>> +		.parent_data = axg_vdin_meas_parent_data,
>> +		.num_parents = ARRAY_SIZE(axg_vdin_meas_parent_data),
>> +		.flags = CLK_SET_RATE_NO_REPARENT,
> 
> A comment about why manual control is required would be nice.

This is a typo, will remove.

> 
>> +	},
>> +};
>> +
>> +static struct clk_regmap axg_vdin_meas_div = {
>> +	.data = &(struct clk_regmap_div_data){
>> +		.offset = HHI_VDIN_MEAS_CLK_CNTL,
>> +		.shift = 12,
>> +		.width = 7,
>> +	},
>> +	.hw.init = &(struct clk_init_data){
>> +		.name = "vdin_meas_div",
>> +		.ops = &clk_regmap_divider_ops,
>> +		.parent_hws = (const struct clk_hw *[]) {
>> +			&axg_vdin_meas_sel.hw },
>> +		.num_parents = 1,
>> +		.flags = CLK_SET_RATE_PARENT,
>> +	},
>> +};
>> +
>> +static struct clk_regmap axg_vdin_meas = {
>> +	.data = &(struct clk_regmap_gate_data){
>> +		.offset = HHI_VDIN_MEAS_CLK_CNTL,
>> +		.bit_idx = 20,
>> +	},
>> +	.hw.init = &(struct clk_init_data) {
>> +		.name = "vdin_meas",
>> +		.ops = &clk_regmap_gate_ops,
>> +		.parent_hws = (const struct clk_hw *[]) {
>> +			&axg_vdin_meas_div.hw },
>> +		.num_parents = 1,
>> +		.flags = CLK_SET_RATE_PARENT,
>> +	},
>> +};
>> +
>>  static u32 mux_table_gen_clk[]	= { 0, 4, 5, 6, 7, 8,
>>  				    9, 10, 11, 13, 14, };
>>  static const struct clk_parent_data gen_clk_parent_data[] = {
>> @@ -1987,6 +2047,9 @@ static struct clk_hw_onecell_data axg_hw_onecell_data = {
>>  		[CLKID_VCLK2_DIV12]		= &axg_vclk2_div12.hw,
>>  		[CLKID_CTS_ENCL_SEL]		= &axg_cts_encl_sel.hw,
>>  		[CLKID_CTS_ENCL]		= &axg_cts_encl.hw,
>> +		[CLKID_VDIN_MEAS_SEL]		= &axg_vdin_meas_sel.hw,
>> +		[CLKID_VDIN_MEAS_DIV]		= &axg_vdin_meas_div.hw,
>> +		[CLKID_VDIN_MEAS]		= &axg_vdin_meas.hw,
>>  		[NR_CLKS]			= NULL,
>>  	},
>>  	.num = NR_CLKS,
>> @@ -2115,6 +2178,9 @@ static struct clk_regmap *const axg_clk_regmaps[] = {
>>  	&axg_vclk2_div12_en,
>>  	&axg_cts_encl_sel,
>>  	&axg_cts_encl,
>> +	&axg_vdin_meas_sel,
>> +	&axg_vdin_meas_div,
>> +	&axg_vdin_meas,
>>  };
>>  
>>  static const struct meson_eeclkc_data axg_clkc_data = {
>> diff --git a/drivers/clk/meson/axg.h b/drivers/clk/meson/axg.h
>> index a8787b394a47..481b307ea3cb 100644
>> --- a/drivers/clk/meson/axg.h
>> +++ b/drivers/clk/meson/axg.h
>> @@ -158,8 +158,10 @@
>>  #define CLKID_VCLK2_DIV6_EN			120
>>  #define CLKID_VCLK2_DIV12_EN			121
>>  #define CLKID_CTS_ENCL_SEL			132
>> +#define CLKID_VDIN_MEAS_SEL			134
>> +#define CLKID_VDIN_MEAS_DIV			135
>>  
>> -#define NR_CLKS					134
>> +#define NR_CLKS					137
>>  
>>  /* include the CLKIDs that have been made part of the DT binding */
>>  #include <dt-bindings/clock/axg-clkc.h>
> 


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

* Re: [PATCH 4/4] clk: meson: axg: add MIPI DSI Host clock
@ 2020-09-10 11:48       ` Neil Armstrong
  0 siblings, 0 replies; 30+ messages in thread
From: Neil Armstrong @ 2020-09-10 11:48 UTC (permalink / raw)
  To: Jerome Brunet; +Cc: linux-amlogic, linux-clk, linux-arm-kernel, linux-kernel

On 10/09/2020 12:15, Jerome Brunet wrote:
> 
> On Mon 07 Sep 2020 at 11:38, Neil Armstrong <narmstrong@baylibre.com> wrote:
> 
>> This adds the MIPI DSI Host clock, used to measure the signal timings (ENC VSYNC or
>> DW-MIPI-DSI eDPI timings).
>>
>> Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
>> ---
>>  drivers/clk/meson/axg.c | 66 +++++++++++++++++++++++++++++++++++++++++
>>  drivers/clk/meson/axg.h |  4 ++-
>>  2 files changed, 69 insertions(+), 1 deletion(-)
>>
>> diff --git a/drivers/clk/meson/axg.c b/drivers/clk/meson/axg.c
>> index 2550616c14b0..0094ca6388d8 100644
>> --- a/drivers/clk/meson/axg.c
>> +++ b/drivers/clk/meson/axg.c
>> @@ -1724,6 +1724,66 @@ static struct clk_regmap axg_cts_encl = {
>>  	},
>>  };
>>  
>> +/* MIPI DSI Host Clock */
>> +
>> +static const struct clk_parent_data axg_vdin_meas_parent_data[] = {
>> +	{ .fw_name = "xtal", },
>> +	{ .hw = &axg_fclk_div4.hw },
>> +	{ .hw = &axg_fclk_div3.hw },
>> +	{ .hw = &axg_fclk_div5.hw },
>> +	{ },
>> +	{ },
> 
> As you've done in other patches, I'd prefer if you used an index table
> instead of having empty entries.
> 
>> +	{ .hw = &axg_fclk_div2.hw },
>> +	{ .hw = &axg_fclk_div7.hw },
>> +};

OK, will do

>> +
>> +static struct clk_regmap axg_vdin_meas_sel = {
>> +	.data = &(struct clk_regmap_mux_data){
>> +		.offset = HHI_VDIN_MEAS_CLK_CNTL,
>> +		.mask = 0x7,
>> +		.shift = 21,
>> +		.flags = CLK_MUX_ROUND_CLOSEST,
>> +	},
>> +	.hw.init = &(struct clk_init_data){
>> +		.name = "vdin_meas_sel",
>> +		.ops = &clk_regmap_mux_ops,
>> +		.parent_data = axg_vdin_meas_parent_data,
>> +		.num_parents = ARRAY_SIZE(axg_vdin_meas_parent_data),
>> +		.flags = CLK_SET_RATE_NO_REPARENT,
> 
> A comment about why manual control is required would be nice.

This is a typo, will remove.

> 
>> +	},
>> +};
>> +
>> +static struct clk_regmap axg_vdin_meas_div = {
>> +	.data = &(struct clk_regmap_div_data){
>> +		.offset = HHI_VDIN_MEAS_CLK_CNTL,
>> +		.shift = 12,
>> +		.width = 7,
>> +	},
>> +	.hw.init = &(struct clk_init_data){
>> +		.name = "vdin_meas_div",
>> +		.ops = &clk_regmap_divider_ops,
>> +		.parent_hws = (const struct clk_hw *[]) {
>> +			&axg_vdin_meas_sel.hw },
>> +		.num_parents = 1,
>> +		.flags = CLK_SET_RATE_PARENT,
>> +	},
>> +};
>> +
>> +static struct clk_regmap axg_vdin_meas = {
>> +	.data = &(struct clk_regmap_gate_data){
>> +		.offset = HHI_VDIN_MEAS_CLK_CNTL,
>> +		.bit_idx = 20,
>> +	},
>> +	.hw.init = &(struct clk_init_data) {
>> +		.name = "vdin_meas",
>> +		.ops = &clk_regmap_gate_ops,
>> +		.parent_hws = (const struct clk_hw *[]) {
>> +			&axg_vdin_meas_div.hw },
>> +		.num_parents = 1,
>> +		.flags = CLK_SET_RATE_PARENT,
>> +	},
>> +};
>> +
>>  static u32 mux_table_gen_clk[]	= { 0, 4, 5, 6, 7, 8,
>>  				    9, 10, 11, 13, 14, };
>>  static const struct clk_parent_data gen_clk_parent_data[] = {
>> @@ -1987,6 +2047,9 @@ static struct clk_hw_onecell_data axg_hw_onecell_data = {
>>  		[CLKID_VCLK2_DIV12]		= &axg_vclk2_div12.hw,
>>  		[CLKID_CTS_ENCL_SEL]		= &axg_cts_encl_sel.hw,
>>  		[CLKID_CTS_ENCL]		= &axg_cts_encl.hw,
>> +		[CLKID_VDIN_MEAS_SEL]		= &axg_vdin_meas_sel.hw,
>> +		[CLKID_VDIN_MEAS_DIV]		= &axg_vdin_meas_div.hw,
>> +		[CLKID_VDIN_MEAS]		= &axg_vdin_meas.hw,
>>  		[NR_CLKS]			= NULL,
>>  	},
>>  	.num = NR_CLKS,
>> @@ -2115,6 +2178,9 @@ static struct clk_regmap *const axg_clk_regmaps[] = {
>>  	&axg_vclk2_div12_en,
>>  	&axg_cts_encl_sel,
>>  	&axg_cts_encl,
>> +	&axg_vdin_meas_sel,
>> +	&axg_vdin_meas_div,
>> +	&axg_vdin_meas,
>>  };
>>  
>>  static const struct meson_eeclkc_data axg_clkc_data = {
>> diff --git a/drivers/clk/meson/axg.h b/drivers/clk/meson/axg.h
>> index a8787b394a47..481b307ea3cb 100644
>> --- a/drivers/clk/meson/axg.h
>> +++ b/drivers/clk/meson/axg.h
>> @@ -158,8 +158,10 @@
>>  #define CLKID_VCLK2_DIV6_EN			120
>>  #define CLKID_VCLK2_DIV12_EN			121
>>  #define CLKID_CTS_ENCL_SEL			132
>> +#define CLKID_VDIN_MEAS_SEL			134
>> +#define CLKID_VDIN_MEAS_DIV			135
>>  
>> -#define NR_CLKS					134
>> +#define NR_CLKS					137
>>  
>>  /* include the CLKIDs that have been made part of the DT binding */
>>  #include <dt-bindings/clock/axg-clkc.h>
> 


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH 4/4] clk: meson: axg: add MIPI DSI Host clock
@ 2020-09-10 11:48       ` Neil Armstrong
  0 siblings, 0 replies; 30+ messages in thread
From: Neil Armstrong @ 2020-09-10 11:48 UTC (permalink / raw)
  To: Jerome Brunet; +Cc: linux-amlogic, linux-clk, linux-arm-kernel, linux-kernel

On 10/09/2020 12:15, Jerome Brunet wrote:
> 
> On Mon 07 Sep 2020 at 11:38, Neil Armstrong <narmstrong@baylibre.com> wrote:
> 
>> This adds the MIPI DSI Host clock, used to measure the signal timings (ENC VSYNC or
>> DW-MIPI-DSI eDPI timings).
>>
>> Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
>> ---
>>  drivers/clk/meson/axg.c | 66 +++++++++++++++++++++++++++++++++++++++++
>>  drivers/clk/meson/axg.h |  4 ++-
>>  2 files changed, 69 insertions(+), 1 deletion(-)
>>
>> diff --git a/drivers/clk/meson/axg.c b/drivers/clk/meson/axg.c
>> index 2550616c14b0..0094ca6388d8 100644
>> --- a/drivers/clk/meson/axg.c
>> +++ b/drivers/clk/meson/axg.c
>> @@ -1724,6 +1724,66 @@ static struct clk_regmap axg_cts_encl = {
>>  	},
>>  };
>>  
>> +/* MIPI DSI Host Clock */
>> +
>> +static const struct clk_parent_data axg_vdin_meas_parent_data[] = {
>> +	{ .fw_name = "xtal", },
>> +	{ .hw = &axg_fclk_div4.hw },
>> +	{ .hw = &axg_fclk_div3.hw },
>> +	{ .hw = &axg_fclk_div5.hw },
>> +	{ },
>> +	{ },
> 
> As you've done in other patches, I'd prefer if you used an index table
> instead of having empty entries.
> 
>> +	{ .hw = &axg_fclk_div2.hw },
>> +	{ .hw = &axg_fclk_div7.hw },
>> +};

OK, will do

>> +
>> +static struct clk_regmap axg_vdin_meas_sel = {
>> +	.data = &(struct clk_regmap_mux_data){
>> +		.offset = HHI_VDIN_MEAS_CLK_CNTL,
>> +		.mask = 0x7,
>> +		.shift = 21,
>> +		.flags = CLK_MUX_ROUND_CLOSEST,
>> +	},
>> +	.hw.init = &(struct clk_init_data){
>> +		.name = "vdin_meas_sel",
>> +		.ops = &clk_regmap_mux_ops,
>> +		.parent_data = axg_vdin_meas_parent_data,
>> +		.num_parents = ARRAY_SIZE(axg_vdin_meas_parent_data),
>> +		.flags = CLK_SET_RATE_NO_REPARENT,
> 
> A comment about why manual control is required would be nice.

This is a typo, will remove.

> 
>> +	},
>> +};
>> +
>> +static struct clk_regmap axg_vdin_meas_div = {
>> +	.data = &(struct clk_regmap_div_data){
>> +		.offset = HHI_VDIN_MEAS_CLK_CNTL,
>> +		.shift = 12,
>> +		.width = 7,
>> +	},
>> +	.hw.init = &(struct clk_init_data){
>> +		.name = "vdin_meas_div",
>> +		.ops = &clk_regmap_divider_ops,
>> +		.parent_hws = (const struct clk_hw *[]) {
>> +			&axg_vdin_meas_sel.hw },
>> +		.num_parents = 1,
>> +		.flags = CLK_SET_RATE_PARENT,
>> +	},
>> +};
>> +
>> +static struct clk_regmap axg_vdin_meas = {
>> +	.data = &(struct clk_regmap_gate_data){
>> +		.offset = HHI_VDIN_MEAS_CLK_CNTL,
>> +		.bit_idx = 20,
>> +	},
>> +	.hw.init = &(struct clk_init_data) {
>> +		.name = "vdin_meas",
>> +		.ops = &clk_regmap_gate_ops,
>> +		.parent_hws = (const struct clk_hw *[]) {
>> +			&axg_vdin_meas_div.hw },
>> +		.num_parents = 1,
>> +		.flags = CLK_SET_RATE_PARENT,
>> +	},
>> +};
>> +
>>  static u32 mux_table_gen_clk[]	= { 0, 4, 5, 6, 7, 8,
>>  				    9, 10, 11, 13, 14, };
>>  static const struct clk_parent_data gen_clk_parent_data[] = {
>> @@ -1987,6 +2047,9 @@ static struct clk_hw_onecell_data axg_hw_onecell_data = {
>>  		[CLKID_VCLK2_DIV12]		= &axg_vclk2_div12.hw,
>>  		[CLKID_CTS_ENCL_SEL]		= &axg_cts_encl_sel.hw,
>>  		[CLKID_CTS_ENCL]		= &axg_cts_encl.hw,
>> +		[CLKID_VDIN_MEAS_SEL]		= &axg_vdin_meas_sel.hw,
>> +		[CLKID_VDIN_MEAS_DIV]		= &axg_vdin_meas_div.hw,
>> +		[CLKID_VDIN_MEAS]		= &axg_vdin_meas.hw,
>>  		[NR_CLKS]			= NULL,
>>  	},
>>  	.num = NR_CLKS,
>> @@ -2115,6 +2178,9 @@ static struct clk_regmap *const axg_clk_regmaps[] = {
>>  	&axg_vclk2_div12_en,
>>  	&axg_cts_encl_sel,
>>  	&axg_cts_encl,
>> +	&axg_vdin_meas_sel,
>> +	&axg_vdin_meas_div,
>> +	&axg_vdin_meas,
>>  };
>>  
>>  static const struct meson_eeclkc_data axg_clkc_data = {
>> diff --git a/drivers/clk/meson/axg.h b/drivers/clk/meson/axg.h
>> index a8787b394a47..481b307ea3cb 100644
>> --- a/drivers/clk/meson/axg.h
>> +++ b/drivers/clk/meson/axg.h
>> @@ -158,8 +158,10 @@
>>  #define CLKID_VCLK2_DIV6_EN			120
>>  #define CLKID_VCLK2_DIV12_EN			121
>>  #define CLKID_CTS_ENCL_SEL			132
>> +#define CLKID_VDIN_MEAS_SEL			134
>> +#define CLKID_VDIN_MEAS_DIV			135
>>  
>> -#define NR_CLKS					134
>> +#define NR_CLKS					137
>>  
>>  /* include the CLKIDs that have been made part of the DT binding */
>>  #include <dt-bindings/clock/axg-clkc.h>
> 


_______________________________________________
linux-amlogic mailing list
linux-amlogic@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-amlogic

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

* Re: [PATCH 3/4] clk: meson: axg: add Video Clocks
  2020-09-10 11:47       ` Neil Armstrong
  (?)
@ 2020-09-11 17:10         ` Kevin Hilman
  -1 siblings, 0 replies; 30+ messages in thread
From: Kevin Hilman @ 2020-09-11 17:10 UTC (permalink / raw)
  To: Neil Armstrong, Jerome Brunet
  Cc: linux-amlogic, linux-clk, linux-arm-kernel, linux-kernel

Neil Armstrong <narmstrong@baylibre.com> writes:

> On 10/09/2020 12:13, Jerome Brunet wrote:

[...]

>> Why is NOCACHE ? Is there something poking behind CCF back ? if yes, why
>> is this required ?
>
> I'm surprised you ask this since the situation hasn't changed since I pushed the
> video clock for GXBB, then G12A.

Even if the situation hasn't changed, providing context is very helpful
for new reviewers or reviewers who might need a reminder of that
situation.  I for one had already forgotten the video clock context so I
had a similiar question as Jerome when I saw the NOCACHE and UNUSED
flags.

As you know, new usage of those flags is always highly scrutinized, so
providing the right context and explanation, even if it's repeating
stuff you've stated elsewhere, can help preempt any questions.  

> The switch to CCF for the VPU is still planned, but until now I was unable to allocate enough
> time for this huge rework.
>
> Since I'm the single DRM driver contributor and lacking any other reviewers, I must deal
> with new features & bugfixing before moving to CCF.

Not at all a blocker for this patch, but just curious do you have a TODO
list someplace for this driver in case others might have some time to
help you with the migration?

> The clock situation is far from perfect, and I'd also like it to be solved at some point.
>
> I'll add the same explanation I gave for GXBB in https://lkml.kernel.org/r/1541516257-16157-5-git-send-email-narmstrong@baylibre.com

Yes, that's perfect.

Thanks,

Kevin

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

* Re: [PATCH 3/4] clk: meson: axg: add Video Clocks
@ 2020-09-11 17:10         ` Kevin Hilman
  0 siblings, 0 replies; 30+ messages in thread
From: Kevin Hilman @ 2020-09-11 17:10 UTC (permalink / raw)
  To: Neil Armstrong, Jerome Brunet
  Cc: linux-amlogic, linux-clk, linux-arm-kernel, linux-kernel

Neil Armstrong <narmstrong@baylibre.com> writes:

> On 10/09/2020 12:13, Jerome Brunet wrote:

[...]

>> Why is NOCACHE ? Is there something poking behind CCF back ? if yes, why
>> is this required ?
>
> I'm surprised you ask this since the situation hasn't changed since I pushed the
> video clock for GXBB, then G12A.

Even if the situation hasn't changed, providing context is very helpful
for new reviewers or reviewers who might need a reminder of that
situation.  I for one had already forgotten the video clock context so I
had a similiar question as Jerome when I saw the NOCACHE and UNUSED
flags.

As you know, new usage of those flags is always highly scrutinized, so
providing the right context and explanation, even if it's repeating
stuff you've stated elsewhere, can help preempt any questions.  

> The switch to CCF for the VPU is still planned, but until now I was unable to allocate enough
> time for this huge rework.
>
> Since I'm the single DRM driver contributor and lacking any other reviewers, I must deal
> with new features & bugfixing before moving to CCF.

Not at all a blocker for this patch, but just curious do you have a TODO
list someplace for this driver in case others might have some time to
help you with the migration?

> The clock situation is far from perfect, and I'd also like it to be solved at some point.
>
> I'll add the same explanation I gave for GXBB in https://lkml.kernel.org/r/1541516257-16157-5-git-send-email-narmstrong@baylibre.com

Yes, that's perfect.

Thanks,

Kevin

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH 3/4] clk: meson: axg: add Video Clocks
@ 2020-09-11 17:10         ` Kevin Hilman
  0 siblings, 0 replies; 30+ messages in thread
From: Kevin Hilman @ 2020-09-11 17:10 UTC (permalink / raw)
  To: Neil Armstrong, Jerome Brunet
  Cc: linux-amlogic, linux-clk, linux-arm-kernel, linux-kernel

Neil Armstrong <narmstrong@baylibre.com> writes:

> On 10/09/2020 12:13, Jerome Brunet wrote:

[...]

>> Why is NOCACHE ? Is there something poking behind CCF back ? if yes, why
>> is this required ?
>
> I'm surprised you ask this since the situation hasn't changed since I pushed the
> video clock for GXBB, then G12A.

Even if the situation hasn't changed, providing context is very helpful
for new reviewers or reviewers who might need a reminder of that
situation.  I for one had already forgotten the video clock context so I
had a similiar question as Jerome when I saw the NOCACHE and UNUSED
flags.

As you know, new usage of those flags is always highly scrutinized, so
providing the right context and explanation, even if it's repeating
stuff you've stated elsewhere, can help preempt any questions.  

> The switch to CCF for the VPU is still planned, but until now I was unable to allocate enough
> time for this huge rework.
>
> Since I'm the single DRM driver contributor and lacking any other reviewers, I must deal
> with new features & bugfixing before moving to CCF.

Not at all a blocker for this patch, but just curious do you have a TODO
list someplace for this driver in case others might have some time to
help you with the migration?

> The clock situation is far from perfect, and I'd also like it to be solved at some point.
>
> I'll add the same explanation I gave for GXBB in https://lkml.kernel.org/r/1541516257-16157-5-git-send-email-narmstrong@baylibre.com

Yes, that's perfect.

Thanks,

Kevin

_______________________________________________
linux-amlogic mailing list
linux-amlogic@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-amlogic

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

end of thread, other threads:[~2020-09-11 17:12 UTC | newest]

Thread overview: 30+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-09-07  9:38 [PATCH 0/4] clk: meson: axg: add clocks for MIPI-DSI support Neil Armstrong
2020-09-07  9:38 ` Neil Armstrong
2020-09-07  9:38 ` Neil Armstrong
2020-09-07  9:38 ` [PATCH 1/4] dt-bindings: clk: axg-clkc: add Video Clocks Neil Armstrong
2020-09-07  9:38   ` Neil Armstrong
2020-09-07  9:38   ` Neil Armstrong
2020-09-07  9:38 ` [PATCH 2/4] dt-bindings: clk: axg-clkc: add MIPI DSI Host clock binding Neil Armstrong
2020-09-07  9:38   ` Neil Armstrong
2020-09-07  9:38   ` Neil Armstrong
2020-09-07  9:38 ` [PATCH 3/4] clk: meson: axg: add Video Clocks Neil Armstrong
2020-09-07  9:38   ` Neil Armstrong
2020-09-07  9:38   ` Neil Armstrong
2020-09-10 10:13   ` Jerome Brunet
2020-09-10 10:13     ` Jerome Brunet
2020-09-10 10:13     ` Jerome Brunet
2020-09-10 11:47     ` Neil Armstrong
2020-09-10 11:47       ` Neil Armstrong
2020-09-10 11:47       ` Neil Armstrong
2020-09-11 17:10       ` Kevin Hilman
2020-09-11 17:10         ` Kevin Hilman
2020-09-11 17:10         ` Kevin Hilman
2020-09-07  9:38 ` [PATCH 4/4] clk: meson: axg: add MIPI DSI Host clock Neil Armstrong
2020-09-07  9:38   ` Neil Armstrong
2020-09-07  9:38   ` Neil Armstrong
2020-09-10 10:15   ` Jerome Brunet
2020-09-10 10:15     ` Jerome Brunet
2020-09-10 10:15     ` Jerome Brunet
2020-09-10 11:48     ` Neil Armstrong
2020-09-10 11:48       ` Neil Armstrong
2020-09-10 11:48       ` Neil Armstrong

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.