board-gpr.c (6095B)
1// SPDX-License-Identifier: GPL-2.0-or-later 2/* 3 * GPR board platform device registration (Au1550) 4 * 5 * Copyright (C) 2010 Wolfgang Grandegger <wg@denx.de> 6 */ 7 8#include <linux/delay.h> 9#include <linux/init.h> 10#include <linux/interrupt.h> 11#include <linux/kernel.h> 12#include <linux/platform_device.h> 13#include <linux/pm.h> 14#include <linux/mtd/partitions.h> 15#include <linux/mtd/physmap.h> 16#include <linux/leds.h> 17#include <linux/gpio.h> 18#include <linux/i2c.h> 19#include <linux/platform_data/i2c-gpio.h> 20#include <linux/gpio/machine.h> 21#include <asm/bootinfo.h> 22#include <asm/idle.h> 23#include <asm/reboot.h> 24#include <asm/setup.h> 25#include <asm/mach-au1x00/au1000.h> 26#include <asm/mach-au1x00/gpio-au1000.h> 27#include <prom.h> 28 29const char *get_system_type(void) 30{ 31 return "GPR"; 32} 33 34void prom_putchar(char c) 35{ 36 alchemy_uart_putchar(AU1000_UART0_PHYS_ADDR, c); 37} 38 39static void gpr_reset(char *c) 40{ 41 /* switch System-LED to orange (red# and green# on) */ 42 alchemy_gpio_direction_output(4, 0); 43 alchemy_gpio_direction_output(5, 0); 44 45 /* trigger watchdog to reset board in 200ms */ 46 printk(KERN_EMERG "Triggering watchdog soft reset...\n"); 47 raw_local_irq_disable(); 48 alchemy_gpio_direction_output(1, 0); 49 udelay(1); 50 alchemy_gpio_set_value(1, 1); 51 while (1) 52 cpu_wait(); 53} 54 55static void gpr_power_off(void) 56{ 57 while (1) 58 cpu_wait(); 59} 60 61void __init board_setup(void) 62{ 63 printk(KERN_INFO "Trapeze ITS GPR board\n"); 64 65 pm_power_off = gpr_power_off; 66 _machine_halt = gpr_power_off; 67 _machine_restart = gpr_reset; 68 69 /* Enable UART1/3 */ 70 alchemy_uart_enable(AU1000_UART3_PHYS_ADDR); 71 alchemy_uart_enable(AU1000_UART1_PHYS_ADDR); 72 73 /* Take away Reset of UMTS-card */ 74 alchemy_gpio_direction_output(215, 1); 75} 76 77/* 78 * Watchdog 79 */ 80static struct resource gpr_wdt_resource[] = { 81 [0] = { 82 .start = 1, 83 .end = 1, 84 .name = "gpr-adm6320-wdt", 85 .flags = IORESOURCE_IRQ, 86 } 87}; 88 89static struct platform_device gpr_wdt_device = { 90 .name = "adm6320-wdt", 91 .id = 0, 92 .num_resources = ARRAY_SIZE(gpr_wdt_resource), 93 .resource = gpr_wdt_resource, 94}; 95 96/* 97 * FLASH 98 * 99 * 0x00000000-0x00200000 : "kernel" 100 * 0x00200000-0x00a00000 : "rootfs" 101 * 0x01d00000-0x01f00000 : "config" 102 * 0x01c00000-0x01d00000 : "yamon" 103 * 0x01d00000-0x01d40000 : "yamon env vars" 104 * 0x00000000-0x00a00000 : "kernel+rootfs" 105 */ 106static struct mtd_partition gpr_mtd_partitions[] = { 107 { 108 .name = "kernel", 109 .size = 0x00200000, 110 .offset = 0, 111 }, 112 { 113 .name = "rootfs", 114 .size = 0x00800000, 115 .offset = MTDPART_OFS_APPEND, 116 .mask_flags = MTD_WRITEABLE, 117 }, 118 { 119 .name = "config", 120 .size = 0x00200000, 121 .offset = 0x01d00000, 122 }, 123 { 124 .name = "yamon", 125 .size = 0x00100000, 126 .offset = 0x01c00000, 127 }, 128 { 129 .name = "yamon env vars", 130 .size = 0x00040000, 131 .offset = MTDPART_OFS_APPEND, 132 }, 133 { 134 .name = "kernel+rootfs", 135 .size = 0x00a00000, 136 .offset = 0, 137 }, 138}; 139 140static struct physmap_flash_data gpr_flash_data = { 141 .width = 4, 142 .nr_parts = ARRAY_SIZE(gpr_mtd_partitions), 143 .parts = gpr_mtd_partitions, 144}; 145 146static struct resource gpr_mtd_resource = { 147 .start = 0x1e000000, 148 .end = 0x1fffffff, 149 .flags = IORESOURCE_MEM, 150}; 151 152static struct platform_device gpr_mtd_device = { 153 .name = "physmap-flash", 154 .dev = { 155 .platform_data = &gpr_flash_data, 156 }, 157 .num_resources = 1, 158 .resource = &gpr_mtd_resource, 159}; 160 161/* 162 * LEDs 163 */ 164static const struct gpio_led gpr_gpio_leds[] = { 165 { /* green */ 166 .name = "gpr:green", 167 .gpio = 4, 168 .active_low = 1, 169 }, 170 { /* red */ 171 .name = "gpr:red", 172 .gpio = 5, 173 .active_low = 1, 174 } 175}; 176 177static struct gpio_led_platform_data gpr_led_data = { 178 .num_leds = ARRAY_SIZE(gpr_gpio_leds), 179 .leds = gpr_gpio_leds, 180}; 181 182static struct platform_device gpr_led_devices = { 183 .name = "leds-gpio", 184 .id = -1, 185 .dev = { 186 .platform_data = &gpr_led_data, 187 } 188}; 189 190/* 191 * I2C 192 */ 193static struct gpiod_lookup_table gpr_i2c_gpiod_table = { 194 .dev_id = "i2c-gpio", 195 .table = { 196 /* 197 * This should be on "GPIO2" which has base at 200 so 198 * the global numbers 209 and 210 should correspond to 199 * local offsets 9 and 10. 200 */ 201 GPIO_LOOKUP_IDX("alchemy-gpio2", 9, NULL, 0, 202 GPIO_ACTIVE_HIGH), 203 GPIO_LOOKUP_IDX("alchemy-gpio2", 10, NULL, 1, 204 GPIO_ACTIVE_HIGH), 205 }, 206}; 207 208static struct i2c_gpio_platform_data gpr_i2c_data = { 209 /* 210 * The open drain mode is hardwired somewhere or an electrical 211 * property of the alchemy GPIO controller. 212 */ 213 .sda_is_open_drain = 1, 214 .scl_is_open_drain = 1, 215 .udelay = 2, /* ~100 kHz */ 216 .timeout = HZ, 217}; 218 219static struct platform_device gpr_i2c_device = { 220 .name = "i2c-gpio", 221 .id = -1, 222 .dev.platform_data = &gpr_i2c_data, 223}; 224 225static struct i2c_board_info gpr_i2c_info[] __initdata = { 226 { 227 I2C_BOARD_INFO("lm83", 0x18), 228 } 229}; 230 231 232 233static struct resource alchemy_pci_host_res[] = { 234 [0] = { 235 .start = AU1500_PCI_PHYS_ADDR, 236 .end = AU1500_PCI_PHYS_ADDR + 0xfff, 237 .flags = IORESOURCE_MEM, 238 }, 239}; 240 241static int gpr_map_pci_irq(const struct pci_dev *d, u8 slot, u8 pin) 242{ 243 if ((slot == 0) && (pin == 1)) 244 return AU1550_PCI_INTA; 245 else if ((slot == 0) && (pin == 2)) 246 return AU1550_PCI_INTB; 247 248 return 0xff; 249} 250 251static struct alchemy_pci_platdata gpr_pci_pd = { 252 .board_map_irq = gpr_map_pci_irq, 253 .pci_cfg_set = PCI_CONFIG_AEN | PCI_CONFIG_R2H | PCI_CONFIG_R1H | 254 PCI_CONFIG_CH | 255#if defined(__MIPSEB__) 256 PCI_CONFIG_SIC_HWA_DAT | PCI_CONFIG_SM, 257#else 258 0, 259#endif 260}; 261 262static struct platform_device gpr_pci_host_dev = { 263 .dev.platform_data = &gpr_pci_pd, 264 .name = "alchemy-pci", 265 .id = 0, 266 .num_resources = ARRAY_SIZE(alchemy_pci_host_res), 267 .resource = alchemy_pci_host_res, 268}; 269 270static struct platform_device *gpr_devices[] __initdata = { 271 &gpr_wdt_device, 272 &gpr_mtd_device, 273 &gpr_i2c_device, 274 &gpr_led_devices, 275}; 276 277static int __init gpr_pci_init(void) 278{ 279 return platform_device_register(&gpr_pci_host_dev); 280} 281/* must be arch_initcall; MIPS PCI scans busses in a subsys_initcall */ 282arch_initcall(gpr_pci_init); 283 284 285static int __init gpr_dev_init(void) 286{ 287 gpiod_add_lookup_table(&gpr_i2c_gpiod_table); 288 i2c_register_board_info(0, gpr_i2c_info, ARRAY_SIZE(gpr_i2c_info)); 289 290 return platform_add_devices(gpr_devices, ARRAY_SIZE(gpr_devices)); 291} 292device_initcall(gpr_dev_init);