clock-r8a7779.c 10.0 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
/*
 * r8a7779 clock framework support
 *
 * Copyright (C) 2011  Renesas Solutions Corp.
 * Copyright (C) 2011  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; either 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.
 */
16
#include <linux/bitops.h>
17 18 19 20 21
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/io.h>
#include <linux/sh_clk.h>
#include <linux/clkdev.h>
22
#include <linux/sh_timer.h>
23

M
Magnus Damm 已提交
24
#include "clock.h"
M
Magnus Damm 已提交
25
#include "common.h"
26
#include "r8a7779.h"
27

28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46
/*
 *		MD1 = 1			MD1 = 0
 *		(PLLA = 1500)		(PLLA = 1600)
 *		(MHz)			(MHz)
 *------------------------------------------------+--------------------
 * clkz		1000   (2/3)		800   (1/2)
 * clkzs	 250   (1/6)		200   (1/8)
 * clki		 750   (1/2)		800   (1/2)
 * clks		 250   (1/6)		200   (1/8)
 * clks1	 125   (1/12)		100   (1/16)
 * clks3	 187.5 (1/8)		200   (1/8)
 * clks4	  93.7 (1/16)		100   (1/16)
 * clkp		  62.5 (1/24)		 50   (1/32)
 * clkg		  62.5 (1/24)		 66.6 (1/24)
 * clkb, CLKOUT
 * (MD2 = 0)	  62.5 (1/24)		 66.6 (1/24)
 * (MD2 = 1)	  41.6 (1/36)		 50   (1/32)
*/

47 48
#define MD(nr)	BIT(nr)

49 50 51 52
#define MSTPCR0		IOMEM(0xffc80030)
#define MSTPCR1		IOMEM(0xffc80034)
#define MSTPCR3		IOMEM(0xffc8003c)
#define MSTPSR1		IOMEM(0xffc80044)
53 54 55 56 57 58 59 60 61 62

/* ioremap() through clock mapping mandatory to avoid
 * collision with ARM coherent DMA virtual memory range.
 */

static struct clk_mapping cpg_mapping = {
	.phys	= 0xffc80000,
	.len	= 0x80,
};

63 64 65 66 67
/*
 * Default rate for the root input clock, reset this with clk_set_rate()
 * from the platform code.
 */
static struct clk plla_clk = {
68
	/* .rate will be updated on r8a7779_clock_init() */
69
	.mapping	= &cpg_mapping,
70 71
};

72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87
/*
 * clock ratio of these clock will be updated
 * on r8a7779_clock_init()
 */
SH_FIXED_RATIO_CLK_SET(clkz_clk,	plla_clk, 1, 1);
SH_FIXED_RATIO_CLK_SET(clkzs_clk,	plla_clk, 1, 1);
SH_FIXED_RATIO_CLK_SET(clki_clk,	plla_clk, 1, 1);
SH_FIXED_RATIO_CLK_SET(clks_clk,	plla_clk, 1, 1);
SH_FIXED_RATIO_CLK_SET(clks1_clk,	plla_clk, 1, 1);
SH_FIXED_RATIO_CLK_SET(clks3_clk,	plla_clk, 1, 1);
SH_FIXED_RATIO_CLK_SET(clks4_clk,	plla_clk, 1, 1);
SH_FIXED_RATIO_CLK_SET(clkb_clk,	plla_clk, 1, 1);
SH_FIXED_RATIO_CLK_SET(clkout_clk,	plla_clk, 1, 1);
SH_FIXED_RATIO_CLK_SET(clkp_clk,	plla_clk, 1, 1);
SH_FIXED_RATIO_CLK_SET(clkg_clk,	plla_clk, 1, 1);

88
static struct clk *main_clks[] = {
89
	&plla_clk,
90 91 92 93 94 95 96 97 98 99 100
	&clkz_clk,
	&clkzs_clk,
	&clki_clk,
	&clks_clk,
	&clks1_clk,
	&clks3_clk,
	&clks4_clk,
	&clkb_clk,
	&clkout_clk,
	&clkp_clk,
	&clkg_clk,
101 102
};

P
Phil Edworthy 已提交
103
enum { MSTP323, MSTP322, MSTP321, MSTP320,
104
	MSTP120,
105
	MSTP116, MSTP115, MSTP114,
106
	MSTP110, MSTP109, MSTP108,
107
	MSTP103, MSTP101, MSTP100,
108 109
	MSTP030,
	MSTP029, MSTP028, MSTP027, MSTP026, MSTP025, MSTP024, MSTP023, MSTP022, MSTP021,
110
	MSTP016, MSTP015, MSTP014,
111
	MSTP007,
112 113 114
	MSTP_NR };

static struct clk mstp_clks[MSTP_NR] = {
115 116 117 118
	[MSTP323] = SH_CLK_MSTP32(&clkp_clk, MSTPCR3, 23, 0), /* SDHI0 */
	[MSTP322] = SH_CLK_MSTP32(&clkp_clk, MSTPCR3, 22, 0), /* SDHI1 */
	[MSTP321] = SH_CLK_MSTP32(&clkp_clk, MSTPCR3, 21, 0), /* SDHI2 */
	[MSTP320] = SH_CLK_MSTP32(&clkp_clk, MSTPCR3, 20, 0), /* SDHI3 */
119 120 121 122 123 124 125 126 127 128
	[MSTP120] = SH_CLK_MSTP32_STS(&clks_clk, MSTPCR1, 20, MSTPSR1, 0), /* VIN3 */
	[MSTP116] = SH_CLK_MSTP32_STS(&clkp_clk, MSTPCR1, 16, MSTPSR1, 0), /* PCIe */
	[MSTP115] = SH_CLK_MSTP32_STS(&clkp_clk, MSTPCR1, 15, MSTPSR1, 0), /* SATA */
	[MSTP114] = SH_CLK_MSTP32_STS(&clkp_clk, MSTPCR1, 14, MSTPSR1, 0), /* Ether */
	[MSTP110] = SH_CLK_MSTP32_STS(&clks_clk, MSTPCR1, 10, MSTPSR1, 0), /* VIN0 */
	[MSTP109] = SH_CLK_MSTP32_STS(&clks_clk, MSTPCR1,  9, MSTPSR1, 0), /* VIN1 */
	[MSTP108] = SH_CLK_MSTP32_STS(&clks_clk, MSTPCR1,  8, MSTPSR1, 0), /* VIN2 */
	[MSTP103] = SH_CLK_MSTP32_STS(&clks_clk, MSTPCR1,  3, MSTPSR1, 0), /* DU */
	[MSTP101] = SH_CLK_MSTP32_STS(&clkp_clk, MSTPCR1,  1, MSTPSR1, 0), /* USB2 */
	[MSTP100] = SH_CLK_MSTP32_STS(&clkp_clk, MSTPCR1,  0, MSTPSR1, 0), /* USB0/1 */
129 130 131 132 133 134 135 136 137 138 139 140 141 142
	[MSTP030] = SH_CLK_MSTP32(&clkp_clk, MSTPCR0, 30, 0), /* I2C0 */
	[MSTP029] = SH_CLK_MSTP32(&clkp_clk, MSTPCR0, 29, 0), /* I2C1 */
	[MSTP028] = SH_CLK_MSTP32(&clkp_clk, MSTPCR0, 28, 0), /* I2C2 */
	[MSTP027] = SH_CLK_MSTP32(&clkp_clk, MSTPCR0, 27, 0), /* I2C3 */
	[MSTP026] = SH_CLK_MSTP32(&clkp_clk, MSTPCR0, 26, 0), /* SCIF0 */
	[MSTP025] = SH_CLK_MSTP32(&clkp_clk, MSTPCR0, 25, 0), /* SCIF1 */
	[MSTP024] = SH_CLK_MSTP32(&clkp_clk, MSTPCR0, 24, 0), /* SCIF2 */
	[MSTP023] = SH_CLK_MSTP32(&clkp_clk, MSTPCR0, 23, 0), /* SCIF3 */
	[MSTP022] = SH_CLK_MSTP32(&clkp_clk, MSTPCR0, 22, 0), /* SCIF4 */
	[MSTP021] = SH_CLK_MSTP32(&clkp_clk, MSTPCR0, 21, 0), /* SCIF5 */
	[MSTP016] = SH_CLK_MSTP32(&clkp_clk, MSTPCR0, 16, 0), /* TMU0 */
	[MSTP015] = SH_CLK_MSTP32(&clkp_clk, MSTPCR0, 15, 0), /* TMU1 */
	[MSTP014] = SH_CLK_MSTP32(&clkp_clk, MSTPCR0, 14, 0), /* TMU2 */
	[MSTP007] = SH_CLK_MSTP32(&clks_clk, MSTPCR0,  7, 0), /* HSPI */
143 144
};

145
static struct clk_lookup lookups[] = {
146 147
	/* main clocks */
	CLKDEV_CON_ID("plla_clk", &plla_clk),
148 149
	CLKDEV_CON_ID("clkz_clk", &clkz_clk),
	CLKDEV_CON_ID("clkzs_clk", &clkzs_clk),
150 151

	/* DIV4 clocks */
152 153 154 155 156 157
	CLKDEV_CON_ID("shyway_clk",	&clks_clk),
	CLKDEV_CON_ID("bus_clk",	&clkout_clk),
	CLKDEV_CON_ID("shyway4_clk",	&clks4_clk),
	CLKDEV_CON_ID("shyway3_clk",	&clks3_clk),
	CLKDEV_CON_ID("shyway1_clk",	&clks1_clk),
	CLKDEV_CON_ID("peripheral_clk",	&clkp_clk),
158

159
	/* MSTP32 clocks */
160
	CLKDEV_DEV_ID("r8a7779-vin.3", &mstp_clks[MSTP120]), /* VIN3 */
161
	CLKDEV_DEV_ID("rcar-pcie", &mstp_clks[MSTP116]), /* PCIe */
162 163
	CLKDEV_DEV_ID("sata_rcar", &mstp_clks[MSTP115]), /* SATA */
	CLKDEV_DEV_ID("fc600000.sata", &mstp_clks[MSTP115]), /* SATA w/DT */
164
	CLKDEV_DEV_ID("r8a777x-ether", &mstp_clks[MSTP114]), /* Ether */
165 166 167
	CLKDEV_DEV_ID("r8a7779-vin.0", &mstp_clks[MSTP110]), /* VIN0 */
	CLKDEV_DEV_ID("r8a7779-vin.1", &mstp_clks[MSTP109]), /* VIN1 */
	CLKDEV_DEV_ID("r8a7779-vin.2", &mstp_clks[MSTP108]), /* VIN2 */
168
	CLKDEV_DEV_ID("ehci-platform.1", &mstp_clks[MSTP101]), /* USB EHCI port2 */
169
	CLKDEV_DEV_ID("ohci-platform.1", &mstp_clks[MSTP101]), /* USB OHCI port2 */
170
	CLKDEV_DEV_ID("ehci-platform.0", &mstp_clks[MSTP100]), /* USB EHCI port0/1 */
171
	CLKDEV_DEV_ID("ohci-platform.0", &mstp_clks[MSTP100]), /* USB OHCI port0/1 */
172
	CLKDEV_ICK_ID("fck", "sh-tmu.0", &mstp_clks[MSTP016]), /* TMU0 */
173
	CLKDEV_DEV_ID("i2c-rcar.0", &mstp_clks[MSTP030]), /* I2C0 */
174
	CLKDEV_DEV_ID("ffc70000.i2c", &mstp_clks[MSTP030]), /* I2C0 */
175
	CLKDEV_DEV_ID("i2c-rcar.1", &mstp_clks[MSTP029]), /* I2C1 */
176
	CLKDEV_DEV_ID("ffc71000.i2c", &mstp_clks[MSTP029]), /* I2C1 */
177
	CLKDEV_DEV_ID("i2c-rcar.2", &mstp_clks[MSTP028]), /* I2C2 */
178
	CLKDEV_DEV_ID("ffc72000.i2c", &mstp_clks[MSTP028]), /* I2C2 */
179
	CLKDEV_DEV_ID("i2c-rcar.3", &mstp_clks[MSTP027]), /* I2C3 */
180
	CLKDEV_DEV_ID("ffc73000.i2c", &mstp_clks[MSTP027]), /* I2C3 */
181 182 183 184 185 186
	CLKDEV_DEV_ID("sh-sci.0", &mstp_clks[MSTP026]), /* SCIF0 */
	CLKDEV_DEV_ID("sh-sci.1", &mstp_clks[MSTP025]), /* SCIF1 */
	CLKDEV_DEV_ID("sh-sci.2", &mstp_clks[MSTP024]), /* SCIF2 */
	CLKDEV_DEV_ID("sh-sci.3", &mstp_clks[MSTP023]), /* SCIF3 */
	CLKDEV_DEV_ID("sh-sci.4", &mstp_clks[MSTP022]), /* SCIF4 */
	CLKDEV_DEV_ID("sh-sci.5", &mstp_clks[MSTP021]), /* SCIF6 */
187
	CLKDEV_DEV_ID("sh-hspi.0", &mstp_clks[MSTP007]), /* HSPI0 */
188
	CLKDEV_DEV_ID("fffc7000.spi", &mstp_clks[MSTP007]), /* HSPI0 */
189
	CLKDEV_DEV_ID("sh-hspi.1", &mstp_clks[MSTP007]), /* HSPI1 */
190
	CLKDEV_DEV_ID("fffc8000.spi", &mstp_clks[MSTP007]), /* HSPI1 */
191
	CLKDEV_DEV_ID("sh-hspi.2", &mstp_clks[MSTP007]), /* HSPI2 */
192
	CLKDEV_DEV_ID("fffc6000.spi", &mstp_clks[MSTP007]), /* HSPI2 */
P
Phil Edworthy 已提交
193
	CLKDEV_DEV_ID("sh_mobile_sdhi.0", &mstp_clks[MSTP323]), /* SDHI0 */
194
	CLKDEV_DEV_ID("ffe4c000.sd", &mstp_clks[MSTP323]), /* SDHI0 */
P
Phil Edworthy 已提交
195
	CLKDEV_DEV_ID("sh_mobile_sdhi.1", &mstp_clks[MSTP322]), /* SDHI1 */
196
	CLKDEV_DEV_ID("ffe4d000.sd", &mstp_clks[MSTP322]), /* SDHI1 */
P
Phil Edworthy 已提交
197
	CLKDEV_DEV_ID("sh_mobile_sdhi.2", &mstp_clks[MSTP321]), /* SDHI2 */
198
	CLKDEV_DEV_ID("ffe4e000.sd", &mstp_clks[MSTP321]), /* SDHI2 */
P
Phil Edworthy 已提交
199
	CLKDEV_DEV_ID("sh_mobile_sdhi.3", &mstp_clks[MSTP320]), /* SDHI3 */
200
	CLKDEV_DEV_ID("ffe4f000.sd", &mstp_clks[MSTP320]), /* SDHI3 */
201
	CLKDEV_DEV_ID("rcar-du-r8a7779", &mstp_clks[MSTP103]), /* DU */
202 203 204 205
};

void __init r8a7779_clock_init(void)
{
206
	u32 mode = r8a7779_read_mode_pins();
207 208
	int k, ret = 0;

209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248
	if (mode & MD(1)) {
		plla_clk.rate = 1500000000;

		SH_CLK_SET_RATIO(&clkz_clk_ratio,	2, 3);
		SH_CLK_SET_RATIO(&clkzs_clk_ratio,	1, 6);
		SH_CLK_SET_RATIO(&clki_clk_ratio,	1, 2);
		SH_CLK_SET_RATIO(&clks_clk_ratio,	1, 6);
		SH_CLK_SET_RATIO(&clks1_clk_ratio,	1, 12);
		SH_CLK_SET_RATIO(&clks3_clk_ratio,	1, 8);
		SH_CLK_SET_RATIO(&clks4_clk_ratio,	1, 16);
		SH_CLK_SET_RATIO(&clkp_clk_ratio,	1, 24);
		SH_CLK_SET_RATIO(&clkg_clk_ratio,	1, 24);
		if (mode & MD(2)) {
			SH_CLK_SET_RATIO(&clkb_clk_ratio,	1, 36);
			SH_CLK_SET_RATIO(&clkout_clk_ratio,	1, 36);
		} else {
			SH_CLK_SET_RATIO(&clkb_clk_ratio,	1, 24);
			SH_CLK_SET_RATIO(&clkout_clk_ratio,	1, 24);
		}
	} else {
		plla_clk.rate = 1600000000;

		SH_CLK_SET_RATIO(&clkz_clk_ratio,	1, 2);
		SH_CLK_SET_RATIO(&clkzs_clk_ratio,	1, 8);
		SH_CLK_SET_RATIO(&clki_clk_ratio,	1, 2);
		SH_CLK_SET_RATIO(&clks_clk_ratio,	1, 8);
		SH_CLK_SET_RATIO(&clks1_clk_ratio,	1, 16);
		SH_CLK_SET_RATIO(&clks3_clk_ratio,	1, 8);
		SH_CLK_SET_RATIO(&clks4_clk_ratio,	1, 16);
		SH_CLK_SET_RATIO(&clkp_clk_ratio,	1, 32);
		SH_CLK_SET_RATIO(&clkg_clk_ratio,	1, 24);
		if (mode & MD(2)) {
			SH_CLK_SET_RATIO(&clkb_clk_ratio,	1, 32);
			SH_CLK_SET_RATIO(&clkout_clk_ratio,	1, 32);
		} else {
			SH_CLK_SET_RATIO(&clkb_clk_ratio,	1, 24);
			SH_CLK_SET_RATIO(&clkout_clk_ratio,	1, 24);
		}
	}

249 250 251 252
	for (k = 0; !ret && (k < ARRAY_SIZE(main_clks)); k++)
		ret = clk_register(main_clks[k]);

	if (!ret)
253
		ret = sh_clk_mstp_register(mstp_clks, MSTP_NR);
254 255 256 257

	clkdev_add_table(lookups, ARRAY_SIZE(lookups));

	if (!ret)
258
		shmobile_clk_init();
259 260 261
	else
		panic("failed to setup r8a7779 clocks\n");
}
262 263 264 265 266 267 268 269 270 271

/* do nothing for !CONFIG_SMP or !CONFIG_HAVE_TWD */
void __init __weak r8a7779_register_twd(void) { }

void __init r8a7779_earlytimer_init(void)
{
	r8a7779_clock_init();
	r8a7779_register_twd();
	shmobile_earlytimer_init();
}