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