1*b2441318SGreg Kroah-Hartman // SPDX-License-Identifier: GPL-2.0
2f86b9e03SGreg Ungerer /***************************************************************************/
3f86b9e03SGreg Ungerer
4f86b9e03SGreg Ungerer /*
5f86b9e03SGreg Ungerer * nettel.c -- startup code support for the NETtel boards
6f86b9e03SGreg Ungerer *
7f86b9e03SGreg Ungerer * Copyright (C) 2009, Greg Ungerer (gerg@snapgear.com)
8f86b9e03SGreg Ungerer */
9f86b9e03SGreg Ungerer
10f86b9e03SGreg Ungerer /***************************************************************************/
11f86b9e03SGreg Ungerer
12f86b9e03SGreg Ungerer #include <linux/kernel.h>
13f86b9e03SGreg Ungerer #include <linux/param.h>
14f86b9e03SGreg Ungerer #include <linux/init.h>
15f86b9e03SGreg Ungerer #include <linux/io.h>
16f86b9e03SGreg Ungerer #include <linux/platform_device.h>
17f86b9e03SGreg Ungerer #include <asm/coldfire.h>
18f86b9e03SGreg Ungerer #include <asm/mcfsim.h>
19f86b9e03SGreg Ungerer #include <asm/nettel.h>
20f86b9e03SGreg Ungerer
21f86b9e03SGreg Ungerer /***************************************************************************/
22f86b9e03SGreg Ungerer
23f86b9e03SGreg Ungerer /*
24f86b9e03SGreg Ungerer * Define the IO and interrupt resources of the 2 SMC9196 interfaces.
25f86b9e03SGreg Ungerer */
26f86b9e03SGreg Ungerer #define NETTEL_SMC0_ADDR 0x30600300
27f86b9e03SGreg Ungerer #define NETTEL_SMC0_IRQ 29
28f86b9e03SGreg Ungerer
29f86b9e03SGreg Ungerer #define NETTEL_SMC1_ADDR 0x30600000
30f86b9e03SGreg Ungerer #define NETTEL_SMC1_IRQ 27
31f86b9e03SGreg Ungerer
32f86b9e03SGreg Ungerer /*
33f86b9e03SGreg Ungerer * We need some access into the SMC9196 registers. Define those registers
34f86b9e03SGreg Ungerer * we will need here (including the smc91x.h doesn't seem to give us these
35f86b9e03SGreg Ungerer * in a simple form).
36f86b9e03SGreg Ungerer */
37f86b9e03SGreg Ungerer #define SMC91xx_BANKSELECT 14
38f86b9e03SGreg Ungerer #define SMC91xx_BASEADDR 2
39f86b9e03SGreg Ungerer #define SMC91xx_BASEMAC 4
40f86b9e03SGreg Ungerer
41f86b9e03SGreg Ungerer /***************************************************************************/
42f86b9e03SGreg Ungerer
43f86b9e03SGreg Ungerer static struct resource nettel_smc91x_0_resources[] = {
44f86b9e03SGreg Ungerer {
45f86b9e03SGreg Ungerer .start = NETTEL_SMC0_ADDR,
46f86b9e03SGreg Ungerer .end = NETTEL_SMC0_ADDR + 0x20,
47f86b9e03SGreg Ungerer .flags = IORESOURCE_MEM,
48f86b9e03SGreg Ungerer },
49f86b9e03SGreg Ungerer {
50f86b9e03SGreg Ungerer .start = NETTEL_SMC0_IRQ,
51f86b9e03SGreg Ungerer .end = NETTEL_SMC0_IRQ,
52f86b9e03SGreg Ungerer .flags = IORESOURCE_IRQ,
53f86b9e03SGreg Ungerer },
54f86b9e03SGreg Ungerer };
55f86b9e03SGreg Ungerer
56f86b9e03SGreg Ungerer static struct resource nettel_smc91x_1_resources[] = {
57f86b9e03SGreg Ungerer {
58f86b9e03SGreg Ungerer .start = NETTEL_SMC1_ADDR,
59f86b9e03SGreg Ungerer .end = NETTEL_SMC1_ADDR + 0x20,
60f86b9e03SGreg Ungerer .flags = IORESOURCE_MEM,
61f86b9e03SGreg Ungerer },
62f86b9e03SGreg Ungerer {
63f86b9e03SGreg Ungerer .start = NETTEL_SMC1_IRQ,
64f86b9e03SGreg Ungerer .end = NETTEL_SMC1_IRQ,
65f86b9e03SGreg Ungerer .flags = IORESOURCE_IRQ,
66f86b9e03SGreg Ungerer },
67f86b9e03SGreg Ungerer };
68f86b9e03SGreg Ungerer
69f86b9e03SGreg Ungerer static struct platform_device nettel_smc91x[] = {
70f86b9e03SGreg Ungerer {
71f86b9e03SGreg Ungerer .name = "smc91x",
72f86b9e03SGreg Ungerer .id = 0,
73f86b9e03SGreg Ungerer .num_resources = ARRAY_SIZE(nettel_smc91x_0_resources),
74f86b9e03SGreg Ungerer .resource = nettel_smc91x_0_resources,
75f86b9e03SGreg Ungerer },
76f86b9e03SGreg Ungerer {
77f86b9e03SGreg Ungerer .name = "smc91x",
78f86b9e03SGreg Ungerer .id = 1,
79f86b9e03SGreg Ungerer .num_resources = ARRAY_SIZE(nettel_smc91x_1_resources),
80f86b9e03SGreg Ungerer .resource = nettel_smc91x_1_resources,
81f86b9e03SGreg Ungerer },
82f86b9e03SGreg Ungerer };
83f86b9e03SGreg Ungerer
84f86b9e03SGreg Ungerer static struct platform_device *nettel_devices[] __initdata = {
85f86b9e03SGreg Ungerer &nettel_smc91x[0],
86f86b9e03SGreg Ungerer &nettel_smc91x[1],
87f86b9e03SGreg Ungerer };
88f86b9e03SGreg Ungerer
89f86b9e03SGreg Ungerer /***************************************************************************/
90f86b9e03SGreg Ungerer
91f86b9e03SGreg Ungerer static u8 nettel_macdefault[] __initdata = {
92f86b9e03SGreg Ungerer 0x00, 0xd0, 0xcf, 0x00, 0x00, 0x01,
93f86b9e03SGreg Ungerer };
94f86b9e03SGreg Ungerer
95f86b9e03SGreg Ungerer /*
96f86b9e03SGreg Ungerer * Set flash contained MAC address into SMC9196 core. Make sure the flash
97f86b9e03SGreg Ungerer * MAC address is sane, and not an empty flash. If no good use the Moreton
98f86b9e03SGreg Ungerer * Bay default MAC address instead.
99f86b9e03SGreg Ungerer */
100f86b9e03SGreg Ungerer
nettel_smc91x_setmac(unsigned int ioaddr,unsigned int flashaddr)101f86b9e03SGreg Ungerer static void __init nettel_smc91x_setmac(unsigned int ioaddr, unsigned int flashaddr)
102f86b9e03SGreg Ungerer {
103f86b9e03SGreg Ungerer u16 *macp;
104f86b9e03SGreg Ungerer
105f86b9e03SGreg Ungerer macp = (u16 *) flashaddr;
106f86b9e03SGreg Ungerer if ((macp[0] == 0xffff) && (macp[1] == 0xffff) && (macp[2] == 0xffff))
107f86b9e03SGreg Ungerer macp = (u16 *) &nettel_macdefault[0];
108f86b9e03SGreg Ungerer
109f86b9e03SGreg Ungerer writew(1, NETTEL_SMC0_ADDR + SMC91xx_BANKSELECT);
110f86b9e03SGreg Ungerer writew(macp[0], ioaddr + SMC91xx_BASEMAC);
111f86b9e03SGreg Ungerer writew(macp[1], ioaddr + SMC91xx_BASEMAC + 2);
112f86b9e03SGreg Ungerer writew(macp[2], ioaddr + SMC91xx_BASEMAC + 4);
113f86b9e03SGreg Ungerer }
114f86b9e03SGreg Ungerer
115f86b9e03SGreg Ungerer /***************************************************************************/
116f86b9e03SGreg Ungerer
117f86b9e03SGreg Ungerer /*
118f86b9e03SGreg Ungerer * Re-map the address space of at least one of the SMC ethernet
119f86b9e03SGreg Ungerer * parts. Both parts power up decoding the same address, so we
120f86b9e03SGreg Ungerer * need to move one of them first, before doing anything else.
121f86b9e03SGreg Ungerer */
122f86b9e03SGreg Ungerer
nettel_smc91x_init(void)123f86b9e03SGreg Ungerer static void __init nettel_smc91x_init(void)
124f86b9e03SGreg Ungerer {
125f86b9e03SGreg Ungerer writew(0x00ec, MCFSIM_PADDR);
126f86b9e03SGreg Ungerer mcf_setppdata(0, 0x0080);
127f86b9e03SGreg Ungerer writew(1, NETTEL_SMC0_ADDR + SMC91xx_BANKSELECT);
128f86b9e03SGreg Ungerer writew(0x0067, NETTEL_SMC0_ADDR + SMC91xx_BASEADDR);
129f86b9e03SGreg Ungerer mcf_setppdata(0x0080, 0);
130f86b9e03SGreg Ungerer
131f86b9e03SGreg Ungerer /* Set correct chip select timing for SMC9196 accesses */
132f86b9e03SGreg Ungerer writew(0x1180, MCFSIM_CSCR3);
133f86b9e03SGreg Ungerer
134f86b9e03SGreg Ungerer /* Set the SMC interrupts to be auto-vectored */
135f86b9e03SGreg Ungerer mcf_autovector(NETTEL_SMC0_IRQ);
136f86b9e03SGreg Ungerer mcf_autovector(NETTEL_SMC1_IRQ);
137f86b9e03SGreg Ungerer
138f86b9e03SGreg Ungerer /* Set MAC addresses from flash for both interfaces */
139f86b9e03SGreg Ungerer nettel_smc91x_setmac(NETTEL_SMC0_ADDR, 0xf0006000);
140f86b9e03SGreg Ungerer nettel_smc91x_setmac(NETTEL_SMC1_ADDR, 0xf0006006);
141f86b9e03SGreg Ungerer }
142f86b9e03SGreg Ungerer
143f86b9e03SGreg Ungerer /***************************************************************************/
144f86b9e03SGreg Ungerer
init_nettel(void)145f86b9e03SGreg Ungerer static int __init init_nettel(void)
146f86b9e03SGreg Ungerer {
147f86b9e03SGreg Ungerer nettel_smc91x_init();
148f86b9e03SGreg Ungerer platform_add_devices(nettel_devices, ARRAY_SIZE(nettel_devices));
149f86b9e03SGreg Ungerer return 0;
150f86b9e03SGreg Ungerer }
151f86b9e03SGreg Ungerer
152f86b9e03SGreg Ungerer arch_initcall(init_nettel);
153f86b9e03SGreg Ungerer
154f86b9e03SGreg Ungerer /***************************************************************************/
155