mirror of
git://projects.qi-hardware.com/openwrt-xburst.git
synced 2024-11-27 17:55:55 +02:00
[xburst] Cleanup clock module a bit and replace last users of __cpm_*
git-svn-id: svn://svn.openwrt.org/openwrt/trunk@19281 3c298f89-4303-0410-b956-a3cf2f4a3e73
This commit is contained in:
parent
08ecc47d81
commit
15b54dd2c0
@ -17,282 +17,16 @@
|
||||
|
||||
#include <asm/mach-jz4740/regs.h>
|
||||
|
||||
/***************************************************************************
|
||||
* CPM
|
||||
***************************************************************************/
|
||||
#define __cpm_get_pllm() \
|
||||
((REG_CPM_CPPCR & CPM_CPPCR_PLLM_MASK) >> CPM_CPPCR_PLLM_BIT)
|
||||
#define __cpm_get_plln() \
|
||||
((REG_CPM_CPPCR & CPM_CPPCR_PLLN_MASK) >> CPM_CPPCR_PLLN_BIT)
|
||||
#define __cpm_get_pllod() \
|
||||
((REG_CPM_CPPCR & CPM_CPPCR_PLLOD_MASK) >> CPM_CPPCR_PLLOD_BIT)
|
||||
|
||||
#define __cpm_get_cdiv() \
|
||||
((REG_CPM_CPCCR & CPM_CPCCR_CDIV_MASK) >> CPM_CPCCR_CDIV_BIT)
|
||||
#define __cpm_get_hdiv() \
|
||||
((REG_CPM_CPCCR & CPM_CPCCR_HDIV_MASK) >> CPM_CPCCR_HDIV_BIT)
|
||||
#define __cpm_get_pdiv() \
|
||||
((REG_CPM_CPCCR & CPM_CPCCR_PDIV_MASK) >> CPM_CPCCR_PDIV_BIT)
|
||||
#define __cpm_get_mdiv() \
|
||||
((REG_CPM_CPCCR & CPM_CPCCR_MDIV_MASK) >> CPM_CPCCR_MDIV_BIT)
|
||||
#define __cpm_get_ldiv() \
|
||||
((REG_CPM_CPCCR & CPM_CPCCR_LDIV_MASK) >> CPM_CPCCR_LDIV_BIT)
|
||||
#define __cpm_get_udiv() \
|
||||
((REG_CPM_CPCCR & CPM_CPCCR_UDIV_MASK) >> CPM_CPCCR_UDIV_BIT)
|
||||
#define __cpm_get_i2sdiv() \
|
||||
((REG_CPM_I2SCDR & CPM_I2SCDR_I2SDIV_MASK) >> CPM_I2SCDR_I2SDIV_BIT)
|
||||
#define __cpm_get_pixdiv() \
|
||||
((REG_CPM_LPCDR & CPM_LPCDR_PIXDIV_MASK) >> CPM_LPCDR_PIXDIV_BIT)
|
||||
#define __cpm_get_mscdiv() \
|
||||
((REG_CPM_MSCCDR & CPM_MSCCDR_MSCDIV_MASK) >> CPM_MSCCDR_MSCDIV_BIT)
|
||||
#define __cpm_get_uhcdiv() \
|
||||
((REG_CPM_UHCCDR & CPM_UHCCDR_UHCDIV_MASK) >> CPM_UHCCDR_UHCDIV_BIT)
|
||||
#define __cpm_get_ssidiv() \
|
||||
((REG_CPM_SSICCDR & CPM_SSICDR_SSICDIV_MASK) >> CPM_SSICDR_SSIDIV_BIT)
|
||||
|
||||
#define __cpm_set_cdiv(v) \
|
||||
(REG_CPM_CPCCR = (REG_CPM_CPCCR & ~CPM_CPCCR_CDIV_MASK) | ((v) << (CPM_CPCCR_CDIV_BIT)))
|
||||
#define __cpm_set_hdiv(v) \
|
||||
(REG_CPM_CPCCR = (REG_CPM_CPCCR & ~CPM_CPCCR_HDIV_MASK) | ((v) << (CPM_CPCCR_HDIV_BIT)))
|
||||
#define __cpm_set_pdiv(v) \
|
||||
(REG_CPM_CPCCR = (REG_CPM_CPCCR & ~CPM_CPCCR_PDIV_MASK) | ((v) << (CPM_CPCCR_PDIV_BIT)))
|
||||
#define __cpm_set_mdiv(v) \
|
||||
(REG_CPM_CPCCR = (REG_CPM_CPCCR & ~CPM_CPCCR_MDIV_MASK) | ((v) << (CPM_CPCCR_MDIV_BIT)))
|
||||
#define __cpm_set_ldiv(v) \
|
||||
(REG_CPM_CPCCR = (REG_CPM_CPCCR & ~CPM_CPCCR_LDIV_MASK) | ((v) << (CPM_CPCCR_LDIV_BIT)))
|
||||
#define __cpm_set_udiv(v) \
|
||||
(REG_CPM_CPCCR = (REG_CPM_CPCCR & ~CPM_CPCCR_UDIV_MASK) | ((v) << (CPM_CPCCR_UDIV_BIT)))
|
||||
#define __cpm_set_i2sdiv(v) \
|
||||
(REG_CPM_I2SCDR = (REG_CPM_I2SCDR & ~CPM_I2SCDR_I2SDIV_MASK) | ((v) << (CPM_I2SCDR_I2SDIV_BIT)))
|
||||
#define __cpm_set_pixdiv(v) \
|
||||
(REG_CPM_LPCDR = (REG_CPM_LPCDR & ~CPM_LPCDR_PIXDIV_MASK) | ((v) << (CPM_LPCDR_PIXDIV_BIT)))
|
||||
#define __cpm_set_mscdiv(v) \
|
||||
(REG_CPM_MSCCDR = (REG_CPM_MSCCDR & ~CPM_MSCCDR_MSCDIV_MASK) | ((v) << (CPM_MSCCDR_MSCDIV_BIT)))
|
||||
#define __cpm_set_uhcdiv(v) \
|
||||
(REG_CPM_UHCCDR = (REG_CPM_UHCCDR & ~CPM_UHCCDR_UHCDIV_MASK) | ((v) << (CPM_UHCCDR_UHCDIV_BIT)))
|
||||
#define __cpm_ssiclk_select_exclk() \
|
||||
(REG_CPM_SSICDR &= ~CPM_SSICDR_SCS)
|
||||
#define __cpm_ssiclk_select_pllout() \
|
||||
(REG_CPM_SSICDR |= CPM_SSICDR_SCS)
|
||||
#define __cpm_set_ssidiv(v) \
|
||||
(REG_CPM_SSICDR = (REG_CPM_SSICDR & ~CPM_SSICDR_SSIDIV_MASK) | ((v) << (CPM_SSICDR_SSIDIV_BIT)))
|
||||
|
||||
#define __cpm_select_i2sclk_exclk() (REG_CPM_CPCCR &= ~CPM_CPCCR_I2CS)
|
||||
#define __cpm_select_i2sclk_pll() (REG_CPM_CPCCR |= CPM_CPCCR_I2CS)
|
||||
#define __cpm_enable_cko() (REG_CPM_CPCCR |= CPM_CPCCR_CLKOEN)
|
||||
#define __cpm_select_usbclk_exclk() (REG_CPM_CPCCR &= ~CPM_CPCCR_UCS)
|
||||
#define __cpm_select_usbclk_pll() (REG_CPM_CPCCR |= CPM_CPCCR_UCS)
|
||||
#define __cpm_enable_pll_change() (REG_CPM_CPCCR |= CPM_CPCCR_CE)
|
||||
#define __cpm_pllout_direct() (REG_CPM_CPCCR |= CPM_CPCCR_PCS)
|
||||
#define __cpm_pllout_div2() (REG_CPM_CPCCR &= ~CPM_CPCCR_PCS)
|
||||
|
||||
#define __cpm_pll_is_on() (REG_CPM_CPPCR & CPM_CPPCR_PLLS)
|
||||
#define __cpm_pll_bypass() (REG_CPM_CPPCR |= CPM_CPPCR_PLLBP)
|
||||
#define __cpm_pll_enable() (REG_CPM_CPPCR |= CPM_CPPCR_PLLEN)
|
||||
|
||||
#define __cpm_get_cclk_doze_duty() \
|
||||
((REG_CPM_LCR & CPM_LCR_DOZE_DUTY_MASK) >> CPM_LCR_DOZE_DUTY_BIT)
|
||||
#define __cpm_set_cclk_doze_duty(v) \
|
||||
(REG_CPM_LCR = (REG_CPM_LCR & ~CPM_LCR_DOZE_DUTY_MASK) | ((v) << (CPM_LCR_DOZE_DUTY_BIT)))
|
||||
|
||||
#define __cpm_doze_mode() (REG_CPM_LCR |= CPM_LCR_DOZE_ON)
|
||||
#define __cpm_idle_mode() \
|
||||
(REG_CPM_LCR = (REG_CPM_LCR & ~CPM_LCR_LPM_MASK) | CPM_LCR_LPM_IDLE)
|
||||
#define __cpm_sleep_mode() \
|
||||
(REG_CPM_LCR = (REG_CPM_LCR & ~CPM_LCR_LPM_MASK) | CPM_LCR_LPM_SLEEP)
|
||||
|
||||
#define __cpm_stop_all() (REG_CPM_CLKGR = 0x7fff)
|
||||
#define __cpm_stop_uart1() (REG_CPM_CLKGR |= CPM_CLKGR_UART1)
|
||||
#define __cpm_stop_uhc() (REG_CPM_CLKGR |= CPM_CLKGR_UHC)
|
||||
#define __cpm_stop_ipu() (REG_CPM_CLKGR |= CPM_CLKGR_IPU)
|
||||
#define __cpm_stop_dmac() (REG_CPM_CLKGR |= CPM_CLKGR_DMAC)
|
||||
#define __cpm_stop_udc() (REG_CPM_CLKGR |= CPM_CLKGR_UDC)
|
||||
#define __cpm_stop_lcd() (REG_CPM_CLKGR |= CPM_CLKGR_LCD)
|
||||
#define __cpm_stop_cim() (REG_CPM_CLKGR |= CPM_CLKGR_CIM)
|
||||
#define __cpm_stop_sadc() (REG_CPM_CLKGR |= CPM_CLKGR_SADC)
|
||||
#define __cpm_stop_msc() (REG_CPM_CLKGR |= CPM_CLKGR_MSC)
|
||||
#define __cpm_stop_aic1() (REG_CPM_CLKGR |= CPM_CLKGR_AIC1)
|
||||
#define __cpm_stop_aic2() (REG_CPM_CLKGR |= CPM_CLKGR_AIC2)
|
||||
#define __cpm_stop_ssi() (REG_CPM_CLKGR |= CPM_CLKGR_SSI)
|
||||
#define __cpm_stop_i2c() (REG_CPM_CLKGR |= CPM_CLKGR_I2C)
|
||||
#define __cpm_stop_rtc() (REG_CPM_CLKGR |= CPM_CLKGR_RTC)
|
||||
#define __cpm_stop_tcu() (REG_CPM_CLKGR |= CPM_CLKGR_TCU)
|
||||
#define __cpm_stop_uart0() (REG_CPM_CLKGR |= CPM_CLKGR_UART0)
|
||||
|
||||
#define __cpm_start_all() (REG_CPM_CLKGR = 0x0)
|
||||
#define __cpm_start_uart1() (REG_CPM_CLKGR &= ~CPM_CLKGR_UART1)
|
||||
#define __cpm_start_uhc() (REG_CPM_CLKGR &= ~CPM_CLKGR_UHC)
|
||||
#define __cpm_start_ipu() (REG_CPM_CLKGR &= ~CPM_CLKGR_IPU)
|
||||
#define __cpm_start_dmac() (REG_CPM_CLKGR &= ~CPM_CLKGR_DMAC)
|
||||
#define __cpm_start_udc() (REG_CPM_CLKGR &= ~CPM_CLKGR_UDC)
|
||||
#define __cpm_start_lcd() (REG_CPM_CLKGR &= ~CPM_CLKGR_LCD)
|
||||
#define __cpm_start_cim() (REG_CPM_CLKGR &= ~CPM_CLKGR_CIM)
|
||||
#define __cpm_start_sadc() (REG_CPM_CLKGR &= ~CPM_CLKGR_SADC)
|
||||
#define __cpm_start_msc() (REG_CPM_CLKGR &= ~CPM_CLKGR_MSC)
|
||||
#define __cpm_start_aic1() (REG_CPM_CLKGR &= ~CPM_CLKGR_AIC1)
|
||||
#define __cpm_start_aic2() (REG_CPM_CLKGR &= ~CPM_CLKGR_AIC2)
|
||||
#define __cpm_start_ssi() (REG_CPM_CLKGR &= ~CPM_CLKGR_SSI)
|
||||
#define __cpm_start_i2c() (REG_CPM_CLKGR &= ~CPM_CLKGR_I2C)
|
||||
#define __cpm_start_rtc() (REG_CPM_CLKGR &= ~CPM_CLKGR_RTC)
|
||||
#define __cpm_start_tcu() (REG_CPM_CLKGR &= ~CPM_CLKGR_TCU)
|
||||
#define __cpm_start_uart0() (REG_CPM_CLKGR &= ~CPM_CLKGR_UART0)
|
||||
|
||||
#define __cpm_get_o1st() \
|
||||
((REG_CPM_SCR & CPM_SCR_O1ST_MASK) >> CPM_SCR_O1ST_BIT)
|
||||
#define __cpm_set_o1st(v) \
|
||||
(REG_CPM_SCR = (REG_CPM_SCR & ~CPM_SCR_O1ST_MASK) | ((v) << (CPM_SCR_O1ST_BIT)))
|
||||
#define __cpm_suspend_usbphy() (REG_CPM_SCR |= CPM_SCR_USBPHY_SUSPEND)
|
||||
#define __cpm_enable_osc_in_sleep() (REG_CPM_SCR |= CPM_SCR_OSC_ENABLE)
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* JZ4740 clocks structure
|
||||
*/
|
||||
typedef struct {
|
||||
unsigned int cclk; /* CPU clock */
|
||||
unsigned int hclk; /* System bus clock */
|
||||
unsigned int pclk; /* Peripheral bus clock */
|
||||
unsigned int mclk; /* Flash/SRAM/SDRAM clock */
|
||||
unsigned int lcdclk; /* LCDC module clock */
|
||||
unsigned int pixclk; /* LCD pixel clock */
|
||||
unsigned int i2sclk; /* AIC module clock */
|
||||
unsigned int usbclk; /* USB module clock */
|
||||
unsigned int mscclk; /* MSC module clock */
|
||||
unsigned int extalclk; /* EXTAL clock for UART,I2C,SSI,TCU,USB-PHY */
|
||||
unsigned int rtcclk; /* RTC clock for CPM,INTC,RTC,TCU,WDT */
|
||||
} jz_clocks_t;
|
||||
|
||||
extern jz_clocks_t jz_clocks;
|
||||
|
||||
|
||||
/* PLL output frequency */
|
||||
static __inline__ unsigned int __cpm_get_pllout(void)
|
||||
enum jz4740_wait_mode
|
||||
{
|
||||
unsigned long m, n, no, pllout;
|
||||
unsigned long cppcr = REG_CPM_CPPCR;
|
||||
unsigned long od[4] = {1, 2, 2, 4};
|
||||
if ((cppcr & CPM_CPPCR_PLLEN) && !(cppcr & CPM_CPPCR_PLLBP)) {
|
||||
m = __cpm_get_pllm() + 2;
|
||||
n = __cpm_get_plln() + 2;
|
||||
no = od[__cpm_get_pllod()];
|
||||
pllout = ((JZ_EXTAL) / (n * no)) * m;
|
||||
} else
|
||||
pllout = JZ_EXTAL;
|
||||
return pllout;
|
||||
}
|
||||
|
||||
/* PLL output frequency for MSC/I2S/LCD/USB */
|
||||
static __inline__ unsigned int __cpm_get_pllout2(void)
|
||||
{
|
||||
if (REG_CPM_CPCCR & CPM_CPCCR_PCS)
|
||||
return __cpm_get_pllout();
|
||||
else
|
||||
return __cpm_get_pllout()/2;
|
||||
}
|
||||
|
||||
/* CPU core clock */
|
||||
static __inline__ unsigned int __cpm_get_cclk(void)
|
||||
{
|
||||
int div[] = {1, 2, 3, 4, 6, 8, 12, 16, 24, 32};
|
||||
|
||||
return __cpm_get_pllout() / div[__cpm_get_cdiv()];
|
||||
}
|
||||
|
||||
/* AHB system bus clock */
|
||||
static __inline__ unsigned int __cpm_get_hclk(void)
|
||||
{
|
||||
int div[] = {1, 2, 3, 4, 6, 8, 12, 16, 24, 32};
|
||||
|
||||
return __cpm_get_pllout() / div[__cpm_get_hdiv()];
|
||||
}
|
||||
|
||||
/* Memory bus clock */
|
||||
static __inline__ unsigned int __cpm_get_mclk(void)
|
||||
{
|
||||
int div[] = {1, 2, 3, 4, 6, 8, 12, 16, 24, 32};
|
||||
|
||||
return __cpm_get_pllout() / div[__cpm_get_mdiv()];
|
||||
}
|
||||
|
||||
/* APB peripheral bus clock */
|
||||
static __inline__ unsigned int __cpm_get_pclk(void)
|
||||
{
|
||||
int div[] = {1, 2, 3, 4, 6, 8, 12, 16, 24, 32};
|
||||
|
||||
return __cpm_get_pllout() / div[__cpm_get_pdiv()];
|
||||
}
|
||||
|
||||
/* LCDC module clock */
|
||||
static __inline__ unsigned int __cpm_get_lcdclk(void)
|
||||
{
|
||||
return __cpm_get_pllout2() / (__cpm_get_ldiv() + 1);
|
||||
}
|
||||
|
||||
/* LCD pixel clock */
|
||||
static __inline__ unsigned int __cpm_get_pixclk(void)
|
||||
{
|
||||
return __cpm_get_pllout2() / (__cpm_get_pixdiv() + 1);
|
||||
}
|
||||
|
||||
/* I2S clock */
|
||||
static __inline__ unsigned int __cpm_get_i2sclk(void)
|
||||
{
|
||||
if (REG_CPM_CPCCR & CPM_CPCCR_I2CS) {
|
||||
return __cpm_get_pllout2() / (__cpm_get_i2sdiv() + 1);
|
||||
}
|
||||
else {
|
||||
return JZ_EXTAL;
|
||||
}
|
||||
}
|
||||
|
||||
/* USB clock */
|
||||
static __inline__ unsigned int __cpm_get_usbclk(void)
|
||||
{
|
||||
if (REG_CPM_CPCCR & CPM_CPCCR_UCS) {
|
||||
return __cpm_get_pllout2() / (__cpm_get_udiv() + 1);
|
||||
}
|
||||
else {
|
||||
return JZ_EXTAL;
|
||||
}
|
||||
}
|
||||
|
||||
/* MSC clock */
|
||||
static __inline__ unsigned int __cpm_get_mscclk(void)
|
||||
{
|
||||
return __cpm_get_pllout2() / (__cpm_get_mscdiv() + 1);
|
||||
}
|
||||
|
||||
/* EXTAL clock for UART,I2C,SSI,TCU,USB-PHY */
|
||||
static __inline__ unsigned int __cpm_get_extalclk(void)
|
||||
{
|
||||
return JZ_EXTAL;
|
||||
}
|
||||
|
||||
/* RTC clock for CPM,INTC,RTC,TCU,WDT */
|
||||
static __inline__ unsigned int __cpm_get_rtcclk(void)
|
||||
{
|
||||
return JZ_EXTAL_RTC;
|
||||
}
|
||||
|
||||
/*
|
||||
* Output 24MHz for SD and 16MHz for MMC.
|
||||
*/
|
||||
static inline void __cpm_select_msc_clk(int sd)
|
||||
{
|
||||
unsigned int pllout2 = __cpm_get_pllout2();
|
||||
unsigned int div = 0;
|
||||
|
||||
if (sd) {
|
||||
div = pllout2 / 24000000;
|
||||
}
|
||||
else {
|
||||
div = pllout2 / 16000000;
|
||||
}
|
||||
|
||||
REG_CPM_MSCCDR = div - 1;
|
||||
}
|
||||
JZ4740_WAIT_MODE_IDLE,
|
||||
JZ4740_WAIT_MODE_SLEEP,
|
||||
};
|
||||
|
||||
int jz_init_clocks(unsigned long ext_rate);
|
||||
void jz4740_clock_set_wait_mode(enum jz4740_wait_mode mode);
|
||||
|
||||
void jz4740_clock_udc_enable_auto_suspend(void);
|
||||
void jz4740_clock_udc_disable_auto_suspend(void);
|
||||
|
||||
#endif /* __ASM_JZ4740_CLOCK_H__ */
|
||||
|
@ -52,162 +52,6 @@
|
||||
#define IPU_BASE 0xB3080000
|
||||
#define ETH_BASE 0xB3100000
|
||||
|
||||
/*************************************************************************
|
||||
* CPM (Clock reset and Power control Management)
|
||||
*************************************************************************/
|
||||
#define CPM_CPCCR (CPM_BASE+0x00)
|
||||
#define CPM_CPPCR (CPM_BASE+0x10)
|
||||
#define CPM_I2SCDR (CPM_BASE+0x60)
|
||||
#define CPM_LPCDR (CPM_BASE+0x64)
|
||||
#define CPM_MSCCDR (CPM_BASE+0x68)
|
||||
#define CPM_UHCCDR (CPM_BASE+0x6C)
|
||||
#define CPM_SSICDR (CPM_BASE+0x74)
|
||||
|
||||
#define CPM_LCR (CPM_BASE+0x04)
|
||||
#define CPM_CLKGR (CPM_BASE+0x20)
|
||||
#define CPM_SCR (CPM_BASE+0x24)
|
||||
|
||||
#define CPM_HCR (CPM_BASE+0x30)
|
||||
#define CPM_HWFCR (CPM_BASE+0x34)
|
||||
#define CPM_HRCR (CPM_BASE+0x38)
|
||||
#define CPM_HWCR (CPM_BASE+0x3c)
|
||||
#define CPM_HWSR (CPM_BASE+0x40)
|
||||
#define CPM_HSPR (CPM_BASE+0x44)
|
||||
|
||||
#define CPM_RSR (CPM_BASE+0x08)
|
||||
|
||||
#define REG_CPM_CPCCR REG32(CPM_CPCCR)
|
||||
#define REG_CPM_CPPCR REG32(CPM_CPPCR)
|
||||
#define REG_CPM_I2SCDR REG32(CPM_I2SCDR)
|
||||
#define REG_CPM_LPCDR REG32(CPM_LPCDR)
|
||||
#define REG_CPM_MSCCDR REG32(CPM_MSCCDR)
|
||||
#define REG_CPM_UHCCDR REG32(CPM_UHCCDR)
|
||||
#define REG_CPM_SSICDR REG32(CPM_SSICDR)
|
||||
|
||||
#define REG_CPM_LCR REG32(CPM_LCR)
|
||||
#define REG_CPM_CLKGR REG32(CPM_CLKGR)
|
||||
#define REG_CPM_SCR REG32(CPM_SCR)
|
||||
#define REG_CPM_HCR REG32(CPM_HCR)
|
||||
#define REG_CPM_HWFCR REG32(CPM_HWFCR)
|
||||
#define REG_CPM_HRCR REG32(CPM_HRCR)
|
||||
#define REG_CPM_HWCR REG32(CPM_HWCR)
|
||||
#define REG_CPM_HWSR REG32(CPM_HWSR)
|
||||
#define REG_CPM_HSPR REG32(CPM_HSPR)
|
||||
|
||||
#define REG_CPM_RSR REG32(CPM_RSR)
|
||||
|
||||
/* Clock Control Register */
|
||||
#define CPM_CPCCR_I2CS (1 << 31)
|
||||
#define CPM_CPCCR_CLKOEN (1 << 30)
|
||||
#define CPM_CPCCR_UCS (1 << 29)
|
||||
#define CPM_CPCCR_UDIV_BIT 23
|
||||
#define CPM_CPCCR_UDIV_MASK (0x3f << CPM_CPCCR_UDIV_BIT)
|
||||
#define CPM_CPCCR_CE (1 << 22)
|
||||
#define CPM_CPCCR_PCS (1 << 21)
|
||||
#define CPM_CPCCR_LDIV_BIT 16
|
||||
#define CPM_CPCCR_LDIV_MASK (0x1f << CPM_CPCCR_LDIV_BIT)
|
||||
#define CPM_CPCCR_MDIV_BIT 12
|
||||
#define CPM_CPCCR_MDIV_MASK (0x0f << CPM_CPCCR_MDIV_BIT)
|
||||
#define CPM_CPCCR_PDIV_BIT 8
|
||||
#define CPM_CPCCR_PDIV_MASK (0x0f << CPM_CPCCR_PDIV_BIT)
|
||||
#define CPM_CPCCR_HDIV_BIT 4
|
||||
#define CPM_CPCCR_HDIV_MASK (0x0f << CPM_CPCCR_HDIV_BIT)
|
||||
#define CPM_CPCCR_CDIV_BIT 0
|
||||
#define CPM_CPCCR_CDIV_MASK (0x0f << CPM_CPCCR_CDIV_BIT)
|
||||
|
||||
/* I2S Clock Divider Register */
|
||||
#define CPM_I2SCDR_I2SDIV_BIT 0
|
||||
#define CPM_I2SCDR_I2SDIV_MASK (0x1ff << CPM_I2SCDR_I2SDIV_BIT)
|
||||
|
||||
/* LCD Pixel Clock Divider Register */
|
||||
#define CPM_LPCDR_PIXDIV_BIT 0
|
||||
#define CPM_LPCDR_PIXDIV_MASK (0x7ff << CPM_LPCDR_PIXDIV_BIT)
|
||||
|
||||
/* MSC Clock Divider Register */
|
||||
#define CPM_MSCCDR_MSCDIV_BIT 0
|
||||
#define CPM_MSCCDR_MSCDIV_MASK (0x1f << CPM_MSCCDR_MSCDIV_BIT)
|
||||
|
||||
/* UHC Clock Divider Register */
|
||||
#define CPM_UHCCDR_UHCDIV_BIT 0
|
||||
#define CPM_UHCCDR_UHCDIV_MASK (0xf << CPM_UHCCDR_UHCDIV_BIT)
|
||||
|
||||
/* SSI Clock Divider Register */
|
||||
#define CPM_SSICDR_SCS (1<<31) /* SSI clock source selection, 0:EXCLK, 1: PLL */
|
||||
#define CPM_SSICDR_SSIDIV_BIT 0
|
||||
#define CPM_SSICDR_SSIDIV_MASK (0xf << CPM_SSICDR_SSIDIV_BIT)
|
||||
|
||||
/* PLL Control Register */
|
||||
#define CPM_CPPCR_PLLM_BIT 23
|
||||
#define CPM_CPPCR_PLLM_MASK (0x1ff << CPM_CPPCR_PLLM_BIT)
|
||||
#define CPM_CPPCR_PLLN_BIT 18
|
||||
#define CPM_CPPCR_PLLN_MASK (0x1f << CPM_CPPCR_PLLN_BIT)
|
||||
#define CPM_CPPCR_PLLOD_BIT 16
|
||||
#define CPM_CPPCR_PLLOD_MASK (0x03 << CPM_CPPCR_PLLOD_BIT)
|
||||
#define CPM_CPPCR_PLLS (1 << 10)
|
||||
#define CPM_CPPCR_PLLBP (1 << 9)
|
||||
#define CPM_CPPCR_PLLEN (1 << 8)
|
||||
#define CPM_CPPCR_PLLST_BIT 0
|
||||
#define CPM_CPPCR_PLLST_MASK (0xff << CPM_CPPCR_PLLST_BIT)
|
||||
|
||||
/* Low Power Control Register */
|
||||
#define CPM_LCR_DOZE_DUTY_BIT 3
|
||||
#define CPM_LCR_DOZE_DUTY_MASK (0x1f << CPM_LCR_DOZE_DUTY_BIT)
|
||||
#define CPM_LCR_DOZE_ON (1 << 2)
|
||||
#define CPM_LCR_LPM_BIT 0
|
||||
#define CPM_LCR_LPM_MASK (0x3 << CPM_LCR_LPM_BIT)
|
||||
#define CPM_LCR_LPM_IDLE (0x0 << CPM_LCR_LPM_BIT)
|
||||
#define CPM_LCR_LPM_SLEEP (0x1 << CPM_LCR_LPM_BIT)
|
||||
|
||||
/* Clock Gate Register */
|
||||
#define CPM_CLKGR_UART1 (1 << 15)
|
||||
#define CPM_CLKGR_UHC (1 << 14)
|
||||
#define CPM_CLKGR_IPU (1 << 13)
|
||||
#define CPM_CLKGR_DMAC (1 << 12)
|
||||
#define CPM_CLKGR_UDC (1 << 11)
|
||||
#define CPM_CLKGR_LCD (1 << 10)
|
||||
#define CPM_CLKGR_CIM (1 << 9)
|
||||
#define CPM_CLKGR_SADC (1 << 8)
|
||||
#define CPM_CLKGR_MSC (1 << 7)
|
||||
#define CPM_CLKGR_AIC1 (1 << 6)
|
||||
#define CPM_CLKGR_AIC2 (1 << 5)
|
||||
#define CPM_CLKGR_SSI (1 << 4)
|
||||
#define CPM_CLKGR_I2C (1 << 3)
|
||||
#define CPM_CLKGR_RTC (1 << 2)
|
||||
#define CPM_CLKGR_TCU (1 << 1)
|
||||
#define CPM_CLKGR_UART0 (1 << 0)
|
||||
|
||||
/* Sleep Control Register */
|
||||
#define CPM_SCR_O1ST_BIT 8
|
||||
#define CPM_SCR_O1ST_MASK (0xff << CPM_SCR_O1ST_BIT)
|
||||
#define CPM_SCR_USBPHY_ENABLE (1 << 6)
|
||||
#define CPM_SCR_OSC_ENABLE (1 << 4)
|
||||
|
||||
/* Hibernate Control Register */
|
||||
#define CPM_HCR_PD (1 << 0)
|
||||
|
||||
/* Wakeup Filter Counter Register in Hibernate Mode */
|
||||
#define CPM_HWFCR_TIME_BIT 0
|
||||
#define CPM_HWFCR_TIME_MASK (0x3ff << CPM_HWFCR_TIME_BIT)
|
||||
|
||||
/* Reset Counter Register in Hibernate Mode */
|
||||
#define CPM_HRCR_TIME_BIT 0
|
||||
#define CPM_HRCR_TIME_MASK (0x7f << CPM_HRCR_TIME_BIT)
|
||||
|
||||
/* Wakeup Control Register in Hibernate Mode */
|
||||
#define CPM_HWCR_WLE_LOW (0 << 2)
|
||||
#define CPM_HWCR_WLE_HIGH (1 << 2)
|
||||
#define CPM_HWCR_PIN_WAKEUP (1 << 1)
|
||||
#define CPM_HWCR_RTC_WAKEUP (1 << 0)
|
||||
|
||||
/* Wakeup Status Register in Hibernate Mode */
|
||||
#define CPM_HWSR_WSR_PIN (1 << 1)
|
||||
#define CPM_HWSR_WSR_RTC (1 << 0)
|
||||
|
||||
/* Reset Status Register */
|
||||
#define CPM_RSR_HR (1 << 2)
|
||||
#define CPM_RSR_WR (1 << 1)
|
||||
#define CPM_RSR_PR (1 << 0)
|
||||
|
||||
/*************************************************************************
|
||||
* UART
|
||||
*************************************************************************/
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (C) 2010, Lars-Peter Clausen <lars@metafoo.de>
|
||||
* JZ4740 SoC TCU support
|
||||
* JZ4740 SoC clock support
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
@ -22,7 +22,11 @@
|
||||
#include <linux/list.h>
|
||||
#include <linux/err.h>
|
||||
|
||||
#include <asm/mach-jz4740/clock.h>
|
||||
|
||||
#define JZ_REG_CLOCK_CTRL 0x00
|
||||
#define JZ_REG_CLOCK_LOW_POWER 0x04
|
||||
#define JZ_REG_CLOCK_SLEEP_CTRL 0x08
|
||||
#define JZ_REG_CLOCK_PLL 0x10
|
||||
#define JZ_REG_CLOCK_GATE 0x20
|
||||
#define JZ_REG_CLOCK_I2S 0x60
|
||||
@ -84,16 +88,17 @@
|
||||
#define JZ_CLOCK_PLL_N_OFFSET 18
|
||||
#define JZ_CLOCK_PLL_OD_OFFSET 16
|
||||
|
||||
#define JZ_CLOCK_LOW_POWER_MODE_DOZE BIT(2)
|
||||
#define JZ_CLOCK_LOW_POWER_MODE_SLEEP BIT(0)
|
||||
|
||||
#define JZ_CLOCK_SLEEP_CTRL_SUSPEND_UHC BIT(7)
|
||||
#define JZ_CLOCK_SLEEP_CTRL_ENABLE_UDC BIT(6)
|
||||
|
||||
static void __iomem *jz_clock_base;
|
||||
static spinlock_t jz_clock_lock;
|
||||
static LIST_HEAD(jz_clocks);
|
||||
|
||||
struct clk {
|
||||
const char *name;
|
||||
struct clk* parent;
|
||||
|
||||
uint32_t gate_bit;
|
||||
|
||||
struct clk_ops {
|
||||
unsigned long (*get_rate)(struct clk* clk);
|
||||
unsigned long (*round_rate)(struct clk *clk, unsigned long rate);
|
||||
int (*set_rate)(struct clk* clk, unsigned long rate);
|
||||
@ -101,6 +106,16 @@ struct clk {
|
||||
int (*disable)(struct clk* clk);
|
||||
|
||||
int (*set_parent)(struct clk* clk, struct clk *parent);
|
||||
};
|
||||
|
||||
struct clk {
|
||||
const char *name;
|
||||
struct clk* parent;
|
||||
|
||||
uint32_t gate_bit;
|
||||
|
||||
const struct clk_ops *ops;
|
||||
|
||||
struct list_head list;
|
||||
};
|
||||
|
||||
@ -220,8 +235,6 @@ static unsigned long jz_clk_pll_half_get_rate(struct clk *clk)
|
||||
return jz_clk_pll_get_rate(clk->parent) >> 1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static const int jz_clk_main_divs[] = {1, 2, 3, 4, 6, 8, 12, 16, 24, 32};
|
||||
|
||||
static unsigned long jz_clk_main_round_rate(struct clk *clk, unsigned long rate)
|
||||
@ -276,33 +289,51 @@ static int jz_clk_main_set_rate(struct clk *clk, unsigned long rate)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct clk_ops jz_clk_static_ops = {
|
||||
.get_rate = jz_clk_static_get_rate,
|
||||
.enable = jz_clk_enable_gating,
|
||||
.disable = jz_clk_disable_gating,
|
||||
};
|
||||
|
||||
static struct static_clk jz_clk_ext = {
|
||||
.clk = {
|
||||
.name = "ext",
|
||||
.get_rate = jz_clk_static_get_rate,
|
||||
.gate_bit = (uint32_t)-1,
|
||||
.ops = &jz_clk_static_ops,
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_ops jz_clk_pll_ops = {
|
||||
.get_rate = jz_clk_static_get_rate,
|
||||
};
|
||||
|
||||
static struct clk jz_clk_pll = {
|
||||
.name = "pll",
|
||||
.parent = &jz_clk_ext.clk,
|
||||
.get_rate = jz_clk_pll_get_rate,
|
||||
.ops = &jz_clk_pll_ops,
|
||||
};
|
||||
|
||||
static struct clk_ops jz_clk_pll_half_ops = {
|
||||
.get_rate = jz_clk_pll_half_get_rate,
|
||||
};
|
||||
|
||||
static struct clk jz_clk_pll_half = {
|
||||
.name = "pll half",
|
||||
.parent = &jz_clk_pll,
|
||||
.get_rate = jz_clk_pll_half_get_rate,
|
||||
.ops = &jz_clk_pll_half_ops,
|
||||
};
|
||||
|
||||
static const struct clk_ops jz_clk_main_ops = {
|
||||
.get_rate = jz_clk_main_get_rate,
|
||||
.set_rate = jz_clk_main_set_rate,
|
||||
.round_rate = jz_clk_main_round_rate,
|
||||
};
|
||||
|
||||
static struct main_clk jz_clk_cpu = {
|
||||
.clk = {
|
||||
.name = "cclk",
|
||||
.parent = &jz_clk_pll,
|
||||
.get_rate = jz_clk_main_get_rate,
|
||||
.set_rate = jz_clk_main_set_rate,
|
||||
.round_rate = jz_clk_main_round_rate,
|
||||
.ops = &jz_clk_main_ops,
|
||||
},
|
||||
.div_offset = JZ_CLOCK_CTRL_CDIV_OFFSET,
|
||||
};
|
||||
@ -311,9 +342,7 @@ static struct main_clk jz_clk_memory = {
|
||||
.clk = {
|
||||
.name = "mclk",
|
||||
.parent = &jz_clk_pll,
|
||||
.get_rate = jz_clk_main_get_rate,
|
||||
.set_rate = jz_clk_main_set_rate,
|
||||
.round_rate = jz_clk_main_round_rate,
|
||||
.ops = &jz_clk_main_ops,
|
||||
},
|
||||
.div_offset = JZ_CLOCK_CTRL_MDIV_OFFSET,
|
||||
};
|
||||
@ -322,9 +351,7 @@ static struct main_clk jz_clk_high_speed_peripheral = {
|
||||
.clk = {
|
||||
.name = "hclk",
|
||||
.parent = &jz_clk_pll,
|
||||
.get_rate = jz_clk_main_get_rate,
|
||||
.set_rate = jz_clk_main_set_rate,
|
||||
.round_rate = jz_clk_main_round_rate,
|
||||
.ops = &jz_clk_main_ops,
|
||||
},
|
||||
.div_offset = JZ_CLOCK_CTRL_HDIV_OFFSET,
|
||||
};
|
||||
@ -334,17 +361,20 @@ static struct main_clk jz_clk_low_speed_peripheral = {
|
||||
.clk = {
|
||||
.name = "pclk",
|
||||
.parent = &jz_clk_pll,
|
||||
.get_rate = jz_clk_main_get_rate,
|
||||
.set_rate = jz_clk_main_set_rate,
|
||||
.ops = &jz_clk_main_ops,
|
||||
},
|
||||
.div_offset = JZ_CLOCK_CTRL_PDIV_OFFSET,
|
||||
};
|
||||
|
||||
static const struct clk_ops jz_clk_ko_ops = {
|
||||
.enable = jz_clk_ko_enable,
|
||||
.disable = jz_clk_ko_disable,
|
||||
};
|
||||
|
||||
static struct clk jz_clk_ko = {
|
||||
.name = "cko",
|
||||
.parent = &jz_clk_memory.clk,
|
||||
.enable = jz_clk_ko_enable,
|
||||
.disable = jz_clk_ko_disable,
|
||||
.ops = &jz_clk_ko_ops,
|
||||
};
|
||||
|
||||
static int jz_clk_spi_set_parent(struct clk *clk, struct clk *parent)
|
||||
@ -375,6 +405,22 @@ static int jz_clk_i2s_set_parent(struct clk *clk, struct clk *parent)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int jz_clk_udc_disable(struct clk *clk)
|
||||
{
|
||||
jz_clk_reg_clear_bits(JZ_REG_CLOCK_SLEEP_CTRL,
|
||||
JZ_CLOCK_SLEEP_CTRL_ENABLE_UDC);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int jz_clk_udc_enable(struct clk *clk)
|
||||
{
|
||||
jz_clk_reg_set_bits(JZ_REG_CLOCK_SLEEP_CTRL,
|
||||
JZ_CLOCK_SLEEP_CTRL_ENABLE_UDC);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int jz_clk_udc_set_parent(struct clk *clk, struct clk *parent)
|
||||
{
|
||||
if (parent == &jz_clk_pll_half)
|
||||
@ -501,14 +547,18 @@ static unsigned long jz_clk_ldclk_get_rate(struct clk *clk)
|
||||
return jz_clk_pll_half_get_rate(clk->parent) / (div + 1);
|
||||
}
|
||||
|
||||
static struct clk jz_clk_ld = {
|
||||
.name = "lcd",
|
||||
.parent = &jz_clk_pll_half,
|
||||
static const struct clk_ops jz_clk_ops_ld = {
|
||||
.set_rate = jz_clk_ldclk_set_rate,
|
||||
.get_rate = jz_clk_ldclk_get_rate,
|
||||
.round_rate = jz_clk_ldclk_round_rate,
|
||||
};
|
||||
|
||||
static struct clk jz_clk_ld = {
|
||||
.name = "lcd",
|
||||
.parent = &jz_clk_pll_half,
|
||||
.ops= &jz_clk_ops_ld,
|
||||
};
|
||||
|
||||
static struct divided_clk jz_clk_lp = {
|
||||
.clk = {
|
||||
.name = "lcd_pclk",
|
||||
@ -527,156 +577,165 @@ static struct static_clk jz_clk_cim_pclk = {
|
||||
.clk = {
|
||||
.name = "cim_pclk",
|
||||
.gate_bit = JZ_CLOCK_GATE_CIM,
|
||||
.get_rate = jz_clk_static_get_rate,
|
||||
.enable = jz_clk_enable_gating,
|
||||
.disable = jz_clk_disable_gating,
|
||||
.ops = &jz_clk_static_ops,
|
||||
},
|
||||
};
|
||||
|
||||
static struct divided_clk jz_clk_i2s = {
|
||||
.clk = {
|
||||
.name = "i2s",
|
||||
.parent = &jz_clk_ext.clk,
|
||||
.gate_bit = JZ_CLOCK_GATE_AIC,
|
||||
.set_rate = jz_clk_divided_set_rate,
|
||||
.get_rate = jz_clk_divided_get_rate,
|
||||
.enable = jz_clk_enable_gating,
|
||||
.disable = jz_clk_disable_gating,
|
||||
.set_parent = jz_clk_i2s_set_parent,
|
||||
},
|
||||
.reg = JZ_REG_CLOCK_I2S,
|
||||
.mask = JZ_CLOCK_I2S_DIV_MASK,
|
||||
static const struct clk_ops jz_clk_i2s_ops =
|
||||
{
|
||||
.set_rate = jz_clk_divided_set_rate,
|
||||
.get_rate = jz_clk_divided_get_rate,
|
||||
.enable = jz_clk_enable_gating,
|
||||
.disable = jz_clk_disable_gating,
|
||||
.set_parent = jz_clk_i2s_set_parent,
|
||||
};
|
||||
|
||||
static struct divided_clk jz_clk_mmc = {
|
||||
.clk = {
|
||||
.name = "mmc",
|
||||
.parent = &jz_clk_pll_half,
|
||||
.gate_bit = JZ_CLOCK_GATE_MMC,
|
||||
.set_rate = jz_clk_divided_set_rate,
|
||||
.get_rate = jz_clk_divided_get_rate,
|
||||
.enable = jz_clk_enable_gating,
|
||||
.disable = jz_clk_disable_gating,
|
||||
},
|
||||
.reg = JZ_REG_CLOCK_MMC,
|
||||
.mask = JZ_CLOCK_MMC_DIV_MASK,
|
||||
static const struct clk_ops jz_clk_spi_ops =
|
||||
{
|
||||
.set_rate = jz_clk_divided_set_rate,
|
||||
.get_rate = jz_clk_divided_get_rate,
|
||||
.enable = jz_clk_enable_gating,
|
||||
.disable = jz_clk_disable_gating,
|
||||
.set_parent = jz_clk_spi_set_parent,
|
||||
};
|
||||
|
||||
static struct divided_clk jz_clk_uhc = {
|
||||
.clk = {
|
||||
.name = "uhc",
|
||||
.parent = &jz_clk_pll_half,
|
||||
.gate_bit = JZ_CLOCK_GATE_UHC,
|
||||
.set_rate = jz_clk_divided_set_rate,
|
||||
.get_rate = jz_clk_divided_get_rate,
|
||||
.enable = jz_clk_enable_gating,
|
||||
.disable = jz_clk_disable_gating,
|
||||
},
|
||||
.reg = JZ_REG_CLOCK_UHC,
|
||||
.mask = JZ_CLOCK_UHC_DIV_MASK,
|
||||
static const struct clk_ops jz_clk_divided_ops =
|
||||
{
|
||||
.set_rate = jz_clk_divided_set_rate,
|
||||
.get_rate = jz_clk_divided_get_rate,
|
||||
.enable = jz_clk_enable_gating,
|
||||
.disable = jz_clk_disable_gating,
|
||||
};
|
||||
|
||||
static struct clk jz_clk_udc = {
|
||||
.name = "udc",
|
||||
.parent = &jz_clk_ext.clk,
|
||||
static struct divided_clk jz4740_clock_divided_clks[] = {
|
||||
{
|
||||
.clk = {
|
||||
.name = "i2s",
|
||||
.parent = &jz_clk_ext.clk,
|
||||
.gate_bit = JZ_CLOCK_GATE_AIC,
|
||||
.ops = &jz_clk_i2s_ops,
|
||||
},
|
||||
.reg = JZ_REG_CLOCK_I2S,
|
||||
.mask = JZ_CLOCK_I2S_DIV_MASK,
|
||||
},
|
||||
{
|
||||
.clk = {
|
||||
.name = "spi",
|
||||
.parent = &jz_clk_ext.clk,
|
||||
.gate_bit = JZ_CLOCK_GATE_SPI,
|
||||
.ops = &jz_clk_spi_ops,
|
||||
},
|
||||
.reg = JZ_REG_CLOCK_SPI,
|
||||
.mask = JZ_CLOCK_SPI_DIV_MASK,
|
||||
},
|
||||
{
|
||||
.clk = {
|
||||
.name = "mmc",
|
||||
.parent = &jz_clk_pll_half,
|
||||
.gate_bit = JZ_CLOCK_GATE_MMC,
|
||||
.ops = &jz_clk_divided_ops,
|
||||
},
|
||||
.reg = JZ_REG_CLOCK_MMC,
|
||||
.mask = JZ_CLOCK_MMC_DIV_MASK,
|
||||
},
|
||||
{
|
||||
.clk = {
|
||||
.name = "uhc",
|
||||
.parent = &jz_clk_pll_half,
|
||||
.gate_bit = JZ_CLOCK_GATE_UHC,
|
||||
.ops = &jz_clk_divided_ops,
|
||||
},
|
||||
.reg = JZ_REG_CLOCK_UHC,
|
||||
.mask = JZ_CLOCK_UHC_DIV_MASK,
|
||||
},
|
||||
};
|
||||
|
||||
static const struct clk_ops jz_clk_udc_ops = {
|
||||
.set_parent = jz_clk_udc_set_parent,
|
||||
.set_rate = jz_clk_udc_set_rate,
|
||||
.get_rate = jz_clk_udc_get_rate,
|
||||
.enable = jz_clk_udc_enable,
|
||||
.disable = jz_clk_udc_disable,
|
||||
};
|
||||
|
||||
static struct divided_clk jz_clk_spi = {
|
||||
.clk = {
|
||||
.name = "spi",
|
||||
static const struct clk_ops jz_clk_simple_ops = {
|
||||
.enable = jz_clk_enable_gating,
|
||||
.disable = jz_clk_disable_gating,
|
||||
};
|
||||
|
||||
static struct clk jz4740_clock_simple_clks[] = {
|
||||
{
|
||||
.name = "udc",
|
||||
.parent = &jz_clk_ext.clk,
|
||||
.gate_bit = JZ_CLOCK_GATE_SPI,
|
||||
.set_rate = jz_clk_divided_set_rate,
|
||||
.get_rate = jz_clk_divided_get_rate,
|
||||
.enable = jz_clk_enable_gating,
|
||||
.disable = jz_clk_disable_gating,
|
||||
.set_parent = jz_clk_spi_set_parent,
|
||||
.ops = &jz_clk_udc_ops,
|
||||
},
|
||||
{
|
||||
.name = "uart0",
|
||||
.parent = &jz_clk_ext.clk,
|
||||
.gate_bit = JZ_CLOCK_GATE_UART0,
|
||||
.ops = &jz_clk_simple_ops,
|
||||
},
|
||||
{
|
||||
.name = "uart1",
|
||||
.parent = &jz_clk_ext.clk,
|
||||
.gate_bit = JZ_CLOCK_GATE_UART1,
|
||||
.ops = &jz_clk_simple_ops,
|
||||
},
|
||||
{
|
||||
.name = "dma",
|
||||
.parent = &jz_clk_high_speed_peripheral.clk,
|
||||
.gate_bit = JZ_CLOCK_GATE_UART0,
|
||||
.ops = &jz_clk_simple_ops,
|
||||
},
|
||||
{
|
||||
.name = "ipu",
|
||||
.parent = &jz_clk_high_speed_peripheral.clk,
|
||||
.gate_bit = JZ_CLOCK_GATE_IPU,
|
||||
.ops = &jz_clk_simple_ops,
|
||||
},
|
||||
{
|
||||
.name = "adc",
|
||||
.parent = &jz_clk_ext.clk,
|
||||
.gate_bit = JZ_CLOCK_GATE_ADC,
|
||||
.ops = &jz_clk_simple_ops,
|
||||
},
|
||||
{
|
||||
.name = "i2c",
|
||||
.parent = &jz_clk_ext.clk,
|
||||
.gate_bit = JZ_CLOCK_GATE_I2C,
|
||||
.ops = &jz_clk_simple_ops,
|
||||
},
|
||||
.reg = JZ_REG_CLOCK_SPI,
|
||||
.mask = JZ_CLOCK_SPI_DIV_MASK,
|
||||
};
|
||||
|
||||
static struct clk jz_clk_uart0 = {
|
||||
.name = "uart0",
|
||||
.parent = &jz_clk_ext.clk,
|
||||
.gate_bit = JZ_CLOCK_GATE_UART0,
|
||||
.enable = jz_clk_enable_gating,
|
||||
.disable = jz_clk_disable_gating,
|
||||
};
|
||||
|
||||
static struct clk jz_clk_uart1 = {
|
||||
.name = "uart1",
|
||||
.parent = &jz_clk_ext.clk,
|
||||
.gate_bit = JZ_CLOCK_GATE_UART1,
|
||||
.enable = jz_clk_enable_gating,
|
||||
.disable = jz_clk_disable_gating,
|
||||
};
|
||||
|
||||
static struct clk jz_clk_dma = {
|
||||
.name = "dma",
|
||||
.parent = &jz_clk_high_speed_peripheral.clk,
|
||||
.gate_bit = JZ_CLOCK_GATE_UART0,
|
||||
.enable = jz_clk_enable_gating,
|
||||
.disable = jz_clk_disable_gating,
|
||||
};
|
||||
|
||||
static struct clk jz_clk_ipu = {
|
||||
.name = "ipu",
|
||||
.parent = &jz_clk_high_speed_peripheral.clk,
|
||||
.gate_bit = JZ_CLOCK_GATE_IPU,
|
||||
.enable = jz_clk_enable_gating,
|
||||
.disable = jz_clk_disable_gating,
|
||||
};
|
||||
|
||||
static struct clk jz_clk_adc = {
|
||||
.name = "adc",
|
||||
.parent = &jz_clk_ext.clk,
|
||||
.gate_bit = JZ_CLOCK_GATE_ADC,
|
||||
.enable = jz_clk_enable_gating,
|
||||
.disable = jz_clk_disable_gating,
|
||||
};
|
||||
|
||||
static struct clk jz_clk_i2c = {
|
||||
.name = "i2c",
|
||||
.parent = &jz_clk_ext.clk,
|
||||
.gate_bit = JZ_CLOCK_GATE_I2C,
|
||||
.enable = jz_clk_enable_gating,
|
||||
.disable = jz_clk_disable_gating,
|
||||
};
|
||||
|
||||
static struct static_clk jz_clk_rtc = {
|
||||
.clk = {
|
||||
.name = "rtc",
|
||||
.gate_bit = JZ_CLOCK_GATE_RTC,
|
||||
.enable = jz_clk_enable_gating,
|
||||
.disable = jz_clk_disable_gating,
|
||||
.ops = &jz_clk_static_ops,
|
||||
},
|
||||
.rate = 32768,
|
||||
};
|
||||
|
||||
int clk_enable(struct clk *clk)
|
||||
{
|
||||
if (!clk->enable)
|
||||
if (!clk->ops->enable)
|
||||
return -EINVAL;
|
||||
|
||||
return clk->enable(clk);
|
||||
return clk->ops->enable(clk);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(clk_enable);
|
||||
|
||||
void clk_disable(struct clk *clk)
|
||||
{
|
||||
if (clk->disable)
|
||||
clk->disable(clk);
|
||||
if (clk->ops->disable)
|
||||
clk->ops->disable(clk);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(clk_disable);
|
||||
|
||||
unsigned long clk_get_rate(struct clk *clk)
|
||||
{
|
||||
if (clk->get_rate)
|
||||
return clk->get_rate(clk);
|
||||
if (clk->ops->get_rate)
|
||||
return clk->ops->get_rate(clk);
|
||||
if (clk->parent)
|
||||
return clk_get_rate(clk->parent);
|
||||
|
||||
@ -686,16 +745,16 @@ EXPORT_SYMBOL_GPL(clk_get_rate);
|
||||
|
||||
int clk_set_rate(struct clk *clk, unsigned long rate)
|
||||
{
|
||||
if (!clk->set_rate)
|
||||
if (!clk->ops->set_rate)
|
||||
return -EINVAL;
|
||||
return clk->set_rate(clk, rate);
|
||||
return clk->ops->set_rate(clk, rate);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(clk_set_rate);
|
||||
|
||||
long clk_round_rate(struct clk *clk, unsigned long rate)
|
||||
{
|
||||
if (clk->round_rate)
|
||||
return clk->round_rate(clk, rate);
|
||||
if (clk->ops->round_rate)
|
||||
return clk->ops->round_rate(clk, rate);
|
||||
|
||||
return -EINVAL;
|
||||
}
|
||||
@ -705,18 +764,17 @@ int clk_set_parent(struct clk *clk, struct clk *parent)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (!clk->set_parent)
|
||||
if (!clk->ops->set_parent)
|
||||
return -EINVAL;
|
||||
|
||||
clk->disable(clk);
|
||||
ret = clk->set_parent(clk, parent);
|
||||
clk->enable(clk);
|
||||
clk_disable(clk);
|
||||
ret = clk->ops->set_parent(clk, parent);
|
||||
clk_enable(clk);
|
||||
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(clk_set_parent);
|
||||
|
||||
|
||||
struct clk *clk_get(struct device *dev, const char *name)
|
||||
{
|
||||
struct clk *clk;
|
||||
@ -741,6 +799,8 @@ inline static void clk_add(struct clk *clk)
|
||||
|
||||
static void clk_register_clks(void)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
clk_add(&jz_clk_ext.clk);
|
||||
clk_add(&jz_clk_pll);
|
||||
clk_add(&jz_clk_pll_half);
|
||||
@ -752,41 +812,63 @@ static void clk_register_clks(void)
|
||||
clk_add(&jz_clk_lp.clk);
|
||||
clk_add(&jz_clk_cim_mclk);
|
||||
clk_add(&jz_clk_cim_pclk.clk);
|
||||
clk_add(&jz_clk_i2s.clk);
|
||||
clk_add(&jz_clk_mmc.clk);
|
||||
clk_add(&jz_clk_uhc.clk);
|
||||
clk_add(&jz_clk_udc);
|
||||
clk_add(&jz_clk_uart0);
|
||||
clk_add(&jz_clk_uart1);
|
||||
clk_add(&jz_clk_dma);
|
||||
clk_add(&jz_clk_ipu);
|
||||
clk_add(&jz_clk_adc);
|
||||
clk_add(&jz_clk_i2c);
|
||||
clk_add(&jz_clk_rtc.clk);
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(jz4740_clock_divided_clks); ++i)
|
||||
clk_add(&jz4740_clock_divided_clks[i].clk);
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(jz4740_clock_simple_clks); ++i)
|
||||
clk_add(&jz4740_clock_simple_clks[i]);
|
||||
}
|
||||
|
||||
void jz4740_clock_set_wait_mode(enum jz4740_wait_mode mode)
|
||||
{
|
||||
switch (mode) {
|
||||
case JZ4740_WAIT_MODE_IDLE:
|
||||
jz_clk_reg_clear_bits(JZ_REG_CLOCK_LOW_POWER, JZ_CLOCK_LOW_POWER_MODE_SLEEP);
|
||||
break;
|
||||
case JZ4740_WAIT_MODE_SLEEP:
|
||||
jz_clk_reg_set_bits(JZ_REG_CLOCK_LOW_POWER, JZ_CLOCK_LOW_POWER_MODE_SLEEP);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void jz4740_clock_udc_disable_auto_suspend(void)
|
||||
{
|
||||
jz_clk_reg_clear_bits(JZ_REG_CLOCK_GATE, JZ_CLOCK_GATE_UDC);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(jz4740_clock_udc_disable_auto_suspend);
|
||||
|
||||
void jz4740_clock_udc_enable_auto_suspend(void)
|
||||
{
|
||||
jz_clk_reg_set_bits(JZ_REG_CLOCK_GATE, JZ_CLOCK_GATE_UDC);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(jz4740_clock_udc_enable_auto_suspend);
|
||||
|
||||
int jz_init_clocks(unsigned long ext_rate)
|
||||
{
|
||||
uint32_t val;
|
||||
|
||||
jz_clock_base = ioremap(0x10000000, 0x100);
|
||||
jz_clock_base = ioremap(CPHYSADDR(CPM_BASE), 0x100);
|
||||
if (!jz_clock_base)
|
||||
return -EBUSY;
|
||||
|
||||
spin_lock_init(&jz_clock_lock);
|
||||
|
||||
jz_clk_ext.rate = ext_rate;
|
||||
|
||||
val = jz_clk_reg_read(JZ_REG_CLOCK_SPI);
|
||||
|
||||
if (val & JZ_CLOCK_SPI_SRC_PLL)
|
||||
jz_clk_spi.clk.parent = &jz_clk_pll_half;
|
||||
jz4740_clock_divided_clks[1].clk.parent = &jz_clk_pll_half;
|
||||
|
||||
val = jz_clk_reg_read(JZ_REG_CLOCK_CTRL);
|
||||
|
||||
if (val & JZ_CLOCK_CTRL_I2S_SRC_PLL)
|
||||
jz_clk_i2s.clk.parent = &jz_clk_pll_half;
|
||||
jz4740_clock_divided_clks[0].clk.parent = &jz_clk_pll_half;
|
||||
|
||||
if (val & JZ_CLOCK_CTRL_UDC_SRC_PLL)
|
||||
jz_clk_udc.parent = &jz_clk_pll_half;
|
||||
jz4740_clock_simple_clks[0].parent = &jz_clk_pll_half;
|
||||
|
||||
clk_register_clks();
|
||||
|
||||
|
@ -18,45 +18,25 @@
|
||||
#include <linux/delay.h>
|
||||
#include <linux/suspend.h>
|
||||
#include <asm/mach-jz4740/regs.h>
|
||||
#include <asm/mach-jz4740/clock.h>
|
||||
|
||||
extern void jz4740_intc_suspend(void);
|
||||
extern void jz4740_intc_resume(void);
|
||||
|
||||
static int jz_pm_enter(suspend_state_t state)
|
||||
{
|
||||
unsigned long nfcsr = REG_EMC_NFCSR;
|
||||
uint32_t scr = REG_CPM_SCR;
|
||||
|
||||
/* Disable nand flash */
|
||||
REG_EMC_NFCSR = ~0xff;
|
||||
|
||||
udelay(100);
|
||||
|
||||
/*stop udc and usb*/
|
||||
REG_CPM_SCR &= ~( 1<<6 | 1<<7);
|
||||
REG_CPM_SCR |= 0<<6 | 1<<7;
|
||||
|
||||
jz4740_intc_suspend();
|
||||
|
||||
/* Enter SLEEP mode */
|
||||
REG_CPM_LCR &= ~CPM_LCR_LPM_MASK;
|
||||
REG_CPM_LCR |= CPM_LCR_LPM_SLEEP;
|
||||
jz4740_clock_set_wait_mode(JZ4740_WAIT_MODE_SLEEP);
|
||||
|
||||
__asm__(".set\tmips3\n\t"
|
||||
"wait\n\t"
|
||||
".set\tmips0");
|
||||
|
||||
/* Restore to IDLE mode */
|
||||
REG_CPM_LCR &= ~CPM_LCR_LPM_MASK;
|
||||
REG_CPM_LCR |= CPM_LCR_LPM_IDLE;
|
||||
|
||||
/* Restore nand flash control register */
|
||||
REG_EMC_NFCSR = nfcsr;
|
||||
jz4740_clock_set_wait_mode(JZ4740_WAIT_MODE_IDLE);
|
||||
|
||||
jz4740_intc_resume();
|
||||
|
||||
/* Restore sleep control register */
|
||||
REG_CPM_SCR = scr;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -48,16 +48,6 @@ extern void jz_halt(void);
|
||||
extern void jz_power_off(void);
|
||||
extern void jz_time_init(void);
|
||||
|
||||
static void __init soc_cpm_setup(void)
|
||||
{
|
||||
/* Enable CKO to external memory */
|
||||
__cpm_enable_cko();
|
||||
|
||||
/* CPU enters IDLE mode when executing 'wait' instruction */
|
||||
__cpm_idle_mode();
|
||||
}
|
||||
|
||||
|
||||
static void __init jz_serial_setup(void)
|
||||
{
|
||||
#ifdef CONFIG_SERIAL_8250
|
||||
@ -102,7 +92,6 @@ void __init plat_mem_setup(void)
|
||||
_machine_restart = jz_restart;
|
||||
_machine_halt = jz_halt;
|
||||
pm_power_off = jz_power_off;
|
||||
soc_cpm_setup();
|
||||
jz_serial_setup();
|
||||
}
|
||||
|
||||
|
@ -32,6 +32,7 @@
|
||||
#include <linux/proc_fs.h>
|
||||
#include <linux/usb.h>
|
||||
#include <linux/usb/gadget.h>
|
||||
#include <linux/clk.h>
|
||||
|
||||
#include <asm/byteorder.h>
|
||||
#include <asm/io.h>
|
||||
@ -345,11 +346,7 @@ static void udc_disable(struct jz4740_udc *dev)
|
||||
usb_clearb(dev, JZ_REG_UDC_POWER, USB_POWER_SOFTCONN);
|
||||
|
||||
/* Disable the USB PHY */
|
||||
#ifdef CONFIG_SOC_JZ4740
|
||||
REG_CPM_SCR &= ~CPM_SCR_USBPHY_ENABLE;
|
||||
#elif defined(CONFIG_SOC_JZ4750) || defined(CONFIG_SOC_JZ4750D)
|
||||
REG_CPM_OPCR &= ~CPM_OPCR_UDCPHY_ENABLE;
|
||||
#endif
|
||||
clk_disable(dev->clk);
|
||||
|
||||
dev->ep0state = WAIT_FOR_SETUP;
|
||||
dev->gadget.speed = USB_SPEED_UNKNOWN;
|
||||
@ -410,14 +407,10 @@ static void udc_enable(struct jz4740_udc *dev)
|
||||
* there are no actions on the USB bus.
|
||||
* UDC still works during this bit was set.
|
||||
*/
|
||||
__cpm_stop_udc();
|
||||
jz4740_clock_udc_enable_auto_suspend();
|
||||
|
||||
/* Enable the USB PHY */
|
||||
#ifdef CONFIG_SOC_JZ4740
|
||||
REG_CPM_SCR |= CPM_SCR_USBPHY_ENABLE;
|
||||
#elif defined(CONFIG_SOC_JZ4750) || defined(CONFIG_SOC_JZ4750D)
|
||||
REG_CPM_OPCR |= CPM_OPCR_UDCPHY_ENABLE;
|
||||
#endif
|
||||
clk_enable(dev->clk);
|
||||
|
||||
/* Disable interrupts */
|
||||
/* usb_writew(dev, JZ_REG_UDC_INTRINE, 0);
|
||||
@ -2302,9 +2295,16 @@ static int jz4740_udc_probe(struct platform_device *pdev)
|
||||
dev->gadget.dev.release = gadget_release;
|
||||
|
||||
ret = device_register(&dev->gadget.dev);
|
||||
if (ret)
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
dev->clk = clk_get(&pdev->dev, "udc");
|
||||
if (IS_ERR(dev->clk)) {
|
||||
ret = PTR_ERR(dev->clk);
|
||||
dev_err(&pdev->dev, "Failed to get udc clock: %d\n", ret);
|
||||
goto err_device_unregister;
|
||||
}
|
||||
|
||||
platform_set_drvdata(pdev, dev);
|
||||
|
||||
dev->mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
@ -2312,7 +2312,7 @@ static int jz4740_udc_probe(struct platform_device *pdev)
|
||||
if (!dev->mem) {
|
||||
ret = -ENOENT;
|
||||
dev_err(&pdev->dev, "Failed to get mmio memory resource\n");
|
||||
goto err_device_unregister;
|
||||
goto err_clk_put;
|
||||
}
|
||||
|
||||
dev->mem = request_mem_region(dev->mem->start, resource_size(dev->mem), pdev->name);
|
||||
@ -2349,6 +2349,8 @@ err_iounmap:
|
||||
iounmap(dev->base);
|
||||
err_release_mem_region:
|
||||
release_mem_region(dev->mem->start, resource_size(dev->mem));
|
||||
err_clk_put:
|
||||
clk_put(dev->clk);
|
||||
err_device_unregister:
|
||||
device_unregister(&dev->gadget.dev);
|
||||
platform_set_drvdata(pdev, NULL);
|
||||
@ -2366,13 +2368,11 @@ static int jz4740_udc_remove(struct platform_device *pdev)
|
||||
return -EBUSY;
|
||||
|
||||
udc_disable(dev);
|
||||
#ifdef UDC_PROC_FILE
|
||||
remove_proc_entry(proc_node_name, NULL);
|
||||
#endif
|
||||
|
||||
free_irq(dev->irq, dev);
|
||||
iounmap(dev->base);
|
||||
release_mem_region(dev->mem->start, resource_size(dev->mem));
|
||||
clk_put(dev->clk);
|
||||
|
||||
platform_set_drvdata(pdev, NULL);
|
||||
device_unregister(&dev->gadget.dev);
|
||||
|
Loading…
Reference in New Issue
Block a user