162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0 262306a36Sopenharmony_ci/***************************************************************************/ 362306a36Sopenharmony_ci 462306a36Sopenharmony_ci/* 562306a36Sopenharmony_ci * nettel.c -- startup code support for the NETtel boards 662306a36Sopenharmony_ci * 762306a36Sopenharmony_ci * Copyright (C) 2009, Greg Ungerer (gerg@snapgear.com) 862306a36Sopenharmony_ci */ 962306a36Sopenharmony_ci 1062306a36Sopenharmony_ci/***************************************************************************/ 1162306a36Sopenharmony_ci 1262306a36Sopenharmony_ci#include <linux/kernel.h> 1362306a36Sopenharmony_ci#include <linux/param.h> 1462306a36Sopenharmony_ci#include <linux/init.h> 1562306a36Sopenharmony_ci#include <linux/io.h> 1662306a36Sopenharmony_ci#include <linux/platform_device.h> 1762306a36Sopenharmony_ci#include <asm/coldfire.h> 1862306a36Sopenharmony_ci#include <asm/mcfsim.h> 1962306a36Sopenharmony_ci#include <asm/nettel.h> 2062306a36Sopenharmony_ci 2162306a36Sopenharmony_ci/***************************************************************************/ 2262306a36Sopenharmony_ci 2362306a36Sopenharmony_ci/* 2462306a36Sopenharmony_ci * Define the IO and interrupt resources of the 2 SMC9196 interfaces. 2562306a36Sopenharmony_ci */ 2662306a36Sopenharmony_ci#define NETTEL_SMC0_ADDR 0x30600300 2762306a36Sopenharmony_ci#define NETTEL_SMC0_IRQ 29 2862306a36Sopenharmony_ci 2962306a36Sopenharmony_ci#define NETTEL_SMC1_ADDR 0x30600000 3062306a36Sopenharmony_ci#define NETTEL_SMC1_IRQ 27 3162306a36Sopenharmony_ci 3262306a36Sopenharmony_ci/* 3362306a36Sopenharmony_ci * We need some access into the SMC9196 registers. Define those registers 3462306a36Sopenharmony_ci * we will need here (including the smc91x.h doesn't seem to give us these 3562306a36Sopenharmony_ci * in a simple form). 3662306a36Sopenharmony_ci */ 3762306a36Sopenharmony_ci#define SMC91xx_BANKSELECT 14 3862306a36Sopenharmony_ci#define SMC91xx_BASEADDR 2 3962306a36Sopenharmony_ci#define SMC91xx_BASEMAC 4 4062306a36Sopenharmony_ci 4162306a36Sopenharmony_ci/***************************************************************************/ 4262306a36Sopenharmony_ci 4362306a36Sopenharmony_cistatic struct resource nettel_smc91x_0_resources[] = { 4462306a36Sopenharmony_ci { 4562306a36Sopenharmony_ci .start = NETTEL_SMC0_ADDR, 4662306a36Sopenharmony_ci .end = NETTEL_SMC0_ADDR + 0x20, 4762306a36Sopenharmony_ci .flags = IORESOURCE_MEM, 4862306a36Sopenharmony_ci }, 4962306a36Sopenharmony_ci { 5062306a36Sopenharmony_ci .start = NETTEL_SMC0_IRQ, 5162306a36Sopenharmony_ci .end = NETTEL_SMC0_IRQ, 5262306a36Sopenharmony_ci .flags = IORESOURCE_IRQ, 5362306a36Sopenharmony_ci }, 5462306a36Sopenharmony_ci}; 5562306a36Sopenharmony_ci 5662306a36Sopenharmony_cistatic struct resource nettel_smc91x_1_resources[] = { 5762306a36Sopenharmony_ci { 5862306a36Sopenharmony_ci .start = NETTEL_SMC1_ADDR, 5962306a36Sopenharmony_ci .end = NETTEL_SMC1_ADDR + 0x20, 6062306a36Sopenharmony_ci .flags = IORESOURCE_MEM, 6162306a36Sopenharmony_ci }, 6262306a36Sopenharmony_ci { 6362306a36Sopenharmony_ci .start = NETTEL_SMC1_IRQ, 6462306a36Sopenharmony_ci .end = NETTEL_SMC1_IRQ, 6562306a36Sopenharmony_ci .flags = IORESOURCE_IRQ, 6662306a36Sopenharmony_ci }, 6762306a36Sopenharmony_ci}; 6862306a36Sopenharmony_ci 6962306a36Sopenharmony_cistatic struct platform_device nettel_smc91x[] = { 7062306a36Sopenharmony_ci { 7162306a36Sopenharmony_ci .name = "smc91x", 7262306a36Sopenharmony_ci .id = 0, 7362306a36Sopenharmony_ci .num_resources = ARRAY_SIZE(nettel_smc91x_0_resources), 7462306a36Sopenharmony_ci .resource = nettel_smc91x_0_resources, 7562306a36Sopenharmony_ci }, 7662306a36Sopenharmony_ci { 7762306a36Sopenharmony_ci .name = "smc91x", 7862306a36Sopenharmony_ci .id = 1, 7962306a36Sopenharmony_ci .num_resources = ARRAY_SIZE(nettel_smc91x_1_resources), 8062306a36Sopenharmony_ci .resource = nettel_smc91x_1_resources, 8162306a36Sopenharmony_ci }, 8262306a36Sopenharmony_ci}; 8362306a36Sopenharmony_ci 8462306a36Sopenharmony_cistatic struct platform_device *nettel_devices[] __initdata = { 8562306a36Sopenharmony_ci &nettel_smc91x[0], 8662306a36Sopenharmony_ci &nettel_smc91x[1], 8762306a36Sopenharmony_ci}; 8862306a36Sopenharmony_ci 8962306a36Sopenharmony_ci/***************************************************************************/ 9062306a36Sopenharmony_ci 9162306a36Sopenharmony_cistatic u8 nettel_macdefault[] __initdata = { 9262306a36Sopenharmony_ci 0x00, 0xd0, 0xcf, 0x00, 0x00, 0x01, 9362306a36Sopenharmony_ci}; 9462306a36Sopenharmony_ci 9562306a36Sopenharmony_ci/* 9662306a36Sopenharmony_ci * Set flash contained MAC address into SMC9196 core. Make sure the flash 9762306a36Sopenharmony_ci * MAC address is sane, and not an empty flash. If no good use the Moreton 9862306a36Sopenharmony_ci * Bay default MAC address instead. 9962306a36Sopenharmony_ci */ 10062306a36Sopenharmony_ci 10162306a36Sopenharmony_cistatic void __init nettel_smc91x_setmac(unsigned int ioaddr, unsigned int flashaddr) 10262306a36Sopenharmony_ci{ 10362306a36Sopenharmony_ci u16 *macp; 10462306a36Sopenharmony_ci 10562306a36Sopenharmony_ci macp = (u16 *) flashaddr; 10662306a36Sopenharmony_ci if ((macp[0] == 0xffff) && (macp[1] == 0xffff) && (macp[2] == 0xffff)) 10762306a36Sopenharmony_ci macp = (u16 *) &nettel_macdefault[0]; 10862306a36Sopenharmony_ci 10962306a36Sopenharmony_ci writew(1, NETTEL_SMC0_ADDR + SMC91xx_BANKSELECT); 11062306a36Sopenharmony_ci writew(macp[0], ioaddr + SMC91xx_BASEMAC); 11162306a36Sopenharmony_ci writew(macp[1], ioaddr + SMC91xx_BASEMAC + 2); 11262306a36Sopenharmony_ci writew(macp[2], ioaddr + SMC91xx_BASEMAC + 4); 11362306a36Sopenharmony_ci} 11462306a36Sopenharmony_ci 11562306a36Sopenharmony_ci/***************************************************************************/ 11662306a36Sopenharmony_ci 11762306a36Sopenharmony_ci/* 11862306a36Sopenharmony_ci * Re-map the address space of at least one of the SMC ethernet 11962306a36Sopenharmony_ci * parts. Both parts power up decoding the same address, so we 12062306a36Sopenharmony_ci * need to move one of them first, before doing anything else. 12162306a36Sopenharmony_ci */ 12262306a36Sopenharmony_ci 12362306a36Sopenharmony_cistatic void __init nettel_smc91x_init(void) 12462306a36Sopenharmony_ci{ 12562306a36Sopenharmony_ci writew(0x00ec, MCFSIM_PADDR); 12662306a36Sopenharmony_ci mcf_setppdata(0, 0x0080); 12762306a36Sopenharmony_ci writew(1, NETTEL_SMC0_ADDR + SMC91xx_BANKSELECT); 12862306a36Sopenharmony_ci writew(0x0067, NETTEL_SMC0_ADDR + SMC91xx_BASEADDR); 12962306a36Sopenharmony_ci mcf_setppdata(0x0080, 0); 13062306a36Sopenharmony_ci 13162306a36Sopenharmony_ci /* Set correct chip select timing for SMC9196 accesses */ 13262306a36Sopenharmony_ci writew(0x1180, MCFSIM_CSCR3); 13362306a36Sopenharmony_ci 13462306a36Sopenharmony_ci /* Set the SMC interrupts to be auto-vectored */ 13562306a36Sopenharmony_ci mcf_autovector(NETTEL_SMC0_IRQ); 13662306a36Sopenharmony_ci mcf_autovector(NETTEL_SMC1_IRQ); 13762306a36Sopenharmony_ci 13862306a36Sopenharmony_ci /* Set MAC addresses from flash for both interfaces */ 13962306a36Sopenharmony_ci nettel_smc91x_setmac(NETTEL_SMC0_ADDR, 0xf0006000); 14062306a36Sopenharmony_ci nettel_smc91x_setmac(NETTEL_SMC1_ADDR, 0xf0006006); 14162306a36Sopenharmony_ci} 14262306a36Sopenharmony_ci 14362306a36Sopenharmony_ci/***************************************************************************/ 14462306a36Sopenharmony_ci 14562306a36Sopenharmony_cistatic int __init init_nettel(void) 14662306a36Sopenharmony_ci{ 14762306a36Sopenharmony_ci nettel_smc91x_init(); 14862306a36Sopenharmony_ci platform_add_devices(nettel_devices, ARRAY_SIZE(nettel_devices)); 14962306a36Sopenharmony_ci return 0; 15062306a36Sopenharmony_ci} 15162306a36Sopenharmony_ci 15262306a36Sopenharmony_ciarch_initcall(init_nettel); 15362306a36Sopenharmony_ci 15462306a36Sopenharmony_ci/***************************************************************************/ 155