mirror of
git://projects.qi-hardware.com/openwrt-xburst.git
synced 2024-08-21 14:17:41 +03:00
This patch fixes the GPIO ALTSEL settings for some of the GPIOs used by the PCI subsystem in Lantiq Danube. These changes are required for more than one PCI device to work. Tested with an ARV7510PW having two PCI-devices; a VIA USB controller and a Ralink WLAN mini-PCI card. Signed-off-by: Matti Laakso <malaakso@elisanet.fi> git-svn-id: svn://svn.openwrt.org/openwrt/trunk@33054 3c298f89-4303-0410-b956-a3cf2f4a3e73
356 lines
11 KiB
Diff
356 lines
11 KiB
Diff
From b80a5236053be899421417871d1be8016912e94b Mon Sep 17 00:00:00 2001
|
|
From: John Crispin <blogic@openwrt.org>
|
|
Date: Fri, 3 Aug 2012 09:52:10 +0200
|
|
Subject: [PATCH 05/25] pci support
|
|
|
|
---
|
|
arch/mips/include/asm/mach-lantiq/lantiq.h | 37 ++++-----
|
|
.../mips/include/asm/mach-lantiq/lantiq_platform.h | 9 ++
|
|
arch/mips/pci/Makefile | 5 +-
|
|
arch/mips/pci/ops-lantiq.c | 6 +-
|
|
arch/mips/pci/pci-lantiq.c | 82 ++++++++------------
|
|
arch/mips/pci/pci-lantiq.h | 2 +-
|
|
arch/mips/pci/pci.c | 25 ++++++
|
|
7 files changed, 89 insertions(+), 77 deletions(-)
|
|
|
|
diff --git a/arch/mips/include/asm/mach-lantiq/lantiq.h b/arch/mips/include/asm/mach-lantiq/lantiq.h
|
|
index ce2f029..622847f 100644
|
|
--- a/arch/mips/include/asm/mach-lantiq/lantiq.h
|
|
+++ b/arch/mips/include/asm/mach-lantiq/lantiq.h
|
|
@@ -9,6 +9,8 @@
|
|
#define _LANTIQ_H__
|
|
|
|
#include <linux/irq.h>
|
|
+#include <linux/clk.h>
|
|
+#include <linux/ioport.h>
|
|
|
|
/* generic reg access functions */
|
|
#define ltq_r32(reg) __raw_readl(reg)
|
|
@@ -18,40 +20,33 @@
|
|
#define ltq_r8(reg) __raw_readb(reg)
|
|
#define ltq_w8(val, reg) __raw_writeb(val, reg)
|
|
|
|
-/* register access macros for EBU and CGU */
|
|
-#define ltq_ebu_w32(x, y) ltq_w32((x), ltq_ebu_membase + (y))
|
|
-#define ltq_ebu_r32(x) ltq_r32(ltq_ebu_membase + (x))
|
|
-#define ltq_cgu_w32(x, y) ltq_w32((x), ltq_cgu_membase + (y))
|
|
-#define ltq_cgu_r32(x) ltq_r32(ltq_cgu_membase + (x))
|
|
-
|
|
-extern __iomem void *ltq_ebu_membase;
|
|
-extern __iomem void *ltq_cgu_membase;
|
|
-
|
|
extern unsigned int ltq_get_cpu_ver(void);
|
|
extern unsigned int ltq_get_soc_type(void);
|
|
|
|
-/* clock speeds */
|
|
-#define CLOCK_60M 60000000
|
|
-#define CLOCK_83M 83333333
|
|
-#define CLOCK_111M 111111111
|
|
-#define CLOCK_133M 133333333
|
|
-#define CLOCK_167M 166666667
|
|
-#define CLOCK_200M 200000000
|
|
-#define CLOCK_266M 266666666
|
|
-#define CLOCK_333M 333333333
|
|
-#define CLOCK_400M 400000000
|
|
-
|
|
/* spinlock all ebu i/o */
|
|
extern spinlock_t ebu_lock;
|
|
|
|
+/* request a non-gpio and set the PIO config */
|
|
+extern int ltq_gpio_request(struct device *dev, unsigned int pin,
|
|
+ unsigned int mux, unsigned int dir, const char *name);
|
|
+
|
|
/* some irq helpers */
|
|
extern void ltq_disable_irq(struct irq_data *data);
|
|
extern void ltq_mask_and_ack_irq(struct irq_data *data);
|
|
extern void ltq_enable_irq(struct irq_data *data);
|
|
|
|
+/* clock handling */
|
|
+extern int clk_activate(struct clk *clk);
|
|
+extern void clk_deactivate(struct clk *clk);
|
|
+extern struct clk *clk_get_cpu(void);
|
|
+extern struct clk *clk_get_fpi(void);
|
|
+extern struct clk *clk_get_io(void);
|
|
+
|
|
/* find out what caused the last cpu reset */
|
|
extern int ltq_reset_cause(void);
|
|
-#define LTQ_RST_CAUSE_WDTRST 0x20
|
|
+
|
|
+/* helper for requesting and remapping resources */
|
|
+extern void __iomem *ltq_remap_resource(struct resource *res);
|
|
|
|
#define IOPORT_RESOURCE_START 0x10000000
|
|
#define IOPORT_RESOURCE_END 0xffffffff
|
|
diff --git a/arch/mips/include/asm/mach-lantiq/lantiq_platform.h b/arch/mips/include/asm/mach-lantiq/lantiq_platform.h
|
|
index a305f1d..38ed938 100644
|
|
--- a/arch/mips/include/asm/mach-lantiq/lantiq_platform.h
|
|
+++ b/arch/mips/include/asm/mach-lantiq/lantiq_platform.h
|
|
@@ -50,4 +50,13 @@ struct ltq_eth_data {
|
|
int mii_mode;
|
|
};
|
|
|
|
+
|
|
+struct ltq_spi_platform_data {
|
|
+ u16 num_chipselect;
|
|
+};
|
|
+
|
|
+struct ltq_spi_controller_data {
|
|
+ unsigned gpio;
|
|
+};
|
|
+
|
|
#endif
|
|
diff --git a/arch/mips/pci/Makefile b/arch/mips/pci/Makefile
|
|
index c3ac4b0..31e70c5 100644
|
|
--- a/arch/mips/pci/Makefile
|
|
+++ b/arch/mips/pci/Makefile
|
|
@@ -41,7 +41,10 @@ obj-$(CONFIG_SIBYTE_SB1250) += fixup-sb1250.o pci-sb1250.o
|
|
obj-$(CONFIG_SIBYTE_BCM112X) += fixup-sb1250.o pci-sb1250.o
|
|
obj-$(CONFIG_SIBYTE_BCM1x80) += pci-bcm1480.o pci-bcm1480ht.o
|
|
obj-$(CONFIG_SNI_RM) += fixup-sni.o ops-sni.o
|
|
-obj-$(CONFIG_SOC_XWAY) += pci-lantiq.o ops-lantiq.o
|
|
+obj-$(CONFIG_LANTIQ) += fixup-lantiq.o
|
|
+obj-$(CONFIG_PCI_LANTIQ) += pci-lantiq.o ops-lantiq.o
|
|
+obj-$(CONFIG_PCIE_LANTIQ) += pcie-lantiq-phy.o pcie-lantiq.o fixup-lantiq-pcie.o
|
|
+obj-$(CONFIG_PCIE_LANTIQ_MSI) += pcie-lantiq-msi.o
|
|
obj-$(CONFIG_TANBAC_TB0219) += fixup-tb0219.o
|
|
obj-$(CONFIG_TANBAC_TB0226) += fixup-tb0226.o
|
|
obj-$(CONFIG_TANBAC_TB0287) += fixup-tb0287.o
|
|
diff --git a/arch/mips/pci/ops-lantiq.c b/arch/mips/pci/ops-lantiq.c
|
|
index 1f2afb5..5cbb0cf 100644
|
|
--- a/arch/mips/pci/ops-lantiq.c
|
|
+++ b/arch/mips/pci/ops-lantiq.c
|
|
@@ -41,7 +41,7 @@ static int ltq_pci_config_access(unsigned char access_type, struct pci_bus *bus,
|
|
|
|
spin_lock_irqsave(&ebu_lock, flags);
|
|
|
|
- cfg_base = (unsigned long) ltq_pci_mapped_cfg;
|
|
+ cfg_base = (unsigned long) ltq_pci_cfgbase;
|
|
cfg_base |= (bus->number << LTQ_PCI_CFG_BUSNUM_SHF) | (devfn <<
|
|
LTQ_PCI_CFG_FUNNUM_SHF) | (where & ~0x3);
|
|
|
|
@@ -55,11 +55,11 @@ static int ltq_pci_config_access(unsigned char access_type, struct pci_bus *bus,
|
|
wmb();
|
|
|
|
/* clean possible Master abort */
|
|
- cfg_base = (unsigned long) ltq_pci_mapped_cfg;
|
|
+ cfg_base = (unsigned long) ltq_pci_cfgbase;
|
|
cfg_base |= (0x0 << LTQ_PCI_CFG_FUNNUM_SHF) + 4;
|
|
temp = ltq_r32(((u32 *)(cfg_base)));
|
|
temp = swab32(temp);
|
|
- cfg_base = (unsigned long) ltq_pci_mapped_cfg;
|
|
+ cfg_base = (unsigned long) ltq_pci_cfgbase;
|
|
cfg_base |= (0x68 << LTQ_PCI_CFG_FUNNUM_SHF) + 4;
|
|
ltq_w32(temp, ((u32 *)cfg_base));
|
|
|
|
diff --git a/arch/mips/pci/pci-lantiq.c b/arch/mips/pci/pci-lantiq.c
|
|
index be1e1af..7a29738 100644
|
|
--- a/arch/mips/pci/pci-lantiq.c
|
|
+++ b/arch/mips/pci/pci-lantiq.c
|
|
@@ -65,45 +65,42 @@
|
|
#define ltq_pci_w32(x, y) ltq_w32((x), ltq_pci_membase + (y))
|
|
#define ltq_pci_r32(x) ltq_r32(ltq_pci_membase + (x))
|
|
|
|
-#define ltq_pci_cfg_w32(x, y) ltq_w32((x), ltq_pci_mapped_cfg + (y))
|
|
-#define ltq_pci_cfg_r32(x) ltq_r32(ltq_pci_mapped_cfg + (x))
|
|
+#define ltq_pci_cfg_w32(x, y) ltq_w32((x), ltq_pci_cfgbase + (y))
|
|
+#define ltq_pci_cfg_r32(x) ltq_r32(ltq_pci_cfgbase + (x))
|
|
|
|
struct ltq_pci_gpio_map {
|
|
int pin;
|
|
- int alt0;
|
|
- int alt1;
|
|
+ int mux;
|
|
int dir;
|
|
char *name;
|
|
};
|
|
|
|
/* the pci core can make use of the following gpios */
|
|
static struct ltq_pci_gpio_map ltq_pci_gpio_map[] = {
|
|
- { 0, 1, 0, 0, "pci-exin0" },
|
|
- { 1, 1, 0, 0, "pci-exin1" },
|
|
- { 2, 1, 0, 0, "pci-exin2" },
|
|
- { 39, 1, 0, 0, "pci-exin3" },
|
|
- { 10, 1, 0, 0, "pci-exin4" },
|
|
- { 9, 1, 0, 0, "pci-exin5" },
|
|
- { 30, 1, 0, 1, "pci-gnt1" },
|
|
- { 23, 1, 0, 1, "pci-gnt2" },
|
|
- { 19, 1, 0, 1, "pci-gnt3" },
|
|
- { 38, 1, 0, 1, "pci-gnt4" },
|
|
- { 29, 1, 0, 0, "pci-req1" },
|
|
- { 31, 1, 0, 0, "pci-req2" },
|
|
- { 3, 1, 0, 0, "pci-req3" },
|
|
- { 37, 1, 0, 0, "pci-req4" },
|
|
+ { 0, 2, 0, "pci-exin0" },
|
|
+ { 1, 2, 0, "pci-exin1" },
|
|
+ { 2, 1, 0, "pci-exin2" },
|
|
+ { 39, 2, 0, "pci-exin3" },
|
|
+ { 10, 2, 0, "pci-exin4" },
|
|
+ { 9, 2, 0, "pci-exin5" },
|
|
+ { 30, 2, 1, "pci-gnt1" },
|
|
+ { 23, 1, 1, "pci-gnt2" },
|
|
+ { 19, 2, 1, "pci-gnt3" },
|
|
+ { 38, 2, 1, "pci-gnt4" },
|
|
+ { 29, 2, 0, "pci-req1" },
|
|
+ { 31, 1, 0, "pci-req2" },
|
|
+ { 3, 3, 0, "pci-req3" },
|
|
+ { 37, 2, 0, "pci-req4" },
|
|
};
|
|
|
|
-__iomem void *ltq_pci_mapped_cfg;
|
|
+__iomem void *ltq_pci_cfgbase;
|
|
static __iomem void *ltq_pci_membase;
|
|
|
|
-int (*ltqpci_plat_dev_init)(struct pci_dev *dev) = NULL;
|
|
-
|
|
/* Since the PCI REQ pins can be reused for other functionality, make it
|
|
possible to exclude those from interpretation by the PCI controller */
|
|
static int ltq_pci_req_mask = 0xf;
|
|
|
|
-static int *ltq_pci_irq_map;
|
|
+extern int *ltq_pci_irq_map;
|
|
|
|
struct pci_ops ltq_pci_ops = {
|
|
.read = ltq_pci_read_config_dword,
|
|
@@ -132,14 +129,6 @@ static struct pci_controller ltq_pci_controller = {
|
|
.io_offset = 0x00000000UL,
|
|
};
|
|
|
|
-int pcibios_plat_dev_init(struct pci_dev *dev)
|
|
-{
|
|
- if (ltqpci_plat_dev_init)
|
|
- return ltqpci_plat_dev_init(dev);
|
|
-
|
|
- return 0;
|
|
-}
|
|
-
|
|
static u32 ltq_calc_bar11mask(void)
|
|
{
|
|
u32 mem, bar11mask;
|
|
@@ -151,25 +140,26 @@ static u32 ltq_calc_bar11mask(void)
|
|
return bar11mask;
|
|
}
|
|
|
|
-static void ltq_pci_setup_gpio(int gpio)
|
|
+static void ltq_pci_setup_gpio(struct device *dev)
|
|
{
|
|
+ struct ltq_pci_data *conf = (struct ltq_pci_data *) dev->platform_data;
|
|
int i;
|
|
for (i = 0; i < ARRAY_SIZE(ltq_pci_gpio_map); i++) {
|
|
- if (gpio & (1 << i)) {
|
|
- ltq_gpio_request(ltq_pci_gpio_map[i].pin,
|
|
- ltq_pci_gpio_map[i].alt0,
|
|
- ltq_pci_gpio_map[i].alt1,
|
|
+ if (conf->gpio & (1 << i)) {
|
|
+ ltq_gpio_request(dev, ltq_pci_gpio_map[i].pin,
|
|
+ ltq_pci_gpio_map[i].mux,
|
|
ltq_pci_gpio_map[i].dir,
|
|
ltq_pci_gpio_map[i].name);
|
|
}
|
|
}
|
|
- ltq_gpio_request(21, 0, 0, 1, "pci-reset");
|
|
- ltq_pci_req_mask = (gpio >> PCI_REQ_SHIFT) & PCI_REQ_MASK;
|
|
+ ltq_gpio_request(dev, 21, 0, 1, "pci-reset");
|
|
+ ltq_pci_req_mask = (conf->gpio >> PCI_REQ_SHIFT) & PCI_REQ_MASK;
|
|
}
|
|
|
|
-static int __devinit ltq_pci_startup(struct ltq_pci_data *conf)
|
|
+static int __devinit ltq_pci_startup(struct device *dev)
|
|
{
|
|
u32 temp_buffer;
|
|
+ struct ltq_pci_data *conf = (struct ltq_pci_data *) dev->platform_data;
|
|
|
|
/* set clock to 33Mhz */
|
|
if (ltq_is_ar9()) {
|
|
@@ -192,7 +182,7 @@ static int __devinit ltq_pci_startup(struct ltq_pci_data *conf)
|
|
}
|
|
|
|
/* setup pci clock and gpis used by pci */
|
|
- ltq_pci_setup_gpio(conf->gpio);
|
|
+ ltq_pci_setup_gpio(dev);
|
|
|
|
/* enable auto-switching between PCI and EBU */
|
|
ltq_pci_w32(0xa, PCI_CR_CLK_CTRL);
|
|
@@ -256,16 +246,6 @@ static int __devinit ltq_pci_startup(struct ltq_pci_data *conf)
|
|
return 0;
|
|
}
|
|
|
|
-int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
|
|
-{
|
|
- if (ltq_pci_irq_map[slot])
|
|
- return ltq_pci_irq_map[slot];
|
|
- printk(KERN_ERR "lq_pci: trying to map irq for unknown slot %d\n",
|
|
- slot);
|
|
-
|
|
- return 0;
|
|
-}
|
|
-
|
|
static int __devinit ltq_pci_probe(struct platform_device *pdev)
|
|
{
|
|
struct ltq_pci_data *ltq_pci_data =
|
|
@@ -273,11 +253,11 @@ static int __devinit ltq_pci_probe(struct platform_device *pdev)
|
|
pci_probe_only = 0;
|
|
ltq_pci_irq_map = ltq_pci_data->irq;
|
|
ltq_pci_membase = ioremap_nocache(PCI_CR_BASE_ADDR, PCI_CR_SIZE);
|
|
- ltq_pci_mapped_cfg =
|
|
+ ltq_pci_cfgbase =
|
|
ioremap_nocache(LTQ_PCI_CFG_BASE, LTQ_PCI_CFG_BASE);
|
|
ltq_pci_controller.io_map_base =
|
|
(unsigned long)ioremap(LTQ_PCI_IO_BASE, LTQ_PCI_IO_SIZE - 1);
|
|
- ltq_pci_startup(ltq_pci_data);
|
|
+ ltq_pci_startup(&pdev->dev);
|
|
register_pci_controller(<q_pci_controller);
|
|
|
|
return 0;
|
|
diff --git a/arch/mips/pci/pci-lantiq.h b/arch/mips/pci/pci-lantiq.h
|
|
index 66bf6cd..c4721b4 100644
|
|
--- a/arch/mips/pci/pci-lantiq.h
|
|
+++ b/arch/mips/pci/pci-lantiq.h
|
|
@@ -9,7 +9,7 @@
|
|
#ifndef _LTQ_PCI_H__
|
|
#define _LTQ_PCI_H__
|
|
|
|
-extern __iomem void *ltq_pci_mapped_cfg;
|
|
+extern __iomem void *ltq_pci_cfgbase;
|
|
extern int ltq_pci_read_config_dword(struct pci_bus *bus,
|
|
unsigned int devfn, int where, int size, u32 *val);
|
|
extern int ltq_pci_write_config_dword(struct pci_bus *bus,
|
|
diff --git a/arch/mips/pci/pci.c b/arch/mips/pci/pci.c
|
|
index 1552150..cd034a9 100644
|
|
--- a/arch/mips/pci/pci.c
|
|
+++ b/arch/mips/pci/pci.c
|
|
@@ -201,6 +201,31 @@ static int __init pcibios_init(void)
|
|
|
|
subsys_initcall(pcibios_init);
|
|
|
|
+int pcibios_host_nr(void)
|
|
+{
|
|
+ int count;
|
|
+ struct pci_controller *hose;
|
|
+ for (count = 0, hose = hose_head; hose; hose = hose->next, count++) {
|
|
+ ;
|
|
+ }
|
|
+ return count;
|
|
+}
|
|
+EXPORT_SYMBOL(pcibios_host_nr);
|
|
+
|
|
+int pcibios_1st_host_bus_nr(void)
|
|
+{
|
|
+ int bus_nr = 0;
|
|
+ struct pci_controller *hose = hose_head;
|
|
+
|
|
+ if (hose != NULL) {
|
|
+ if (hose->bus != NULL) {
|
|
+ bus_nr = hose->bus->subordinate + 1;
|
|
+ }
|
|
+ }
|
|
+ return bus_nr;
|
|
+}
|
|
+EXPORT_SYMBOL(pcibios_1st_host_bus_nr);
|
|
+
|
|
static int pcibios_enable_resources(struct pci_dev *dev, int mask)
|
|
{
|
|
u16 cmd, old_cmd;
|
|
--
|
|
1.7.9.1
|
|
|