summaryrefslogtreecommitdiffstats
path: root/firmware/target/arm/imx233/clkctrl-imx233.c
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/target/arm/imx233/clkctrl-imx233.c')
-rw-r--r--firmware/target/arm/imx233/clkctrl-imx233.c203
1 files changed, 78 insertions, 125 deletions
diff --git a/firmware/target/arm/imx233/clkctrl-imx233.c b/firmware/target/arm/imx233/clkctrl-imx233.c
index cfee4aea37..1553889543 100644
--- a/firmware/target/arm/imx233/clkctrl-imx233.c
+++ b/firmware/target/arm/imx233/clkctrl-imx233.c
@@ -26,9 +26,9 @@
void imx233_clkctrl_enable_xtal(enum imx233_xtal_clk_t xtal_clk, bool enable)
{
if(enable)
- __REG_CLR(HW_CLKCTRL_XTAL) = xtal_clk;
+ HW_CLKCTRL_XTAL_CLR = xtal_clk;
else
- __REG_SET(HW_CLKCTRL_XTAL) = xtal_clk;
+ HW_CLKCTRL_XTAL_SET = xtal_clk;
}
bool imx233_clkctrl_is_xtal_enable(enum imx233_xtal_clk_t clk)
@@ -38,78 +38,49 @@ bool imx233_clkctrl_is_xtal_enable(enum imx233_xtal_clk_t clk)
void imx233_clkctrl_enable_clock(enum imx233_clock_t clk, bool enable)
{
- volatile uint32_t *REG;
+ bool gate = !enable;
switch(clk)
{
- case CLK_PIX: REG = &HW_CLKCTRL_PIX; break;
- case CLK_SSP: REG = &HW_CLKCTRL_SSP; break;
+ case CLK_PIX: BF_WR(CLKCTRL_PIX, CLKGATE, gate); break;
+ case CLK_SSP: BF_WR(CLKCTRL_SSP, CLKGATE, gate); break;
case CLK_PLL:
- {
+ /* pll is a special case */
if(enable)
{
- __REG_SET(HW_CLKCTRL_PLLCTRL0) = HW_CLKCTRL_PLLCTRL0__POWER;
- while(!(HW_CLKCTRL_PLLCTRL1 & HW_CLKCTRL_PLLCTRL1__LOCK));
+ BF_SET(CLKCTRL_PLLCTRL0, POWER);
+ while(!BF_RD(CLKCTRL_PLLCTRL1, LOCK));
}
else
- __REG_CLR(HW_CLKCTRL_PLLCTRL0) = HW_CLKCTRL_PLLCTRL0__POWER;
- return;
- }
- default: return;
- }
-
- /* warning: some registers like HW_CLKCTRL_PIX don't have a CLR/SET variant ! */
- if(enable)
- {
- *REG = (*REG) & ~__CLK_CLKGATE;
- while((*REG) & __CLK_CLKGATE);
- while((*REG) & __CLK_BUSY);
- }
- else
- {
- *REG |= __CLK_CLKGATE;
- while(!((*REG) & __CLK_CLKGATE));
+ BF_CLR(CLKCTRL_PLLCTRL0, POWER);
+ break;
+ default:
+ break;
}
}
bool imx233_clkctrl_is_clock_enabled(enum imx233_clock_t clk)
{
- volatile uint32_t *REG;
switch(clk)
{
- case CLK_PLL: return HW_CLKCTRL_PLLCTRL0 & HW_CLKCTRL_PLLCTRL0__POWER;
- case CLK_PIX: REG = &HW_CLKCTRL_PIX; break;
- case CLK_SSP: REG = &HW_CLKCTRL_SSP; break;
+ case CLK_PLL: return BF_RD(CLKCTRL_PLLCTRL0, POWER);
+ case CLK_PIX: return !BF_RD(CLKCTRL_PIX, CLKGATE);
+ case CLK_SSP: return !BF_RD(CLKCTRL_SSP, CLKGATE);
default: return true;
}
-
- return !((*REG) & __CLK_CLKGATE);
}
void imx233_clkctrl_set_clock_divisor(enum imx233_clock_t clk, int div)
{
- /* warning: some registers like HW_CLKCTRL_PIX don't have a CLR/SET variant ! */
+ /* warning: some registers like HW_CLKCTRL_PIX don't have a CLR/SET variant !
+ * assume that we always derive emi and cpu from ref_XX */
switch(clk)
{
- case CLK_PIX:
- __FIELD_SET(HW_CLKCTRL_PIX, DIV, div);
- break;
- case CLK_SSP:
- __FIELD_SET(HW_CLKCTRL_SSP, DIV, div);
- break;
- case CLK_CPU:
- __FIELD_SET(HW_CLKCTRL_CPU, DIV_CPU, div);
- break;
- case CLK_EMI:
- __FIELD_SET(HW_CLKCTRL_EMI, DIV_EMI, div);
- break;
- case CLK_HBUS:
- /* disable frac enable at the same time */
- HW_CLKCTRL_HBUS = div << HW_CLKCTRL_HBUS__DIV_BP |
- (HW_CLKCTRL_HBUS & ~(HW_CLKCTRL_HBUS__DIV_FRAC_EN | HW_CLKCTRL_HBUS__DIV_BM));
- break;
- case CLK_XBUS:
- __FIELD_SET(HW_CLKCTRL_XBUS, DIV, div);
- break;
+ case CLK_PIX: BF_WR(CLKCTRL_PIX, DIV, div); break;
+ case CLK_CPU: BF_WR(CLKCTRL_CPU, DIV_CPU, div); break;
+ case CLK_EMI: BF_WR(CLKCTRL_EMI, DIV_EMI, div); break;
+ case CLK_SSP: BF_WR(CLKCTRL_SSP, DIV, div); break;
+ case CLK_HBUS: BF_WR(CLKCTRL_HBUS, DIV, div); break;
+ case CLK_XBUS: BF_WR(CLKCTRL_XBUS, DIV, div); break;
default: return;
}
}
@@ -118,66 +89,54 @@ int imx233_clkctrl_get_clock_divisor(enum imx233_clock_t clk)
{
switch(clk)
{
- case CLK_PIX: return __XTRACT(HW_CLKCTRL_PIX, DIV);
- case CLK_SSP: return __XTRACT(HW_CLKCTRL_SSP, DIV);
- case CLK_CPU: return __XTRACT(HW_CLKCTRL_CPU, DIV_CPU);
- case CLK_EMI: return __XTRACT(HW_CLKCTRL_EMI, DIV_EMI);
- case CLK_HBUS:
- if(HW_CLKCTRL_HBUS & HW_CLKCTRL_HBUS__DIV_FRAC_EN)
- return 0;
- else
- return __XTRACT(HW_CLKCTRL_HBUS, DIV);
- case CLK_XBUS: return __XTRACT(HW_CLKCTRL_XBUS, DIV);
+ case CLK_PIX: return BF_RD(CLKCTRL_PIX, DIV);
+ case CLK_CPU: return BF_RD(CLKCTRL_CPU, DIV_CPU);
+ case CLK_EMI: return BF_RD(CLKCTRL_EMI, DIV_EMI);
+ case CLK_SSP: return BF_RD(CLKCTRL_SSP, DIV);
+ case CLK_HBUS: return BF_RD(CLKCTRL_HBUS, DIV);
+ case CLK_XBUS: return BF_RD(CLKCTRL_XBUS, DIV);
default: return 0;
}
}
void imx233_clkctrl_set_fractional_divisor(enum imx233_clock_t clk, int fracdiv)
{
- /* NOTE: HW_CLKCTRL_FRAC only support byte access ! */
- volatile uint8_t *REG;
+#define handle_frac(dev) \
+ case CLK_##dev: \
+ if(fracdiv == 0) \
+ BF_SET(CLKCTRL_FRAC, CLKGATE##dev); \
+ else { \
+ BF_WR(CLKCTRL_FRAC, dev##FRAC, fracdiv); \
+ BF_CLR(CLKCTRL_FRAC, CLKGATE##dev); } \
+ break;
switch(clk)
{
- case CLK_HBUS:
- /* set frac enable at the same time */
- HW_CLKCTRL_HBUS = fracdiv << HW_CLKCTRL_HBUS__DIV_BP | HW_CLKCTRL_HBUS__DIV_FRAC_EN |
- (HW_CLKCTRL_HBUS & ~HW_CLKCTRL_HBUS__DIV_BM);
- return;
- case CLK_PIX: REG = &HW_CLKCTRL_FRAC_PIX; break;
- case CLK_IO: REG = &HW_CLKCTRL_FRAC_IO; break;
- case CLK_CPU: REG = &HW_CLKCTRL_FRAC_CPU; break;
- case CLK_EMI: REG = &HW_CLKCTRL_FRAC_EMI; break;
- default: return;
+ handle_frac(PIX)
+ handle_frac(IO)
+ handle_frac(CPU)
+ handle_frac(EMI)
+ default: break;
}
-
- if(fracdiv != 0)
- *REG = fracdiv;
- else
- *REG = HW_CLKCTRL_FRAC_XX__CLKGATEXX;
+#undef handle_frac
}
int imx233_clkctrl_get_fractional_divisor(enum imx233_clock_t clk)
{
- /* NOTE: HW_CLKCTRL_FRAC only support byte access ! */
- volatile uint8_t *REG;
+#define handle_frac(dev) \
+ case CLK_##dev:\
+ if(BF_RD(CLKCTRL_FRAC, CLKGATE##dev)) \
+ return 0; \
+ else \
+ return BF_RD(CLKCTRL_FRAC, dev##FRAC);
switch(clk)
{
- case CLK_HBUS:
- if(HW_CLKCTRL_HBUS & HW_CLKCTRL_HBUS__DIV_FRAC_EN)
- return __XTRACT(HW_CLKCTRL_HBUS, DIV);
- else
- return 0;
- case CLK_PIX: REG = &HW_CLKCTRL_FRAC_PIX; break;
- case CLK_IO: REG = &HW_CLKCTRL_FRAC_IO; break;
- case CLK_CPU: REG = &HW_CLKCTRL_FRAC_CPU; break;
- case CLK_EMI: REG = &HW_CLKCTRL_FRAC_EMI; break;
+ handle_frac(PIX)
+ handle_frac(IO)
+ handle_frac(CPU)
+ handle_frac(EMI)
default: return 0;
}
-
- if((*REG) & HW_CLKCTRL_FRAC_XX__CLKGATEXX)
- return 0;
- else
- return *REG & ~HW_CLKCTRL_FRAC_XX__XX_STABLE;
+#undef handle_frac
}
void imx233_clkctrl_set_bypass_pll(enum imx233_clock_t clk, bool bypass)
@@ -185,45 +144,42 @@ void imx233_clkctrl_set_bypass_pll(enum imx233_clock_t clk, bool bypass)
uint32_t msk;
switch(clk)
{
- case CLK_PIX: msk = HW_CLKCTRL_CLKSEQ__BYPASS_PIX; break;
- case CLK_SSP: msk = HW_CLKCTRL_CLKSEQ__BYPASS_SSP; break;
- case CLK_CPU: msk = HW_CLKCTRL_CLKSEQ__BYPASS_CPU; break;
- case CLK_EMI: msk = HW_CLKCTRL_CLKSEQ__BYPASS_EMI; break;
+ case CLK_PIX: msk = BM_CLKCTRL_CLKSEQ_BYPASS_PIX; break;
+ case CLK_SSP: msk = BM_CLKCTRL_CLKSEQ_BYPASS_SSP; break;
+ case CLK_CPU: msk = BM_CLKCTRL_CLKSEQ_BYPASS_CPU; break;
+ case CLK_EMI: msk = BM_CLKCTRL_CLKSEQ_BYPASS_EMI; break;
default: return;
}
if(bypass)
- __REG_SET(HW_CLKCTRL_CLKSEQ) = msk;
+ HW_CLKCTRL_CLKSEQ_SET = msk;
else
- __REG_CLR(HW_CLKCTRL_CLKSEQ) = msk;
+ HW_CLKCTRL_CLKSEQ_CLR = msk;
}
bool imx233_clkctrl_get_bypass_pll(enum imx233_clock_t clk)
{
- uint32_t msk;
switch(clk)
{
- case CLK_PIX: msk = HW_CLKCTRL_CLKSEQ__BYPASS_PIX; break;
- case CLK_SSP: msk = HW_CLKCTRL_CLKSEQ__BYPASS_SSP; break;
- case CLK_CPU: msk = HW_CLKCTRL_CLKSEQ__BYPASS_CPU; break;
- case CLK_EMI: msk = HW_CLKCTRL_CLKSEQ__BYPASS_EMI; break;
+ case CLK_PIX: return BF_RD(CLKCTRL_CLKSEQ, BYPASS_PIX);
+ case CLK_SSP: return BF_RD(CLKCTRL_CLKSEQ, BYPASS_SSP);
+ case CLK_CPU: return BF_RD(CLKCTRL_CLKSEQ, BYPASS_CPU);
+ case CLK_EMI: return BF_RD(CLKCTRL_CLKSEQ, BYPASS_EMI);
default: return false;
}
-
- return HW_CLKCTRL_CLKSEQ & msk;
}
void imx233_clkctrl_enable_usb_pll(bool enable)
{
if(enable)
- __REG_SET(HW_CLKCTRL_PLLCTRL0) = HW_CLKCTRL_PLLCTRL0__EN_USB_CLKS;
+ BF_SET(CLKCTRL_PLLCTRL0, EN_USB_CLKS);
else
- __REG_CLR(HW_CLKCTRL_PLLCTRL0) = HW_CLKCTRL_PLLCTRL0__EN_USB_CLKS;
+ BF_CLR(CLKCTRL_PLLCTRL0, EN_USB_CLKS);
}
bool imx233_clkctrl_is_usb_pll_enabled(void)
{
- return HW_CLKCTRL_PLLCTRL0 & HW_CLKCTRL_PLLCTRL0__EN_USB_CLKS;
+ return BF_RD(CLKCTRL_PLLCTRL0, EN_USB_CLKS);
}
void imx233_clkctrl_set_auto_slow_divisor(enum imx233_as_div_t div)
@@ -231,34 +187,31 @@ void imx233_clkctrl_set_auto_slow_divisor(enum imx233_as_div_t div)
/* the SLOW_DIV must only be set when auto-slow is disabled */
bool old_status = imx233_clkctrl_is_auto_slow_enabled();
imx233_clkctrl_enable_auto_slow(false);
- __FIELD_SET(HW_CLKCTRL_HBUS, SLOW_DIV, div);
+ BF_WR(CLKCTRL_HBUS, SLOW_DIV, div);
imx233_clkctrl_enable_auto_slow(old_status);
}
enum imx233_as_div_t imx233_clkctrl_get_auto_slow_divisor(void)
{
- return __XTRACT(HW_CLKCTRL_HBUS, SLOW_DIV);
+ return BF_RD(CLKCTRL_HBUS, SLOW_DIV);
}
void imx233_clkctrl_enable_auto_slow(bool enable)
{
- if(enable)
- __REG_SET(HW_CLKCTRL_HBUS) = HW_CLKCTRL_HBUS__AUTO_SLOW_MODE;
- else
- __REG_CLR(HW_CLKCTRL_HBUS) = HW_CLKCTRL_HBUS__AUTO_SLOW_MODE;
+ BF_WR(CLKCTRL_HBUS, AUTO_SLOW_MODE, enable);
}
bool imx233_clkctrl_is_auto_slow_enabled(void)
{
- return HW_CLKCTRL_HBUS & HW_CLKCTRL_HBUS__AUTO_SLOW_MODE;
+ return BF_RD(CLKCTRL_HBUS, AUTO_SLOW_MODE);
}
void imx233_clkctrl_enable_auto_slow_monitor(enum imx233_as_monitor_t monitor, bool enable)
{
if(enable)
- __REG_SET(HW_CLKCTRL_HBUS) = monitor;
+ HW_CLKCTRL_HBUS_SET = monitor;
else
- __REG_CLR(HW_CLKCTRL_HBUS) = monitor;
+ HW_CLKCTRL_HBUS_CLR = monitor;
}
bool imx233_clkctrl_is_auto_slow_monitor_enabled(enum imx233_as_monitor_t monitor)
@@ -268,7 +221,7 @@ bool imx233_clkctrl_is_auto_slow_monitor_enabled(enum imx233_as_monitor_t monito
bool imx233_clkctrl_is_emi_sync_enabled(void)
{
- return !!(HW_CLKCTRL_EMI & HW_CLKCTRL_EMI__SYNC_MODE_EN);
+ return BF_RD(CLKCTRL_EMI, SYNC_MODE_EN);
}
unsigned imx233_clkctrl_get_clock_freq(enum imx233_clock_t clk)
@@ -289,9 +242,9 @@ unsigned imx233_clkctrl_get_clock_freq(enum imx233_clock_t clk)
{
ref = imx233_clkctrl_get_clock_freq(CLK_XTAL);
/* Integer divide mode vs fractional divide mode */
- if(HW_CLKCTRL_CPU & HW_CLKCTRL_CPU__DIV_XTAL_FRAC_EN)
+ if(BF_RD(CLKCTRL_CPU, DIV_XTAL_FRAC_EN))
- return (ref * __XTRACT(HW_CLKCTRL_CPU, DIV_XTAL)) / 32;
+ return (ref * BF_RD(CLKCTRL_CPU, DIV_XTAL)) / 32;
else
return ref / imx233_clkctrl_get_clock_divisor(CLK_CPU);
}
@@ -357,10 +310,10 @@ unsigned imx233_clkctrl_get_clock_freq(enum imx233_clock_t clk)
if(imx233_clkctrl_get_bypass_pll(CLK_EMI))
{
ref = imx233_clkctrl_get_clock_freq(CLK_XTAL);
- if(HW_CLKCTRL_EMI & HW_CLKCTRL_EMI__CLKGATE)
+ if(BF_RD(CLKCTRL_EMI, CLKGATE))
return 0;
else
- return ref / __XTRACT(HW_CLKCTRL_EMI, DIV_XTAL);
+ return ref / BF_RD(CLKCTRL_EMI, DIV_XTAL);
}
else
{