forked from len0rd/rockbox
imx233: rewrite clkctrl using new register headers
Change-Id: I6c79e99ed4ab20e00c3110d870e144a6c8596769
This commit is contained in:
parent
f545908c16
commit
2a01b3766f
4 changed files with 98 additions and 218 deletions
|
@ -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
|
||||
{
|
||||
|
|
|
@ -25,92 +25,15 @@
|
|||
#include "system.h"
|
||||
#include "cpu.h"
|
||||
|
||||
#define HW_CLKCTRL_BASE 0x80040000
|
||||
|
||||
#define HW_CLKCTRL_PLLCTRL0 (*(volatile uint32_t *)(HW_CLKCTRL_BASE + 0x0))
|
||||
#define HW_CLKCTRL_PLLCTRL0__POWER (1 << 16)
|
||||
#define HW_CLKCTRL_PLLCTRL0__EN_USB_CLKS (1 << 18)
|
||||
#define HW_CLKCTRL_PLLCTRL0__DIV_SEL_BP 20
|
||||
#define HW_CLKCTRL_PLLCTRL0__DIV_SEL_BM (3 << 20)
|
||||
|
||||
#define HW_CLKCTRL_PLLCTRL1 (*(volatile uint32_t *)(HW_CLKCTRL_BASE + 0x10))
|
||||
#define HW_CLKCTRL_PLLCTRL1__LOCK (1 << 31)
|
||||
|
||||
#define HW_CLKCTRL_CPU (*(volatile uint32_t *)(HW_CLKCTRL_BASE + 0x20))
|
||||
#define HW_CLKCTRL_CPU__DIV_CPU_BP 0
|
||||
#define HW_CLKCTRL_CPU__DIV_CPU_BM 0x3f
|
||||
#define HW_CLKCTRL_CPU__INTERRUPT_WAIT (1 << 12)
|
||||
#define HW_CLKCTRL_CPU__DIV_XTAL_BP 16
|
||||
#define HW_CLKCTRL_CPU__DIV_XTAL_BM (0x3ff << 16)
|
||||
#define HW_CLKCTRL_CPU__DIV_XTAL_FRAC_EN (1 << 26)
|
||||
#define HW_CLKCTRL_CPU__BUSY_REF_CPU (1 << 28)
|
||||
|
||||
#define HW_CLKCTRL_HBUS (*(volatile uint32_t *)(HW_CLKCTRL_BASE + 0x30))
|
||||
#define HW_CLKCTRL_HBUS__DIV_BP 0
|
||||
#define HW_CLKCTRL_HBUS__DIV_BM 0x1f
|
||||
#define HW_CLKCTRL_HBUS__DIV_FRAC_EN (1 << 5)
|
||||
#define HW_CLKCTRL_HBUS__SLOW_DIV_BP 16
|
||||
#define HW_CLKCTRL_HBUS__SLOW_DIV_BM (0x7 << 16)
|
||||
#define HW_CLKCTRL_HBUS__AUTO_SLOW_MODE (1 << 20)
|
||||
|
||||
/* warning: this register doesn't have a CLR/SET variant ! */
|
||||
#define HW_CLKCTRL_XBUS (*(volatile uint32_t *)(HW_CLKCTRL_BASE + 0x40))
|
||||
#define HW_CLKCTRL_XBUS__DIV_BP 0
|
||||
#define HW_CLKCTRL_XBUS__DIV_BM 0x3ff
|
||||
#define HW_CLKCTRL_XBUS__BUSY (1 << 31)
|
||||
|
||||
#define HW_CLKCTRL_XTAL (*(volatile uint32_t *)(HW_CLKCTRL_BASE + 0x50))
|
||||
#define HW_CLKCTRL_XTAL__TIMROT_CLK32K_GATE (1 << 26)
|
||||
#define HW_CLKCTRL_XTAL__DRI_CLK24M_GATE (1 << 28)
|
||||
#define HW_CLKCTRL_XTAL__FILT_CLK24M_GATE (1 << 30)
|
||||
|
||||
/* warning: this register doesn't have a CLR/SET variant ! */
|
||||
#define HW_CLKCTRL_PIX (*(volatile uint32_t *)(HW_CLKCTRL_BASE + 0x60))
|
||||
#define HW_CLKCTRL_PIX__DIV_BP 0
|
||||
#define HW_CLKCTRL_PIX__DIV_BM 0xfff
|
||||
|
||||
/* warning: this register doesn't have a CLR/SET variant ! */
|
||||
#define HW_CLKCTRL_SSP (*(volatile uint32_t *)(HW_CLKCTRL_BASE + 0x70))
|
||||
#define HW_CLKCTRL_SSP__DIV_BP 0
|
||||
#define HW_CLKCTRL_SSP__DIV_BM 0x1ff
|
||||
|
||||
/* warning: this register doesn't have a CLR/SET variant ! */
|
||||
#define HW_CLKCTRL_EMI (*(volatile uint32_t *)(HW_CLKCTRL_BASE + 0xa0))
|
||||
#define HW_CLKCTRL_EMI__DIV_EMI_BP 0
|
||||
#define HW_CLKCTRL_EMI__DIV_EMI_BM 0x3f
|
||||
#define HW_CLKCTRL_EMI__DIV_XTAL_BP 8
|
||||
#define HW_CLKCTRL_EMI__DIV_XTAL_BM (0xf << 8)
|
||||
#define HW_CLKCTRL_EMI__BUSY_REF_EMI (1 << 28)
|
||||
#define HW_CLKCTRL_EMI__BUSY_REF_XTAL (1 << 29)
|
||||
#define HW_CLKCTRL_EMI__SYNC_MODE_EN (1 << 30)
|
||||
#define HW_CLKCTRL_EMI__CLKGATE (1 << 31)
|
||||
|
||||
#define HW_CLKCTRL_CLKSEQ (*(volatile uint32_t *)(HW_CLKCTRL_BASE + 0x110))
|
||||
#define HW_CLKCTRL_CLKSEQ__BYPASS_PIX (1 << 1)
|
||||
#define HW_CLKCTRL_CLKSEQ__BYPASS_SSP (1 << 5)
|
||||
#define HW_CLKCTRL_CLKSEQ__BYPASS_EMI (1 << 6)
|
||||
#define HW_CLKCTRL_CLKSEQ__BYPASS_CPU (1 << 7)
|
||||
|
||||
#define HW_CLKCTRL_FRAC (*(volatile uint32_t *)(HW_CLKCTRL_BASE + 0xf0))
|
||||
#define HW_CLKCTRL_FRAC_CPU (*(volatile uint8_t *)(HW_CLKCTRL_BASE + 0xf0))
|
||||
#define HW_CLKCTRL_FRAC_EMI (*(volatile uint8_t *)(HW_CLKCTRL_BASE + 0xf1))
|
||||
#define HW_CLKCTRL_FRAC_PIX (*(volatile uint8_t *)(HW_CLKCTRL_BASE + 0xf2))
|
||||
#define HW_CLKCTRL_FRAC_IO (*(volatile uint8_t *)(HW_CLKCTRL_BASE + 0xf3))
|
||||
#define HW_CLKCTRL_FRAC_XX__XXDIV_BM 0x3f
|
||||
#define HW_CLKCTRL_FRAC_XX__XX_STABLE (1 << 6)
|
||||
#define HW_CLKCTRL_FRAC_XX__CLKGATEXX (1 << 7)
|
||||
|
||||
/* warning: this register doesn't have a CLR/SET variant ! */
|
||||
#define HW_CLKCTRL_RESET (*(volatile uint32_t *)(HW_CLKCTRL_BASE + 0x120))
|
||||
#define HW_CLKCTRL_RESET_CHIP 0x2
|
||||
#define HW_CLKCTRL_RESET_DIG 0x1
|
||||
#include "regs/regs-clkctrl.h"
|
||||
|
||||
static inline void core_sleep(void)
|
||||
{
|
||||
__REG_SET(HW_CLKCTRL_CPU) = HW_CLKCTRL_CPU__INTERRUPT_WAIT;
|
||||
BF_WR(CLKCTRL_CPU, INTERRUPT_WAIT, 1);
|
||||
asm volatile (
|
||||
"mcr p15, 0, %0, c7, c0, 4 \n" /* Wait for interrupt */
|
||||
"nop\n" /* Datasheet unclear: "The lr sent to handler points here after RTI"*/
|
||||
"nop\n"
|
||||
: : "r"(0)
|
||||
);
|
||||
enable_irq();
|
||||
|
|
|
@ -91,33 +91,37 @@ static void set_frequency(unsigned long freq) ICODE_ATTR;
|
|||
|
||||
static void set_frequency(unsigned long freq)
|
||||
{
|
||||
/* Set divider and clear clkgate. Do byte access to register to avoid bothering
|
||||
* with other PFDs */
|
||||
/** WARNING all restriction of imx233_emi_set_frequency apply here !! */
|
||||
/* Set divider and clear clkgate. */
|
||||
unsigned fracdiv;
|
||||
unsigned div;
|
||||
switch(freq)
|
||||
{
|
||||
case IMX233_EMIFREQ_151_MHz:
|
||||
/* clk_emi@ref_emi/3*18/19 */
|
||||
HW_CLKCTRL_FRAC_EMI = 19;
|
||||
__FIELD_SET(HW_CLKCTRL_EMI, DIV_EMI, 3);
|
||||
fracdiv = 19;
|
||||
div = 3;
|
||||
/* ref_emi@480 MHz
|
||||
* clk_emi@151.58 MHz */
|
||||
break;
|
||||
case IMX233_EMIFREQ_130_MHz:
|
||||
/* clk_emi@ref_emi/2*18/33 */
|
||||
HW_CLKCTRL_FRAC_EMI = 33;
|
||||
__FIELD_SET(HW_CLKCTRL_EMI, DIV_EMI, 2);
|
||||
fracdiv = 33;
|
||||
div = 2;
|
||||
/* ref_emi@480 MHz
|
||||
* clk_emi@130.91 MHz */
|
||||
break;
|
||||
case IMX233_EMIFREQ_64_MHz:
|
||||
default:
|
||||
/* clk_emi@ref_emi/5*18/27 */
|
||||
HW_CLKCTRL_FRAC_EMI = 27;
|
||||
__FIELD_SET(HW_CLKCTRL_EMI, DIV_EMI, 5);
|
||||
fracdiv = 27;
|
||||
div = 5;
|
||||
/* ref_emi@480 MHz
|
||||
* clk_emi@64 MHz */
|
||||
break;
|
||||
}
|
||||
BF_WR(CLKCTRL_FRAC, EMIFRAC, fracdiv);
|
||||
BF_WR(CLKCTRL_EMI, DIV_EMI, div);
|
||||
}
|
||||
|
||||
void imx233_emi_set_frequency(unsigned long freq) ICODE_ATTR;
|
||||
|
@ -162,17 +166,17 @@ void imx233_emi_set_frequency(unsigned long freq)
|
|||
HW_DRAM_CTLxx(regs->index) = regs->value;
|
||||
while((regs++)->index != 40);
|
||||
/* switch emi to xtal */
|
||||
__REG_SET(HW_CLKCTRL_CLKSEQ) = HW_CLKCTRL_CLKSEQ__BYPASS_EMI;
|
||||
BF_SET(CLKCTRL_CLKSEQ, BYPASS_EMI);
|
||||
/* wait for transition */
|
||||
while(HW_CLKCTRL_EMI & HW_CLKCTRL_EMI__BUSY_REF_XTAL);
|
||||
while(BF_RD(CLKCTRL_EMI, BUSY_REF_XTAL));
|
||||
/* put emi dll into reset mode */
|
||||
__REG_SET(HW_EMI_CTRL) = HW_EMI_CTRL__DLL_RESET | HW_EMI_CTRL__DLL_SHIFT_RESET;
|
||||
/* load the new frequency dividers */
|
||||
set_frequency(freq);
|
||||
/* switch emi back to pll */
|
||||
__REG_CLR(HW_CLKCTRL_CLKSEQ) = HW_CLKCTRL_CLKSEQ__BYPASS_EMI;
|
||||
BF_CLR(CLKCTRL_CLKSEQ, BYPASS_EMI);
|
||||
/* wait for transition */
|
||||
while(HW_CLKCTRL_EMI & HW_CLKCTRL_EMI__BUSY_REF_EMI);
|
||||
while(BF_RD(CLKCTRL_EMI, BUSY_REF_EMI));
|
||||
/* allow emi dll to lock again */
|
||||
__REG_CLR(HW_EMI_CTRL) = HW_EMI_CTRL__DLL_RESET | HW_EMI_CTRL__DLL_SHIFT_RESET;
|
||||
/* wait for lock */
|
||||
|
|
|
@ -44,7 +44,7 @@
|
|||
|
||||
void imx233_chip_reset(void)
|
||||
{
|
||||
HW_CLKCTRL_RESET = HW_CLKCTRL_RESET_CHIP;
|
||||
HW_CLKCTRL_RESET = BM_CLKCTRL_RESET_CHIP;
|
||||
}
|
||||
|
||||
void system_reboot(void)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue