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