diff options
Diffstat (limited to 'target')
6 files changed, 226 insertions, 175 deletions
diff --git a/target/linux/adm8668/files/arch/mips/adm8668/Makefile b/target/linux/adm8668/files/arch/mips/adm8668/Makefile index aff789c7d..e443f6866 100644 --- a/target/linux/adm8668/files/arch/mips/adm8668/Makefile +++ b/target/linux/adm8668/files/arch/mips/adm8668/Makefile @@ -2,6 +2,6 @@  # something witty  --neutronscott  # -obj-y	 	:= irq.o pci.o prom.o platform.o proc.o \ +obj-y	 	:= irq.o prom.o platform.o proc.o \  		   setup.o clock.o time.o early_printk.o \  		   net_core.o net_intr.o diff --git a/target/linux/adm8668/files/arch/mips/adm8668/pci.c b/target/linux/adm8668/files/arch/mips/adm8668/pci.c deleted file mode 100644 index 2bf119297..000000000 --- a/target/linux/adm8668/files/arch/mips/adm8668/pci.c +++ /dev/null @@ -1,171 +0,0 @@ -/* - * Copyright (C) 2010 Scott Nicholas <neutronscott@scottn.us> - * - * This file is subject to the terms and conditions of the GNU General Public - * License.  See the file "COPYING" in the main directory of this archive - * for more details. - */ - -#include <linux/kernel.h> -#include <linux/init.h> -#include <linux/pci.h> -#include <linux/types.h> -#include <asm/byteorder.h> -#include <asm/pci.h> -#include <adm8668.h> - -volatile u32* pci_config_address_reg = (volatile u32*)KSEG1ADDR(PCICFG_BASE); -volatile u32* pci_config_data_reg = (volatile u32*)KSEG1ADDR(PCIDAT_BASE); - -#define PCI_ENABLE			0x80000000 -#define	ADMPCI_IO_BASE			0x12600000 -#define	ADMPCI_IO_SIZE			0x1fffff -#define	ADMPCI_MEM_BASE			0x16000000 -#define	ADMPCI_MEM_SIZE			0x7ffffff -#define PCI_CMM_IOACC_EN		0x1 -#define PCI_CMM_MEMACC_EN		0x2 -#define PCI_CMM_MASTER_EN		0x4 -#define PCI_CMM_DEF			(PCI_CMM_IOACC_EN | PCI_CMM_MEMACC_EN | PCI_CMM_MASTER_EN) - -#define PCI_DEF_CACHE_LINE_SZ	0 -#define PCI_DEF_LATENCY_TIMER	0x20 -#define PCI_DEF_CACHE_LATENCY	((PCI_DEF_LATENCY_TIMER << 8) | PCI_DEF_CACHE_LINE_SZ) - - -#define cfgaddr(bus, devfn, where)	(	\ -				(bus ? ((bus->number & 0xff) << 0x10) : 0) | \ -					 ((devfn & 0xff) << 0x08) | \ -					 (where & 0xfc)) | PCI_ENABLE - -/* assumed little endian */ -static int adm8668_read_config(struct pci_bus *bus, unsigned int devfn, -				int where, int size, u32 *val) -{ -    	switch (size) -	{ -	case 1: -		*pci_config_address_reg = cfgaddr(bus, devfn, where); -		*val = (le32_to_cpu(*pci_config_data_reg) >> ((where&3)<<3)) & 0xff; -		break; -	case 2: -		if (where & 1) -			return PCIBIOS_BAD_REGISTER_NUMBER; -		*pci_config_address_reg = cfgaddr(bus, devfn, where); -		*val = (le32_to_cpu(*pci_config_data_reg) >> ((where&3)<<3)) & 0xffff; -		break; -	case 4: -		if (where & 3) -			return PCIBIOS_BAD_REGISTER_NUMBER; -		*pci_config_address_reg = cfgaddr(bus, devfn, where); -		*val = le32_to_cpu(*pci_config_data_reg); -		break; -	} - -	return PCIBIOS_SUCCESSFUL; -} - -static int adm8668_write_config(struct pci_bus *bus, unsigned int devfn, -				int where, int size, u32 val) -{ -	switch (size) -	{ -	case 1: -		*pci_config_address_reg = cfgaddr(bus, devfn, where); -		*(volatile u8 *)(((int)pci_config_data_reg) + (where & 3)) = val; -		break; -	case 2: -		if (where & 1) -			return PCIBIOS_BAD_REGISTER_NUMBER; -		*pci_config_address_reg = cfgaddr(bus, devfn, where); -		*(volatile u16 *)(((int)pci_config_data_reg) + (where & 2)) = val; -		break; -	case 4: -		if (where & 3) -			return PCIBIOS_BAD_REGISTER_NUMBER; -		*pci_config_address_reg = cfgaddr(bus, devfn, where); -		*pci_config_data_reg = (val); -	} - -	return PCIBIOS_SUCCESSFUL; -} - - -struct pci_ops adm8668_pci_ops = { -	.read = adm8668_read_config, -	.write = adm8668_write_config -}; - - -struct resource pciioport_resource = { -	.name	= "adm8668_pci", -	.start	= ADMPCI_IO_BASE, -	.end	= ADMPCI_IO_BASE + ADMPCI_IO_SIZE, -	.flags	= IORESOURCE_IO -}; - - -struct resource pciiomem_resource = { -	.name	= "adm8668_pci", -	.start	= ADMPCI_MEM_BASE, -	.end	= ADMPCI_MEM_BASE + ADMPCI_MEM_SIZE, -	.flags	= IORESOURCE_MEM -}; - -#ifdef CONFIG_ADM8668_DISABLE_PCI -struct pci_controller mips_pci_channels[] = { -	{ NULL, NULL, NULL , NULL , NULL} -}; -#else -struct pci_controller mips_pci_channels = { -	.pci_ops = &adm8668_pci_ops, -	.io_resource = &pciioport_resource, -	.mem_resource = &pciiomem_resource, -}; -#endif - -int pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) -{ -	switch (slot) -	{ -		case 1: -			return 14; -		case 2: -			return 13; -		case 3: -			return 12; -		default: -			return dev->irq; -	} -} - -int pcibios_plat_dev_init(struct pci_dev *dev) -{ -	return 0; -} - -static int __init adm8668_pci_init(void) -{ -	void __iomem *io_map_base; - -	printk("adm8668_pci_init()\n"); - -	/* what's an io port? this is MIPS... *shrug* */ -	ioport_resource.start   = ADMPCI_IO_BASE; -	ioport_resource.end     = ADMPCI_IO_BASE + ADMPCI_IO_SIZE; - -	io_map_base = ioremap(ADMPCI_IO_BASE, ADMPCI_IO_SIZE); -	if (!io_map_base) -		printk("io_map_base didn't work.\n"); -	mips_pci_channels.io_map_base = (unsigned long)io_map_base; -	register_pci_controller(&mips_pci_channels); - -	/* this needed? linksys' gpl 2.4 did it... */ -	adm8668_write_config(NULL, 0, PCI_CACHE_LINE_SIZE, 2, 0); -	adm8668_write_config(NULL, 0, PCI_BASE_ADDRESS_0, 4, 0); -	adm8668_write_config(NULL, 0, PCI_BASE_ADDRESS_1, 4, 0); -	adm8668_write_config(NULL, 0, PCI_COMMAND, 4, PCI_CMM_DEF); - -	return 0; -} - -arch_initcall(adm8668_pci_init); diff --git a/target/linux/adm8668/files/arch/mips/include/asm/mach-adm8668/adm8668.h b/target/linux/adm8668/files/arch/mips/include/asm/mach-adm8668/adm8668.h index 250447bbf..f0608d155 100644 --- a/target/linux/adm8668/files/arch/mips/include/asm/mach-adm8668/adm8668.h +++ b/target/linux/adm8668/files/arch/mips/include/asm/mach-adm8668/adm8668.h @@ -26,8 +26,8 @@  #define ADM8668_SMEM0_BASE	0x1FC00000  #define ADM8668_NAND_BASE	0x1FFFFF00 -#define PCICFG_BASE		0x12200000 -#define PCIDAT_BASE		0x12400000 +#define ADM8668_PCICFG_BASE	0x12200000 +#define ADM8668_PCIDAT_BASE	0x12400000  /** onboard uart **/  #define ADM8668_UARTCLK_FREQ	62500000 diff --git a/target/linux/adm8668/files/arch/mips/pci/pci-adm8668.c b/target/linux/adm8668/files/arch/mips/pci/pci-adm8668.c new file mode 100644 index 000000000..5cfa54604 --- /dev/null +++ b/target/linux/adm8668/files/arch/mips/pci/pci-adm8668.c @@ -0,0 +1,200 @@ +/* + * Copyright (C) 2010 Scott Nicholas <neutronscott@scottn.us> + * Copyright (C) 2012 Florian Fainelli <florian@openwrt.org> + * + * This file is subject to the terms and conditions of the GNU General Public + * License.  See the file "COPYING" in the main directory of this archive + * for more details. + * + * Note that this controller is identical to the ADM5120 one + */ + +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/pci.h> +#include <linux/types.h> +#include <linux/spinlock.h> + +#include <asm/byteorder.h> +#include <asm/pci.h> +#include <adm8668.h> + +static DEFINE_SPINLOCK(pci_lock); + +#define PCI_ENABLE			0x80000000 +#define	ADMPCI_IO_BASE			0x12600000 +#define	ADMPCI_IO_SIZE			0x1fffff +#define	ADMPCI_MEM_BASE			0x16000000 +#define	ADMPCI_MEM_SIZE			0x7ffffff + +static inline void write_cfgaddr(u32 addr) +{ +	__raw_writel((addr | PCI_ENABLE), +			(void __iomem *)KSEG1ADDR(ADM8668_PCICFG_BASE)); +} + +static inline void write_cfgdata(u32 data) +{ +	__raw_writel(data, (void __iomem *)KSEG1ADDR(ADM8668_PCIDAT_BASE)); +} + +static inline u32 read_cfgdata(void) +{ +	return __raw_readl((void __iomem *)KSEG1ADDR(ADM8668_PCIDAT_BASE)); +} + +static inline u32 mkaddr(struct pci_bus *bus, unsigned int devfn, int where) +{ +	return ((bus->number & 0xff) << 16) | ((devfn & 0xff) << 8) | +		(where & 0xfc); +} + +static int pci_read_config(struct pci_bus *bus, unsigned int devfn, +				int where, int size, u32 *val) +{ +	unsigned long flags; +	u32 data; + +	spin_lock_irqsave(&pci_lock, flags); +	write_cfgaddr(mkaddr(bus, devfn, where)); +	data = read_cfgdata(); + +	switch (size) { +	case 1: +		if (where & 1) +			data >>= 8; +		if (where & 2) +			data >>= 16; +		data &= 0xff; +		break; +	case 2: +		if (where & 2) +			data >>= 16; +		data &= 0xffff; +		break; +	} + +	*val = data; + +	spin_unlock_irqrestore(&pci_lock, flags); + +	return PCIBIOS_SUCCESSFUL; +} + +static int pci_write_config(struct pci_bus *bus, unsigned int devfn, +				int where, int size, u32 val) +{ +	unsigned long flags; +	u32 data; +	int s; + +	spin_lock_irqsave(&pci_lock, flags); + +	write_cfgaddr(mkaddr(bus, devfn, where)); +	data = read_cfgdata(); + +	switch (size) { +	case 1: +		s = ((where & 3) << 3); +		data &= ~(0xff << s); +		data |= ((val & 0xff) << s); +		break; +	case 2: +		s = ((where & 2) << 4); +		data &= ~(0xffff << s); +		data |= ((val & 0xffff) << s); +		break; +	case 4: +		data = val; +		break; +	} + +	write_cfgdata(data); + +	spin_unlock_irqrestore(&pci_lock, flags); + +	return PCIBIOS_SUCCESSFUL; +} + +struct pci_ops adm8668_pci_ops = { +	.read = pci_read_config, +	.write = pci_write_config +}; + + +struct resource pciioport_resource = { +	.name	= "adm8668_pci", +	.start	= ADMPCI_IO_BASE, +	.end	= ADMPCI_IO_BASE + ADMPCI_IO_SIZE, +	.flags	= IORESOURCE_IO +}; + +struct resource pciiomem_resource = { +	.name	= "adm8668_pci", +	.start	= ADMPCI_MEM_BASE, +	.end	= ADMPCI_MEM_BASE + ADMPCI_MEM_SIZE, +	.flags	= IORESOURCE_MEM +}; + +struct pci_controller adm8668_pci_controller = { +	.pci_ops	= &adm8668_pci_ops, +	.io_resource	= &pciioport_resource, +	.mem_resource	= &pciiomem_resource, +}; + +int pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) +{ +	switch (slot) { +	case 1: +		return 14; +	case 2: +		return 13; +	case 3: +		return 12; +	default: +		return dev->irq; +	} +} + +int pcibios_plat_dev_init(struct pci_dev *dev) +{ +	return 0; +} + +static void adm8668_pci_fixup(struct pci_dev *dev) +{ +	if (dev->devfn != 0) +		return; + +	pr_info("PCI: fixing up ADM8668 controller\n"); + +	/* setup COMMAND register */ +	pci_write_config_word(dev, PCI_COMMAND, +		(PCI_COMMAND_IO | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER)); + +	/* setup CACHE_LINE_SIZE register */ +	pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, 4); + +	/* setup BARS */ +	pci_write_config_dword(dev, PCI_BASE_ADDRESS_0, 0); +	pci_write_config_dword(dev, PCI_BASE_ADDRESS_1, 0); +} +DECLARE_PCI_FIXUP_HEADER(0x1317, 0x8688, adm8668_pci_fixup); + +static int __init adm8668_pci_init(void) +{ +	void __iomem *io_map_base; + +	ioport_resource.start   = ADMPCI_IO_BASE; +	ioport_resource.end     = ADMPCI_IO_BASE + ADMPCI_IO_SIZE; + +	io_map_base = ioremap(ADMPCI_IO_BASE, ADMPCI_IO_SIZE); +	if (!io_map_base) +		printk("io_map_base didn't work.\n"); + +	adm8668_pci_controller.io_map_base = (unsigned long)io_map_base; +	register_pci_controller(&adm8668_pci_controller); + +	return 0; +} +arch_initcall(adm8668_pci_init); diff --git a/target/linux/adm8668/patches-3.3/001-adm8668_arch.patch b/target/linux/adm8668/patches-3.3/001-adm8668_arch.patch index 541b0bff5..66be46c8d 100644 --- a/target/linux/adm8668/patches-3.3/001-adm8668_arch.patch +++ b/target/linux/adm8668/patches-3.3/001-adm8668_arch.patch @@ -36,7 +36,7 @@   config BCM63XX   	bool "Broadcom BCM63XX based boards"   	select CEVT_R4K -@@ -813,6 +833,7 @@ config NLM_XLP_BOARD +@@ -813,6 +832,7 @@ config NLM_XLP_BOARD   endchoice diff --git a/target/linux/adm8668/patches-3.3/002-adm8668_pci.patch b/target/linux/adm8668/patches-3.3/002-adm8668_pci.patch new file mode 100644 index 000000000..17be86489 --- /dev/null +++ b/target/linux/adm8668/patches-3.3/002-adm8668_pci.patch @@ -0,0 +1,22 @@ +--- a/arch/mips/pci/Makefile ++++ b/arch/mips/pci/Makefile +@@ -57,6 +57,7 @@ obj-$(CONFIG_WR_PPMC)		+= fixup-wrppmc.o + obj-$(CONFIG_MIKROTIK_RB532)	+= pci-rc32434.o ops-rc32434.o fixup-rc32434.o + obj-$(CONFIG_CPU_CAVIUM_OCTEON)	+= pci-octeon.o pcie-octeon.o + obj-$(CONFIG_CPU_XLR)		+= pci-xlr.o ++obj-$(CONFIG_ADM8668)		+= pci-adm8668.o +  + ifdef CONFIG_PCI_MSI + obj-$(CONFIG_CPU_CAVIUM_OCTEON)	+= msi-octeon.o +--- a/include/linux/pci_ids.h ++++ b/include/linux/pci_ids.h +@@ -1803,6 +1803,9 @@ + #define PCI_VENDOR_ID_ESDGMBH		0x12fe + #define PCI_DEVICE_ID_ESDGMBH_CPCIASIO4 0x0111 +  ++#define PCI_VENDOR_ADMTEK		0x1317 ++#define PCI_DEVICE_ID_ADM8668		0x8688 ++ + #define PCI_VENDOR_ID_SIIG		0x131f + #define PCI_SUBVENDOR_ID_SIIG		0x131f + #define PCI_DEVICE_ID_SIIG_1S_10x_550	0x1000  | 
