diff options
author | juhosg <juhosg@3c298f89-4303-0410-b956-a3cf2f4a3e73> | 2010-09-27 14:53:46 +0000 |
---|---|---|
committer | juhosg <juhosg@3c298f89-4303-0410-b956-a3cf2f4a3e73> | 2010-09-27 14:53:46 +0000 |
commit | ae0b1149b962026c2eb449a709139a952bdeb047 (patch) | |
tree | caa591ebfab387913e0a21031a8c40572167e45c /target/linux/ar71xx/files/arch/mips | |
parent | d39b21c7f6cb1321bff15ac03fdf796d38a92246 (diff) |
ar71xx: move ath9k specific PCI fixup into a separate file
git-svn-id: svn://svn.openwrt.org/openwrt/trunk@23131 3c298f89-4303-0410-b956-a3cf2f4a3e73
Diffstat (limited to 'target/linux/ar71xx/files/arch/mips')
6 files changed, 140 insertions, 148 deletions
diff --git a/target/linux/ar71xx/files/arch/mips/ar71xx/Kconfig b/target/linux/ar71xx/files/arch/mips/ar71xx/Kconfig index 2b4c3bdcf..2c4390051 100644 --- a/target/linux/ar71xx/files/arch/mips/ar71xx/Kconfig +++ b/target/linux/ar71xx/files/arch/mips/ar71xx/Kconfig @@ -261,6 +261,7 @@ config AR71XX_DEV_M25P80 def_bool n config AR71XX_DEV_AP91_PCI + select AR71XX_PCI_ATH9K_FIXUP def_bool n config AR71XX_DEV_AP91_ETH @@ -268,6 +269,7 @@ config AR71XX_DEV_AP91_ETH def_bool n config AR71XX_DEV_AP94_PCI + select AR71XX_PCI_ATH9K_FIXUP def_bool n config AR71XX_DEV_AR913X_WMAC @@ -294,4 +296,7 @@ config AR71XX_DEV_USB config AR71XX_NVRAM def_bool n +config AR71XX_PCI_ATH9K_FIXUP + def_bool n + endif diff --git a/target/linux/ar71xx/files/arch/mips/ar71xx/Makefile b/target/linux/ar71xx/files/arch/mips/ar71xx/Makefile index 81dab7c71..8548fd9af 100644 --- a/target/linux/ar71xx/files/arch/mips/ar71xx/Makefile +++ b/target/linux/ar71xx/files/arch/mips/ar71xx/Makefile @@ -26,6 +26,7 @@ obj-$(CONFIG_AR71XX_DEV_PB9X_PCI) += dev-pb9x-pci.o obj-$(CONFIG_AR71XX_DEV_USB) += dev-usb.o obj-$(CONFIG_AR71XX_NVRAM) += nvram.o +obj-$(CONFIG_AR71XX_PCI_ATH9K_FIXUP) += pci-ath9k-fixup.o obj-$(CONFIG_AR71XX_MACH_AP81) += mach-ap81.o obj-$(CONFIG_AR71XX_MACH_AP83) += mach-ap83.o diff --git a/target/linux/ar71xx/files/arch/mips/ar71xx/dev-ap91-pci.c b/target/linux/ar71xx/files/arch/mips/ar71xx/dev-ap91-pci.c index f24d4697c..2342d7f7e 100644 --- a/target/linux/ar71xx/files/arch/mips/ar71xx/dev-ap91-pci.c +++ b/target/linux/ar71xx/files/arch/mips/ar71xx/dev-ap91-pci.c @@ -16,10 +16,10 @@ #include <asm/mach-ar71xx/pci.h> #include "dev-ap91-pci.h" +#include "pci-ath9k-fixup.h" static struct ath9k_platform_data ap91_wmac_data; static char ap91_wmac_mac[6]; -static int ap91_pci_fixup_enabled; static struct ar71xx_pci_irq ap91_pci_irqs[] __initdata = { { @@ -40,75 +40,6 @@ static int ap91_pci_plat_dev_init(struct pci_dev *dev) return 0; } -static void ap91_pci_fixup(struct pci_dev *dev) -{ - void __iomem *mem; - u16 *cal_data; - u16 cmd; - u32 val; - - if (!ap91_pci_fixup_enabled) - return; - - printk(KERN_INFO "PCI: fixup device %s\n", pci_name(dev)); - - cal_data = ap91_wmac_data.eeprom_data; - if (*cal_data != 0xa55a) { - printk(KERN_ERR "PCI: no calibration data found for %s\n", - pci_name(dev)); - return; - } - - mem = ioremap(AR71XX_PCI_MEM_BASE, 0x10000); - if (!mem) { - printk(KERN_ERR "PCI: ioremap error for device %s\n", - pci_name(dev)); - return; - } - - /* Setup the PCI device to allow access to the internal registers */ - switch (ar71xx_soc) { - case AR71XX_SOC_AR7240: - pci_write_config_dword(dev, PCI_BASE_ADDRESS_0, 0xffff); - break; - - case AR71XX_SOC_AR7241: - case AR71XX_SOC_AR7242: - pci_write_config_dword(dev, PCI_BASE_ADDRESS_0, 0x1000ffff); - break; - - default: - BUG(); - } - - pci_read_config_word(dev, PCI_COMMAND, &cmd); - cmd |= PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY; - pci_write_config_word(dev, PCI_COMMAND, cmd); - - /* set pointer to first reg address */ - cal_data += 3; - while (*cal_data != 0xffff) { - u32 reg; - reg = *cal_data++; - val = *cal_data++; - val |= (*cal_data++) << 16; - - __raw_writel(val, mem + reg); - udelay(100); - } - - pci_read_config_dword(dev, PCI_VENDOR_ID, &val); - dev->vendor = val & 0xffff; - dev->device = (val >> 16) & 0xffff; - - pci_read_config_dword(dev, PCI_CLASS_REVISION, &val); - dev->revision = val & 0xff; - dev->class = val >> 8; /* upper 3 bytes */ - - iounmap(mem); -} -DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_ATHEROS, PCI_ANY_ID, ap91_pci_fixup); - void __init ap91_pci_init(u8 *cal_data, u8 *mac_addr) { if (cal_data) @@ -123,5 +54,5 @@ void __init ap91_pci_init(u8 *cal_data, u8 *mac_addr) ar71xx_pci_plat_dev_init = ap91_pci_plat_dev_init; ar71xx_pci_init(ARRAY_SIZE(ap91_pci_irqs), ap91_pci_irqs); - ap91_pci_fixup_enabled = 1; + pci_enable_ath9k_fixup(0, ap91_wmac_data.eeprom_data); } diff --git a/target/linux/ar71xx/files/arch/mips/ar71xx/dev-ap94-pci.c b/target/linux/ar71xx/files/arch/mips/ar71xx/dev-ap94-pci.c index bfa668f74..2436491b4 100644 --- a/target/linux/ar71xx/files/arch/mips/ar71xx/dev-ap94-pci.c +++ b/target/linux/ar71xx/files/arch/mips/ar71xx/dev-ap94-pci.c @@ -16,12 +16,12 @@ #include <asm/mach-ar71xx/pci.h> #include "dev-ap94-pci.h" +#include "pci-ath9k-fixup.h" static struct ath9k_platform_data ap94_wmac0_data; static struct ath9k_platform_data ap94_wmac1_data; static char ap94_wmac0_mac[6]; static char ap94_wmac1_mac[6]; -static int ap94_pci_fixup_enabled; static struct ar71xx_pci_irq ap94_pci_irqs[] __initdata = { { @@ -50,81 +50,6 @@ static int ap94_pci_plat_dev_init(struct pci_dev *dev) return 0; } -static void ap94_pci_fixup(struct pci_dev *dev) -{ - void __iomem *mem; - u16 *cal_data; - u16 cmd; - u32 bar0; - u32 val; - - if (!ap94_pci_fixup_enabled) - return; - - switch (PCI_SLOT(dev->devfn)) { - case 17: - cal_data = ap94_wmac0_data.eeprom_data; - break; - case 18: - cal_data = ap94_wmac1_data.eeprom_data; - break; - default: - return; - } - - if (*cal_data != 0xa55a) { - printk(KERN_ERR "PCI: no calibration data found for %s\n", - pci_name(dev)); - return; - } - - mem = ioremap(AR71XX_PCI_MEM_BASE, 0x10000); - if (!mem) { - printk(KERN_ERR "PCI: ioremap error for device %s\n", - pci_name(dev)); - return; - } - - printk(KERN_INFO "PCI: fixup device %s\n", pci_name(dev)); - - pci_read_config_dword(dev, PCI_BASE_ADDRESS_0, &bar0); - - /* Setup the PCI device to allow access to the internal registers */ - pci_write_config_dword(dev, PCI_BASE_ADDRESS_0, AR71XX_PCI_MEM_BASE); - pci_read_config_word(dev, PCI_COMMAND, &cmd); - cmd |= PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY; - pci_write_config_word(dev, PCI_COMMAND, cmd); - - /* set pointer to first reg address */ - cal_data += 3; - while (*cal_data != 0xffff) { - u32 reg; - reg = *cal_data++; - val = *cal_data++; - val |= (*cal_data++) << 16; - - __raw_writel(val, mem + reg); - udelay(100); - } - - pci_read_config_dword(dev, PCI_VENDOR_ID, &val); - dev->vendor = val & 0xffff; - dev->device = (val >> 16) & 0xffff; - - pci_read_config_dword(dev, PCI_CLASS_REVISION, &val); - dev->revision = val & 0xff; - dev->class = val >> 8; /* upper 3 bytes */ - - pci_read_config_word(dev, PCI_COMMAND, &cmd); - cmd &= ~(PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY); - pci_write_config_word(dev, PCI_COMMAND, cmd); - - pci_write_config_dword(dev, PCI_BASE_ADDRESS_0, bar0); - - iounmap(mem); -} -DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_ATHEROS, PCI_ANY_ID, ap94_pci_fixup); - void __init ap94_pci_enable_quirk_wndr3700(void) { ap94_wmac0_data.quirk_wndr3700 = 1; @@ -155,5 +80,6 @@ void __init ap94_pci_init(u8 *cal_data0, u8 *mac_addr0, ar71xx_pci_plat_dev_init = ap94_pci_plat_dev_init; ar71xx_pci_init(ARRAY_SIZE(ap94_pci_irqs), ap94_pci_irqs); - ap94_pci_fixup_enabled = 1; + pci_enable_ath9k_fixup(17, ap94_wmac0_data.eeprom_data); + pci_enable_ath9k_fixup(18, ap94_wmac1_data.eeprom_data); } diff --git a/target/linux/ar71xx/files/arch/mips/ar71xx/pci-ath9k-fixup.c b/target/linux/ar71xx/files/arch/mips/ar71xx/pci-ath9k-fixup.c new file mode 100644 index 000000000..21f5a6816 --- /dev/null +++ b/target/linux/ar71xx/files/arch/mips/ar71xx/pci-ath9k-fixup.c @@ -0,0 +1,123 @@ +/* + * Atheros AP94 reference board PCI initialization + * + * Copyright (C) 2009-2010 Gabor Juhos <juhosg@openwrt.org> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published + * by the Free Software Foundation. + */ + +#include <linux/pci.h> +#include <linux/delay.h> + +#include <asm/mach-ar71xx/ar71xx.h> +#include <asm/mach-ar71xx/pci.h> + +struct ath9k_fixup { + u16 *cal_data; + unsigned slot; +}; + +static int ath9k_num_fixups; +static struct ath9k_fixup ath9k_fixups[2]; + +static void ath9k_pci_fixup(struct pci_dev *dev) +{ + void __iomem *mem; + u16 *cal_data = NULL; + u16 cmd; + u32 bar0; + u32 val; + unsigned i; + + for (i = 0; i < ath9k_num_fixups; i++) { + if (ath9k_fixups[i].cal_data == NULL) + continue; + + if (ath9k_fixups[i].slot != PCI_SLOT(dev->devfn)) + continue; + + cal_data = ath9k_fixups[i].cal_data; + break; + } + + if (cal_data == NULL) + return; + + if (*cal_data != 0xa55a) { + pr_err("pci %s: invalid calibration data\n", pci_name(dev)); + return; + } + + pr_info("pci %s: fixup device configuration\n", pci_name(dev)); + + mem = ioremap(AR71XX_PCI_MEM_BASE, 0x10000); + if (!mem) { + pr_err("pci %s: ioremap error\n", pci_name(dev)); + return; + } + + pci_read_config_dword(dev, PCI_BASE_ADDRESS_0, &bar0); + + switch (ar71xx_soc) { + case AR71XX_SOC_AR7161: + pci_write_config_dword(dev, PCI_BASE_ADDRESS_0, + AR71XX_PCI_MEM_BASE); + break; + case AR71XX_SOC_AR7240: + pci_write_config_dword(dev, PCI_BASE_ADDRESS_0, 0xffff); + break; + + case AR71XX_SOC_AR7241: + case AR71XX_SOC_AR7242: + pci_write_config_dword(dev, PCI_BASE_ADDRESS_0, 0x1000ffff); + break; + + default: + BUG(); + } + + pci_read_config_word(dev, PCI_COMMAND, &cmd); + cmd |= PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY; + pci_write_config_word(dev, PCI_COMMAND, cmd); + + /* set pointer to first reg address */ + cal_data += 3; + while (*cal_data != 0xffff) { + u32 reg; + reg = *cal_data++; + val = *cal_data++; + val |= (*cal_data++) << 16; + + __raw_writel(val, mem + reg); + udelay(100); + } + + pci_read_config_dword(dev, PCI_VENDOR_ID, &val); + dev->vendor = val & 0xffff; + dev->device = (val >> 16) & 0xffff; + + pci_read_config_dword(dev, PCI_CLASS_REVISION, &val); + dev->revision = val & 0xff; + dev->class = val >> 8; /* upper 3 bytes */ + + pci_read_config_word(dev, PCI_COMMAND, &cmd); + cmd &= ~(PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY); + pci_write_config_word(dev, PCI_COMMAND, cmd); + + pci_write_config_dword(dev, PCI_BASE_ADDRESS_0, bar0); + + iounmap(mem); +} +DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_ATHEROS, PCI_ANY_ID, ath9k_pci_fixup); + +void __init pci_enable_ath9k_fixup(unsigned slot, u16 *cal_data) +{ + if (ath9k_num_fixups >= ARRAY_SIZE(ath9k_fixups)) + return; + + ath9k_fixups[ath9k_num_fixups].slot = slot; + ath9k_fixups[ath9k_num_fixups].cal_data = cal_data; + ath9k_num_fixups++; +} diff --git a/target/linux/ar71xx/files/arch/mips/ar71xx/pci-ath9k-fixup.h b/target/linux/ar71xx/files/arch/mips/ar71xx/pci-ath9k-fixup.h new file mode 100644 index 000000000..5794941f0 --- /dev/null +++ b/target/linux/ar71xx/files/arch/mips/ar71xx/pci-ath9k-fixup.h @@ -0,0 +1,6 @@ +#ifndef _PCI_ATH9K_FIXUP +#define _PCI_ATH9K_FIXUP + +void pci_enable_ath9k_fixup(unsigned slot, u16 *cal_data) __init; + +#endif /* _PCI_ATH9K_FIXUP */ |