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(&ltq_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