aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/clk/meson/gxbb.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/clk/meson/gxbb.c')
-rw-r--r--drivers/clk/meson/gxbb.c119
1 files changed, 76 insertions, 43 deletions
diff --git a/drivers/clk/meson/gxbb.c b/drivers/clk/meson/gxbb.c
index 240658404367..86d3ae58e84c 100644
--- a/drivers/clk/meson/gxbb.c
+++ b/drivers/clk/meson/gxbb.c
@@ -7,7 +7,6 @@
#include <linux/clk.h>
#include <linux/clk-provider.h>
#include <linux/init.h>
-#include <linux/of_address.h>
#include <linux/of_device.h>
#include <linux/mfd/syscon.h>
#include <linux/platform_device.h>
@@ -498,6 +497,7 @@ static struct clk_regmap gxbb_fclk_div2 = {
.ops = &clk_regmap_gate_ops,
.parent_names = (const char *[]){ "fclk_div2_div" },
.num_parents = 1,
+ .flags = CLK_IS_CRITICAL,
},
};
@@ -970,28 +970,26 @@ static struct clk_regmap gxbb_cts_amclk_sel = {
.mask = 0x3,
.shift = 9,
.table = (u32[]){ 1, 2, 3 },
+ .flags = CLK_MUX_ROUND_CLOSEST,
},
.hw.init = &(struct clk_init_data){
.name = "cts_amclk_sel",
.ops = &clk_regmap_mux_ops,
.parent_names = (const char *[]){ "mpll0", "mpll1", "mpll2" },
.num_parents = 3,
- .flags = CLK_SET_RATE_PARENT,
},
};
static struct clk_regmap gxbb_cts_amclk_div = {
- .data = &(struct meson_clk_audio_div_data){
- .div = {
- .reg_off = HHI_AUD_CLK_CNTL,
- .shift = 0,
- .width = 8,
- },
+ .data = &(struct clk_regmap_div_data) {
+ .offset = HHI_AUD_CLK_CNTL,
+ .shift = 0,
+ .width = 8,
.flags = CLK_DIVIDER_ROUND_CLOSEST,
},
.hw.init = &(struct clk_init_data){
.name = "cts_amclk_div",
- .ops = &meson_clk_audio_divider_ops,
+ .ops = &clk_regmap_divider_ops,
.parent_names = (const char *[]){ "cts_amclk_sel" },
.num_parents = 1,
.flags = CLK_SET_RATE_PARENT,
@@ -1018,13 +1016,13 @@ static struct clk_regmap gxbb_cts_mclk_i958_sel = {
.mask = 0x3,
.shift = 25,
.table = (u32[]){ 1, 2, 3 },
+ .flags = CLK_MUX_ROUND_CLOSEST,
},
.hw.init = &(struct clk_init_data) {
.name = "cts_mclk_i958_sel",
.ops = &clk_regmap_mux_ops,
.parent_names = (const char *[]){ "mpll0", "mpll1", "mpll2" },
.num_parents = 3,
- .flags = CLK_SET_RATE_PARENT,
},
};
@@ -1626,6 +1624,63 @@ static struct clk_regmap gxbb_vdec_hevc = {
},
};
+static u32 mux_table_gen_clk[] = { 0, 4, 5, 6, 7, 8,
+ 9, 10, 11, 13, 14, };
+static const char * const gen_clk_parent_names[] = {
+ "xtal", "vdec_1", "vdec_hevc", "mpll0", "mpll1", "mpll2",
+ "fclk_div4", "fclk_div3", "fclk_div5", "fclk_div7", "gp0_pll",
+};
+
+static struct clk_regmap gxbb_gen_clk_sel = {
+ .data = &(struct clk_regmap_mux_data){
+ .offset = HHI_GEN_CLK_CNTL,
+ .mask = 0xf,
+ .shift = 12,
+ .table = mux_table_gen_clk,
+ },
+ .hw.init = &(struct clk_init_data){
+ .name = "gen_clk_sel",
+ .ops = &clk_regmap_mux_ops,
+ /*
+ * bits 15:12 selects from 14 possible parents:
+ * xtal, [rtc_oscin_i], [sys_cpu_div16], [ddr_dpll_pt],
+ * vid_pll, vid2_pll (hevc), mpll0, mpll1, mpll2, fdiv4,
+ * fdiv3, fdiv5, [cts_msr_clk], fdiv7, gp0_pll
+ */
+ .parent_names = gen_clk_parent_names,
+ .num_parents = ARRAY_SIZE(gen_clk_parent_names),
+ },
+};
+
+static struct clk_regmap gxbb_gen_clk_div = {
+ .data = &(struct clk_regmap_div_data){
+ .offset = HHI_GEN_CLK_CNTL,
+ .shift = 0,
+ .width = 11,
+ },
+ .hw.init = &(struct clk_init_data){
+ .name = "gen_clk_div",
+ .ops = &clk_regmap_divider_ops,
+ .parent_names = (const char *[]){ "gen_clk_sel" },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ },
+};
+
+static struct clk_regmap gxbb_gen_clk = {
+ .data = &(struct clk_regmap_gate_data){
+ .offset = HHI_GEN_CLK_CNTL,
+ .bit_idx = 7,
+ },
+ .hw.init = &(struct clk_init_data){
+ .name = "gen_clk",
+ .ops = &clk_regmap_gate_ops,
+ .parent_names = (const char *[]){ "gen_clk_div" },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ },
+};
+
/* Everything Else (EE) domain gates */
static MESON_GATE(gxbb_ddr, HHI_GCLK_MPEG0, 0);
static MESON_GATE(gxbb_dos, HHI_GCLK_MPEG0, 1);
@@ -1875,6 +1930,9 @@ static struct clk_hw_onecell_data gxbb_hw_onecell_data = {
[CLKID_VDEC_HEVC_SEL] = &gxbb_vdec_hevc_sel.hw,
[CLKID_VDEC_HEVC_DIV] = &gxbb_vdec_hevc_div.hw,
[CLKID_VDEC_HEVC] = &gxbb_vdec_hevc.hw,
+ [CLKID_GEN_CLK_SEL] = &gxbb_gen_clk_sel.hw,
+ [CLKID_GEN_CLK_DIV] = &gxbb_gen_clk_div.hw,
+ [CLKID_GEN_CLK] = &gxbb_gen_clk.hw,
[NR_CLKS] = NULL,
},
.num = NR_CLKS,
@@ -2037,6 +2095,9 @@ static struct clk_hw_onecell_data gxl_hw_onecell_data = {
[CLKID_VDEC_HEVC_SEL] = &gxbb_vdec_hevc_sel.hw,
[CLKID_VDEC_HEVC_DIV] = &gxbb_vdec_hevc_div.hw,
[CLKID_VDEC_HEVC] = &gxbb_vdec_hevc.hw,
+ [CLKID_GEN_CLK_SEL] = &gxbb_gen_clk_sel.hw,
+ [CLKID_GEN_CLK_DIV] = &gxbb_gen_clk_div.hw,
+ [CLKID_GEN_CLK] = &gxbb_gen_clk.hw,
[NR_CLKS] = NULL,
},
.num = NR_CLKS,
@@ -2201,6 +2262,9 @@ static struct clk_regmap *const gx_clk_regmaps[] = {
&gxbb_vdec_hevc_sel,
&gxbb_vdec_hevc_div,
&gxbb_vdec_hevc,
+ &gxbb_gen_clk_sel,
+ &gxbb_gen_clk_div,
+ &gxbb_gen_clk,
};
struct clkc_data {
@@ -2227,17 +2291,9 @@ static const struct of_device_id clkc_match_table[] = {
{},
};
-static const struct regmap_config clkc_regmap_config = {
- .reg_bits = 32,
- .val_bits = 32,
- .reg_stride = 4,
-};
-
static int gxbb_clkc_probe(struct platform_device *pdev)
{
const struct clkc_data *clkc_data;
- struct resource *res;
- void __iomem *clk_base;
struct regmap *map;
int ret, i;
struct device *dev = &pdev->dev;
@@ -2249,31 +2305,8 @@ static int gxbb_clkc_probe(struct platform_device *pdev)
/* Get the hhi system controller node if available */
map = syscon_node_to_regmap(of_get_parent(dev->of_node));
if (IS_ERR(map)) {
- dev_err(dev,
- "failed to get HHI regmap - Trying obsolete regs\n");
-
- /*
- * FIXME: HHI registers should be accessed through
- * the appropriate system controller. This is required because
- * there is more than just clocks in this register space
- *
- * This fallback method is only provided temporarily until
- * all the platform DTs are properly using the syscon node
- */
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- if (!res)
- return -EINVAL;
-
- clk_base = devm_ioremap(dev, res->start, resource_size(res));
- if (!clk_base) {
- dev_err(dev, "Unable to map clk base\n");
- return -ENXIO;
- }
-
- map = devm_regmap_init_mmio(dev, clk_base,
- &clkc_regmap_config);
- if (IS_ERR(map))
- return PTR_ERR(map);
+ dev_err(dev, "failed to get HHI regmap\n");
+ return PTR_ERR(map);
}
/* Populate regmap for the common regmap backed clocks */