1 /* 2 * arch/sh/boards/renesas/r7780rp/setup.c 3 * 4 * Renesas Solutions Highlander Support. 5 * 6 * Copyright (C) 2002 Atom Create Engineering Co., Ltd. 7 * Copyright (C) 2005 - 2008 Paul Mundt 8 * 9 * This contains support for the R7780RP-1, R7780MP, and R7785RP 10 * Highlander modules. 11 * 12 * This file is subject to the terms and conditions of the GNU General Public 13 * License. See the file "COPYING" in the main directory of this archive 14 * for more details. 15 */ 16 #include <linux/init.h> 17 #include <linux/platform_device.h> 18 #include <linux/ata_platform.h> 19 #include <linux/types.h> 20 #include <linux/i2c.h> 21 #include <linux/irq.h> 22 #include <linux/interrupt.h> 23 #include <linux/usb/r8a66597.h> 24 #include <net/ax88796.h> 25 #include <asm/machvec.h> 26 #include <mach/highlander.h> 27 #include <asm/clock.h> 28 #include <asm/heartbeat.h> 29 #include <asm/io.h> 30 #include <asm/io_trapped.h> 31 32 static struct r8a66597_platdata r8a66597_data = { 33 .xtal = R8A66597_PLATDATA_XTAL_12MHZ, 34 .vif = 1, 35 }; 36 37 static struct resource r8a66597_usb_host_resources[] = { 38 [0] = { 39 .start = 0xA4200000, 40 .end = 0xA42000FF, 41 .flags = IORESOURCE_MEM, 42 }, 43 [1] = { 44 .start = IRQ_EXT1, /* irq number */ 45 .end = IRQ_EXT1, 46 .flags = IORESOURCE_IRQ | IRQF_TRIGGER_LOW, 47 }, 48 }; 49 50 static struct platform_device r8a66597_usb_host_device = { 51 .name = "r8a66597_hcd", 52 .id = -1, 53 .dev = { 54 .dma_mask = NULL, /* don't use dma */ 55 .coherent_dma_mask = 0xffffffff, 56 .platform_data = &r8a66597_data, 57 }, 58 .num_resources = ARRAY_SIZE(r8a66597_usb_host_resources), 59 .resource = r8a66597_usb_host_resources, 60 }; 61 62 static struct resource m66592_usb_peripheral_resources[] = { 63 [0] = { 64 .name = "m66592_udc", 65 .start = 0xb0000000, 66 .end = 0xb00000FF, 67 .flags = IORESOURCE_MEM, 68 }, 69 [1] = { 70 .name = "m66592_udc", 71 .start = IRQ_EXT4, /* irq number */ 72 .end = IRQ_EXT4, 73 .flags = IORESOURCE_IRQ, 74 }, 75 }; 76 77 static struct platform_device m66592_usb_peripheral_device = { 78 .name = "m66592_udc", 79 .id = -1, 80 .dev = { 81 .dma_mask = NULL, /* don't use dma */ 82 .coherent_dma_mask = 0xffffffff, 83 }, 84 .num_resources = ARRAY_SIZE(m66592_usb_peripheral_resources), 85 .resource = m66592_usb_peripheral_resources, 86 }; 87 88 static struct resource cf_ide_resources[] = { 89 [0] = { 90 .start = PA_AREA5_IO + 0x1000, 91 .end = PA_AREA5_IO + 0x1000 + 0x08 - 1, 92 .flags = IORESOURCE_MEM, 93 }, 94 [1] = { 95 .start = PA_AREA5_IO + 0x80c, 96 .end = PA_AREA5_IO + 0x80c + 0x16 - 1, 97 .flags = IORESOURCE_MEM, 98 }, 99 [2] = { 100 .start = IRQ_CF, 101 .flags = IORESOURCE_IRQ, 102 }, 103 }; 104 105 static struct pata_platform_info pata_info = { 106 .ioport_shift = 1, 107 }; 108 109 static struct platform_device cf_ide_device = { 110 .name = "pata_platform", 111 .id = -1, 112 .num_resources = ARRAY_SIZE(cf_ide_resources), 113 .resource = cf_ide_resources, 114 .dev = { 115 .platform_data = &pata_info, 116 }, 117 }; 118 119 static struct resource heartbeat_resources[] = { 120 [0] = { 121 .start = PA_OBLED, 122 .end = PA_OBLED, 123 .flags = IORESOURCE_MEM, 124 }, 125 }; 126 127 #ifndef CONFIG_SH_R7785RP 128 static unsigned char heartbeat_bit_pos[] = { 2, 1, 0, 3, 6, 5, 4, 7 }; 129 130 static struct heartbeat_data heartbeat_data = { 131 .bit_pos = heartbeat_bit_pos, 132 .nr_bits = ARRAY_SIZE(heartbeat_bit_pos), 133 }; 134 #endif 135 136 static struct platform_device heartbeat_device = { 137 .name = "heartbeat", 138 .id = -1, 139 140 /* R7785RP has a slightly more sensible FPGA.. */ 141 #ifndef CONFIG_SH_R7785RP 142 .dev = { 143 .platform_data = &heartbeat_data, 144 }, 145 #endif 146 .num_resources = ARRAY_SIZE(heartbeat_resources), 147 .resource = heartbeat_resources, 148 }; 149 150 static struct ax_plat_data ax88796_platdata = { 151 .flags = AXFLG_HAS_93CX6, 152 .wordlength = 2, 153 .dcr_val = 0x1, 154 .rcr_val = 0x40, 155 }; 156 157 static struct resource ax88796_resources[] = { 158 { 159 #ifdef CONFIG_SH_R7780RP 160 .start = 0xa5800400, 161 .end = 0xa5800400 + (0x20 * 0x2) - 1, 162 #else 163 .start = 0xa4100400, 164 .end = 0xa4100400 + (0x20 * 0x2) - 1, 165 #endif 166 .flags = IORESOURCE_MEM, 167 }, 168 { 169 .start = IRQ_AX88796, 170 .end = IRQ_AX88796, 171 .flags = IORESOURCE_IRQ, 172 }, 173 }; 174 175 static struct platform_device ax88796_device = { 176 .name = "ax88796", 177 .id = 0, 178 179 .dev = { 180 .platform_data = &ax88796_platdata, 181 }, 182 183 .num_resources = ARRAY_SIZE(ax88796_resources), 184 .resource = ax88796_resources, 185 }; 186 187 static struct resource smbus_resources[] = { 188 [0] = { 189 .start = PA_SMCR, 190 .end = PA_SMCR + 0x100 - 1, 191 .flags = IORESOURCE_MEM, 192 }, 193 [1] = { 194 .start = IRQ_SMBUS, 195 .end = IRQ_SMBUS, 196 .flags = IORESOURCE_IRQ, 197 }, 198 }; 199 200 static struct platform_device smbus_device = { 201 .name = "i2c-highlander", 202 .id = 0, 203 .num_resources = ARRAY_SIZE(smbus_resources), 204 .resource = smbus_resources, 205 }; 206 207 static struct i2c_board_info __initdata highlander_i2c_devices[] = { 208 { 209 I2C_BOARD_INFO("r2025sd", 0x32), 210 }, 211 }; 212 213 static struct platform_device *r7780rp_devices[] __initdata = { 214 &r8a66597_usb_host_device, 215 &m66592_usb_peripheral_device, 216 &heartbeat_device, 217 &smbus_device, 218 #ifndef CONFIG_SH_R7780RP 219 &ax88796_device, 220 #endif 221 }; 222 223 /* 224 * The CF is connected using a 16-bit bus where 8-bit operations are 225 * unsupported. The linux ata driver is however using 8-bit operations, so 226 * insert a trapped io filter to convert 8-bit operations into 16-bit. 227 */ 228 static struct trapped_io cf_trapped_io = { 229 .resource = cf_ide_resources, 230 .num_resources = 2, 231 .minimum_bus_width = 16, 232 }; 233 234 static int __init r7780rp_devices_setup(void) 235 { 236 int ret = 0; 237 238 #ifndef CONFIG_SH_R7780RP 239 if (register_trapped_io(&cf_trapped_io) == 0) 240 ret |= platform_device_register(&cf_ide_device); 241 #endif 242 243 ret |= platform_add_devices(r7780rp_devices, 244 ARRAY_SIZE(r7780rp_devices)); 245 246 ret |= i2c_register_board_info(0, highlander_i2c_devices, 247 ARRAY_SIZE(highlander_i2c_devices)); 248 249 return ret; 250 } 251 device_initcall(r7780rp_devices_setup); 252 253 /* 254 * Platform specific clocks 255 */ 256 static void ivdr_clk_enable(struct clk *clk) 257 { 258 ctrl_outw(ctrl_inw(PA_IVDRCTL) | (1 << IVDR_CK_ON), PA_IVDRCTL); 259 } 260 261 static void ivdr_clk_disable(struct clk *clk) 262 { 263 ctrl_outw(ctrl_inw(PA_IVDRCTL) & ~(1 << IVDR_CK_ON), PA_IVDRCTL); 264 } 265 266 static struct clk_ops ivdr_clk_ops = { 267 .enable = ivdr_clk_enable, 268 .disable = ivdr_clk_disable, 269 }; 270 271 static struct clk ivdr_clk = { 272 .name = "ivdr_clk", 273 .ops = &ivdr_clk_ops, 274 }; 275 276 static struct clk *r7780rp_clocks[] = { 277 &ivdr_clk, 278 }; 279 280 static void r7780rp_power_off(void) 281 { 282 if (mach_is_r7780mp() || mach_is_r7785rp()) 283 ctrl_outw(0x0001, PA_POFF); 284 } 285 286 /* 287 * Initialize the board 288 */ 289 static void __init highlander_setup(char **cmdline_p) 290 { 291 u16 ver = ctrl_inw(PA_VERREG); 292 int i; 293 294 printk(KERN_INFO "Renesas Solutions Highlander %s support.\n", 295 mach_is_r7780rp() ? "R7780RP-1" : 296 mach_is_r7780mp() ? "R7780MP" : 297 "R7785RP"); 298 299 printk(KERN_INFO "Board version: %d (revision %d), " 300 "FPGA version: %d (revision %d)\n", 301 (ver >> 12) & 0xf, (ver >> 8) & 0xf, 302 (ver >> 4) & 0xf, ver & 0xf); 303 304 highlander_plat_pinmux_setup(); 305 306 /* 307 * Enable the important clocks right away.. 308 */ 309 for (i = 0; i < ARRAY_SIZE(r7780rp_clocks); i++) { 310 struct clk *clk = r7780rp_clocks[i]; 311 312 clk_register(clk); 313 clk_enable(clk); 314 } 315 316 ctrl_outw(0x0000, PA_OBLED); /* Clear LED. */ 317 318 if (mach_is_r7780rp()) 319 ctrl_outw(0x0001, PA_SDPOW); /* SD Power ON */ 320 321 ctrl_outw(ctrl_inw(PA_IVDRCTL) | 0x01, PA_IVDRCTL); /* Si13112 */ 322 323 pm_power_off = r7780rp_power_off; 324 } 325 326 static unsigned char irl2irq[HL_NR_IRL]; 327 328 static int highlander_irq_demux(int irq) 329 { 330 if (irq >= HL_NR_IRL || !irl2irq[irq]) 331 return irq; 332 333 return irl2irq[irq]; 334 } 335 336 static void __init highlander_init_irq(void) 337 { 338 unsigned char *ucp = highlander_plat_irq_setup(); 339 340 if (ucp) { 341 plat_irq_setup_pins(IRQ_MODE_IRL3210); 342 memcpy(irl2irq, ucp, HL_NR_IRL); 343 } 344 } 345 346 /* 347 * The Machine Vector 348 */ 349 static struct sh_machine_vector mv_highlander __initmv = { 350 .mv_name = "Highlander", 351 .mv_setup = highlander_setup, 352 .mv_init_irq = highlander_init_irq, 353 .mv_irq_demux = highlander_irq_demux, 354 }; 355