/* * linux/include/asm-mips/mach-jz4740/clock.h * * JZ4740 clocks definition. * * Copyright (C) 2006 - 2007 Ingenic Semiconductor Inc. * * Author: * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. */ #ifndef __ASM_JZ4740_CLOCK_H__ #define __ASM_JZ4740_CLOCK_H__ #include /*************************************************************************** * 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) { 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; } int jz_init_clocks(unsigned long ext_rate); #endif /* __ASM_JZ4740_CLOCK_H__ */