From 9ea010582cb6019160db81cadc467720bd6ab116 Mon Sep 17 00:00:00 2001 From: root Date: Fri, 8 Apr 2011 15:16:26 +0800 Subject: [PATCH] add 300mhz and 96mhz for periph pll --- arch/arm/mach-rk29/board-malata.c | 2 +- arch/arm/mach-rk29/board-rk29-a22.c | 2 +- arch/arm/mach-rk29/board-rk29-aigo.c | 2 +- arch/arm/mach-rk29/board-rk29-ddr3sdk.c | 2 +- arch/arm/mach-rk29/board-rk29-fih.c | 2 +- arch/arm/mach-rk29/board-rk29-phonesdk.c | 2 +- arch/arm/mach-rk29/board-rk29-winaccord.c | 2 +- arch/arm/mach-rk29/board-rk29sdk.c | 2 +- arch/arm/mach-rk29/clock.c | 191 +++++++++++++++++----- arch/arm/mach-rk29/include/mach/board.h | 8 +- sound/soc/rk29/rk29_i2s.c | 18 +- sound/soc/rk29/rk29_wm8900.c | 28 +++- 12 files changed, 206 insertions(+), 55 deletions(-) mode change 100644 => 100755 sound/soc/rk29/rk29_wm8900.c diff --git a/arch/arm/mach-rk29/board-malata.c b/arch/arm/mach-rk29/board-malata.c index d71bceb82534..212f983df340 100755 --- a/arch/arm/mach-rk29/board-malata.c +++ b/arch/arm/mach-rk29/board-malata.c @@ -1968,7 +1968,7 @@ static void __init machine_rk29_mapio(void) rk29_map_common_io(); rk29_setup_early_printk(); rk29_sram_init(); - rk29_clock_init(); + rk29_clock_init(periph_pll_288mhz); rk29_iomux_init(); } diff --git a/arch/arm/mach-rk29/board-rk29-a22.c b/arch/arm/mach-rk29/board-rk29-a22.c index 2eeccd6800b5..4c5b9e215a5d 100755 --- a/arch/arm/mach-rk29/board-rk29-a22.c +++ b/arch/arm/mach-rk29/board-rk29-a22.c @@ -3009,7 +3009,7 @@ static void __init machine_rk29_fixup(struct machine_desc *desc, struct tag *tag static void __init machine_rk29_mapio(void) { - rk29_map_common_io(); + rk29_map_common_io(periph_pll_288mhz); rk29_setup_early_printk(); rk29_sram_init(); rk29_clock_init(); diff --git a/arch/arm/mach-rk29/board-rk29-aigo.c b/arch/arm/mach-rk29/board-rk29-aigo.c index 1a858336f16e..22a26b0c4a16 100755 --- a/arch/arm/mach-rk29/board-rk29-aigo.c +++ b/arch/arm/mach-rk29/board-rk29-aigo.c @@ -1746,7 +1746,7 @@ static void __init machine_rk29_mapio(void) rk29_map_common_io(); rk29_setup_early_printk(); rk29_sram_init(); - rk29_clock_init(); + rk29_clock_init(periph_pll_288mhz); rk29_iomux_init(); } diff --git a/arch/arm/mach-rk29/board-rk29-ddr3sdk.c b/arch/arm/mach-rk29/board-rk29-ddr3sdk.c index dcbb8b7ae76c..3908f71eea36 100755 --- a/arch/arm/mach-rk29/board-rk29-ddr3sdk.c +++ b/arch/arm/mach-rk29/board-rk29-ddr3sdk.c @@ -1869,7 +1869,7 @@ static void __init machine_rk29_mapio(void) rk29_map_common_io(); rk29_setup_early_printk(); rk29_sram_init(); - rk29_clock_init(); + rk29_clock_init(periph_pll_288mhz); rk29_iomux_init(); } diff --git a/arch/arm/mach-rk29/board-rk29-fih.c b/arch/arm/mach-rk29/board-rk29-fih.c index b3a1a5ac70f5..eb434081f2c4 100755 --- a/arch/arm/mach-rk29/board-rk29-fih.c +++ b/arch/arm/mach-rk29/board-rk29-fih.c @@ -2272,7 +2272,7 @@ static void __init machine_rk29_mapio(void) rk29_map_common_io(); rk29_setup_early_printk(); rk29_sram_init(); - rk29_clock_init(); + rk29_clock_init(periph_pll_288mhz); rk29_iomux_init(); } diff --git a/arch/arm/mach-rk29/board-rk29-phonesdk.c b/arch/arm/mach-rk29/board-rk29-phonesdk.c index 3f49da2b2e30..b19cb828799d 100755 --- a/arch/arm/mach-rk29/board-rk29-phonesdk.c +++ b/arch/arm/mach-rk29/board-rk29-phonesdk.c @@ -3003,7 +3003,7 @@ static void __init machine_rk29_mapio(void) rk29_map_common_io(); rk29_setup_early_printk(); rk29_sram_init(); - rk29_clock_init(); + rk29_clock_init(periph_pll_288mhz); rk29_iomux_init(); } diff --git a/arch/arm/mach-rk29/board-rk29-winaccord.c b/arch/arm/mach-rk29/board-rk29-winaccord.c index 89db2b7d9c70..eb7a4602b735 100755 --- a/arch/arm/mach-rk29/board-rk29-winaccord.c +++ b/arch/arm/mach-rk29/board-rk29-winaccord.c @@ -1649,7 +1649,7 @@ static void __init machine_rk29_mapio(void) rk29_map_common_io(); rk29_setup_early_printk(); rk29_sram_init(); - rk29_clock_init(); + rk29_clock_init(periph_pll_288mhz); rk29_iomux_init(); } diff --git a/arch/arm/mach-rk29/board-rk29sdk.c b/arch/arm/mach-rk29/board-rk29sdk.c index 23847b714e1e..566d342b50aa 100755 --- a/arch/arm/mach-rk29/board-rk29sdk.c +++ b/arch/arm/mach-rk29/board-rk29sdk.c @@ -1891,7 +1891,7 @@ static void __init machine_rk29_mapio(void) rk29_map_common_io(); rk29_setup_early_printk(); rk29_sram_init(); - rk29_clock_init(); + rk29_clock_init(periph_pll_288mhz); rk29_iomux_init(); } diff --git a/arch/arm/mach-rk29/clock.c b/arch/arm/mach-rk29/clock.c index b776f716ec9f..ed908ef1914e 100755 --- a/arch/arm/mach-rk29/clock.c +++ b/arch/arm/mach-rk29/clock.c @@ -621,10 +621,22 @@ static int general_pll_clk_set_rate(struct clk *clk, unsigned long rate) u32 pll_con; switch (rate) { + case 96 * MHZ: + /* 96M: low-band, NR=1, NF=16, NO=4 */ + pll_con = PLL_LOW_BAND | PLL_CLKR(1) | PLL_CLKF(16) | PLL_NO_4; + break; + case 144*MHZ: + /* 96M: low-band, NR=1, NF=16, NO=4 */ + pll_con = PLL_LOW_BAND | PLL_CLKR(1) | PLL_CLKF(24) | PLL_NO_4; + break; case 288 * MHZ: /* 288M: low-band, NR=1, NF=24, NO=2 */ pll_con = PLL_LOW_BAND | PLL_CLKR(1) | PLL_CLKF(24) | PLL_NO_2; break; + case 300 * MHZ: + /* 300M: low-band, NR=1, NF=25, NO=2 */ + pll_con = PLL_LOW_BAND | PLL_CLKR(1) | PLL_CLKF(25) | PLL_NO_2; + break; case 624 * MHZ: /* 624M: high-band, NR=1, NF=26, NO=1 */ pll_con = PLL_HIGH_BAND | PLL_CLKR(1) | PLL_CLKF(26) | PLL_NO_1; @@ -878,11 +890,50 @@ static struct clk clk_spdif_div = { .clksel_parent_shift = 20, .parents = clk_i2s_div_parents, }; +u32 clk_gcd(u32 numerator,u32 denominator) +{ + + u32 a,b,r; + + if(!numerator||!denominator) + return 0; + if(numerator > denominator){ + a = numerator; + b = denominator; + }else{ + a = denominator; + b = numerator; + } + while(b != 0){ + int r = b; + b = a % b; + a = r; + } + return a; +} static int clk_i2s_frac_div_set_rate(struct clk *clk, unsigned long rate) { u16 numerator, denominator; - + u32 gcd=0; + gcd=clk_gcd(rate,clk->parent->rate); + pr_debug("%s i2s rate=%d,parent=%d,gcd=%d\n",__FUNCTION__, + rate,clk->parent->rate,gcd); + if(!gcd) + { + printk("gcd=0,i2s frac div is not be supported\n"); + return -ENOENT; + } + numerator=rate/gcd; + denominator=clk->parent->rate/gcd; + pr_debug("%s i2s numerator=%d,denominator=%d,times=%d\n", + __FUNCTION__,numerator,denominator,denominator/numerator); + if(numerator>0xffff||denominator>0xffff) + { + printk("i2s can't get a available nume and deno\n"); + return -ENOENT; + } +#if 0 switch (rate) { case 8192000: /* 288*32/1125 */ numerator = 32; @@ -899,7 +950,7 @@ static int clk_i2s_frac_div_set_rate(struct clk *clk, unsigned long rate) default: return -ENOENT; } - +#endif pr_debug("set clock %s to rate %ld (%d/%d)\n", clk->name, rate, numerator, denominator); cru_writel((u32)numerator << 16 | denominator, clk->clksel_con); @@ -1187,7 +1238,24 @@ static int clk_uart_set_rate(struct clk *clk, unsigned long rate) static int clk_uart_frac_div_set_rate(struct clk *clk, unsigned long rate) { u16 numerator, denominator; - + u32 gcd=0; + gcd=clk_gcd(rate,clk->parent->rate); + pr_debug("%s uart rate=%d,parent=%d,gcd=%d\n",__FUNCTION__,rate,clk->parent->rate,gcd); + if(!gcd) + { + printk("gcd=0,uart frac div is not be supported\n"); + return -ENOENT; + } + numerator=rate/gcd; + denominator=clk->parent->rate/gcd; + pr_debug("%s uart numerator=%d,denominator=%d,times=%d\n",__FUNCTION__, + numerator,denominator,denominator/numerator); + if(numerator>0xffff||denominator>0xffff) + { + printk("uart_frac can't get a available nume and deno\n"); + return -ENOENT; + } +#if 0 switch (rate) { case 19200*16: /* 288*2/1875 */ numerator = 2; @@ -1220,7 +1288,7 @@ static int clk_uart_frac_div_set_rate(struct clk *clk, unsigned long rate) default: return -ENOENT; } - +#endif pr_debug("set clock %s to rate %ld (%d/%d)\n", clk->name, rate, numerator, denominator); cru_writel((u32)numerator << 16 | denominator, clk->clksel_con); @@ -2341,44 +2409,83 @@ static int __init armclk_setup(char *str) } early_param("armclk", armclk_setup); -static void __init rk29_clock_common_init(void) +static void __init rk29_clock_common_init(unsigned long ppll_rate) { - /* general pll */ - clk_set_rate_nolock(&general_pll_clk, 288 * MHZ); - clk_set_parent_nolock(&aclk_periph, &general_pll_clk); - clk_set_rate_nolock(&aclk_periph, 144 * MHZ); - clk_set_rate_nolock(&hclk_periph, 144 * MHZ); - clk_set_rate_nolock(&pclk_periph, 36 * MHZ); - clk_set_parent_nolock(&clk_uhost, &general_pll_clk); - clk_set_rate_nolock(&clk_uhost, 48 * MHZ); - clk_set_parent_nolock(&clk_i2s0_div, &general_pll_clk); - clk_set_parent_nolock(&clk_i2s1_div, &general_pll_clk); - clk_set_parent_nolock(&clk_spdif_div, &general_pll_clk); - clk_set_parent_nolock(&clk_spi_src, &general_pll_clk); - clk_set_parent_nolock(&clk_mmc_src, &general_pll_clk); - clk_set_parent_nolock(&clk_uart01_src, &general_pll_clk); - clk_set_parent_nolock(&clk_uart23_src, &general_pll_clk); - clk_set_parent_nolock(&dclk_lcdc_div, &general_pll_clk); - clk_set_parent_nolock(&aclk_lcdc, &general_pll_clk); - clk_set_parent_nolock(&aclk_vepu, &general_pll_clk); - clk_set_rate_nolock(&aclk_vepu, 288 * MHZ); - clk_set_rate_nolock(&clk_aclk_ddr_vepu, 288 * MHZ); - clk_set_rate_nolock(&hclk_vepu, 144 * MHZ); - clk_set_parent_nolock(&aclk_vdpu, &general_pll_clk); - clk_set_parent_nolock(&aclk_gpu, &general_pll_clk); - clk_set_rate_nolock(&aclk_gpu, 288 * MHZ); - clk_set_parent_nolock(&clk_mac_ref_div, &general_pll_clk); - clk_set_parent_nolock(&clk_hsadc_div, &general_pll_clk); - - /* codec pll */ - clk_set_rate_nolock(&codec_pll_clk, 552 * MHZ); - clk_set_parent_nolock(&clk_gpu, &codec_pll_clk); - - /* arm pll */ - clk_set_rate_nolock(&arm_pll_clk, armclk); - clk_set_parent_nolock(&clk_mac_ref_div, &arm_pll_clk); + unsigned long aclk_p,hclk_p,pclk_p; + struct clk *aclk_vepu_parent,*aclk_vdpu_parent,*aclk_gpu_parent; + unsigned long aclk_vepu_rate,hclk_vepu_rate,aclk_ddr_vepu_rate,aclk_gpu_rate; + unsigned long codec_pll=552 * MHZ; + /* general pll */ + switch(ppll_rate) + { + case 96* MHZ: + aclk_p=96*MHZ; + hclk_p=48*MHZ; + pclk_p=24*MHZ; + aclk_gpu_parent=aclk_vdpu_parent=aclk_vepu_parent=&codec_pll_clk; + aclk_gpu_rate=aclk_ddr_vepu_rate=aclk_vepu_rate=codec_pll/2; + hclk_vepu_rate=codec_pll/4; + break; + case 144* MHZ: + aclk_p=144*MHZ; + hclk_p=72*MHZ; + pclk_p=36*MHZ; + aclk_gpu_parent=aclk_vdpu_parent=aclk_vepu_parent=&codec_pll_clk; + aclk_gpu_rate=aclk_ddr_vepu_rate=aclk_vepu_rate=codec_pll/2; + hclk_vepu_rate=codec_pll/4; + break; + case 288* MHZ: + case 300* MHZ: + aclk_p=ppll_rate/2; + hclk_p=ppll_rate/2; + pclk_p=ppll_rate/8; + aclk_gpu_parent=aclk_vdpu_parent=aclk_vepu_parent=&general_pll_clk; + aclk_gpu_rate=aclk_ddr_vepu_rate=aclk_vepu_rate=ppll_rate; + hclk_vepu_rate=ppll_rate/2; + break; + default: + ppll_rate=288* MHZ; + aclk_p=ppll_rate/2; + hclk_p=ppll_rate/2; + pclk_p=ppll_rate/8; + aclk_gpu_parent=aclk_vdpu_parent=aclk_vepu_parent=&general_pll_clk; + aclk_gpu_rate=aclk_ddr_vepu_rate=aclk_vepu_rate=ppll_rate; + hclk_vepu_rate=ppll_rate/2; + break; + } + clk_set_rate_nolock(&general_pll_clk,ppll_rate);// 288 + clk_set_parent_nolock(&aclk_periph, &general_pll_clk); + clk_set_rate_nolock(&aclk_periph, aclk_p);//144 + clk_set_rate_nolock(&hclk_periph, hclk_p);// 144 + clk_set_rate_nolock(&pclk_periph, pclk_p);// 36 + clk_set_parent_nolock(&clk_uhost, &general_pll_clk); + clk_set_rate_nolock(&clk_uhost, 48 * MHZ); + clk_set_parent_nolock(&clk_i2s0_div, &general_pll_clk); + clk_set_parent_nolock(&clk_i2s1_div, &general_pll_clk); + clk_set_parent_nolock(&clk_spdif_div, &general_pll_clk); + clk_set_parent_nolock(&clk_spi_src, &general_pll_clk); + clk_set_parent_nolock(&clk_mmc_src, &general_pll_clk); + clk_set_parent_nolock(&clk_uart01_src, &general_pll_clk); + clk_set_parent_nolock(&clk_uart23_src, &general_pll_clk); + clk_set_parent_nolock(&dclk_lcdc_div, &general_pll_clk); + clk_set_parent_nolock(&aclk_lcdc, &general_pll_clk); + clk_set_parent_nolock(&clk_mac_ref_div, &general_pll_clk); + clk_set_parent_nolock(&clk_hsadc_div, &general_pll_clk); + /* codec pll */ + clk_set_rate_nolock(&codec_pll_clk, codec_pll); + clk_set_parent_nolock(&clk_gpu, &codec_pll_clk); + /* arm pll */ + clk_set_rate_nolock(&arm_pll_clk, armclk); + clk_set_parent_nolock(&clk_mac_ref_div, &arm_pll_clk); + /*you can choose clk parent form codec pll or periph pll for following logic*/ + clk_set_parent_nolock(&aclk_vepu, aclk_vepu_parent); + clk_set_rate_nolock(&aclk_vepu, aclk_vepu_rate); + clk_set_rate_nolock(&clk_aclk_ddr_vepu,aclk_ddr_vepu_rate); + clk_set_rate_nolock(&hclk_vepu, hclk_vepu_rate); + clk_set_parent_nolock(&aclk_vdpu, aclk_vdpu_parent); + clk_set_parent_nolock(&aclk_gpu, aclk_gpu_parent); + clk_set_rate_nolock(&aclk_gpu,aclk_gpu_rate); } - static void __init clk_enable_init_clocks(void) { clk_enable_nolock(&hclk_cpu); @@ -2421,7 +2528,7 @@ static int __init clk_disable_unused(void) return 0; } -void __init rk29_clock_init(void) +void __init rk29_clock_init(unsigned long ppll_rate) { struct clk_lookup *lk; @@ -2449,7 +2556,7 @@ void __init rk29_clock_init(void) */ clk_disable_unused(); - rk29_clock_common_init(); + rk29_clock_common_init(ppll_rate); printk(KERN_INFO "Clocking rate (apll/dpll/cpll/gpll/core/aclk_cpu/hclk_cpu/pclk_cpu/aclk_periph/hclk_periph/pclk_periph): %ld/%ld/%ld/%ld/%ld/%ld/%ld/%ld/%ld/%ld/%ld MHz\n", arm_pll_clk.rate / MHZ, ddr_pll_clk.rate / MHZ, codec_pll_clk.rate / MHZ, general_pll_clk.rate / MHZ, clk_core.rate / MHZ, diff --git a/arch/arm/mach-rk29/include/mach/board.h b/arch/arm/mach-rk29/include/mach/board.h index e16ef7a2bd02..fe03a22769ed 100755 --- a/arch/arm/mach-rk29/include/mach/board.h +++ b/arch/arm/mach-rk29/include/mach/board.h @@ -233,7 +233,7 @@ struct tca6424_platform_data { void __init rk29_setup_early_printk(void); void __init rk29_map_common_io(void); -void __init rk29_clock_init(void); +void __init rk29_clock_init(unsigned long ppll_rate); void __init board_power_init(void); #define BOOT_MODE_NORMAL 0 @@ -243,6 +243,12 @@ void __init board_power_init(void); #define BOOT_MODE_POWER_TEST 4 #define BOOT_MODE_OFFMODE_CHARGING 5 int board_boot_mode(void); +enum periph_pll{ + periph_pll_96mhz=96000000, + periph_pll_144mhz=144000000, + periph_pll_288mhz=288000000, + periph_pll_300mhz=300000000, +}; /* for USB detection */ #ifdef CONFIG_USB_GADGET diff --git a/sound/soc/rk29/rk29_i2s.c b/sound/soc/rk29/rk29_i2s.c index 0ae4212329e1..cdf68ecf2775 100755 --- a/sound/soc/rk29/rk29_i2s.c +++ b/sound/soc/rk29/rk29_i2s.c @@ -569,6 +569,8 @@ static int __devinit rockchip_i2s_probe(struct platform_device *pdev) { struct rk29_i2s_info *i2s; struct snd_soc_dai *dai; + struct clk *general_pll; + unsigned long i2smclk; int ret; I2S_DBG("Enter %s, %d pdev->id = %d >>>>>>>>>>>\n", __func__, __LINE__, pdev->id); @@ -631,7 +633,21 @@ static int __devinit rockchip_i2s_probe(struct platform_device *pdev) } clk_enable(i2s->iis_clk); - clk_set_rate(i2s->iis_clk, 11289600); + general_pll=clk_get(NULL, "general_pll"); + if(clk_get_rate(general_pll)>260000000) + { + i2smclk=11289600; + } + else if(clk_get_rate(general_pll)>130000000) + { + i2smclk=11289600/2; + } + else + { + i2smclk=11289600/4; + } + I2S_DBG("func is %s,general pll=%ld,mclk=%ld\n",__FUNCTION__,clk_get_rate(general_pll),i2smclk); + clk_set_rate(i2s->iis_clk, i2smclk); ret = rk29_i2s_probe(pdev, dai, i2s, 0); if (ret) goto err_clk; diff --git a/sound/soc/rk29/rk29_wm8900.c b/sound/soc/rk29/rk29_wm8900.c old mode 100644 new mode 100755 index c82169294ba3..e7430080ee91 --- a/sound/soc/rk29/rk29_wm8900.c +++ b/sound/soc/rk29/rk29_wm8900.c @@ -23,6 +23,7 @@ #include "../codecs/wm8900.h" #include "rk29_pcm.h" #include "rk29_i2s.h" +#include #if 0 #define DBG(x...) printk(KERN_INFO x) @@ -38,7 +39,9 @@ static int rk29_hw_params(struct snd_pcm_substream *substream, struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; unsigned int pll_out = 0; unsigned int lrclk = 0; + int div_bclk,div_mclk; int ret; + struct clk *general_pll; DBG("Enter::%s----%d\n",__FUNCTION__,__LINE__); /*by Vincent Hsiung for EQ Vol Change*/ @@ -110,9 +113,28 @@ static int rk29_hw_params(struct snd_pcm_substream *substream, #endif #if defined (CONFIG_SND_RK29_CODEC_SOC_SLAVE) - snd_soc_dai_set_sysclk(cpu_dai, 0, pll_out, 0); - snd_soc_dai_set_clkdiv(cpu_dai, ROCKCHIP_DIV_BCLK, (pll_out/4)/params_rate(params)-1); - snd_soc_dai_set_clkdiv(cpu_dai, ROCKCHIP_DIV_MCLK, 3); + general_pll=clk_get(NULL, "general_pll"); + if(clk_get_rate(general_pll)>260000000) + { + div_bclk=(pll_out/4)/params_rate(params)-1; + div_mclk=3; + } + else if(clk_get_rate(general_pll)>130000000) + { + div_bclk=(pll_out/2)/params_rate(params)-1; + div_mclk=1; + } + else + { + pll_out=pll_out/4; + div_bclk=(pll_out)/params_rate(params)-1; + div_mclk=0; + } + DBG("func is%s,gpll=%ld,pll_out=%ld,div_mclk=%ld\n", + __FUNCTION__,clk_get_rate(general_pll),pll_out,div_mclk); + snd_soc_dai_set_sysclk(cpu_dai, 0, pll_out, 0); + snd_soc_dai_set_clkdiv(cpu_dai, ROCKCHIP_DIV_BCLK,div_bclk); + snd_soc_dai_set_clkdiv(cpu_dai, ROCKCHIP_DIV_MCLK, div_mclk); #endif DBG("Enter:%s, %d, LRCK=%d\n",__FUNCTION__,__LINE__,(pll_out/4)/params_rate(params)); -- 2.34.1