aboutsummaryrefslogtreecommitdiffstats
path: root/target/linux/ipq806x/patches/0128-clk-qcom-Add-support-for-banked-MD-RCGs.patch
diff options
context:
space:
mode:
Diffstat (limited to 'target/linux/ipq806x/patches/0128-clk-qcom-Add-support-for-banked-MD-RCGs.patch')
-rw-r--r--target/linux/ipq806x/patches/0128-clk-qcom-Add-support-for-banked-MD-RCGs.patch317
1 files changed, 317 insertions, 0 deletions
diff --git a/target/linux/ipq806x/patches/0128-clk-qcom-Add-support-for-banked-MD-RCGs.patch b/target/linux/ipq806x/patches/0128-clk-qcom-Add-support-for-banked-MD-RCGs.patch
new file mode 100644
index 0000000000..0b9e237c71
--- /dev/null
+++ b/target/linux/ipq806x/patches/0128-clk-qcom-Add-support-for-banked-MD-RCGs.patch
@@ -0,0 +1,317 @@
+From 856324d2daa3246ac62d7920d6a274e1fa35bcf5 Mon Sep 17 00:00:00 2001
+From: Stephen Boyd <sboyd@codeaurora.org>
+Date: Mon, 28 Apr 2014 15:59:16 -0700
+Subject: [PATCH 128/182] clk: qcom: Add support for banked MD RCGs
+
+The banked MD RCGs in global clock control have a different
+register layout than the ones implemented in multimedia clock
+control. Add support for these types of clocks so we can change
+the rates of the UBI32 clocks.
+
+Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
+---
+ drivers/clk/qcom/clk-rcg.c | 99 ++++++++++++++++++++-------------------
+ drivers/clk/qcom/clk-rcg.h | 5 +-
+ drivers/clk/qcom/mmcc-msm8960.c | 24 +++++++---
+ 3 files changed, 73 insertions(+), 55 deletions(-)
+
+diff --git a/drivers/clk/qcom/clk-rcg.c b/drivers/clk/qcom/clk-rcg.c
+index abfc2b6..7bce729 100644
+--- a/drivers/clk/qcom/clk-rcg.c
++++ b/drivers/clk/qcom/clk-rcg.c
+@@ -67,16 +67,16 @@ static u8 clk_dyn_rcg_get_parent(struct clk_hw *hw)
+ {
+ struct clk_dyn_rcg *rcg = to_clk_dyn_rcg(hw);
+ int num_parents = __clk_get_num_parents(hw->clk);
+- u32 ns, ctl;
++ u32 ns, reg;
+ int bank;
+ int i;
+ struct src_sel *s;
+
+- regmap_read(rcg->clkr.regmap, rcg->clkr.enable_reg, &ctl);
+- bank = reg_to_bank(rcg, ctl);
++ regmap_read(rcg->clkr.regmap, rcg->bank_reg, &reg);
++ bank = reg_to_bank(rcg, reg);
+ s = &rcg->s[bank];
+
+- regmap_read(rcg->clkr.regmap, rcg->ns_reg, &ns);
++ regmap_read(rcg->clkr.regmap, rcg->ns_reg[bank], &ns);
+ ns = ns_to_src(s, ns);
+
+ for (i = 0; i < num_parents; i++)
+@@ -192,90 +192,93 @@ static u32 mn_to_reg(struct mn *mn, u32 m, u32 n, u32 val)
+
+ static void configure_bank(struct clk_dyn_rcg *rcg, const struct freq_tbl *f)
+ {
+- u32 ns, md, ctl, *regp;
++ u32 ns, md, reg;
+ int bank, new_bank;
+ struct mn *mn;
+ struct pre_div *p;
+ struct src_sel *s;
+ bool enabled;
+- u32 md_reg;
+- u32 bank_reg;
++ u32 md_reg, ns_reg;
+ bool banked_mn = !!rcg->mn[1].width;
++ bool banked_p = !!rcg->p[1].pre_div_width;
+ struct clk_hw *hw = &rcg->clkr.hw;
+
+ enabled = __clk_is_enabled(hw->clk);
+
+- regmap_read(rcg->clkr.regmap, rcg->ns_reg, &ns);
+- regmap_read(rcg->clkr.regmap, rcg->clkr.enable_reg, &ctl);
+-
+- if (banked_mn) {
+- regp = &ctl;
+- bank_reg = rcg->clkr.enable_reg;
+- } else {
+- regp = &ns;
+- bank_reg = rcg->ns_reg;
+- }
+-
+- bank = reg_to_bank(rcg, *regp);
++ regmap_read(rcg->clkr.regmap, rcg->bank_reg, &reg);
++ bank = reg_to_bank(rcg, reg);
+ new_bank = enabled ? !bank : bank;
+
++ ns_reg = rcg->ns_reg[new_bank];
++ regmap_read(rcg->clkr.regmap, ns_reg, &ns);
++
+ if (banked_mn) {
+ mn = &rcg->mn[new_bank];
+ md_reg = rcg->md_reg[new_bank];
+
+ ns |= BIT(mn->mnctr_reset_bit);
+- regmap_write(rcg->clkr.regmap, rcg->ns_reg, ns);
++ regmap_write(rcg->clkr.regmap, ns_reg, ns);
+
+ regmap_read(rcg->clkr.regmap, md_reg, &md);
+ md = mn_to_md(mn, f->m, f->n, md);
+ regmap_write(rcg->clkr.regmap, md_reg, md);
+
+ ns = mn_to_ns(mn, f->m, f->n, ns);
+- regmap_write(rcg->clkr.regmap, rcg->ns_reg, ns);
++ regmap_write(rcg->clkr.regmap, ns_reg, ns);
+
+- ctl = mn_to_reg(mn, f->m, f->n, ctl);
+- regmap_write(rcg->clkr.regmap, rcg->clkr.enable_reg, ctl);
++ /* Two NS registers means mode control is in NS register */
++ if (rcg->ns_reg[0] != rcg->ns_reg[1]) {
++ ns = mn_to_reg(mn, f->m, f->n, ns);
++ regmap_write(rcg->clkr.regmap, ns_reg, ns);
++ } else {
++ reg = mn_to_reg(mn, f->m, f->n, reg);
++ regmap_write(rcg->clkr.regmap, rcg->bank_reg, reg);
++ }
+
+ ns &= ~BIT(mn->mnctr_reset_bit);
+- regmap_write(rcg->clkr.regmap, rcg->ns_reg, ns);
+- } else {
++ regmap_write(rcg->clkr.regmap, ns_reg, ns);
++ }
++
++ if (banked_p) {
+ p = &rcg->p[new_bank];
+ ns = pre_div_to_ns(p, f->pre_div - 1, ns);
+ }
+
+ s = &rcg->s[new_bank];
+ ns = src_to_ns(s, s->parent_map[f->src], ns);
+- regmap_write(rcg->clkr.regmap, rcg->ns_reg, ns);
++ regmap_write(rcg->clkr.regmap, ns_reg, ns);
+
+ if (enabled) {
+- *regp ^= BIT(rcg->mux_sel_bit);
+- regmap_write(rcg->clkr.regmap, bank_reg, *regp);
++ regmap_read(rcg->clkr.regmap, rcg->bank_reg, &reg);
++ reg ^= BIT(rcg->mux_sel_bit);
++ regmap_write(rcg->clkr.regmap, rcg->bank_reg, reg);
+ }
+ }
+
+ static int clk_dyn_rcg_set_parent(struct clk_hw *hw, u8 index)
+ {
+ struct clk_dyn_rcg *rcg = to_clk_dyn_rcg(hw);
+- u32 ns, ctl, md, reg;
++ u32 ns, md, reg;
+ int bank;
+ struct freq_tbl f = { 0 };
+ bool banked_mn = !!rcg->mn[1].width;
++ bool banked_p = !!rcg->p[1].pre_div_width;
+
+- regmap_read(rcg->clkr.regmap, rcg->ns_reg, &ns);
+- regmap_read(rcg->clkr.regmap, rcg->clkr.enable_reg, &ctl);
+- reg = banked_mn ? ctl : ns;
+-
++ regmap_read(rcg->clkr.regmap, rcg->bank_reg, &reg);
+ bank = reg_to_bank(rcg, reg);
+
++ regmap_read(rcg->clkr.regmap, rcg->ns_reg[bank], &ns);
++
+ if (banked_mn) {
+ regmap_read(rcg->clkr.regmap, rcg->md_reg[bank], &md);
+ f.m = md_to_m(&rcg->mn[bank], md);
+ f.n = ns_m_to_n(&rcg->mn[bank], ns, f.m);
+- } else {
+- f.pre_div = ns_to_pre_div(&rcg->p[bank], ns) + 1;
+ }
+- f.src = index;
+
++ if (banked_p)
++ f.pre_div = ns_to_pre_div(&rcg->p[bank], ns) + 1;
++
++ f.src = index;
+ configure_bank(rcg, &f);
+
+ return 0;
+@@ -336,28 +339,30 @@ clk_dyn_rcg_recalc_rate(struct clk_hw *hw, unsigned long parent_rate)
+ u32 m, n, pre_div, ns, md, mode, reg;
+ int bank;
+ struct mn *mn;
++ bool banked_p = !!rcg->p[1].pre_div_width;
+ bool banked_mn = !!rcg->mn[1].width;
+
+- regmap_read(rcg->clkr.regmap, rcg->ns_reg, &ns);
+-
+- if (banked_mn)
+- regmap_read(rcg->clkr.regmap, rcg->clkr.enable_reg, &reg);
+- else
+- reg = ns;
+-
++ regmap_read(rcg->clkr.regmap, rcg->bank_reg, &reg);
+ bank = reg_to_bank(rcg, reg);
+
++ regmap_read(rcg->clkr.regmap, rcg->ns_reg[bank], &ns);
++ m = n = pre_div = mode = 0;
++
+ if (banked_mn) {
+ mn = &rcg->mn[bank];
+ regmap_read(rcg->clkr.regmap, rcg->md_reg[bank], &md);
+ m = md_to_m(mn, md);
+ n = ns_m_to_n(mn, ns, m);
++ /* Two NS registers means mode control is in NS register */
++ if (rcg->ns_reg[0] != rcg->ns_reg[1])
++ reg = ns;
+ mode = reg_to_mnctr_mode(mn, reg);
+- return calc_rate(parent_rate, m, n, mode, 0);
+- } else {
+- pre_div = ns_to_pre_div(&rcg->p[bank], ns);
+- return calc_rate(parent_rate, 0, 0, 0, pre_div);
+ }
++
++ if (banked_p)
++ pre_div = ns_to_pre_div(&rcg->p[bank], ns);
++
++ return calc_rate(parent_rate, m, n, mode, pre_div);
+ }
+
+ static const
+diff --git a/drivers/clk/qcom/clk-rcg.h b/drivers/clk/qcom/clk-rcg.h
+index b9ec11d..5f8b06d 100644
+--- a/drivers/clk/qcom/clk-rcg.h
++++ b/drivers/clk/qcom/clk-rcg.h
+@@ -102,7 +102,7 @@ extern const struct clk_ops clk_rcg_ops;
+ * struct clk_dyn_rcg - root clock generator with glitch free mux
+ *
+ * @mux_sel_bit: bit to switch glitch free mux
+- * @ns_reg: NS register
++ * @ns_reg: NS0 and NS1 register
+ * @md_reg: MD0 and MD1 register
+ * @mn: mn counter (banked)
+ * @s: source selector (banked)
+@@ -112,8 +112,9 @@ extern const struct clk_ops clk_rcg_ops;
+ *
+ */
+ struct clk_dyn_rcg {
+- u32 ns_reg;
++ u32 ns_reg[2];
+ u32 md_reg[2];
++ u32 bank_reg;
+
+ u8 mux_sel_bit;
+
+diff --git a/drivers/clk/qcom/mmcc-msm8960.c b/drivers/clk/qcom/mmcc-msm8960.c
+index 12f3c0b..ce48ad1 100644
+--- a/drivers/clk/qcom/mmcc-msm8960.c
++++ b/drivers/clk/qcom/mmcc-msm8960.c
+@@ -726,9 +726,11 @@ static struct freq_tbl clk_tbl_gfx2d[] = {
+ };
+
+ static struct clk_dyn_rcg gfx2d0_src = {
+- .ns_reg = 0x0070,
++ .ns_reg[0] = 0x0070,
++ .ns_reg[1] = 0x0070,
+ .md_reg[0] = 0x0064,
+ .md_reg[1] = 0x0068,
++ .bank_reg = 0x0060,
+ .mn[0] = {
+ .mnctr_en_bit = 8,
+ .mnctr_reset_bit = 25,
+@@ -784,9 +786,11 @@ static struct clk_branch gfx2d0_clk = {
+ };
+
+ static struct clk_dyn_rcg gfx2d1_src = {
+- .ns_reg = 0x007c,
++ .ns_reg[0] = 0x007c,
++ .ns_reg[1] = 0x007c,
+ .md_reg[0] = 0x0078,
+ .md_reg[1] = 0x006c,
++ .bank_reg = 0x0074,
+ .mn[0] = {
+ .mnctr_en_bit = 8,
+ .mnctr_reset_bit = 25,
+@@ -862,9 +866,11 @@ static struct freq_tbl clk_tbl_gfx3d[] = {
+ };
+
+ static struct clk_dyn_rcg gfx3d_src = {
+- .ns_reg = 0x008c,
++ .ns_reg[0] = 0x008c,
++ .ns_reg[1] = 0x008c,
+ .md_reg[0] = 0x0084,
+ .md_reg[1] = 0x0088,
++ .bank_reg = 0x0080,
+ .mn[0] = {
+ .mnctr_en_bit = 8,
+ .mnctr_reset_bit = 25,
+@@ -1051,9 +1057,11 @@ static struct freq_tbl clk_tbl_mdp[] = {
+ };
+
+ static struct clk_dyn_rcg mdp_src = {
+- .ns_reg = 0x00d0,
++ .ns_reg[0] = 0x00d0,
++ .ns_reg[1] = 0x00d0,
+ .md_reg[0] = 0x00c4,
+ .md_reg[1] = 0x00c8,
++ .bank_reg = 0x00c0,
+ .mn[0] = {
+ .mnctr_en_bit = 8,
+ .mnctr_reset_bit = 31,
+@@ -1158,7 +1166,9 @@ static struct freq_tbl clk_tbl_rot[] = {
+ };
+
+ static struct clk_dyn_rcg rot_src = {
+- .ns_reg = 0x00e8,
++ .ns_reg[0] = 0x00e8,
++ .ns_reg[1] = 0x00e8,
++ .bank_reg = 0x00e8,
+ .p[0] = {
+ .pre_div_shift = 22,
+ .pre_div_width = 4,
+@@ -1355,9 +1365,11 @@ static struct freq_tbl clk_tbl_vcodec[] = {
+ };
+
+ static struct clk_dyn_rcg vcodec_src = {
+- .ns_reg = 0x0100,
++ .ns_reg[0] = 0x0100,
++ .ns_reg[1] = 0x0100,
+ .md_reg[0] = 0x00fc,
+ .md_reg[1] = 0x0128,
++ .bank_reg = 0x00f8,
+ .mn[0] = {
+ .mnctr_en_bit = 5,
+ .mnctr_reset_bit = 31,
+--
+1.7.10.4
+