diff options
| -rw-r--r-- | arch/arm/mach-imx/clk-pllv2.c | 93 | ||||
| -rw-r--r-- | arch/arm/mach-imx/crm-regs-imx5.h | 2 |
2 files changed, 56 insertions, 39 deletions
diff --git a/arch/arm/mach-imx/clk-pllv2.c b/arch/arm/mach-imx/clk-pllv2.c index 4685919deb63..0440379e3628 100644 --- a/arch/arm/mach-imx/clk-pllv2.c +++ b/arch/arm/mach-imx/clk-pllv2.c | |||
| @@ -74,30 +74,15 @@ struct clk_pllv2 { | |||
| 74 | void __iomem *base; | 74 | void __iomem *base; |
| 75 | }; | 75 | }; |
| 76 | 76 | ||
| 77 | static unsigned long clk_pllv2_recalc_rate(struct clk_hw *hw, | 77 | static unsigned long __clk_pllv2_recalc_rate(unsigned long parent_rate, |
| 78 | unsigned long parent_rate) | 78 | u32 dp_ctl, u32 dp_op, u32 dp_mfd, u32 dp_mfn) |
| 79 | { | 79 | { |
| 80 | long mfi, mfn, mfd, pdf, ref_clk, mfn_abs; | 80 | long mfi, mfn, mfd, pdf, ref_clk, mfn_abs; |
| 81 | unsigned long dp_op, dp_mfd, dp_mfn, dp_ctl, pll_hfsm, dbl; | 81 | unsigned long dbl; |
| 82 | void __iomem *pllbase; | ||
| 83 | s64 temp; | 82 | s64 temp; |
| 84 | struct clk_pllv2 *pll = to_clk_pllv2(hw); | ||
| 85 | |||
| 86 | pllbase = pll->base; | ||
| 87 | 83 | ||
| 88 | dp_ctl = __raw_readl(pllbase + MXC_PLL_DP_CTL); | ||
| 89 | pll_hfsm = dp_ctl & MXC_PLL_DP_CTL_HFSM; | ||
| 90 | dbl = dp_ctl & MXC_PLL_DP_CTL_DPDCK0_2_EN; | 84 | dbl = dp_ctl & MXC_PLL_DP_CTL_DPDCK0_2_EN; |
| 91 | 85 | ||
| 92 | if (pll_hfsm == 0) { | ||
| 93 | dp_op = __raw_readl(pllbase + MXC_PLL_DP_OP); | ||
| 94 | dp_mfd = __raw_readl(pllbase + MXC_PLL_DP_MFD); | ||
| 95 | dp_mfn = __raw_readl(pllbase + MXC_PLL_DP_MFN); | ||
| 96 | } else { | ||
| 97 | dp_op = __raw_readl(pllbase + MXC_PLL_DP_HFS_OP); | ||
| 98 | dp_mfd = __raw_readl(pllbase + MXC_PLL_DP_HFS_MFD); | ||
| 99 | dp_mfn = __raw_readl(pllbase + MXC_PLL_DP_HFS_MFN); | ||
| 100 | } | ||
| 101 | pdf = dp_op & MXC_PLL_DP_OP_PDF_MASK; | 86 | pdf = dp_op & MXC_PLL_DP_OP_PDF_MASK; |
| 102 | mfi = (dp_op & MXC_PLL_DP_OP_MFI_MASK) >> MXC_PLL_DP_OP_MFI_OFFSET; | 87 | mfi = (dp_op & MXC_PLL_DP_OP_MFI_MASK) >> MXC_PLL_DP_OP_MFI_OFFSET; |
| 103 | mfi = (mfi <= 5) ? 5 : mfi; | 88 | mfi = (mfi <= 5) ? 5 : mfi; |
| @@ -123,18 +108,30 @@ static unsigned long clk_pllv2_recalc_rate(struct clk_hw *hw, | |||
| 123 | return temp; | 108 | return temp; |
| 124 | } | 109 | } |
| 125 | 110 | ||
| 126 | static int clk_pllv2_set_rate(struct clk_hw *hw, unsigned long rate, | 111 | static unsigned long clk_pllv2_recalc_rate(struct clk_hw *hw, |
| 127 | unsigned long parent_rate) | 112 | unsigned long parent_rate) |
| 128 | { | 113 | { |
| 114 | u32 dp_op, dp_mfd, dp_mfn, dp_ctl; | ||
| 115 | void __iomem *pllbase; | ||
| 129 | struct clk_pllv2 *pll = to_clk_pllv2(hw); | 116 | struct clk_pllv2 *pll = to_clk_pllv2(hw); |
| 117 | |||
| 118 | pllbase = pll->base; | ||
| 119 | |||
| 120 | dp_ctl = __raw_readl(pllbase + MXC_PLL_DP_CTL); | ||
| 121 | dp_op = __raw_readl(pllbase + MXC_PLL_DP_OP); | ||
| 122 | dp_mfd = __raw_readl(pllbase + MXC_PLL_DP_MFD); | ||
| 123 | dp_mfn = __raw_readl(pllbase + MXC_PLL_DP_MFN); | ||
| 124 | |||
| 125 | return __clk_pllv2_recalc_rate(parent_rate, dp_ctl, dp_op, dp_mfd, dp_mfn); | ||
| 126 | } | ||
| 127 | |||
| 128 | static int __clk_pllv2_set_rate(unsigned long rate, unsigned long parent_rate, | ||
| 129 | u32 *dp_op, u32 *dp_mfd, u32 *dp_mfn) | ||
| 130 | { | ||
| 130 | u32 reg; | 131 | u32 reg; |
| 131 | void __iomem *pllbase; | ||
| 132 | long mfi, pdf, mfn, mfd = 999999; | 132 | long mfi, pdf, mfn, mfd = 999999; |
| 133 | s64 temp64; | 133 | s64 temp64; |
| 134 | unsigned long quad_parent_rate; | 134 | unsigned long quad_parent_rate; |
| 135 | unsigned long pll_hfsm, dp_ctl; | ||
| 136 | |||
| 137 | pllbase = pll->base; | ||
| 138 | 135 | ||
| 139 | quad_parent_rate = 4 * parent_rate; | 136 | quad_parent_rate = 4 * parent_rate; |
| 140 | pdf = mfi = -1; | 137 | pdf = mfi = -1; |
| @@ -144,25 +141,41 @@ static int clk_pllv2_set_rate(struct clk_hw *hw, unsigned long rate, | |||
| 144 | return -EINVAL; | 141 | return -EINVAL; |
| 145 | pdf--; | 142 | pdf--; |
| 146 | 143 | ||
| 147 | temp64 = rate * (pdf+1) - quad_parent_rate * mfi; | 144 | temp64 = rate * (pdf + 1) - quad_parent_rate * mfi; |
| 148 | do_div(temp64, quad_parent_rate/1000000); | 145 | do_div(temp64, quad_parent_rate / 1000000); |
| 149 | mfn = (long)temp64; | 146 | mfn = (long)temp64; |
| 150 | 147 | ||
| 148 | reg = mfi << 4 | pdf; | ||
| 149 | |||
| 150 | *dp_op = reg; | ||
| 151 | *dp_mfd = mfd; | ||
| 152 | *dp_mfn = mfn; | ||
| 153 | |||
| 154 | return 0; | ||
| 155 | } | ||
| 156 | |||
| 157 | static int clk_pllv2_set_rate(struct clk_hw *hw, unsigned long rate, | ||
| 158 | unsigned long parent_rate) | ||
| 159 | { | ||
| 160 | struct clk_pllv2 *pll = to_clk_pllv2(hw); | ||
| 161 | void __iomem *pllbase; | ||
| 162 | u32 dp_ctl, dp_op, dp_mfd, dp_mfn; | ||
| 163 | int ret; | ||
| 164 | |||
| 165 | pllbase = pll->base; | ||
| 166 | |||
| 167 | |||
| 168 | ret = __clk_pllv2_set_rate(rate, parent_rate, &dp_op, &dp_mfd, &dp_mfn); | ||
| 169 | if (ret) | ||
| 170 | return ret; | ||
| 171 | |||
| 151 | dp_ctl = __raw_readl(pllbase + MXC_PLL_DP_CTL); | 172 | dp_ctl = __raw_readl(pllbase + MXC_PLL_DP_CTL); |
| 152 | /* use dpdck0_2 */ | 173 | /* use dpdck0_2 */ |
| 153 | __raw_writel(dp_ctl | 0x1000L, pllbase + MXC_PLL_DP_CTL); | 174 | __raw_writel(dp_ctl | 0x1000L, pllbase + MXC_PLL_DP_CTL); |
| 154 | pll_hfsm = dp_ctl & MXC_PLL_DP_CTL_HFSM; | 175 | |
| 155 | if (pll_hfsm == 0) { | 176 | __raw_writel(dp_op, pllbase + MXC_PLL_DP_OP); |
| 156 | reg = mfi << 4 | pdf; | 177 | __raw_writel(dp_mfd, pllbase + MXC_PLL_DP_MFD); |
| 157 | __raw_writel(reg, pllbase + MXC_PLL_DP_OP); | 178 | __raw_writel(dp_mfn, pllbase + MXC_PLL_DP_MFN); |
| 158 | __raw_writel(mfd, pllbase + MXC_PLL_DP_MFD); | ||
| 159 | __raw_writel(mfn, pllbase + MXC_PLL_DP_MFN); | ||
| 160 | } else { | ||
| 161 | reg = mfi << 4 | pdf; | ||
| 162 | __raw_writel(reg, pllbase + MXC_PLL_DP_HFS_OP); | ||
| 163 | __raw_writel(mfd, pllbase + MXC_PLL_DP_HFS_MFD); | ||
| 164 | __raw_writel(mfn, pllbase + MXC_PLL_DP_HFS_MFN); | ||
| 165 | } | ||
| 166 | 179 | ||
| 167 | return 0; | 180 | return 0; |
| 168 | } | 181 | } |
| @@ -170,7 +183,11 @@ static int clk_pllv2_set_rate(struct clk_hw *hw, unsigned long rate, | |||
| 170 | static long clk_pllv2_round_rate(struct clk_hw *hw, unsigned long rate, | 183 | static long clk_pllv2_round_rate(struct clk_hw *hw, unsigned long rate, |
| 171 | unsigned long *prate) | 184 | unsigned long *prate) |
| 172 | { | 185 | { |
| 173 | return rate; | 186 | u32 dp_op, dp_mfd, dp_mfn; |
| 187 | |||
| 188 | __clk_pllv2_set_rate(rate, *prate, &dp_op, &dp_mfd, &dp_mfn); | ||
| 189 | return __clk_pllv2_recalc_rate(*prate, MXC_PLL_DP_CTL_DPDCK0_2_EN, | ||
| 190 | dp_op, dp_mfd, dp_mfn); | ||
| 174 | } | 191 | } |
| 175 | 192 | ||
| 176 | static int clk_pllv2_prepare(struct clk_hw *hw) | 193 | static int clk_pllv2_prepare(struct clk_hw *hw) |
diff --git a/arch/arm/mach-imx/crm-regs-imx5.h b/arch/arm/mach-imx/crm-regs-imx5.h index 5e11ba7daee2..5e3f1f0f4cab 100644 --- a/arch/arm/mach-imx/crm-regs-imx5.h +++ b/arch/arm/mach-imx/crm-regs-imx5.h | |||
| @@ -23,7 +23,7 @@ | |||
| 23 | #define MX53_DPLL1_BASE MX53_IO_ADDRESS(MX53_PLL1_BASE_ADDR) | 23 | #define MX53_DPLL1_BASE MX53_IO_ADDRESS(MX53_PLL1_BASE_ADDR) |
| 24 | #define MX53_DPLL2_BASE MX53_IO_ADDRESS(MX53_PLL2_BASE_ADDR) | 24 | #define MX53_DPLL2_BASE MX53_IO_ADDRESS(MX53_PLL2_BASE_ADDR) |
| 25 | #define MX53_DPLL3_BASE MX53_IO_ADDRESS(MX53_PLL3_BASE_ADDR) | 25 | #define MX53_DPLL3_BASE MX53_IO_ADDRESS(MX53_PLL3_BASE_ADDR) |
| 26 | #define MX53_DPLL4_BASE MX53_IO_ADDRESS(MX53_PLL3_BASE_ADDR) | 26 | #define MX53_DPLL4_BASE MX53_IO_ADDRESS(MX53_PLL4_BASE_ADDR) |
| 27 | 27 | ||
| 28 | /* PLL Register Offsets */ | 28 | /* PLL Register Offsets */ |
| 29 | #define MXC_PLL_DP_CTL 0x00 | 29 | #define MXC_PLL_DP_CTL 0x00 |
