xref: /openbmc/linux/arch/m68k/coldfire/nettel.c (revision 498495dba268b20e8eadd7fe93c140c68b6cc9d2)
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