xref: /linux/arch/mips/rb532/devices.c (revision e5a52fd2b8cdb700b3c07b030e050a49ef3156b9)
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3  *  RouterBoard 500 Platform devices
4  *
5  *  Copyright (C) 2006 Felix Fietkau <nbd@openwrt.org>
6  *  Copyright (C) 2007 Florian Fainelli <florian@openwrt.org>
7  */
8 #include <linux/kernel.h>
9 #include <linux/export.h>
10 #include <linux/init.h>
11 #include <linux/ctype.h>
12 #include <linux/string.h>
13 #include <linux/platform_device.h>
14 #include <linux/mtd/platnand.h>
15 #include <linux/mtd/mtd.h>
16 #include <linux/gpio.h>
17 #include <linux/gpio/machine.h>
18 #include <linux/gpio_keys.h>
19 #include <linux/input.h>
20 #include <linux/serial_8250.h>
21 
22 #include <asm/bootinfo.h>
23 
24 #include <asm/mach-rc32434/rc32434.h>
25 #include <asm/mach-rc32434/dma.h>
26 #include <asm/mach-rc32434/dma_v.h>
27 #include <asm/mach-rc32434/eth.h>
28 #include <asm/mach-rc32434/rb.h>
29 #include <asm/mach-rc32434/integ.h>
30 #include <asm/mach-rc32434/gpio.h>
31 #include <asm/mach-rc32434/irq.h>
32 
33 #define ETH0_RX_DMA_ADDR  (DMA0_BASE_ADDR + 0 * DMA_CHAN_OFFSET)
34 #define ETH0_TX_DMA_ADDR  (DMA0_BASE_ADDR + 1 * DMA_CHAN_OFFSET)
35 
36 extern unsigned int idt_cpu_freq;
37 
38 static struct mpmc_device dev3;
39 
40 void set_latch_u5(unsigned char or_mask, unsigned char nand_mask)
41 {
42 	unsigned long flags;
43 
44 	spin_lock_irqsave(&dev3.lock, flags);
45 
46 	dev3.state = (dev3.state | or_mask) & ~nand_mask;
47 	writeb(dev3.state, dev3.base);
48 
49 	spin_unlock_irqrestore(&dev3.lock, flags);
50 }
51 EXPORT_SYMBOL(set_latch_u5);
52 
53 unsigned char get_latch_u5(void)
54 {
55 	return dev3.state;
56 }
57 EXPORT_SYMBOL(get_latch_u5);
58 
59 static struct resource korina_dev0_res[] = {
60 	{
61 		.name = "korina_regs",
62 		.start = ETH0_BASE_ADDR,
63 		.end = ETH0_BASE_ADDR + sizeof(struct eth_regs),
64 		.flags = IORESOURCE_MEM,
65 	 }, {
66 		.name = "korina_rx",
67 		.start = ETH0_DMA_RX_IRQ,
68 		.end = ETH0_DMA_RX_IRQ,
69 		.flags = IORESOURCE_IRQ
70 	}, {
71 		.name = "korina_tx",
72 		.start = ETH0_DMA_TX_IRQ,
73 		.end = ETH0_DMA_TX_IRQ,
74 		.flags = IORESOURCE_IRQ
75 	}, {
76 		.name = "korina_ovr",
77 		.start = ETH0_RX_OVR_IRQ,
78 		.end = ETH0_RX_OVR_IRQ,
79 		.flags = IORESOURCE_IRQ
80 	}, {
81 		.name = "korina_und",
82 		.start = ETH0_TX_UND_IRQ,
83 		.end = ETH0_TX_UND_IRQ,
84 		.flags = IORESOURCE_IRQ
85 	}, {
86 		.name = "korina_dma_rx",
87 		.start = ETH0_RX_DMA_ADDR,
88 		.end = ETH0_RX_DMA_ADDR + DMA_CHAN_OFFSET - 1,
89 		.flags = IORESOURCE_MEM,
90 	 }, {
91 		.name = "korina_dma_tx",
92 		.start = ETH0_TX_DMA_ADDR,
93 		.end = ETH0_TX_DMA_ADDR + DMA_CHAN_OFFSET - 1,
94 		.flags = IORESOURCE_MEM,
95 	 }
96 };
97 
98 static struct korina_device korina_dev0_data = {
99 	.name = "korina0",
100 	.mac = {0xde, 0xca, 0xff, 0xc0, 0xff, 0xee}
101 };
102 
103 static struct platform_device korina_dev0 = {
104 	.id = -1,
105 	.name = "korina",
106 	.resource = korina_dev0_res,
107 	.num_resources = ARRAY_SIZE(korina_dev0_res),
108 };
109 
110 static struct resource cf_slot0_res[] = {
111 	{
112 		.name = "cf_membase",
113 		.flags = IORESOURCE_MEM
114 	}, {
115 		.name = "cf_irq",
116 		.start = (8 + 4 * 32 + CF_GPIO_NUM),	/* 149 */
117 		.end = (8 + 4 * 32 + CF_GPIO_NUM),
118 		.flags = IORESOURCE_IRQ
119 	}
120 };
121 
122 static struct gpiod_lookup_table cf_slot0_gpio_table = {
123 	.dev_id = "pata-rb532-cf",
124 	.table = {
125 		GPIO_LOOKUP("gpio0", CF_GPIO_NUM,
126 			    NULL, GPIO_ACTIVE_HIGH),
127 		{ },
128 	},
129 };
130 
131 static struct platform_device cf_slot0 = {
132 	.id = -1,
133 	.name = "pata-rb532-cf",
134 	.resource = cf_slot0_res,
135 	.num_resources = ARRAY_SIZE(cf_slot0_res),
136 };
137 
138 /* Resources and device for NAND */
139 static int rb532_dev_ready(struct nand_chip *chip)
140 {
141 	return gpio_get_value(GPIO_RDY);
142 }
143 
144 static void rb532_cmd_ctrl(struct nand_chip *chip, int cmd, unsigned int ctrl)
145 {
146 	unsigned char orbits, nandbits;
147 
148 	if (ctrl & NAND_CTRL_CHANGE) {
149 		orbits = (ctrl & NAND_CLE) << 1;
150 		orbits |= (ctrl & NAND_ALE) >> 1;
151 
152 		nandbits = (~ctrl & NAND_CLE) << 1;
153 		nandbits |= (~ctrl & NAND_ALE) >> 1;
154 
155 		set_latch_u5(orbits, nandbits);
156 	}
157 	if (cmd != NAND_CMD_NONE)
158 		writeb(cmd, chip->legacy.IO_ADDR_W);
159 }
160 
161 static struct resource nand_slot0_res[] = {
162 	[0] = {
163 		.name = "nand_membase",
164 		.flags = IORESOURCE_MEM
165 	}
166 };
167 
168 static struct platform_nand_data rb532_nand_data = {
169 	.ctrl.dev_ready = rb532_dev_ready,
170 	.ctrl.cmd_ctrl	= rb532_cmd_ctrl,
171 };
172 
173 static struct platform_device nand_slot0 = {
174 	.name = "gen_nand",
175 	.id = -1,
176 	.resource = nand_slot0_res,
177 	.num_resources = ARRAY_SIZE(nand_slot0_res),
178 	.dev.platform_data = &rb532_nand_data,
179 };
180 
181 static struct mtd_partition rb532_partition_info[] = {
182 	{
183 		.name = "Routerboard NAND boot",
184 		.offset = 0,
185 		.size = 4 * 1024 * 1024,
186 	}, {
187 		.name = "rootfs",
188 		.offset = MTDPART_OFS_NXTBLK,
189 		.size = MTDPART_SIZ_FULL,
190 	}
191 };
192 
193 static struct platform_device rb532_led = {
194 	.name = "rb532-led",
195 	.id = -1,
196 };
197 
198 static struct platform_device rb532_button = {
199 	.name	= "rb532-button",
200 	.id	= -1,
201 };
202 
203 static struct resource rb532_wdt_res[] = {
204 	{
205 		.name = "rb532_wdt_res",
206 		.start = INTEG0_BASE_ADDR,
207 		.end = INTEG0_BASE_ADDR + sizeof(struct integ),
208 		.flags = IORESOURCE_MEM,
209 	}
210 };
211 
212 static struct platform_device rb532_wdt = {
213 	.name		= "rc32434_wdt",
214 	.id		= -1,
215 	.resource	= rb532_wdt_res,
216 	.num_resources	= ARRAY_SIZE(rb532_wdt_res),
217 };
218 
219 static struct plat_serial8250_port rb532_uart_res[] = {
220 	{
221 		.type           = PORT_16550A,
222 		.membase	= (char *)KSEG1ADDR(REGBASE + UART0BASE),
223 		.irq		= UART0_IRQ,
224 		.regshift	= 2,
225 		.iotype		= UPIO_MEM,
226 		.flags		= UPF_BOOT_AUTOCONF,
227 	},
228 	{
229 		.flags		= 0,
230 	}
231 };
232 
233 static struct platform_device rb532_uart = {
234 	.name		   = "serial8250",
235 	.id		   = PLAT8250_DEV_PLATFORM,
236 	.dev.platform_data = &rb532_uart_res,
237 };
238 
239 static struct platform_device *rb532_devs[] = {
240 	&korina_dev0,
241 	&nand_slot0,
242 	&cf_slot0,
243 	&rb532_led,
244 	&rb532_button,
245 	&rb532_uart,
246 	&rb532_wdt
247 };
248 
249 /* NAND definitions */
250 #define NAND_CHIP_DELAY 25
251 
252 static void __init rb532_nand_setup(void)
253 {
254 	switch (mips_machtype) {
255 	case MACH_MIKROTIK_RB532A:
256 		set_latch_u5(LO_FOFF | LO_CEX,
257 				LO_ULED | LO_ALE | LO_CLE | LO_WPX);
258 		break;
259 	default:
260 		set_latch_u5(LO_WPX | LO_FOFF | LO_CEX,
261 				LO_ULED | LO_ALE | LO_CLE);
262 		break;
263 	}
264 
265 	/* Setup NAND specific settings */
266 	rb532_nand_data.chip.nr_chips = 1;
267 	rb532_nand_data.chip.nr_partitions = ARRAY_SIZE(rb532_partition_info);
268 	rb532_nand_data.chip.partitions = rb532_partition_info;
269 	rb532_nand_data.chip.chip_delay = NAND_CHIP_DELAY;
270 }
271 
272 
273 static int __init plat_setup_devices(void)
274 {
275 	/* Look for the CF card reader */
276 	if (!readl(IDT434_REG_BASE + DEV1MASK))
277 		rb532_devs[2] = NULL;	/* disable cf_slot0 at index 2 */
278 	else {
279 		cf_slot0_res[0].start =
280 		    readl(IDT434_REG_BASE + DEV1BASE);
281 		cf_slot0_res[0].end = cf_slot0_res[0].start + 0x1000;
282 	}
283 
284 	/* Read the NAND resources from the device controller */
285 	nand_slot0_res[0].start = readl(IDT434_REG_BASE + DEV2BASE);
286 	nand_slot0_res[0].end = nand_slot0_res[0].start + 0x1000;
287 
288 	/* Read and map device controller 3 */
289 	dev3.base = ioremap(readl(IDT434_REG_BASE + DEV3BASE), 1);
290 
291 	if (!dev3.base) {
292 		printk(KERN_ERR "rb532: cannot remap device controller 3\n");
293 		return -ENXIO;
294 	}
295 
296 	/* Initialise the NAND device */
297 	rb532_nand_setup();
298 
299 	/* set the uart clock to the current cpu frequency */
300 	rb532_uart_res[0].uartclk = idt_cpu_freq;
301 
302 	dev_set_drvdata(&korina_dev0.dev, &korina_dev0_data);
303 
304 	gpiod_add_lookup_table(&cf_slot0_gpio_table);
305 	return platform_add_devices(rb532_devs, ARRAY_SIZE(rb532_devs));
306 }
307 
308 #ifdef CONFIG_NET
309 
310 static int __init setup_kmac(char *s)
311 {
312 	printk(KERN_INFO "korina mac = %s\n", s);
313 	if (!mac_pton(s, korina_dev0_data.mac)) {
314 		printk(KERN_ERR "Invalid mac\n");
315 		return -EINVAL;
316 	}
317 	return 0;
318 }
319 
320 __setup("kmac=", setup_kmac);
321 
322 #endif /* CONFIG_NET */
323 
324 arch_initcall(plat_setup_devices);
325