1/* 2 * r8a7779 clock framework support 3 * 4 * Copyright (C) 2011 Renesas Solutions Corp. 5 * Copyright (C) 2011 Magnus Damm 6 * 7 * This program is free software; you can redistribute it and/or modify 8 * it under the terms of the GNU General Public License as published by 9 * the Free Software Foundation; either version 2 of the License 10 * 11 * This program is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 * GNU General Public License for more details. 15 */ 16#include <linux/bitops.h> 17#include <linux/init.h> 18#include <linux/kernel.h> 19#include <linux/io.h> 20#include <linux/sh_clk.h> 21#include <linux/clkdev.h> 22#include <linux/sh_timer.h> 23 24#include "clock.h" 25#include "common.h" 26#include "r8a7779.h" 27 28/* 29 * MD1 = 1 MD1 = 0 30 * (PLLA = 1500) (PLLA = 1600) 31 * (MHz) (MHz) 32 *------------------------------------------------+-------------------- 33 * clkz 1000 (2/3) 800 (1/2) 34 * clkzs 250 (1/6) 200 (1/8) 35 * clki 750 (1/2) 800 (1/2) 36 * clks 250 (1/6) 200 (1/8) 37 * clks1 125 (1/12) 100 (1/16) 38 * clks3 187.5 (1/8) 200 (1/8) 39 * clks4 93.7 (1/16) 100 (1/16) 40 * clkp 62.5 (1/24) 50 (1/32) 41 * clkg 62.5 (1/24) 66.6 (1/24) 42 * clkb, CLKOUT 43 * (MD2 = 0) 62.5 (1/24) 66.6 (1/24) 44 * (MD2 = 1) 41.6 (1/36) 50 (1/32) 45*/ 46 47#define MD(nr) BIT(nr) 48 49#define MSTPCR0 IOMEM(0xffc80030) 50#define MSTPCR1 IOMEM(0xffc80034) 51#define MSTPCR3 IOMEM(0xffc8003c) 52#define MSTPSR1 IOMEM(0xffc80044) 53 54/* ioremap() through clock mapping mandatory to avoid 55 * collision with ARM coherent DMA virtual memory range. 56 */ 57 58static struct clk_mapping cpg_mapping = { 59 .phys = 0xffc80000, 60 .len = 0x80, 61}; 62 63/* 64 * Default rate for the root input clock, reset this with clk_set_rate() 65 * from the platform code. 66 */ 67static struct clk plla_clk = { 68 /* .rate will be updated on r8a7779_clock_init() */ 69 .mapping = &cpg_mapping, 70}; 71 72/* 73 * clock ratio of these clock will be updated 74 * on r8a7779_clock_init() 75 */ 76SH_FIXED_RATIO_CLK_SET(clkz_clk, plla_clk, 1, 1); 77SH_FIXED_RATIO_CLK_SET(clkzs_clk, plla_clk, 1, 1); 78SH_FIXED_RATIO_CLK_SET(clki_clk, plla_clk, 1, 1); 79SH_FIXED_RATIO_CLK_SET(clks_clk, plla_clk, 1, 1); 80SH_FIXED_RATIO_CLK_SET(clks1_clk, plla_clk, 1, 1); 81SH_FIXED_RATIO_CLK_SET(clks3_clk, plla_clk, 1, 1); 82SH_FIXED_RATIO_CLK_SET(clks4_clk, plla_clk, 1, 1); 83SH_FIXED_RATIO_CLK_SET(clkb_clk, plla_clk, 1, 1); 84SH_FIXED_RATIO_CLK_SET(clkout_clk, plla_clk, 1, 1); 85SH_FIXED_RATIO_CLK_SET(clkp_clk, plla_clk, 1, 1); 86SH_FIXED_RATIO_CLK_SET(clkg_clk, plla_clk, 1, 1); 87 88static struct clk *main_clks[] = { 89 &plla_clk, 90 &clkz_clk, 91 &clkzs_clk, 92 &clki_clk, 93 &clks_clk, 94 &clks1_clk, 95 &clks3_clk, 96 &clks4_clk, 97 &clkb_clk, 98 &clkout_clk, 99 &clkp_clk, 100 &clkg_clk, 101}; 102 103enum { MSTP323, MSTP322, MSTP321, MSTP320, 104 MSTP120, 105 MSTP116, MSTP115, MSTP114, 106 MSTP110, MSTP109, MSTP108, 107 MSTP103, MSTP101, MSTP100, 108 MSTP030, 109 MSTP029, MSTP028, MSTP027, MSTP026, MSTP025, MSTP024, MSTP023, MSTP022, MSTP021, 110 MSTP016, MSTP015, MSTP014, 111 MSTP007, 112 MSTP_NR }; 113 114static struct clk mstp_clks[MSTP_NR] = { 115 [MSTP323] = SH_CLK_MSTP32(&clkp_clk, MSTPCR3, 23, 0), /* SDHI0 */ 116 [MSTP322] = SH_CLK_MSTP32(&clkp_clk, MSTPCR3, 22, 0), /* SDHI1 */ 117 [MSTP321] = SH_CLK_MSTP32(&clkp_clk, MSTPCR3, 21, 0), /* SDHI2 */ 118 [MSTP320] = SH_CLK_MSTP32(&clkp_clk, MSTPCR3, 20, 0), /* SDHI3 */ 119 [MSTP120] = SH_CLK_MSTP32_STS(&clks_clk, MSTPCR1, 20, MSTPSR1, 0), /* VIN3 */ 120 [MSTP116] = SH_CLK_MSTP32_STS(&clkp_clk, MSTPCR1, 16, MSTPSR1, 0), /* PCIe */ 121 [MSTP115] = SH_CLK_MSTP32_STS(&clkp_clk, MSTPCR1, 15, MSTPSR1, 0), /* SATA */ 122 [MSTP114] = SH_CLK_MSTP32_STS(&clkp_clk, MSTPCR1, 14, MSTPSR1, 0), /* Ether */ 123 [MSTP110] = SH_CLK_MSTP32_STS(&clks_clk, MSTPCR1, 10, MSTPSR1, 0), /* VIN0 */ 124 [MSTP109] = SH_CLK_MSTP32_STS(&clks_clk, MSTPCR1, 9, MSTPSR1, 0), /* VIN1 */ 125 [MSTP108] = SH_CLK_MSTP32_STS(&clks_clk, MSTPCR1, 8, MSTPSR1, 0), /* VIN2 */ 126 [MSTP103] = SH_CLK_MSTP32_STS(&clks_clk, MSTPCR1, 3, MSTPSR1, 0), /* DU */ 127 [MSTP101] = SH_CLK_MSTP32_STS(&clkp_clk, MSTPCR1, 1, MSTPSR1, 0), /* USB2 */ 128 [MSTP100] = SH_CLK_MSTP32_STS(&clkp_clk, MSTPCR1, 0, MSTPSR1, 0), /* USB0/1 */ 129 [MSTP030] = SH_CLK_MSTP32(&clkp_clk, MSTPCR0, 30, 0), /* I2C0 */ 130 [MSTP029] = SH_CLK_MSTP32(&clkp_clk, MSTPCR0, 29, 0), /* I2C1 */ 131 [MSTP028] = SH_CLK_MSTP32(&clkp_clk, MSTPCR0, 28, 0), /* I2C2 */ 132 [MSTP027] = SH_CLK_MSTP32(&clkp_clk, MSTPCR0, 27, 0), /* I2C3 */ 133 [MSTP026] = SH_CLK_MSTP32(&clkp_clk, MSTPCR0, 26, 0), /* SCIF0 */ 134 [MSTP025] = SH_CLK_MSTP32(&clkp_clk, MSTPCR0, 25, 0), /* SCIF1 */ 135 [MSTP024] = SH_CLK_MSTP32(&clkp_clk, MSTPCR0, 24, 0), /* SCIF2 */ 136 [MSTP023] = SH_CLK_MSTP32(&clkp_clk, MSTPCR0, 23, 0), /* SCIF3 */ 137 [MSTP022] = SH_CLK_MSTP32(&clkp_clk, MSTPCR0, 22, 0), /* SCIF4 */ 138 [MSTP021] = SH_CLK_MSTP32(&clkp_clk, MSTPCR0, 21, 0), /* SCIF5 */ 139 [MSTP016] = SH_CLK_MSTP32(&clkp_clk, MSTPCR0, 16, 0), /* TMU0 */ 140 [MSTP015] = SH_CLK_MSTP32(&clkp_clk, MSTPCR0, 15, 0), /* TMU1 */ 141 [MSTP014] = SH_CLK_MSTP32(&clkp_clk, MSTPCR0, 14, 0), /* TMU2 */ 142 [MSTP007] = SH_CLK_MSTP32(&clks_clk, MSTPCR0, 7, 0), /* HSPI */ 143}; 144 145static struct clk_lookup lookups[] = { 146 /* main clocks */ 147 CLKDEV_CON_ID("plla_clk", &plla_clk), 148 CLKDEV_CON_ID("clkz_clk", &clkz_clk), 149 CLKDEV_CON_ID("clkzs_clk", &clkzs_clk), 150 151 /* DIV4 clocks */ 152 CLKDEV_CON_ID("shyway_clk", &clks_clk), 153 CLKDEV_CON_ID("bus_clk", &clkout_clk), 154 CLKDEV_CON_ID("shyway4_clk", &clks4_clk), 155 CLKDEV_CON_ID("shyway3_clk", &clks3_clk), 156 CLKDEV_CON_ID("shyway1_clk", &clks1_clk), 157 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 CLKDEV_DEV_ID("sata_rcar", &mstp_clks[MSTP115]), /* SATA */ 163 CLKDEV_DEV_ID("fc600000.sata", &mstp_clks[MSTP115]), /* SATA w/DT */ 164 CLKDEV_DEV_ID("r8a777x-ether", &mstp_clks[MSTP114]), /* Ether */ 165 CLKDEV_DEV_ID("r8a7779-vin.0", &mstp_clks[MSTP110]), /* VIN0 */ 166 CLKDEV_DEV_ID("r8a7779-vin.1", &mstp_clks[MSTP109]), /* VIN1 */ 167 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 CLKDEV_DEV_ID("sh-sci.0", &mstp_clks[MSTP026]), /* SCIF0 */ 182 CLKDEV_DEV_ID("sh-sci.1", &mstp_clks[MSTP025]), /* SCIF1 */ 183 CLKDEV_DEV_ID("sh-sci.2", &mstp_clks[MSTP024]), /* SCIF2 */ 184 CLKDEV_DEV_ID("sh-sci.3", &mstp_clks[MSTP023]), /* SCIF3 */ 185 CLKDEV_DEV_ID("sh-sci.4", &mstp_clks[MSTP022]), /* SCIF4 */ 186 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 */ 193 CLKDEV_DEV_ID("sh_mobile_sdhi.0", &mstp_clks[MSTP323]), /* SDHI0 */ 194 CLKDEV_DEV_ID("ffe4c000.sd", &mstp_clks[MSTP323]), /* SDHI0 */ 195 CLKDEV_DEV_ID("sh_mobile_sdhi.1", &mstp_clks[MSTP322]), /* SDHI1 */ 196 CLKDEV_DEV_ID("ffe4d000.sd", &mstp_clks[MSTP322]), /* SDHI1 */ 197 CLKDEV_DEV_ID("sh_mobile_sdhi.2", &mstp_clks[MSTP321]), /* SDHI2 */ 198 CLKDEV_DEV_ID("ffe4e000.sd", &mstp_clks[MSTP321]), /* SDHI2 */ 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 204void __init r8a7779_clock_init(void) 205{ 206 u32 mode = r8a7779_read_mode_pins(); 207 int k, ret = 0; 208 209 if (mode & MD(1)) { 210 plla_clk.rate = 1500000000; 211 212 SH_CLK_SET_RATIO(&clkz_clk_ratio, 2, 3); 213 SH_CLK_SET_RATIO(&clkzs_clk_ratio, 1, 6); 214 SH_CLK_SET_RATIO(&clki_clk_ratio, 1, 2); 215 SH_CLK_SET_RATIO(&clks_clk_ratio, 1, 6); 216 SH_CLK_SET_RATIO(&clks1_clk_ratio, 1, 12); 217 SH_CLK_SET_RATIO(&clks3_clk_ratio, 1, 8); 218 SH_CLK_SET_RATIO(&clks4_clk_ratio, 1, 16); 219 SH_CLK_SET_RATIO(&clkp_clk_ratio, 1, 24); 220 SH_CLK_SET_RATIO(&clkg_clk_ratio, 1, 24); 221 if (mode & MD(2)) { 222 SH_CLK_SET_RATIO(&clkb_clk_ratio, 1, 36); 223 SH_CLK_SET_RATIO(&clkout_clk_ratio, 1, 36); 224 } else { 225 SH_CLK_SET_RATIO(&clkb_clk_ratio, 1, 24); 226 SH_CLK_SET_RATIO(&clkout_clk_ratio, 1, 24); 227 } 228 } else { 229 plla_clk.rate = 1600000000; 230 231 SH_CLK_SET_RATIO(&clkz_clk_ratio, 1, 2); 232 SH_CLK_SET_RATIO(&clkzs_clk_ratio, 1, 8); 233 SH_CLK_SET_RATIO(&clki_clk_ratio, 1, 2); 234 SH_CLK_SET_RATIO(&clks_clk_ratio, 1, 8); 235 SH_CLK_SET_RATIO(&clks1_clk_ratio, 1, 16); 236 SH_CLK_SET_RATIO(&clks3_clk_ratio, 1, 8); 237 SH_CLK_SET_RATIO(&clks4_clk_ratio, 1, 16); 238 SH_CLK_SET_RATIO(&clkp_clk_ratio, 1, 32); 239 SH_CLK_SET_RATIO(&clkg_clk_ratio, 1, 24); 240 if (mode & MD(2)) { 241 SH_CLK_SET_RATIO(&clkb_clk_ratio, 1, 32); 242 SH_CLK_SET_RATIO(&clkout_clk_ratio, 1, 32); 243 } else { 244 SH_CLK_SET_RATIO(&clkb_clk_ratio, 1, 24); 245 SH_CLK_SET_RATIO(&clkout_clk_ratio, 1, 24); 246 } 247 } 248 249 for (k = 0; !ret && (k < ARRAY_SIZE(main_clks)); k++) 250 ret = clk_register(main_clks[k]); 251 252 if (!ret) 253 ret = sh_clk_mstp_register(mstp_clks, MSTP_NR); 254 255 clkdev_add_table(lookups, ARRAY_SIZE(lookups)); 256 257 if (!ret) 258 shmobile_clk_init(); 259 else 260 panic("failed to setup r8a7779 clocks\n"); 261} 262 263/* do nothing for !CONFIG_SMP or !CONFIG_HAVE_TWD */ 264void __init __weak r8a7779_register_twd(void) { } 265 266void __init r8a7779_earlytimer_init(void) 267{ 268 r8a7779_clock_init(); 269 r8a7779_register_twd(); 270 shmobile_earlytimer_init(); 271} 272