1
0
mirror of git://projects.qi-hardware.com/openwrt-xburst.git synced 2024-11-29 03:23:43 +02:00
openwrt-xburst/target/linux/xburst/files-2.6.27/include/asm-mips/mach-jz4760/clock.h
Mirko Vogt dc3d3f1c49 yet another patchset - 2.6.27
it's basically also provided by ingenic and nativly based on 2.6.27,
adjusted to fit into the OpenWrt-environment
2009-10-28 03:13:11 +08:00

232 lines
4.9 KiB
C

/*
* linux/include/asm-mips/mach-jz4760/clock.h
*
* JZ4760 clocks definition.
*
* Copyright (C) 2008 Ingenic Semiconductor Inc.
*
* Author: <cwjia@ingenic.cn>
*
* 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_JZ4760_CLOCK_H__
#define __ASM_JZ4760_CLOCK_H__
#ifndef JZ_EXTAL
#define JZ_EXTAL 12000000 /* 3.6864 MHz */
#endif
#ifndef JZ_EXTAL2
#define JZ_EXTAL2 32768 /* 32.768 KHz */
#endif
/*
* JZ4760 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 h1clk; /* AHB1 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)
{
#if defined(CONFIG_FPGA)
return JZ_EXTAL*2/CFG_DIV;
#else
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;
#endif
}
/* PLL output frequency for MSC/I2S/LCD/USB */
static __inline__ unsigned int __cpm_get_pllout2(void)
{
#if defined(CONFIG_FPGA)
return JZ_EXTAL*2/CFG_DIV;
#else
if (REG_CPM_CPCCR & CPM_CPCCR_PCS)
return __cpm_get_pllout();
else
return __cpm_get_pllout()/2;
#endif
}
/* CPU core clock */
static __inline__ unsigned int __cpm_get_cclk(void)
{
#if defined(CONFIG_FGPA)
return JZ_EXTAL;
#else
int div[] = {1, 2, 3, 4, 6, 8, 12, 16, 24, 32};
return __cpm_get_pllout() / div[__cpm_get_cdiv()];
#endif
}
/* AHB system bus clock */
static __inline__ unsigned int __cpm_get_h0clk(void)
{
#if defined(CONFIG_FPGA)
return JZ_EXTAL/CFG_DIV;
#else
int div[] = {1, 2, 3, 4, 6, 8, 12, 16, 24, 32};
return __cpm_get_pllout() / div[__cpm_get_hdiv()];
#endif
}
/* Memory bus clock */
static __inline__ unsigned int __cpm_get_mclk(void)
{
#if defined(CONFIG_FPGA)
return JZ_EXTAL/CFG_DIV;
#else
int div[] = {1, 2, 3, 4, 6, 8, 12, 16, 24, 32};
return __cpm_get_pllout() / div[__cpm_get_mdiv()];
#endif
}
/* APB peripheral bus clock */
static __inline__ unsigned int __cpm_get_pclk(void)
{
#if defined(CONFIG_FPGA)
return JZ_EXTAL/CFG_DIV;
#else
int div[] = {1, 2, 3, 4, 6, 8, 12, 16, 24, 32};
return __cpm_get_pllout() / div[__cpm_get_pdiv()];
#endif
}
/* AHB1 module clock */
static __inline__ unsigned int __cpm_get_h1clk(void)
{
return __cpm_get_pllout2() / (__cpm_get_h1div() + 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
* @n: the index of MMC/SD controller
*/
static __inline__ unsigned int __cpm_get_mscclk(int n)
{
return __cpm_get_pllout2() / (__cpm_get_mscdiv(n) + 1);
}
/* EXTAL clock */
static __inline__ unsigned int __cpm_get_extalclk0(void)
{
return JZ_EXTAL;
}
/* EXTAL clock for UART,I2C,SSI,TCU,USB-PHY */
static __inline__ unsigned int __cpm_get_extalclk(void)
{
#if defined(CONFIG_FPGA)
return __cpm_get_extalclk0()/2;
#else
if (REG_CPM_CPCCR & CPM_CPCCR_ECS)
return __cpm_get_extalclk0()/2;
else
return __cpm_get_extalclk0();
#endif
}
/* RTC clock for CPM,INTC,RTC,TCU,WDT */
static __inline__ unsigned int __cpm_get_rtcclk(void)
{
return JZ_EXTAL2;
}
/*
* Output 24MHz for SD and 16MHz for MMC.
* @n: the index of MMC/SD controller
*/
static inline void __cpm_select_msc_clk(int n, int sd)
{
unsigned int pllout2 = __cpm_get_pllout2();
unsigned int div = 0;
if (sd) {
div = pllout2 / 24000000;
}
else {
div = pllout2 / 16000000;
}
REG_CPM_MSCCDR(n) = div - 1;
REG_CPM_CPCCR |= CPM_CPCCR_CE;
}
/*
* Output 48MHz for high speed card.
*/
static inline void __cpm_select_msc_clk_high(int n, int sd)
{
unsigned int pllout2 = __cpm_get_pllout2();
unsigned int div = 0;
div = pllout2 / 48000000;
REG_CPM_MSCCDR(n) = div - 1;
REG_CPM_CPCCR |= CPM_CPCCR_CE;
}
#endif /* __ASM_JZ4760_CLOCK_H__ */