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 29 const char *get_system_type(void) 30 { 31 return "GPR"; 32 } 33 34 void prom_putchar(char c) 35 { 36 alchemy_uart_putchar(AU1000_UART0_PHYS_ADDR, c); 37 } 38 39 static 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 55 static void gpr_power_off(void) 56 { 57 while (1) 58 cpu_wait(); 59 } 60 61 void __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 */ 80 static 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 89 static 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 */ 106 static 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 140 static 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 146 static struct resource gpr_mtd_resource = { 147 .start = 0x1e000000, 148 .end = 0x1fffffff, 149 .flags = IORESOURCE_MEM, 150 }; 151 152 static 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 */ 164 static 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 177 static struct gpio_led_platform_data gpr_led_data = { 178 .num_leds = ARRAY_SIZE(gpr_gpio_leds), 179 .leds = gpr_gpio_leds, 180 }; 181 182 static 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 */ 193 static 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 208 static 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 219 static struct platform_device gpr_i2c_device = { 220 .name = "i2c-gpio", 221 .id = -1, 222 .dev.platform_data = &gpr_i2c_data, 223 }; 224 225 static struct i2c_board_info gpr_i2c_info[] __initdata = { 226 { 227 I2C_BOARD_INFO("lm83", 0x18), 228 } 229 }; 230 231 232 233 static 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 241 static 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 251 static 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 262 static 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 270 static struct platform_device *gpr_devices[] __initdata = { 271 &gpr_wdt_device, 272 &gpr_mtd_device, 273 &gpr_i2c_device, 274 &gpr_led_devices, 275 }; 276 277 static 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 */ 282 arch_initcall(gpr_pci_init); 283 284 285 static 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 } 292 device_initcall(gpr_dev_init); 293