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