Cleanup clock module a bit and replace last users of __cpm_*

SVN-Revision: 19281
lede-17.01
Lars-Peter Clausen 2010-01-22 18:13:02 +00:00
parent 275f0556a8
commit ad8700a22a
6 changed files with 271 additions and 642 deletions

View File

@ -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__ */

View File

@ -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
*************************************************************************/

View File

@ -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();

View File

@ -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;
}

View File

@ -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();
}

View File

@ -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);