mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-25 21:24:08 +08:00
[MIPS] Ocelot 3: Fix MAC address detection after platform_device conversion.
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
This commit is contained in:
parent
907c51b2d1
commit
ff28cbd280
@ -5,4 +5,4 @@
|
||||
# removes any old dependencies. DON'T put your own dependencies here
|
||||
# unless it's something special (ie not a .c file).
|
||||
#
|
||||
obj-y += irq.o prom.o reset.o setup.o
|
||||
obj-y += irq.o platform.o prom.o reset.o setup.o
|
||||
|
235
arch/mips/momentum/ocelot_3/platform.c
Normal file
235
arch/mips/momentum/ocelot_3/platform.c
Normal file
@ -0,0 +1,235 @@
|
||||
#include <linux/delay.h>
|
||||
#include <linux/if_ether.h>
|
||||
#include <linux/ioport.h>
|
||||
#include <linux/mv643xx.h>
|
||||
#include <linux/platform_device.h>
|
||||
|
||||
#include "ocelot_3_fpga.h"
|
||||
|
||||
#if defined(CONFIG_MV643XX_ETH) || defined(CONFIG_MV643XX_ETH_MODULE)
|
||||
|
||||
static struct resource mv643xx_eth_shared_resources[] = {
|
||||
[0] = {
|
||||
.name = "ethernet shared base",
|
||||
.start = 0xf1000000 + MV643XX_ETH_SHARED_REGS,
|
||||
.end = 0xf1000000 + MV643XX_ETH_SHARED_REGS +
|
||||
MV643XX_ETH_SHARED_REGS_SIZE - 1,
|
||||
.flags = IORESOURCE_MEM,
|
||||
},
|
||||
};
|
||||
|
||||
static struct platform_device mv643xx_eth_shared_device = {
|
||||
.name = MV643XX_ETH_SHARED_NAME,
|
||||
.id = 0,
|
||||
.num_resources = ARRAY_SIZE(mv643xx_eth_shared_resources),
|
||||
.resource = mv643xx_eth_shared_resources,
|
||||
};
|
||||
|
||||
#define MV_SRAM_BASE 0xfe000000UL
|
||||
#define MV_SRAM_SIZE (256 * 1024)
|
||||
|
||||
#define MV_SRAM_RXRING_SIZE (MV_SRAM_SIZE / 4)
|
||||
#define MV_SRAM_TXRING_SIZE (MV_SRAM_SIZE / 4)
|
||||
|
||||
#define MV_SRAM_BASE_ETH0 MV_SRAM_BASE
|
||||
#define MV_SRAM_BASE_ETH1 (MV_SRAM_BASE + (MV_SRAM_SIZE / 2))
|
||||
|
||||
#define MV64x60_IRQ_ETH_0 48
|
||||
#define MV64x60_IRQ_ETH_1 49
|
||||
#define MV64x60_IRQ_ETH_2 50
|
||||
|
||||
#ifdef CONFIG_MV643XX_ETH_0
|
||||
|
||||
static struct resource mv64x60_eth0_resources[] = {
|
||||
[0] = {
|
||||
.name = "eth0 irq",
|
||||
.start = MV64x60_IRQ_ETH_0,
|
||||
.end = MV64x60_IRQ_ETH_0,
|
||||
.flags = IORESOURCE_IRQ,
|
||||
},
|
||||
};
|
||||
|
||||
static char eth0_mac_addr[ETH_ALEN];
|
||||
|
||||
static struct mv643xx_eth_platform_data eth0_pd = {
|
||||
.mac_addr = eth0_mac_addr,
|
||||
|
||||
.tx_sram_addr = MV_SRAM_BASE_ETH0,
|
||||
.tx_sram_size = MV_SRAM_TXRING_SIZE,
|
||||
.tx_queue_size = MV_SRAM_TXRING_SIZE / 16,
|
||||
|
||||
.rx_sram_addr = MV_SRAM_BASE_ETH0 + MV_SRAM_TXRING_SIZE,
|
||||
.rx_sram_size = MV_SRAM_RXRING_SIZE,
|
||||
.rx_queue_size = MV_SRAM_RXRING_SIZE / 16,
|
||||
};
|
||||
|
||||
static struct platform_device eth0_device = {
|
||||
.name = MV643XX_ETH_NAME,
|
||||
.id = 0,
|
||||
.num_resources = ARRAY_SIZE(mv64x60_eth0_resources),
|
||||
.resource = mv64x60_eth0_resources,
|
||||
.dev = {
|
||||
.platform_data = ð0_pd,
|
||||
},
|
||||
};
|
||||
#endif /* CONFIG_MV643XX_ETH_0 */
|
||||
|
||||
#ifdef CONFIG_MV643XX_ETH_1
|
||||
|
||||
static struct resource mv64x60_eth1_resources[] = {
|
||||
[0] = {
|
||||
.name = "eth1 irq",
|
||||
.start = MV64x60_IRQ_ETH_1,
|
||||
.end = MV64x60_IRQ_ETH_1,
|
||||
.flags = IORESOURCE_IRQ,
|
||||
},
|
||||
};
|
||||
|
||||
static char eth1_mac_addr[ETH_ALEN];
|
||||
|
||||
static struct mv643xx_eth_platform_data eth1_pd = {
|
||||
.mac_addr = eth1_mac_addr,
|
||||
|
||||
.tx_sram_addr = MV_SRAM_BASE_ETH1,
|
||||
.tx_sram_size = MV_SRAM_TXRING_SIZE,
|
||||
.tx_queue_size = MV_SRAM_TXRING_SIZE / 16,
|
||||
|
||||
.rx_sram_addr = MV_SRAM_BASE_ETH1 + MV_SRAM_TXRING_SIZE,
|
||||
.rx_sram_size = MV_SRAM_RXRING_SIZE,
|
||||
.rx_queue_size = MV_SRAM_RXRING_SIZE / 16,
|
||||
};
|
||||
|
||||
static struct platform_device eth1_device = {
|
||||
.name = MV643XX_ETH_NAME,
|
||||
.id = 1,
|
||||
.num_resources = ARRAY_SIZE(mv64x60_eth1_resources),
|
||||
.resource = mv64x60_eth1_resources,
|
||||
.dev = {
|
||||
.platform_data = ð1_pd,
|
||||
},
|
||||
};
|
||||
#endif /* CONFIG_MV643XX_ETH_1 */
|
||||
|
||||
#ifdef CONFIG_MV643XX_ETH_2
|
||||
|
||||
static struct resource mv64x60_eth2_resources[] = {
|
||||
[0] = {
|
||||
.name = "eth2 irq",
|
||||
.start = MV64x60_IRQ_ETH_2,
|
||||
.end = MV64x60_IRQ_ETH_2,
|
||||
.flags = IORESOURCE_IRQ,
|
||||
},
|
||||
};
|
||||
|
||||
static char eth2_mac_addr[ETH_ALEN];
|
||||
|
||||
static struct mv643xx_eth_platform_data eth2_pd = {
|
||||
.mac_addr = eth2_mac_addr,
|
||||
};
|
||||
|
||||
static struct platform_device eth2_device = {
|
||||
.name = MV643XX_ETH_NAME,
|
||||
.id = 1,
|
||||
.num_resources = ARRAY_SIZE(mv64x60_eth2_resources),
|
||||
.resource = mv64x60_eth2_resources,
|
||||
.dev = {
|
||||
.platform_data = ð2_pd,
|
||||
},
|
||||
};
|
||||
#endif /* CONFIG_MV643XX_ETH_2 */
|
||||
|
||||
static struct platform_device *mv643xx_eth_pd_devs[] __initdata = {
|
||||
&mv643xx_eth_shared_device,
|
||||
#ifdef CONFIG_MV643XX_ETH_0
|
||||
ð0_device,
|
||||
#endif
|
||||
#ifdef CONFIG_MV643XX_ETH_1
|
||||
ð1_device,
|
||||
#endif
|
||||
#ifdef CONFIG_MV643XX_ETH_2
|
||||
ð2_device,
|
||||
#endif
|
||||
};
|
||||
|
||||
static u8 __init exchange_bit(u8 val, u8 cs)
|
||||
{
|
||||
/* place the data */
|
||||
OCELOT_FPGA_WRITE((val << 2) | cs, EEPROM_MODE);
|
||||
udelay(1);
|
||||
|
||||
/* turn the clock on */
|
||||
OCELOT_FPGA_WRITE((val << 2) | cs | 0x2, EEPROM_MODE);
|
||||
udelay(1);
|
||||
|
||||
/* turn the clock off and read-strobe */
|
||||
OCELOT_FPGA_WRITE((val << 2) | cs | 0x10, EEPROM_MODE);
|
||||
|
||||
/* return the data */
|
||||
return (OCELOT_FPGA_READ(EEPROM_MODE) >> 3) & 0x1;
|
||||
}
|
||||
|
||||
static void __init get_mac(char dest[6])
|
||||
{
|
||||
u8 read_opcode[12] = {1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
|
||||
int i,j;
|
||||
|
||||
for (i = 0; i < 12; i++)
|
||||
exchange_bit(read_opcode[i], 1);
|
||||
|
||||
for (j = 0; j < 6; j++) {
|
||||
dest[j] = 0;
|
||||
for (i = 0; i < 8; i++) {
|
||||
dest[j] <<= 1;
|
||||
dest[j] |= exchange_bit(0, 1);
|
||||
}
|
||||
}
|
||||
|
||||
/* turn off CS */
|
||||
exchange_bit(0,0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Copy and increment ethernet MAC address by a small value.
|
||||
*
|
||||
* This is useful for systems where the only one MAC address is stored in
|
||||
* non-volatile memory for multiple ports.
|
||||
*/
|
||||
static inline void eth_mac_add(unsigned char *dst, unsigned char *src,
|
||||
unsigned int add)
|
||||
{
|
||||
int i;
|
||||
|
||||
BUG_ON(add >= 256);
|
||||
|
||||
for (i = ETH_ALEN; i >= 0; i--) {
|
||||
dst[i] = src[i] + add;
|
||||
add = dst[i] < src[i]; /* compute carry */
|
||||
}
|
||||
|
||||
WARN_ON(add);
|
||||
}
|
||||
|
||||
static int __init mv643xx_eth_add_pds(void)
|
||||
{
|
||||
unsigned char mac[ETH_ALEN];
|
||||
int ret;
|
||||
|
||||
get_mac(mac);
|
||||
#ifdef CONFIG_MV643XX_ETH_0
|
||||
eth_mac_add(eth1_mac_addr, mac, 0);
|
||||
#endif
|
||||
#ifdef CONFIG_MV643XX_ETH_1
|
||||
eth_mac_add(eth1_mac_addr, mac, 1);
|
||||
#endif
|
||||
#ifdef CONFIG_MV643XX_ETH_2
|
||||
eth_mac_add(eth2_mac_addr, mac, 2);
|
||||
#endif
|
||||
ret = platform_add_devices(mv643xx_eth_pd_devs,
|
||||
ARRAY_SIZE(mv643xx_eth_pd_devs));
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
device_initcall(mv643xx_eth_add_pds);
|
||||
|
||||
#endif /* defined(CONFIG_MV643XX_ETH) || defined(CONFIG_MV643XX_ETH_MODULE) */
|
@ -34,64 +34,11 @@ struct callvectors* debug_vectors;
|
||||
extern unsigned long marvell_base;
|
||||
extern unsigned long cpu_clock;
|
||||
|
||||
#ifdef CONFIG_MV643XX_ETH
|
||||
extern unsigned char prom_mac_addr_base[6];
|
||||
#endif
|
||||
|
||||
const char *get_system_type(void)
|
||||
{
|
||||
return "Momentum Ocelot-3";
|
||||
}
|
||||
|
||||
#ifdef CONFIG_MV643XX_ETH
|
||||
void burn_clocks(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
/* this loop should burn at least 1us -- this should be plenty */
|
||||
for (i = 0; i < 0x10000; i++)
|
||||
;
|
||||
}
|
||||
|
||||
u8 exchange_bit(u8 val, u8 cs)
|
||||
{
|
||||
/* place the data */
|
||||
OCELOT_FPGA_WRITE((val << 2) | cs, EEPROM_MODE);
|
||||
burn_clocks();
|
||||
|
||||
/* turn the clock on */
|
||||
OCELOT_FPGA_WRITE((val << 2) | cs | 0x2, EEPROM_MODE);
|
||||
burn_clocks();
|
||||
|
||||
/* turn the clock off and read-strobe */
|
||||
OCELOT_FPGA_WRITE((val << 2) | cs | 0x10, EEPROM_MODE);
|
||||
|
||||
/* return the data */
|
||||
return ((OCELOT_FPGA_READ(EEPROM_MODE) >> 3) & 0x1);
|
||||
}
|
||||
|
||||
void get_mac(char dest[6])
|
||||
{
|
||||
u8 read_opcode[12] = {1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
|
||||
int i,j;
|
||||
|
||||
for (i = 0; i < 12; i++)
|
||||
exchange_bit(read_opcode[i], 1);
|
||||
|
||||
for (j = 0; j < 6; j++) {
|
||||
dest[j] = 0;
|
||||
for (i = 0; i < 8; i++) {
|
||||
dest[j] <<= 1;
|
||||
dest[j] |= exchange_bit(0, 1);
|
||||
}
|
||||
}
|
||||
|
||||
/* turn off CS */
|
||||
exchange_bit(0,0);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef CONFIG_64BIT
|
||||
|
||||
unsigned long signext(unsigned long addr)
|
||||
@ -228,11 +175,6 @@ void __init prom_init(void)
|
||||
mips_machgroup = MACH_GROUP_MOMENCO;
|
||||
mips_machtype = MACH_MOMENCO_OCELOT_3;
|
||||
|
||||
#ifdef CONFIG_MV643XX_ETH
|
||||
/* get the base MAC address for on-board ethernet ports */
|
||||
get_mac(prom_mac_addr_base);
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_64BIT
|
||||
debug_vectors->printf("Booting Linux kernel...\n");
|
||||
#endif
|
||||
|
@ -4,7 +4,7 @@
|
||||
* BRIEF MODULE DESCRIPTION
|
||||
* Momentum Computer Ocelot-3 board dependent boot routines
|
||||
*
|
||||
* Copyright (C) 1996, 1997, 01, 05 Ralf Baechle
|
||||
* Copyright (C) 1996, 1997, 01, 05 - 06 Ralf Baechle
|
||||
* Copyright (C) 2000 RidgeRun, Inc.
|
||||
* Copyright (C) 2001 Red Hat, Inc.
|
||||
* Copyright (C) 2002 Momentum Computer
|
||||
|
Loading…
Reference in New Issue
Block a user