mirror of https://github.com/Qortal/Brooklyn
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
201 lines
5.1 KiB
201 lines
5.1 KiB
// SPDX-License-Identifier: GPL-2.0 |
|
/* |
|
* Copyright (C) 2005 Sven Luther <[email protected]> |
|
* Thanks to : |
|
* Dale Farnsworth <[email protected]> |
|
* Mark A. Greer <[email protected]> |
|
* Nicolas DET <[email protected]> |
|
* Benjamin Herrenschmidt <[email protected]> |
|
* And anyone else who helped me on this. |
|
*/ |
|
|
|
#include <linux/types.h> |
|
#include <linux/init.h> |
|
#include <linux/ioport.h> |
|
#include <linux/device.h> |
|
#include <linux/platform_device.h> |
|
#include <linux/mv643xx.h> |
|
#include <linux/pci.h> |
|
|
|
#define PEGASOS2_MARVELL_REGBASE (0xf1000000) |
|
#define PEGASOS2_MARVELL_REGSIZE (0x00004000) |
|
#define PEGASOS2_SRAM_BASE (0xf2000000) |
|
#define PEGASOS2_SRAM_SIZE (256*1024) |
|
|
|
#define PEGASOS2_SRAM_BASE_ETH_PORT0 (PEGASOS2_SRAM_BASE) |
|
#define PEGASOS2_SRAM_BASE_ETH_PORT1 (PEGASOS2_SRAM_BASE_ETH_PORT0 + (PEGASOS2_SRAM_SIZE / 2) ) |
|
|
|
|
|
#define PEGASOS2_SRAM_RXRING_SIZE (PEGASOS2_SRAM_SIZE/4) |
|
#define PEGASOS2_SRAM_TXRING_SIZE (PEGASOS2_SRAM_SIZE/4) |
|
|
|
#undef BE_VERBOSE |
|
|
|
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, |
|
}; |
|
|
|
/* |
|
* The orion mdio driver only covers shared + 0x4 up to shared + 0x84 - 1 |
|
*/ |
|
static struct resource mv643xx_eth_mvmdio_resources[] = { |
|
[0] = { |
|
.name = "ethernet mdio base", |
|
.start = 0xf1000000 + MV643XX_ETH_SHARED_REGS + 0x4, |
|
.end = 0xf1000000 + MV643XX_ETH_SHARED_REGS + 0x83, |
|
.flags = IORESOURCE_MEM, |
|
}, |
|
}; |
|
|
|
static struct platform_device mv643xx_eth_mvmdio_device = { |
|
.name = "orion-mdio", |
|
.id = -1, |
|
.num_resources = ARRAY_SIZE(mv643xx_eth_mvmdio_resources), |
|
.resource = mv643xx_eth_mvmdio_resources, |
|
}; |
|
|
|
static struct resource mv643xx_eth_port1_resources[] = { |
|
[0] = { |
|
.name = "eth port1 irq", |
|
.start = 9, |
|
.end = 9, |
|
.flags = IORESOURCE_IRQ, |
|
}, |
|
}; |
|
|
|
static struct mv643xx_eth_platform_data eth_port1_pd = { |
|
.shared = &mv643xx_eth_shared_device, |
|
.port_number = 1, |
|
.phy_addr = MV643XX_ETH_PHY_ADDR(7), |
|
|
|
.tx_sram_addr = PEGASOS2_SRAM_BASE_ETH_PORT1, |
|
.tx_sram_size = PEGASOS2_SRAM_TXRING_SIZE, |
|
.tx_queue_size = PEGASOS2_SRAM_TXRING_SIZE/16, |
|
|
|
.rx_sram_addr = PEGASOS2_SRAM_BASE_ETH_PORT1 + PEGASOS2_SRAM_TXRING_SIZE, |
|
.rx_sram_size = PEGASOS2_SRAM_RXRING_SIZE, |
|
.rx_queue_size = PEGASOS2_SRAM_RXRING_SIZE/16, |
|
}; |
|
|
|
static struct platform_device eth_port1_device = { |
|
.name = MV643XX_ETH_NAME, |
|
.id = 1, |
|
.num_resources = ARRAY_SIZE(mv643xx_eth_port1_resources), |
|
.resource = mv643xx_eth_port1_resources, |
|
.dev = { |
|
.platform_data = ð_port1_pd, |
|
}, |
|
}; |
|
|
|
static struct platform_device *mv643xx_eth_pd_devs[] __initdata = { |
|
&mv643xx_eth_shared_device, |
|
&mv643xx_eth_mvmdio_device, |
|
ð_port1_device, |
|
}; |
|
|
|
/***********/ |
|
/***********/ |
|
#define MV_READ(offset,val) { val = readl(mv643xx_reg_base + offset); } |
|
#define MV_WRITE(offset,data) writel(data, mv643xx_reg_base + offset) |
|
|
|
static void __iomem *mv643xx_reg_base; |
|
|
|
static int Enable_SRAM(void) |
|
{ |
|
u32 ALong; |
|
|
|
if (mv643xx_reg_base == NULL) |
|
mv643xx_reg_base = ioremap(PEGASOS2_MARVELL_REGBASE, |
|
PEGASOS2_MARVELL_REGSIZE); |
|
|
|
if (mv643xx_reg_base == NULL) |
|
return -ENOMEM; |
|
|
|
#ifdef BE_VERBOSE |
|
printk("Pegasos II/Marvell MV64361: register remapped from %p to %p\n", |
|
(void *)PEGASOS2_MARVELL_REGBASE, (void *)mv643xx_reg_base); |
|
#endif |
|
|
|
MV_WRITE(MV64340_SRAM_CONFIG, 0); |
|
|
|
MV_WRITE(MV64340_INTEGRATED_SRAM_BASE_ADDR, PEGASOS2_SRAM_BASE >> 16); |
|
|
|
MV_READ(MV64340_BASE_ADDR_ENABLE, ALong); |
|
ALong &= ~(1 << 19); |
|
MV_WRITE(MV64340_BASE_ADDR_ENABLE, ALong); |
|
|
|
ALong = 0x02; |
|
ALong |= PEGASOS2_SRAM_BASE & 0xffff0000; |
|
MV_WRITE(MV643XX_ETH_BAR_4, ALong); |
|
|
|
MV_WRITE(MV643XX_ETH_SIZE_REG_4, (PEGASOS2_SRAM_SIZE-1) & 0xffff0000); |
|
|
|
MV_READ(MV643XX_ETH_BASE_ADDR_ENABLE_REG, ALong); |
|
ALong &= ~(1 << 4); |
|
MV_WRITE(MV643XX_ETH_BASE_ADDR_ENABLE_REG, ALong); |
|
|
|
#ifdef BE_VERBOSE |
|
printk("Pegasos II/Marvell MV64361: register unmapped\n"); |
|
printk("Pegasos II/Marvell MV64361: SRAM at %p, size=%x\n", (void*) PEGASOS2_SRAM_BASE, PEGASOS2_SRAM_SIZE); |
|
#endif |
|
|
|
iounmap(mv643xx_reg_base); |
|
mv643xx_reg_base = NULL; |
|
|
|
return 1; |
|
} |
|
|
|
|
|
/***********/ |
|
/***********/ |
|
static int __init mv643xx_eth_add_pds(void) |
|
{ |
|
int ret = 0; |
|
static struct pci_device_id pci_marvell_mv64360[] = { |
|
{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL, PCI_DEVICE_ID_MARVELL_MV64360) }, |
|
{ } |
|
}; |
|
|
|
#ifdef BE_VERBOSE |
|
printk("Pegasos II/Marvell MV64361: init\n"); |
|
#endif |
|
|
|
if (pci_dev_present(pci_marvell_mv64360)) { |
|
ret = platform_add_devices(mv643xx_eth_pd_devs, |
|
ARRAY_SIZE(mv643xx_eth_pd_devs)); |
|
|
|
if ( Enable_SRAM() < 0) |
|
{ |
|
eth_port1_pd.tx_sram_addr = 0; |
|
eth_port1_pd.tx_sram_size = 0; |
|
eth_port1_pd.rx_sram_addr = 0; |
|
eth_port1_pd.rx_sram_size = 0; |
|
|
|
#ifdef BE_VERBOSE |
|
printk("Pegasos II/Marvell MV64361: Can't enable the " |
|
"SRAM\n"); |
|
#endif |
|
} |
|
} |
|
|
|
#ifdef BE_VERBOSE |
|
printk("Pegasos II/Marvell MV64361: init is over\n"); |
|
#endif |
|
|
|
return ret; |
|
} |
|
|
|
device_initcall(mv643xx_eth_add_pds);
|
|
|