aboutsummaryrefslogtreecommitdiffstats
path: root/arch/mips/lantiq
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2012-12-14 17:27:45 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2012-12-14 17:27:45 -0500
commitcebfa85eb86d92bf85d3b041c6b044184517a988 (patch)
treebe0a374556fe335ce96dfdb296c89537750d5868 /arch/mips/lantiq
parentd42b3a2906a10b732ea7d7f849d49be79d242ef0 (diff)
parent241738bd51cb0efe58e6c570223153e970afe3ae (diff)
Merge branch 'upstream' of git://git.linux-mips.org/pub/scm/ralf/upstream-linus
Pull MIPS updates from Ralf Baechle: "The MIPS bits for 3.8. This also includes a bunch fixes that were sitting in the linux-mips.org git tree for a long time. This pull request contains updates to several OCTEON drivers and the board support code for BCM47XX, BCM63XX, XLP, XLR, XLS, lantiq, Loongson1B, updates to the SSB bus support, MIPS kexec code and adds support for kdump. When pulling this, there are two expected merge conflicts in include/linux/bcma/bcma_driver_chipcommon.h which are trivial to resolve, just remove the conflict markers and keep both alternatives." * 'upstream' of git://git.linux-mips.org/pub/scm/ralf/upstream-linus: (90 commits) MIPS: PMC-Sierra Yosemite: Remove support. VIDEO: Newport Fix console crashes MIPS: wrppmc: Fix build of PCI code. MIPS: IP22/IP28: Fix build of EISA code. MIPS: RB532: Fix build of prom code. MIPS: PowerTV: Fix build. MIPS: IP27: Correct fucked grammar in ops-bridge.c MIPS: Highmem: Fix build error if CONFIG_DEBUG_HIGHMEM is disabled MIPS: Fix potencial corruption MIPS: Fix for warning from FPU emulation code MIPS: Handle COP3 Unusable exception as COP1X for FP emulation MIPS: Fix poweroff failure when HOTPLUG_CPU configured. MIPS: MT: Fix build with CONFIG_UIDGID_STRICT_TYPE_CHECKS=y MIPS: Remove unused smvp.h MIPS/EDAC: Improve OCTEON EDAC support. MIPS: OCTEON: Add definitions for OCTEON memory contoller registers. MIPS: OCTEON: Add OCTEON family definitions to octeon-model.h ata: pata_octeon_cf: Use correct byte order for DMA in when built little-endian. MIPS/OCTEON/ata: Convert pata_octeon_cf.c to use device tree. MIPS: Remove usage of CEVT_R4K_LIB config option. ...
Diffstat (limited to 'arch/mips/lantiq')
-rw-r--r--arch/mips/lantiq/Kconfig4
-rw-r--r--arch/mips/lantiq/prom.c5
-rw-r--r--arch/mips/lantiq/xway/Makefile2
-rw-r--r--arch/mips/lantiq/xway/dma.c15
-rw-r--r--arch/mips/lantiq/xway/reset.c58
-rw-r--r--arch/mips/lantiq/xway/sysctrl.c4
-rw-r--r--arch/mips/lantiq/xway/xrx200_phy_fw.c97
7 files changed, 170 insertions, 15 deletions
diff --git a/arch/mips/lantiq/Kconfig b/arch/mips/lantiq/Kconfig
index d84f361f1e45..c0021912131e 100644
--- a/arch/mips/lantiq/Kconfig
+++ b/arch/mips/lantiq/Kconfig
@@ -36,4 +36,8 @@ config PCI_LANTIQ
36 bool "PCI Support" 36 bool "PCI Support"
37 depends on SOC_XWAY && PCI 37 depends on SOC_XWAY && PCI
38 38
39config XRX200_PHY_FW
40 bool "XRX200 PHY firmware loader"
41 depends on SOC_XWAY
42
39endif 43endif
diff --git a/arch/mips/lantiq/prom.c b/arch/mips/lantiq/prom.c
index 6cfd6117fbfd..9f9e875967aa 100644
--- a/arch/mips/lantiq/prom.c
+++ b/arch/mips/lantiq/prom.c
@@ -87,9 +87,6 @@ void __init device_tree_init(void)
87 reserve_bootmem(base, size, BOOTMEM_DEFAULT); 87 reserve_bootmem(base, size, BOOTMEM_DEFAULT);
88 88
89 unflatten_device_tree(); 89 unflatten_device_tree();
90
91 /* free the space reserved for the dt blob */
92 free_bootmem(base, size);
93} 90}
94 91
95void __init prom_init(void) 92void __init prom_init(void)
@@ -119,7 +116,7 @@ int __init plat_of_setup(void)
119 sizeof(of_ids[0].compatible)); 116 sizeof(of_ids[0].compatible));
120 strncpy(of_ids[1].compatible, "simple-bus", 117 strncpy(of_ids[1].compatible, "simple-bus",
121 sizeof(of_ids[1].compatible)); 118 sizeof(of_ids[1].compatible));
122 return of_platform_bus_probe(NULL, of_ids, NULL); 119 return of_platform_populate(NULL, of_ids, NULL, NULL);
123} 120}
124 121
125arch_initcall(plat_of_setup); 122arch_initcall(plat_of_setup);
diff --git a/arch/mips/lantiq/xway/Makefile b/arch/mips/lantiq/xway/Makefile
index 70a58c747bd0..7a13660d630d 100644
--- a/arch/mips/lantiq/xway/Makefile
+++ b/arch/mips/lantiq/xway/Makefile
@@ -1 +1,3 @@
1obj-y := prom.o sysctrl.o clk.o reset.o dma.o gptu.o 1obj-y := prom.o sysctrl.o clk.o reset.o dma.o gptu.o
2
3obj-$(CONFIG_XRX200_PHY_FW) += xrx200_phy_fw.o
diff --git a/arch/mips/lantiq/xway/dma.c b/arch/mips/lantiq/xway/dma.c
index 55d2c4fa4714..6453962ac898 100644
--- a/arch/mips/lantiq/xway/dma.c
+++ b/arch/mips/lantiq/xway/dma.c
@@ -25,6 +25,7 @@
25#include <lantiq_soc.h> 25#include <lantiq_soc.h>
26#include <xway_dma.h> 26#include <xway_dma.h>
27 27
28#define LTQ_DMA_ID 0x08
28#define LTQ_DMA_CTRL 0x10 29#define LTQ_DMA_CTRL 0x10
29#define LTQ_DMA_CPOLL 0x14 30#define LTQ_DMA_CPOLL 0x14
30#define LTQ_DMA_CS 0x18 31#define LTQ_DMA_CS 0x18
@@ -48,7 +49,7 @@
48#define DMA_CLK_DIV4 BIT(6) /* polling clock divider */ 49#define DMA_CLK_DIV4 BIT(6) /* polling clock divider */
49#define DMA_2W_BURST BIT(1) /* 2 word burst length */ 50#define DMA_2W_BURST BIT(1) /* 2 word burst length */
50#define DMA_MAX_CHANNEL 20 /* the soc has 20 channels */ 51#define DMA_MAX_CHANNEL 20 /* the soc has 20 channels */
51#define DMA_ETOP_ENDIANESS (0xf << 8) /* endianess swap etop channels */ 52#define DMA_ETOP_ENDIANNESS (0xf << 8) /* endianness swap etop channels */
52#define DMA_WEIGHT (BIT(17) | BIT(16)) /* default channel wheight */ 53#define DMA_WEIGHT (BIT(17) | BIT(16)) /* default channel wheight */
53 54
54#define ltq_dma_r32(x) ltq_r32(ltq_dma_membase + (x)) 55#define ltq_dma_r32(x) ltq_r32(ltq_dma_membase + (x))
@@ -191,10 +192,10 @@ ltq_dma_init_port(int p)
191 switch (p) { 192 switch (p) {
192 case DMA_PORT_ETOP: 193 case DMA_PORT_ETOP:
193 /* 194 /*
194 * Tell the DMA engine to swap the endianess of data frames and 195 * Tell the DMA engine to swap the endianness of data frames and
195 * drop packets if the channel arbitration fails. 196 * drop packets if the channel arbitration fails.
196 */ 197 */
197 ltq_dma_w32_mask(0, DMA_ETOP_ENDIANESS | DMA_PDEN, 198 ltq_dma_w32_mask(0, DMA_ETOP_ENDIANNESS | DMA_PDEN,
198 LTQ_DMA_PCTRL); 199 LTQ_DMA_PCTRL);
199 break; 200 break;
200 201
@@ -214,6 +215,7 @@ ltq_dma_init(struct platform_device *pdev)
214{ 215{
215 struct clk *clk; 216 struct clk *clk;
216 struct resource *res; 217 struct resource *res;
218 unsigned id;
217 int i; 219 int i;
218 220
219 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 221 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
@@ -243,7 +245,12 @@ ltq_dma_init(struct platform_device *pdev)
243 ltq_dma_w32(DMA_POLL | DMA_CLK_DIV4, LTQ_DMA_CPOLL); 245 ltq_dma_w32(DMA_POLL | DMA_CLK_DIV4, LTQ_DMA_CPOLL);
244 ltq_dma_w32_mask(DMA_CHAN_ON, 0, LTQ_DMA_CCTRL); 246 ltq_dma_w32_mask(DMA_CHAN_ON, 0, LTQ_DMA_CCTRL);
245 } 247 }
246 dev_info(&pdev->dev, "init done\n"); 248
249 id = ltq_dma_r32(LTQ_DMA_ID);
250 dev_info(&pdev->dev,
251 "Init done - hw rev: %X, ports: %d, channels: %d\n",
252 id & 0x1f, (id >> 16) & 0xf, id >> 20);
253
247 return 0; 254 return 0;
248} 255}
249 256
diff --git a/arch/mips/lantiq/xway/reset.c b/arch/mips/lantiq/xway/reset.c
index 22c55f73aa9d..544dbb7fb421 100644
--- a/arch/mips/lantiq/xway/reset.c
+++ b/arch/mips/lantiq/xway/reset.c
@@ -28,17 +28,24 @@
28#define RCU_RST_REQ 0x0010 28#define RCU_RST_REQ 0x0010
29/* reset status register */ 29/* reset status register */
30#define RCU_RST_STAT 0x0014 30#define RCU_RST_STAT 0x0014
31/* vr9 gphy registers */
32#define RCU_GFS_ADD0_XRX200 0x0020
33#define RCU_GFS_ADD1_XRX200 0x0068
31 34
32/* reboot bit */ 35/* reboot bit */
36#define RCU_RD_GPHY0_XRX200 BIT(31)
33#define RCU_RD_SRST BIT(30) 37#define RCU_RD_SRST BIT(30)
38#define RCU_RD_GPHY1_XRX200 BIT(29)
39
34/* reset cause */ 40/* reset cause */
35#define RCU_STAT_SHIFT 26 41#define RCU_STAT_SHIFT 26
36/* boot selection */ 42/* boot selection */
37#define RCU_BOOT_SEL_SHIFT 26 43#define RCU_BOOT_SEL(x) ((x >> 18) & 0x7)
38#define RCU_BOOT_SEL_MASK 0x7 44#define RCU_BOOT_SEL_XRX200(x) (((x >> 17) & 0xf) | ((x >> 8) & 0x10))
39 45
40/* remapped base addr of the reset control unit */ 46/* remapped base addr of the reset control unit */
41static void __iomem *ltq_rcu_membase; 47static void __iomem *ltq_rcu_membase;
48static struct device_node *ltq_rcu_np;
42 49
43/* This function is used by the watchdog driver */ 50/* This function is used by the watchdog driver */
44int ltq_reset_cause(void) 51int ltq_reset_cause(void)
@@ -52,7 +59,41 @@ EXPORT_SYMBOL_GPL(ltq_reset_cause);
52unsigned char ltq_boot_select(void) 59unsigned char ltq_boot_select(void)
53{ 60{
54 u32 val = ltq_rcu_r32(RCU_RST_STAT); 61 u32 val = ltq_rcu_r32(RCU_RST_STAT);
55 return (val >> RCU_BOOT_SEL_SHIFT) & RCU_BOOT_SEL_MASK; 62
63 if (of_device_is_compatible(ltq_rcu_np, "lantiq,rcu-xrx200"))
64 return RCU_BOOT_SEL_XRX200(val);
65
66 return RCU_BOOT_SEL(val);
67}
68
69/* reset / boot a gphy */
70static struct ltq_xrx200_gphy_reset {
71 u32 rd;
72 u32 addr;
73} xrx200_gphy[] = {
74 {RCU_RD_GPHY0_XRX200, RCU_GFS_ADD0_XRX200},
75 {RCU_RD_GPHY1_XRX200, RCU_GFS_ADD1_XRX200},
76};
77
78/* reset and boot a gphy. these phys only exist on xrx200 SoC */
79int xrx200_gphy_boot(struct device *dev, unsigned int id, dma_addr_t dev_addr)
80{
81 if (!of_device_is_compatible(ltq_rcu_np, "lantiq,rcu-xrx200")) {
82 dev_err(dev, "this SoC has no GPHY\n");
83 return -EINVAL;
84 }
85 if (id > 1) {
86 dev_err(dev, "%u is an invalid gphy id\n", id);
87 return -EINVAL;
88 }
89 dev_info(dev, "booting GPHY%u firmware at %X\n", id, dev_addr);
90
91 ltq_rcu_w32(ltq_rcu_r32(RCU_RST_REQ) | xrx200_gphy[id].rd,
92 RCU_RST_REQ);
93 ltq_rcu_w32(dev_addr, xrx200_gphy[id].addr);
94 ltq_rcu_w32(ltq_rcu_r32(RCU_RST_REQ) & ~xrx200_gphy[id].rd,
95 RCU_RST_REQ);
96 return 0;
56} 97}
57 98
58/* reset a io domain for u micro seconds */ 99/* reset a io domain for u micro seconds */
@@ -85,14 +126,17 @@ static void ltq_machine_power_off(void)
85static int __init mips_reboot_setup(void) 126static int __init mips_reboot_setup(void)
86{ 127{
87 struct resource res; 128 struct resource res;
88 struct device_node *np = 129
89 of_find_compatible_node(NULL, NULL, "lantiq,rcu-xway"); 130 ltq_rcu_np = of_find_compatible_node(NULL, NULL, "lantiq,rcu-xway");
131 if (!ltq_rcu_np)
132 ltq_rcu_np = of_find_compatible_node(NULL, NULL,
133 "lantiq,rcu-xrx200");
90 134
91 /* check if all the reset register range is available */ 135 /* check if all the reset register range is available */
92 if (!np) 136 if (!ltq_rcu_np)
93 panic("Failed to load reset resources from devicetree"); 137 panic("Failed to load reset resources from devicetree");
94 138
95 if (of_address_to_resource(np, 0, &res)) 139 if (of_address_to_resource(ltq_rcu_np, 0, &res))
96 panic("Failed to get rcu memory range"); 140 panic("Failed to get rcu memory range");
97 141
98 if (request_mem_region(res.start, resource_size(&res), res.name) < 0) 142 if (request_mem_region(res.start, resource_size(&res), res.name) < 0)
diff --git a/arch/mips/lantiq/xway/sysctrl.c b/arch/mips/lantiq/xway/sysctrl.c
index 2917b56b6b25..3925e6609acc 100644
--- a/arch/mips/lantiq/xway/sysctrl.c
+++ b/arch/mips/lantiq/xway/sysctrl.c
@@ -370,6 +370,10 @@ void __init ltq_soc_init(void)
370 clkdev_add_pmu("1d900000.pcie", "pdi", 1, PMU1_PCIE_PDI); 370 clkdev_add_pmu("1d900000.pcie", "pdi", 1, PMU1_PCIE_PDI);
371 clkdev_add_pmu("1d900000.pcie", "ctl", 1, PMU1_PCIE_CTL); 371 clkdev_add_pmu("1d900000.pcie", "ctl", 1, PMU1_PCIE_CTL);
372 clkdev_add_pmu("1d900000.pcie", "ahb", 0, PMU_AHBM | PMU_AHBS); 372 clkdev_add_pmu("1d900000.pcie", "ahb", 0, PMU_AHBM | PMU_AHBS);
373 clkdev_add_pmu("1e108000.eth", NULL, 0,
374 PMU_SWITCH | PMU_PPE_DPLUS | PMU_PPE_DPLUM |
375 PMU_PPE_EMA | PMU_PPE_TC | PMU_PPE_SLL01 |
376 PMU_PPE_QSB | PMU_PPE_TOP);
373 } else if (of_machine_is_compatible("lantiq,ar9")) { 377 } else if (of_machine_is_compatible("lantiq,ar9")) {
374 clkdev_add_static(ltq_ar9_cpu_hz(), ltq_ar9_fpi_hz(), 378 clkdev_add_static(ltq_ar9_cpu_hz(), ltq_ar9_fpi_hz(),
375 ltq_ar9_fpi_hz()); 379 ltq_ar9_fpi_hz());
diff --git a/arch/mips/lantiq/xway/xrx200_phy_fw.c b/arch/mips/lantiq/xway/xrx200_phy_fw.c
new file mode 100644
index 000000000000..fe808bf5366d
--- /dev/null
+++ b/arch/mips/lantiq/xway/xrx200_phy_fw.c
@@ -0,0 +1,97 @@
1/*
2 * This program is free software; you can redistribute it and/or modify it
3 * under the terms of the GNU General Public License version 2 as published
4 * by the Free Software Foundation.
5 *
6 * Copyright (C) 2012 John Crispin <blogic@openwrt.org>
7 */
8
9#include <linux/delay.h>
10#include <linux/dma-mapping.h>
11#include <linux/module.h>
12#include <linux/firmware.h>
13#include <linux/of_platform.h>
14
15#include <lantiq_soc.h>
16
17#define XRX200_GPHY_FW_ALIGN (16 * 1024)
18
19static dma_addr_t xway_gphy_load(struct platform_device *pdev)
20{
21 const struct firmware *fw;
22 dma_addr_t dev_addr = 0;
23 const char *fw_name;
24 void *fw_addr;
25 size_t size;
26
27 if (of_property_read_string(pdev->dev.of_node, "firmware", &fw_name)) {
28 dev_err(&pdev->dev, "failed to load firmware filename\n");
29 return 0;
30 }
31
32 dev_info(&pdev->dev, "requesting %s\n", fw_name);
33 if (request_firmware(&fw, fw_name, &pdev->dev)) {
34 dev_err(&pdev->dev, "failed to load firmware: %s\n", fw_name);
35 return 0;
36 }
37
38 /*
39 * GPHY cores need the firmware code in a persistent and contiguous
40 * memory area with a 16 kB boundary aligned start address
41 */
42 size = fw->size + XRX200_GPHY_FW_ALIGN;
43
44 fw_addr = dma_alloc_coherent(&pdev->dev, size, &dev_addr, GFP_KERNEL);
45 if (fw_addr) {
46 fw_addr = PTR_ALIGN(fw_addr, XRX200_GPHY_FW_ALIGN);
47 dev_addr = ALIGN(dev_addr, XRX200_GPHY_FW_ALIGN);
48 memcpy(fw_addr, fw->data, fw->size);
49 } else {
50 dev_err(&pdev->dev, "failed to alloc firmware memory\n");
51 }
52
53 release_firmware(fw);
54 return dev_addr;
55}
56
57static int __devinit xway_phy_fw_probe(struct platform_device *pdev)
58{
59 dma_addr_t fw_addr;
60 struct property *pp;
61 unsigned char *phyids;
62 int i, ret = 0;
63
64 fw_addr = xway_gphy_load(pdev);
65 if (!fw_addr)
66 return -EINVAL;
67 pp = of_find_property(pdev->dev.of_node, "phys", NULL);
68 if (!pp)
69 return -ENOENT;
70 phyids = pp->value;
71 for (i = 0; i < pp->length && !ret; i++)
72 ret = xrx200_gphy_boot(&pdev->dev, phyids[i], fw_addr);
73 if (!ret)
74 mdelay(100);
75 return ret;
76}
77
78static const struct of_device_id xway_phy_match[] = {
79 { .compatible = "lantiq,phy-xrx200" },
80 {},
81};
82MODULE_DEVICE_TABLE(of, xway_phy_match);
83
84static struct platform_driver xway_phy_driver = {
85 .probe = xway_phy_fw_probe,
86 .driver = {
87 .name = "phy-xrx200",
88 .owner = THIS_MODULE,
89 .of_match_table = xway_phy_match,
90 },
91};
92
93module_platform_driver(xway_phy_driver);
94
95MODULE_AUTHOR("John Crispin <blogic@openwrt.org>");
96MODULE_DESCRIPTION("Lantiq XRX200 PHY Firmware Loader");
97MODULE_LICENSE("GPL");