mach-vr1000.c (8803B)
1// SPDX-License-Identifier: GPL-2.0 2// 3// Copyright (c) 2003-2008 Simtec Electronics 4// Ben Dooks <ben@simtec.co.uk> 5// 6// Machine support for Thorcom VR1000 board. Designed for Thorcom by 7// Simtec Electronics, http://www.simtec.co.uk/ 8 9#include <linux/kernel.h> 10#include <linux/types.h> 11#include <linux/interrupt.h> 12#include <linux/list.h> 13#include <linux/timer.h> 14#include <linux/init.h> 15#include <linux/gpio.h> 16#include <linux/gpio/machine.h> 17#include <linux/dm9000.h> 18#include <linux/i2c.h> 19 20#include <linux/serial.h> 21#include <linux/tty.h> 22#include <linux/serial_8250.h> 23#include <linux/serial_reg.h> 24#include <linux/serial_s3c.h> 25#include <linux/io.h> 26 27#include <asm/mach/arch.h> 28#include <asm/mach/map.h> 29#include <asm/mach/irq.h> 30 31#include <asm/irq.h> 32#include <asm/mach-types.h> 33 34#include <linux/platform_data/leds-s3c24xx.h> 35#include <linux/platform_data/i2c-s3c2410.h> 36#include <linux/platform_data/asoc-s3c24xx_simtec.h> 37 38#include "regs-gpio.h" 39#include "gpio-samsung.h" 40#include "gpio-cfg.h" 41 42#include "cpu.h" 43#include "devs.h" 44 45#include "bast.h" 46#include "s3c24xx.h" 47#include "simtec.h" 48#include "vr1000.h" 49 50/* macros for virtual address mods for the io space entries */ 51#define VA_C5(item) ((unsigned long)(item) + BAST_VAM_CS5) 52#define VA_C4(item) ((unsigned long)(item) + BAST_VAM_CS4) 53#define VA_C3(item) ((unsigned long)(item) + BAST_VAM_CS3) 54#define VA_C2(item) ((unsigned long)(item) + BAST_VAM_CS2) 55 56/* macros to modify the physical addresses for io space */ 57 58#define PA_CS2(item) (__phys_to_pfn((item) + S3C2410_CS2)) 59#define PA_CS3(item) (__phys_to_pfn((item) + S3C2410_CS3)) 60#define PA_CS4(item) (__phys_to_pfn((item) + S3C2410_CS4)) 61#define PA_CS5(item) (__phys_to_pfn((item) + S3C2410_CS5)) 62 63static struct map_desc vr1000_iodesc[] __initdata = { 64 /* ISA IO areas */ 65 { 66 .virtual = (u32)S3C24XX_VA_ISA_BYTE, 67 .pfn = PA_CS2(BAST_PA_ISAIO), 68 .length = SZ_16M, 69 .type = MT_DEVICE, 70 }, 71 72 /* CPLD control registers, and external interrupt controls */ 73 { 74 .virtual = (u32)VR1000_VA_CTRL1, 75 .pfn = __phys_to_pfn(VR1000_PA_CTRL1), 76 .length = SZ_1M, 77 .type = MT_DEVICE, 78 }, { 79 .virtual = (u32)VR1000_VA_CTRL2, 80 .pfn = __phys_to_pfn(VR1000_PA_CTRL2), 81 .length = SZ_1M, 82 .type = MT_DEVICE, 83 }, { 84 .virtual = (u32)VR1000_VA_CTRL3, 85 .pfn = __phys_to_pfn(VR1000_PA_CTRL3), 86 .length = SZ_1M, 87 .type = MT_DEVICE, 88 }, { 89 .virtual = (u32)VR1000_VA_CTRL4, 90 .pfn = __phys_to_pfn(VR1000_PA_CTRL4), 91 .length = SZ_1M, 92 .type = MT_DEVICE, 93 }, 94}; 95 96#define UCON S3C2410_UCON_DEFAULT | S3C2410_UCON_UCLK 97#define ULCON S3C2410_LCON_CS8 | S3C2410_LCON_PNONE | S3C2410_LCON_STOPB 98#define UFCON S3C2410_UFCON_RXTRIG8 | S3C2410_UFCON_FIFOMODE 99 100static struct s3c2410_uartcfg vr1000_uartcfgs[] __initdata = { 101 [0] = { 102 .hwport = 0, 103 .flags = 0, 104 .ucon = UCON, 105 .ulcon = ULCON, 106 .ufcon = UFCON, 107 }, 108 [1] = { 109 .hwport = 1, 110 .flags = 0, 111 .ucon = UCON, 112 .ulcon = ULCON, 113 .ufcon = UFCON, 114 }, 115 /* port 2 is not actually used */ 116 [2] = { 117 .hwport = 2, 118 .flags = 0, 119 .ucon = UCON, 120 .ulcon = ULCON, 121 .ufcon = UFCON, 122 } 123}; 124 125/* definitions for the vr1000 extra 16550 serial ports */ 126 127#define VR1000_BAUDBASE (3692307) 128 129#define VR1000_SERIAL_MAPBASE(x) (VR1000_PA_SERIAL + 0x80 + ((x) << 5)) 130 131static struct plat_serial8250_port serial_platform_data[] = { 132 [0] = { 133 .mapbase = VR1000_SERIAL_MAPBASE(0), 134 .irq = VR1000_IRQ_SERIAL + 0, 135 .flags = UPF_BOOT_AUTOCONF | UPF_IOREMAP, 136 .iotype = UPIO_MEM, 137 .regshift = 0, 138 .uartclk = VR1000_BAUDBASE, 139 }, 140 [1] = { 141 .mapbase = VR1000_SERIAL_MAPBASE(1), 142 .irq = VR1000_IRQ_SERIAL + 1, 143 .flags = UPF_BOOT_AUTOCONF | UPF_IOREMAP, 144 .iotype = UPIO_MEM, 145 .regshift = 0, 146 .uartclk = VR1000_BAUDBASE, 147 }, 148 [2] = { 149 .mapbase = VR1000_SERIAL_MAPBASE(2), 150 .irq = VR1000_IRQ_SERIAL + 2, 151 .flags = UPF_BOOT_AUTOCONF | UPF_IOREMAP, 152 .iotype = UPIO_MEM, 153 .regshift = 0, 154 .uartclk = VR1000_BAUDBASE, 155 }, 156 [3] = { 157 .mapbase = VR1000_SERIAL_MAPBASE(3), 158 .irq = VR1000_IRQ_SERIAL + 3, 159 .flags = UPF_BOOT_AUTOCONF | UPF_IOREMAP, 160 .iotype = UPIO_MEM, 161 .regshift = 0, 162 .uartclk = VR1000_BAUDBASE, 163 }, 164 { }, 165}; 166 167static struct platform_device serial_device = { 168 .name = "serial8250", 169 .id = PLAT8250_DEV_PLATFORM, 170 .dev = { 171 .platform_data = serial_platform_data, 172 }, 173}; 174 175/* DM9000 ethernet devices */ 176 177static struct resource vr1000_dm9k0_resource[] = { 178 [0] = DEFINE_RES_MEM(S3C2410_CS5 + VR1000_PA_DM9000, 4), 179 [1] = DEFINE_RES_MEM(S3C2410_CS5 + VR1000_PA_DM9000 + 0x40, 0x40), 180 [2] = DEFINE_RES_NAMED(VR1000_IRQ_DM9000A, 1, NULL, IORESOURCE_IRQ \ 181 | IORESOURCE_IRQ_HIGHLEVEL), 182}; 183 184static struct resource vr1000_dm9k1_resource[] = { 185 [0] = DEFINE_RES_MEM(S3C2410_CS5 + VR1000_PA_DM9000 + 0x80, 4), 186 [1] = DEFINE_RES_MEM(S3C2410_CS5 + VR1000_PA_DM9000 + 0xC0, 0x40), 187 [2] = DEFINE_RES_NAMED(VR1000_IRQ_DM9000N, 1, NULL, IORESOURCE_IRQ \ 188 | IORESOURCE_IRQ_HIGHLEVEL), 189}; 190 191/* for the moment we limit ourselves to 16bit IO until some 192 * better IO routines can be written and tested 193*/ 194 195static struct dm9000_plat_data vr1000_dm9k_platdata = { 196 .flags = DM9000_PLATF_16BITONLY, 197}; 198 199static struct platform_device vr1000_dm9k0 = { 200 .name = "dm9000", 201 .id = 0, 202 .num_resources = ARRAY_SIZE(vr1000_dm9k0_resource), 203 .resource = vr1000_dm9k0_resource, 204 .dev = { 205 .platform_data = &vr1000_dm9k_platdata, 206 } 207}; 208 209static struct platform_device vr1000_dm9k1 = { 210 .name = "dm9000", 211 .id = 1, 212 .num_resources = ARRAY_SIZE(vr1000_dm9k1_resource), 213 .resource = vr1000_dm9k1_resource, 214 .dev = { 215 .platform_data = &vr1000_dm9k_platdata, 216 } 217}; 218 219/* LEDS */ 220 221static struct gpiod_lookup_table vr1000_led1_gpio_table = { 222 .dev_id = "s3c24xx_led.1", 223 .table = { 224 GPIO_LOOKUP("GPB", 0, NULL, GPIO_ACTIVE_HIGH), 225 { }, 226 }, 227}; 228 229static struct gpiod_lookup_table vr1000_led2_gpio_table = { 230 .dev_id = "s3c24xx_led.2", 231 .table = { 232 GPIO_LOOKUP("GPB", 1, NULL, GPIO_ACTIVE_HIGH), 233 { }, 234 }, 235}; 236 237static struct gpiod_lookup_table vr1000_led3_gpio_table = { 238 .dev_id = "s3c24xx_led.3", 239 .table = { 240 GPIO_LOOKUP("GPB", 2, NULL, GPIO_ACTIVE_HIGH), 241 { }, 242 }, 243}; 244 245static struct s3c24xx_led_platdata vr1000_led1_pdata = { 246 .name = "led1", 247 .def_trigger = "", 248}; 249 250static struct s3c24xx_led_platdata vr1000_led2_pdata = { 251 .name = "led2", 252 .def_trigger = "", 253}; 254 255static struct s3c24xx_led_platdata vr1000_led3_pdata = { 256 .name = "led3", 257 .def_trigger = "", 258}; 259 260static struct platform_device vr1000_led1 = { 261 .name = "s3c24xx_led", 262 .id = 1, 263 .dev = { 264 .platform_data = &vr1000_led1_pdata, 265 }, 266}; 267 268static struct platform_device vr1000_led2 = { 269 .name = "s3c24xx_led", 270 .id = 2, 271 .dev = { 272 .platform_data = &vr1000_led2_pdata, 273 }, 274}; 275 276static struct platform_device vr1000_led3 = { 277 .name = "s3c24xx_led", 278 .id = 3, 279 .dev = { 280 .platform_data = &vr1000_led3_pdata, 281 }, 282}; 283 284/* I2C devices. */ 285 286static struct i2c_board_info vr1000_i2c_devs[] __initdata = { 287 { 288 I2C_BOARD_INFO("tlv320aic23", 0x1a), 289 }, { 290 I2C_BOARD_INFO("tmp101", 0x48), 291 }, { 292 I2C_BOARD_INFO("m41st87", 0x68), 293 }, 294}; 295 296/* devices for this board */ 297 298static struct platform_device *vr1000_devices[] __initdata = { 299 &s3c2410_device_dclk, 300 &s3c_device_ohci, 301 &s3c_device_lcd, 302 &s3c_device_wdt, 303 &s3c_device_i2c0, 304 &s3c_device_adc, 305 &serial_device, 306 &vr1000_dm9k0, 307 &vr1000_dm9k1, 308 &vr1000_led1, 309 &vr1000_led2, 310 &vr1000_led3, 311}; 312 313static void vr1000_power_off(void) 314{ 315 gpio_direction_output(S3C2410_GPB(9), 1); 316} 317 318static void __init vr1000_map_io(void) 319{ 320 pm_power_off = vr1000_power_off; 321 322 s3c24xx_init_io(vr1000_iodesc, ARRAY_SIZE(vr1000_iodesc)); 323 s3c24xx_init_uarts(vr1000_uartcfgs, ARRAY_SIZE(vr1000_uartcfgs)); 324 s3c24xx_set_timer_source(S3C24XX_PWM3, S3C24XX_PWM4); 325} 326 327static void __init vr1000_init_time(void) 328{ 329 s3c2410_init_clocks(12000000); 330 s3c24xx_timer_init(); 331} 332 333static void __init vr1000_init(void) 334{ 335 s3c_i2c0_set_platdata(NULL); 336 337 /* Disable pull-up on LED lines and register GPIO lookups */ 338 s3c_gpio_setpull(S3C2410_GPB(0), S3C_GPIO_PULL_NONE); 339 s3c_gpio_setpull(S3C2410_GPB(1), S3C_GPIO_PULL_NONE); 340 s3c_gpio_setpull(S3C2410_GPB(2), S3C_GPIO_PULL_NONE); 341 gpiod_add_lookup_table(&vr1000_led1_gpio_table); 342 gpiod_add_lookup_table(&vr1000_led2_gpio_table); 343 gpiod_add_lookup_table(&vr1000_led3_gpio_table); 344 345 platform_add_devices(vr1000_devices, ARRAY_SIZE(vr1000_devices)); 346 347 i2c_register_board_info(0, vr1000_i2c_devs, 348 ARRAY_SIZE(vr1000_i2c_devs)); 349 350 nor_simtec_init(); 351 simtec_audio_add(NULL, true, NULL); 352 353 WARN_ON(gpio_request(S3C2410_GPB(9), "power off")); 354} 355 356MACHINE_START(VR1000, "Thorcom-VR1000") 357 /* Maintainer: Ben Dooks <ben@simtec.co.uk> */ 358 .atag_offset = 0x100, 359 .nr_irqs = NR_IRQS_S3C2410, 360 .map_io = vr1000_map_io, 361 .init_machine = vr1000_init, 362 .init_irq = s3c2410_init_irq, 363 .init_time = vr1000_init_time, 364MACHINE_END