summaryrefslogtreecommitdiff
authorJian Hu <jian.hu@amlogic.com>2019-05-08 11:52:28 (GMT)
committer Jian Hu <jian.hu@amlogic.com>2019-08-01 11:29:39 (GMT)
commit5c40910faec42ff81772f94a1f3539c687261b0c (patch)
tree5c97d1e769fbcca6f02e336905653173a7323ee8
parent75eac27815f36c778c8c509299ff0a967eafd5a9 (diff)
downloadcommon-5c40910faec42ff81772f94a1f3539c687261b0c.zip
common-5c40910faec42ff81772f94a1f3539c687261b0c.tar.gz
common-5c40910faec42ff81772f94a1f3539c687261b0c.tar.bz2
clk: tl1: add clk81 mux clock [1/1]
PD#SWPL-8215 Problem: 1.clk81 can not switch to 24M 2.fixed pll can set rate call clk_prepare_enable to open it call clk_disable_unprepare to close it Solution: 1.add clk81 mux clock 2.change fixed pll callback Read only to R/W Verify: test passed on tm2 ab301 Change-Id: I426d4307f19647afcb0166a23c1988df1b504807 Signed-off-by: Jian Hu <jian.hu@amlogic.com>
Diffstat
-rw-r--r--drivers/amlogic/clk/clkc.h2
-rw-r--r--drivers/amlogic/clk/tl1/tl1.c29
-rw-r--r--drivers/amlogic/clk/tl1/tl1_ao.c2
-rw-r--r--drivers/amlogic/clk/tl1/tl1_clk-pll.c44
-rw-r--r--include/dt-bindings/clock/amlogic,tl1-clkc.h6
5 files changed, 69 insertions, 14 deletions
diff --git a/drivers/amlogic/clk/clkc.h b/drivers/amlogic/clk/clkc.h
index 7deac3e..b23fd61 100644
--- a/drivers/amlogic/clk/clkc.h
+++ b/drivers/amlogic/clk/clkc.h
@@ -53,7 +53,7 @@ struct pll_rate_table {
u16 n;
u16 od;
u16 od2;
- u16 frac;
+ u32 frac;
};
struct fclk_rate_table {
diff --git a/drivers/amlogic/clk/tl1/tl1.c b/drivers/amlogic/clk/tl1/tl1.c
index 86207a9..ee90068 100644
--- a/drivers/amlogic/clk/tl1/tl1.c
+++ b/drivers/amlogic/clk/tl1/tl1.c
@@ -185,6 +185,10 @@ static struct meson_clk_pll tl1_adc_pll = {
};
#endif
+static const struct pll_rate_table tl1_fixed_pll_rate_table[] = {
+ PLL_FRAC_RATE(2000000000ULL, 166, 1, 1, 0, 0x3F15555),
+};
+
static struct meson_clk_pll tl1_fixed_pll = {
.m = {
.reg_off = HHI_FIX_PLL_CNTL0,
@@ -207,12 +211,14 @@ static struct meson_clk_pll tl1_fixed_pll = {
.width = 19,
},
.lock = &clk_lock,
+ .rate_table = tl1_fixed_pll_rate_table,
+ .rate_count = ARRAY_SIZE(tl1_fixed_pll_rate_table),
.hw.init = &(struct clk_init_data){
.name = "fixed_pll",
- .ops = &meson_tl1_pll_ro_ops,
+ .ops = &meson_tl1_pll_ops,
.parent_names = (const char *[]){ "xtal" },
.num_parents = 1,
- .flags = CLK_GET_RATE_NOCACHE,
+ .flags = CLK_GET_RATE_NOCACHE | CLK_IGNORE_UNUSED,
},
};
@@ -676,6 +682,19 @@ static struct clk_gate tl1_clk81 = {
},
};
+static struct clk_mux tl1_switch_clk81 = {
+ .reg = (void *)HHI_MPEG_CLK_CNTL,
+ .mask = 0x1,
+ .shift = 8,
+ .lock = &clk_lock,
+ .hw.init = &(struct clk_init_data){
+ .name = "switch_clk81",
+ .ops = &clk_mux_ops,
+ .parent_names = (const char *[]){ "xtal", "clk81" },
+ .num_parents = 2,
+ },
+};
+
/* Everything Else (EE) domain gates */
/* HHI_GCLK_MPEG0 26 bits valid */
static MESON_GATE_TL1(tl1_ddr, HHI_GCLK_MPEG0, 0);
@@ -881,6 +900,7 @@ static struct clk_hw *tl1_clk_hws[] = {
[CLKID_DSU_PRE_PARENT0] = &tl1_dsu_pre0_clk.hw,
[CLKID_DSU_PRE_CLK] = &tl1_dsu_pre_clk.hw,
[CLKID_DSU_CLK] = &tl1_dsu_clk.hw,
+ [CLKID_SWITCH_CLK81] = &tl1_switch_clk81.hw,
};
/* Convenience tables to populate base addresses in .probe */
@@ -1101,6 +1121,9 @@ static void __init tl1_clkc_init(struct device_node *np)
tl1_dsu_clk.reg = clk_base
+ (unsigned long)tl1_dsu_clk.reg;
+ tl1_switch_clk81.reg = clk_base
+ + (unsigned long)tl1_switch_clk81.reg;
+
/* Populate base address for gates */
for (i = 0; i < ARRAY_SIZE(tl1_clk_gates); i++)
tl1_clk_gates[i]->reg = clk_base +
@@ -1127,6 +1150,8 @@ static void __init tl1_clkc_init(struct device_node *np)
WARN_ON(IS_ERR(clks[clkid]));
}
}
+ clks[CLKID_SWITCH_CLK81] = clk_register(NULL, &tl1_switch_clk81.hw);
+ WARN_ON(IS_ERR(clks[CLKID_SWITCH_CLK81]));
meson_tl1_sdemmc_init();
meson_tl1_media_init();
diff --git a/drivers/amlogic/clk/tl1/tl1_ao.c b/drivers/amlogic/clk/tl1/tl1_ao.c
index b3c099c..ab6bca5 100644
--- a/drivers/amlogic/clk/tl1/tl1_ao.c
+++ b/drivers/amlogic/clk/tl1/tl1_ao.c
@@ -172,7 +172,7 @@ static int tl1_aoclkc_probe(struct platform_device *pdev)
tl1_saradc_div.reg = aoclk_base + (unsigned long)tl1_saradc_div.reg;
tl1_saradc_gate.reg = aoclk_base + (unsigned long)tl1_saradc_gate.reg;
- for (clkid = CLKID_AO_BASE; clkid < NR_CLKS; clkid++) {
+ for (clkid = CLKID_AO_BASE; clkid < CLKID_AO_END; clkid++) {
if (tl1_ao_clk_hws[clkid-CLKID_AO_BASE]) {
clks[clkid] = clk_register(NULL,
tl1_ao_clk_hws[clkid-CLKID_AO_BASE]);
diff --git a/drivers/amlogic/clk/tl1/tl1_clk-pll.c b/drivers/amlogic/clk/tl1/tl1_clk-pll.c
index 69eac78..473e644 100644
--- a/drivers/amlogic/clk/tl1/tl1_clk-pll.c
+++ b/drivers/amlogic/clk/tl1/tl1_clk-pll.c
@@ -55,6 +55,14 @@
#define TL1_SYS_PLL_CNTL4 0x88770290
#define TL1_SYS_PLL_CNTL5 0x39272000
+#define TL1_FIXED_PLL_CNTL0 0xD00104A6
+#define TL1_FIXED_PLL_CNTL1 0x3F15555
+#define TL1_FIXED_PLL_CNTL2 0x00000000
+#define TL1_FIXED_PLL_CNTL3 0x6A285C60
+#define TL1_FIXED_PLL_CNTL4 0x65771290
+#define TL1_FIXED_PLL_CNTL5 0x39272000
+#define TL1_FIXED_PLL_CNTL6 0x56540000
+#define TL1_FIXED_PLL_TST 0xA000004F
#define TL1_GP0_PLL_CNTL1 0x00000000
#define TL1_GP0_PLL_CNTL2 0x00000000
@@ -165,16 +173,20 @@ static long meson_tl1_pll_round_rate(struct clk_hw *hw, unsigned long rate,
for (i = 0; i < pll->rate_count; i++) {
if (rate <= rate_table[i].rate) {
ret_rate = rate_table[i].rate;
- if (!strcmp(clk_hw_get_name(hw), "sys_pll"))
+ if (!strcmp(clk_hw_get_name(hw), "sys_pll")
+ || !strcmp(clk_hw_get_name(hw), "fixed_pll"))
do_div(ret_rate, 1000);
+
return ret_rate;
}
}
/* else return the smallest value */
ret_rate = rate_table[0].rate;
- if (!strcmp(clk_hw_get_name(hw), "sys_pll"))
+ if (!strcmp(clk_hw_get_name(hw), "sys_pll")
+ || !strcmp(clk_hw_get_name(hw), "fixed_pll"))
do_div(ret_rate, 1000);
+
return ret_rate;
}
@@ -223,7 +235,8 @@ static int meson_tl1_pll_set_rate(struct clk_hw *hw, unsigned long rate,
if (parent_rate == 0 || rate == 0)
return -EINVAL;
- if (!strcmp(clk_hw_get_name(hw), "sys_pll"))
+ if (!strcmp(clk_hw_get_name(hw), "sys_pll")
+ || !strcmp(clk_hw_get_name(hw), "fixed_pll"))
rate *= 1000;
old_rate = rate;
@@ -331,14 +344,30 @@ static int meson_tl1_pll_set_rate(struct clk_hw *hw, unsigned long rate,
cntlbase + (unsigned long)(0*4));
writel(TM2_PCIE_PLL_CNTL2_,
cntlbase + (unsigned long)(7*4));
+ } else if (!strcmp(clk_hw_get_name(hw), "fixed_pll")) {
+ writel((readl(cntlbase) | MESON_PLL_RESET)
+ & (~MESON_PLL_ENABLE), cntlbase);
+
+ udelay(100);
+ writel(TL1_FIXED_PLL_CNTL1,
+ cntlbase + (unsigned long)(1*4));
+ writel(TL1_FIXED_PLL_CNTL2,
+ cntlbase + (unsigned long)(2*4));
+ writel(TL1_FIXED_PLL_CNTL3,
+ cntlbase + (unsigned long)(3*4));
+ writel(TL1_FIXED_PLL_CNTL4,
+ cntlbase + (unsigned long)(4*4));
+ writel(TL1_FIXED_PLL_CNTL5,
+ cntlbase + (unsigned long)(5*4));
+ writel(TL1_FIXED_PLL_CNTL6,
+ cntlbase + (unsigned long)(6*4));
+ udelay(10);
} else {
pr_err("%s: %s pll not found!!!\n",
__func__, clk_hw_get_name(hw));
return -EINVAL;
}
- /* when set rate for pcie pll, do not set M/N/OD/frac registers bit */
- if (strcmp(clk_hw_get_name(hw), "pcie_pll")) {
reg = readl(pll->base + p->reg_off);
tmp = rate_set->n;
@@ -379,7 +408,6 @@ static int meson_tl1_pll_set_rate(struct clk_hw *hw, unsigned long rate,
reg = PARM_SET(p->width, p->shift, reg, tmp);
writel(reg, pll->base + p->reg_off);
}
- }
p = &pll->n;
/* PLL reset */
@@ -427,7 +455,8 @@ static int meson_tl1_pll_enable(struct clk_hw *hw)
if (!strcmp(clk_hw_get_name(hw), "gp0_pll")
|| !strcmp(clk_hw_get_name(hw), "gp1_pll")
|| !strcmp(clk_hw_get_name(hw), "hifi_pll")
- || !strcmp(clk_hw_get_name(hw), "sys_pll")) {
+ || !strcmp(clk_hw_get_name(hw), "sys_pll")
+ || !strcmp(clk_hw_get_name(hw), "fixed_pll")) {
void *cntlbase = pll->base + p->reg_off;
if (readl(cntlbase + (unsigned long)(6*4))
@@ -435,7 +464,6 @@ static int meson_tl1_pll_enable(struct clk_hw *hw)
first_set = 0;
}
-
parent = clk_hw_get_parent(hw);
/*First init, just set minimal rate.*/
diff --git a/include/dt-bindings/clock/amlogic,tl1-clkc.h b/include/dt-bindings/clock/amlogic,tl1-clkc.h
index 733d470..a37705b 100644
--- a/include/dt-bindings/clock/amlogic,tl1-clkc.h
+++ b/include/dt-bindings/clock/amlogic,tl1-clkc.h
@@ -161,7 +161,6 @@
#define CLKID_VCLK2_VENCLMMC (GATE_OTHER + 14)
#define CLKID_VCLK2_VENCL (GATE_OTHER + 15)
#define CLKID_VCLK2_OTHER1 (GATE_OTHER + 16)
-
/*HHI_GCLK_OTHER: 0x55*/
#define GATE_AO_BASE (GATE_OTHER + 17)
@@ -298,5 +297,8 @@
#define CLKID_AO_UART2 (CLKID_AO_BASE + 10)
#define CLKID_AO_IR_BLASTER (CLKID_AO_BASE + 11)
#define CLKID_AO_SAR_ADC (CLKID_AO_BASE + 12)
-#define NR_CLKS (CLKID_AO_BASE + 13)
+#define CLKID_AO_END (CLKID_AO_BASE + 13)
+#define CLKID_SWITCH_CLK81 (CLKID_AO_BASE + 13)
+#define NR_CLKS (CLKID_AO_BASE + 14)
+
#endif /* __DT_BINDINGS_TL1_CLKC_H */