pegasos_eth.c 4.52 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14
/*
 *  Copyright (C) 2005 Sven Luther <sl@bplan-gmbh.de>
 *  Thanks to :
 *	Dale Farnsworth <dale@farnsworth.org>
 *	Mark A. Greer <mgreer@mvista.com>
 *	Nicolas DET <nd@bplan-gmbh.de>
 *	Benjamin Herrenschmidt <benh@kernel.crashing.org>
 *  And anyone else who helped me on this.
 */

#include <linux/types.h>
#include <linux/init.h>
#include <linux/ioport.h>
#include <linux/device.h>
15
#include <linux/platform_device.h>
16 17 18
#include <linux/mv643xx.h>
#include <linux/pci.h>

19 20 21 22 23
#define PEGASOS2_MARVELL_REGBASE 		(0xf1000000)
#define PEGASOS2_MARVELL_REGSIZE 		(0x00004000)
#define PEGASOS2_SRAM_BASE 			(0xf2000000)
#define PEGASOS2_SRAM_SIZE			(256*1024)

24 25
#define PEGASOS2_SRAM_BASE_ETH_PORT0			(PEGASOS2_SRAM_BASE)
#define PEGASOS2_SRAM_BASE_ETH_PORT1			(PEGASOS2_SRAM_BASE_ETH_PORT0 + (PEGASOS2_SRAM_SIZE / 2) )
26 27 28 29 30 31 32


#define PEGASOS2_SRAM_RXRING_SIZE		(PEGASOS2_SRAM_SIZE/4)
#define PEGASOS2_SRAM_TXRING_SIZE		(PEGASOS2_SRAM_SIZE/4)

#undef BE_VERBOSE

33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49
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,
};

50
static struct resource mv643xx_eth_port1_resources[] = {
51
	[0] = {
52
		.name	= "eth port1 irq",
53 54 55 56 57 58
		.start	= 9,
		.end	= 9,
		.flags	= IORESOURCE_IRQ,
	},
};

59
static struct mv643xx_eth_platform_data eth_port1_pd = {
60
	.shared		= &mv643xx_eth_shared_device,
61
	.port_number	= 1,
62
	.phy_addr	= MV643XX_ETH_PHY_ADDR(7),
63

64
	.tx_sram_addr = PEGASOS2_SRAM_BASE_ETH_PORT1,
65 66 67
	.tx_sram_size = PEGASOS2_SRAM_TXRING_SIZE,
	.tx_queue_size = PEGASOS2_SRAM_TXRING_SIZE/16,

68
	.rx_sram_addr = PEGASOS2_SRAM_BASE_ETH_PORT1 + PEGASOS2_SRAM_TXRING_SIZE,
69 70 71
	.rx_sram_size = PEGASOS2_SRAM_RXRING_SIZE,
	.rx_queue_size = PEGASOS2_SRAM_RXRING_SIZE/16,
};
72

73
static struct platform_device eth_port1_device = {
74 75
	.name		= MV643XX_ETH_NAME,
	.id		= 1,
76 77
	.num_resources	= ARRAY_SIZE(mv643xx_eth_port1_resources),
	.resource	= mv643xx_eth_port1_resources,
78
	.dev = {
79
		.platform_data = &eth_port1_pd,
80 81 82 83 84
	},
};

static struct platform_device *mv643xx_eth_pd_devs[] __initdata = {
	&mv643xx_eth_shared_device,
85
	&eth_port1_device,
86 87
};

88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111
/***********/
/***********/
#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);
112

113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142
	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;
}


/***********/
/***********/
143
static int __init mv643xx_eth_add_pds(void)
144 145 146 147 148 149 150
{
	int ret = 0;
	static struct pci_device_id pci_marvell_mv64360[] = {
		{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL, PCI_DEVICE_ID_MARVELL_MV64360) },
		{ }
	};

151 152 153 154
#ifdef BE_VERBOSE
	printk("Pegasos II/Marvell MV64361: init\n");
#endif

155
	if (pci_dev_present(pci_marvell_mv64360)) {
156 157 158 159 160
		ret = platform_add_devices(mv643xx_eth_pd_devs,
				ARRAY_SIZE(mv643xx_eth_pd_devs));

		if ( Enable_SRAM() < 0)
		{
161 162 163 164
			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;
165 166 167 168 169 170

#ifdef BE_VERBOSE
			printk("Pegasos II/Marvell MV64361: Can't enable the "
				"SRAM\n");
#endif
		}
171
	}
172 173 174 175 176

#ifdef BE_VERBOSE
	printk("Pegasos II/Marvell MV64361: init is over\n");
#endif

177 178
	return ret;
}
179

180
device_initcall(mv643xx_eth_add_pds);