[xburst] Cleanup clock module a bit and replace last users of __cpm_*
authorLars-Peter Clausen <lars@metafoo.de>
Fri, 22 Jan 2010 18:13:02 +0000 (18:13 +0000)
committerLars-Peter Clausen <lars@metafoo.de>
Fri, 22 Jan 2010 18:13:02 +0000 (18:13 +0000)
SVN-Revision: 19281

target/linux/xburst/files-2.6.32/arch/mips/include/asm/mach-jz4740/clock.h
target/linux/xburst/files-2.6.32/arch/mips/include/asm/mach-jz4740/regs.h
target/linux/xburst/files-2.6.32/arch/mips/jz4740/clock.c
target/linux/xburst/files-2.6.32/arch/mips/jz4740/pm.c
target/linux/xburst/files-2.6.32/arch/mips/jz4740/setup.c
target/linux/xburst/files-2.6.32/drivers/usb/gadget/jz4740_udc.c

index 4869b88..c75c07b 100644 (file)
 
 #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)
-{
-       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)
+enum jz4740_wait_mode
 {
-       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__ */
index 3046fee..2ea90ca 100644 (file)
 #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
  *************************************************************************/
index 853c6d8..49ea717 100644 (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
 #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
 #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,
-       },
-};
-
-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 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,
+               .ops = &jz_clk_static_ops,
        },
-       .reg = JZ_REG_CLOCK_MMC,
-       .mask = JZ_CLOCK_MMC_DIV_MASK,
 };
 
-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 struct clk jz_clk_udc = {
-       .name = "udc",
-       .parent = &jz_clk_ext.clk,
-       .set_parent = jz_clk_udc_set_parent,
-       .set_rate = jz_clk_udc_set_rate,
-       .get_rate = jz_clk_udc_get_rate,
-};
-
-static struct divided_clk jz_clk_spi = {
-       .clk = {
-               .name = "spi",
-               .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,
-       },
-       .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,
+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 clk jz_clk_uart1 = {
-       .name = "uart1",
-       .parent = &jz_clk_ext.clk,
-       .gate_bit = JZ_CLOCK_GATE_UART1,
+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 clk jz_clk_dma = {
-       .name = "dma",
-       .parent = &jz_clk_high_speed_peripheral.clk,
-       .gate_bit = JZ_CLOCK_GATE_UART0,
+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_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 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 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 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 clk jz_clk_i2c = {
-       .name = "i2c",
-       .parent = &jz_clk_ext.clk,
-       .gate_bit = JZ_CLOCK_GATE_I2C,
+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,
+               .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,
+       },
+};
+
 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();
 
index d19bb81..9fb0ceb 100644 (file)
 #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;
 }
 
index 3f12e2e..466d5fd 100644 (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();
 }
 
index 4a98d33..881bca7 100644 (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);