| 
									
										
										
										
											2013-03-26 10:34:24 +09:00
										 |  |  | /*
 | 
					
						
							|  |  |  |  * r8a73a4 clock framework support | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Copyright (C) 2013  Renesas Solutions Corp. | 
					
						
							|  |  |  |  * Copyright (C) 2013  Magnus Damm | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * This program is free software; you can redistribute it and/or modify | 
					
						
							|  |  |  |  * it under the terms of the GNU General Public License as published by | 
					
						
							|  |  |  |  * the Free Software Foundation; version 2 of the License. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * This program is distributed in the hope that it will be useful, | 
					
						
							|  |  |  |  * but WITHOUT ANY WARRANTY; without even the implied warranty of | 
					
						
							|  |  |  |  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | 
					
						
							|  |  |  |  * GNU General Public License for more details. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * You should have received a copy of the GNU General Public License | 
					
						
							|  |  |  |  * along with this program; if not, write to the Free Software | 
					
						
							|  |  |  |  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | #include <linux/init.h>
 | 
					
						
							|  |  |  | #include <linux/io.h>
 | 
					
						
							|  |  |  | #include <linux/kernel.h>
 | 
					
						
							|  |  |  | #include <linux/sh_clk.h>
 | 
					
						
							|  |  |  | #include <linux/clkdev.h>
 | 
					
						
							| 
									
										
										
										
											2014-06-17 16:47:37 +09:00
										 |  |  | #include "common.h"
 | 
					
						
							| 
									
										
										
										
											2014-06-17 16:47:21 +09:00
										 |  |  | #include "clock.h"
 | 
					
						
							| 
									
										
										
										
											2013-03-26 10:34:24 +09:00
										 |  |  | 
 | 
					
						
							|  |  |  | #define CPG_BASE 0xe6150000
 | 
					
						
							|  |  |  | #define CPG_LEN 0x270
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-03-26 10:34:33 +09:00
										 |  |  | #define SMSTPCR2 0xe6150138
 | 
					
						
							| 
									
										
										
										
											2013-05-17 16:55:14 +02:00
										 |  |  | #define SMSTPCR3 0xe615013c
 | 
					
						
							| 
									
										
										
										
											2013-06-27 11:47:56 +02:00
										 |  |  | #define SMSTPCR4 0xe6150140
 | 
					
						
							| 
									
										
										
										
											2013-03-25 23:18:15 -07:00
										 |  |  | #define SMSTPCR5 0xe6150144
 | 
					
						
							| 
									
										
										
										
											2013-03-26 10:34:24 +09:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-04-04 21:22:16 -07:00
										 |  |  | #define FRQCRA		0xE6150000
 | 
					
						
							|  |  |  | #define FRQCRB		0xE6150004
 | 
					
						
							| 
									
										
										
										
											2013-05-22 11:12:37 +02:00
										 |  |  | #define FRQCRC		0xE61500E0
 | 
					
						
							| 
									
										
										
										
											2013-04-04 21:22:41 -07:00
										 |  |  | #define VCLKCR1		0xE6150008
 | 
					
						
							|  |  |  | #define VCLKCR2		0xE615000C
 | 
					
						
							|  |  |  | #define VCLKCR3		0xE615001C
 | 
					
						
							|  |  |  | #define VCLKCR4		0xE6150014
 | 
					
						
							|  |  |  | #define VCLKCR5		0xE6150034
 | 
					
						
							|  |  |  | #define ZBCKCR		0xE6150010
 | 
					
						
							|  |  |  | #define SD0CKCR		0xE6150074
 | 
					
						
							|  |  |  | #define SD1CKCR		0xE6150078
 | 
					
						
							|  |  |  | #define SD2CKCR		0xE615007C
 | 
					
						
							|  |  |  | #define MMC0CKCR	0xE6150240
 | 
					
						
							|  |  |  | #define MMC1CKCR	0xE6150244
 | 
					
						
							|  |  |  | #define FSIACKCR	0xE6150018
 | 
					
						
							|  |  |  | #define FSIBCKCR	0xE6150090
 | 
					
						
							|  |  |  | #define MPCKCR		0xe6150080
 | 
					
						
							|  |  |  | #define SPUVCKCR	0xE6150094
 | 
					
						
							|  |  |  | #define HSICKCR		0xE615026C
 | 
					
						
							|  |  |  | #define M4CKCR		0xE6150098
 | 
					
						
							| 
									
										
										
										
											2013-04-04 21:21:39 -07:00
										 |  |  | #define PLLECR		0xE61500D0
 | 
					
						
							| 
									
										
										
										
											2013-05-22 11:12:37 +02:00
										 |  |  | #define PLL0CR		0xE61500D8
 | 
					
						
							| 
									
										
										
										
											2013-04-04 21:21:39 -07:00
										 |  |  | #define PLL1CR		0xE6150028
 | 
					
						
							|  |  |  | #define PLL2CR		0xE615002C
 | 
					
						
							|  |  |  | #define PLL2SCR		0xE61501F4
 | 
					
						
							|  |  |  | #define PLL2HCR		0xE61501E4
 | 
					
						
							| 
									
										
										
										
											2013-04-04 21:22:41 -07:00
										 |  |  | #define CKSCR		0xE61500C0
 | 
					
						
							| 
									
										
										
										
											2013-04-04 21:21:39 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | #define CPG_MAP(o) ((o - CPG_BASE) + cpg_mapping.base)
 | 
					
						
							| 
									
										
										
										
											2013-04-04 21:20:40 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-03-26 10:34:24 +09:00
										 |  |  | static struct clk_mapping cpg_mapping = { | 
					
						
							|  |  |  | 	.phys   = CPG_BASE, | 
					
						
							|  |  |  | 	.len    = CPG_LEN, | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static struct clk extalr_clk = { | 
					
						
							|  |  |  | 	.rate	= 32768, | 
					
						
							|  |  |  | 	.mapping	= &cpg_mapping, | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static struct clk extal1_clk = { | 
					
						
							|  |  |  | 	.rate	= 26000000, | 
					
						
							|  |  |  | 	.mapping	= &cpg_mapping, | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static struct clk extal2_clk = { | 
					
						
							|  |  |  | 	.rate	= 48000000, | 
					
						
							|  |  |  | 	.mapping	= &cpg_mapping, | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-04-04 21:20:40 -07:00
										 |  |  | static struct sh_clk_ops followparent_clk_ops = { | 
					
						
							|  |  |  | 	.recalc	= followparent_recalc, | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static struct clk main_clk = { | 
					
						
							|  |  |  | 	/* .parent will be set r8a73a4_clock_init */ | 
					
						
							|  |  |  | 	.ops	= &followparent_clk_ops, | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | SH_CLK_RATIO(div2,	1, 2); | 
					
						
							|  |  |  | SH_CLK_RATIO(div4,	1, 4); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | SH_FIXED_RATIO_CLK(main_div2_clk,	main_clk,		div2); | 
					
						
							|  |  |  | SH_FIXED_RATIO_CLK(extal1_div2_clk,	extal1_clk,		div2); | 
					
						
							|  |  |  | SH_FIXED_RATIO_CLK(extal2_div2_clk,	extal2_clk,		div2); | 
					
						
							|  |  |  | SH_FIXED_RATIO_CLK(extal2_div4_clk,	extal2_clk,		div4); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-04-04 21:22:41 -07:00
										 |  |  | /* External FSIACK/FSIBCK clock */ | 
					
						
							|  |  |  | static struct clk fsiack_clk = { | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static struct clk fsibck_clk = { | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-04-04 21:21:39 -07:00
										 |  |  | /*
 | 
					
						
							|  |  |  |  *		PLL clocks | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | static struct clk *pll_parent_main[] = { | 
					
						
							|  |  |  | 	[0] = &main_clk, | 
					
						
							|  |  |  | 	[1] = &main_div2_clk | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static struct clk *pll_parent_main_extal[8] = { | 
					
						
							|  |  |  | 	[0] = &main_div2_clk, | 
					
						
							|  |  |  | 	[1] = &extal2_div2_clk, | 
					
						
							|  |  |  | 	[3] = &extal2_div4_clk, | 
					
						
							|  |  |  | 	[4] = &main_clk, | 
					
						
							|  |  |  | 	[5] = &extal2_clk, | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static unsigned long pll_recalc(struct clk *clk) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	unsigned long mult = 1; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (ioread32(CPG_MAP(PLLECR)) & (1 << clk->enable_bit)) | 
					
						
							|  |  |  | 		mult = (((ioread32(clk->mapped_reg) >> 24) & 0x7f) + 1); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return clk->parent->rate * mult; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static int pll_set_parent(struct clk *clk, struct clk *parent) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	u32 val; | 
					
						
							|  |  |  | 	int i, ret; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (!clk->parent_table || !clk->parent_num) | 
					
						
							|  |  |  | 		return -EINVAL; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* Search the parent */ | 
					
						
							|  |  |  | 	for (i = 0; i < clk->parent_num; i++) | 
					
						
							|  |  |  | 		if (clk->parent_table[i] == parent) | 
					
						
							|  |  |  | 			break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (i == clk->parent_num) | 
					
						
							|  |  |  | 		return -ENODEV; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	ret = clk_reparent(clk, parent); | 
					
						
							|  |  |  | 	if (ret < 0) | 
					
						
							|  |  |  | 		return ret; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	val = ioread32(clk->mapped_reg) & | 
					
						
							|  |  |  | 		~(((1 << clk->src_width) - 1) << clk->src_shift); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	iowrite32(val | i << clk->src_shift, clk->mapped_reg); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static struct sh_clk_ops pll_clk_ops = { | 
					
						
							|  |  |  | 	.recalc		= pll_recalc, | 
					
						
							|  |  |  | 	.set_parent	= pll_set_parent, | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #define PLL_CLOCK(name, p, pt, w, s, reg, e)		\
 | 
					
						
							|  |  |  | 	static struct clk name = {			\ | 
					
						
							|  |  |  | 		.ops		= &pll_clk_ops,		\ | 
					
						
							|  |  |  | 		.flags		= CLK_ENABLE_ON_INIT,	\ | 
					
						
							|  |  |  | 		.parent		= p,			\ | 
					
						
							|  |  |  | 		.parent_table	= pt,			\ | 
					
						
							|  |  |  | 		.parent_num	= ARRAY_SIZE(pt),	\ | 
					
						
							|  |  |  | 		.src_width	= w,			\ | 
					
						
							|  |  |  | 		.src_shift	= s,			\ | 
					
						
							|  |  |  | 		.enable_reg	= (void __iomem *)reg,	\ | 
					
						
							|  |  |  | 		.enable_bit	= e,			\ | 
					
						
							|  |  |  | 		.mapping	= &cpg_mapping,		\ | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-05-22 11:12:37 +02:00
										 |  |  | PLL_CLOCK(pll0_clk,  &main_clk,      pll_parent_main,      1, 20, PLL0CR,  0); | 
					
						
							| 
									
										
										
										
											2013-04-04 21:21:39 -07:00
										 |  |  | PLL_CLOCK(pll1_clk,  &main_clk,      pll_parent_main,       1, 7, PLL1CR,  1); | 
					
						
							|  |  |  | PLL_CLOCK(pll2_clk,  &main_div2_clk, pll_parent_main_extal, 3, 5, PLL2CR,  2); | 
					
						
							|  |  |  | PLL_CLOCK(pll2s_clk, &main_div2_clk, pll_parent_main_extal, 3, 5, PLL2SCR, 4); | 
					
						
							|  |  |  | PLL_CLOCK(pll2h_clk, &main_div2_clk, pll_parent_main_extal, 3, 5, PLL2HCR, 5); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | SH_FIXED_RATIO_CLK(pll1_div2_clk,	pll1_clk,	div2); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-05-22 11:12:37 +02:00
										 |  |  | static atomic_t frqcr_lock; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* Several clocks need to access FRQCRB, have to lock */ | 
					
						
							|  |  |  | static bool frqcr_kick_check(struct clk *clk) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	return !(ioread32(CPG_MAP(FRQCRB)) & BIT(31)); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-05-22 11:12:33 +02:00
										 |  |  | static int frqcr_kick_do(struct clk *clk) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	int i; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* set KICK bit in FRQCRB to update hardware setting, check success */ | 
					
						
							|  |  |  | 	iowrite32(ioread32(CPG_MAP(FRQCRB)) | BIT(31), CPG_MAP(FRQCRB)); | 
					
						
							|  |  |  | 	for (i = 1000; i; i--) | 
					
						
							|  |  |  | 		if (ioread32(CPG_MAP(FRQCRB)) & BIT(31)) | 
					
						
							|  |  |  | 			cpu_relax(); | 
					
						
							|  |  |  | 		else | 
					
						
							|  |  |  | 			return 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return -ETIMEDOUT; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-05-22 11:12:37 +02:00
										 |  |  | static int zclk_set_rate(struct clk *clk, unsigned long rate) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	void __iomem *frqcrc; | 
					
						
							|  |  |  | 	int ret; | 
					
						
							|  |  |  | 	unsigned long step, p_rate; | 
					
						
							|  |  |  | 	u32 val; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (!clk->parent || !__clk_get(clk->parent)) | 
					
						
							|  |  |  | 		return -ENODEV; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (!atomic_inc_and_test(&frqcr_lock) || !frqcr_kick_check(clk)) { | 
					
						
							|  |  |  | 		ret = -EBUSY; | 
					
						
							|  |  |  | 		goto done; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-06-21 09:10:35 +02:00
										 |  |  | 	/*
 | 
					
						
							|  |  |  | 	 * Users are supposed to first call clk_set_rate() only with | 
					
						
							|  |  |  | 	 * clk_round_rate() results. So, we don't fix wrong rates here, but | 
					
						
							|  |  |  | 	 * guard against them anyway | 
					
						
							|  |  |  | 	 */ | 
					
						
							| 
									
										
										
										
											2013-05-22 11:12:37 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	p_rate = clk_get_rate(clk->parent); | 
					
						
							|  |  |  | 	if (rate == p_rate) { | 
					
						
							|  |  |  | 		val = 0; | 
					
						
							|  |  |  | 	} else { | 
					
						
							|  |  |  | 		step = DIV_ROUND_CLOSEST(p_rate, 32); | 
					
						
							| 
									
										
										
										
											2013-06-21 09:10:35 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		if (rate > p_rate || rate < step) { | 
					
						
							|  |  |  | 			ret = -EINVAL; | 
					
						
							|  |  |  | 			goto done; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-05-22 11:12:37 +02:00
										 |  |  | 		val = 32 - rate / step; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-06-21 09:10:35 +02:00
										 |  |  | 	frqcrc = clk->mapped_reg + (FRQCRC - (u32)clk->enable_reg); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-05-22 11:12:37 +02:00
										 |  |  | 	iowrite32((ioread32(frqcrc) & ~(clk->div_mask << clk->enable_bit)) | | 
					
						
							|  |  |  | 		  (val << clk->enable_bit), frqcrc); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	ret = frqcr_kick_do(clk); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | done: | 
					
						
							|  |  |  | 	atomic_dec(&frqcr_lock); | 
					
						
							|  |  |  | 	__clk_put(clk->parent); | 
					
						
							|  |  |  | 	return ret; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static long zclk_round_rate(struct clk *clk, unsigned long rate) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	/*
 | 
					
						
							|  |  |  | 	 * theoretical rate = parent rate * multiplier / 32, | 
					
						
							|  |  |  | 	 * where 1 <= multiplier <= 32. Therefore we should do | 
					
						
							|  |  |  | 	 * multiplier = rate * 32 / parent rate | 
					
						
							|  |  |  | 	 * rounded rate = parent rate * multiplier / 32. | 
					
						
							|  |  |  | 	 * However, multiplication before division won't fit in 32 bits, so | 
					
						
							|  |  |  | 	 * we sacrifice some precision by first dividing and then multiplying. | 
					
						
							|  |  |  | 	 * To find the nearest divisor we calculate both and pick up the best | 
					
						
							|  |  |  | 	 * one. This avoids 64-bit arithmetics. | 
					
						
							|  |  |  | 	 */ | 
					
						
							|  |  |  | 	unsigned long step, mul_min, mul_max, rate_min, rate_max; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	rate_max = clk_get_rate(clk->parent); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* output freq <= parent */ | 
					
						
							|  |  |  | 	if (rate >= rate_max) | 
					
						
							|  |  |  | 		return rate_max; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	step = DIV_ROUND_CLOSEST(rate_max, 32); | 
					
						
							|  |  |  | 	/* output freq >= parent / 32 */ | 
					
						
							|  |  |  | 	if (step >= rate) | 
					
						
							|  |  |  | 		return step; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	mul_min = rate / step; | 
					
						
							|  |  |  | 	mul_max = DIV_ROUND_UP(rate, step); | 
					
						
							|  |  |  | 	rate_min = step * mul_min; | 
					
						
							|  |  |  | 	if (mul_max == mul_min) | 
					
						
							|  |  |  | 		return rate_min; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	rate_max = step * mul_max; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (rate_max - rate <  rate - rate_min) | 
					
						
							|  |  |  | 		return rate_max; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return rate_min; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static unsigned long zclk_recalc(struct clk *clk) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	void __iomem *frqcrc = FRQCRC - (u32)clk->enable_reg + clk->mapped_reg; | 
					
						
							|  |  |  | 	unsigned int max = clk->div_mask + 1; | 
					
						
							|  |  |  | 	unsigned long val = ((ioread32(frqcrc) >> clk->enable_bit) & | 
					
						
							|  |  |  | 			     clk->div_mask); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return DIV_ROUND_CLOSEST(clk_get_rate(clk->parent), max) * | 
					
						
							|  |  |  | 		(max - val); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static struct sh_clk_ops zclk_ops = { | 
					
						
							|  |  |  | 	.recalc = zclk_recalc, | 
					
						
							|  |  |  | 	.set_rate = zclk_set_rate, | 
					
						
							|  |  |  | 	.round_rate = zclk_round_rate, | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static struct clk z_clk = { | 
					
						
							|  |  |  | 	.parent = &pll0_clk, | 
					
						
							|  |  |  | 	.div_mask = 0x1f, | 
					
						
							|  |  |  | 	.enable_bit = 8, | 
					
						
							|  |  |  | 	/* We'll need to access FRQCRB and FRQCRC */ | 
					
						
							|  |  |  | 	.enable_reg = (void __iomem *)FRQCRB, | 
					
						
							|  |  |  | 	.ops = &zclk_ops, | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-06-21 09:10:38 +02:00
										 |  |  | /*
 | 
					
						
							|  |  |  |  * It seems only 1/2 divider is usable in manual mode. 1/2 / 2/3 | 
					
						
							|  |  |  |  * switching is only available in auto-DVFS mode | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | SH_FIXED_RATIO_CLK(pll0_div2_clk,	pll0_clk,		div2); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static struct clk z2_clk = { | 
					
						
							|  |  |  | 	.parent = &pll0_div2_clk, | 
					
						
							|  |  |  | 	.div_mask = 0x1f, | 
					
						
							|  |  |  | 	.enable_bit = 0, | 
					
						
							|  |  |  | 	/* We'll need to access FRQCRB and FRQCRC */ | 
					
						
							|  |  |  | 	.enable_reg = (void __iomem *)FRQCRB, | 
					
						
							|  |  |  | 	.ops = &zclk_ops, | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-03-26 10:34:24 +09:00
										 |  |  | static struct clk *main_clks[] = { | 
					
						
							|  |  |  | 	&extalr_clk, | 
					
						
							|  |  |  | 	&extal1_clk, | 
					
						
							| 
									
										
										
										
											2013-04-04 21:20:40 -07:00
										 |  |  | 	&extal1_div2_clk, | 
					
						
							| 
									
										
										
										
											2013-03-26 10:34:24 +09:00
										 |  |  | 	&extal2_clk, | 
					
						
							| 
									
										
										
										
											2013-04-04 21:20:40 -07:00
										 |  |  | 	&extal2_div2_clk, | 
					
						
							|  |  |  | 	&extal2_div4_clk, | 
					
						
							|  |  |  | 	&main_clk, | 
					
						
							|  |  |  | 	&main_div2_clk, | 
					
						
							| 
									
										
										
										
											2013-04-04 21:22:41 -07:00
										 |  |  | 	&fsiack_clk, | 
					
						
							|  |  |  | 	&fsibck_clk, | 
					
						
							| 
									
										
										
										
											2013-05-22 11:12:37 +02:00
										 |  |  | 	&pll0_clk, | 
					
						
							| 
									
										
										
										
											2013-04-04 21:21:39 -07:00
										 |  |  | 	&pll1_clk, | 
					
						
							|  |  |  | 	&pll1_div2_clk, | 
					
						
							|  |  |  | 	&pll2_clk, | 
					
						
							|  |  |  | 	&pll2s_clk, | 
					
						
							|  |  |  | 	&pll2h_clk, | 
					
						
							| 
									
										
										
										
											2013-05-22 11:12:37 +02:00
										 |  |  | 	&z_clk, | 
					
						
							| 
									
										
										
										
											2013-06-21 09:10:38 +02:00
										 |  |  | 	&pll0_div2_clk, | 
					
						
							|  |  |  | 	&z2_clk, | 
					
						
							| 
									
										
										
										
											2013-03-26 10:34:24 +09:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-04-04 21:22:16 -07:00
										 |  |  | /* DIV4 */ | 
					
						
							|  |  |  | static void div4_kick(struct clk *clk) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2013-05-22 11:12:37 +02:00
										 |  |  | 	if (!WARN(!atomic_inc_and_test(&frqcr_lock), "FRQCR* lock broken!\n")) | 
					
						
							|  |  |  | 		frqcr_kick_do(clk); | 
					
						
							|  |  |  | 	atomic_dec(&frqcr_lock); | 
					
						
							| 
									
										
										
										
											2013-04-04 21:22:16 -07:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static int divisors[] = { 2, 3, 4, 6, 8, 12, 16, 18, 24, 0, 36, 48, 10}; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static struct clk_div_mult_table div4_div_mult_table = { | 
					
						
							|  |  |  | 	.divisors	= divisors, | 
					
						
							|  |  |  | 	.nr_divisors	= ARRAY_SIZE(divisors), | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static struct clk_div4_table div4_table = { | 
					
						
							|  |  |  | 	.div_mult_table	= &div4_div_mult_table, | 
					
						
							|  |  |  | 	.kick		= div4_kick, | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | enum { | 
					
						
							|  |  |  | 	DIV4_I, DIV4_M3, DIV4_B, DIV4_M1, DIV4_M2, | 
					
						
							|  |  |  | 	DIV4_ZX, DIV4_ZS, DIV4_HP, | 
					
						
							|  |  |  | 	DIV4_NR }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static struct clk div4_clks[DIV4_NR] = { | 
					
						
							|  |  |  | 	[DIV4_I]	= SH_CLK_DIV4(&pll1_clk, FRQCRA, 20, 0x0dff, CLK_ENABLE_ON_INIT), | 
					
						
							|  |  |  | 	[DIV4_M3]	= SH_CLK_DIV4(&pll1_clk, FRQCRA, 12, 0x1dff, CLK_ENABLE_ON_INIT), | 
					
						
							|  |  |  | 	[DIV4_B]	= SH_CLK_DIV4(&pll1_clk, FRQCRA,  8, 0x0dff, CLK_ENABLE_ON_INIT), | 
					
						
							|  |  |  | 	[DIV4_M1]	= SH_CLK_DIV4(&pll1_clk, FRQCRA,  4, 0x1dff, 0), | 
					
						
							|  |  |  | 	[DIV4_M2]	= SH_CLK_DIV4(&pll1_clk, FRQCRA,  0, 0x1dff, 0), | 
					
						
							|  |  |  | 	[DIV4_ZX]	= SH_CLK_DIV4(&pll1_clk, FRQCRB, 12, 0x0dff, 0), | 
					
						
							|  |  |  | 	[DIV4_ZS]	= SH_CLK_DIV4(&pll1_clk, FRQCRB,  8, 0x0dff, 0), | 
					
						
							|  |  |  | 	[DIV4_HP]	= SH_CLK_DIV4(&pll1_clk, FRQCRB,  4, 0x0dff, 0), | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-04-04 21:22:41 -07:00
										 |  |  | enum { | 
					
						
							|  |  |  | 	DIV6_ZB, | 
					
						
							|  |  |  | 	DIV6_SDHI0, DIV6_SDHI1, DIV6_SDHI2, | 
					
						
							|  |  |  | 	DIV6_MMC0, DIV6_MMC1, | 
					
						
							|  |  |  | 	DIV6_VCK1, DIV6_VCK2, DIV6_VCK3, DIV6_VCK4, DIV6_VCK5, | 
					
						
							|  |  |  | 	DIV6_FSIA, DIV6_FSIB, | 
					
						
							|  |  |  | 	DIV6_MP, DIV6_M4, DIV6_HSI, DIV6_SPUV, | 
					
						
							|  |  |  | 	DIV6_NR }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static struct clk *div6_parents[8] = { | 
					
						
							|  |  |  | 	[0] = &pll1_div2_clk, | 
					
						
							|  |  |  | 	[1] = &pll2s_clk, | 
					
						
							|  |  |  | 	[3] = &extal2_clk, | 
					
						
							|  |  |  | 	[4] = &main_div2_clk, | 
					
						
							|  |  |  | 	[6] = &extalr_clk, | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static struct clk *fsia_parents[4] = { | 
					
						
							|  |  |  | 	[0] = &pll1_div2_clk, | 
					
						
							|  |  |  | 	[1] = &pll2s_clk, | 
					
						
							|  |  |  | 	[2] = &fsiack_clk, | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static struct clk *fsib_parents[4] = { | 
					
						
							|  |  |  | 	[0] = &pll1_div2_clk, | 
					
						
							|  |  |  | 	[1] = &pll2s_clk, | 
					
						
							|  |  |  | 	[2] = &fsibck_clk, | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static struct clk *mp_parents[4] = { | 
					
						
							|  |  |  | 	[0] = &pll1_div2_clk, | 
					
						
							|  |  |  | 	[1] = &pll2s_clk, | 
					
						
							|  |  |  | 	[2] = &extal2_clk, | 
					
						
							|  |  |  | 	[3] = &extal2_clk, | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static struct clk *m4_parents[2] = { | 
					
						
							|  |  |  | 	[0] = &pll2s_clk, | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static struct clk *hsi_parents[4] = { | 
					
						
							|  |  |  | 	[0] = &pll2h_clk, | 
					
						
							|  |  |  | 	[1] = &pll1_div2_clk, | 
					
						
							|  |  |  | 	[3] = &pll2s_clk, | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*** FIXME ***
 | 
					
						
							|  |  |  |  * SH_CLK_DIV6_EXT() macro doesn't care .mapping | 
					
						
							|  |  |  |  * but, it is necessary on R-Car (= ioremap() base CPG) | 
					
						
							|  |  |  |  * The difference between | 
					
						
							|  |  |  |  * SH_CLK_DIV6_EXT() <--> SH_CLK_MAP_DIV6_EXT() | 
					
						
							|  |  |  |  * is only .mapping | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | #define SH_CLK_MAP_DIV6_EXT(_reg, _flags, _parents,			\
 | 
					
						
							|  |  |  | 			    _num_parents, _src_shift, _src_width)	\ | 
					
						
							|  |  |  | {									\ | 
					
						
							|  |  |  | 	.enable_reg	= (void __iomem *)_reg,				\ | 
					
						
							|  |  |  | 	.enable_bit	= 0, /* unused */				\ | 
					
						
							|  |  |  | 	.flags		= _flags | CLK_MASK_DIV_ON_DISABLE,		\ | 
					
						
							|  |  |  | 	.div_mask	= SH_CLK_DIV6_MSK,				\ | 
					
						
							|  |  |  | 	.parent_table	= _parents,					\ | 
					
						
							|  |  |  | 	.parent_num	= _num_parents,					\ | 
					
						
							|  |  |  | 	.src_shift	= _src_shift,					\ | 
					
						
							|  |  |  | 	.src_width	= _src_width,					\ | 
					
						
							|  |  |  | 	.mapping	= &cpg_mapping,					\ | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static struct clk div6_clks[DIV6_NR] = { | 
					
						
							|  |  |  | 	[DIV6_ZB] = SH_CLK_MAP_DIV6_EXT(ZBCKCR, CLK_ENABLE_ON_INIT, | 
					
						
							|  |  |  | 				div6_parents, 2, 7, 1), | 
					
						
							|  |  |  | 	[DIV6_SDHI0] = SH_CLK_MAP_DIV6_EXT(SD0CKCR, 0, | 
					
						
							|  |  |  | 				div6_parents, 2, 6, 2), | 
					
						
							|  |  |  | 	[DIV6_SDHI1] = SH_CLK_MAP_DIV6_EXT(SD1CKCR, 0, | 
					
						
							|  |  |  | 				div6_parents, 2, 6, 2), | 
					
						
							|  |  |  | 	[DIV6_SDHI2] = SH_CLK_MAP_DIV6_EXT(SD2CKCR, 0, | 
					
						
							|  |  |  | 				div6_parents, 2, 6, 2), | 
					
						
							|  |  |  | 	[DIV6_MMC0] = SH_CLK_MAP_DIV6_EXT(MMC0CKCR, 0, | 
					
						
							|  |  |  | 				div6_parents, 2, 6, 2), | 
					
						
							|  |  |  | 	[DIV6_MMC1] = SH_CLK_MAP_DIV6_EXT(MMC1CKCR, 0, | 
					
						
							|  |  |  | 				div6_parents, 2, 6, 2), | 
					
						
							|  |  |  | 	[DIV6_VCK1] = SH_CLK_MAP_DIV6_EXT(VCLKCR1, 0, /* didn't care bit[6-7] */ | 
					
						
							|  |  |  | 				div6_parents, ARRAY_SIZE(div6_parents), 12, 3), | 
					
						
							|  |  |  | 	[DIV6_VCK2] = SH_CLK_MAP_DIV6_EXT(VCLKCR2, 0, /* didn't care bit[6-7] */ | 
					
						
							|  |  |  | 				div6_parents, ARRAY_SIZE(div6_parents), 12, 3), | 
					
						
							|  |  |  | 	[DIV6_VCK3] = SH_CLK_MAP_DIV6_EXT(VCLKCR3, 0, /* didn't care bit[6-7] */ | 
					
						
							|  |  |  | 				div6_parents, ARRAY_SIZE(div6_parents), 12, 3), | 
					
						
							|  |  |  | 	[DIV6_VCK4] = SH_CLK_MAP_DIV6_EXT(VCLKCR4, 0, /* didn't care bit[6-7] */ | 
					
						
							|  |  |  | 				div6_parents, ARRAY_SIZE(div6_parents), 12, 3), | 
					
						
							|  |  |  | 	[DIV6_VCK5] = SH_CLK_MAP_DIV6_EXT(VCLKCR5, 0, /* didn't care bit[6-7] */ | 
					
						
							|  |  |  | 				div6_parents, ARRAY_SIZE(div6_parents), 12, 3), | 
					
						
							|  |  |  | 	[DIV6_FSIA] = SH_CLK_MAP_DIV6_EXT(FSIACKCR, 0, | 
					
						
							|  |  |  | 				fsia_parents, ARRAY_SIZE(fsia_parents), 6, 2), | 
					
						
							|  |  |  | 	[DIV6_FSIB] = SH_CLK_MAP_DIV6_EXT(FSIBCKCR, 0, | 
					
						
							|  |  |  | 				fsib_parents, ARRAY_SIZE(fsib_parents), 6, 2), | 
					
						
							|  |  |  | 	[DIV6_MP] = SH_CLK_MAP_DIV6_EXT(MPCKCR, 0, /* it needs bit[9-11] control */ | 
					
						
							|  |  |  | 				mp_parents, ARRAY_SIZE(mp_parents), 6, 2), | 
					
						
							|  |  |  | 	/* pll2s will be selected always for M4 */ | 
					
						
							|  |  |  | 	[DIV6_M4] = SH_CLK_MAP_DIV6_EXT(M4CKCR, 0, /* it needs bit[9] control */ | 
					
						
							|  |  |  | 				m4_parents, ARRAY_SIZE(m4_parents), 6, 1), | 
					
						
							|  |  |  | 	[DIV6_HSI] = SH_CLK_MAP_DIV6_EXT(HSICKCR, 0, /* it needs bit[9] control */ | 
					
						
							|  |  |  | 				hsi_parents, ARRAY_SIZE(hsi_parents), 6, 2), | 
					
						
							|  |  |  | 	[DIV6_SPUV] = SH_CLK_MAP_DIV6_EXT(SPUVCKCR, 0, | 
					
						
							|  |  |  | 				mp_parents, ARRAY_SIZE(mp_parents), 6, 2), | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-04-04 21:22:16 -07:00
										 |  |  | /* MSTP */ | 
					
						
							| 
									
										
										
										
											2013-03-25 23:18:15 -07:00
										 |  |  | enum { | 
					
						
							| 
									
										
										
										
											2013-08-02 16:50:40 +02:00
										 |  |  | 	MSTP218, MSTP217, MSTP216, MSTP207, MSTP206, MSTP204, MSTP203, | 
					
						
							| 
									
										
										
										
											2013-06-28 20:27:23 +09:00
										 |  |  | 	MSTP329, MSTP323, MSTP318, MSTP317, MSTP316, | 
					
						
							| 
									
										
										
										
											2013-06-27 11:47:56 +02:00
										 |  |  | 	MSTP315, MSTP314, MSTP313, MSTP312, MSTP305, MSTP300, | 
					
						
							|  |  |  | 	MSTP411, MSTP410, MSTP409, | 
					
						
							|  |  |  | 	MSTP522, MSTP515, | 
					
						
							| 
									
										
										
										
											2013-03-25 23:18:15 -07:00
										 |  |  | 	MSTP_NR | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-03-26 10:34:24 +09:00
										 |  |  | static struct clk mstp_clks[MSTP_NR] = { | 
					
						
							| 
									
										
										
										
											2013-04-04 21:22:41 -07:00
										 |  |  | 	[MSTP204] = SH_CLK_MSTP32(&div6_clks[DIV6_MP],	SMSTPCR2, 4, 0), /* SCIFA0 */ | 
					
						
							|  |  |  | 	[MSTP203] = SH_CLK_MSTP32(&div6_clks[DIV6_MP],	SMSTPCR2, 3, 0), /* SCIFA1 */ | 
					
						
							|  |  |  | 	[MSTP206] = SH_CLK_MSTP32(&div6_clks[DIV6_MP],	SMSTPCR2, 6, 0), /* SCIFB0 */ | 
					
						
							|  |  |  | 	[MSTP207] = SH_CLK_MSTP32(&div6_clks[DIV6_MP],	SMSTPCR2, 7, 0), /* SCIFB1 */ | 
					
						
							|  |  |  | 	[MSTP216] = SH_CLK_MSTP32(&div6_clks[DIV6_MP],	SMSTPCR2, 16, 0), /* SCIFB2 */ | 
					
						
							|  |  |  | 	[MSTP217] = SH_CLK_MSTP32(&div6_clks[DIV6_MP],	SMSTPCR2, 17, 0), /* SCIFB3 */ | 
					
						
							| 
									
										
										
										
											2013-08-02 16:50:40 +02:00
										 |  |  | 	[MSTP218] = SH_CLK_MSTP32(&div4_clks[DIV4_HP],	SMSTPCR2, 18, 0), /* DMAC */ | 
					
						
							| 
									
										
										
										
											2013-06-27 11:47:56 +02:00
										 |  |  | 	[MSTP300] = SH_CLK_MSTP32(&div4_clks[DIV4_HP],	SMSTPCR3, 0, 0), /* IIC2 */ | 
					
						
							| 
									
										
										
										
											2013-05-17 16:55:14 +02:00
										 |  |  | 	[MSTP305] = SH_CLK_MSTP32(&div6_clks[DIV6_MMC1],SMSTPCR3, 5, 0), /* MMCIF1 */ | 
					
						
							|  |  |  | 	[MSTP312] = SH_CLK_MSTP32(&div6_clks[DIV6_SDHI2],SMSTPCR3, 12, 0), /* SDHI2 */ | 
					
						
							|  |  |  | 	[MSTP313] = SH_CLK_MSTP32(&div6_clks[DIV6_SDHI1],SMSTPCR3, 13, 0), /* SDHI1 */ | 
					
						
							|  |  |  | 	[MSTP314] = SH_CLK_MSTP32(&div6_clks[DIV6_SDHI0],SMSTPCR3, 14, 0), /* SDHI0 */ | 
					
						
							|  |  |  | 	[MSTP315] = SH_CLK_MSTP32(&div6_clks[DIV6_MMC0],SMSTPCR3, 15, 0), /* MMCIF0 */ | 
					
						
							| 
									
										
										
										
											2013-06-27 11:47:56 +02:00
										 |  |  | 	[MSTP316] = SH_CLK_MSTP32(&div4_clks[DIV4_HP],	SMSTPCR3, 16, 0), /* IIC6 */ | 
					
						
							|  |  |  | 	[MSTP317] = SH_CLK_MSTP32(&div4_clks[DIV4_HP],	SMSTPCR3, 17, 0), /* IIC7 */ | 
					
						
							|  |  |  | 	[MSTP318] = SH_CLK_MSTP32(&div4_clks[DIV4_HP],	SMSTPCR3, 18, 0), /* IIC0 */ | 
					
						
							|  |  |  | 	[MSTP323] = SH_CLK_MSTP32(&div4_clks[DIV4_HP],	SMSTPCR3, 23, 0), /* IIC1 */ | 
					
						
							| 
									
										
										
										
											2013-06-28 20:27:23 +09:00
										 |  |  | 	[MSTP329] = SH_CLK_MSTP32(&extalr_clk, SMSTPCR3, 29, 0), /* CMT10 */ | 
					
						
							| 
									
										
										
										
											2013-06-27 11:47:56 +02:00
										 |  |  | 	[MSTP409] = SH_CLK_MSTP32(&main_div2_clk,	SMSTPCR4, 9, 0), /* IIC5 */ | 
					
						
							|  |  |  | 	[MSTP410] = SH_CLK_MSTP32(&div4_clks[DIV4_HP],	SMSTPCR4, 10, 0), /* IIC4 */ | 
					
						
							|  |  |  | 	[MSTP411] = SH_CLK_MSTP32(&div4_clks[DIV4_HP],	SMSTPCR4, 11, 0), /* IIC3 */ | 
					
						
							| 
									
										
										
										
											2013-03-25 23:18:15 -07:00
										 |  |  | 	[MSTP522] = SH_CLK_MSTP32(&extal2_clk, SMSTPCR5, 22, 0), /* Thermal */ | 
					
						
							| 
									
										
										
										
											2013-06-27 11:47:56 +02:00
										 |  |  | 	[MSTP515] = SH_CLK_MSTP32(&div4_clks[DIV4_HP],	SMSTPCR5, 15, 0), /* IIC8 */ | 
					
						
							| 
									
										
										
										
											2013-03-26 10:34:24 +09:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static struct clk_lookup lookups[] = { | 
					
						
							| 
									
										
										
										
											2013-04-04 21:20:40 -07:00
										 |  |  | 	/* main clock */ | 
					
						
							|  |  |  | 	CLKDEV_CON_ID("extal1",			&extal1_clk), | 
					
						
							|  |  |  | 	CLKDEV_CON_ID("extal1_div2",		&extal1_div2_clk), | 
					
						
							|  |  |  | 	CLKDEV_CON_ID("extal2",			&extal2_clk), | 
					
						
							|  |  |  | 	CLKDEV_CON_ID("extal2_div2",		&extal2_div2_clk), | 
					
						
							|  |  |  | 	CLKDEV_CON_ID("extal2_div4",		&extal2_div4_clk), | 
					
						
							| 
									
										
										
										
											2013-04-04 21:22:41 -07:00
										 |  |  | 	CLKDEV_CON_ID("fsiack",			&fsiack_clk), | 
					
						
							|  |  |  | 	CLKDEV_CON_ID("fsibck",			&fsibck_clk), | 
					
						
							| 
									
										
										
										
											2013-04-04 21:20:40 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-04-04 21:21:39 -07:00
										 |  |  | 	/* pll clock */ | 
					
						
							|  |  |  | 	CLKDEV_CON_ID("pll1",			&pll1_clk), | 
					
						
							|  |  |  | 	CLKDEV_CON_ID("pll1_div2",		&pll1_div2_clk), | 
					
						
							|  |  |  | 	CLKDEV_CON_ID("pll2",			&pll2_clk), | 
					
						
							|  |  |  | 	CLKDEV_CON_ID("pll2s",			&pll2s_clk), | 
					
						
							|  |  |  | 	CLKDEV_CON_ID("pll2h",			&pll2h_clk), | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-05-22 11:12:37 +02:00
										 |  |  | 	/* CPU clock */ | 
					
						
							| 
									
										
										
										
											2013-09-10 18:59:49 +01:00
										 |  |  | 	CLKDEV_DEV_ID("cpu0",			&z_clk), | 
					
						
							| 
									
										
										
										
											2013-05-22 11:12:37 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-04-04 21:22:41 -07:00
										 |  |  | 	/* DIV6 */ | 
					
						
							|  |  |  | 	CLKDEV_CON_ID("zb",			&div6_clks[DIV6_ZB]), | 
					
						
							|  |  |  | 	CLKDEV_CON_ID("vck1",			&div6_clks[DIV6_VCK1]), | 
					
						
							|  |  |  | 	CLKDEV_CON_ID("vck2",			&div6_clks[DIV6_VCK2]), | 
					
						
							|  |  |  | 	CLKDEV_CON_ID("vck3",			&div6_clks[DIV6_VCK3]), | 
					
						
							|  |  |  | 	CLKDEV_CON_ID("vck4",			&div6_clks[DIV6_VCK4]), | 
					
						
							|  |  |  | 	CLKDEV_CON_ID("vck5",			&div6_clks[DIV6_VCK5]), | 
					
						
							|  |  |  | 	CLKDEV_CON_ID("fsia",			&div6_clks[DIV6_FSIA]), | 
					
						
							|  |  |  | 	CLKDEV_CON_ID("fsib",			&div6_clks[DIV6_FSIB]), | 
					
						
							|  |  |  | 	CLKDEV_CON_ID("mp",			&div6_clks[DIV6_MP]), | 
					
						
							|  |  |  | 	CLKDEV_CON_ID("m4",			&div6_clks[DIV6_M4]), | 
					
						
							|  |  |  | 	CLKDEV_CON_ID("hsi",			&div6_clks[DIV6_HSI]), | 
					
						
							|  |  |  | 	CLKDEV_CON_ID("spuv",			&div6_clks[DIV6_SPUV]), | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-04-04 21:21:39 -07:00
										 |  |  | 	/* MSTP */ | 
					
						
							| 
									
										
										
										
											2013-03-26 10:34:33 +09:00
										 |  |  | 	CLKDEV_DEV_ID("sh-sci.0", &mstp_clks[MSTP204]), | 
					
						
							| 
									
										
										
										
											2014-07-07 09:54:32 +02:00
										 |  |  | 	CLKDEV_DEV_ID("e6c40000.serial", &mstp_clks[MSTP204]), | 
					
						
							| 
									
										
										
										
											2013-03-26 10:34:33 +09:00
										 |  |  | 	CLKDEV_DEV_ID("sh-sci.1", &mstp_clks[MSTP203]), | 
					
						
							| 
									
										
										
										
											2014-07-07 09:54:32 +02:00
										 |  |  | 	CLKDEV_DEV_ID("e6c50000.serial", &mstp_clks[MSTP203]), | 
					
						
							| 
									
										
										
										
											2013-03-26 10:34:33 +09:00
										 |  |  | 	CLKDEV_DEV_ID("sh-sci.2", &mstp_clks[MSTP206]), | 
					
						
							| 
									
										
										
										
											2014-07-07 09:54:32 +02:00
										 |  |  | 	CLKDEV_DEV_ID("e6c20000.serial", &mstp_clks[MSTP206]), | 
					
						
							| 
									
										
										
										
											2013-03-26 10:34:33 +09:00
										 |  |  | 	CLKDEV_DEV_ID("sh-sci.3", &mstp_clks[MSTP207]), | 
					
						
							| 
									
										
										
										
											2014-07-07 09:54:32 +02:00
										 |  |  | 	CLKDEV_DEV_ID("e6c30000.serial", &mstp_clks[MSTP207]), | 
					
						
							| 
									
										
										
										
											2013-03-26 10:34:33 +09:00
										 |  |  | 	CLKDEV_DEV_ID("sh-sci.4", &mstp_clks[MSTP216]), | 
					
						
							| 
									
										
										
										
											2014-07-07 09:54:32 +02:00
										 |  |  | 	CLKDEV_DEV_ID("e6ce0000.serial", &mstp_clks[MSTP216]), | 
					
						
							| 
									
										
										
										
											2013-03-26 10:34:33 +09:00
										 |  |  | 	CLKDEV_DEV_ID("sh-sci.5", &mstp_clks[MSTP217]), | 
					
						
							| 
									
										
										
										
											2014-07-07 09:54:32 +02:00
										 |  |  | 	CLKDEV_DEV_ID("e6cf0000.serial", &mstp_clks[MSTP217]), | 
					
						
							| 
									
										
										
										
											2013-08-02 16:50:40 +02:00
										 |  |  | 	CLKDEV_DEV_ID("sh-dma-engine.0", &mstp_clks[MSTP218]), | 
					
						
							| 
									
										
										
										
											2013-09-26 19:30:02 +02:00
										 |  |  | 	CLKDEV_DEV_ID("e6700020.dma-controller", &mstp_clks[MSTP218]), | 
					
						
							| 
									
										
										
										
											2013-03-25 23:18:15 -07:00
										 |  |  | 	CLKDEV_DEV_ID("rcar_thermal", &mstp_clks[MSTP522]), | 
					
						
							| 
									
										
										
										
											2013-06-27 11:47:56 +02:00
										 |  |  | 	CLKDEV_DEV_ID("e6520000.i2c", &mstp_clks[MSTP300]), | 
					
						
							| 
									
										
										
										
											2013-05-17 16:55:14 +02:00
										 |  |  | 	CLKDEV_DEV_ID("sh_mmcif.1", &mstp_clks[MSTP305]), | 
					
						
							| 
									
										
										
										
											2013-10-21 19:35:31 -07:00
										 |  |  | 	CLKDEV_DEV_ID("ee220000.mmc", &mstp_clks[MSTP305]), | 
					
						
							| 
									
										
										
										
											2013-05-17 16:55:14 +02:00
										 |  |  | 	CLKDEV_DEV_ID("sh_mobile_sdhi.2", &mstp_clks[MSTP312]), | 
					
						
							| 
									
										
										
										
											2013-10-21 19:35:31 -07:00
										 |  |  | 	CLKDEV_DEV_ID("ee140000.sd", &mstp_clks[MSTP312]), | 
					
						
							| 
									
										
										
										
											2013-05-17 16:55:14 +02:00
										 |  |  | 	CLKDEV_DEV_ID("sh_mobile_sdhi.1", &mstp_clks[MSTP313]), | 
					
						
							| 
									
										
										
										
											2013-10-21 19:35:31 -07:00
										 |  |  | 	CLKDEV_DEV_ID("ee120000.sd", &mstp_clks[MSTP313]), | 
					
						
							| 
									
										
										
										
											2013-05-17 16:55:14 +02:00
										 |  |  | 	CLKDEV_DEV_ID("sh_mobile_sdhi.0", &mstp_clks[MSTP314]), | 
					
						
							| 
									
										
										
										
											2013-10-21 19:35:31 -07:00
										 |  |  | 	CLKDEV_DEV_ID("ee100000.sd", &mstp_clks[MSTP314]), | 
					
						
							| 
									
										
										
										
											2013-05-17 16:55:14 +02:00
										 |  |  | 	CLKDEV_DEV_ID("sh_mmcif.0", &mstp_clks[MSTP315]), | 
					
						
							| 
									
										
										
										
											2013-10-21 19:35:31 -07:00
										 |  |  | 	CLKDEV_DEV_ID("ee200000.mmc", &mstp_clks[MSTP315]), | 
					
						
							| 
									
										
										
										
											2013-06-27 11:47:56 +02:00
										 |  |  | 	CLKDEV_DEV_ID("e6550000.i2c", &mstp_clks[MSTP316]), | 
					
						
							|  |  |  | 	CLKDEV_DEV_ID("e6560000.i2c", &mstp_clks[MSTP317]), | 
					
						
							|  |  |  | 	CLKDEV_DEV_ID("e6500000.i2c", &mstp_clks[MSTP318]), | 
					
						
							|  |  |  | 	CLKDEV_DEV_ID("e6510000.i2c", &mstp_clks[MSTP323]), | 
					
						
							| 
									
										
										
										
											2014-04-23 13:15:11 +02:00
										 |  |  | 	CLKDEV_ICK_ID("fck", "sh-cmt-48-gen2.1", &mstp_clks[MSTP329]), | 
					
						
							| 
									
										
										
										
											2014-07-07 09:54:35 +02:00
										 |  |  | 	CLKDEV_ICK_ID("fck", "e6130000.timer", &mstp_clks[MSTP329]), | 
					
						
							| 
									
										
										
										
											2013-06-27 11:47:56 +02:00
										 |  |  | 	CLKDEV_DEV_ID("e60b0000.i2c", &mstp_clks[MSTP409]), | 
					
						
							|  |  |  | 	CLKDEV_DEV_ID("e6540000.i2c", &mstp_clks[MSTP410]), | 
					
						
							|  |  |  | 	CLKDEV_DEV_ID("e6530000.i2c", &mstp_clks[MSTP411]), | 
					
						
							|  |  |  | 	CLKDEV_DEV_ID("e6570000.i2c", &mstp_clks[MSTP515]), | 
					
						
							| 
									
										
										
										
											2013-03-25 23:18:15 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	/* for DT */ | 
					
						
							|  |  |  | 	CLKDEV_DEV_ID("e61f0000.thermal", &mstp_clks[MSTP522]), | 
					
						
							| 
									
										
										
										
											2013-03-26 10:34:24 +09:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void __init r8a73a4_clock_init(void) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2013-04-04 21:22:41 -07:00
										 |  |  | 	void __iomem *reg; | 
					
						
							| 
									
										
										
										
											2013-03-26 10:34:24 +09:00
										 |  |  | 	int k, ret = 0; | 
					
						
							| 
									
										
										
										
											2013-04-04 21:20:40 -07:00
										 |  |  | 	u32 ckscr; | 
					
						
							| 
									
										
										
										
											2013-03-26 10:34:24 +09:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-05-22 11:12:37 +02:00
										 |  |  | 	atomic_set(&frqcr_lock, -1); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-04-04 21:20:40 -07:00
										 |  |  | 	reg = ioremap_nocache(CKSCR, PAGE_SIZE); | 
					
						
							|  |  |  | 	BUG_ON(!reg); | 
					
						
							|  |  |  | 	ckscr = ioread32(reg); | 
					
						
							|  |  |  | 	iounmap(reg); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	switch ((ckscr >> 28) & 0x3) { | 
					
						
							|  |  |  | 	case 0: | 
					
						
							|  |  |  | 		main_clk.parent = &extal1_clk; | 
					
						
							|  |  |  | 		break; | 
					
						
							|  |  |  | 	case 1: | 
					
						
							|  |  |  | 		main_clk.parent = &extal1_div2_clk; | 
					
						
							|  |  |  | 		break; | 
					
						
							|  |  |  | 	case 2: | 
					
						
							|  |  |  | 		main_clk.parent = &extal2_clk; | 
					
						
							|  |  |  | 		break; | 
					
						
							|  |  |  | 	case 3: | 
					
						
							|  |  |  | 		main_clk.parent = &extal2_div2_clk; | 
					
						
							|  |  |  | 		break; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-03-26 10:34:24 +09:00
										 |  |  | 	for (k = 0; !ret && (k < ARRAY_SIZE(main_clks)); k++) | 
					
						
							|  |  |  | 		ret = clk_register(main_clks[k]); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-04-04 21:22:16 -07:00
										 |  |  | 	if (!ret) | 
					
						
							|  |  |  | 		ret = sh_clk_div4_register(div4_clks, DIV4_NR, &div4_table); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-04-04 21:22:41 -07:00
										 |  |  | 	if (!ret) | 
					
						
							|  |  |  | 		ret = sh_clk_div6_reparent_register(div6_clks, DIV6_NR); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-03-26 10:34:24 +09:00
										 |  |  | 	if (!ret) | 
					
						
							|  |  |  | 		ret = sh_clk_mstp_register(mstp_clks, MSTP_NR); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	clkdev_add_table(lookups, ARRAY_SIZE(lookups)); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (!ret) | 
					
						
							|  |  |  | 		shmobile_clk_init(); | 
					
						
							|  |  |  | 	else | 
					
						
							|  |  |  | 		panic("failed to setup r8a73a4 clocks\n"); | 
					
						
							|  |  |  | } |