예제 #1
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;
	
	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;
}
예제 #2
0
파일: clock-perf.c 프로젝트: Arakmar/G3MOD
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;
}