mirror of
https://github.com/Fishwaldo/build.git
synced 2025-03-26 16:51:48 +00:00
357 lines
10 KiB
Diff
357 lines
10 KiB
Diff
From a3b8b7bfd775fa521425c72856b4394fb6fec518 Mon Sep 17 00:00:00 2001
|
|
From: Neil Armstrong <narmstrong@baylibre.com>
|
|
Date: Fri, 13 Oct 2017 14:38:37 +0200
|
|
Subject: [PATCH 15/39] clk: meson: gxbb: Add VPU and VAPB clocks data
|
|
|
|
The Amlogic Meson GX SoCs needs these two clocks to power up the
|
|
VPU power domain.
|
|
|
|
These two clocks are similar to the MALI clocks by having a glitch-free
|
|
mux and two similar clocks with gate, divider and muxes.
|
|
|
|
Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
|
|
---
|
|
drivers/clk/meson/gxbb.c | 292 +++++++++++++++++++++++++++++++++++++++++++++++
|
|
1 file changed, 292 insertions(+)
|
|
|
|
diff --git a/drivers/clk/meson/gxbb.c b/drivers/clk/meson/gxbb.c
|
|
index 92168348..86cb5af 100644
|
|
--- a/drivers/clk/meson/gxbb.c
|
|
+++ b/drivers/clk/meson/gxbb.c
|
|
@@ -1131,6 +1131,253 @@ static struct clk_gate gxbb_sd_emmc_c_clk0 = {
|
|
},
|
|
};
|
|
|
|
+/* VPU Clock */
|
|
+
|
|
+static u32 mux_table_vpu[] = {0, 1, 2, 3};
|
|
+static const char * const gxbb_vpu_parent_names[] = {
|
|
+ "fclk_div4", "fclk_div3", "fclk_div5", "fclk_div7"
|
|
+};
|
|
+
|
|
+static struct clk_mux gxbb_vpu_0_sel = {
|
|
+ .reg = (void *)HHI_VPU_CLK_CNTL,
|
|
+ .mask = 0x3,
|
|
+ .shift = 9,
|
|
+ .lock = &clk_lock,
|
|
+ .table = mux_table_vpu,
|
|
+ .hw.init = &(struct clk_init_data){
|
|
+ .name = "vpu_0_sel",
|
|
+ .ops = &clk_mux_ops,
|
|
+ /*
|
|
+ * bits 9:10 selects from 4 possible parents:
|
|
+ * fclk_div4, fclk_div3, fclk_div5, fclk_div7,
|
|
+ */
|
|
+ .parent_names = gxbb_vpu_parent_names,
|
|
+ .num_parents = ARRAY_SIZE(gxbb_vpu_parent_names),
|
|
+ .flags = CLK_SET_RATE_NO_REPARENT | CLK_IGNORE_UNUSED,
|
|
+ },
|
|
+};
|
|
+
|
|
+static struct clk_divider gxbb_vpu_0_div = {
|
|
+ .reg = (void *)HHI_VPU_CLK_CNTL,
|
|
+ .shift = 0,
|
|
+ .width = 7,
|
|
+ .lock = &clk_lock,
|
|
+ .hw.init = &(struct clk_init_data){
|
|
+ .name = "vpu_0_div",
|
|
+ .ops = &clk_divider_ops,
|
|
+ .parent_names = (const char *[]){ "vpu_0_sel" },
|
|
+ .num_parents = 1,
|
|
+ .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
|
|
+ },
|
|
+};
|
|
+
|
|
+static struct clk_gate gxbb_vpu_0 = {
|
|
+ .reg = (void *)HHI_VPU_CLK_CNTL,
|
|
+ .bit_idx = 8,
|
|
+ .lock = &clk_lock,
|
|
+ .hw.init = &(struct clk_init_data) {
|
|
+ .name = "vpu_0",
|
|
+ .ops = &clk_gate_ops,
|
|
+ .parent_names = (const char *[]){ "vpu_0_div" },
|
|
+ .num_parents = 1,
|
|
+ .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
|
|
+ },
|
|
+};
|
|
+
|
|
+static struct clk_mux gxbb_vpu_1_sel = {
|
|
+ .reg = (void *)HHI_VPU_CLK_CNTL,
|
|
+ .mask = 0x3,
|
|
+ .shift = 25,
|
|
+ .lock = &clk_lock,
|
|
+ .table = mux_table_vpu,
|
|
+ .hw.init = &(struct clk_init_data){
|
|
+ .name = "vpu_1_sel",
|
|
+ .ops = &clk_mux_ops,
|
|
+ /*
|
|
+ * bits 25:26 selects from 4 possible parents:
|
|
+ * fclk_div4, fclk_div3, fclk_div5, fclk_div7,
|
|
+ */
|
|
+ .parent_names = gxbb_vpu_parent_names,
|
|
+ .num_parents = ARRAY_SIZE(gxbb_vpu_parent_names),
|
|
+ .flags = CLK_SET_RATE_NO_REPARENT | CLK_IGNORE_UNUSED,
|
|
+ },
|
|
+};
|
|
+
|
|
+static struct clk_divider gxbb_vpu_1_div = {
|
|
+ .reg = (void *)HHI_VPU_CLK_CNTL,
|
|
+ .shift = 16,
|
|
+ .width = 7,
|
|
+ .lock = &clk_lock,
|
|
+ .hw.init = &(struct clk_init_data){
|
|
+ .name = "vpu_1_div",
|
|
+ .ops = &clk_divider_ops,
|
|
+ .parent_names = (const char *[]){ "vpu_1_sel" },
|
|
+ .num_parents = 1,
|
|
+ .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
|
|
+ },
|
|
+};
|
|
+
|
|
+static struct clk_gate gxbb_vpu_1 = {
|
|
+ .reg = (void *)HHI_VPU_CLK_CNTL,
|
|
+ .bit_idx = 24,
|
|
+ .lock = &clk_lock,
|
|
+ .hw.init = &(struct clk_init_data) {
|
|
+ .name = "vpu_1",
|
|
+ .ops = &clk_gate_ops,
|
|
+ .parent_names = (const char *[]){ "vpu_1_div" },
|
|
+ .num_parents = 1,
|
|
+ .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
|
|
+ },
|
|
+};
|
|
+
|
|
+static struct clk_mux gxbb_vpu = {
|
|
+ .reg = (void *)HHI_VPU_CLK_CNTL,
|
|
+ .mask = 1,
|
|
+ .shift = 31,
|
|
+ .lock = &clk_lock,
|
|
+ .hw.init = &(struct clk_init_data){
|
|
+ .name = "vpu",
|
|
+ .ops = &clk_mux_ops,
|
|
+ /*
|
|
+ * bit 31 selects from 2 possible parents:
|
|
+ * vpu_0 or vpu_1
|
|
+ */
|
|
+ .parent_names = (const char *[]){ "vpu_0", "vpu_1" },
|
|
+ .num_parents = 2,
|
|
+ .flags = CLK_SET_RATE_NO_REPARENT | CLK_IGNORE_UNUSED,
|
|
+ },
|
|
+};
|
|
+
|
|
+/* VAPB Clock */
|
|
+
|
|
+static u32 mux_table_vapb[] = {0, 1, 2, 3};
|
|
+static const char * const gxbb_vapb_parent_names[] = {
|
|
+ "fclk_div4", "fclk_div3", "fclk_div5", "fclk_div7"
|
|
+};
|
|
+
|
|
+static struct clk_mux gxbb_vapb_0_sel = {
|
|
+ .reg = (void *)HHI_VAPBCLK_CNTL,
|
|
+ .mask = 0x3,
|
|
+ .shift = 9,
|
|
+ .lock = &clk_lock,
|
|
+ .table = mux_table_vapb,
|
|
+ .hw.init = &(struct clk_init_data){
|
|
+ .name = "vapb_0_sel",
|
|
+ .ops = &clk_mux_ops,
|
|
+ /*
|
|
+ * bits 9:10 selects from 4 possible parents:
|
|
+ * fclk_div4, fclk_div3, fclk_div5, fclk_div7,
|
|
+ */
|
|
+ .parent_names = gxbb_vapb_parent_names,
|
|
+ .num_parents = ARRAY_SIZE(gxbb_vapb_parent_names),
|
|
+ .flags = CLK_SET_RATE_NO_REPARENT | CLK_IGNORE_UNUSED,
|
|
+ },
|
|
+};
|
|
+
|
|
+static struct clk_divider gxbb_vapb_0_div = {
|
|
+ .reg = (void *)HHI_VAPBCLK_CNTL,
|
|
+ .shift = 0,
|
|
+ .width = 7,
|
|
+ .lock = &clk_lock,
|
|
+ .hw.init = &(struct clk_init_data){
|
|
+ .name = "vapb_0_div",
|
|
+ .ops = &clk_divider_ops,
|
|
+ .parent_names = (const char *[]){ "vapb_0_sel" },
|
|
+ .num_parents = 1,
|
|
+ .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
|
|
+ },
|
|
+};
|
|
+
|
|
+static struct clk_gate gxbb_vapb_0 = {
|
|
+ .reg = (void *)HHI_VAPBCLK_CNTL,
|
|
+ .bit_idx = 8,
|
|
+ .lock = &clk_lock,
|
|
+ .hw.init = &(struct clk_init_data) {
|
|
+ .name = "vapb_0",
|
|
+ .ops = &clk_gate_ops,
|
|
+ .parent_names = (const char *[]){ "vapb_0_div" },
|
|
+ .num_parents = 1,
|
|
+ .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
|
|
+ },
|
|
+};
|
|
+
|
|
+static struct clk_mux gxbb_vapb_1_sel = {
|
|
+ .reg = (void *)HHI_VAPBCLK_CNTL,
|
|
+ .mask = 0x3,
|
|
+ .shift = 25,
|
|
+ .lock = &clk_lock,
|
|
+ .table = mux_table_vapb,
|
|
+ .hw.init = &(struct clk_init_data){
|
|
+ .name = "vapb_1_sel",
|
|
+ .ops = &clk_mux_ops,
|
|
+ /*
|
|
+ * bits 25:26 selects from 4 possible parents:
|
|
+ * fclk_div4, fclk_div3, fclk_div5, fclk_div7,
|
|
+ */
|
|
+ .parent_names = gxbb_vapb_parent_names,
|
|
+ .num_parents = ARRAY_SIZE(gxbb_vapb_parent_names),
|
|
+ .flags = CLK_SET_RATE_NO_REPARENT | CLK_IGNORE_UNUSED,
|
|
+ },
|
|
+};
|
|
+
|
|
+static struct clk_divider gxbb_vapb_1_div = {
|
|
+ .reg = (void *)HHI_VAPBCLK_CNTL,
|
|
+ .shift = 16,
|
|
+ .width = 7,
|
|
+ .lock = &clk_lock,
|
|
+ .hw.init = &(struct clk_init_data){
|
|
+ .name = "vapb_1_div",
|
|
+ .ops = &clk_divider_ops,
|
|
+ .parent_names = (const char *[]){ "vapb_1_sel" },
|
|
+ .num_parents = 1,
|
|
+ .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
|
|
+ },
|
|
+};
|
|
+
|
|
+static struct clk_gate gxbb_vapb_1 = {
|
|
+ .reg = (void *)HHI_VAPBCLK_CNTL,
|
|
+ .bit_idx = 24,
|
|
+ .lock = &clk_lock,
|
|
+ .hw.init = &(struct clk_init_data) {
|
|
+ .name = "vapb_1",
|
|
+ .ops = &clk_gate_ops,
|
|
+ .parent_names = (const char *[]){ "vapb_1_div" },
|
|
+ .num_parents = 1,
|
|
+ .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
|
|
+ },
|
|
+};
|
|
+
|
|
+static struct clk_mux gxbb_vapb_sel = {
|
|
+ .reg = (void *)HHI_VAPBCLK_CNTL,
|
|
+ .mask = 1,
|
|
+ .shift = 31,
|
|
+ .lock = &clk_lock,
|
|
+ .hw.init = &(struct clk_init_data){
|
|
+ .name = "vapb_sel",
|
|
+ .ops = &clk_mux_ops,
|
|
+ /*
|
|
+ * bit 31 selects from 2 possible parents:
|
|
+ * vapb_0 or vapb_1
|
|
+ */
|
|
+ .parent_names = (const char *[]){ "vapb_0", "vapb_1" },
|
|
+ .num_parents = 2,
|
|
+ .flags = CLK_SET_RATE_NO_REPARENT | CLK_IGNORE_UNUSED,
|
|
+ },
|
|
+};
|
|
+
|
|
+static struct clk_gate gxbb_vapb = {
|
|
+ .reg = (void *)HHI_VAPBCLK_CNTL,
|
|
+ .bit_idx = 30,
|
|
+ .lock = &clk_lock,
|
|
+ .hw.init = &(struct clk_init_data) {
|
|
+ .name = "vapb",
|
|
+ .ops = &clk_gate_ops,
|
|
+ .parent_names = (const char *[]){ "vapb_sel" },
|
|
+ .num_parents = 1,
|
|
+ .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
|
|
+ },
|
|
+};
|
|
+
|
|
/* Everything Else (EE) domain gates */
|
|
static MESON_GATE(gxbb_ddr, HHI_GCLK_MPEG0, 0);
|
|
static MESON_GATE(gxbb_dos, HHI_GCLK_MPEG0, 1);
|
|
@@ -1349,6 +1596,21 @@ static struct clk_hw_onecell_data gxbb_hw_onecell_data = {
|
|
[CLKID_SD_EMMC_C_CLK0_SEL] = &gxbb_sd_emmc_c_clk0_sel.hw,
|
|
[CLKID_SD_EMMC_C_CLK0_DIV] = &gxbb_sd_emmc_c_clk0_div.hw,
|
|
[CLKID_SD_EMMC_C_CLK0] = &gxbb_sd_emmc_c_clk0.hw,
|
|
+ [CLKID_VPU_0_SEL] = &gxbb_vpu_0_sel.hw,
|
|
+ [CLKID_VPU_0_DIV] = &gxbb_vpu_0_div.hw,
|
|
+ [CLKID_VPU_0] = &gxbb_vpu_0.hw,
|
|
+ [CLKID_VPU_1_SEL] = &gxbb_vpu_1_sel.hw,
|
|
+ [CLKID_VPU_1_DIV] = &gxbb_vpu_1_div.hw,
|
|
+ [CLKID_VPU_1] = &gxbb_vpu_1.hw,
|
|
+ [CLKID_VPU] = &gxbb_vpu.hw,
|
|
+ [CLKID_VAPB_0_SEL] = &gxbb_vapb_0_sel.hw,
|
|
+ [CLKID_VAPB_0_DIV] = &gxbb_vapb_0_div.hw,
|
|
+ [CLKID_VAPB_0] = &gxbb_vapb_0.hw,
|
|
+ [CLKID_VAPB_1_SEL] = &gxbb_vapb_1_sel.hw,
|
|
+ [CLKID_VAPB_1_DIV] = &gxbb_vapb_1_div.hw,
|
|
+ [CLKID_VAPB_1] = &gxbb_vapb_1.hw,
|
|
+ [CLKID_VAPB_SEL] = &gxbb_vapb_sel.hw,
|
|
+ [CLKID_VAPB] = &gxbb_vapb.hw,
|
|
[NR_CLKS] = NULL,
|
|
},
|
|
.num = NR_CLKS,
|
|
@@ -1481,6 +1743,21 @@ static struct clk_hw_onecell_data gxl_hw_onecell_data = {
|
|
[CLKID_SD_EMMC_C_CLK0_SEL] = &gxbb_sd_emmc_c_clk0_sel.hw,
|
|
[CLKID_SD_EMMC_C_CLK0_DIV] = &gxbb_sd_emmc_c_clk0_div.hw,
|
|
[CLKID_SD_EMMC_C_CLK0] = &gxbb_sd_emmc_c_clk0.hw,
|
|
+ [CLKID_VPU_0_SEL] = &gxbb_vpu_0_sel.hw,
|
|
+ [CLKID_VPU_0_DIV] = &gxbb_vpu_0_div.hw,
|
|
+ [CLKID_VPU_0] = &gxbb_vpu_0.hw,
|
|
+ [CLKID_VPU_1_SEL] = &gxbb_vpu_1_sel.hw,
|
|
+ [CLKID_VPU_1_DIV] = &gxbb_vpu_1_div.hw,
|
|
+ [CLKID_VPU_1] = &gxbb_vpu_1.hw,
|
|
+ [CLKID_VPU] = &gxbb_vpu.hw,
|
|
+ [CLKID_VAPB_0_SEL] = &gxbb_vapb_0_sel.hw,
|
|
+ [CLKID_VAPB_0_DIV] = &gxbb_vapb_0_div.hw,
|
|
+ [CLKID_VAPB_0] = &gxbb_vapb_0.hw,
|
|
+ [CLKID_VAPB_1_SEL] = &gxbb_vapb_1_sel.hw,
|
|
+ [CLKID_VAPB_1_DIV] = &gxbb_vapb_1_div.hw,
|
|
+ [CLKID_VAPB_1] = &gxbb_vapb_1.hw,
|
|
+ [CLKID_VAPB_SEL] = &gxbb_vapb_sel.hw,
|
|
+ [CLKID_VAPB] = &gxbb_vapb.hw,
|
|
[NR_CLKS] = NULL,
|
|
},
|
|
.num = NR_CLKS,
|
|
@@ -1600,6 +1877,11 @@ static struct clk_gate *const gxbb_clk_gates[] = {
|
|
&gxbb_sd_emmc_a_clk0,
|
|
&gxbb_sd_emmc_b_clk0,
|
|
&gxbb_sd_emmc_c_clk0,
|
|
+ &gxbb_vpu_0,
|
|
+ &gxbb_vpu_1,
|
|
+ &gxbb_vapb_0,
|
|
+ &gxbb_vapb_1,
|
|
+ &gxbb_vapb,
|
|
};
|
|
|
|
static struct clk_mux *const gxbb_clk_muxes[] = {
|
|
@@ -1615,6 +1897,12 @@ static struct clk_mux *const gxbb_clk_muxes[] = {
|
|
&gxbb_sd_emmc_a_clk0_sel,
|
|
&gxbb_sd_emmc_b_clk0_sel,
|
|
&gxbb_sd_emmc_c_clk0_sel,
|
|
+ &gxbb_vpu_0_sel,
|
|
+ &gxbb_vpu_1_sel,
|
|
+ &gxbb_vpu,
|
|
+ &gxbb_vapb_0_sel,
|
|
+ &gxbb_vapb_1_sel,
|
|
+ &gxbb_vapb_sel,
|
|
};
|
|
|
|
static struct clk_divider *const gxbb_clk_dividers[] = {
|
|
@@ -1627,6 +1915,10 @@ static struct clk_divider *const gxbb_clk_dividers[] = {
|
|
&gxbb_sd_emmc_a_clk0_div,
|
|
&gxbb_sd_emmc_b_clk0_div,
|
|
&gxbb_sd_emmc_c_clk0_div,
|
|
+ &gxbb_vpu_0_div,
|
|
+ &gxbb_vpu_1_div,
|
|
+ &gxbb_vapb_0_div,
|
|
+ &gxbb_vapb_1_div,
|
|
};
|
|
|
|
static struct meson_clk_audio_divider *const gxbb_audio_dividers[] = {
|
|
--
|
|
2.7.4
|
|
|