From 7633432049f9c04e8af0b5ba1ee2c4b922b08c53 Mon Sep 17 00:00:00 2001 From: yxj Date: Sun, 21 Apr 2013 10:12:27 +0800 Subject: [PATCH] mfd:rk616:core:add pll config --- drivers/mfd/rk616-core.c | 72 +++++++++++++++++++++++++++++++++++++++ include/linux/mfd/rk616.h | 10 ++++++ 2 files changed, 82 insertions(+) diff --git a/drivers/mfd/rk616-core.c b/drivers/mfd/rk616-core.c index cb929603d712..ee6ef15e1733 100644 --- a/drivers/mfd/rk616-core.c +++ b/drivers/mfd/rk616-core.c @@ -222,6 +222,74 @@ static int rk616_pll_clk_get_set(struct mfd_rk616 *rk616,unsigned long fin_hz,un return 0; } + +static int rk616_pll_wait_lock(struct mfd_rk616 *rk616,int id) +{ + u32 delay = 50; + u32 val ; + int ret; + int offset; + + if(id == 0) //PLL0 + { + offset = 0; + } + else // PLL1 + { + offset = 0x0c; + } + while (delay >= 1) + { + ret = rk616->write_dev(rk616,CRU_PLL0_CON1 + offset,&val); + if (val&PLL0_LOCK) + { + break; + } + msleep(1); + printk("0x%08x\n",val); + delay--; + } + if (delay == 1) + { + dev_err(rk616->dev,"wait pll bit time out!\n"); + while(1); + } + + return 0; +} + +static int rk616_pll_cfg(struct mfd_rk616 *rk616,int id) +{ + u32 val = 0; + int ret; + int offset; + if(id == 0) //PLL0 + { + offset = 0; + } + else // PLL1 + { + offset = 0x0c; + } + + val = PLL0_PWR_DN | (PLL0_PWR_DN << 16); + ret = rk616->write_dev(rk616,CRU_PLL0_CON1 + offset,&val); + + val = PLL0_POSTDIV1(1) | PLL0_FBDIV(20) | PLL0_POSTDIV1_MASK | + PLL0_FBDIV_MASK | (PLL0_BYPASS << 16); + ret = rk616->write_dev(rk616,CRU_PLL0_CON0 + offset,&val); + + val = PLL0_DIV_MODE | PLL0_POSTDIV2(1) | PLL0_REFDIV(20) | + (PLL0_DIV_MODE << 16) | PLL0_POSTDIV1_MASK | PLL0_REFDIV_MASK; + ret = rk616->write_dev(rk616,CRU_PLL0_CON1 + offset,&val); + + val = (PLL0_PWR_DN << 16); + ret = rk616->write_dev(rk616,CRU_PLL0_CON1 + offset,&val); + rk616_pll_wait_lock(rk616,id); + + return 0; + +} /*********************************** default clk patch settiing: CLKIN-------->CODEC @@ -245,8 +313,12 @@ static int rk616_clk_common_init(struct mfd_rk616 *rk616) val = 0; //codec mck = clkin ret = rk616->write_dev(rk616,CRU_CODEC_DIV,&val); +#if 0 val = (PLL0_BYPASS) | (PLL0_BYPASS << 16); //bypass pll0 ret = rk616->write_dev(rk616,CRU_PLL0_CON0,&val); +#else + rk616_pll_cfg(rk616,0); +#endif val = (PLL1_BYPASS) | (PLL1_BYPASS << 16); ret = rk616->write_dev(rk616,CRU_PLL1_CON0,&val); diff --git a/include/linux/mfd/rk616.h b/include/linux/mfd/rk616.h index 74dcf72181a2..d7993b1b618d 100644 --- a/include/linux/mfd/rk616.h +++ b/include/linux/mfd/rk616.h @@ -83,11 +83,16 @@ #define VIF0_CLK_SEL (1<<0) #define CRU_PLL0_CON0 0x0068 +#define PLL0_POSTDIV1_MASK (7<<28) +#define PLL0_FBDIV_MASK (0xfff << 16) #define PLL0_BYPASS (1<<15) #define PLL0_POSTDIV1(x) (((x)&7)<<12) #define PLL0_FBDIV(x) (((x)&0xfff)<<0) #define CRU_PLL0_CON1 0x006C +#define PLL0_POSTDIV2_MASK (7<<22) +#define PLL0_REFDIV_MASK (0x3f<<16) +#define PLL0_LOCK (1<<15) #define PLL0_PWR_DN (1<<10) #define PLL0_DIV_MODE (1<<9) #define PLL0_POSTDIV2(x) (((x)&7)<<6) @@ -101,11 +106,16 @@ #define PLL0_FRAC(x) (((x)&0xffffff)<0) #define CRU_PLL1_CON0 0x0074 +#define PLL1_POSTDIV1_MASK (7<<28) +#define PLL1_FBDIV_MASK (0xfff << 16) #define PLL1_BYPASS (1<<15) #define PLL1_POSTDIV1(x) (((x)&7)<<12) #define PLL1_FBDIV(x) (((x)&0xfff)<<0) #define CRU_PLL1_CON1 0x0078 +#define PLL1_POSTDIV2_MASK (7<<22) +#define PLL1_REFDIV_MASK (0x3f<<16) +#define PLL1_LOCK (1<<15) #define PLL1_PWR_DN (1<<10) #define PLL1_DIV_MODE (1<<9) #define PLL1_POSTDIV2(x) (((x)&7)<<6) -- 2.34.1