spear6xx_clock.c 11.9 KB
Newer Older
1 2 3 4
/*
 * SPEAr6xx machines clock framework source file
 *
 * Copyright (C) 2012 ST Microelectronics
V
Viresh Kumar 已提交
5
 * Viresh Kumar <viresh.linux@gmail.com>
6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99
 *
 * This file is licensed under the terms of the GNU General Public
 * License version 2. This program is licensed "as is" without any
 * warranty of any kind, whether express or implied.
 */

#include <linux/clk.h>
#include <linux/clkdev.h>
#include <linux/io.h>
#include <linux/spinlock_types.h>
#include <mach/misc_regs.h>
#include "clk.h"

static DEFINE_SPINLOCK(_lock);

#define PLL1_CTR			(MISC_BASE + 0x008)
#define PLL1_FRQ			(MISC_BASE + 0x00C)
#define PLL2_CTR			(MISC_BASE + 0x014)
#define PLL2_FRQ			(MISC_BASE + 0x018)
#define PLL_CLK_CFG			(MISC_BASE + 0x020)
	/* PLL_CLK_CFG register masks */
	#define MCTR_CLK_SHIFT		28
	#define MCTR_CLK_MASK		3

#define CORE_CLK_CFG			(MISC_BASE + 0x024)
	/* CORE CLK CFG register masks */
	#define HCLK_RATIO_SHIFT	10
	#define HCLK_RATIO_MASK		2
	#define PCLK_RATIO_SHIFT	8
	#define PCLK_RATIO_MASK		2

#define PERIP_CLK_CFG			(MISC_BASE + 0x028)
	/* PERIP_CLK_CFG register masks */
	#define CLCD_CLK_SHIFT		2
	#define CLCD_CLK_MASK		2
	#define UART_CLK_SHIFT		4
	#define UART_CLK_MASK		1
	#define FIRDA_CLK_SHIFT		5
	#define FIRDA_CLK_MASK		2
	#define GPT0_CLK_SHIFT		8
	#define GPT1_CLK_SHIFT		10
	#define GPT2_CLK_SHIFT		11
	#define GPT3_CLK_SHIFT		12
	#define GPT_CLK_MASK		1

#define PERIP1_CLK_ENB			(MISC_BASE + 0x02C)
	/* PERIP1_CLK_ENB register masks */
	#define UART0_CLK_ENB		3
	#define UART1_CLK_ENB		4
	#define SSP0_CLK_ENB		5
	#define SSP1_CLK_ENB		6
	#define I2C_CLK_ENB		7
	#define JPEG_CLK_ENB		8
	#define FSMC_CLK_ENB		9
	#define FIRDA_CLK_ENB		10
	#define GPT2_CLK_ENB		11
	#define GPT3_CLK_ENB		12
	#define GPIO2_CLK_ENB		13
	#define SSP2_CLK_ENB		14
	#define ADC_CLK_ENB		15
	#define GPT1_CLK_ENB		11
	#define RTC_CLK_ENB		17
	#define GPIO1_CLK_ENB		18
	#define DMA_CLK_ENB		19
	#define SMI_CLK_ENB		21
	#define CLCD_CLK_ENB		22
	#define GMAC_CLK_ENB		23
	#define USBD_CLK_ENB		24
	#define USBH0_CLK_ENB		25
	#define USBH1_CLK_ENB		26

#define PRSC0_CLK_CFG			(MISC_BASE + 0x044)
#define PRSC1_CLK_CFG			(MISC_BASE + 0x048)
#define PRSC2_CLK_CFG			(MISC_BASE + 0x04C)

#define CLCD_CLK_SYNT			(MISC_BASE + 0x05C)
#define FIRDA_CLK_SYNT			(MISC_BASE + 0x060)
#define UART_CLK_SYNT			(MISC_BASE + 0x064)

/* vco rate configuration table, in ascending order of rates */
static struct pll_rate_tbl pll_rtbl[] = {
	{.mode = 0, .m = 0x53, .n = 0x0F, .p = 0x1}, /* vco 332 & pll 166 MHz */
	{.mode = 0, .m = 0x85, .n = 0x0F, .p = 0x1}, /* vco 532 & pll 266 MHz */
	{.mode = 0, .m = 0xA6, .n = 0x0F, .p = 0x1}, /* vco 664 & pll 332 MHz */
};

/* aux rate configuration table, in ascending order of rates */
static struct aux_rate_tbl aux_rtbl[] = {
	/* For PLL1 = 332 MHz */
	{.xscale = 2, .yscale = 8, .eq = 0}, /* 41.5 MHz */
	{.xscale = 2, .yscale = 4, .eq = 0}, /* 83 MHz */
	{.xscale = 1, .yscale = 2, .eq = 1}, /* 166 MHz */
};

100 101 102 103 104 105
static const char *clcd_parents[] = { "pll3_clk", "clcd_syn_gclk", };
static const char *firda_parents[] = { "pll3_clk", "firda_syn_gclk", };
static const char *uart_parents[] = { "pll3_clk", "uart_syn_gclk", };
static const char *gpt0_1_parents[] = { "pll3_clk", "gpt0_1_syn_clk", };
static const char *gpt2_parents[] = { "pll3_clk", "gpt2_syn_clk", };
static const char *gpt3_parents[] = { "pll3_clk", "gpt3_syn_clk", };
106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137
static const char *ddr_parents[] = { "ahb_clk", "ahbmult2_clk", "none",
	"pll2_clk", };

/* gpt rate configuration table, in ascending order of rates */
static struct gpt_rate_tbl gpt_rtbl[] = {
	/* For pll1 = 332 MHz */
	{.mscale = 4, .nscale = 0}, /* 41.5 MHz */
	{.mscale = 2, .nscale = 0}, /* 55.3 MHz */
	{.mscale = 1, .nscale = 0}, /* 83 MHz */
};

void __init spear6xx_clk_init(void)
{
	struct clk *clk, *clk1;

	clk = clk_register_fixed_rate(NULL, "apb_pclk", NULL, CLK_IS_ROOT, 0);
	clk_register_clkdev(clk, "apb_pclk", NULL);

	clk = clk_register_fixed_rate(NULL, "osc_32k_clk", NULL, CLK_IS_ROOT,
			32000);
	clk_register_clkdev(clk, "osc_32k_clk", NULL);

	clk = clk_register_fixed_rate(NULL, "osc_30m_clk", NULL, CLK_IS_ROOT,
			30000000);
	clk_register_clkdev(clk, "osc_30m_clk", NULL);

	/* clock derived from 32 KHz osc clk */
	clk = clk_register_gate(NULL, "rtc_spear", "osc_32k_clk", 0,
			PERIP1_CLK_ENB, RTC_CLK_ENB, 0, &_lock);
	clk_register_clkdev(clk, NULL, "rtc-spear");

	/* clock derived from 30 MHz osc clk */
138
	clk = clk_register_fixed_rate(NULL, "pll3_clk", "osc_24m_clk", 0,
139
			48000000);
140
	clk_register_clkdev(clk, "pll3_clk", NULL);
141 142 143 144 145 146 147

	clk = clk_register_vco_pll("vco1_clk", "pll1_clk", NULL, "osc_30m_clk",
			0, PLL1_CTR, PLL1_FRQ, pll_rtbl, ARRAY_SIZE(pll_rtbl),
			&_lock, &clk1, NULL);
	clk_register_clkdev(clk, "vco1_clk", NULL);
	clk_register_clkdev(clk1, "pll1_clk", NULL);

148 149 150
	clk = clk_register_vco_pll("vco2_clk", "pll2_clk", NULL, "osc_30m_clk",
			0, PLL2_CTR, PLL2_FRQ, pll_rtbl, ARRAY_SIZE(pll_rtbl),
			&_lock, &clk1, NULL);
151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166
	clk_register_clkdev(clk, "vco2_clk", NULL);
	clk_register_clkdev(clk1, "pll2_clk", NULL);

	clk = clk_register_fixed_factor(NULL, "wdt_clk", "osc_30m_clk", 0, 1,
			1);
	clk_register_clkdev(clk, NULL, "wdt");

	/* clock derived from pll1 clk */
	clk = clk_register_fixed_factor(NULL, "cpu_clk", "pll1_clk", 0, 1, 1);
	clk_register_clkdev(clk, "cpu_clk", NULL);

	clk = clk_register_divider(NULL, "ahb_clk", "pll1_clk",
			CLK_SET_RATE_PARENT, CORE_CLK_CFG, HCLK_RATIO_SHIFT,
			HCLK_RATIO_MASK, 0, &_lock);
	clk_register_clkdev(clk, "ahb_clk", NULL);

167 168 169 170 171
	clk = clk_register_aux("uart_syn_clk", "uart_syn_gclk", "pll1_clk", 0,
			UART_CLK_SYNT, NULL, aux_rtbl, ARRAY_SIZE(aux_rtbl),
			&_lock, &clk1);
	clk_register_clkdev(clk, "uart_syn_clk", NULL);
	clk_register_clkdev(clk1, "uart_syn_gclk", NULL);
172

173
	clk = clk_register_mux(NULL, "uart_mclk", uart_parents,
174 175
			ARRAY_SIZE(uart_parents), 0, PERIP_CLK_CFG,
			UART_CLK_SHIFT, UART_CLK_MASK, 0, &_lock);
176
	clk_register_clkdev(clk, "uart_mclk", NULL);
177

178 179
	clk = clk_register_gate(NULL, "uart0", "uart_mclk", 0, PERIP1_CLK_ENB,
			UART0_CLK_ENB, 0, &_lock);
180 181
	clk_register_clkdev(clk, NULL, "d0000000.serial");

182 183
	clk = clk_register_gate(NULL, "uart1", "uart_mclk", 0, PERIP1_CLK_ENB,
			UART1_CLK_ENB, 0, &_lock);
184 185
	clk_register_clkdev(clk, NULL, "d0080000.serial");

186 187 188 189 190
	clk = clk_register_aux("firda_syn_clk", "firda_syn_gclk", "pll1_clk",
			0, FIRDA_CLK_SYNT, NULL, aux_rtbl, ARRAY_SIZE(aux_rtbl),
			&_lock, &clk1);
	clk_register_clkdev(clk, "firda_syn_clk", NULL);
	clk_register_clkdev(clk1, "firda_syn_gclk", NULL);
191

192
	clk = clk_register_mux(NULL, "firda_mclk", firda_parents,
193 194
			ARRAY_SIZE(firda_parents), 0, PERIP_CLK_CFG,
			FIRDA_CLK_SHIFT, FIRDA_CLK_MASK, 0, &_lock);
195
	clk_register_clkdev(clk, "firda_mclk", NULL);
196

197
	clk = clk_register_gate(NULL, "firda_clk", "firda_mclk", 0,
198 199 200
			PERIP1_CLK_ENB, FIRDA_CLK_ENB, 0, &_lock);
	clk_register_clkdev(clk, NULL, "firda");

201 202 203 204 205
	clk = clk_register_aux("clcd_syn_clk", "clcd_syn_gclk", "pll1_clk",
			0, CLCD_CLK_SYNT, NULL, aux_rtbl, ARRAY_SIZE(aux_rtbl),
			&_lock, &clk1);
	clk_register_clkdev(clk, "clcd_syn_clk", NULL);
	clk_register_clkdev(clk1, "clcd_syn_gclk", NULL);
206

207
	clk = clk_register_mux(NULL, "clcd_mclk", clcd_parents,
208 209
			ARRAY_SIZE(clcd_parents), 0, PERIP_CLK_CFG,
			CLCD_CLK_SHIFT, CLCD_CLK_MASK, 0, &_lock);
210
	clk_register_clkdev(clk, "clcd_mclk", NULL);
211

212
	clk = clk_register_gate(NULL, "clcd_clk", "clcd_mclk", 0,
213 214 215 216
			PERIP1_CLK_ENB, CLCD_CLK_ENB, 0, &_lock);
	clk_register_clkdev(clk, NULL, "clcd");

	/* gpt clocks */
217
	clk = clk_register_gpt("gpt0_1_syn_clk", "pll1_clk", 0, PRSC0_CLK_CFG,
218
			gpt_rtbl, ARRAY_SIZE(gpt_rtbl), &_lock);
219
	clk_register_clkdev(clk, "gpt0_1_syn_clk", NULL);
220

221
	clk = clk_register_mux(NULL, "gpt0_mclk", gpt0_1_parents,
222 223 224 225
			ARRAY_SIZE(gpt0_1_parents), 0, PERIP_CLK_CFG,
			GPT0_CLK_SHIFT, GPT_CLK_MASK, 0, &_lock);
	clk_register_clkdev(clk, NULL, "gpt0");

226
	clk = clk_register_mux(NULL, "gpt1_mclk", gpt0_1_parents,
227 228
			ARRAY_SIZE(gpt0_1_parents), 0, PERIP_CLK_CFG,
			GPT1_CLK_SHIFT, GPT_CLK_MASK, 0, &_lock);
229
	clk_register_clkdev(clk, "gpt1_mclk", NULL);
230

231
	clk = clk_register_gate(NULL, "gpt1_clk", "gpt1_mclk", 0,
232 233 234
			PERIP1_CLK_ENB, GPT1_CLK_ENB, 0, &_lock);
	clk_register_clkdev(clk, NULL, "gpt1");

235
	clk = clk_register_gpt("gpt2_syn_clk", "pll1_clk", 0, PRSC1_CLK_CFG,
236
			gpt_rtbl, ARRAY_SIZE(gpt_rtbl), &_lock);
237
	clk_register_clkdev(clk, "gpt2_syn_clk", NULL);
238

239
	clk = clk_register_mux(NULL, "gpt2_mclk", gpt2_parents,
240 241
			ARRAY_SIZE(gpt2_parents), 0, PERIP_CLK_CFG,
			GPT2_CLK_SHIFT, GPT_CLK_MASK, 0, &_lock);
242
	clk_register_clkdev(clk, "gpt2_mclk", NULL);
243

244
	clk = clk_register_gate(NULL, "gpt2_clk", "gpt2_mclk", 0,
245 246 247
			PERIP1_CLK_ENB, GPT2_CLK_ENB, 0, &_lock);
	clk_register_clkdev(clk, NULL, "gpt2");

248
	clk = clk_register_gpt("gpt3_syn_clk", "pll1_clk", 0, PRSC2_CLK_CFG,
249
			gpt_rtbl, ARRAY_SIZE(gpt_rtbl), &_lock);
250
	clk_register_clkdev(clk, "gpt3_syn_clk", NULL);
251

252
	clk = clk_register_mux(NULL, "gpt3_mclk", gpt3_parents,
253 254
			ARRAY_SIZE(gpt3_parents), 0, PERIP_CLK_CFG,
			GPT3_CLK_SHIFT, GPT_CLK_MASK, 0, &_lock);
255
	clk_register_clkdev(clk, "gpt3_mclk", NULL);
256

257
	clk = clk_register_gate(NULL, "gpt3_clk", "gpt3_mclk", 0,
258 259 260 261
			PERIP1_CLK_ENB, GPT3_CLK_ENB, 0, &_lock);
	clk_register_clkdev(clk, NULL, "gpt3");

	/* clock derived from pll3 clk */
262
	clk = clk_register_gate(NULL, "usbh0_clk", "pll3_clk", 0,
263 264 265
			PERIP1_CLK_ENB, USBH0_CLK_ENB, 0, &_lock);
	clk_register_clkdev(clk, NULL, "usbh.0_clk");

266
	clk = clk_register_gate(NULL, "usbh1_clk", "pll3_clk", 0,
267 268 269
			PERIP1_CLK_ENB, USBH1_CLK_ENB, 0, &_lock);
	clk_register_clkdev(clk, NULL, "usbh.1_clk");

270 271
	clk = clk_register_gate(NULL, "usbd_clk", "pll3_clk", 0, PERIP1_CLK_ENB,
			USBD_CLK_ENB, 0, &_lock);
272 273 274 275 276 277 278 279
	clk_register_clkdev(clk, NULL, "designware_udc");

	/* clock derived from ahb clk */
	clk = clk_register_fixed_factor(NULL, "ahbmult2_clk", "ahb_clk", 0, 2,
			1);
	clk_register_clkdev(clk, "ahbmult2_clk", NULL);

	clk = clk_register_mux(NULL, "ddr_clk", ddr_parents,
280 281
			ARRAY_SIZE(ddr_parents), 0, PLL_CLK_CFG, MCTR_CLK_SHIFT,
			MCTR_CLK_MASK, 0, &_lock);
282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298
	clk_register_clkdev(clk, "ddr_clk", NULL);

	clk = clk_register_divider(NULL, "apb_clk", "ahb_clk",
			CLK_SET_RATE_PARENT, CORE_CLK_CFG, PCLK_RATIO_SHIFT,
			PCLK_RATIO_MASK, 0, &_lock);
	clk_register_clkdev(clk, "apb_clk", NULL);

	clk = clk_register_gate(NULL, "dma_clk", "ahb_clk", 0, PERIP1_CLK_ENB,
			DMA_CLK_ENB, 0, &_lock);
	clk_register_clkdev(clk, NULL, "fc400000.dma");

	clk = clk_register_gate(NULL, "fsmc_clk", "ahb_clk", 0, PERIP1_CLK_ENB,
			FSMC_CLK_ENB, 0, &_lock);
	clk_register_clkdev(clk, NULL, "d1800000.flash");

	clk = clk_register_gate(NULL, "gmac_clk", "ahb_clk", 0, PERIP1_CLK_ENB,
			GMAC_CLK_ENB, 0, &_lock);
299
	clk_register_clkdev(clk, NULL, "e0800000.ethernet");
300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340

	clk = clk_register_gate(NULL, "i2c_clk", "ahb_clk", 0, PERIP1_CLK_ENB,
			I2C_CLK_ENB, 0, &_lock);
	clk_register_clkdev(clk, NULL, "d0200000.i2c");

	clk = clk_register_gate(NULL, "jpeg_clk", "ahb_clk", 0, PERIP1_CLK_ENB,
			JPEG_CLK_ENB, 0, &_lock);
	clk_register_clkdev(clk, NULL, "jpeg");

	clk = clk_register_gate(NULL, "smi_clk", "ahb_clk", 0, PERIP1_CLK_ENB,
			SMI_CLK_ENB, 0, &_lock);
	clk_register_clkdev(clk, NULL, "fc000000.flash");

	/* clock derived from apb clk */
	clk = clk_register_gate(NULL, "adc_clk", "apb_clk", 0, PERIP1_CLK_ENB,
			ADC_CLK_ENB, 0, &_lock);
	clk_register_clkdev(clk, NULL, "adc");

	clk = clk_register_fixed_factor(NULL, "gpio0_clk", "apb_clk", 0, 1, 1);
	clk_register_clkdev(clk, NULL, "f0100000.gpio");

	clk = clk_register_gate(NULL, "gpio1_clk", "apb_clk", 0, PERIP1_CLK_ENB,
			GPIO1_CLK_ENB, 0, &_lock);
	clk_register_clkdev(clk, NULL, "fc980000.gpio");

	clk = clk_register_gate(NULL, "gpio2_clk", "apb_clk", 0, PERIP1_CLK_ENB,
			GPIO2_CLK_ENB, 0, &_lock);
	clk_register_clkdev(clk, NULL, "d8100000.gpio");

	clk = clk_register_gate(NULL, "ssp0_clk", "apb_clk", 0, PERIP1_CLK_ENB,
			SSP0_CLK_ENB, 0, &_lock);
	clk_register_clkdev(clk, NULL, "ssp-pl022.0");

	clk = clk_register_gate(NULL, "ssp1_clk", "apb_clk", 0, PERIP1_CLK_ENB,
			SSP1_CLK_ENB, 0, &_lock);
	clk_register_clkdev(clk, NULL, "ssp-pl022.1");

	clk = clk_register_gate(NULL, "ssp2_clk", "apb_clk", 0, PERIP1_CLK_ENB,
			SSP2_CLK_ENB, 0, &_lock);
	clk_register_clkdev(clk, NULL, "ssp-pl022.2");
}