|  | @@ -135,3 +135,85 @@ static struct sh_clk_ops pllc01_clk_ops = {
 | 
											
												
													
														|  |  static struct clk pllc0_clk = {
 |  |  static struct clk pllc0_clk = {
 | 
											
												
													
														|  |  	.ops		= &pllc01_clk_ops,
 |  |  	.ops		= &pllc01_clk_ops,
 | 
											
												
													
														|  |  	.flags		= CLK_ENABLE_ON_INIT,
 |  |  	.flags		= CLK_ENABLE_ON_INIT,
 | 
											
												
													
														|  | 
 |  | +	.parent		= &extal1_div2_clk,
 | 
											
												
													
														|  | 
 |  | +	.enable_reg	= (void __iomem *)FRQCRC,
 | 
											
												
													
														|  | 
 |  | +};
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +static struct clk pllc1_clk = {
 | 
											
												
													
														|  | 
 |  | +	.ops		= &pllc01_clk_ops,
 | 
											
												
													
														|  | 
 |  | +	.flags		= CLK_ENABLE_ON_INIT,
 | 
											
												
													
														|  | 
 |  | +	.parent		= &extal1_div2_clk,
 | 
											
												
													
														|  | 
 |  | +	.enable_reg	= (void __iomem *)FRQCRA,
 | 
											
												
													
														|  | 
 |  | +};
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +/* Divide PLLC1 by two */
 | 
											
												
													
														|  | 
 |  | +static struct clk pllc1_div2_clk = {
 | 
											
												
													
														|  | 
 |  | +	.ops		= &div2_clk_ops,
 | 
											
												
													
														|  | 
 |  | +	.parent		= &pllc1_clk,
 | 
											
												
													
														|  | 
 |  | +};
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +/* PLLC2 */
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +/* Indices are important - they are the actual src selecting values */
 | 
											
												
													
														|  | 
 |  | +static struct clk *pllc2_parent[] = {
 | 
											
												
													
														|  | 
 |  | +	[0] = &extal1_div2_clk,
 | 
											
												
													
														|  | 
 |  | +	[1] = &extal2_div2_clk,
 | 
											
												
													
														|  | 
 |  | +	[2] = &sh7372_dv_clki_div2_clk,
 | 
											
												
													
														|  | 
 |  | +};
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +/* Only multipliers 20 * 2 to 46 * 2 are valid, last entry for CPUFREQ_TABLE_END */
 | 
											
												
													
														|  | 
 |  | +static struct cpufreq_frequency_table pllc2_freq_table[29];
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +static void pllc2_table_rebuild(struct clk *clk)
 | 
											
												
													
														|  | 
 |  | +{
 | 
											
												
													
														|  | 
 |  | +	int i;
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +	/* Initialise PLLC2 frequency table */
 | 
											
												
													
														|  | 
 |  | +	for (i = 0; i < ARRAY_SIZE(pllc2_freq_table) - 2; i++) {
 | 
											
												
													
														|  | 
 |  | +		pllc2_freq_table[i].frequency = clk->parent->rate * (i + 20) * 2;
 | 
											
												
													
														|  | 
 |  | +		pllc2_freq_table[i].index = i;
 | 
											
												
													
														|  | 
 |  | +	}
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +	/* This is a special entry - switching PLL off makes it a repeater */
 | 
											
												
													
														|  | 
 |  | +	pllc2_freq_table[i].frequency = clk->parent->rate;
 | 
											
												
													
														|  | 
 |  | +	pllc2_freq_table[i].index = i;
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +	pllc2_freq_table[++i].frequency = CPUFREQ_TABLE_END;
 | 
											
												
													
														|  | 
 |  | +	pllc2_freq_table[i].index = i;
 | 
											
												
													
														|  | 
 |  | +}
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +static unsigned long pllc2_recalc(struct clk *clk)
 | 
											
												
													
														|  | 
 |  | +{
 | 
											
												
													
														|  | 
 |  | +	unsigned long mult = 1;
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +	pllc2_table_rebuild(clk);
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +	/*
 | 
											
												
													
														|  | 
 |  | +	 * If the PLL is off, mult == 1, clk->rate will be updated in
 | 
											
												
													
														|  | 
 |  | +	 * pllc2_enable().
 | 
											
												
													
														|  | 
 |  | +	 */
 | 
											
												
													
														|  | 
 |  | +	if (__raw_readl(PLLC2CR) & (1 << 31))
 | 
											
												
													
														|  | 
 |  | +		mult = (((__raw_readl(PLLC2CR) >> 24) & 0x3f) + 1) * 2;
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +	return clk->parent->rate * mult;
 | 
											
												
													
														|  | 
 |  | +}
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +static long pllc2_round_rate(struct clk *clk, unsigned long rate)
 | 
											
												
													
														|  | 
 |  | +{
 | 
											
												
													
														|  | 
 |  | +	return clk_rate_table_round(clk, clk->freq_table, rate);
 | 
											
												
													
														|  | 
 |  | +}
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +static int pllc2_enable(struct clk *clk)
 | 
											
												
													
														|  | 
 |  | +{
 | 
											
												
													
														|  | 
 |  | +	int i;
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +	__raw_writel(__raw_readl(PLLC2CR) | 0x80000000, PLLC2CR);
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +	for (i = 0; i < 100; i++)
 | 
											
												
													
														|  | 
 |  | +		if (__raw_readl(PLLC2CR) & 0x80000000) {
 | 
											
												
													
														|  | 
 |  | +			clk->rate = pllc2_recalc(clk);
 | 
											
												
													
														|  | 
 |  | +			return 0;
 | 
											
												
													
														|  | 
 |  | +		}
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +	pr_err("%s(): timeout!\n", __func__);
 | 
											
												
													
														|  | 
 |  | +
 |