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