summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--firmware/target/arm/imx233/clkctrl-imx233.c28
-rw-r--r--firmware/target/arm/imx233/clkctrl-imx233.h2
2 files changed, 27 insertions, 3 deletions
diff --git a/firmware/target/arm/imx233/clkctrl-imx233.c b/firmware/target/arm/imx233/clkctrl-imx233.c
index 59c23c1a76..1a8f523d5a 100644
--- a/firmware/target/arm/imx233/clkctrl-imx233.c
+++ b/firmware/target/arm/imx233/clkctrl-imx233.c
@@ -87,7 +87,9 @@ void imx233_clkctrl_set_div(enum imx233_clock_t clk, int div)
87 case CLK_EMI: BF_WR(CLKCTRL_EMI, DIV(div)); break; 87 case CLK_EMI: BF_WR(CLKCTRL_EMI, DIV(div)); break;
88#endif 88#endif
89 case CLK_SSP: BF_WR(CLKCTRL_SSP, DIV(div)); break; 89 case CLK_SSP: BF_WR(CLKCTRL_SSP, DIV(div)); break;
90 case CLK_HBUS: BF_WR(CLKCTRL_HBUS, DIV(div)); break; 90 case CLK_HBUS:
91 /* make sure to switch to integer divide mode simulteanously */
92 BF_WR(CLKCTRL_HBUS, DIV_FRAC_EN(0), DIV(div)); break;
91 case CLK_XBUS: BF_WR(CLKCTRL_XBUS, DIV(div)); break; 93 case CLK_XBUS: BF_WR(CLKCTRL_XBUS, DIV(div)); break;
92 default: return; 94 default: return;
93 } 95 }
@@ -107,7 +109,12 @@ int imx233_clkctrl_get_div(enum imx233_clock_t clk)
107 case CLK_EMI: return BF_RD(CLKCTRL_EMI, DIV); 109 case CLK_EMI: return BF_RD(CLKCTRL_EMI, DIV);
108#endif 110#endif
109 case CLK_SSP: return BF_RD(CLKCTRL_SSP, DIV); 111 case CLK_SSP: return BF_RD(CLKCTRL_SSP, DIV);
110 case CLK_HBUS: return BF_RD(CLKCTRL_HBUS, DIV); 112 case CLK_HBUS:
113 /* since fractional and integer divider share the same field, clain it is disabled in frac mode */
114 if(BF_RD(CLKCTRL_HBUS, DIV_FRAC_EN))
115 return 0;
116 else
117 return BF_RD(CLKCTRL_HBUS, DIV);
111 case CLK_XBUS: return BF_RD(CLKCTRL_XBUS, DIV); 118 case CLK_XBUS: return BF_RD(CLKCTRL_XBUS, DIV);
112 default: return 0; 119 default: return 0;
113 } 120 }
@@ -130,6 +137,14 @@ void imx233_clkctrl_set_frac_div(enum imx233_clock_t clk, int fracdiv)
130 handle_frac(IO) 137 handle_frac(IO)
131 handle_frac(CPU) 138 handle_frac(CPU)
132 handle_frac(EMI) 139 handle_frac(EMI)
140 case CLK_HBUS:
141 if(fracdiv == 0)
142 panicf("Don't set hbus fracdiv to 0!");
143 /* value 0 is forbidden because we can't simply disabble the divider, it's always
144 * active but either in integer or fractional mode
145 * make sure we write both the value and frac_en bit at the same time */
146 BF_WR(CLKCTRL_HBUS, DIV_FRAC_EN(1), DIV(fracdiv));
147 break;
133 default: break; 148 default: break;
134 } 149 }
135#undef handle_frac 150#undef handle_frac
@@ -151,6 +166,11 @@ int imx233_clkctrl_get_frac_div(enum imx233_clock_t clk)
151 handle_frac(IO) 166 handle_frac(IO)
152 handle_frac(CPU) 167 handle_frac(CPU)
153 handle_frac(EMI) 168 handle_frac(EMI)
169 case CLK_HBUS:
170 if(BF_RD(CLKCTRL_HBUS, DIV_FRAC_EN))
171 return BF_RD(CLKCTRL_HBUS, DIV);
172 else
173 return 0;
154 default: return 0; 174 default: return 0;
155 } 175 }
156#undef handle_frac 176#undef handle_frac
@@ -303,8 +323,12 @@ unsigned imx233_clkctrl_get_freq(enum imx233_clock_t clk)
303 /* Derived from clk_p via integer/fractional div */ 323 /* Derived from clk_p via integer/fractional div */
304 unsigned ref = imx233_clkctrl_get_freq(CLK_CPU); 324 unsigned ref = imx233_clkctrl_get_freq(CLK_CPU);
305#if IMX233_SUBTARGET >= 3700 325#if IMX233_SUBTARGET >= 3700
326 /* if divider is in fractional mode, integer divider does not take effect (in fact it's
327 * the same divider but in a different mode ). Also the fractiona value is encoded as
328 * a fraction, not a divider */
306 if(imx233_clkctrl_get_frac_div(CLK_HBUS) != 0) 329 if(imx233_clkctrl_get_frac_div(CLK_HBUS) != 0)
307 ref = (ref * imx233_clkctrl_get_frac_div(CLK_HBUS)) / 32; 330 ref = (ref * imx233_clkctrl_get_frac_div(CLK_HBUS)) / 32;
331 else
308#endif 332#endif
309 if(imx233_clkctrl_get_div(CLK_HBUS) != 0) 333 if(imx233_clkctrl_get_div(CLK_HBUS) != 0)
310 ref /= imx233_clkctrl_get_div(CLK_HBUS); 334 ref /= imx233_clkctrl_get_div(CLK_HBUS);
diff --git a/firmware/target/arm/imx233/clkctrl-imx233.h b/firmware/target/arm/imx233/clkctrl-imx233.h
index f12d181c50..d150912cfe 100644
--- a/firmware/target/arm/imx233/clkctrl-imx233.h
+++ b/firmware/target/arm/imx233/clkctrl-imx233.h
@@ -68,7 +68,7 @@ int imx233_clkctrl_get_div(enum imx233_clock_t clk);
68#if IMX233_SUBTARGET >= 3700 68#if IMX233_SUBTARGET >= 3700
69/* call with fracdiv=0 to disable it */ 69/* call with fracdiv=0 to disable it */
70void imx233_clkctrl_set_frac_div(enum imx233_clock_t clk, int fracdiv); 70void imx233_clkctrl_set_frac_div(enum imx233_clock_t clk, int fracdiv);
71/* 0 means fractional dividor disable */ 71/* 0 means fractional dividor disabled */
72int imx233_clkctrl_get_frac_div(enum imx233_clock_t clk); 72int imx233_clkctrl_get_frac_div(enum imx233_clock_t clk);
73void imx233_clkctrl_set_bypass(enum imx233_clock_t clk, bool bypass); 73void imx233_clkctrl_set_bypass(enum imx233_clock_t clk, bool bypass);
74bool imx233_clkctrl_get_bypass(enum imx233_clock_t clk); 74bool imx233_clkctrl_get_bypass(enum imx233_clock_t clk);