int s5p6442_clk_set_rate(unsigned int target_freq, unsigned int index ) { int pll_change = 0; int cur_freq; unsigned int mask; u32 clk_div0; u32 size; int timeout = 1000; //10 msec //10 usec uints static int flag = 0; static unsigned int hd0_clk; static unsigned int hd1_clk; static unsigned int arm_clk, clk_tmp; static u32 (*cpu_clk_tab)[10]; static int cur_idx; if (!flag){ hd0_clk = clk_hd0.rate; hd1_clk = clk_hd1.rate; arm_clk = clk_f.rate; cur_idx = 3; flag = 1; } cpu_clk_tab = s5p_cpu_clk_tab_666_166MHz; size = s5p_cpu_clk_tab_size(); if(index >= size) return 1; if (index == cur_idx) return 0; mask = (~S5P_CLKDIV0_APLL_MASK) & (~S5P_CLKDIV0_D0CLK_MASK) & (~S5P_CLKDIV0_P0CLK_MASK) & (~S5P_CLKDIV0_D1CLK_MASK) & (~S5P_CLKDIV0_P1CLK_MASK); clk_div0 = __raw_readl(S5P_CLK_DIV0) & mask; clk_div0 |= cpu_clk_tab[index][5] << S5P_CLKDIV0_APLL_SHIFT; clk_div0 |= (cpu_clk_tab[index][6]) << S5P_CLKDIV0_D0CLK_SHIFT; clk_div0 |= (cpu_clk_tab[index][7]) << S5P_CLKDIV0_P0CLK_SHIFT; clk_div0 |= (cpu_clk_tab[index][8]) << S5P_CLKDIV0_D1CLK_SHIFT; clk_div0 |= (cpu_clk_tab[index][9]) << S5P_CLKDIV0_P1CLK_SHIFT; #ifdef MUXD0D1_A2M clk_div0 &= ~(S5P_CLKDIV0_A2M_MASK ); clk_div0 |= (cpu_clk_tab[index][4] << S5P_CLKDIV0_A2M_SHIFT); #endif /* MUXD0D1_A2M */ if (index > cur_idx) { clk_tmp = __raw_readl(S5P_APLL_CON); // printk("----> s5p6442 : APLL_CON = %x - will be changed to apll_tab = %x (index=%d)\n", clk_tmp, s5p_cpu_pll_tab[index][0], index); if (clk_tmp != s5p_cpu_pll_tab[index]) { pll_change = 1; __raw_writel(0xe10, S5P_APLL_LOCK); __raw_writel(s5p_cpu_pll_tab[index],S5P_APLL_CON); // printk("----> s5p6442 : apll changed\n"); } /* clk_tmp = __raw_readl(S5P_MPLL_CON); // printk("----> s5p6442 : MPLL_CON = %x - will be changed to mpll_tab = %x (index=%d)\n", clk_tmp, s5p_cpu_pll_tab[index][1],index); if (clk_tmp != s5p_cpu_pll_tab[index][1]) { pll_change = 1; __raw_writel(0xe10, S5P_MPLL_LOCK); __raw_writel(s5p_cpu_pll_tab[index][1],S5P_MPLL_CON); // printk("----> s5p6442 : mpll changed\n"); } */ // printk("----> s5p6442 : clk_div0 before : %x \n", __raw_readl(S5P_CLK_DIV0)); s5p6442_changeDivider(clk_div0, (int) S5P_CLK_DIV0); // printk("----> s5p6442 : clk_div0 after : %x \n", __raw_readl(S5P_CLK_DIV0)); } else { // printk("----> s5p6442 : clk_div0 before : %x \n", __raw_readl(S5P_CLK_DIV0)); s5p6442_changeDivider(clk_div0, (int) S5P_CLK_DIV0); // printk("----> s5p6442 : clk_div0 after : %x \n", __raw_readl(S5P_CLK_DIV0)); clk_tmp = __raw_readl(S5P_APLL_CON); // printk("----> s5p6442 : APLL_CON = %x - will be changed to apll_tab = %x (index=%d)\n", clk_tmp, s5p_cpu_pll_tab[index][0], index); if (clk_tmp != s5p_cpu_pll_tab[index]) { pll_change = 1; __raw_writel(0xe10, S5P_APLL_LOCK); __raw_writel(s5p_cpu_pll_tab[index],S5P_APLL_CON); // printk("----> s5p6442 : apll changed\n"); } /* clk_tmp = __raw_readl(S5P_MPLL_CON); // printk("----> s5p6442 : MPLL_CON = %x - will be changed to mpll_tab = %x (index=%d)\n", clk_tmp, s5p_cpu_pll_tab[index][1],index); if (clk_tmp != s5p_cpu_pll_tab[index][1]) { pll_change = 1; __raw_writel(0xe10, S5P_MPLL_LOCK); __raw_writel(s5p_cpu_pll_tab[index][1],S5P_MPLL_CON); // printk("----> s5p6442 : mpll changed\n"); } */ } __raw_writel(0x00001111, S5P_CLK_SRC0); arm_clk = s5p_fclk_get_rate(); __raw_writel(AVG_PRD_REFRESH_INTERVAL_166MHZ, S5P_DRAMC_TIMINGAREF); while(__raw_readl(S5P_CLK_DIV_STAT0) && (timeout > 0)){ timeout--; udelay(10); } if (pll_change == 1) { s5p_cpu_pll_tab[index] = __raw_readl(S5P_APLL_CON); // s5p_cpu_pll_tab[index][1] = __raw_readl(S5P_MPLL_CON); // printk("----> s5p6442 : stored new values : apll %x mpll %x\n", s5p_cpu_pll_tab[index][0], s5p_cpu_pll_tab[index][1]); } clk_f.rate = arm_clk / (cpu_clk_tab[index][5] + 1); clk_hd0.rate = (hd0_clk / (cpu_clk_tab[index][6] + 1)); clk_hd1.rate = (hd1_clk / (cpu_clk_tab[index][8] + 1)); clk_pd0.rate = clk_hd0.rate/ (cpu_clk_tab[index][7] + 1); clk_pd1.rate = clk_hd1.rate/ (cpu_clk_tab[index][9] + 1); /* For backward compatibility */ clk_h.rate = clk_hd1.rate; clk_p.rate = clk_pd1.rate; // printk("#####arm_clk %d hd0_clk %d p0_clk %d hd1_clk %d p1_clk %d clkdiv0 %x timeout %d\n", clk_f.rate, clk_hd0.rate, clk_pd0.rate, // clk_hd1.rate, clk_pd1.rate, clk_div0, timeout); cur_idx = index; return 0; }
int s5p6442_clk_set_rate(unsigned int target_freq, unsigned int index ) { int pll_change = 0; int cur_freq; unsigned int mask; u32 clk_div0; u32 size; int timeout = 1000; //10 msec //10 usec uints static int flag = 0; static unsigned int hd0_clk; static unsigned int hd1_clk; static unsigned int arm_clk, clk_tmp; static u32 (*cpu_clk_tab)[10]; static int cur_idx; if (!flag){ hd0_clk = clk_hd0.rate; hd1_clk = clk_hd1.rate; arm_clk = clk_f.rate; cur_idx = 3; flag = 1; } cpu_clk_tab = s5p_cpu_clk_tab_666_166MHz; size = s5p_cpu_clk_tab_size(); if(index >= size) return 1; if (index == cur_idx) return 0; if(cpu_clk_tab[index][6] > 0) __raw_writel(s5p_avg_prd_refresh_rate[S5P6442_FREQ_TAB * 2 + 1], S5P_DRAMC_TIMINGAREF); mask = (~S5P_CLKDIV0_APLL_MASK) & (~S5P_CLKDIV0_D0CLK_MASK) & (~S5P_CLKDIV0_P0CLK_MASK) & (~S5P_CLKDIV0_D1CLK_MASK) & (~S5P_CLKDIV0_P1CLK_MASK); clk_div0 = __raw_readl(S5P_CLK_DIV0) & mask; clk_div0 |= cpu_clk_tab[index][5] << S5P_CLKDIV0_APLL_SHIFT; clk_div0 |= (cpu_clk_tab[index][6]) << S5P_CLKDIV0_D0CLK_SHIFT; clk_div0 |= (cpu_clk_tab[index][7]) << S5P_CLKDIV0_P0CLK_SHIFT; clk_div0 |= (cpu_clk_tab[index][8]) << S5P_CLKDIV0_D1CLK_SHIFT; clk_div0 |= (cpu_clk_tab[index][9]) << S5P_CLKDIV0_P1CLK_SHIFT; #ifdef MUXD0D1_A2M clk_div0 &= ~(S5P_CLKDIV0_A2M_MASK ); clk_div0 |= (cpu_clk_tab[index][4] << S5P_CLKDIV0_A2M_SHIFT); #endif /* MUXD0D1_A2M */ if (index > cur_idx) { clk_tmp = __raw_readl(S5P_APLL_CON); if (clk_tmp != s5p_cpu_pll_tab[index][0]) { pll_change = 1; __raw_writel(0xe10, S5P_APLL_LOCK); __raw_writel(s5p_cpu_pll_tab[index][0],S5P_APLL_CON); } clk_tmp = __raw_readl(S5P_MPLL_CON); if (clk_tmp != s5p_cpu_pll_tab[index][1]) { pll_change = 1; __raw_writel(0xe10, S5P_MPLL_LOCK); __raw_writel(s5p_cpu_pll_tab[index][1],S5P_MPLL_CON); } s5p6442_changeDivider(clk_div0, S5P_CLK_DIV0); } else { s5p6442_changeDivider(clk_div0, S5P_CLK_DIV0); clk_tmp = __raw_readl(S5P_APLL_CON); if (clk_tmp != s5p_cpu_pll_tab[index][0]) { pll_change = 1; __raw_writel(0xe10, S5P_APLL_LOCK); __raw_writel(s5p_cpu_pll_tab[index][0],S5P_APLL_CON); } clk_tmp = __raw_readl(S5P_MPLL_CON); if (clk_tmp != s5p_cpu_pll_tab[index][1]) { pll_change = 1; __raw_writel(0xe10, S5P_MPLL_LOCK); __raw_writel(s5p_cpu_pll_tab[index][1],S5P_MPLL_CON); } } __raw_writel(0x00001111, S5P_CLK_SRC0); arm_clk = s5p_fclk_get_rate(); if(cpu_clk_tab[index][6] == 0) __raw_writel(s5p_avg_prd_refresh_rate[S5P6442_FREQ_TAB * 2], S5P_DRAMC_TIMINGAREF); while(__raw_readl(S5P_CLK_DIV_STAT0) && (timeout > 0)){ timeout--; udelay(10); } if (pll_change == 1) { s5p_cpu_pll_tab[index][0] = __raw_readl(S5P_APLL_CON); s5p_cpu_pll_tab[index][1] = __raw_readl(S5P_MPLL_CON); } clk_f.rate = arm_clk / (cpu_clk_tab[index][5] + 1); clk_hd0.rate = (hd0_clk / (cpu_clk_tab[index][6] + 1)); clk_hd1.rate = (hd1_clk / (cpu_clk_tab[index][8] + 1)); clk_pd0.rate = clk_hd0.rate/ (cpu_clk_tab[index][7] + 1); clk_pd1.rate = clk_hd1.rate/ (cpu_clk_tab[index][9] + 1); /* For backward compatibility */ clk_h.rate = clk_hd1.rate; clk_p.rate = clk_pd1.rate; cur_idx = index; return 0; }