1/* 2 * G4EVM board support 3 * 4 * Copyright (C) 2010 Magnus Damm 5 * Copyright (C) 2008 Yoshihiro Shimoda 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/kernel.h> 21#include <linux/init.h> 22#include <linux/interrupt.h> 23#include <linux/irq.h> 24#include <linux/platform_device.h> 25#include <linux/delay.h> 26#include <linux/mtd/mtd.h> 27#include <linux/mtd/partitions.h> 28#include <linux/mtd/physmap.h> 29#include <linux/usb/r8a66597.h> 30#include <linux/io.h> 31#include <linux/input.h> 32#include <linux/input/sh_keysc.h> 33#include <linux/mmc/host.h> 34#include <linux/mmc/sh_mobile_sdhi.h> 35#include <linux/gpio.h> 36#include <linux/dma-mapping.h> 37#include <mach/irqs.h> 38#include <mach/sh7377.h> 39#include <mach/common.h> 40#include <asm/mach-types.h> 41#include <asm/mach/arch.h> 42 43/* 44 * SDHI 45 * 46 * SDHI0 : card detection is possible 47 * SDHI1 : card detection is impossible 48 * 49 * [G4-MAIN-BOARD] 50 * JP74 : short # DBG_2V8A for SDHI0 51 * JP75 : NC # DBG_3V3A for SDHI0 52 * JP76 : NC # DBG_3V3A_SD for SDHI0 53 * JP77 : NC # 3V3A_SDIO for SDHI1 54 * JP78 : short # DBG_2V8A for SDHI1 55 * JP79 : NC # DBG_3V3A for SDHI1 56 * JP80 : NC # DBG_3V3A_SD for SDHI1 57 * 58 * [G4-CORE-BOARD] 59 * S32 : all off # to dissever from G3-CORE_DBG board 60 * S33 : all off # to dissever from G3-CORE_DBG board 61 * 62 * [G3-CORE_DBG-BOARD] 63 * S1 : all off # to dissever from G3-CORE_DBG board 64 * S3 : all off # to dissever from G3-CORE_DBG board 65 * S4 : all off # to dissever from G3-CORE_DBG board 66 */ 67 68static struct mtd_partition nor_flash_partitions[] = { 69 { 70 .name = "loader", 71 .offset = 0x00000000, 72 .size = 512 * 1024, 73 }, 74 { 75 .name = "bootenv", 76 .offset = MTDPART_OFS_APPEND, 77 .size = 512 * 1024, 78 }, 79 { 80 .name = "kernel_ro", 81 .offset = MTDPART_OFS_APPEND, 82 .size = 8 * 1024 * 1024, 83 .mask_flags = MTD_WRITEABLE, 84 }, 85 { 86 .name = "kernel", 87 .offset = MTDPART_OFS_APPEND, 88 .size = 8 * 1024 * 1024, 89 }, 90 { 91 .name = "data", 92 .offset = MTDPART_OFS_APPEND, 93 .size = MTDPART_SIZ_FULL, 94 }, 95}; 96 97static struct physmap_flash_data nor_flash_data = { 98 .width = 2, 99 .parts = nor_flash_partitions, 100 .nr_parts = ARRAY_SIZE(nor_flash_partitions), 101}; 102 103static struct resource nor_flash_resources[] = { 104 [0] = { 105 .start = 0x00000000, 106 .end = 0x08000000 - 1, 107 .flags = IORESOURCE_MEM, 108 } 109}; 110 111static struct platform_device nor_flash_device = { 112 .name = "physmap-flash", 113 .dev = { 114 .platform_data = &nor_flash_data, 115 }, 116 .num_resources = ARRAY_SIZE(nor_flash_resources), 117 .resource = nor_flash_resources, 118}; 119 120/* USBHS */ 121static void usb_host_port_power(int port, int power) 122{ 123 if (!power) /* only power-on supported for now */ 124 return; 125 126 /* set VBOUT/PWEN and EXTLP0 in DVSTCTR */ 127 __raw_writew(__raw_readw(0xe6890008) | 0x600, 0xe6890008); 128} 129 130static struct r8a66597_platdata usb_host_data = { 131 .on_chip = 1, 132 .port_power = usb_host_port_power, 133}; 134 135static struct resource usb_host_resources[] = { 136 [0] = { 137 .name = "USBHS", 138 .start = 0xe6890000, 139 .end = 0xe68900e5, 140 .flags = IORESOURCE_MEM, 141 }, 142 [1] = { 143 .start = evt2irq(0x0a20), /* USBHS_USHI0 */ 144 .flags = IORESOURCE_IRQ, 145 }, 146}; 147 148static struct platform_device usb_host_device = { 149 .name = "r8a66597_hcd", 150 .id = 0, 151 .dev = { 152 .platform_data = &usb_host_data, 153 .dma_mask = NULL, 154 .coherent_dma_mask = 0xffffffff, 155 }, 156 .num_resources = ARRAY_SIZE(usb_host_resources), 157 .resource = usb_host_resources, 158}; 159 160/* KEYSC */ 161static struct sh_keysc_info keysc_info = { 162 .mode = SH_KEYSC_MODE_5, 163 .scan_timing = 3, 164 .delay = 100, 165 .keycodes = { 166 KEY_A, KEY_B, KEY_C, KEY_D, KEY_E, KEY_F, 167 KEY_G, KEY_H, KEY_I, KEY_J, KEY_K, KEY_L, 168 KEY_M, KEY_N, KEY_U, KEY_P, KEY_Q, KEY_R, 169 KEY_S, KEY_T, KEY_U, KEY_V, KEY_W, KEY_X, 170 KEY_Y, KEY_Z, KEY_HOME, KEY_SLEEP, KEY_WAKEUP, KEY_COFFEE, 171 KEY_0, KEY_1, KEY_2, KEY_3, KEY_4, KEY_5, 172 KEY_6, KEY_7, KEY_8, KEY_9, KEY_STOP, KEY_COMPUTER, 173 }, 174}; 175 176static struct resource keysc_resources[] = { 177 [0] = { 178 .name = "KEYSC", 179 .start = 0xe61b0000, 180 .end = 0xe61b000f, 181 .flags = IORESOURCE_MEM, 182 }, 183 [1] = { 184 .start = evt2irq(0x0be0), /* KEYSC_KEY */ 185 .flags = IORESOURCE_IRQ, 186 }, 187}; 188 189static struct platform_device keysc_device = { 190 .name = "sh_keysc", 191 .id = 0, /* keysc0 clock */ 192 .num_resources = ARRAY_SIZE(keysc_resources), 193 .resource = keysc_resources, 194 .dev = { 195 .platform_data = &keysc_info, 196 }, 197}; 198 199/* SDHI */ 200static struct sh_mobile_sdhi_info sdhi0_info = { 201 .tmio_caps = MMC_CAP_SDIO_IRQ, 202}; 203 204static struct resource sdhi0_resources[] = { 205 [0] = { 206 .name = "SDHI0", 207 .start = 0xe6d50000, 208 .end = 0xe6d500ff, 209 .flags = IORESOURCE_MEM, 210 }, 211 [1] = { 212 .start = evt2irq(0x0e00), /* SDHI0 */ 213 .flags = IORESOURCE_IRQ, 214 }, 215}; 216 217static struct platform_device sdhi0_device = { 218 .name = "sh_mobile_sdhi", 219 .num_resources = ARRAY_SIZE(sdhi0_resources), 220 .resource = sdhi0_resources, 221 .id = 0, 222 .dev = { 223 .platform_data = &sdhi0_info, 224 }, 225}; 226 227static struct sh_mobile_sdhi_info sdhi1_info = { 228 .tmio_caps = MMC_CAP_NONREMOVABLE | MMC_CAP_SDIO_IRQ, 229}; 230 231static struct resource sdhi1_resources[] = { 232 [0] = { 233 .name = "SDHI1", 234 .start = 0xe6d60000, 235 .end = 0xe6d600ff, 236 .flags = IORESOURCE_MEM, 237 }, 238 [1] = { 239 .start = evt2irq(0x0e80), /* SDHI1 */ 240 .flags = IORESOURCE_IRQ, 241 }, 242}; 243 244static struct platform_device sdhi1_device = { 245 .name = "sh_mobile_sdhi", 246 .num_resources = ARRAY_SIZE(sdhi1_resources), 247 .resource = sdhi1_resources, 248 .id = 1, 249 .dev = { 250 .platform_data = &sdhi1_info, 251 }, 252}; 253 254static struct platform_device *g4evm_devices[] __initdata = { 255 &nor_flash_device, 256 &usb_host_device, 257 &keysc_device, 258 &sdhi0_device, 259 &sdhi1_device, 260}; 261 262#define GPIO_SDHID0_D0 0xe60520fc 263#define GPIO_SDHID0_D1 0xe60520fd 264#define GPIO_SDHID0_D2 0xe60520fe 265#define GPIO_SDHID0_D3 0xe60520ff 266#define GPIO_SDHICMD0 0xe6052100 267 268#define GPIO_SDHID1_D0 0xe6052103 269#define GPIO_SDHID1_D1 0xe6052104 270#define GPIO_SDHID1_D2 0xe6052105 271#define GPIO_SDHID1_D3 0xe6052106 272#define GPIO_SDHICMD1 0xe6052107 273 274/* 275 * FIXME !! 276 * 277 * gpio_pull_up is quick_hack. 278 * 279 * current gpio frame work doesn't have 280 * the method to control only pull up/down/free. 281 * this function should be replaced by correct gpio function 282 */ 283static void __init gpio_pull_up(u32 addr) 284{ 285 u8 data = __raw_readb(addr); 286 287 data &= 0x0F; 288 data |= 0xC0; 289 __raw_writeb(data, addr); 290} 291 292static void __init g4evm_init(void) 293{ 294 sh7377_pinmux_init(); 295 296 /* Lit DS14 LED */ 297 gpio_request(GPIO_PORT109, NULL); 298 gpio_direction_output(GPIO_PORT109, 1); 299 gpio_export(GPIO_PORT109, 1); 300 301 /* Lit DS15 LED */ 302 gpio_request(GPIO_PORT110, NULL); 303 gpio_direction_output(GPIO_PORT110, 1); 304 gpio_export(GPIO_PORT110, 1); 305 306 /* Lit DS16 LED */ 307 gpio_request(GPIO_PORT112, NULL); 308 gpio_direction_output(GPIO_PORT112, 1); 309 gpio_export(GPIO_PORT112, 1); 310 311 /* Lit DS17 LED */ 312 gpio_request(GPIO_PORT113, NULL); 313 gpio_direction_output(GPIO_PORT113, 1); 314 gpio_export(GPIO_PORT113, 1); 315 316 /* USBHS */ 317 gpio_request(GPIO_FN_VBUS_0, NULL); 318 gpio_request(GPIO_FN_PWEN, NULL); 319 gpio_request(GPIO_FN_OVCN, NULL); 320 gpio_request(GPIO_FN_OVCN2, NULL); 321 gpio_request(GPIO_FN_EXTLP, NULL); 322 gpio_request(GPIO_FN_IDIN, NULL); 323 324 /* setup USB phy */ 325 __raw_writew(0x0200, 0xe605810a); /* USBCR1 */ 326 __raw_writew(0x00e0, 0xe60581c0); /* CPFCH */ 327 __raw_writew(0x6010, 0xe60581c6); /* CGPOSR */ 328 __raw_writew(0x8a0a, 0xe605810c); /* USBCR2 */ 329 330 /* KEYSC @ CN31 */ 331 gpio_request(GPIO_FN_PORT60_KEYOUT5, NULL); 332 gpio_request(GPIO_FN_PORT61_KEYOUT4, NULL); 333 gpio_request(GPIO_FN_PORT62_KEYOUT3, NULL); 334 gpio_request(GPIO_FN_PORT63_KEYOUT2, NULL); 335 gpio_request(GPIO_FN_PORT64_KEYOUT1, NULL); 336 gpio_request(GPIO_FN_PORT65_KEYOUT0, NULL); 337 gpio_request(GPIO_FN_PORT66_KEYIN0_PU, NULL); 338 gpio_request(GPIO_FN_PORT67_KEYIN1_PU, NULL); 339 gpio_request(GPIO_FN_PORT68_KEYIN2_PU, NULL); 340 gpio_request(GPIO_FN_PORT69_KEYIN3_PU, NULL); 341 gpio_request(GPIO_FN_PORT70_KEYIN4_PU, NULL); 342 gpio_request(GPIO_FN_PORT71_KEYIN5_PU, NULL); 343 gpio_request(GPIO_FN_PORT72_KEYIN6_PU, NULL); 344 345 /* SDHI0 */ 346 gpio_request(GPIO_FN_SDHICLK0, NULL); 347 gpio_request(GPIO_FN_SDHICD0, NULL); 348 gpio_request(GPIO_FN_SDHID0_0, NULL); 349 gpio_request(GPIO_FN_SDHID0_1, NULL); 350 gpio_request(GPIO_FN_SDHID0_2, NULL); 351 gpio_request(GPIO_FN_SDHID0_3, NULL); 352 gpio_request(GPIO_FN_SDHICMD0, NULL); 353 gpio_request(GPIO_FN_SDHIWP0, NULL); 354 gpio_pull_up(GPIO_SDHID0_D0); 355 gpio_pull_up(GPIO_SDHID0_D1); 356 gpio_pull_up(GPIO_SDHID0_D2); 357 gpio_pull_up(GPIO_SDHID0_D3); 358 gpio_pull_up(GPIO_SDHICMD0); 359 360 /* SDHI1 */ 361 gpio_request(GPIO_FN_SDHICLK1, NULL); 362 gpio_request(GPIO_FN_SDHID1_0, NULL); 363 gpio_request(GPIO_FN_SDHID1_1, NULL); 364 gpio_request(GPIO_FN_SDHID1_2, NULL); 365 gpio_request(GPIO_FN_SDHID1_3, NULL); 366 gpio_request(GPIO_FN_SDHICMD1, NULL); 367 gpio_pull_up(GPIO_SDHID1_D0); 368 gpio_pull_up(GPIO_SDHID1_D1); 369 gpio_pull_up(GPIO_SDHID1_D2); 370 gpio_pull_up(GPIO_SDHID1_D3); 371 gpio_pull_up(GPIO_SDHICMD1); 372 373 sh7377_add_standard_devices(); 374 375 platform_add_devices(g4evm_devices, ARRAY_SIZE(g4evm_devices)); 376} 377 378MACHINE_START(G4EVM, "g4evm") 379 .map_io = sh7377_map_io, 380 .init_early = sh7377_add_early_devices, 381 .init_irq = sh7377_init_irq, 382 .handle_irq = shmobile_handle_irq_intc, 383 .init_machine = g4evm_init, 384 .timer = &shmobile_timer, 385MACHINE_END 386