18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0
28c2ecf20Sopenharmony_ci/***************************************************************************/
38c2ecf20Sopenharmony_ci
48c2ecf20Sopenharmony_ci/*
58c2ecf20Sopenharmony_ci *	nettel.c -- startup code support for the NETtel boards
68c2ecf20Sopenharmony_ci *
78c2ecf20Sopenharmony_ci *	Copyright (C) 2009, Greg Ungerer (gerg@snapgear.com)
88c2ecf20Sopenharmony_ci */
98c2ecf20Sopenharmony_ci
108c2ecf20Sopenharmony_ci/***************************************************************************/
118c2ecf20Sopenharmony_ci
128c2ecf20Sopenharmony_ci#include <linux/kernel.h>
138c2ecf20Sopenharmony_ci#include <linux/param.h>
148c2ecf20Sopenharmony_ci#include <linux/init.h>
158c2ecf20Sopenharmony_ci#include <linux/io.h>
168c2ecf20Sopenharmony_ci#include <linux/platform_device.h>
178c2ecf20Sopenharmony_ci#include <asm/coldfire.h>
188c2ecf20Sopenharmony_ci#include <asm/mcfsim.h>
198c2ecf20Sopenharmony_ci#include <asm/nettel.h>
208c2ecf20Sopenharmony_ci
218c2ecf20Sopenharmony_ci/***************************************************************************/
228c2ecf20Sopenharmony_ci
238c2ecf20Sopenharmony_ci/*
248c2ecf20Sopenharmony_ci * Define the IO and interrupt resources of the 2 SMC9196 interfaces.
258c2ecf20Sopenharmony_ci */
268c2ecf20Sopenharmony_ci#define	NETTEL_SMC0_ADDR	0x30600300
278c2ecf20Sopenharmony_ci#define	NETTEL_SMC0_IRQ		29
288c2ecf20Sopenharmony_ci
298c2ecf20Sopenharmony_ci#define	NETTEL_SMC1_ADDR	0x30600000
308c2ecf20Sopenharmony_ci#define	NETTEL_SMC1_IRQ		27
318c2ecf20Sopenharmony_ci
328c2ecf20Sopenharmony_ci/*
338c2ecf20Sopenharmony_ci * We need some access into the SMC9196 registers. Define those registers
348c2ecf20Sopenharmony_ci * we will need here (including the smc91x.h doesn't seem to give us these
358c2ecf20Sopenharmony_ci * in a simple form).
368c2ecf20Sopenharmony_ci */
378c2ecf20Sopenharmony_ci#define	SMC91xx_BANKSELECT	14
388c2ecf20Sopenharmony_ci#define	SMC91xx_BASEADDR	2
398c2ecf20Sopenharmony_ci#define	SMC91xx_BASEMAC		4
408c2ecf20Sopenharmony_ci
418c2ecf20Sopenharmony_ci/***************************************************************************/
428c2ecf20Sopenharmony_ci
438c2ecf20Sopenharmony_cistatic struct resource nettel_smc91x_0_resources[] = {
448c2ecf20Sopenharmony_ci	{
458c2ecf20Sopenharmony_ci		.start		= NETTEL_SMC0_ADDR,
468c2ecf20Sopenharmony_ci		.end		= NETTEL_SMC0_ADDR + 0x20,
478c2ecf20Sopenharmony_ci		.flags		= IORESOURCE_MEM,
488c2ecf20Sopenharmony_ci	},
498c2ecf20Sopenharmony_ci	{
508c2ecf20Sopenharmony_ci		.start		= NETTEL_SMC0_IRQ,
518c2ecf20Sopenharmony_ci		.end		= NETTEL_SMC0_IRQ,
528c2ecf20Sopenharmony_ci		.flags		= IORESOURCE_IRQ,
538c2ecf20Sopenharmony_ci	},
548c2ecf20Sopenharmony_ci};
558c2ecf20Sopenharmony_ci
568c2ecf20Sopenharmony_cistatic struct resource nettel_smc91x_1_resources[] = {
578c2ecf20Sopenharmony_ci	{
588c2ecf20Sopenharmony_ci		.start		= NETTEL_SMC1_ADDR,
598c2ecf20Sopenharmony_ci		.end		= NETTEL_SMC1_ADDR + 0x20,
608c2ecf20Sopenharmony_ci		.flags		= IORESOURCE_MEM,
618c2ecf20Sopenharmony_ci	},
628c2ecf20Sopenharmony_ci	{
638c2ecf20Sopenharmony_ci		.start		= NETTEL_SMC1_IRQ,
648c2ecf20Sopenharmony_ci		.end		= NETTEL_SMC1_IRQ,
658c2ecf20Sopenharmony_ci		.flags		= IORESOURCE_IRQ,
668c2ecf20Sopenharmony_ci	},
678c2ecf20Sopenharmony_ci};
688c2ecf20Sopenharmony_ci
698c2ecf20Sopenharmony_cistatic struct platform_device nettel_smc91x[] = {
708c2ecf20Sopenharmony_ci	{
718c2ecf20Sopenharmony_ci		.name			= "smc91x",
728c2ecf20Sopenharmony_ci		.id			= 0,
738c2ecf20Sopenharmony_ci		.num_resources		= ARRAY_SIZE(nettel_smc91x_0_resources),
748c2ecf20Sopenharmony_ci		.resource		= nettel_smc91x_0_resources,
758c2ecf20Sopenharmony_ci	},
768c2ecf20Sopenharmony_ci	{
778c2ecf20Sopenharmony_ci		.name			= "smc91x",
788c2ecf20Sopenharmony_ci		.id			= 1,
798c2ecf20Sopenharmony_ci		.num_resources		= ARRAY_SIZE(nettel_smc91x_1_resources),
808c2ecf20Sopenharmony_ci		.resource		= nettel_smc91x_1_resources,
818c2ecf20Sopenharmony_ci	},
828c2ecf20Sopenharmony_ci};
838c2ecf20Sopenharmony_ci
848c2ecf20Sopenharmony_cistatic struct platform_device *nettel_devices[] __initdata = {
858c2ecf20Sopenharmony_ci	&nettel_smc91x[0],
868c2ecf20Sopenharmony_ci	&nettel_smc91x[1],
878c2ecf20Sopenharmony_ci};
888c2ecf20Sopenharmony_ci
898c2ecf20Sopenharmony_ci/***************************************************************************/
908c2ecf20Sopenharmony_ci
918c2ecf20Sopenharmony_cistatic u8 nettel_macdefault[] __initdata = {
928c2ecf20Sopenharmony_ci	0x00, 0xd0, 0xcf, 0x00, 0x00, 0x01,
938c2ecf20Sopenharmony_ci};
948c2ecf20Sopenharmony_ci
958c2ecf20Sopenharmony_ci/*
968c2ecf20Sopenharmony_ci * Set flash contained MAC address into SMC9196 core. Make sure the flash
978c2ecf20Sopenharmony_ci * MAC address is sane, and not an empty flash. If no good use the Moreton
988c2ecf20Sopenharmony_ci * Bay default MAC address instead.
998c2ecf20Sopenharmony_ci */
1008c2ecf20Sopenharmony_ci
1018c2ecf20Sopenharmony_cistatic void __init nettel_smc91x_setmac(unsigned int ioaddr, unsigned int flashaddr)
1028c2ecf20Sopenharmony_ci{
1038c2ecf20Sopenharmony_ci	u16 *macp;
1048c2ecf20Sopenharmony_ci
1058c2ecf20Sopenharmony_ci	macp = (u16 *) flashaddr;
1068c2ecf20Sopenharmony_ci	if ((macp[0] == 0xffff) && (macp[1] == 0xffff) && (macp[2] == 0xffff))
1078c2ecf20Sopenharmony_ci		macp = (u16 *) &nettel_macdefault[0];
1088c2ecf20Sopenharmony_ci
1098c2ecf20Sopenharmony_ci	writew(1, NETTEL_SMC0_ADDR + SMC91xx_BANKSELECT);
1108c2ecf20Sopenharmony_ci	writew(macp[0], ioaddr + SMC91xx_BASEMAC);
1118c2ecf20Sopenharmony_ci	writew(macp[1], ioaddr + SMC91xx_BASEMAC + 2);
1128c2ecf20Sopenharmony_ci	writew(macp[2], ioaddr + SMC91xx_BASEMAC + 4);
1138c2ecf20Sopenharmony_ci}
1148c2ecf20Sopenharmony_ci
1158c2ecf20Sopenharmony_ci/***************************************************************************/
1168c2ecf20Sopenharmony_ci
1178c2ecf20Sopenharmony_ci/*
1188c2ecf20Sopenharmony_ci * Re-map the address space of at least one of the SMC ethernet
1198c2ecf20Sopenharmony_ci * parts. Both parts power up decoding the same address, so we
1208c2ecf20Sopenharmony_ci * need to move one of them first, before doing anything else.
1218c2ecf20Sopenharmony_ci */
1228c2ecf20Sopenharmony_ci
1238c2ecf20Sopenharmony_cistatic void __init nettel_smc91x_init(void)
1248c2ecf20Sopenharmony_ci{
1258c2ecf20Sopenharmony_ci	writew(0x00ec, MCFSIM_PADDR);
1268c2ecf20Sopenharmony_ci	mcf_setppdata(0, 0x0080);
1278c2ecf20Sopenharmony_ci	writew(1, NETTEL_SMC0_ADDR + SMC91xx_BANKSELECT);
1288c2ecf20Sopenharmony_ci	writew(0x0067, NETTEL_SMC0_ADDR + SMC91xx_BASEADDR);
1298c2ecf20Sopenharmony_ci	mcf_setppdata(0x0080, 0);
1308c2ecf20Sopenharmony_ci
1318c2ecf20Sopenharmony_ci	/* Set correct chip select timing for SMC9196 accesses */
1328c2ecf20Sopenharmony_ci	writew(0x1180, MCFSIM_CSCR3);
1338c2ecf20Sopenharmony_ci
1348c2ecf20Sopenharmony_ci	/* Set the SMC interrupts to be auto-vectored */
1358c2ecf20Sopenharmony_ci	mcf_autovector(NETTEL_SMC0_IRQ);
1368c2ecf20Sopenharmony_ci	mcf_autovector(NETTEL_SMC1_IRQ);
1378c2ecf20Sopenharmony_ci
1388c2ecf20Sopenharmony_ci	/* Set MAC addresses from flash for both interfaces */
1398c2ecf20Sopenharmony_ci	nettel_smc91x_setmac(NETTEL_SMC0_ADDR, 0xf0006000);
1408c2ecf20Sopenharmony_ci	nettel_smc91x_setmac(NETTEL_SMC1_ADDR, 0xf0006006);
1418c2ecf20Sopenharmony_ci}
1428c2ecf20Sopenharmony_ci
1438c2ecf20Sopenharmony_ci/***************************************************************************/
1448c2ecf20Sopenharmony_ci
1458c2ecf20Sopenharmony_cistatic int __init init_nettel(void)
1468c2ecf20Sopenharmony_ci{
1478c2ecf20Sopenharmony_ci	nettel_smc91x_init();
1488c2ecf20Sopenharmony_ci	platform_add_devices(nettel_devices, ARRAY_SIZE(nettel_devices));
1498c2ecf20Sopenharmony_ci	return 0;
1508c2ecf20Sopenharmony_ci}
1518c2ecf20Sopenharmony_ci
1528c2ecf20Sopenharmony_ciarch_initcall(init_nettel);
1538c2ecf20Sopenharmony_ci
1548c2ecf20Sopenharmony_ci/***************************************************************************/
155