1 /* 2 * R8A7740 processor support 3 * 4 * Copyright (C) 2011 Renesas Solutions Corp. 5 * Copyright (C) 2011 Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> 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; 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 * You should have received a copy of the GNU General Public License 17 * along with this program; if not, write to the Free Software 18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 19 */ 20 #include <linux/delay.h> 21 #include <linux/kernel.h> 22 #include <linux/init.h> 23 #include <linux/io.h> 24 #include <linux/platform_device.h> 25 #include <linux/serial_sci.h> 26 #include <linux/sh_timer.h> 27 #include <mach/r8a7740.h> 28 #include <mach/common.h> 29 #include <mach/irqs.h> 30 #include <asm/mach-types.h> 31 #include <asm/mach/map.h> 32 #include <asm/mach/arch.h> 33 #include <asm/mach/time.h> 34 35 static struct map_desc r8a7740_io_desc[] __initdata = { 36 /* 37 * for CPGA/INTC/PFC 38 * 0xe6000000-0xefffffff -> 0xe6000000-0xefffffff 39 */ 40 { 41 .virtual = 0xe6000000, 42 .pfn = __phys_to_pfn(0xe6000000), 43 .length = 160 << 20, 44 .type = MT_DEVICE_NONSHARED 45 }, 46 #ifdef CONFIG_CACHE_L2X0 47 /* 48 * for l2x0_init() 49 * 0xf0100000-0xf0101000 -> 0xf0002000-0xf0003000 50 */ 51 { 52 .virtual = 0xf0002000, 53 .pfn = __phys_to_pfn(0xf0100000), 54 .length = PAGE_SIZE, 55 .type = MT_DEVICE_NONSHARED 56 }, 57 #endif 58 }; 59 60 void __init r8a7740_map_io(void) 61 { 62 iotable_init(r8a7740_io_desc, ARRAY_SIZE(r8a7740_io_desc)); 63 } 64 65 /* SCIFA0 */ 66 static struct plat_sci_port scif0_platform_data = { 67 .mapbase = 0xe6c40000, 68 .flags = UPF_BOOT_AUTOCONF, 69 .scscr = SCSCR_RE | SCSCR_TE, 70 .scbrr_algo_id = SCBRR_ALGO_4, 71 .type = PORT_SCIFA, 72 .irqs = SCIx_IRQ_MUXED(evt2irq(0x0c00)), 73 }; 74 75 static struct platform_device scif0_device = { 76 .name = "sh-sci", 77 .id = 0, 78 .dev = { 79 .platform_data = &scif0_platform_data, 80 }, 81 }; 82 83 /* SCIFA1 */ 84 static struct plat_sci_port scif1_platform_data = { 85 .mapbase = 0xe6c50000, 86 .flags = UPF_BOOT_AUTOCONF, 87 .scscr = SCSCR_RE | SCSCR_TE, 88 .scbrr_algo_id = SCBRR_ALGO_4, 89 .type = PORT_SCIFA, 90 .irqs = SCIx_IRQ_MUXED(evt2irq(0x0c20)), 91 }; 92 93 static struct platform_device scif1_device = { 94 .name = "sh-sci", 95 .id = 1, 96 .dev = { 97 .platform_data = &scif1_platform_data, 98 }, 99 }; 100 101 /* SCIFA2 */ 102 static struct plat_sci_port scif2_platform_data = { 103 .mapbase = 0xe6c60000, 104 .flags = UPF_BOOT_AUTOCONF, 105 .scscr = SCSCR_RE | SCSCR_TE, 106 .scbrr_algo_id = SCBRR_ALGO_4, 107 .type = PORT_SCIFA, 108 .irqs = SCIx_IRQ_MUXED(evt2irq(0x0c40)), 109 }; 110 111 static struct platform_device scif2_device = { 112 .name = "sh-sci", 113 .id = 2, 114 .dev = { 115 .platform_data = &scif2_platform_data, 116 }, 117 }; 118 119 /* SCIFA3 */ 120 static struct plat_sci_port scif3_platform_data = { 121 .mapbase = 0xe6c70000, 122 .flags = UPF_BOOT_AUTOCONF, 123 .scscr = SCSCR_RE | SCSCR_TE, 124 .scbrr_algo_id = SCBRR_ALGO_4, 125 .type = PORT_SCIFA, 126 .irqs = SCIx_IRQ_MUXED(evt2irq(0x0c60)), 127 }; 128 129 static struct platform_device scif3_device = { 130 .name = "sh-sci", 131 .id = 3, 132 .dev = { 133 .platform_data = &scif3_platform_data, 134 }, 135 }; 136 137 /* SCIFA4 */ 138 static struct plat_sci_port scif4_platform_data = { 139 .mapbase = 0xe6c80000, 140 .flags = UPF_BOOT_AUTOCONF, 141 .scscr = SCSCR_RE | SCSCR_TE, 142 .scbrr_algo_id = SCBRR_ALGO_4, 143 .type = PORT_SCIFA, 144 .irqs = SCIx_IRQ_MUXED(evt2irq(0x0d20)), 145 }; 146 147 static struct platform_device scif4_device = { 148 .name = "sh-sci", 149 .id = 4, 150 .dev = { 151 .platform_data = &scif4_platform_data, 152 }, 153 }; 154 155 /* SCIFA5 */ 156 static struct plat_sci_port scif5_platform_data = { 157 .mapbase = 0xe6cb0000, 158 .flags = UPF_BOOT_AUTOCONF, 159 .scscr = SCSCR_RE | SCSCR_TE, 160 .scbrr_algo_id = SCBRR_ALGO_4, 161 .type = PORT_SCIFA, 162 .irqs = SCIx_IRQ_MUXED(evt2irq(0x0d40)), 163 }; 164 165 static struct platform_device scif5_device = { 166 .name = "sh-sci", 167 .id = 5, 168 .dev = { 169 .platform_data = &scif5_platform_data, 170 }, 171 }; 172 173 /* SCIFA6 */ 174 static struct plat_sci_port scif6_platform_data = { 175 .mapbase = 0xe6cc0000, 176 .flags = UPF_BOOT_AUTOCONF, 177 .scscr = SCSCR_RE | SCSCR_TE, 178 .scbrr_algo_id = SCBRR_ALGO_4, 179 .type = PORT_SCIFA, 180 .irqs = SCIx_IRQ_MUXED(evt2irq(0x04c0)), 181 }; 182 183 static struct platform_device scif6_device = { 184 .name = "sh-sci", 185 .id = 6, 186 .dev = { 187 .platform_data = &scif6_platform_data, 188 }, 189 }; 190 191 /* SCIFA7 */ 192 static struct plat_sci_port scif7_platform_data = { 193 .mapbase = 0xe6cd0000, 194 .flags = UPF_BOOT_AUTOCONF, 195 .scscr = SCSCR_RE | SCSCR_TE, 196 .scbrr_algo_id = SCBRR_ALGO_4, 197 .type = PORT_SCIFA, 198 .irqs = SCIx_IRQ_MUXED(evt2irq(0x04e0)), 199 }; 200 201 static struct platform_device scif7_device = { 202 .name = "sh-sci", 203 .id = 7, 204 .dev = { 205 .platform_data = &scif7_platform_data, 206 }, 207 }; 208 209 /* SCIFB */ 210 static struct plat_sci_port scifb_platform_data = { 211 .mapbase = 0xe6c30000, 212 .flags = UPF_BOOT_AUTOCONF, 213 .scscr = SCSCR_RE | SCSCR_TE, 214 .scbrr_algo_id = SCBRR_ALGO_4, 215 .type = PORT_SCIFB, 216 .irqs = SCIx_IRQ_MUXED(evt2irq(0x0d60)), 217 }; 218 219 static struct platform_device scifb_device = { 220 .name = "sh-sci", 221 .id = 8, 222 .dev = { 223 .platform_data = &scifb_platform_data, 224 }, 225 }; 226 227 /* CMT */ 228 static struct sh_timer_config cmt10_platform_data = { 229 .name = "CMT10", 230 .channel_offset = 0x10, 231 .timer_bit = 0, 232 .clockevent_rating = 125, 233 .clocksource_rating = 125, 234 }; 235 236 static struct resource cmt10_resources[] = { 237 [0] = { 238 .name = "CMT10", 239 .start = 0xe6138010, 240 .end = 0xe613801b, 241 .flags = IORESOURCE_MEM, 242 }, 243 [1] = { 244 .start = evt2irq(0x0b00), 245 .flags = IORESOURCE_IRQ, 246 }, 247 }; 248 249 static struct platform_device cmt10_device = { 250 .name = "sh_cmt", 251 .id = 10, 252 .dev = { 253 .platform_data = &cmt10_platform_data, 254 }, 255 .resource = cmt10_resources, 256 .num_resources = ARRAY_SIZE(cmt10_resources), 257 }; 258 259 static struct platform_device *r8a7740_early_devices[] __initdata = { 260 &scif0_device, 261 &scif1_device, 262 &scif2_device, 263 &scif3_device, 264 &scif4_device, 265 &scif5_device, 266 &scif6_device, 267 &scif7_device, 268 &scifb_device, 269 &cmt10_device, 270 }; 271 272 /* I2C */ 273 static struct resource i2c0_resources[] = { 274 [0] = { 275 .name = "IIC0", 276 .start = 0xfff20000, 277 .end = 0xfff20425 - 1, 278 .flags = IORESOURCE_MEM, 279 }, 280 [1] = { 281 .start = intcs_evt2irq(0xe00), 282 .end = intcs_evt2irq(0xe60), 283 .flags = IORESOURCE_IRQ, 284 }, 285 }; 286 287 static struct resource i2c1_resources[] = { 288 [0] = { 289 .name = "IIC1", 290 .start = 0xe6c20000, 291 .end = 0xe6c20425 - 1, 292 .flags = IORESOURCE_MEM, 293 }, 294 [1] = { 295 .start = evt2irq(0x780), /* IIC1_ALI1 */ 296 .end = evt2irq(0x7e0), /* IIC1_DTEI1 */ 297 .flags = IORESOURCE_IRQ, 298 }, 299 }; 300 301 static struct platform_device i2c0_device = { 302 .name = "i2c-sh_mobile", 303 .id = 0, 304 .resource = i2c0_resources, 305 .num_resources = ARRAY_SIZE(i2c0_resources), 306 }; 307 308 static struct platform_device i2c1_device = { 309 .name = "i2c-sh_mobile", 310 .id = 1, 311 .resource = i2c1_resources, 312 .num_resources = ARRAY_SIZE(i2c1_resources), 313 }; 314 315 static struct platform_device *r8a7740_late_devices[] __initdata = { 316 &i2c0_device, 317 &i2c1_device, 318 }; 319 320 #define ICCR 0x0004 321 #define ICSTART 0x0070 322 323 #define i2c_read(reg, offset) ioread8(reg + offset) 324 #define i2c_write(reg, offset, data) iowrite8(data, reg + offset) 325 326 /* 327 * r8a7740 chip has lasting errata on I2C I/O pad reset. 328 * this is work-around for it. 329 */ 330 static void r8a7740_i2c_workaround(struct platform_device *pdev) 331 { 332 struct resource *res; 333 void __iomem *reg; 334 335 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 336 if (unlikely(!res)) { 337 pr_err("r8a7740 i2c workaround fail (cannot find resource)\n"); 338 return; 339 } 340 341 reg = ioremap(res->start, resource_size(res)); 342 if (unlikely(!reg)) { 343 pr_err("r8a7740 i2c workaround fail (cannot map IO)\n"); 344 return; 345 } 346 347 i2c_write(reg, ICCR, i2c_read(reg, ICCR) | 0x80); 348 i2c_read(reg, ICCR); /* dummy read */ 349 350 i2c_write(reg, ICSTART, i2c_read(reg, ICSTART) | 0x10); 351 i2c_read(reg, ICSTART); /* dummy read */ 352 353 mdelay(100); 354 355 i2c_write(reg, ICCR, 0x01); 356 i2c_read(reg, ICCR); 357 i2c_write(reg, ICSTART, 0x00); 358 i2c_read(reg, ICSTART); 359 360 i2c_write(reg, ICCR, 0x10); 361 mdelay(100); 362 i2c_write(reg, ICCR, 0x00); 363 mdelay(100); 364 i2c_write(reg, ICCR, 0x10); 365 mdelay(100); 366 367 iounmap(reg); 368 } 369 370 void __init r8a7740_add_standard_devices(void) 371 { 372 /* I2C work-around */ 373 r8a7740_i2c_workaround(&i2c0_device); 374 r8a7740_i2c_workaround(&i2c1_device); 375 376 platform_add_devices(r8a7740_early_devices, 377 ARRAY_SIZE(r8a7740_early_devices)); 378 platform_add_devices(r8a7740_late_devices, 379 ARRAY_SIZE(r8a7740_late_devices)); 380 } 381 382 static void __init r8a7740_earlytimer_init(void) 383 { 384 r8a7740_clock_init(0); 385 shmobile_earlytimer_init(); 386 } 387 388 void __init r8a7740_add_early_devices(void) 389 { 390 early_platform_add_devices(r8a7740_early_devices, 391 ARRAY_SIZE(r8a7740_early_devices)); 392 393 /* setup early console here as well */ 394 shmobile_setup_console(); 395 396 /* override timer setup with soc-specific code */ 397 shmobile_timer.init = r8a7740_earlytimer_init; 398 } 399