1 /* 2 * Renesas Technology Corp. R0P7785LC0011RL Support. 3 * 4 * Copyright (C) 2008 Yoshihiro Shimoda 5 * 6 * This file is subject to the terms and conditions of the GNU General Public 7 * License. See the file "COPYING" in the main directory of this archive 8 * for more details. 9 */ 10 11 #include <linux/init.h> 12 #include <linux/platform_device.h> 13 #include <linux/sm501.h> 14 #include <linux/sm501-regs.h> 15 #include <linux/fb.h> 16 #include <linux/mtd/physmap.h> 17 #include <linux/delay.h> 18 #include <linux/i2c.h> 19 #include <linux/i2c-pca-platform.h> 20 #include <linux/i2c-algo-pca.h> 21 #include <linux/irq.h> 22 #include <asm/heartbeat.h> 23 #include <mach/sh7785lcr.h> 24 25 /* 26 * NOTE: This board has 2 physical memory maps. 27 * Please look at include/asm-sh/sh7785lcr.h or hardware manual. 28 */ 29 static struct resource heartbeat_resources[] = { 30 [0] = { 31 .start = PLD_LEDCR, 32 .end = PLD_LEDCR, 33 .flags = IORESOURCE_MEM, 34 }, 35 }; 36 37 static struct heartbeat_data heartbeat_data = { 38 .regsize = 8, 39 }; 40 41 static struct platform_device heartbeat_device = { 42 .name = "heartbeat", 43 .id = -1, 44 .dev = { 45 .platform_data = &heartbeat_data, 46 }, 47 .num_resources = ARRAY_SIZE(heartbeat_resources), 48 .resource = heartbeat_resources, 49 }; 50 51 static struct mtd_partition nor_flash_partitions[] = { 52 { 53 .name = "loader", 54 .offset = 0x00000000, 55 .size = 512 * 1024, 56 }, 57 { 58 .name = "bootenv", 59 .offset = MTDPART_OFS_APPEND, 60 .size = 512 * 1024, 61 }, 62 { 63 .name = "kernel", 64 .offset = MTDPART_OFS_APPEND, 65 .size = 4 * 1024 * 1024, 66 }, 67 { 68 .name = "data", 69 .offset = MTDPART_OFS_APPEND, 70 .size = MTDPART_SIZ_FULL, 71 }, 72 }; 73 74 static struct physmap_flash_data nor_flash_data = { 75 .width = 4, 76 .parts = nor_flash_partitions, 77 .nr_parts = ARRAY_SIZE(nor_flash_partitions), 78 }; 79 80 static struct resource nor_flash_resources[] = { 81 [0] = { 82 .start = NOR_FLASH_ADDR, 83 .end = NOR_FLASH_ADDR + NOR_FLASH_SIZE - 1, 84 .flags = IORESOURCE_MEM, 85 } 86 }; 87 88 static struct platform_device nor_flash_device = { 89 .name = "physmap-flash", 90 .dev = { 91 .platform_data = &nor_flash_data, 92 }, 93 .num_resources = ARRAY_SIZE(nor_flash_resources), 94 .resource = nor_flash_resources, 95 }; 96 97 static struct resource r8a66597_usb_host_resources[] = { 98 [0] = { 99 .name = "r8a66597_hcd", 100 .start = R8A66597_ADDR, 101 .end = R8A66597_ADDR + R8A66597_SIZE - 1, 102 .flags = IORESOURCE_MEM, 103 }, 104 [1] = { 105 .name = "r8a66597_hcd", 106 .start = 2, 107 .end = 2, 108 .flags = IORESOURCE_IRQ, 109 }, 110 }; 111 112 static struct platform_device r8a66597_usb_host_device = { 113 .name = "r8a66597_hcd", 114 .id = -1, 115 .dev = { 116 .dma_mask = NULL, 117 .coherent_dma_mask = 0xffffffff, 118 }, 119 .num_resources = ARRAY_SIZE(r8a66597_usb_host_resources), 120 .resource = r8a66597_usb_host_resources, 121 }; 122 123 static struct resource sm501_resources[] = { 124 [0] = { 125 .start = SM107_MEM_ADDR, 126 .end = SM107_MEM_ADDR + SM107_MEM_SIZE - 1, 127 .flags = IORESOURCE_MEM, 128 }, 129 [1] = { 130 .start = SM107_REG_ADDR, 131 .end = SM107_REG_ADDR + SM107_REG_SIZE - 1, 132 .flags = IORESOURCE_MEM, 133 }, 134 [2] = { 135 .start = 10, 136 .flags = IORESOURCE_IRQ, 137 }, 138 }; 139 140 static struct fb_videomode sm501_default_mode_crt = { 141 .pixclock = 35714, /* 28MHz */ 142 .xres = 640, 143 .yres = 480, 144 .left_margin = 105, 145 .right_margin = 16, 146 .upper_margin = 33, 147 .lower_margin = 10, 148 .hsync_len = 39, 149 .vsync_len = 2, 150 .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, 151 }; 152 153 static struct fb_videomode sm501_default_mode_pnl = { 154 .pixclock = 40000, /* 25MHz */ 155 .xres = 640, 156 .yres = 480, 157 .left_margin = 2, 158 .right_margin = 16, 159 .upper_margin = 33, 160 .lower_margin = 10, 161 .hsync_len = 39, 162 .vsync_len = 2, 163 .sync = 0, 164 }; 165 166 static struct sm501_platdata_fbsub sm501_pdata_fbsub_pnl = { 167 .def_bpp = 16, 168 .def_mode = &sm501_default_mode_pnl, 169 .flags = SM501FB_FLAG_USE_INIT_MODE | 170 SM501FB_FLAG_USE_HWCURSOR | 171 SM501FB_FLAG_USE_HWACCEL | 172 SM501FB_FLAG_DISABLE_AT_EXIT | 173 SM501FB_FLAG_PANEL_NO_VBIASEN, 174 }; 175 176 static struct sm501_platdata_fbsub sm501_pdata_fbsub_crt = { 177 .def_bpp = 16, 178 .def_mode = &sm501_default_mode_crt, 179 .flags = SM501FB_FLAG_USE_INIT_MODE | 180 SM501FB_FLAG_USE_HWCURSOR | 181 SM501FB_FLAG_USE_HWACCEL | 182 SM501FB_FLAG_DISABLE_AT_EXIT, 183 }; 184 185 static struct sm501_platdata_fb sm501_fb_pdata = { 186 .fb_route = SM501_FB_OWN, 187 .fb_crt = &sm501_pdata_fbsub_crt, 188 .fb_pnl = &sm501_pdata_fbsub_pnl, 189 }; 190 191 static struct sm501_initdata sm501_initdata = { 192 .gpio_high = { 193 .set = 0x00001fe0, 194 .mask = 0x0, 195 }, 196 .devices = 0, 197 .mclk = 84 * 1000000, 198 .m1xclk = 112 * 1000000, 199 }; 200 201 static struct sm501_platdata sm501_platform_data = { 202 .init = &sm501_initdata, 203 .fb = &sm501_fb_pdata, 204 }; 205 206 static struct platform_device sm501_device = { 207 .name = "sm501", 208 .id = -1, 209 .dev = { 210 .platform_data = &sm501_platform_data, 211 }, 212 .num_resources = ARRAY_SIZE(sm501_resources), 213 .resource = sm501_resources, 214 }; 215 216 static struct resource i2c_resources[] = { 217 [0] = { 218 .start = PCA9564_ADDR, 219 .end = PCA9564_ADDR + PCA9564_SIZE - 1, 220 .flags = IORESOURCE_MEM | IORESOURCE_MEM_8BIT, 221 }, 222 [1] = { 223 .start = 12, 224 .end = 12, 225 .flags = IORESOURCE_IRQ, 226 }, 227 }; 228 229 static struct i2c_pca9564_pf_platform_data i2c_platform_data = { 230 .gpio = 0, 231 .i2c_clock_speed = I2C_PCA_CON_330kHz, 232 .timeout = HZ, 233 }; 234 235 static struct platform_device i2c_device = { 236 .name = "i2c-pca-platform", 237 .id = -1, 238 .dev = { 239 .platform_data = &i2c_platform_data, 240 }, 241 .num_resources = ARRAY_SIZE(i2c_resources), 242 .resource = i2c_resources, 243 }; 244 245 static struct platform_device *sh7785lcr_devices[] __initdata = { 246 &heartbeat_device, 247 &nor_flash_device, 248 &r8a66597_usb_host_device, 249 &sm501_device, 250 &i2c_device, 251 }; 252 253 static struct i2c_board_info __initdata sh7785lcr_i2c_devices[] = { 254 { 255 I2C_BOARD_INFO("r2025sd", 0x32), 256 }, 257 }; 258 259 static int __init sh7785lcr_devices_setup(void) 260 { 261 i2c_register_board_info(0, sh7785lcr_i2c_devices, 262 ARRAY_SIZE(sh7785lcr_i2c_devices)); 263 264 return platform_add_devices(sh7785lcr_devices, 265 ARRAY_SIZE(sh7785lcr_devices)); 266 } 267 __initcall(sh7785lcr_devices_setup); 268 269 /* Initialize IRQ setting */ 270 void __init init_sh7785lcr_IRQ(void) 271 { 272 plat_irq_setup_pins(IRQ_MODE_IRQ7654); 273 plat_irq_setup_pins(IRQ_MODE_IRQ3210); 274 } 275 276 static void sh7785lcr_power_off(void) 277 { 278 unsigned char *p; 279 280 p = ioremap(PLD_POFCR, PLD_POFCR + 1); 281 if (!p) { 282 printk(KERN_ERR "%s: ioremap error.\n", __func__); 283 return; 284 } 285 *p = 0x01; 286 iounmap(p); 287 set_bl_bit(); 288 while (1) 289 cpu_relax(); 290 } 291 292 /* Initialize the board */ 293 static void __init sh7785lcr_setup(char **cmdline_p) 294 { 295 void __iomem *sm501_reg; 296 297 printk(KERN_INFO "Renesas Technology Corp. R0P7785LC0011RL support.\n"); 298 299 pm_power_off = sh7785lcr_power_off; 300 301 /* sm501 DRAM configuration */ 302 sm501_reg = (void __iomem *)0xb3e00000 + SM501_DRAM_CONTROL; 303 writel(0x000307c2, sm501_reg); 304 } 305 306 /* 307 * The Machine Vector 308 */ 309 static struct sh_machine_vector mv_sh7785lcr __initmv = { 310 .mv_name = "SH7785LCR", 311 .mv_setup = sh7785lcr_setup, 312 .mv_init_irq = init_sh7785lcr_IRQ, 313 }; 314 315