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 <asm/mach-types.h> 29 #include <asm/mach/arch.h> 30 31 /* SCIFA0 */ 32 static struct plat_sci_port scif0_platform_data = { 33 .mapbase = 0xe6c40000, 34 .flags = UPF_BOOT_AUTOCONF, 35 .scscr = SCSCR_RE | SCSCR_TE, 36 .scbrr_algo_id = SCBRR_ALGO_4, 37 .type = PORT_SCIFA, 38 .irqs = SCIx_IRQ_MUXED(evt2irq(0x0c00)), 39 }; 40 41 static struct platform_device scif0_device = { 42 .name = "sh-sci", 43 .id = 0, 44 .dev = { 45 .platform_data = &scif0_platform_data, 46 }, 47 }; 48 49 /* SCIFA1 */ 50 static struct plat_sci_port scif1_platform_data = { 51 .mapbase = 0xe6c50000, 52 .flags = UPF_BOOT_AUTOCONF, 53 .scscr = SCSCR_RE | SCSCR_TE, 54 .scbrr_algo_id = SCBRR_ALGO_4, 55 .type = PORT_SCIFA, 56 .irqs = SCIx_IRQ_MUXED(evt2irq(0x0c20)), 57 }; 58 59 static struct platform_device scif1_device = { 60 .name = "sh-sci", 61 .id = 1, 62 .dev = { 63 .platform_data = &scif1_platform_data, 64 }, 65 }; 66 67 /* SCIFA2 */ 68 static struct plat_sci_port scif2_platform_data = { 69 .mapbase = 0xe6c60000, 70 .flags = UPF_BOOT_AUTOCONF, 71 .scscr = SCSCR_RE | SCSCR_TE, 72 .scbrr_algo_id = SCBRR_ALGO_4, 73 .type = PORT_SCIFA, 74 .irqs = SCIx_IRQ_MUXED(evt2irq(0x0c40)), 75 }; 76 77 static struct platform_device scif2_device = { 78 .name = "sh-sci", 79 .id = 2, 80 .dev = { 81 .platform_data = &scif2_platform_data, 82 }, 83 }; 84 85 /* SCIFA3 */ 86 static struct plat_sci_port scif3_platform_data = { 87 .mapbase = 0xe6c70000, 88 .flags = UPF_BOOT_AUTOCONF, 89 .scscr = SCSCR_RE | SCSCR_TE, 90 .scbrr_algo_id = SCBRR_ALGO_4, 91 .type = PORT_SCIFA, 92 .irqs = SCIx_IRQ_MUXED(evt2irq(0x0c60)), 93 }; 94 95 static struct platform_device scif3_device = { 96 .name = "sh-sci", 97 .id = 3, 98 .dev = { 99 .platform_data = &scif3_platform_data, 100 }, 101 }; 102 103 /* SCIFA4 */ 104 static struct plat_sci_port scif4_platform_data = { 105 .mapbase = 0xe6c80000, 106 .flags = UPF_BOOT_AUTOCONF, 107 .scscr = SCSCR_RE | SCSCR_TE, 108 .scbrr_algo_id = SCBRR_ALGO_4, 109 .type = PORT_SCIFA, 110 .irqs = SCIx_IRQ_MUXED(evt2irq(0x0d20)), 111 }; 112 113 static struct platform_device scif4_device = { 114 .name = "sh-sci", 115 .id = 4, 116 .dev = { 117 .platform_data = &scif4_platform_data, 118 }, 119 }; 120 121 /* SCIFA5 */ 122 static struct plat_sci_port scif5_platform_data = { 123 .mapbase = 0xe6cb0000, 124 .flags = UPF_BOOT_AUTOCONF, 125 .scscr = SCSCR_RE | SCSCR_TE, 126 .scbrr_algo_id = SCBRR_ALGO_4, 127 .type = PORT_SCIFA, 128 .irqs = SCIx_IRQ_MUXED(evt2irq(0x0d40)), 129 }; 130 131 static struct platform_device scif5_device = { 132 .name = "sh-sci", 133 .id = 5, 134 .dev = { 135 .platform_data = &scif5_platform_data, 136 }, 137 }; 138 139 /* SCIFA6 */ 140 static struct plat_sci_port scif6_platform_data = { 141 .mapbase = 0xe6cc0000, 142 .flags = UPF_BOOT_AUTOCONF, 143 .scscr = SCSCR_RE | SCSCR_TE, 144 .scbrr_algo_id = SCBRR_ALGO_4, 145 .type = PORT_SCIFA, 146 .irqs = SCIx_IRQ_MUXED(evt2irq(0x04c0)), 147 }; 148 149 static struct platform_device scif6_device = { 150 .name = "sh-sci", 151 .id = 6, 152 .dev = { 153 .platform_data = &scif6_platform_data, 154 }, 155 }; 156 157 /* SCIFA7 */ 158 static struct plat_sci_port scif7_platform_data = { 159 .mapbase = 0xe6cd0000, 160 .flags = UPF_BOOT_AUTOCONF, 161 .scscr = SCSCR_RE | SCSCR_TE, 162 .scbrr_algo_id = SCBRR_ALGO_4, 163 .type = PORT_SCIFA, 164 .irqs = SCIx_IRQ_MUXED(evt2irq(0x04e0)), 165 }; 166 167 static struct platform_device scif7_device = { 168 .name = "sh-sci", 169 .id = 7, 170 .dev = { 171 .platform_data = &scif7_platform_data, 172 }, 173 }; 174 175 /* SCIFB */ 176 static struct plat_sci_port scifb_platform_data = { 177 .mapbase = 0xe6c30000, 178 .flags = UPF_BOOT_AUTOCONF, 179 .scscr = SCSCR_RE | SCSCR_TE, 180 .scbrr_algo_id = SCBRR_ALGO_4, 181 .type = PORT_SCIFB, 182 .irqs = SCIx_IRQ_MUXED(evt2irq(0x0d60)), 183 }; 184 185 static struct platform_device scifb_device = { 186 .name = "sh-sci", 187 .id = 8, 188 .dev = { 189 .platform_data = &scifb_platform_data, 190 }, 191 }; 192 193 /* CMT */ 194 static struct sh_timer_config cmt10_platform_data = { 195 .name = "CMT10", 196 .channel_offset = 0x10, 197 .timer_bit = 0, 198 .clockevent_rating = 125, 199 .clocksource_rating = 125, 200 }; 201 202 static struct resource cmt10_resources[] = { 203 [0] = { 204 .name = "CMT10", 205 .start = 0xe6138010, 206 .end = 0xe613801b, 207 .flags = IORESOURCE_MEM, 208 }, 209 [1] = { 210 .start = evt2irq(0x0b00), 211 .flags = IORESOURCE_IRQ, 212 }, 213 }; 214 215 static struct platform_device cmt10_device = { 216 .name = "sh_cmt", 217 .id = 10, 218 .dev = { 219 .platform_data = &cmt10_platform_data, 220 }, 221 .resource = cmt10_resources, 222 .num_resources = ARRAY_SIZE(cmt10_resources), 223 }; 224 225 static struct platform_device *r8a7740_early_devices[] __initdata = { 226 &scif0_device, 227 &scif1_device, 228 &scif2_device, 229 &scif3_device, 230 &scif4_device, 231 &scif5_device, 232 &scif6_device, 233 &scif7_device, 234 &scifb_device, 235 &cmt10_device, 236 }; 237 238 /* I2C */ 239 static struct resource i2c0_resources[] = { 240 [0] = { 241 .name = "IIC0", 242 .start = 0xfff20000, 243 .end = 0xfff20425 - 1, 244 .flags = IORESOURCE_MEM, 245 }, 246 [1] = { 247 .start = intcs_evt2irq(0xe00), 248 .end = intcs_evt2irq(0xe60), 249 .flags = IORESOURCE_IRQ, 250 }, 251 }; 252 253 static struct resource i2c1_resources[] = { 254 [0] = { 255 .name = "IIC1", 256 .start = 0xe6c20000, 257 .end = 0xe6c20425 - 1, 258 .flags = IORESOURCE_MEM, 259 }, 260 [1] = { 261 .start = evt2irq(0x780), /* IIC1_ALI1 */ 262 .end = evt2irq(0x7e0), /* IIC1_DTEI1 */ 263 .flags = IORESOURCE_IRQ, 264 }, 265 }; 266 267 static struct platform_device i2c0_device = { 268 .name = "i2c-sh_mobile", 269 .id = 0, 270 .resource = i2c0_resources, 271 .num_resources = ARRAY_SIZE(i2c0_resources), 272 }; 273 274 static struct platform_device i2c1_device = { 275 .name = "i2c-sh_mobile", 276 .id = 1, 277 .resource = i2c1_resources, 278 .num_resources = ARRAY_SIZE(i2c1_resources), 279 }; 280 281 static struct platform_device *r8a7740_late_devices[] __initdata = { 282 &i2c0_device, 283 &i2c1_device, 284 }; 285 286 #define ICCR 0x0004 287 #define ICSTART 0x0070 288 289 #define i2c_read(reg, offset) ioread8(reg + offset) 290 #define i2c_write(reg, offset, data) iowrite8(data, reg + offset) 291 292 /* 293 * r8a7740 chip has lasting errata on I2C I/O pad reset. 294 * this is work-around for it. 295 */ 296 static void r8a7740_i2c_workaround(struct platform_device *pdev) 297 { 298 struct resource *res; 299 void __iomem *reg; 300 301 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 302 if (unlikely(!res)) { 303 pr_err("r8a7740 i2c workaround fail (cannot find resource)\n"); 304 return; 305 } 306 307 reg = ioremap(res->start, resource_size(res)); 308 if (unlikely(!reg)) { 309 pr_err("r8a7740 i2c workaround fail (cannot map IO)\n"); 310 return; 311 } 312 313 i2c_write(reg, ICCR, i2c_read(reg, ICCR) | 0x80); 314 i2c_read(reg, ICCR); /* dummy read */ 315 316 i2c_write(reg, ICSTART, i2c_read(reg, ICSTART) | 0x10); 317 i2c_read(reg, ICSTART); /* dummy read */ 318 319 mdelay(100); 320 321 i2c_write(reg, ICCR, 0x01); 322 i2c_read(reg, ICCR); 323 i2c_write(reg, ICSTART, 0x00); 324 i2c_read(reg, ICSTART); 325 326 i2c_write(reg, ICCR, 0x10); 327 mdelay(100); 328 i2c_write(reg, ICCR, 0x00); 329 mdelay(100); 330 i2c_write(reg, ICCR, 0x10); 331 mdelay(100); 332 333 iounmap(reg); 334 } 335 336 void __init r8a7740_add_standard_devices(void) 337 { 338 /* I2C work-around */ 339 r8a7740_i2c_workaround(&i2c0_device); 340 r8a7740_i2c_workaround(&i2c1_device); 341 342 platform_add_devices(r8a7740_early_devices, 343 ARRAY_SIZE(r8a7740_early_devices)); 344 platform_add_devices(r8a7740_late_devices, 345 ARRAY_SIZE(r8a7740_late_devices)); 346 } 347 348 void __init r8a7740_add_early_devices(void) 349 { 350 early_platform_add_devices(r8a7740_early_devices, 351 ARRAY_SIZE(r8a7740_early_devices)); 352 } 353