mirror of
git://projects.qi-hardware.com/openwrt-xburst.git
synced 2024-12-24 05:11:46 +02:00
[lantiq] adds 3.6 files, patches and config
git-svn-id: svn://svn.openwrt.org/openwrt/trunk@34061 3c298f89-4303-0410-b956-a3cf2f4a3e73
This commit is contained in:
parent
1048c7b452
commit
4f2c17075b
154
target/linux/lantiq/config-3.6
Normal file
154
target/linux/lantiq/config-3.6
Normal file
@ -0,0 +1,154 @@
|
||||
CONFIG_ARCH_BINFMT_ELF_RANDOMIZE_PIE=y
|
||||
CONFIG_ARCH_DISCARD_MEMBLOCK=y
|
||||
CONFIG_ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE=y
|
||||
CONFIG_ARCH_HAVE_CUSTOM_GPIO_H=y
|
||||
CONFIG_ARCH_HIBERNATION_POSSIBLE=y
|
||||
CONFIG_ARCH_REQUIRE_GPIOLIB=y
|
||||
CONFIG_ARCH_SUSPEND_POSSIBLE=y
|
||||
CONFIG_ARCH_WANT_IPC_PARSE_VERSION=y
|
||||
CONFIG_BCMA_POSSIBLE=y
|
||||
CONFIG_BUILDTIME_EXTABLE_SORT=y
|
||||
CONFIG_CEVT_R4K=y
|
||||
CONFIG_CEVT_R4K_LIB=y
|
||||
CONFIG_CLKDEV_LOOKUP=y
|
||||
CONFIG_CPU_BIG_ENDIAN=y
|
||||
CONFIG_CPU_HAS_PREFETCH=y
|
||||
CONFIG_CPU_HAS_SYNC=y
|
||||
CONFIG_CPU_MIPS32=y
|
||||
# CONFIG_CPU_MIPS32_R1 is not set
|
||||
CONFIG_CPU_MIPS32_R2=y
|
||||
CONFIG_CPU_MIPSR2=y
|
||||
CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y
|
||||
CONFIG_CPU_SUPPORTS_HIGHMEM=y
|
||||
CONFIG_CSRC_R4K=y
|
||||
CONFIG_CSRC_R4K_LIB=y
|
||||
# CONFIG_DEBUG_PINCTRL is not set
|
||||
CONFIG_DECOMPRESS_LZMA=y
|
||||
CONFIG_DMA_NONCOHERENT=y
|
||||
CONFIG_DTC=y
|
||||
# CONFIG_DT_EASY50712 is not set
|
||||
CONFIG_DT_EASY80920=y
|
||||
CONFIG_EARLY_PRINTK=y
|
||||
CONFIG_ETHERNET_PACKET_MANGLE=y
|
||||
CONFIG_GENERIC_ATOMIC64=y
|
||||
CONFIG_GENERIC_CLOCKEVENTS=y
|
||||
CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
|
||||
CONFIG_GENERIC_CMOS_UPDATE=y
|
||||
CONFIG_GENERIC_GPIO=y
|
||||
CONFIG_GENERIC_IO=y
|
||||
CONFIG_GENERIC_IRQ_SHOW=y
|
||||
CONFIG_GENERIC_PCI_IOMAP=y
|
||||
CONFIG_GENERIC_SMP_IDLE_THREAD=y
|
||||
CONFIG_GPIOLIB=y
|
||||
CONFIG_GPIO_MM_LANTIQ=y
|
||||
CONFIG_GPIO_STP_XWAY=y
|
||||
CONFIG_GPIO_SYSFS=y
|
||||
CONFIG_HARDWARE_WATCHPOINTS=y
|
||||
CONFIG_HAS_DMA=y
|
||||
CONFIG_HAS_IOMEM=y
|
||||
CONFIG_HAS_IOPORT=y
|
||||
CONFIG_HAVE_ARCH_JUMP_LABEL=y
|
||||
CONFIG_HAVE_ARCH_KGDB=y
|
||||
CONFIG_HAVE_CLK=y
|
||||
CONFIG_HAVE_C_RECORDMCOUNT=y
|
||||
CONFIG_HAVE_DMA_API_DEBUG=y
|
||||
CONFIG_HAVE_DMA_ATTRS=y
|
||||
CONFIG_HAVE_DYNAMIC_FTRACE=y
|
||||
CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
|
||||
CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
|
||||
CONFIG_HAVE_FUNCTION_TRACER=y
|
||||
CONFIG_HAVE_FUNCTION_TRACE_MCOUNT_TEST=y
|
||||
CONFIG_HAVE_GENERIC_DMA_COHERENT=y
|
||||
CONFIG_HAVE_GENERIC_HARDIRQS=y
|
||||
CONFIG_HAVE_IDE=y
|
||||
CONFIG_HAVE_IRQ_WORK=y
|
||||
CONFIG_HAVE_MACH_CLKDEV=y
|
||||
CONFIG_HAVE_MEMBLOCK=y
|
||||
CONFIG_HAVE_MEMBLOCK_NODE_MAP=y
|
||||
CONFIG_HAVE_OPROFILE=y
|
||||
CONFIG_HAVE_PERF_EVENTS=y
|
||||
CONFIG_HW_HAS_PCI=y
|
||||
CONFIG_HW_RANDOM=y
|
||||
CONFIG_HZ=250
|
||||
# CONFIG_HZ_100 is not set
|
||||
CONFIG_HZ_250=y
|
||||
CONFIG_IMAGE_CMDLINE_HACK=y
|
||||
CONFIG_INITRAMFS_SOURCE=""
|
||||
CONFIG_IRQ_CPU=y
|
||||
CONFIG_IRQ_DOMAIN=y
|
||||
CONFIG_IRQ_FORCED_THREADING=y
|
||||
CONFIG_LANTIQ=y
|
||||
CONFIG_LANTIQ_ETOP=y
|
||||
CONFIG_LANTIQ_PHY=y
|
||||
CONFIG_LANTIQ_WDT=y
|
||||
CONFIG_LANTIQ_XRX200=y
|
||||
CONFIG_LEDS_GPIO=y
|
||||
# CONFIG_MACH_LOONGSON1 is not set
|
||||
CONFIG_MDIO_BOARDINFO=y
|
||||
# CONFIG_MDIO_BUS_MUX_GPIO is not set
|
||||
CONFIG_MIPS=y
|
||||
CONFIG_MIPS_L1_CACHE_SHIFT=5
|
||||
# CONFIG_MIPS_MACHINE is not set
|
||||
CONFIG_MIPS_MT_DISABLED=y
|
||||
# CONFIG_MIPS_MT_SMP is not set
|
||||
# CONFIG_MIPS_MT_SMTC is not set
|
||||
# CONFIG_MIPS_VPE_LOADER is not set
|
||||
CONFIG_MTD_CFI_ADV_OPTIONS=y
|
||||
CONFIG_MTD_CFI_GEOMETRY=y
|
||||
CONFIG_MTD_CMDLINE_PARTS=y
|
||||
CONFIG_MTD_LANTIQ=y
|
||||
CONFIG_MTD_OF_PARTS=y
|
||||
CONFIG_MTD_PHYSMAP_OF=y
|
||||
CONFIG_NEED_DMA_MAP_STATE=y
|
||||
CONFIG_NEED_PER_CPU_KM=y
|
||||
CONFIG_NO_GENERIC_PCI_IOPORT_MAP=y
|
||||
CONFIG_OF=y
|
||||
CONFIG_OF_ADDRESS=y
|
||||
CONFIG_OF_DEVICE=y
|
||||
CONFIG_OF_EARLY_FLATTREE=y
|
||||
CONFIG_OF_FLATTREE=y
|
||||
CONFIG_OF_GPIO=y
|
||||
CONFIG_OF_IRQ=y
|
||||
CONFIG_OF_MDIO=y
|
||||
CONFIG_OF_MTD=y
|
||||
CONFIG_OF_NET=y
|
||||
CONFIG_OF_PCI=y
|
||||
CONFIG_OF_PCI_IRQ=y
|
||||
CONFIG_PAGEFLAGS_EXTENDED=y
|
||||
CONFIG_PANIC_ON_OOPS_VALUE=0
|
||||
CONFIG_PCI=y
|
||||
CONFIG_PCI_DOMAINS=y
|
||||
CONFIG_PCI_LANTIQ=y
|
||||
CONFIG_PERF_USE_VMALLOC=y
|
||||
CONFIG_PHYLIB=y
|
||||
CONFIG_PINCONF=y
|
||||
CONFIG_PINCTRL=y
|
||||
CONFIG_PINCTRL_LANTIQ=y
|
||||
# CONFIG_PINCTRL_SINGLE is not set
|
||||
CONFIG_PINCTRL_XWAY=y
|
||||
CONFIG_PINMUX=y
|
||||
# CONFIG_PREEMPT_RCU is not set
|
||||
CONFIG_PROC_DEVICETREE=y
|
||||
CONFIG_PSB6970_PHY=y
|
||||
CONFIG_RTL8366RB_PHY=y
|
||||
CONFIG_RTL8366_SMI=y
|
||||
# CONFIG_SCSI_DMA is not set
|
||||
# CONFIG_SERIAL_8250 is not set
|
||||
CONFIG_SERIAL_LANTIQ=y
|
||||
# CONFIG_SOC_AMAZON_SE is not set
|
||||
# CONFIG_SOC_FALCON is not set
|
||||
CONFIG_SOC_TYPE_XWAY=y
|
||||
CONFIG_SOC_XWAY=y
|
||||
CONFIG_SWAP_IO_SPACE=y
|
||||
CONFIG_SWCONFIG=y
|
||||
CONFIG_SYS_HAS_CPU_MIPS32_R1=y
|
||||
CONFIG_SYS_HAS_CPU_MIPS32_R2=y
|
||||
CONFIG_SYS_HAS_EARLY_PRINTK=y
|
||||
CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y
|
||||
CONFIG_SYS_SUPPORTS_ARBIT_HZ=y
|
||||
CONFIG_SYS_SUPPORTS_BIG_ENDIAN=y
|
||||
CONFIG_SYS_SUPPORTS_MULTITHREADING=y
|
||||
CONFIG_USB_ARCH_HAS_XHCI=y
|
||||
CONFIG_USE_OF=y
|
||||
CONFIG_XZ_DEC=y
|
||||
CONFIG_ZONE_DMA_FLAG=0
|
BIN
target/linux/lantiq/files-3.6/firmware/lantiq/vr9_phy11g_a1x.bin
Normal file
BIN
target/linux/lantiq/files-3.6/firmware/lantiq/vr9_phy11g_a1x.bin
Normal file
Binary file not shown.
BIN
target/linux/lantiq/files-3.6/firmware/lantiq/vr9_phy11g_a2x.bin
Normal file
BIN
target/linux/lantiq/files-3.6/firmware/lantiq/vr9_phy11g_a2x.bin
Normal file
Binary file not shown.
BIN
target/linux/lantiq/files-3.6/firmware/lantiq/vr9_phy22f_a1x.bin
Normal file
BIN
target/linux/lantiq/files-3.6/firmware/lantiq/vr9_phy22f_a1x.bin
Normal file
Binary file not shown.
BIN
target/linux/lantiq/files-3.6/firmware/lantiq/vr9_phy22f_a2x.bin
Normal file
BIN
target/linux/lantiq/files-3.6/firmware/lantiq/vr9_phy22f_a2x.bin
Normal file
Binary file not shown.
@ -0,0 +1,34 @@
|
||||
From 98dbc5764d8b6fa9cabe316fe725281703bf0fc6 Mon Sep 17 00:00:00 2001
|
||||
From: John Crispin <blogic@openwrt.org>
|
||||
Date: Tue, 24 Jul 2012 08:56:41 +0200
|
||||
Subject: [PATCH] MIPS: lantiq: explicitly enable clkout generation
|
||||
|
||||
Previously we relied on the bootloader to have enabled this bit. However some
|
||||
bootloaders seem to not enable this for us.
|
||||
|
||||
Signed-off-by: John Crispin <blogic@openwrt.org>
|
||||
Patchwork: http://patchwork.linux-mips.org/patch/4120/
|
||||
---
|
||||
arch/mips/lantiq/xway/sysctrl.c | 2 ++
|
||||
1 file changed, 2 insertions(+)
|
||||
|
||||
diff --git a/arch/mips/lantiq/xway/sysctrl.c b/arch/mips/lantiq/xway/sysctrl.c
|
||||
index befbb76..8430983 100644
|
||||
--- a/arch/mips/lantiq/xway/sysctrl.c
|
||||
+++ b/arch/mips/lantiq/xway/sysctrl.c
|
||||
@@ -187,10 +187,12 @@ static int clkout_enable(struct clk *clk)
|
||||
for (i = 0; i < 4; i++) {
|
||||
if (clk->rates[i] == clk->rate) {
|
||||
int shift = 14 - (2 * clk->module);
|
||||
+ int enable = 7 - clk->module;
|
||||
unsigned int val = ltq_cgu_r32(ifccr);
|
||||
|
||||
val &= ~(3 << shift);
|
||||
val |= i << shift;
|
||||
+ val |= enable;
|
||||
ltq_cgu_w32(val, ifccr);
|
||||
return 0;
|
||||
}
|
||||
--
|
||||
1.7.10.4
|
||||
|
@ -0,0 +1,195 @@
|
||||
From 61fa969f27ec58296544bf94d058f3aa704cb8d9 Mon Sep 17 00:00:00 2001
|
||||
From: John Crispin <blogic@openwrt.org>
|
||||
Date: Thu, 16 Aug 2012 11:39:57 +0000
|
||||
Subject: [PATCH 2/9] MIPS: lantiq: split up IRQ IM ranges
|
||||
|
||||
Up to now all our SoCs had the 5 IM ranges in a consecutive order. To accomodate
|
||||
the SVIP we need to support IM ranges that are scattered inside the register range.
|
||||
|
||||
Signed-off-by: John Crispin <blogic@openwrt.org>
|
||||
Patchwork: http://patchwork.linux-mips.org/patch/4237/
|
||||
---
|
||||
.../include/asm/mach-lantiq/falcon/falcon_irq.h | 2 +
|
||||
.../mips/include/asm/mach-lantiq/xway/lantiq_irq.h | 2 +
|
||||
arch/mips/lantiq/irq.c | 60 +++++++++++---------
|
||||
3 files changed, 36 insertions(+), 28 deletions(-)
|
||||
|
||||
diff --git a/arch/mips/include/asm/mach-lantiq/falcon/falcon_irq.h b/arch/mips/include/asm/mach-lantiq/falcon/falcon_irq.h
|
||||
index 318f982..c6b63a4 100644
|
||||
--- a/arch/mips/include/asm/mach-lantiq/falcon/falcon_irq.h
|
||||
+++ b/arch/mips/include/asm/mach-lantiq/falcon/falcon_irq.h
|
||||
@@ -20,4 +20,6 @@
|
||||
|
||||
#define MIPS_CPU_TIMER_IRQ 7
|
||||
|
||||
+#define MAX_IM 5
|
||||
+
|
||||
#endif /* _FALCON_IRQ__ */
|
||||
diff --git a/arch/mips/include/asm/mach-lantiq/xway/lantiq_irq.h b/arch/mips/include/asm/mach-lantiq/xway/lantiq_irq.h
|
||||
index aa0b3b8..5eadfe5 100644
|
||||
--- a/arch/mips/include/asm/mach-lantiq/xway/lantiq_irq.h
|
||||
+++ b/arch/mips/include/asm/mach-lantiq/xway/lantiq_irq.h
|
||||
@@ -21,4 +21,6 @@
|
||||
|
||||
#define MIPS_CPU_TIMER_IRQ 7
|
||||
|
||||
+#define MAX_IM 5
|
||||
+
|
||||
#endif
|
||||
diff --git a/arch/mips/lantiq/irq.c b/arch/mips/lantiq/irq.c
|
||||
index 57c1a4e..a2699a70 100644
|
||||
--- a/arch/mips/lantiq/irq.c
|
||||
+++ b/arch/mips/lantiq/irq.c
|
||||
@@ -55,8 +55,8 @@
|
||||
*/
|
||||
#define LTQ_ICU_EBU_IRQ 22
|
||||
|
||||
-#define ltq_icu_w32(x, y) ltq_w32((x), ltq_icu_membase + (y))
|
||||
-#define ltq_icu_r32(x) ltq_r32(ltq_icu_membase + (x))
|
||||
+#define ltq_icu_w32(m, x, y) ltq_w32((x), ltq_icu_membase[m] + (y))
|
||||
+#define ltq_icu_r32(m, x) ltq_r32(ltq_icu_membase[m] + (x))
|
||||
|
||||
#define ltq_eiu_w32(x, y) ltq_w32((x), ltq_eiu_membase + (y))
|
||||
#define ltq_eiu_r32(x) ltq_r32(ltq_eiu_membase + (x))
|
||||
@@ -82,17 +82,17 @@ static unsigned short ltq_eiu_irq[MAX_EIU] = {
|
||||
};
|
||||
|
||||
static int exin_avail;
|
||||
-static void __iomem *ltq_icu_membase;
|
||||
+static void __iomem *ltq_icu_membase[MAX_IM];
|
||||
static void __iomem *ltq_eiu_membase;
|
||||
|
||||
void ltq_disable_irq(struct irq_data *d)
|
||||
{
|
||||
u32 ier = LTQ_ICU_IM0_IER;
|
||||
int offset = d->hwirq - MIPS_CPU_IRQ_CASCADE;
|
||||
+ int im = offset / INT_NUM_IM_OFFSET;
|
||||
|
||||
- ier += LTQ_ICU_OFFSET * (offset / INT_NUM_IM_OFFSET);
|
||||
offset %= INT_NUM_IM_OFFSET;
|
||||
- ltq_icu_w32(ltq_icu_r32(ier) & ~BIT(offset), ier);
|
||||
+ ltq_icu_w32(im, ltq_icu_r32(im, ier) & ~BIT(offset), ier);
|
||||
}
|
||||
|
||||
void ltq_mask_and_ack_irq(struct irq_data *d)
|
||||
@@ -100,32 +100,31 @@ void ltq_mask_and_ack_irq(struct irq_data *d)
|
||||
u32 ier = LTQ_ICU_IM0_IER;
|
||||
u32 isr = LTQ_ICU_IM0_ISR;
|
||||
int offset = d->hwirq - MIPS_CPU_IRQ_CASCADE;
|
||||
+ int im = offset / INT_NUM_IM_OFFSET;
|
||||
|
||||
- ier += LTQ_ICU_OFFSET * (offset / INT_NUM_IM_OFFSET);
|
||||
- isr += LTQ_ICU_OFFSET * (offset / INT_NUM_IM_OFFSET);
|
||||
offset %= INT_NUM_IM_OFFSET;
|
||||
- ltq_icu_w32(ltq_icu_r32(ier) & ~BIT(offset), ier);
|
||||
- ltq_icu_w32(BIT(offset), isr);
|
||||
+ ltq_icu_w32(im, ltq_icu_r32(im, ier) & ~BIT(offset), ier);
|
||||
+ ltq_icu_w32(im, BIT(offset), isr);
|
||||
}
|
||||
|
||||
static void ltq_ack_irq(struct irq_data *d)
|
||||
{
|
||||
u32 isr = LTQ_ICU_IM0_ISR;
|
||||
int offset = d->hwirq - MIPS_CPU_IRQ_CASCADE;
|
||||
+ int im = offset / INT_NUM_IM_OFFSET;
|
||||
|
||||
- isr += LTQ_ICU_OFFSET * (offset / INT_NUM_IM_OFFSET);
|
||||
offset %= INT_NUM_IM_OFFSET;
|
||||
- ltq_icu_w32(BIT(offset), isr);
|
||||
+ ltq_icu_w32(im, BIT(offset), isr);
|
||||
}
|
||||
|
||||
void ltq_enable_irq(struct irq_data *d)
|
||||
{
|
||||
u32 ier = LTQ_ICU_IM0_IER;
|
||||
int offset = d->hwirq - MIPS_CPU_IRQ_CASCADE;
|
||||
+ int im = offset / INT_NUM_IM_OFFSET;
|
||||
|
||||
- ier += LTQ_ICU_OFFSET * (offset / INT_NUM_IM_OFFSET);
|
||||
offset %= INT_NUM_IM_OFFSET;
|
||||
- ltq_icu_w32(ltq_icu_r32(ier) | BIT(offset), ier);
|
||||
+ ltq_icu_w32(im, ltq_icu_r32(im, ier) | BIT(offset), ier);
|
||||
}
|
||||
|
||||
static unsigned int ltq_startup_eiu_irq(struct irq_data *d)
|
||||
@@ -192,7 +191,7 @@ static void ltq_hw_irqdispatch(int module)
|
||||
{
|
||||
u32 irq;
|
||||
|
||||
- irq = ltq_icu_r32(LTQ_ICU_IM0_IOSR + (module * LTQ_ICU_OFFSET));
|
||||
+ irq = ltq_icu_r32(module, LTQ_ICU_IM0_IOSR);
|
||||
if (irq == 0)
|
||||
return;
|
||||
|
||||
@@ -275,7 +274,7 @@ asmlinkage void plat_irq_dispatch(void)
|
||||
do_IRQ(MIPS_CPU_TIMER_IRQ);
|
||||
goto out;
|
||||
} else {
|
||||
- for (i = 0; i < 5; i++) {
|
||||
+ for (i = 0; i < MAX_IM; i++) {
|
||||
if (pending & (CAUSEF_IP2 << i)) {
|
||||
ltq_hw_irqdispatch(i);
|
||||
goto out;
|
||||
@@ -318,15 +317,19 @@ int __init icu_of_init(struct device_node *node, struct device_node *parent)
|
||||
struct resource res;
|
||||
int i;
|
||||
|
||||
- if (of_address_to_resource(node, 0, &res))
|
||||
- panic("Failed to get icu memory range");
|
||||
+ for (i = 0; i < MAX_IM; i++) {
|
||||
+ if (of_address_to_resource(node, i, &res))
|
||||
+ panic("Failed to get icu memory range");
|
||||
|
||||
- if (request_mem_region(res.start, resource_size(&res), res.name) < 0)
|
||||
- pr_err("Failed to request icu memory");
|
||||
+ if (request_mem_region(res.start, resource_size(&res),
|
||||
+ res.name) < 0)
|
||||
+ pr_err("Failed to request icu memory");
|
||||
|
||||
- ltq_icu_membase = ioremap_nocache(res.start, resource_size(&res));
|
||||
- if (!ltq_icu_membase)
|
||||
- panic("Failed to remap icu memory");
|
||||
+ ltq_icu_membase[i] = ioremap_nocache(res.start,
|
||||
+ resource_size(&res));
|
||||
+ if (!ltq_icu_membase[i])
|
||||
+ panic("Failed to remap icu memory");
|
||||
+ }
|
||||
|
||||
/* the external interrupts are optional and xway only */
|
||||
eiu_node = of_find_compatible_node(NULL, NULL, "lantiq,eiu");
|
||||
@@ -351,17 +354,17 @@ int __init icu_of_init(struct device_node *node, struct device_node *parent)
|
||||
}
|
||||
|
||||
/* turn off all irqs by default */
|
||||
- for (i = 0; i < 5; i++) {
|
||||
+ for (i = 0; i < MAX_IM; i++) {
|
||||
/* make sure all irqs are turned off by default */
|
||||
- ltq_icu_w32(0, LTQ_ICU_IM0_IER + (i * LTQ_ICU_OFFSET));
|
||||
+ ltq_icu_w32(i, 0, LTQ_ICU_IM0_IER);
|
||||
/* clear all possibly pending interrupts */
|
||||
- ltq_icu_w32(~0, LTQ_ICU_IM0_ISR + (i * LTQ_ICU_OFFSET));
|
||||
+ ltq_icu_w32(i, ~0, LTQ_ICU_IM0_ISR);
|
||||
}
|
||||
|
||||
mips_cpu_irq_init();
|
||||
|
||||
- for (i = 2; i <= 6; i++)
|
||||
- setup_irq(i, &cascade);
|
||||
+ for (i = 0; i < MAX_IM; i++)
|
||||
+ setup_irq(i + 2, &cascade);
|
||||
|
||||
if (cpu_has_vint) {
|
||||
pr_info("Setting up vectored interrupts\n");
|
||||
@@ -373,7 +376,8 @@ int __init icu_of_init(struct device_node *node, struct device_node *parent)
|
||||
set_vi_handler(7, ltq_hw5_irqdispatch);
|
||||
}
|
||||
|
||||
- irq_domain_add_linear(node, 6 * INT_NUM_IM_OFFSET,
|
||||
+ irq_domain_add_linear(node,
|
||||
+ (MAX_IM * INT_NUM_IM_OFFSET) + MIPS_CPU_IRQ_CASCADE,
|
||||
&irq_domain_ops, 0);
|
||||
|
||||
#if defined(CONFIG_MIPS_MT_SMP)
|
||||
--
|
||||
1.7.10.4
|
||||
|
@ -0,0 +1,84 @@
|
||||
From c2c9c788b91218bccbb9ac31539ffa577fe502bf Mon Sep 17 00:00:00 2001
|
||||
From: John Crispin <blogic@openwrt.org>
|
||||
Date: Thu, 16 Aug 2012 08:09:20 +0000
|
||||
Subject: [PATCH 3/9] MIPS: lantiq: timer irq can be different to 7
|
||||
|
||||
The SVIP SoC has its timer IRQ on a different IRQ than 7. Fix up the irq
|
||||
code to be able to handle this.
|
||||
|
||||
Signed-off-by: John Crispin <blogic@openwrt.org>
|
||||
Patchwork: http://patchwork.linux-mips.org/patch/4229/
|
||||
---
|
||||
arch/mips/lantiq/irq.c | 19 ++++++++++++++++---
|
||||
1 file changed, 16 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/arch/mips/lantiq/irq.c b/arch/mips/lantiq/irq.c
|
||||
index a2699a70..0cec43d 100644
|
||||
--- a/arch/mips/lantiq/irq.c
|
||||
+++ b/arch/mips/lantiq/irq.c
|
||||
@@ -84,6 +84,7 @@ static unsigned short ltq_eiu_irq[MAX_EIU] = {
|
||||
static int exin_avail;
|
||||
static void __iomem *ltq_icu_membase[MAX_IM];
|
||||
static void __iomem *ltq_eiu_membase;
|
||||
+static struct irq_domain *ltq_domain;
|
||||
|
||||
void ltq_disable_irq(struct irq_data *d)
|
||||
{
|
||||
@@ -219,10 +220,14 @@ DEFINE_HWx_IRQDISPATCH(2)
|
||||
DEFINE_HWx_IRQDISPATCH(3)
|
||||
DEFINE_HWx_IRQDISPATCH(4)
|
||||
|
||||
+#if MIPS_CPU_TIMER_IRQ == 7
|
||||
static void ltq_hw5_irqdispatch(void)
|
||||
{
|
||||
do_IRQ(MIPS_CPU_TIMER_IRQ);
|
||||
}
|
||||
+#else
|
||||
+DEFINE_HWx_IRQDISPATCH(5)
|
||||
+#endif
|
||||
|
||||
#ifdef CONFIG_MIPS_MT_SMP
|
||||
void __init arch_init_ipiirq(int irq, struct irqaction *action)
|
||||
@@ -270,7 +275,7 @@ asmlinkage void plat_irq_dispatch(void)
|
||||
unsigned int pending = read_c0_status() & read_c0_cause() & ST0_IM;
|
||||
unsigned int i;
|
||||
|
||||
- if (pending & CAUSEF_IP7) {
|
||||
+ if ((MIPS_CPU_TIMER_IRQ == 7) && (pending & CAUSEF_IP7)) {
|
||||
do_IRQ(MIPS_CPU_TIMER_IRQ);
|
||||
goto out;
|
||||
} else {
|
||||
@@ -376,7 +381,7 @@ int __init icu_of_init(struct device_node *node, struct device_node *parent)
|
||||
set_vi_handler(7, ltq_hw5_irqdispatch);
|
||||
}
|
||||
|
||||
- irq_domain_add_linear(node,
|
||||
+ ltq_domain = irq_domain_add_linear(node,
|
||||
(MAX_IM * INT_NUM_IM_OFFSET) + MIPS_CPU_IRQ_CASCADE,
|
||||
&irq_domain_ops, 0);
|
||||
|
||||
@@ -401,12 +406,20 @@ int __init icu_of_init(struct device_node *node, struct device_node *parent)
|
||||
|
||||
/* tell oprofile which irq to use */
|
||||
cp0_perfcount_irq = LTQ_PERF_IRQ;
|
||||
+
|
||||
+ /*
|
||||
+ * if the timer irq is not one of the mips irqs we need to
|
||||
+ * create a mapping
|
||||
+ */
|
||||
+ if (MIPS_CPU_TIMER_IRQ != 7)
|
||||
+ irq_create_mapping(ltq_domain, MIPS_CPU_TIMER_IRQ);
|
||||
+
|
||||
return 0;
|
||||
}
|
||||
|
||||
unsigned int __cpuinit get_c0_compare_int(void)
|
||||
{
|
||||
- return CP0_LEGACY_COMPARE_IRQ;
|
||||
+ return MIPS_CPU_TIMER_IRQ;
|
||||
}
|
||||
|
||||
static struct of_device_id __initdata of_irq_ids[] = {
|
||||
--
|
||||
1.7.10.4
|
||||
|
@ -0,0 +1,30 @@
|
||||
From 9c1628b603ee9d2bb220be0400c5dc6950cf012b Mon Sep 17 00:00:00 2001
|
||||
From: John Crispin <blogic@openwrt.org>
|
||||
Date: Thu, 16 Aug 2012 08:09:21 +0000
|
||||
Subject: [PATCH 4/9] MIPS: lantiq: dont register irq_chip for the irq cascade
|
||||
|
||||
We dont want to register the irq_chip for the MIPS IRQ cascade.
|
||||
|
||||
Signed-off-by: John Crispin <blogic@openwrt.org>
|
||||
Patchwork: http://patchwork.linux-mips.org/patch/4230/
|
||||
---
|
||||
arch/mips/lantiq/irq.c | 3 +++
|
||||
1 file changed, 3 insertions(+)
|
||||
|
||||
diff --git a/arch/mips/lantiq/irq.c b/arch/mips/lantiq/irq.c
|
||||
index 0cec43d..87f15d6 100644
|
||||
--- a/arch/mips/lantiq/irq.c
|
||||
+++ b/arch/mips/lantiq/irq.c
|
||||
@@ -297,6 +297,9 @@ static int icu_map(struct irq_domain *d, unsigned int irq, irq_hw_number_t hw)
|
||||
struct irq_chip *chip = <q_irq_type;
|
||||
int i;
|
||||
|
||||
+ if (hw < MIPS_CPU_IRQ_CASCADE)
|
||||
+ return 0;
|
||||
+
|
||||
for (i = 0; i < exin_avail; i++)
|
||||
if (hw == ltq_eiu_irq[i])
|
||||
chip = <q_eiu_type;
|
||||
--
|
||||
1.7.10.4
|
||||
|
@ -0,0 +1,31 @@
|
||||
From 70ec9054e7a65c878298666083f7d5b70ccf9032 Mon Sep 17 00:00:00 2001
|
||||
From: John Crispin <blogic@openwrt.org>
|
||||
Date: Thu, 16 Aug 2012 08:09:22 +0000
|
||||
Subject: [PATCH 5/9] MIPS: lantiq: external irq sources are not loaded
|
||||
properly
|
||||
|
||||
Support for the external interrupt unit was broken when the code was converted
|
||||
to devicetree support.
|
||||
|
||||
Signed-off-by: John Crispin <blogic@openwrt.org>
|
||||
Patchwork: http://patchwork.linux-mips.org/patch/4231/
|
||||
---
|
||||
arch/mips/lantiq/irq.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/arch/mips/lantiq/irq.c b/arch/mips/lantiq/irq.c
|
||||
index 87f15d6..f36acd1 100644
|
||||
--- a/arch/mips/lantiq/irq.c
|
||||
+++ b/arch/mips/lantiq/irq.c
|
||||
@@ -341,7 +341,7 @@ int __init icu_of_init(struct device_node *node, struct device_node *parent)
|
||||
|
||||
/* the external interrupts are optional and xway only */
|
||||
eiu_node = of_find_compatible_node(NULL, NULL, "lantiq,eiu");
|
||||
- if (eiu_node && of_address_to_resource(eiu_node, 0, &res)) {
|
||||
+ if (eiu_node && !of_address_to_resource(eiu_node, 0, &res)) {
|
||||
/* find out how many external irq sources we have */
|
||||
const __be32 *count = of_get_property(node,
|
||||
"lantiq,count", NULL);
|
||||
--
|
||||
1.7.10.4
|
||||
|
@ -0,0 +1,39 @@
|
||||
From f8cd170dabeca90c976e6487ba7a8a7752aae571 Mon Sep 17 00:00:00 2001
|
||||
From: John Crispin <blogic@openwrt.org>
|
||||
Date: Thu, 16 Aug 2012 11:39:56 +0000
|
||||
Subject: [PATCH 6/9] MIPS: lantiq: adds support for nmi and ejtag bootrom
|
||||
vectors
|
||||
|
||||
Register nmi and ejtag bootrom vectors for FALC-ON SoC.
|
||||
|
||||
Signed-off-by: Thomas Langer <thomas.langer@lantiq.com>
|
||||
Signed-off-by: John Crispin <blogic@openwrt.org>
|
||||
Patchwork: http://patchwork.linux-mips.org/patch/4238/
|
||||
---
|
||||
arch/mips/lantiq/falcon/prom.c | 5 +++++
|
||||
1 file changed, 5 insertions(+)
|
||||
|
||||
diff --git a/arch/mips/lantiq/falcon/prom.c b/arch/mips/lantiq/falcon/prom.c
|
||||
index c1d278f..aa94979 100644
|
||||
--- a/arch/mips/lantiq/falcon/prom.c
|
||||
+++ b/arch/mips/lantiq/falcon/prom.c
|
||||
@@ -8,6 +8,8 @@
|
||||
*/
|
||||
|
||||
#include <linux/kernel.h>
|
||||
+#include <asm/cacheflush.h>
|
||||
+#include <asm/traps.h>
|
||||
#include <asm/io.h>
|
||||
|
||||
#include <lantiq_soc.h>
|
||||
@@ -84,4 +86,7 @@ void __init ltq_soc_detect(struct ltq_soc_info *i)
|
||||
unreachable();
|
||||
break;
|
||||
}
|
||||
+
|
||||
+ board_nmi_handler_setup = ltq_soc_nmi_setup;
|
||||
+ board_ejtag_handler_setup = ltq_soc_ejtag_setup;
|
||||
}
|
||||
--
|
||||
1.7.10.4
|
||||
|
@ -0,0 +1,30 @@
|
||||
From 3a6ac5004c7c8b140319439f8b1f3f6d4cbfe67a Mon Sep 17 00:00:00 2001
|
||||
From: John Crispin <blogic@openwrt.org>
|
||||
Date: Thu, 16 Aug 2012 08:25:41 +0000
|
||||
Subject: [PATCH 7/9] MIPS: lantiq: falcon clocks were not enabled properly
|
||||
|
||||
As a result of a non populated ->bits field inside the clock struct, the clock
|
||||
domains were never powered on the Falcon. Until now we only used domains that
|
||||
were also used and powered by the bootloader.
|
||||
|
||||
Signed-off-by: John Crispin <blogic@openwrt.org>
|
||||
Patchwork: http://patchwork.linux-mips.org/patch/4234/
|
||||
---
|
||||
arch/mips/lantiq/falcon/sysctrl.c | 1 +
|
||||
1 file changed, 1 insertion(+)
|
||||
|
||||
diff --git a/arch/mips/lantiq/falcon/sysctrl.c b/arch/mips/lantiq/falcon/sysctrl.c
|
||||
index ba0123d..2d4ced3 100644
|
||||
--- a/arch/mips/lantiq/falcon/sysctrl.c
|
||||
+++ b/arch/mips/lantiq/falcon/sysctrl.c
|
||||
@@ -171,6 +171,7 @@ static inline void clkdev_add_sys(const char *dev, unsigned int module,
|
||||
clk->cl.con_id = NULL;
|
||||
clk->cl.clk = clk;
|
||||
clk->module = module;
|
||||
+ clk->bits = bits;
|
||||
clk->activate = sysctl_activate;
|
||||
clk->deactivate = sysctl_deactivate;
|
||||
clk->enable = sysctl_clken;
|
||||
--
|
||||
1.7.10.4
|
||||
|
@ -0,0 +1,31 @@
|
||||
From f40e1f9d856ec417468c090c4b56826171daa670 Mon Sep 17 00:00:00 2001
|
||||
From: John Crispin <blogic@openwrt.org>
|
||||
Date: Thu, 16 Aug 2012 08:25:42 +0000
|
||||
Subject: [PATCH 8/9] MIPS: lantiq: enable pci clk conditional for xrx200 SoC
|
||||
|
||||
The xrx200 SoC family has the same PCI clock register layout as the AR9.
|
||||
Enable the same quirk as for AR9
|
||||
|
||||
Signed-off-by: John Crispin <blogic@openwrt.org>
|
||||
Patchwork: http://patchwork.linux-mips.org/patch/4235/
|
||||
---
|
||||
arch/mips/lantiq/xway/sysctrl.c | 3 ++-
|
||||
1 file changed, 2 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/arch/mips/lantiq/xway/sysctrl.c b/arch/mips/lantiq/xway/sysctrl.c
|
||||
index befbb76..67c3a91 100644
|
||||
--- a/arch/mips/lantiq/xway/sysctrl.c
|
||||
+++ b/arch/mips/lantiq/xway/sysctrl.c
|
||||
@@ -145,7 +145,8 @@ static int pci_enable(struct clk *clk)
|
||||
{
|
||||
unsigned int val = ltq_cgu_r32(ifccr);
|
||||
/* set bus clock speed */
|
||||
- if (of_machine_is_compatible("lantiq,ar9")) {
|
||||
+ if (of_machine_is_compatible("lantiq,ar9") ||
|
||||
+ of_machine_is_compatible("lantiq,vr9")) {
|
||||
val &= ~0x1f00000;
|
||||
if (clk->rate == CLOCK_33M)
|
||||
val |= 0xe00000;
|
||||
--
|
||||
1.7.10.4
|
||||
|
@ -0,0 +1,246 @@
|
||||
From 30404aec4d093942ba67ded8e1926cbf4472d4f7 Mon Sep 17 00:00:00 2001
|
||||
From: John Crispin <blogic@openwrt.org>
|
||||
Date: Thu, 16 Aug 2012 11:31:02 +0000
|
||||
Subject: [PATCH 9/9] MIPS: lantiq: adds support for gptu timers
|
||||
|
||||
Lantiq socs have a General Purpose Timer Unit (GPTU). This driver allows us to
|
||||
initialize the timers. The voice firmware needs these timers as a reference.
|
||||
|
||||
Signed-off-by: John Crispin <blogic@openwrt.org>
|
||||
Patchwork: http://patchwork.linux-mips.org/patch/4236/
|
||||
---
|
||||
arch/mips/lantiq/xway/Makefile | 2 +-
|
||||
arch/mips/lantiq/xway/gptu.c | 214 ++++++++++++++++++++++++++++++++++++++++
|
||||
2 files changed, 215 insertions(+), 1 deletion(-)
|
||||
create mode 100644 arch/mips/lantiq/xway/gptu.c
|
||||
|
||||
diff --git a/arch/mips/lantiq/xway/Makefile b/arch/mips/lantiq/xway/Makefile
|
||||
index dc3194f..f7053b8 100644
|
||||
--- a/arch/mips/lantiq/xway/Makefile
|
||||
+++ b/arch/mips/lantiq/xway/Makefile
|
||||
@@ -1 +1 @@
|
||||
-obj-y := prom.o sysctrl.o clk.o reset.o gpio.o dma.o
|
||||
+obj-y := prom.o sysctrl.o clk.o reset.o gpio.o dma.o gptu.o
|
||||
diff --git a/arch/mips/lantiq/xway/gptu.c b/arch/mips/lantiq/xway/gptu.c
|
||||
new file mode 100644
|
||||
index 0000000..cbb56fc
|
||||
--- /dev/null
|
||||
+++ b/arch/mips/lantiq/xway/gptu.c
|
||||
@@ -0,0 +1,214 @@
|
||||
+/*
|
||||
+ * 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.
|
||||
+ *
|
||||
+ * Copyright (C) 2012 John Crispin <blogic@openwrt.org>
|
||||
+ * Copyright (C) 2012 Lantiq GmbH
|
||||
+ */
|
||||
+
|
||||
+#include <linux/interrupt.h>
|
||||
+#include <linux/ioport.h>
|
||||
+#include <linux/module.h>
|
||||
+#include <linux/of_platform.h>
|
||||
+#include <linux/of_irq.h>
|
||||
+
|
||||
+#include <lantiq_soc.h>
|
||||
+#include "../clk.h"
|
||||
+
|
||||
+/* the magic ID byte of the core */
|
||||
+#define GPTU_MAGIC 0x59
|
||||
+/* clock control register */
|
||||
+#define GPTU_CLC 0x00
|
||||
+/* id register */
|
||||
+#define GPTU_ID 0x08
|
||||
+/* interrupt node enable */
|
||||
+#define GPTU_IRNEN 0xf4
|
||||
+/* interrupt control register */
|
||||
+#define GPTU_IRCR 0xf8
|
||||
+/* interrupt capture register */
|
||||
+#define GPTU_IRNCR 0xfc
|
||||
+/* there are 3 identical blocks of 2 timers. calculate register offsets */
|
||||
+#define GPTU_SHIFT(x) (x % 2 ? 4 : 0)
|
||||
+#define GPTU_BASE(x) (((x >> 1) * 0x20) + 0x10)
|
||||
+/* timer control register */
|
||||
+#define GPTU_CON(x) (GPTU_BASE(x) + GPTU_SHIFT(x) + 0x00)
|
||||
+/* timer auto reload register */
|
||||
+#define GPTU_RUN(x) (GPTU_BASE(x) + GPTU_SHIFT(x) + 0x08)
|
||||
+/* timer manual reload register */
|
||||
+#define GPTU_RLD(x) (GPTU_BASE(x) + GPTU_SHIFT(x) + 0x10)
|
||||
+/* timer count register */
|
||||
+#define GPTU_CNT(x) (GPTU_BASE(x) + GPTU_SHIFT(x) + 0x18)
|
||||
+
|
||||
+/* GPTU_CON(x) */
|
||||
+#define CON_CNT BIT(2)
|
||||
+#define CON_EDGE_ANY (BIT(7) | BIT(6))
|
||||
+#define CON_SYNC BIT(8)
|
||||
+#define CON_CLK_INT BIT(10)
|
||||
+
|
||||
+/* GPTU_RUN(x) */
|
||||
+#define RUN_SEN BIT(0)
|
||||
+#define RUN_RL BIT(2)
|
||||
+
|
||||
+/* set clock to runmode */
|
||||
+#define CLC_RMC BIT(8)
|
||||
+/* bring core out of suspend */
|
||||
+#define CLC_SUSPEND BIT(4)
|
||||
+/* the disable bit */
|
||||
+#define CLC_DISABLE BIT(0)
|
||||
+
|
||||
+#define gptu_w32(x, y) ltq_w32((x), gptu_membase + (y))
|
||||
+#define gptu_r32(x) ltq_r32(gptu_membase + (x))
|
||||
+
|
||||
+enum gptu_timer {
|
||||
+ TIMER1A = 0,
|
||||
+ TIMER1B,
|
||||
+ TIMER2A,
|
||||
+ TIMER2B,
|
||||
+ TIMER3A,
|
||||
+ TIMER3B
|
||||
+};
|
||||
+
|
||||
+static void __iomem *gptu_membase;
|
||||
+static struct resource irqres[6];
|
||||
+
|
||||
+static irqreturn_t timer_irq_handler(int irq, void *priv)
|
||||
+{
|
||||
+ int timer = irq - irqres[0].start;
|
||||
+ gptu_w32(1 << timer, GPTU_IRNCR);
|
||||
+ return IRQ_HANDLED;
|
||||
+}
|
||||
+
|
||||
+static void gptu_hwinit(void)
|
||||
+{
|
||||
+ gptu_w32(0x00, GPTU_IRNEN);
|
||||
+ gptu_w32(0xff, GPTU_IRNCR);
|
||||
+ gptu_w32(CLC_RMC | CLC_SUSPEND, GPTU_CLC);
|
||||
+}
|
||||
+
|
||||
+static void gptu_hwexit(void)
|
||||
+{
|
||||
+ gptu_w32(0x00, GPTU_IRNEN);
|
||||
+ gptu_w32(0xff, GPTU_IRNCR);
|
||||
+ gptu_w32(CLC_DISABLE, GPTU_CLC);
|
||||
+}
|
||||
+
|
||||
+static int gptu_enable(struct clk *clk)
|
||||
+{
|
||||
+ int ret = request_irq(irqres[clk->bits].start, timer_irq_handler,
|
||||
+ IRQF_TIMER, "gtpu", NULL);
|
||||
+ if (ret) {
|
||||
+ pr_err("gptu: failed to request irq\n");
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ gptu_w32(CON_CNT | CON_EDGE_ANY | CON_SYNC | CON_CLK_INT,
|
||||
+ GPTU_CON(clk->bits));
|
||||
+ gptu_w32(1, GPTU_RLD(clk->bits));
|
||||
+ gptu_w32(gptu_r32(GPTU_IRNEN) | BIT(clk->bits), GPTU_IRNEN);
|
||||
+ gptu_w32(RUN_SEN | RUN_RL, GPTU_RUN(clk->bits));
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static void gptu_disable(struct clk *clk)
|
||||
+{
|
||||
+ gptu_w32(0, GPTU_RUN(clk->bits));
|
||||
+ gptu_w32(0, GPTU_CON(clk->bits));
|
||||
+ gptu_w32(0, GPTU_RLD(clk->bits));
|
||||
+ gptu_w32(gptu_r32(GPTU_IRNEN) & ~BIT(clk->bits), GPTU_IRNEN);
|
||||
+ free_irq(irqres[clk->bits].start, NULL);
|
||||
+}
|
||||
+
|
||||
+static inline void clkdev_add_gptu(struct device *dev, const char *con,
|
||||
+ unsigned int timer)
|
||||
+{
|
||||
+ struct clk *clk = kzalloc(sizeof(struct clk), GFP_KERNEL);
|
||||
+
|
||||
+ clk->cl.dev_id = dev_name(dev);
|
||||
+ clk->cl.con_id = con;
|
||||
+ clk->cl.clk = clk;
|
||||
+ clk->enable = gptu_enable;
|
||||
+ clk->disable = gptu_disable;
|
||||
+ clk->bits = timer;
|
||||
+ clkdev_add(&clk->cl);
|
||||
+}
|
||||
+
|
||||
+static int __devinit gptu_probe(struct platform_device *pdev)
|
||||
+{
|
||||
+ struct clk *clk;
|
||||
+ struct resource *res;
|
||||
+
|
||||
+ if (of_irq_to_resource_table(pdev->dev.of_node, irqres, 6) != 6) {
|
||||
+ dev_err(&pdev->dev, "Failed to get IRQ list\n");
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+
|
||||
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
+ if (!res) {
|
||||
+ dev_err(&pdev->dev, "Failed to get resource\n");
|
||||
+ return -ENOMEM;
|
||||
+ }
|
||||
+
|
||||
+ /* remap gptu register range */
|
||||
+ gptu_membase = devm_request_and_ioremap(&pdev->dev, res);
|
||||
+ if (!gptu_membase) {
|
||||
+ dev_err(&pdev->dev, "Failed to remap resource\n");
|
||||
+ return -ENOMEM;
|
||||
+ }
|
||||
+
|
||||
+ /* enable our clock */
|
||||
+ clk = clk_get(&pdev->dev, NULL);
|
||||
+ if (IS_ERR(clk)) {
|
||||
+ dev_err(&pdev->dev, "Failed to get clock\n");
|
||||
+ return -ENOENT;
|
||||
+ }
|
||||
+ clk_enable(clk);
|
||||
+
|
||||
+ /* power up the core */
|
||||
+ gptu_hwinit();
|
||||
+
|
||||
+ /* the gptu has a ID register */
|
||||
+ if (((gptu_r32(GPTU_ID) >> 8) & 0xff) != GPTU_MAGIC) {
|
||||
+ dev_err(&pdev->dev, "Failed to find magic\n");
|
||||
+ gptu_hwexit();
|
||||
+ return -ENAVAIL;
|
||||
+ }
|
||||
+
|
||||
+ /* register the clocks */
|
||||
+ clkdev_add_gptu(&pdev->dev, "timer1a", TIMER1A);
|
||||
+ clkdev_add_gptu(&pdev->dev, "timer1b", TIMER1B);
|
||||
+ clkdev_add_gptu(&pdev->dev, "timer2a", TIMER2A);
|
||||
+ clkdev_add_gptu(&pdev->dev, "timer2b", TIMER2B);
|
||||
+ clkdev_add_gptu(&pdev->dev, "timer3a", TIMER3A);
|
||||
+ clkdev_add_gptu(&pdev->dev, "timer3b", TIMER3B);
|
||||
+
|
||||
+ dev_info(&pdev->dev, "gptu: 6 timers loaded\n");
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static const struct of_device_id gptu_match[] = {
|
||||
+ { .compatible = "lantiq,gptu-xway" },
|
||||
+ {},
|
||||
+};
|
||||
+MODULE_DEVICE_TABLE(of, dma_match);
|
||||
+
|
||||
+static struct platform_driver dma_driver = {
|
||||
+ .probe = gptu_probe,
|
||||
+ .driver = {
|
||||
+ .name = "gptu-xway",
|
||||
+ .owner = THIS_MODULE,
|
||||
+ .of_match_table = gptu_match,
|
||||
+ },
|
||||
+};
|
||||
+
|
||||
+int __init gptu_init(void)
|
||||
+{
|
||||
+ int ret = platform_driver_register(&dma_driver);
|
||||
+
|
||||
+ if (ret)
|
||||
+ pr_info("gptu: Error registering platform driver\n");
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+arch_initcall(gptu_init);
|
||||
--
|
||||
1.7.10.4
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,554 @@
|
||||
From e316cb2b16bbfbe48387b56e7e6b5d32ec686f82 Mon Sep 17 00:00:00 2001
|
||||
From: John Crispin <blogic@openwrt.org>
|
||||
Date: Sun, 20 May 2012 00:33:56 +0200
|
||||
Subject: [PATCH 11/15] OF: pinctrl: MIPS: lantiq: adds support for FALCON SoC
|
||||
|
||||
Implement support for pinctrl on lantiq/falcon socs. The FALCON has 5 banks
|
||||
of up to 32 pins.
|
||||
|
||||
Signed-off-by: John Crispin <blogic@openwrt.org>
|
||||
Signed-off-by: Thomas Langer <thomas.langer@lantiq.com>
|
||||
Acked-by: Linus Walleij <linus.walleij@linaro.org>
|
||||
Cc: devicetree-discuss@lists.ozlabs.org
|
||||
Cc: linux-kernel@vger.kernel.org
|
||||
---
|
||||
.../include/asm/mach-lantiq/falcon/lantiq_soc.h | 4 +
|
||||
arch/mips/lantiq/Kconfig | 1 +
|
||||
drivers/pinctrl/Kconfig | 5 +
|
||||
drivers/pinctrl/Makefile | 1 +
|
||||
drivers/pinctrl/pinctrl-falcon.c | 468 ++++++++++++++++++++
|
||||
5 files changed, 479 insertions(+)
|
||||
create mode 100644 drivers/pinctrl/pinctrl-falcon.c
|
||||
|
||||
diff --git a/arch/mips/include/asm/mach-lantiq/falcon/lantiq_soc.h b/arch/mips/include/asm/mach-lantiq/falcon/lantiq_soc.h
|
||||
index b385252..fccac35 100644
|
||||
--- a/arch/mips/include/asm/mach-lantiq/falcon/lantiq_soc.h
|
||||
+++ b/arch/mips/include/asm/mach-lantiq/falcon/lantiq_soc.h
|
||||
@@ -57,6 +57,10 @@ extern __iomem void *ltq_sys1_membase;
|
||||
#define ltq_sys1_w32_mask(clear, set, reg) \
|
||||
ltq_sys1_w32((ltq_sys1_r32(reg) & ~(clear)) | (set), reg)
|
||||
|
||||
+/* allow the gpio and pinctrl drivers to talk to eachother */
|
||||
+extern int pinctrl_falcon_get_range_size(int id);
|
||||
+extern void pinctrl_falcon_add_gpio_range(struct pinctrl_gpio_range *range);
|
||||
+
|
||||
/*
|
||||
* to keep the irq code generic we need to define this to 0 as falcon
|
||||
* has no EIU/EBU
|
||||
diff --git a/arch/mips/lantiq/Kconfig b/arch/mips/lantiq/Kconfig
|
||||
index 080c013..d84f361 100644
|
||||
--- a/arch/mips/lantiq/Kconfig
|
||||
+++ b/arch/mips/lantiq/Kconfig
|
||||
@@ -20,6 +20,7 @@ config SOC_XWAY
|
||||
|
||||
config SOC_FALCON
|
||||
bool "FALCON"
|
||||
+ select PINCTRL_FALCON
|
||||
|
||||
endchoice
|
||||
|
||||
diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig
|
||||
index f77dce0..45d2158 100644
|
||||
--- a/drivers/pinctrl/Kconfig
|
||||
+++ b/drivers/pinctrl/Kconfig
|
||||
@@ -65,6 +65,11 @@ config PINCTRL_PXA3xx
|
||||
bool
|
||||
select PINMUX
|
||||
|
||||
+config PINCTRL_FALCON
|
||||
+ bool
|
||||
+ depends on SOC_FALCON
|
||||
+ depends on PINCTRL_LANTIQ
|
||||
+
|
||||
config PINCTRL_MMP2
|
||||
bool "MMP2 pin controller driver"
|
||||
depends on ARCH_MMP
|
||||
diff --git a/drivers/pinctrl/Makefile b/drivers/pinctrl/Makefile
|
||||
index e19e207..c0566c8 100644
|
||||
--- a/drivers/pinctrl/Makefile
|
||||
+++ b/drivers/pinctrl/Makefile
|
||||
@@ -14,6 +14,7 @@ obj-$(CONFIG_PINCTRL_IMX51) += pinctrl-imx51.o
|
||||
obj-$(CONFIG_PINCTRL_IMX53) += pinctrl-imx53.o
|
||||
obj-$(CONFIG_PINCTRL_IMX6Q) += pinctrl-imx6q.o
|
||||
obj-$(CONFIG_PINCTRL_PXA3xx) += pinctrl-pxa3xx.o
|
||||
+obj-$(CONFIG_PINCTRL_FALCON) += pinctrl-falcon.o
|
||||
obj-$(CONFIG_PINCTRL_MMP2) += pinctrl-mmp2.o
|
||||
obj-$(CONFIG_PINCTRL_MXS) += pinctrl-mxs.o
|
||||
obj-$(CONFIG_PINCTRL_IMX23) += pinctrl-imx23.o
|
||||
diff --git a/drivers/pinctrl/pinctrl-falcon.c b/drivers/pinctrl/pinctrl-falcon.c
|
||||
new file mode 100644
|
||||
index 0000000..ee73059
|
||||
--- /dev/null
|
||||
+++ b/drivers/pinctrl/pinctrl-falcon.c
|
||||
@@ -0,0 +1,468 @@
|
||||
+/*
|
||||
+ * linux/drivers/pinctrl/pinmux-falcon.c
|
||||
+ * based on linux/drivers/pinctrl/pinmux-pxa910.c
|
||||
+ *
|
||||
+ * 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.
|
||||
+ *
|
||||
+ * Copyright (C) 2012 Thomas Langer <thomas.langer@lantiq.com>
|
||||
+ * Copyright (C) 2012 John Crispin <blogic@openwrt.org>
|
||||
+ */
|
||||
+
|
||||
+#include <linux/gpio.h>
|
||||
+#include <linux/interrupt.h>
|
||||
+#include <linux/slab.h>
|
||||
+#include <linux/export.h>
|
||||
+#include <linux/err.h>
|
||||
+#include <linux/module.h>
|
||||
+#include <linux/of.h>
|
||||
+#include <linux/of_platform.h>
|
||||
+#include <linux/of_address.h>
|
||||
+#include <linux/of_gpio.h>
|
||||
+#include <linux/platform_device.h>
|
||||
+
|
||||
+#include "pinctrl-lantiq.h"
|
||||
+
|
||||
+#include <lantiq_soc.h>
|
||||
+
|
||||
+/* Multiplexer Control Register */
|
||||
+#define LTQ_PADC_MUX(x) (x * 0x4)
|
||||
+/* Pull Up Enable Register */
|
||||
+#define LTQ_PADC_PUEN 0x80
|
||||
+/* Pull Down Enable Register */
|
||||
+#define LTQ_PADC_PDEN 0x84
|
||||
+/* Slew Rate Control Register */
|
||||
+#define LTQ_PADC_SRC 0x88
|
||||
+/* Drive Current Control Register */
|
||||
+#define LTQ_PADC_DCC 0x8C
|
||||
+/* Pad Control Availability Register */
|
||||
+#define LTQ_PADC_AVAIL 0xF0
|
||||
+
|
||||
+#define pad_r32(p, reg) ltq_r32(p + reg)
|
||||
+#define pad_w32(p, val, reg) ltq_w32(val, p + reg)
|
||||
+#define pad_w32_mask(c, clear, set, reg) \
|
||||
+ pad_w32(c, (pad_r32(c, reg) & ~(clear)) | (set), reg)
|
||||
+
|
||||
+#define pad_getbit(m, r, p) (!!(ltq_r32(m + r) & (1 << p)))
|
||||
+
|
||||
+#define PORTS 5
|
||||
+#define PINS 32
|
||||
+#define PORT(x) (x / PINS)
|
||||
+#define PORT_PIN(x) (x % PINS)
|
||||
+
|
||||
+#define MFP_FALCON(a, f0, f1, f2, f3) \
|
||||
+{ \
|
||||
+ .name = #a, \
|
||||
+ .pin = a, \
|
||||
+ .func = { \
|
||||
+ FALCON_MUX_##f0, \
|
||||
+ FALCON_MUX_##f1, \
|
||||
+ FALCON_MUX_##f2, \
|
||||
+ FALCON_MUX_##f3, \
|
||||
+ }, \
|
||||
+}
|
||||
+
|
||||
+#define GRP_MUX(a, m, p) \
|
||||
+{ \
|
||||
+ .name = a, \
|
||||
+ .mux = FALCON_MUX_##m, \
|
||||
+ .pins = p, \
|
||||
+ .npins = ARRAY_SIZE(p), \
|
||||
+}
|
||||
+
|
||||
+enum falcon_mux {
|
||||
+ FALCON_MUX_GPIO = 0,
|
||||
+ FALCON_MUX_RST,
|
||||
+ FALCON_MUX_NTR,
|
||||
+ FALCON_MUX_MDIO,
|
||||
+ FALCON_MUX_LED,
|
||||
+ FALCON_MUX_SPI,
|
||||
+ FALCON_MUX_ASC,
|
||||
+ FALCON_MUX_I2C,
|
||||
+ FALCON_MUX_HOSTIF,
|
||||
+ FALCON_MUX_SLIC,
|
||||
+ FALCON_MUX_JTAG,
|
||||
+ FALCON_MUX_PCM,
|
||||
+ FALCON_MUX_MII,
|
||||
+ FALCON_MUX_PHY,
|
||||
+ FALCON_MUX_NONE = 0xffff,
|
||||
+};
|
||||
+
|
||||
+static struct pinctrl_pin_desc falcon_pads[PORTS * PINS];
|
||||
+static int pad_count[PORTS];
|
||||
+
|
||||
+static void lantiq_load_pin_desc(struct pinctrl_pin_desc *d, int bank, int len)
|
||||
+{
|
||||
+ int base = bank * PINS;
|
||||
+ int i;
|
||||
+
|
||||
+ for (i = 0; i < len; i++) {
|
||||
+ /* strlen("ioXYZ") + 1 = 6 */
|
||||
+ char *name = kzalloc(6, GFP_KERNEL);
|
||||
+ snprintf(name, 6, "io%d", base + i);
|
||||
+ d[i].number = base + i;
|
||||
+ d[i].name = name;
|
||||
+ }
|
||||
+ pad_count[bank] = len;
|
||||
+}
|
||||
+
|
||||
+static struct ltq_mfp_pin falcon_mfp[] = {
|
||||
+ /* pin f0 f1 f2 f3 */
|
||||
+ MFP_FALCON(GPIO0, RST, GPIO, NONE, NONE),
|
||||
+ MFP_FALCON(GPIO1, GPIO, GPIO, NONE, NONE),
|
||||
+ MFP_FALCON(GPIO2, GPIO, GPIO, NONE, NONE),
|
||||
+ MFP_FALCON(GPIO3, GPIO, GPIO, NONE, NONE),
|
||||
+ MFP_FALCON(GPIO4, NTR, GPIO, NONE, NONE),
|
||||
+ MFP_FALCON(GPIO5, NTR, GPIO, NONE, NONE),
|
||||
+ MFP_FALCON(GPIO6, RST, GPIO, NONE, NONE),
|
||||
+ MFP_FALCON(GPIO7, MDIO, GPIO, NONE, NONE),
|
||||
+ MFP_FALCON(GPIO8, MDIO, GPIO, NONE, NONE),
|
||||
+ MFP_FALCON(GPIO9, LED, GPIO, NONE, NONE),
|
||||
+ MFP_FALCON(GPIO10, LED, GPIO, NONE, NONE),
|
||||
+ MFP_FALCON(GPIO11, LED, GPIO, NONE, NONE),
|
||||
+ MFP_FALCON(GPIO12, LED, GPIO, NONE, NONE),
|
||||
+ MFP_FALCON(GPIO13, LED, GPIO, NONE, NONE),
|
||||
+ MFP_FALCON(GPIO14, LED, GPIO, NONE, NONE),
|
||||
+ MFP_FALCON(GPIO32, ASC, GPIO, NONE, NONE),
|
||||
+ MFP_FALCON(GPIO33, ASC, GPIO, NONE, NONE),
|
||||
+ MFP_FALCON(GPIO34, SPI, GPIO, NONE, NONE),
|
||||
+ MFP_FALCON(GPIO35, SPI, GPIO, NONE, NONE),
|
||||
+ MFP_FALCON(GPIO36, SPI, GPIO, NONE, NONE),
|
||||
+ MFP_FALCON(GPIO37, SPI, GPIO, NONE, NONE),
|
||||
+ MFP_FALCON(GPIO38, SPI, GPIO, NONE, NONE),
|
||||
+ MFP_FALCON(GPIO39, I2C, GPIO, NONE, NONE),
|
||||
+ MFP_FALCON(GPIO40, I2C, GPIO, NONE, NONE),
|
||||
+ MFP_FALCON(GPIO41, HOSTIF, GPIO, HOSTIF, JTAG),
|
||||
+ MFP_FALCON(GPIO42, HOSTIF, GPIO, HOSTIF, NONE),
|
||||
+ MFP_FALCON(GPIO43, SLIC, GPIO, NONE, NONE),
|
||||
+ MFP_FALCON(GPIO44, SLIC, GPIO, PCM, ASC),
|
||||
+ MFP_FALCON(GPIO45, SLIC, GPIO, PCM, ASC),
|
||||
+ MFP_FALCON(GPIO64, MII, GPIO, NONE, NONE),
|
||||
+ MFP_FALCON(GPIO65, MII, GPIO, NONE, NONE),
|
||||
+ MFP_FALCON(GPIO66, MII, GPIO, NONE, NONE),
|
||||
+ MFP_FALCON(GPIO67, MII, GPIO, NONE, NONE),
|
||||
+ MFP_FALCON(GPIO68, MII, GPIO, NONE, NONE),
|
||||
+ MFP_FALCON(GPIO69, MII, GPIO, NONE, NONE),
|
||||
+ MFP_FALCON(GPIO70, MII, GPIO, NONE, NONE),
|
||||
+ MFP_FALCON(GPIO71, MII, GPIO, NONE, NONE),
|
||||
+ MFP_FALCON(GPIO72, MII, GPIO, NONE, NONE),
|
||||
+ MFP_FALCON(GPIO73, MII, GPIO, NONE, NONE),
|
||||
+ MFP_FALCON(GPIO74, MII, GPIO, NONE, NONE),
|
||||
+ MFP_FALCON(GPIO75, MII, GPIO, NONE, NONE),
|
||||
+ MFP_FALCON(GPIO76, MII, GPIO, NONE, NONE),
|
||||
+ MFP_FALCON(GPIO77, MII, GPIO, NONE, NONE),
|
||||
+ MFP_FALCON(GPIO78, MII, GPIO, NONE, NONE),
|
||||
+ MFP_FALCON(GPIO79, MII, GPIO, NONE, NONE),
|
||||
+ MFP_FALCON(GPIO80, MII, GPIO, NONE, NONE),
|
||||
+ MFP_FALCON(GPIO81, MII, GPIO, NONE, NONE),
|
||||
+ MFP_FALCON(GPIO82, MII, GPIO, NONE, NONE),
|
||||
+ MFP_FALCON(GPIO83, MII, GPIO, NONE, NONE),
|
||||
+ MFP_FALCON(GPIO84, MII, GPIO, NONE, NONE),
|
||||
+ MFP_FALCON(GPIO85, MII, GPIO, NONE, NONE),
|
||||
+ MFP_FALCON(GPIO86, MII, GPIO, NONE, NONE),
|
||||
+ MFP_FALCON(GPIO87, MII, GPIO, NONE, NONE),
|
||||
+ MFP_FALCON(GPIO88, PHY, GPIO, NONE, NONE),
|
||||
+};
|
||||
+
|
||||
+static const unsigned pins_por[] = {GPIO0};
|
||||
+static const unsigned pins_ntr[] = {GPIO4};
|
||||
+static const unsigned pins_ntr8k[] = {GPIO5};
|
||||
+static const unsigned pins_hrst[] = {GPIO6};
|
||||
+static const unsigned pins_mdio[] = {GPIO7, GPIO8};
|
||||
+static const unsigned pins_bled[] = {GPIO7, GPIO10, GPIO11,
|
||||
+ GPIO12, GPIO13, GPIO14};
|
||||
+static const unsigned pins_asc0[] = {GPIO32, GPIO33};
|
||||
+static const unsigned pins_spi[] = {GPIO34, GPIO35, GPIO36};
|
||||
+static const unsigned pins_spi_cs0[] = {GPIO37};
|
||||
+static const unsigned pins_spi_cs1[] = {GPIO38};
|
||||
+static const unsigned pins_i2c[] = {GPIO39, GPIO40};
|
||||
+static const unsigned pins_jtag[] = {GPIO41};
|
||||
+static const unsigned pins_slic[] = {GPIO43, GPIO44, GPIO45};
|
||||
+static const unsigned pins_pcm[] = {GPIO44, GPIO45};
|
||||
+static const unsigned pins_asc1[] = {GPIO44, GPIO45};
|
||||
+
|
||||
+static struct ltq_pin_group falcon_grps[] = {
|
||||
+ GRP_MUX("por", RST, pins_por),
|
||||
+ GRP_MUX("ntr", NTR, pins_ntr),
|
||||
+ GRP_MUX("ntr8k", NTR, pins_ntr8k),
|
||||
+ GRP_MUX("hrst", RST, pins_hrst),
|
||||
+ GRP_MUX("mdio", MDIO, pins_mdio),
|
||||
+ GRP_MUX("bootled", LED, pins_bled),
|
||||
+ GRP_MUX("asc0", ASC, pins_asc0),
|
||||
+ GRP_MUX("spi", SPI, pins_spi),
|
||||
+ GRP_MUX("spi cs0", SPI, pins_spi_cs0),
|
||||
+ GRP_MUX("spi cs1", SPI, pins_spi_cs1),
|
||||
+ GRP_MUX("i2c", I2C, pins_i2c),
|
||||
+ GRP_MUX("jtag", JTAG, pins_jtag),
|
||||
+ GRP_MUX("slic", SLIC, pins_slic),
|
||||
+ GRP_MUX("pcm", PCM, pins_pcm),
|
||||
+ GRP_MUX("asc1", ASC, pins_asc1),
|
||||
+};
|
||||
+
|
||||
+static const char * const ltq_rst_grps[] = {"por", "hrst"};
|
||||
+static const char * const ltq_ntr_grps[] = {"ntr", "ntr8k"};
|
||||
+static const char * const ltq_mdio_grps[] = {"mdio"};
|
||||
+static const char * const ltq_bled_grps[] = {"bootled"};
|
||||
+static const char * const ltq_asc_grps[] = {"asc0", "asc1"};
|
||||
+static const char * const ltq_spi_grps[] = {"spi", "spi cs0", "spi cs1"};
|
||||
+static const char * const ltq_i2c_grps[] = {"i2c"};
|
||||
+static const char * const ltq_jtag_grps[] = {"jtag"};
|
||||
+static const char * const ltq_slic_grps[] = {"slic"};
|
||||
+static const char * const ltq_pcm_grps[] = {"pcm"};
|
||||
+
|
||||
+static struct ltq_pmx_func falcon_funcs[] = {
|
||||
+ {"rst", ARRAY_AND_SIZE(ltq_rst_grps)},
|
||||
+ {"ntr", ARRAY_AND_SIZE(ltq_ntr_grps)},
|
||||
+ {"mdio", ARRAY_AND_SIZE(ltq_mdio_grps)},
|
||||
+ {"led", ARRAY_AND_SIZE(ltq_bled_grps)},
|
||||
+ {"asc", ARRAY_AND_SIZE(ltq_asc_grps)},
|
||||
+ {"spi", ARRAY_AND_SIZE(ltq_spi_grps)},
|
||||
+ {"i2c", ARRAY_AND_SIZE(ltq_i2c_grps)},
|
||||
+ {"jtag", ARRAY_AND_SIZE(ltq_jtag_grps)},
|
||||
+ {"slic", ARRAY_AND_SIZE(ltq_slic_grps)},
|
||||
+ {"pcm", ARRAY_AND_SIZE(ltq_pcm_grps)},
|
||||
+};
|
||||
+
|
||||
+
|
||||
+
|
||||
+
|
||||
+/* --------- pinconf related code --------- */
|
||||
+static int falcon_pinconf_group_get(struct pinctrl_dev *pctrldev,
|
||||
+ unsigned group, unsigned long *config)
|
||||
+{
|
||||
+ return -ENOTSUPP;
|
||||
+}
|
||||
+
|
||||
+static int falcon_pinconf_group_set(struct pinctrl_dev *pctrldev,
|
||||
+ unsigned group, unsigned long config)
|
||||
+{
|
||||
+ return -ENOTSUPP;
|
||||
+}
|
||||
+
|
||||
+static int falcon_pinconf_get(struct pinctrl_dev *pctrldev,
|
||||
+ unsigned pin, unsigned long *config)
|
||||
+{
|
||||
+ struct ltq_pinmux_info *info = pinctrl_dev_get_drvdata(pctrldev);
|
||||
+ enum ltq_pinconf_param param = LTQ_PINCONF_UNPACK_PARAM(*config);
|
||||
+ void __iomem *mem = info->membase[PORT(pin)];
|
||||
+
|
||||
+ switch (param) {
|
||||
+ case LTQ_PINCONF_PARAM_DRIVE_CURRENT:
|
||||
+ *config = LTQ_PINCONF_PACK(param,
|
||||
+ !!pad_getbit(mem, LTQ_PADC_DCC, PORT_PIN(pin)));
|
||||
+ break;
|
||||
+
|
||||
+ case LTQ_PINCONF_PARAM_SLEW_RATE:
|
||||
+ *config = LTQ_PINCONF_PACK(param,
|
||||
+ !!pad_getbit(mem, LTQ_PADC_SRC, PORT_PIN(pin)));
|
||||
+ break;
|
||||
+
|
||||
+ case LTQ_PINCONF_PARAM_PULL:
|
||||
+ if (pad_getbit(mem, LTQ_PADC_PDEN, PORT_PIN(pin)))
|
||||
+ *config = LTQ_PINCONF_PACK(param, 1);
|
||||
+ else if (pad_getbit(mem, LTQ_PADC_PUEN, PORT_PIN(pin)))
|
||||
+ *config = LTQ_PINCONF_PACK(param, 2);
|
||||
+ else
|
||||
+ *config = LTQ_PINCONF_PACK(param, 0);
|
||||
+
|
||||
+ break;
|
||||
+
|
||||
+ default:
|
||||
+ return -ENOTSUPP;
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int falcon_pinconf_set(struct pinctrl_dev *pctrldev,
|
||||
+ unsigned pin, unsigned long config)
|
||||
+{
|
||||
+ enum ltq_pinconf_param param = LTQ_PINCONF_UNPACK_PARAM(config);
|
||||
+ int arg = LTQ_PINCONF_UNPACK_ARG(config);
|
||||
+ struct ltq_pinmux_info *info = pinctrl_dev_get_drvdata(pctrldev);
|
||||
+ void __iomem *mem = info->membase[PORT(pin)];
|
||||
+ u32 reg;
|
||||
+
|
||||
+ switch (param) {
|
||||
+ case LTQ_PINCONF_PARAM_DRIVE_CURRENT:
|
||||
+ reg = LTQ_PADC_DCC;
|
||||
+ break;
|
||||
+
|
||||
+ case LTQ_PINCONF_PARAM_SLEW_RATE:
|
||||
+ reg = LTQ_PADC_SRC;
|
||||
+ break;
|
||||
+
|
||||
+ case LTQ_PINCONF_PARAM_PULL:
|
||||
+ if (arg == 1)
|
||||
+ reg = LTQ_PADC_PDEN;
|
||||
+ else
|
||||
+ reg = LTQ_PADC_PUEN;
|
||||
+ break;
|
||||
+
|
||||
+ default:
|
||||
+ pr_err("%s: Invalid config param %04x\n",
|
||||
+ pinctrl_dev_get_name(pctrldev), param);
|
||||
+ return -ENOTSUPP;
|
||||
+ }
|
||||
+
|
||||
+ pad_w32(mem, BIT(PORT_PIN(pin)), reg);
|
||||
+ if (!(pad_r32(mem, reg) & BIT(PORT_PIN(pin))))
|
||||
+ return -ENOTSUPP;
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static void falcon_pinconf_dbg_show(struct pinctrl_dev *pctrldev,
|
||||
+ struct seq_file *s, unsigned offset)
|
||||
+{
|
||||
+}
|
||||
+
|
||||
+static void falcon_pinconf_group_dbg_show(struct pinctrl_dev *pctrldev,
|
||||
+ struct seq_file *s, unsigned selector)
|
||||
+{
|
||||
+}
|
||||
+
|
||||
+struct pinconf_ops falcon_pinconf_ops = {
|
||||
+ .pin_config_get = falcon_pinconf_get,
|
||||
+ .pin_config_set = falcon_pinconf_set,
|
||||
+ .pin_config_group_get = falcon_pinconf_group_get,
|
||||
+ .pin_config_group_set = falcon_pinconf_group_set,
|
||||
+ .pin_config_dbg_show = falcon_pinconf_dbg_show,
|
||||
+ .pin_config_group_dbg_show = falcon_pinconf_group_dbg_show,
|
||||
+};
|
||||
+
|
||||
+static struct pinctrl_desc falcon_pctrl_desc = {
|
||||
+ .owner = THIS_MODULE,
|
||||
+ .pins = falcon_pads,
|
||||
+ .confops = &falcon_pinconf_ops,
|
||||
+};
|
||||
+
|
||||
+static inline int falcon_mux_apply(struct pinctrl_dev *pctrldev,
|
||||
+ int mfp, int mux)
|
||||
+{
|
||||
+ struct ltq_pinmux_info *info = pinctrl_dev_get_drvdata(pctrldev);
|
||||
+ int port = PORT(info->mfp[mfp].pin);
|
||||
+
|
||||
+ if ((port >= PORTS) || (!info->membase[port]))
|
||||
+ return -ENODEV;
|
||||
+
|
||||
+ pad_w32(info->membase[port], mux,
|
||||
+ LTQ_PADC_MUX(PORT_PIN(info->mfp[mfp].pin)));
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static const struct ltq_cfg_param falcon_cfg_params[] = {
|
||||
+ {"lantiq,pull", LTQ_PINCONF_PARAM_PULL},
|
||||
+ {"lantiq,drive-current", LTQ_PINCONF_PARAM_DRIVE_CURRENT},
|
||||
+ {"lantiq,slew-rate", LTQ_PINCONF_PARAM_SLEW_RATE},
|
||||
+};
|
||||
+
|
||||
+static struct ltq_pinmux_info falcon_info = {
|
||||
+ .desc = &falcon_pctrl_desc,
|
||||
+ .apply_mux = falcon_mux_apply,
|
||||
+};
|
||||
+
|
||||
+
|
||||
+
|
||||
+
|
||||
+/* --------- register the pinctrl layer --------- */
|
||||
+
|
||||
+int pinctrl_falcon_get_range_size(int id)
|
||||
+{
|
||||
+ u32 avail;
|
||||
+
|
||||
+ if ((id >= PORTS) || (!falcon_info.membase[id]))
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ avail = pad_r32(falcon_info.membase[id], LTQ_PADC_AVAIL);
|
||||
+
|
||||
+ return fls(avail);
|
||||
+}
|
||||
+
|
||||
+void pinctrl_falcon_add_gpio_range(struct pinctrl_gpio_range *range)
|
||||
+{
|
||||
+ pinctrl_add_gpio_range(falcon_info.pctrl, range);
|
||||
+}
|
||||
+
|
||||
+static int pinctrl_falcon_probe(struct platform_device *pdev)
|
||||
+{
|
||||
+ struct device_node *np;
|
||||
+ int pad_count = 0;
|
||||
+ int ret = 0;
|
||||
+
|
||||
+ /* load and remap the pad resources of the different banks */
|
||||
+ for_each_compatible_node(np, NULL, "lantiq,pad-falcon") {
|
||||
+ struct platform_device *ppdev = of_find_device_by_node(np);
|
||||
+ const __be32 *bank = of_get_property(np, "lantiq,bank", NULL);
|
||||
+ struct resource res;
|
||||
+ u32 avail;
|
||||
+ int pins;
|
||||
+
|
||||
+ if (!ppdev) {
|
||||
+ dev_err(&pdev->dev, "failed to find pad pdev\n");
|
||||
+ continue;
|
||||
+ }
|
||||
+ if (!bank || *bank >= PORTS)
|
||||
+ continue;
|
||||
+ if (of_address_to_resource(np, 0, &res))
|
||||
+ continue;
|
||||
+ falcon_info.clk[*bank] = clk_get(&ppdev->dev, NULL);
|
||||
+ if (IS_ERR(falcon_info.clk[*bank])) {
|
||||
+ dev_err(&ppdev->dev, "failed to get clock\n");
|
||||
+ return PTR_ERR(falcon_info.clk[*bank]);
|
||||
+ }
|
||||
+ falcon_info.membase[*bank] =
|
||||
+ devm_request_and_ioremap(&pdev->dev, &res);
|
||||
+ if (!falcon_info.membase[*bank]) {
|
||||
+ dev_err(&pdev->dev,
|
||||
+ "Failed to remap memory for bank %d\n",
|
||||
+ *bank);
|
||||
+ return -ENOMEM;
|
||||
+ }
|
||||
+ avail = pad_r32(falcon_info.membase[*bank],
|
||||
+ LTQ_PADC_AVAIL);
|
||||
+ pins = fls(avail);
|
||||
+ lantiq_load_pin_desc(&falcon_pads[pad_count], *bank, pins);
|
||||
+ pad_count += pins;
|
||||
+ clk_enable(falcon_info.clk[*bank]);
|
||||
+ dev_dbg(&pdev->dev, "found %s with %d pads\n",
|
||||
+ res.name, pins);
|
||||
+ }
|
||||
+ dev_dbg(&pdev->dev, "found a total of %d pads\n", pad_count);
|
||||
+ falcon_pctrl_desc.name = dev_name(&pdev->dev);
|
||||
+ falcon_pctrl_desc.npins = pad_count;
|
||||
+
|
||||
+ falcon_info.mfp = falcon_mfp;
|
||||
+ falcon_info.num_mfp = ARRAY_SIZE(falcon_mfp);
|
||||
+ falcon_info.grps = falcon_grps;
|
||||
+ falcon_info.num_grps = ARRAY_SIZE(falcon_grps);
|
||||
+ falcon_info.funcs = falcon_funcs;
|
||||
+ falcon_info.num_funcs = ARRAY_SIZE(falcon_funcs);
|
||||
+
|
||||
+ ret = ltq_pinctrl_register(pdev, &falcon_info);
|
||||
+ if (!ret)
|
||||
+ dev_info(&pdev->dev, "Init done\n");
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static const struct of_device_id falcon_match[] = {
|
||||
+ { .compatible = "lantiq,pinctrl-falcon" },
|
||||
+ {},
|
||||
+};
|
||||
+MODULE_DEVICE_TABLE(of, falcon_match);
|
||||
+
|
||||
+static struct platform_driver pinctrl_falcon_driver = {
|
||||
+ .probe = pinctrl_falcon_probe,
|
||||
+ .driver = {
|
||||
+ .name = "pinctrl-falcon",
|
||||
+ .owner = THIS_MODULE,
|
||||
+ .of_match_table = falcon_match,
|
||||
+ },
|
||||
+};
|
||||
+
|
||||
+int __init pinctrl_falcon_init(void)
|
||||
+{
|
||||
+ return platform_driver_register(&pinctrl_falcon_driver);
|
||||
+}
|
||||
+
|
||||
+core_initcall_sync(pinctrl_falcon_init);
|
||||
--
|
||||
1.7.10.4
|
||||
|
@ -0,0 +1,121 @@
|
||||
From 5c56f76995691cf761f66d6d89a00eea80be660c Mon Sep 17 00:00:00 2001
|
||||
From: John Crispin <blogic@openwrt.org>
|
||||
Date: Fri, 20 Jul 2012 19:01:00 +0200
|
||||
Subject: [PATCH 12/15] Document: devicetree: add OF documents for lantiq xway
|
||||
pinctrl
|
||||
|
||||
Signed-off-by: John Crispin <blogic@openwrt.org>
|
||||
Acked-by: Linus Walleij <linus.walleij@linaro.org>
|
||||
Cc: devicetree-discuss@lists.ozlabs.org
|
||||
Cc: linux-kernel@vger.kernel.org
|
||||
---
|
||||
.../bindings/pinctrl/lantiq,xway-pinumx.txt | 97 ++++++++++++++++++++
|
||||
1 file changed, 97 insertions(+)
|
||||
create mode 100644 Documentation/devicetree/bindings/pinctrl/lantiq,xway-pinumx.txt
|
||||
|
||||
diff --git a/Documentation/devicetree/bindings/pinctrl/lantiq,xway-pinumx.txt b/Documentation/devicetree/bindings/pinctrl/lantiq,xway-pinumx.txt
|
||||
new file mode 100644
|
||||
index 0000000..b5469db
|
||||
--- /dev/null
|
||||
+++ b/Documentation/devicetree/bindings/pinctrl/lantiq,xway-pinumx.txt
|
||||
@@ -0,0 +1,97 @@
|
||||
+Lantiq XWAY pinmux controller
|
||||
+
|
||||
+Required properties:
|
||||
+- compatible: "lantiq,pinctrl-xway" or "lantiq,pinctrl-xr9"
|
||||
+- reg: Should contain the physical address and length of the gpio/pinmux
|
||||
+ register range
|
||||
+
|
||||
+Please refer to pinctrl-bindings.txt in this directory for details of the
|
||||
+common pinctrl bindings used by client devices, including the meaning of the
|
||||
+phrase "pin configuration node".
|
||||
+
|
||||
+Lantiq's pin configuration nodes act as a container for an abitrary number of
|
||||
+subnodes. Each of these subnodes represents some desired configuration for a
|
||||
+pin, a group, or a list of pins or groups. This configuration can include the
|
||||
+mux function to select on those group(s), and two pin configuration parameters:
|
||||
+pull-up and open-drain
|
||||
+
|
||||
+The name of each subnode is not important as long as it is unique; all subnodes
|
||||
+should be enumerated and processed purely based on their content.
|
||||
+
|
||||
+Each subnode only affects those parameters that are explicitly listed. In
|
||||
+other words, a subnode that lists a mux function but no pin configuration
|
||||
+parameters implies no information about any pin configuration parameters.
|
||||
+Similarly, a pin subnode that describes a pullup parameter implies no
|
||||
+information about e.g. the mux function.
|
||||
+
|
||||
+We support 2 types of nodes.
|
||||
+
|
||||
+Definition of mux function groups:
|
||||
+
|
||||
+Required subnode-properties:
|
||||
+- lantiq,groups : An array of strings. Each string contains the name of a group.
|
||||
+ Valid values for these names are listed below.
|
||||
+- lantiq,function: A string containing the name of the function to mux to the
|
||||
+ group. Valid values for function names are listed below.
|
||||
+
|
||||
+Valid values for group and function names:
|
||||
+
|
||||
+ mux groups:
|
||||
+ exin0, exin1, exin2, jtag, ebu a23, ebu a24, ebu a25, ebu clk, ebu cs1,
|
||||
+ ebu wait, nand ale, nand cs1, nand cle, spi, spi_cs1, spi_cs2, spi_cs3,
|
||||
+ spi_cs4, spi_cs5, spi_cs6, asc0, asc0 cts rts, stp, nmi , gpt1, gpt2,
|
||||
+ gpt3, clkout0, clkout1, clkout2, clkout3, gnt1, gnt2, gnt3, req1, req2,
|
||||
+ req3
|
||||
+
|
||||
+ additional mux groups (XR9 only):
|
||||
+ mdio, nand rdy, nand rd, exin3, exin4, gnt4, req4
|
||||
+
|
||||
+ functions:
|
||||
+ spi, asc, cgu, jtag, exin, stp, gpt, nmi, pci, ebu, mdio
|
||||
+
|
||||
+
|
||||
+
|
||||
+Definition of pin configurations:
|
||||
+
|
||||
+Required subnode-properties:
|
||||
+- lantiq,pins : An array of strings. Each string contains the name of a pin.
|
||||
+ Valid values for these names are listed below.
|
||||
+
|
||||
+Optional subnode-properties:
|
||||
+- lantiq,pull: Integer, representing the pull-down/up to apply to the pin.
|
||||
+ 0: none, 1: down, 2: up.
|
||||
+- lantiq,open-drain: Boolean, enables open-drain on the defined pin.
|
||||
+
|
||||
+Valid values for XWAY pin names:
|
||||
+ Pinconf pins can be referenced via the names io0-io31.
|
||||
+
|
||||
+Valid values for XR9 pin names:
|
||||
+ Pinconf pins can be referenced via the names io0-io55.
|
||||
+
|
||||
+Example:
|
||||
+ gpio: pinmux@E100B10 {
|
||||
+ compatible = "lantiq,pinctrl-xway";
|
||||
+ pinctrl-names = "default";
|
||||
+ pinctrl-0 = <&state_default>;
|
||||
+
|
||||
+ #gpio-cells = <2>;
|
||||
+ gpio-controller;
|
||||
+ reg = <0xE100B10 0xA0>;
|
||||
+
|
||||
+ state_default: pinmux {
|
||||
+ stp {
|
||||
+ lantiq,groups = "stp";
|
||||
+ lantiq,function = "stp";
|
||||
+ };
|
||||
+ pci {
|
||||
+ lantiq,groups = "gnt1";
|
||||
+ lantiq,function = "pci";
|
||||
+ };
|
||||
+ conf_out {
|
||||
+ lantiq,pins = "io4", "io5", "io6"; /* stp */
|
||||
+ lantiq,open-drain;
|
||||
+ lantiq,pull = <0>;
|
||||
+ };
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
--
|
||||
1.7.10.4
|
||||
|
@ -0,0 +1,108 @@
|
||||
From 8e004b47b7645fe8ebe1bb81f75cd8f16650de68 Mon Sep 17 00:00:00 2001
|
||||
From: John Crispin <blogic@openwrt.org>
|
||||
Date: Sun, 22 Jul 2012 09:23:50 +0200
|
||||
Subject: [PATCH 13/15] Document: devicetree: add OF documents for lantiq
|
||||
falcon pinctrl
|
||||
|
||||
Signed-off-by: John Crispin <blogic@openwrt.org>
|
||||
Signed-off-by: Thomas Langer <thomas.langer@lantiq.com>
|
||||
Acked-by: Linus Walleij <linus.walleij@linaro.org>
|
||||
Cc: devicetree-discuss@lists.ozlabs.org
|
||||
Cc: linux-kernel@vger.kernel.org
|
||||
---
|
||||
.../bindings/pinctrl/lantiq,falcon-pinumx.txt | 83 ++++++++++++++++++++
|
||||
1 file changed, 83 insertions(+)
|
||||
create mode 100644 Documentation/devicetree/bindings/pinctrl/lantiq,falcon-pinumx.txt
|
||||
|
||||
diff --git a/Documentation/devicetree/bindings/pinctrl/lantiq,falcon-pinumx.txt b/Documentation/devicetree/bindings/pinctrl/lantiq,falcon-pinumx.txt
|
||||
new file mode 100644
|
||||
index 0000000..daa7689
|
||||
--- /dev/null
|
||||
+++ b/Documentation/devicetree/bindings/pinctrl/lantiq,falcon-pinumx.txt
|
||||
@@ -0,0 +1,83 @@
|
||||
+Lantiq FALCON pinmux controller
|
||||
+
|
||||
+Required properties:
|
||||
+- compatible: "lantiq,pinctrl-falcon"
|
||||
+- reg: Should contain the physical address and length of the gpio/pinmux
|
||||
+ register range
|
||||
+
|
||||
+Please refer to pinctrl-bindings.txt in this directory for details of the
|
||||
+common pinctrl bindings used by client devices, including the meaning of the
|
||||
+phrase "pin configuration node".
|
||||
+
|
||||
+Lantiq's pin configuration nodes act as a container for an abitrary number of
|
||||
+subnodes. Each of these subnodes represents some desired configuration for a
|
||||
+pin, a group, or a list of pins or groups. This configuration can include the
|
||||
+mux function to select on those group(s), and two pin configuration parameters:
|
||||
+pull-up and open-drain
|
||||
+
|
||||
+The name of each subnode is not important as long as it is unique; all subnodes
|
||||
+should be enumerated and processed purely based on their content.
|
||||
+
|
||||
+Each subnode only affects those parameters that are explicitly listed. In
|
||||
+other words, a subnode that lists a mux function but no pin configuration
|
||||
+parameters implies no information about any pin configuration parameters.
|
||||
+Similarly, a pin subnode that describes a pullup parameter implies no
|
||||
+information about e.g. the mux function.
|
||||
+
|
||||
+We support 2 types of nodes.
|
||||
+
|
||||
+Definition of mux function groups:
|
||||
+
|
||||
+Required subnode-properties:
|
||||
+- lantiq,groups : An array of strings. Each string contains the name of a group.
|
||||
+ Valid values for these names are listed below.
|
||||
+- lantiq,function: A string containing the name of the function to mux to the
|
||||
+ group. Valid values for function names are listed below.
|
||||
+
|
||||
+Valid values for group and function names:
|
||||
+
|
||||
+ mux groups:
|
||||
+ por, ntr, ntr8k, hrst, mdio, bootled, asc0, spi, spi cs0, spi cs1, i2c,
|
||||
+ jtag, slic, pcm, asc1
|
||||
+
|
||||
+ functions:
|
||||
+ rst, ntr, mdio, led, asc, spi, i2c, jtag, slic, pcm
|
||||
+
|
||||
+
|
||||
+Definition of pin configurations:
|
||||
+
|
||||
+Required subnode-properties:
|
||||
+- lantiq,pins : An array of strings. Each string contains the name of a pin.
|
||||
+ Valid values for these names are listed below.
|
||||
+
|
||||
+Optional subnode-properties:
|
||||
+- lantiq,pull: Integer, representing the pull-down/up to apply to the pin.
|
||||
+ 0: none, 1: down
|
||||
+- lantiq,drive-current: Boolean, enables drive-current
|
||||
+- lantiq,slew-rate: Boolean, enables slew-rate
|
||||
+
|
||||
+Example:
|
||||
+ pinmux0 {
|
||||
+ compatible = "lantiq,pinctrl-falcon";
|
||||
+ pinctrl-names = "default";
|
||||
+ pinctrl-0 = <&state_default>;
|
||||
+
|
||||
+ state_default: pinmux {
|
||||
+ asc0 {
|
||||
+ lantiq,groups = "asc0";
|
||||
+ lantiq,function = "asc";
|
||||
+ };
|
||||
+ ntr {
|
||||
+ lantiq,groups = "ntr8k";
|
||||
+ lantiq,function = "ntr";
|
||||
+ };
|
||||
+ i2c {
|
||||
+ lantiq,groups = "i2c";
|
||||
+ lantiq,function = "i2c";
|
||||
+ };
|
||||
+ hrst {
|
||||
+ lantiq,groups = "hrst";
|
||||
+ lantiq,function = "rst";
|
||||
+ };
|
||||
+ };
|
||||
+ };
|
||||
--
|
||||
1.7.10.4
|
||||
|
@ -0,0 +1,33 @@
|
||||
From 6a88a0f762a61f212d4bbcf1ad45369f28014484 Mon Sep 17 00:00:00 2001
|
||||
From: John Crispin <blogic@openwrt.org>
|
||||
Date: Wed, 15 Aug 2012 15:41:50 +0200
|
||||
Subject: [PATCH 14/15] MIPS: lantiq: make use of __gpio_to_irq
|
||||
|
||||
The gpio_chip struct allows us to set a .to_irq callback. Once this is set
|
||||
we can rely on the generic __gpio_to_irq() function to map gpio->irq allowing
|
||||
more than one gpio_chip to register an interrupt
|
||||
|
||||
Signed-off-by: John Crispin <blogic@openwrt.org>
|
||||
---
|
||||
arch/mips/include/asm/mach-lantiq/gpio.h | 5 +----
|
||||
1 file changed, 1 insertion(+), 4 deletions(-)
|
||||
|
||||
diff --git a/arch/mips/include/asm/mach-lantiq/gpio.h b/arch/mips/include/asm/mach-lantiq/gpio.h
|
||||
index f79505b..9ba1cae 100644
|
||||
--- a/arch/mips/include/asm/mach-lantiq/gpio.h
|
||||
+++ b/arch/mips/include/asm/mach-lantiq/gpio.h
|
||||
@@ -1,10 +1,7 @@
|
||||
#ifndef __ASM_MIPS_MACH_LANTIQ_GPIO_H
|
||||
#define __ASM_MIPS_MACH_LANTIQ_GPIO_H
|
||||
|
||||
-static inline int gpio_to_irq(unsigned int gpio)
|
||||
-{
|
||||
- return -1;
|
||||
-}
|
||||
+#define gpio_to_irq __gpio_to_irq
|
||||
|
||||
#define gpio_get_value __gpio_get_value
|
||||
#define gpio_set_value __gpio_set_value
|
||||
--
|
||||
1.7.10.4
|
||||
|
@ -0,0 +1,34 @@
|
||||
From c9e854cf940fbc09846c255895efceb3bc9bf095 Mon Sep 17 00:00:00 2001
|
||||
From: John Crispin <blogic@openwrt.org>
|
||||
Date: Wed, 11 Jul 2012 16:33:43 +0200
|
||||
Subject: [PATCH 15/15] GPIO: MIPS: lantiq: fix overflow inside stp-xway
|
||||
driver
|
||||
|
||||
The driver was using a 16 bit field for storing the shadow value of the shift
|
||||
register cascade. This resulted in only the first 2 shift registeres receiving
|
||||
the correct data. The third shift register would always receive 0x00.
|
||||
|
||||
Fix this by using a 32bit field for the shadow value.
|
||||
|
||||
Signed-off-by: John Crispin <blogic@openwrt.org>
|
||||
Cc: linux-kernel@vger.kernel.org
|
||||
---
|
||||
drivers/gpio/gpio-stp-xway.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/drivers/gpio/gpio-stp-xway.c b/drivers/gpio/gpio-stp-xway.c
|
||||
index e35096b..8bead0b 100644
|
||||
--- a/drivers/gpio/gpio-stp-xway.c
|
||||
+++ b/drivers/gpio/gpio-stp-xway.c
|
||||
@@ -82,7 +82,7 @@ struct xway_stp {
|
||||
struct gpio_chip gc;
|
||||
void __iomem *virt;
|
||||
u32 edge; /* rising or falling edge triggered shift register */
|
||||
- u16 shadow; /* shadow the shift registers state */
|
||||
+ u32 shadow; /* shadow the shift registers state */
|
||||
u8 groups; /* we can drive 1-3 groups of 8bit each */
|
||||
u8 dsl; /* the 2 LSBs can be driven by the dsl core */
|
||||
u8 phy1; /* 3 bits can be driven by phy1 */
|
||||
--
|
||||
1.7.10.4
|
||||
|
@ -0,0 +1,257 @@
|
||||
From 99f2b107924c07bee0bae7151426495fb815ca6e Mon Sep 17 00:00:00 2001
|
||||
From: John Crispin <blogic@openwrt.org>
|
||||
Date: Thu, 23 Aug 2012 20:28:32 +0200
|
||||
Subject: [PATCH] mtd: lantiq: Add NAND support on Lantiq XWAY SoC.
|
||||
|
||||
The driver uses plat_nand. As the platform_device is loaded from DT, we need
|
||||
to lookup the node and attach our xway specific "struct platform_nand_data"
|
||||
to it.
|
||||
|
||||
Signed-off-by: John Crispin <blogic@openwrt.org>
|
||||
Signed-off-by: Artem Bityutskiy <artem.bityutskiy@linux.intel.com>
|
||||
Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
|
||||
---
|
||||
drivers/mtd/nand/Kconfig | 8 ++
|
||||
drivers/mtd/nand/Makefile | 1 +
|
||||
drivers/mtd/nand/xway_nand.c | 201 ++++++++++++++++++++++++++++++++++++++++++
|
||||
3 files changed, 210 insertions(+)
|
||||
create mode 100644 drivers/mtd/nand/xway_nand.c
|
||||
|
||||
diff --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig
|
||||
index 7101e8a..ce5cf02 100644
|
||||
--- a/drivers/mtd/nand/Kconfig
|
||||
+++ b/drivers/mtd/nand/Kconfig
|
||||
@@ -580,4 +580,12 @@ config MTD_NAND_FSMC
|
||||
Enables support for NAND Flash chips on the ST Microelectronics
|
||||
Flexible Static Memory Controller (FSMC)
|
||||
|
||||
+config MTD_NAND_XWAY
|
||||
+ tristate "Support for NAND on Lantiq XWAY SoC"
|
||||
+ depends on LANTIQ && SOC_TYPE_XWAY
|
||||
+ select MTD_NAND_PLATFORM
|
||||
+ help
|
||||
+ Enables support for NAND Flash chips on Lantiq XWAY SoCs. NAND is attached
|
||||
+ to the External Bus Unit (EBU).
|
||||
+
|
||||
endif # MTD_NAND
|
||||
diff --git a/drivers/mtd/nand/Makefile b/drivers/mtd/nand/Makefile
|
||||
index ddee818..c4b0ab3 100644
|
||||
--- a/drivers/mtd/nand/Makefile
|
||||
+++ b/drivers/mtd/nand/Makefile
|
||||
@@ -53,5 +53,6 @@ obj-$(CONFIG_MTD_NAND_MPC5121_NFC) += mpc5121_nfc.o
|
||||
obj-$(CONFIG_MTD_NAND_RICOH) += r852.o
|
||||
obj-$(CONFIG_MTD_NAND_JZ4740) += jz4740_nand.o
|
||||
obj-$(CONFIG_MTD_NAND_GPMI_NAND) += gpmi-nand/
|
||||
+obj-$(CONFIG_MTD_NAND_XWAY) += xway_nand.o
|
||||
|
||||
nand-objs := nand_base.o nand_bbt.o
|
||||
diff --git a/drivers/mtd/nand/xway_nand.c b/drivers/mtd/nand/xway_nand.c
|
||||
new file mode 100644
|
||||
index 0000000..3f81dc8
|
||||
--- /dev/null
|
||||
+++ b/drivers/mtd/nand/xway_nand.c
|
||||
@@ -0,0 +1,201 @@
|
||||
+/*
|
||||
+ * 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.
|
||||
+ *
|
||||
+ * Copyright © 2012 John Crispin <blogic@openwrt.org>
|
||||
+ */
|
||||
+
|
||||
+#include <linux/mtd/nand.h>
|
||||
+#include <linux/of_gpio.h>
|
||||
+#include <linux/of_platform.h>
|
||||
+
|
||||
+#include <lantiq_soc.h>
|
||||
+
|
||||
+/* nand registers */
|
||||
+#define EBU_ADDSEL1 0x24
|
||||
+#define EBU_NAND_CON 0xB0
|
||||
+#define EBU_NAND_WAIT 0xB4
|
||||
+#define EBU_NAND_ECC0 0xB8
|
||||
+#define EBU_NAND_ECC_AC 0xBC
|
||||
+
|
||||
+/* nand commands */
|
||||
+#define NAND_CMD_ALE (1 << 2)
|
||||
+#define NAND_CMD_CLE (1 << 3)
|
||||
+#define NAND_CMD_CS (1 << 4)
|
||||
+#define NAND_WRITE_CMD_RESET 0xff
|
||||
+#define NAND_WRITE_CMD (NAND_CMD_CS | NAND_CMD_CLE)
|
||||
+#define NAND_WRITE_ADDR (NAND_CMD_CS | NAND_CMD_ALE)
|
||||
+#define NAND_WRITE_DATA (NAND_CMD_CS)
|
||||
+#define NAND_READ_DATA (NAND_CMD_CS)
|
||||
+#define NAND_WAIT_WR_C (1 << 3)
|
||||
+#define NAND_WAIT_RD (0x1)
|
||||
+
|
||||
+/* we need to tel the ebu which addr we mapped the nand to */
|
||||
+#define ADDSEL1_MASK(x) (x << 4)
|
||||
+#define ADDSEL1_REGEN 1
|
||||
+
|
||||
+/* we need to tell the EBU that we have nand attached and set it up properly */
|
||||
+#define BUSCON1_SETUP (1 << 22)
|
||||
+#define BUSCON1_BCGEN_RES (0x3 << 12)
|
||||
+#define BUSCON1_WAITWRC2 (2 << 8)
|
||||
+#define BUSCON1_WAITRDC2 (2 << 6)
|
||||
+#define BUSCON1_HOLDC1 (1 << 4)
|
||||
+#define BUSCON1_RECOVC1 (1 << 2)
|
||||
+#define BUSCON1_CMULT4 1
|
||||
+
|
||||
+#define NAND_CON_CE (1 << 20)
|
||||
+#define NAND_CON_OUT_CS1 (1 << 10)
|
||||
+#define NAND_CON_IN_CS1 (1 << 8)
|
||||
+#define NAND_CON_PRE_P (1 << 7)
|
||||
+#define NAND_CON_WP_P (1 << 6)
|
||||
+#define NAND_CON_SE_P (1 << 5)
|
||||
+#define NAND_CON_CS_P (1 << 4)
|
||||
+#define NAND_CON_CSMUX (1 << 1)
|
||||
+#define NAND_CON_NANDM 1
|
||||
+
|
||||
+static void xway_reset_chip(struct nand_chip *chip)
|
||||
+{
|
||||
+ unsigned long nandaddr = (unsigned long) chip->IO_ADDR_W;
|
||||
+ unsigned long flags;
|
||||
+
|
||||
+ nandaddr &= ~NAND_WRITE_ADDR;
|
||||
+ nandaddr |= NAND_WRITE_CMD;
|
||||
+
|
||||
+ /* finish with a reset */
|
||||
+ spin_lock_irqsave(&ebu_lock, flags);
|
||||
+ writeb(NAND_WRITE_CMD_RESET, (void __iomem *) nandaddr);
|
||||
+ while ((ltq_ebu_r32(EBU_NAND_WAIT) & NAND_WAIT_WR_C) == 0)
|
||||
+ ;
|
||||
+ spin_unlock_irqrestore(&ebu_lock, flags);
|
||||
+}
|
||||
+
|
||||
+static void xway_select_chip(struct mtd_info *mtd, int chip)
|
||||
+{
|
||||
+
|
||||
+ switch (chip) {
|
||||
+ case -1:
|
||||
+ ltq_ebu_w32_mask(NAND_CON_CE, 0, EBU_NAND_CON);
|
||||
+ ltq_ebu_w32_mask(NAND_CON_NANDM, 0, EBU_NAND_CON);
|
||||
+ break;
|
||||
+ case 0:
|
||||
+ ltq_ebu_w32_mask(0, NAND_CON_NANDM, EBU_NAND_CON);
|
||||
+ ltq_ebu_w32_mask(0, NAND_CON_CE, EBU_NAND_CON);
|
||||
+ break;
|
||||
+ default:
|
||||
+ BUG();
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static void xway_cmd_ctrl(struct mtd_info *mtd, int cmd, unsigned int ctrl)
|
||||
+{
|
||||
+ struct nand_chip *this = mtd->priv;
|
||||
+ unsigned long nandaddr = (unsigned long) this->IO_ADDR_W;
|
||||
+ unsigned long flags;
|
||||
+
|
||||
+ if (ctrl & NAND_CTRL_CHANGE) {
|
||||
+ nandaddr &= ~(NAND_WRITE_CMD | NAND_WRITE_ADDR);
|
||||
+ if (ctrl & NAND_CLE)
|
||||
+ nandaddr |= NAND_WRITE_CMD;
|
||||
+ else
|
||||
+ nandaddr |= NAND_WRITE_ADDR;
|
||||
+ this->IO_ADDR_W = (void __iomem *) nandaddr;
|
||||
+ }
|
||||
+
|
||||
+ if (cmd != NAND_CMD_NONE) {
|
||||
+ spin_lock_irqsave(&ebu_lock, flags);
|
||||
+ writeb(cmd, this->IO_ADDR_W);
|
||||
+ while ((ltq_ebu_r32(EBU_NAND_WAIT) & NAND_WAIT_WR_C) == 0)
|
||||
+ ;
|
||||
+ spin_unlock_irqrestore(&ebu_lock, flags);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static int xway_dev_ready(struct mtd_info *mtd)
|
||||
+{
|
||||
+ return ltq_ebu_r32(EBU_NAND_WAIT) & NAND_WAIT_RD;
|
||||
+}
|
||||
+
|
||||
+static unsigned char xway_read_byte(struct mtd_info *mtd)
|
||||
+{
|
||||
+ struct nand_chip *this = mtd->priv;
|
||||
+ unsigned long nandaddr = (unsigned long) this->IO_ADDR_R;
|
||||
+ unsigned long flags;
|
||||
+ int ret;
|
||||
+
|
||||
+ spin_lock_irqsave(&ebu_lock, flags);
|
||||
+ ret = ltq_r8((void __iomem *)(nandaddr + NAND_READ_DATA));
|
||||
+ spin_unlock_irqrestore(&ebu_lock, flags);
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static int xway_nand_probe(struct platform_device *pdev)
|
||||
+{
|
||||
+ struct nand_chip *this = platform_get_drvdata(pdev);
|
||||
+ unsigned long nandaddr = (unsigned long) this->IO_ADDR_W;
|
||||
+ const __be32 *cs = of_get_property(pdev->dev.of_node,
|
||||
+ "lantiq,cs", NULL);
|
||||
+ u32 cs_flag = 0;
|
||||
+
|
||||
+ /* load our CS from the DT. Either we find a valid 1 or default to 0 */
|
||||
+ if (cs && (*cs == 1))
|
||||
+ cs_flag = NAND_CON_IN_CS1 | NAND_CON_OUT_CS1;
|
||||
+
|
||||
+ /* setup the EBU to run in NAND mode on our base addr */
|
||||
+ ltq_ebu_w32(CPHYSADDR(nandaddr)
|
||||
+ | ADDSEL1_MASK(3) | ADDSEL1_REGEN, EBU_ADDSEL1);
|
||||
+
|
||||
+ ltq_ebu_w32(BUSCON1_SETUP | BUSCON1_BCGEN_RES | BUSCON1_WAITWRC2
|
||||
+ | BUSCON1_WAITRDC2 | BUSCON1_HOLDC1 | BUSCON1_RECOVC1
|
||||
+ | BUSCON1_CMULT4, LTQ_EBU_BUSCON1);
|
||||
+
|
||||
+ ltq_ebu_w32(NAND_CON_NANDM | NAND_CON_CSMUX | NAND_CON_CS_P
|
||||
+ | NAND_CON_SE_P | NAND_CON_WP_P | NAND_CON_PRE_P
|
||||
+ | cs_flag, EBU_NAND_CON);
|
||||
+
|
||||
+ /* finish with a reset */
|
||||
+ xway_reset_chip(this);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+/* allow users to override the partition in DT using the cmdline */
|
||||
+static const char *part_probes[] = { "cmdlinepart", "ofpart", NULL };
|
||||
+
|
||||
+static struct platform_nand_data xway_nand_data = {
|
||||
+ .chip = {
|
||||
+ .nr_chips = 1,
|
||||
+ .chip_delay = 30,
|
||||
+ .part_probe_types = part_probes,
|
||||
+ },
|
||||
+ .ctrl = {
|
||||
+ .probe = xway_nand_probe,
|
||||
+ .cmd_ctrl = xway_cmd_ctrl,
|
||||
+ .dev_ready = xway_dev_ready,
|
||||
+ .select_chip = xway_select_chip,
|
||||
+ .read_byte = xway_read_byte,
|
||||
+ }
|
||||
+};
|
||||
+
|
||||
+/*
|
||||
+ * Try to find the node inside the DT. If it is available attach out
|
||||
+ * platform_nand_data
|
||||
+ */
|
||||
+static int __init xway_register_nand(void)
|
||||
+{
|
||||
+ struct device_node *node;
|
||||
+ struct platform_device *pdev;
|
||||
+
|
||||
+ node = of_find_compatible_node(NULL, NULL, "lantiq,nand-xway");
|
||||
+ if (!node)
|
||||
+ return -ENOENT;
|
||||
+ pdev = of_find_device_by_node(node);
|
||||
+ if (!pdev)
|
||||
+ return -EINVAL;
|
||||
+ pdev->dev.platform_data = &xway_nand_data;
|
||||
+ of_node_put(node);
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+subsys_initcall(xway_register_nand);
|
||||
--
|
||||
1.7.10.4
|
||||
|
@ -0,0 +1,71 @@
|
||||
From b27b8f1bd7d46f1affc9a2bc4142e248411c1afa Mon Sep 17 00:00:00 2001
|
||||
From: John Crispin <blogic@openwrt.org>
|
||||
Date: Mon, 22 Oct 2012 17:42:48 +0200
|
||||
Subject: [PATCH 100/113] MIPS: lantiq: external interrupt units not loaded
|
||||
properly
|
||||
|
||||
The code references the wrong device node causing the number of EIU pins to
|
||||
be wrong.
|
||||
|
||||
Signed-off-by: John Crispin <blogic@openwrt.org>
|
||||
---
|
||||
arch/mips/lantiq/irq.c | 2 +-
|
||||
drivers/pinctrl/pinctrl-xway.c | 15 +++++++++++++++
|
||||
2 files changed, 16 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/arch/mips/lantiq/irq.c b/arch/mips/lantiq/irq.c
|
||||
index f36acd1..8e55622 100644
|
||||
--- a/arch/mips/lantiq/irq.c
|
||||
+++ b/arch/mips/lantiq/irq.c
|
||||
@@ -343,7 +343,7 @@ int __init icu_of_init(struct device_node *node, struct device_node *parent)
|
||||
eiu_node = of_find_compatible_node(NULL, NULL, "lantiq,eiu");
|
||||
if (eiu_node && !of_address_to_resource(eiu_node, 0, &res)) {
|
||||
/* find out how many external irq sources we have */
|
||||
- const __be32 *count = of_get_property(node,
|
||||
+ const __be32 *count = of_get_property(eiu_node,
|
||||
"lantiq,count", NULL);
|
||||
|
||||
if (count)
|
||||
diff --git a/drivers/pinctrl/pinctrl-xway.c b/drivers/pinctrl/pinctrl-xway.c
|
||||
index b9bcaec..ea5e017 100644
|
||||
--- a/drivers/pinctrl/pinctrl-xway.c
|
||||
+++ b/drivers/pinctrl/pinctrl-xway.c
|
||||
@@ -14,6 +14,7 @@
|
||||
#include <linux/of_platform.h>
|
||||
#include <linux/of_address.h>
|
||||
#include <linux/of_gpio.h>
|
||||
+#include <linux/of_irq.h>
|
||||
#include <linux/ioport.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/device.h>
|
||||
@@ -618,6 +619,19 @@ static void xway_gpio_free(struct gpio_chip *chip, unsigned offset)
|
||||
pinctrl_free_gpio(gpio);
|
||||
}
|
||||
|
||||
+static int xway_gpio_to_irq(struct gpio_chip *chip, unsigned int offset)
|
||||
+{
|
||||
+ struct ltq_pinmux_info *info = dev_get_drvdata(chip->dev);
|
||||
+ struct resource res;
|
||||
+ int i;
|
||||
+
|
||||
+ for (i = 0; i < info->num_exin; i++)
|
||||
+ if (offset == info->exin[i])
|
||||
+ if (of_irq_to_resource(chip->dev->of_node, i, &res))
|
||||
+ return res.start;
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
static struct gpio_chip xway_chip = {
|
||||
.label = "gpio-xway",
|
||||
.direction_input = xway_gpio_dir_in,
|
||||
@@ -626,6 +640,7 @@ static struct gpio_chip xway_chip = {
|
||||
.set = xway_gpio_set,
|
||||
.request = xway_gpio_req,
|
||||
.free = xway_gpio_free,
|
||||
+ .to_irq = xway_gpio_to_irq,
|
||||
.base = -1,
|
||||
};
|
||||
|
||||
--
|
||||
1.7.10.4
|
||||
|
@ -0,0 +1,27 @@
|
||||
From 50b5073dd266721a690323519fb906a56daa09d7 Mon Sep 17 00:00:00 2001
|
||||
From: John Crispin <blogic@openwrt.org>
|
||||
Date: Thu, 1 Nov 2012 20:39:43 +0100
|
||||
Subject: [PATCH 101/113] MIPS: lantiq: bootsel bits are wrong
|
||||
|
||||
---
|
||||
arch/mips/lantiq/xway/reset.c | 4 ++--
|
||||
1 file changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/arch/mips/lantiq/xway/reset.c b/arch/mips/lantiq/xway/reset.c
|
||||
index 22c55f7..a89d1a3 100644
|
||||
--- a/arch/mips/lantiq/xway/reset.c
|
||||
+++ b/arch/mips/lantiq/xway/reset.c
|
||||
@@ -34,8 +34,8 @@
|
||||
/* reset cause */
|
||||
#define RCU_STAT_SHIFT 26
|
||||
/* boot selection */
|
||||
-#define RCU_BOOT_SEL_SHIFT 26
|
||||
-#define RCU_BOOT_SEL_MASK 0x7
|
||||
+#define RCU_BOOT_SEL_SHIFT 17
|
||||
+#define RCU_BOOT_SEL_MASK 0xf
|
||||
|
||||
/* remapped base addr of the reset control unit */
|
||||
static void __iomem *ltq_rcu_membase;
|
||||
--
|
||||
1.7.10.4
|
||||
|
@ -0,0 +1,62 @@
|
||||
From 671f34ea864ddc353f32272b3a2f7ee62d6f8548 Mon Sep 17 00:00:00 2001
|
||||
From: John Crispin <blogic@openwrt.org>
|
||||
Date: Thu, 1 Nov 2012 20:50:39 +0100
|
||||
Subject: [PATCH 102/113] MIPS: lantiq: fixes dma irq ack
|
||||
|
||||
---
|
||||
arch/mips/lantiq/xway/dma.c | 11 ++++++++++-
|
||||
1 file changed, 10 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/arch/mips/lantiq/xway/dma.c b/arch/mips/lantiq/xway/dma.c
|
||||
index 55d2c4f..a301b3b 100644
|
||||
--- a/arch/mips/lantiq/xway/dma.c
|
||||
+++ b/arch/mips/lantiq/xway/dma.c
|
||||
@@ -25,6 +25,7 @@
|
||||
#include <lantiq_soc.h>
|
||||
#include <xway_dma.h>
|
||||
|
||||
+#define LTQ_DMA_ID 0x08
|
||||
#define LTQ_DMA_CTRL 0x10
|
||||
#define LTQ_DMA_CPOLL 0x14
|
||||
#define LTQ_DMA_CS 0x18
|
||||
@@ -89,7 +90,7 @@ ltq_dma_ack_irq(struct ltq_dma_channel *ch)
|
||||
|
||||
local_irq_save(flags);
|
||||
ltq_dma_w32(ch->nr, LTQ_DMA_CS);
|
||||
- ltq_dma_w32(DMA_IRQ_ACK, LTQ_DMA_CIS);
|
||||
+ ltq_dma_w32(ltq_dma_r32(LTQ_DMA_CIS), LTQ_DMA_CIS);
|
||||
local_irq_restore(flags);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(ltq_dma_ack_irq);
|
||||
@@ -103,6 +104,7 @@ ltq_dma_open(struct ltq_dma_channel *ch)
|
||||
ltq_dma_w32(ch->nr, LTQ_DMA_CS);
|
||||
ltq_dma_w32_mask(0, DMA_CHAN_ON, LTQ_DMA_CCTRL);
|
||||
ltq_dma_enable_irq(ch);
|
||||
+ ltq_dma_ack_irq(ch);
|
||||
local_irq_restore(flag);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(ltq_dma_open);
|
||||
@@ -214,6 +216,7 @@ ltq_dma_init(struct platform_device *pdev)
|
||||
{
|
||||
struct clk *clk;
|
||||
struct resource *res;
|
||||
+ unsigned id;
|
||||
int i;
|
||||
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
@@ -243,6 +246,12 @@ ltq_dma_init(struct platform_device *pdev)
|
||||
ltq_dma_w32(DMA_POLL | DMA_CLK_DIV4, LTQ_DMA_CPOLL);
|
||||
ltq_dma_w32_mask(DMA_CHAN_ON, 0, LTQ_DMA_CCTRL);
|
||||
}
|
||||
+
|
||||
+ id = ltq_dma_r32(LTQ_DMA_ID);
|
||||
+ dev_info(&pdev->dev,
|
||||
+ "Init done - hw rev: %X, ports: %d, channels: %d\n",
|
||||
+ id & 0x1f, (id >> 16) & 0xf, id >> 20);
|
||||
+
|
||||
dev_info(&pdev->dev, "init done\n");
|
||||
return 0;
|
||||
}
|
||||
--
|
||||
1.7.10.4
|
||||
|
@ -0,0 +1,36 @@
|
||||
From 176aad2b97d2e7d623ef07ee9b68b71c7db8cce4 Mon Sep 17 00:00:00 2001
|
||||
From: John Crispin <blogic@openwrt.org>
|
||||
Date: Thu, 1 Nov 2012 20:50:52 +0100
|
||||
Subject: [PATCH 103/113] MIPS: lantiq: prom code invalidated devicetree
|
||||
memory
|
||||
|
||||
---
|
||||
arch/mips/lantiq/prom.c | 5 +----
|
||||
1 file changed, 1 insertion(+), 4 deletions(-)
|
||||
|
||||
diff --git a/arch/mips/lantiq/prom.c b/arch/mips/lantiq/prom.c
|
||||
index 6cfd611..9f9e875 100644
|
||||
--- a/arch/mips/lantiq/prom.c
|
||||
+++ b/arch/mips/lantiq/prom.c
|
||||
@@ -87,9 +87,6 @@ void __init device_tree_init(void)
|
||||
reserve_bootmem(base, size, BOOTMEM_DEFAULT);
|
||||
|
||||
unflatten_device_tree();
|
||||
-
|
||||
- /* free the space reserved for the dt blob */
|
||||
- free_bootmem(base, size);
|
||||
}
|
||||
|
||||
void __init prom_init(void)
|
||||
@@ -119,7 +116,7 @@ int __init plat_of_setup(void)
|
||||
sizeof(of_ids[0].compatible));
|
||||
strncpy(of_ids[1].compatible, "simple-bus",
|
||||
sizeof(of_ids[1].compatible));
|
||||
- return of_platform_bus_probe(NULL, of_ids, NULL);
|
||||
+ return of_platform_populate(NULL, of_ids, NULL, NULL);
|
||||
}
|
||||
|
||||
arch_initcall(plat_of_setup);
|
||||
--
|
||||
1.7.10.4
|
||||
|
@ -0,0 +1,60 @@
|
||||
From 8fc2eacbe332fbf6bfd09425fb141bb47d843a78 Mon Sep 17 00:00:00 2001
|
||||
From: John Crispin <blogic@openwrt.org>
|
||||
Date: Mon, 22 Oct 2012 09:32:46 +0200
|
||||
Subject: [PATCH 104/113] MIPS: lantiq: xway: split ltq_reset_once into 2
|
||||
subfunctions
|
||||
|
||||
We need to call the reset functions from within the phy reset code and dont
|
||||
want to duplicate the access code for the reset registers.
|
||||
|
||||
Signed-off-by: John Crispin <blogic@openwrt.org>
|
||||
---
|
||||
arch/mips/include/asm/mach-lantiq/xway/lantiq_soc.h | 3 +++
|
||||
arch/mips/lantiq/xway/reset.c | 14 ++++++++++++--
|
||||
2 files changed, 15 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/arch/mips/include/asm/mach-lantiq/xway/lantiq_soc.h b/arch/mips/include/asm/mach-lantiq/xway/lantiq_soc.h
|
||||
index 6a2df70..6b9f5be 100644
|
||||
--- a/arch/mips/include/asm/mach-lantiq/xway/lantiq_soc.h
|
||||
+++ b/arch/mips/include/asm/mach-lantiq/xway/lantiq_soc.h
|
||||
@@ -87,5 +87,8 @@ extern __iomem void *ltq_cgu_membase;
|
||||
extern void ltq_pmu_enable(unsigned int module);
|
||||
extern void ltq_pmu_disable(unsigned int module);
|
||||
|
||||
+/* allow drivers to reset clock domains and ip cores */
|
||||
+void ltq_reset_once(unsigned int module, ulong u);
|
||||
+
|
||||
#endif /* CONFIG_SOC_TYPE_XWAY */
|
||||
#endif /* _LTQ_XWAY_H__ */
|
||||
diff --git a/arch/mips/lantiq/xway/reset.c b/arch/mips/lantiq/xway/reset.c
|
||||
index a89d1a3..1b77f82 100644
|
||||
--- a/arch/mips/lantiq/xway/reset.c
|
||||
+++ b/arch/mips/lantiq/xway/reset.c
|
||||
@@ -55,12 +55,22 @@ unsigned char ltq_boot_select(void)
|
||||
return (val >> RCU_BOOT_SEL_SHIFT) & RCU_BOOT_SEL_MASK;
|
||||
}
|
||||
|
||||
+static void ltq_reset_enter(unsigned int module)
|
||||
+{
|
||||
+ ltq_rcu_w32(ltq_rcu_r32(RCU_RST_REQ) | module, RCU_RST_REQ);
|
||||
+}
|
||||
+
|
||||
+static void ltq_reset_leave(unsigned int module)
|
||||
+{
|
||||
+ ltq_rcu_w32(ltq_rcu_r32(RCU_RST_REQ) & ~module, RCU_RST_REQ);
|
||||
+}
|
||||
+
|
||||
/* reset a io domain for u micro seconds */
|
||||
void ltq_reset_once(unsigned int module, ulong u)
|
||||
{
|
||||
- ltq_rcu_w32(ltq_rcu_r32(RCU_RST_REQ) | module, RCU_RST_REQ);
|
||||
+ ltq_reset_enter(RCU_RST_REQ);
|
||||
udelay(u);
|
||||
- ltq_rcu_w32(ltq_rcu_r32(RCU_RST_REQ) & ~module, RCU_RST_REQ);
|
||||
+ ltq_reset_leave(RCU_RST_REQ);
|
||||
}
|
||||
|
||||
static void ltq_machine_restart(char *command)
|
||||
--
|
||||
1.7.10.4
|
||||
|
@ -0,0 +1,210 @@
|
||||
From 4ed46c23c7257e15a419eb3176375601b312c157 Mon Sep 17 00:00:00 2001
|
||||
From: John Crispin <blogic@openwrt.org>
|
||||
Date: Mon, 22 Oct 2012 09:47:09 +0200
|
||||
Subject: [PATCH 105/113] MIPS: lantiq: xway: adds reset code for 11G PHYs
|
||||
|
||||
Signed-off-by: John Crispin <blogic@openwrt.org>
|
||||
---
|
||||
arch/mips/a | 42 +++++++++++++
|
||||
arch/mips/b | 36 +++++++++++
|
||||
.../mips/include/asm/mach-lantiq/xway/lantiq_soc.h | 3 +
|
||||
arch/mips/lantiq/xway/reset.c | 63 +++++++++++++++++++-
|
||||
4 files changed, 142 insertions(+), 2 deletions(-)
|
||||
create mode 100644 arch/mips/a
|
||||
create mode 100644 arch/mips/b
|
||||
|
||||
diff --git a/arch/mips/a b/arch/mips/a
|
||||
new file mode 100644
|
||||
index 0000000..31e61f8
|
||||
--- /dev/null
|
||||
+++ b/arch/mips/a
|
||||
@@ -0,0 +1,42 @@
|
||||
+diff --git a/arch/mips/include/asm/mach-lantiq/xway/lantiq_soc.h b/arch/mips/include/asm/mach-lantiq/xway/lantiq_soc.h
|
||||
+index 6a2df70..056df1a 100644
|
||||
+--- a/arch/mips/include/asm/mach-lantiq/xway/lantiq_soc.h
|
||||
++++ b/arch/mips/include/asm/mach-lantiq/xway/lantiq_soc.h
|
||||
+@@ -87,5 +87,8 @@ extern __iomem void *ltq_cgu_membase;
|
||||
+ extern void ltq_pmu_enable(unsigned int module);
|
||||
+ extern void ltq_pmu_disable(unsigned int module);
|
||||
+
|
||||
++/* allow drivers to reset clock domains and ip cores */
|
||||
++void ltq_reset_once(unsigned int module, ulong u);
|
||||
++
|
||||
+ #endif /* CONFIG_SOC_TYPE_XWAY */
|
||||
+ #endif /* _LTQ_XWAY_H__ */
|
||||
+diff --git a/arch/mips/lantiq/xway/reset.c b/arch/mips/lantiq/xway/reset.c
|
||||
+index 22c55f7..c2a7e65 100644
|
||||
+--- a/arch/mips/lantiq/xway/reset.c
|
||||
++++ b/arch/mips/lantiq/xway/reset.c
|
||||
+@@ -55,13 +62,23 @@ unsigned char ltq_boot_select(void)
|
||||
+ return (val >> RCU_BOOT_SEL_SHIFT) & RCU_BOOT_SEL_MASK;
|
||||
+ }
|
||||
+
|
||||
++static void ltq_reset_enter(unsigned int module)
|
||||
++{
|
||||
++ ltq_rcu_w32(ltq_rcu_r32(RCU_RST_REQ) | module, RCU_RST_REQ);
|
||||
++}
|
||||
++
|
||||
++static void ltq_reset_leave(unsigned int module)
|
||||
++{
|
||||
++ ltq_rcu_w32(ltq_rcu_r32(RCU_RST_REQ) & ~module, RCU_RST_REQ);
|
||||
++}
|
||||
++
|
||||
+ /* reset a io domain for u micro seconds */
|
||||
+ void ltq_reset_once(unsigned int module, ulong u)
|
||||
+ {
|
||||
+- ltq_rcu_w32(ltq_rcu_r32(RCU_RST_REQ) | module, RCU_RST_REQ);
|
||||
++ ltq_reset_enter(RCU_RST_REQ);
|
||||
+ udelay(u);
|
||||
+- ltq_rcu_w32(ltq_rcu_r32(RCU_RST_REQ) & ~module, RCU_RST_REQ);
|
||||
++ ltq_reset_leave(RCU_RST_REQ);
|
||||
+ }
|
||||
+
|
||||
+ static void ltq_machine_restart(char *command)
|
||||
diff --git a/arch/mips/b b/arch/mips/b
|
||||
new file mode 100644
|
||||
index 0000000..c6a0323
|
||||
--- /dev/null
|
||||
+++ b/arch/mips/b
|
||||
@@ -0,0 +1,36 @@
|
||||
+diff --git a/arch/mips/include/asm/mach-lantiq/xway/lantiq_soc.h b/arch/mips/include/asm/mach-lantiq/xway/lantiq_soc.h
|
||||
+index 6a2df70..056df1a 100644
|
||||
+--- a/arch/mips/include/asm/mach-lantiq/xway/lantiq_soc.h
|
||||
++++ b/arch/mips/include/asm/mach-lantiq/xway/lantiq_soc.h
|
||||
+@@ -87,8 +87,11 @@ extern __iomem void *ltq_cgu_membase;
|
||||
+ extern void ltq_pmu_enable(unsigned int module);
|
||||
+ extern void ltq_pmu_disable(unsigned int module);
|
||||
+
|
||||
++/* allow booting xrx200 phys */
|
||||
++int xrx200_gphy_boot(struct device *dev, unsigned int id, dma_addr_t dev_addr);
|
||||
++
|
||||
+ #endif /* CONFIG_SOC_TYPE_XWAY */
|
||||
+ #endif /* _LTQ_XWAY_H__ */
|
||||
+diff --git a/arch/mips/lantiq/xway/reset.c b/arch/mips/lantiq/xway/reset.c
|
||||
+index 22c55f7..c2a7e65 100644
|
||||
+--- a/arch/mips/lantiq/xway/reset.c
|
||||
++++ b/arch/mips/lantiq/xway/reset.c
|
||||
+@@ -26,11 +26,18 @@
|
||||
+
|
||||
+ /* reset request register */
|
||||
+ #define RCU_RST_REQ 0x0010
|
||||
++
|
||||
++#define VR9_RCU_GFS_ADD0 0x0020
|
||||
++#define VR9_RCU_GFS_ADD1 0x0068
|
||||
++
|
||||
+ /* reset status register */
|
||||
+ #define RCU_RST_STAT 0x0014
|
||||
+
|
||||
+ /* reboot bit */
|
||||
++#define VR9_RCU_RD_GPHY0 BIT(31)
|
||||
+ #define RCU_RD_SRST BIT(30)
|
||||
++#define VR9_RCU_RD_GPHY1 BIT(29)
|
||||
++
|
||||
+ /* reset cause */
|
||||
+ #define RCU_STAT_SHIFT 26
|
||||
+ /* boot selection */
|
||||
diff --git a/arch/mips/include/asm/mach-lantiq/xway/lantiq_soc.h b/arch/mips/include/asm/mach-lantiq/xway/lantiq_soc.h
|
||||
index 6b9f5be..056df1a 100644
|
||||
--- a/arch/mips/include/asm/mach-lantiq/xway/lantiq_soc.h
|
||||
+++ b/arch/mips/include/asm/mach-lantiq/xway/lantiq_soc.h
|
||||
@@ -90,5 +90,8 @@ extern void ltq_pmu_disable(unsigned int module);
|
||||
/* allow drivers to reset clock domains and ip cores */
|
||||
void ltq_reset_once(unsigned int module, ulong u);
|
||||
|
||||
+/* allow booting xrx200 phys */
|
||||
+int xrx200_gphy_boot(struct device *dev, unsigned int id, dma_addr_t dev_addr);
|
||||
+
|
||||
#endif /* CONFIG_SOC_TYPE_XWAY */
|
||||
#endif /* _LTQ_XWAY_H__ */
|
||||
diff --git a/arch/mips/lantiq/xway/reset.c b/arch/mips/lantiq/xway/reset.c
|
||||
index 1b77f82..56293cf 100644
|
||||
--- a/arch/mips/lantiq/xway/reset.c
|
||||
+++ b/arch/mips/lantiq/xway/reset.c
|
||||
@@ -28,9 +28,15 @@
|
||||
#define RCU_RST_REQ 0x0010
|
||||
/* reset status register */
|
||||
#define RCU_RST_STAT 0x0014
|
||||
+/* vr9 gphy registers */
|
||||
+#define VR9_RCU_GFS_ADD0 0x0020
|
||||
+#define VR9_RCU_GFS_ADD1 0x0068
|
||||
|
||||
/* reboot bit */
|
||||
+#define VR9_RCU_RD_GPHY0 BIT(31)
|
||||
#define RCU_RD_SRST BIT(30)
|
||||
+#define VR9_RCU_RD_GPHY1 BIT(29)
|
||||
+
|
||||
/* reset cause */
|
||||
#define RCU_STAT_SHIFT 26
|
||||
/* boot selection */
|
||||
@@ -65,13 +71,66 @@ static void ltq_reset_leave(unsigned int module)
|
||||
ltq_rcu_w32(ltq_rcu_r32(RCU_RST_REQ) & ~module, RCU_RST_REQ);
|
||||
}
|
||||
|
||||
+/* reset / boot a gphy */
|
||||
+static struct ltq_xrx200_gphy_reset {
|
||||
+ u32 rd;
|
||||
+ u32 addr;
|
||||
+} xrx200_gphy[] = {
|
||||
+ {VR9_RCU_RD_GPHY0, VR9_RCU_GFS_ADD0},
|
||||
+ {VR9_RCU_RD_GPHY1, VR9_RCU_GFS_ADD1},
|
||||
+};
|
||||
+
|
||||
+/* reset and boot a gphy. these phys only exist on xrx200 SoC */
|
||||
+int xrx200_gphy_boot(struct device *dev, unsigned int id, dma_addr_t dev_addr)
|
||||
+{
|
||||
+ if (id > 1) {
|
||||
+ dev_err(dev, "%u is an invalid gphy id\n", id);
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+ dev_info(dev, "booting GPHY%u firmware at %X\n", id, dev_addr);
|
||||
+
|
||||
+ ltq_reset_enter(xrx200_gphy[id].rd);
|
||||
+ ltq_rcu_w32(dev_addr, xrx200_gphy[id].addr);
|
||||
+ ltq_reset_leave(xrx200_gphy[id].rd);
|
||||
+ return 0;
|
||||
+}
|
||||
+EXPORT_SYMBOL_GPL(xrx200_gphy_boot);
|
||||
+
|
||||
/* reset a io domain for u micro seconds */
|
||||
void ltq_reset_once(unsigned int module, ulong u)
|
||||
{
|
||||
- ltq_reset_enter(RCU_RST_REQ);
|
||||
+ ltq_reset_enter(module);
|
||||
udelay(u);
|
||||
- ltq_reset_leave(RCU_RST_REQ);
|
||||
+ ltq_reset_leave(module);
|
||||
+}
|
||||
+
|
||||
+int ifx_rcu_rst(unsigned int reset_domain_id, unsigned int module_id)
|
||||
+{
|
||||
+ ltq_reset_once(BIT(module_id), 20);
|
||||
+ return 0;
|
||||
+}
|
||||
+EXPORT_SYMBOL(ifx_rcu_rst);
|
||||
+
|
||||
+unsigned int ifx_rcu_rst_req_read(void)
|
||||
+{
|
||||
+ unsigned int ret;
|
||||
+
|
||||
+ ret = ltq_rcu_r32(RCU_RST_REQ);
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+EXPORT_SYMBOL(ifx_rcu_rst_req_read);
|
||||
+
|
||||
+void ifx_rcu_rst_req_write(unsigned int value, unsigned int mask)
|
||||
+{
|
||||
+ unsigned int ret;
|
||||
+
|
||||
+ ret = ltq_rcu_r32(RCU_RST_REQ);
|
||||
+ ret &= ~mask;
|
||||
+ ret |= value & mask;
|
||||
+ ltq_rcu_w32(ret, RCU_RST_REQ);
|
||||
}
|
||||
+EXPORT_SYMBOL(ifx_rcu_rst_req_write);
|
||||
|
||||
static void ltq_machine_restart(char *command)
|
||||
{
|
||||
--
|
||||
1.7.10.4
|
||||
|
@ -0,0 +1,607 @@
|
||||
From b2ea96b934fcf665b4c0cc844416a7a2618e198e Mon Sep 17 00:00:00 2001
|
||||
From: John Crispin <blogic@openwrt.org>
|
||||
Date: Mon, 22 Oct 2012 09:52:50 +0200
|
||||
Subject: [PATCH 106/113] MIPS: lantiq: xway: adds PHY11G platform code
|
||||
|
||||
Signed-off-by: John Crispin <blogic@openwrt.org>
|
||||
---
|
||||
arch/mips/lantiq/xway/Makefile | 2 +-
|
||||
arch/mips/lantiq/xway/vr9_switch_regs.h | 425 +++++++++++++++++++++++++++++++
|
||||
arch/mips/lantiq/xway/xway_phy_fw.c | 146 +++++++++++
|
||||
3 files changed, 572 insertions(+), 1 deletion(-)
|
||||
create mode 100644 arch/mips/lantiq/xway/vr9_switch_regs.h
|
||||
create mode 100644 arch/mips/lantiq/xway/xway_phy_fw.c
|
||||
|
||||
diff --git a/arch/mips/lantiq/xway/Makefile b/arch/mips/lantiq/xway/Makefile
|
||||
index 70a58c7..1998b7c 100644
|
||||
--- a/arch/mips/lantiq/xway/Makefile
|
||||
+++ b/arch/mips/lantiq/xway/Makefile
|
||||
@@ -1 +1 @@
|
||||
-obj-y := prom.o sysctrl.o clk.o reset.o dma.o gptu.o
|
||||
+obj-y := prom.o sysctrl.o clk.o reset.o dma.o gptu.o xway_phy_fw.o
|
||||
diff --git a/arch/mips/lantiq/xway/vr9_switch_regs.h b/arch/mips/lantiq/xway/vr9_switch_regs.h
|
||||
new file mode 100644
|
||||
index 0000000..339e4c1
|
||||
--- /dev/null
|
||||
+++ b/arch/mips/lantiq/xway/vr9_switch_regs.h
|
||||
@@ -0,0 +1,425 @@
|
||||
+/*
|
||||
+ * This program is free software; you can redistribute it and/or modify
|
||||
+ * it under the terms of the GNU General Public License as published by
|
||||
+ * the Free Software Foundation; either version 2 of the License, or
|
||||
+ * (at your option) any later version.
|
||||
+ *
|
||||
+ * This program is distributed in the hope that it will be useful,
|
||||
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
+ * GNU General Public License for more details.
|
||||
+ *
|
||||
+ * You should have received a copy of the GNU General Public License
|
||||
+ * along with this program; if not, write to the Free Software
|
||||
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
|
||||
+ *
|
||||
+ * Copyright (C) 2012 Daniel Schwierzeck <daniel.schwierzeck@googlemail.com>
|
||||
+ */
|
||||
+
|
||||
+#ifndef __VR9_SWITCH_REGS_H__
|
||||
+#define __VR9_SWITCH_REGS_H__
|
||||
+
|
||||
+/* Switch core registers */
|
||||
+struct vr9_switch_core_regs {
|
||||
+ __be32 swres;
|
||||
+ /* TODO: implement registers */
|
||||
+ __be32 rsvd0[0x3f];
|
||||
+};
|
||||
+
|
||||
+/* Switch buffer management registers */
|
||||
+struct vr9_switch_bm_regs {
|
||||
+ struct bm_core {
|
||||
+ __be32 ram_val3; /* RAM value 3 */
|
||||
+ __be32 ram_val2; /* RAM value 2 */
|
||||
+ __be32 ram_val1; /* RAM value 1 */
|
||||
+ __be32 ram_val0; /* RAM value 0 */
|
||||
+ __be32 ram_addr; /* RAM address */
|
||||
+ __be32 ram_ctrl; /* RAM access control */
|
||||
+ __be32 fsqm_gctrl; /* Free segment queue global control */
|
||||
+ __be32 cons_sel; /* Number of consumed segments */
|
||||
+ __be32 cons_pkt; /* Number of consumed packet pointers */
|
||||
+ __be32 gctrl; /* Global control */
|
||||
+ __be32 queue_gctrl; /* Queue manager global control */
|
||||
+ /* TODO: implement registers */
|
||||
+ __be32 rsvd0[0x35];
|
||||
+ } core;
|
||||
+
|
||||
+ struct bm_port {
|
||||
+ __be32 pcfg; /* Port config */
|
||||
+ __be32 rmon_ctrl; /* RMON control */
|
||||
+ } port[13];
|
||||
+
|
||||
+ __be32 rsvd0[0x66];
|
||||
+
|
||||
+ struct bm_queue {
|
||||
+ __be32 rsvd0;
|
||||
+ __be32 pqm_rs; /* Packet queue manager rate shape assignment */
|
||||
+ } queue[32];
|
||||
+
|
||||
+ struct bm_shaper {
|
||||
+ __be32 ctrl; /* Rate shaper control */
|
||||
+ __be32 cbs; /* Rate shaper committed burst size */
|
||||
+ __be32 ibs; /* Rate shaper instantaneous burst size */
|
||||
+ __be32 cir_ext; /* Rate shaper rate exponent */
|
||||
+ __be32 cir_mant; /* Rate shaper rate mantissa */
|
||||
+ } shaper[16];
|
||||
+
|
||||
+ __be32 rsvd1[0x2a8];
|
||||
+};
|
||||
+
|
||||
+/* Switch parser and classification engine registers */
|
||||
+struct vr9_switch_pce_regs {
|
||||
+ struct pce_core {
|
||||
+ __be32 tbl_key[16]; /* Table key data */
|
||||
+ __be32 tbl_mask; /* Table mask */
|
||||
+ __be32 tbl_val[5]; /* Table value */
|
||||
+ __be32 tbl_addr; /* Table entry address */
|
||||
+ __be32 tbl_ctrl; /* Table access control */
|
||||
+ __be32 tbl_stat; /* Table general status */
|
||||
+ __be32 age_0; /* Aging counter config 0 */
|
||||
+ __be32 age_1; /* Aging counter config 1 */
|
||||
+ __be32 pmap_1; /* Port map (monitoring) */
|
||||
+ __be32 pmap_2; /* Port map (multicast) */
|
||||
+ __be32 pmap_3; /* Port map (unknown unicast) */
|
||||
+ __be32 gctrl_0; /* Global control 0 */
|
||||
+ __be32 gctrl_1; /* Global control 1 */
|
||||
+ __be32 tcm_gctrl; /* Three-color marker global control */
|
||||
+ __be32 igmp_ctrl; /* IGMP control */
|
||||
+ __be32 igmp_drpm; /* IGMP default router port map */
|
||||
+ __be32 igmp_age_0; /* IGMP aging 0 */
|
||||
+ __be32 igmp_age_1; /* IGMP aging 1 */
|
||||
+ __be32 igmp_stat; /* IGMP status */
|
||||
+ __be32 wol_gctrl; /* Wake-on-LAN control */
|
||||
+ __be32 wol_da_0; /* Wake-on-LAN destination address 0 */
|
||||
+ __be32 wol_da_1; /* Wake-on-LAN destination address 1 */
|
||||
+ __be32 wol_da_2; /* Wake-on-LAN destination address 2 */
|
||||
+ __be32 wol_pw_0; /* Wake-on-LAN password 0 */
|
||||
+ __be32 wol_pw_1; /* Wake-on-LAN password 1 */
|
||||
+ __be32 wol_pw_2; /* Wake-on-LAN password 2 */
|
||||
+ __be32 ier_0; /* PCE global interrupt enable 0 */
|
||||
+ __be32 ier_1; /* PCE global interrupt enable 1 */
|
||||
+ __be32 isr_0; /* PCE global interrupt status 0 */
|
||||
+ __be32 isr_1; /* PCE global interrupt status 1 */
|
||||
+ __be32 parser_stat; /* Parser status */
|
||||
+ __be32 rsvd0[0x6];
|
||||
+ } core;
|
||||
+
|
||||
+ __be32 rsvd0[0x10];
|
||||
+
|
||||
+ struct pce_port {
|
||||
+ __be32 pctrl_0; /* Port control 0 */
|
||||
+ __be32 pctrl_1; /* Port control 1 */
|
||||
+ __be32 pctrl_2; /* Port control 2 */
|
||||
+ __be32 pctrl_3; /* Port control 3 */
|
||||
+ __be32 wol_ctrl; /* Wake-on-LAN control */
|
||||
+ __be32 vlan_ctrl; /* VLAN control */
|
||||
+ __be32 def_pvid; /* Default port VID */
|
||||
+ __be32 pstat; /* Port status */
|
||||
+ __be32 pier; /* Interrupt enable */
|
||||
+ __be32 pisr; /* Interrupt status */
|
||||
+ } port[13];
|
||||
+
|
||||
+ __be32 rsvd1[0x7e];
|
||||
+
|
||||
+ struct pce_meter {
|
||||
+ /* TODO: implement registers */
|
||||
+ __be32 rsvd0[0x7];
|
||||
+ } meter[8];
|
||||
+
|
||||
+ __be32 rsvd2[0x308];
|
||||
+};
|
||||
+
|
||||
+static inline unsigned int to_pce_tbl_key_id(unsigned int id)
|
||||
+{
|
||||
+ return 15 - id;
|
||||
+}
|
||||
+
|
||||
+static inline unsigned int to_pce_tbl_value_id(unsigned int id)
|
||||
+{
|
||||
+ return 4 - id;
|
||||
+}
|
||||
+
|
||||
+/* Switch ethernet MAC registers */
|
||||
+struct vr9_switch_mac_regs {
|
||||
+ struct mac_core {
|
||||
+ __be32 test; /* MAC test */
|
||||
+ __be32 pfad_cfg; /* Pause frame source address config */
|
||||
+ __be32 pfsa_0; /* Pause frame source address 0 */
|
||||
+ __be32 pfsa_1; /* Pause frame source address 1 */
|
||||
+ __be32 pfsa_2; /* Pause frame source address 2 */
|
||||
+ __be32 flen; /* Frame length */
|
||||
+ __be32 vlan_etype_0; /* VLAN ethertype 0 */
|
||||
+ __be32 vlan_etype_1; /* VLAN ethertype 1 */
|
||||
+ __be32 ier; /* Interrupt enable */
|
||||
+ __be32 isr; /* Interrupt status */
|
||||
+ __be32 rsvd0[0x36];
|
||||
+ } core;
|
||||
+
|
||||
+ struct mac_port {
|
||||
+ __be32 pstat; /* Port status */
|
||||
+ __be32 pisr; /* Interrupt status */
|
||||
+ __be32 pier; /* Interrupt enable */
|
||||
+ __be32 ctrl_0; /* Control 0 */
|
||||
+ __be32 ctrl_1; /* Control 1 */
|
||||
+ __be32 ctrl_2; /* Control 2 */
|
||||
+ __be32 ctrl_3; /* Control 3 */
|
||||
+ __be32 ctrl_4; /* Control 4 */
|
||||
+ __be32 ctrl_5; /* Control 5 */
|
||||
+ __be32 rsvd0[0x2];
|
||||
+ __be32 testen; /* Test enable */
|
||||
+ } port[13];
|
||||
+
|
||||
+ __be32 rsvd0[0xa4];
|
||||
+};
|
||||
+
|
||||
+/* Switch Fetch DMA registers */
|
||||
+struct vr9_switch_fdma_regs {
|
||||
+ struct fdma_core {
|
||||
+ __be32 ctrl; /* FDMA control */
|
||||
+ __be32 stetype; /* Special tag ethertype control */
|
||||
+ __be32 vtetype; /* VLAN tag ethertype control */
|
||||
+ __be32 stat; /* FDMA status */
|
||||
+ __be32 ier; /* FDMA interrupt enable */
|
||||
+ __be32 isr; /* FDMA interrupt status */
|
||||
+ } core;
|
||||
+
|
||||
+ __be32 rsvd0[0x3a];
|
||||
+
|
||||
+ struct fdma_port {
|
||||
+ __be32 pctrl; /* Port control */
|
||||
+ __be32 prio; /* Port priority */
|
||||
+ __be32 pstat_0; /* Port status 0 */
|
||||
+ __be32 pstat_1; /* Port status 1 */
|
||||
+ __be32 tstamp_0; /* Egress time stamp 0 */
|
||||
+ __be32 tstamp_1; /* Egress time stamp 1 */
|
||||
+ } port[13];
|
||||
+
|
||||
+ __be32 rsvd1[0x72];
|
||||
+};
|
||||
+
|
||||
+/* Switch Store DMA registers */
|
||||
+struct vr9_switch_sdma_regs {
|
||||
+ struct sdma_core {
|
||||
+ __be32 ctrl; /* SDMA Control */
|
||||
+ __be32 fcthr_1; /* Flow control threshold 1 */
|
||||
+ __be32 rsvd0;
|
||||
+ __be32 fcthr_3; /* Flow control threshold 3 */
|
||||
+ __be32 fcthr_4; /* Flow control threshold 4 */
|
||||
+ __be32 fcthr_5; /* Flow control threshold 5 */
|
||||
+ __be32 fcthr_6; /* Flow control threshold 6 */
|
||||
+ __be32 fcthr_7; /* Flow control threshold 7 */
|
||||
+ __be32 stat_0; /* SDMA status 0 */
|
||||
+ __be32 stat_1; /* SDMA status 1 */
|
||||
+ __be32 stat_2; /* SDMA status 2 */
|
||||
+ __be32 ier; /* SDMA interrupt enable */
|
||||
+ __be32 isr; /* SDMA interrupt status */
|
||||
+ } core;
|
||||
+
|
||||
+ __be32 rsvd0[0x73];
|
||||
+
|
||||
+ struct sdma_port {
|
||||
+ __be32 pctrl; /* Port control */
|
||||
+ __be32 prio; /* Port priority */
|
||||
+ __be32 pstat_0; /* Port status 0 */
|
||||
+ __be32 pstat_1; /* Port status 1 */
|
||||
+ __be32 tstamp_0; /* Ingress time stamp 0 */
|
||||
+ __be32 tstamp_1; /* Ingress time stamp 1 */
|
||||
+ } port[13];
|
||||
+
|
||||
+ __be32 rsvd1[0x32];
|
||||
+};
|
||||
+
|
||||
+/* Switch MDIO control and status registers */
|
||||
+struct vr9_switch_mdio_regs {
|
||||
+ __be32 glob_ctrl; /* Global control 0 */
|
||||
+ __be32 rsvd0[7];
|
||||
+ __be32 mdio_ctrl; /* MDIO control */
|
||||
+ __be32 mdio_read; /* MDIO read data */
|
||||
+ __be32 mdio_write; /* MDIO write data */
|
||||
+ __be32 mdc_cfg_0; /* MDC clock configuration 0 */
|
||||
+ __be32 mdc_cfg_1; /* MDC clock configuration 1 */
|
||||
+ __be32 rsvd1[0x3];
|
||||
+ __be32 phy_addr[6]; /* PHY address port 5..0 */
|
||||
+ __be32 mdio_stat[6]; /* MDIO PHY polling status port 0..5 */
|
||||
+ __be32 aneg_eee[6]; /* EEE auto-neg overrides port 0..5 */
|
||||
+ __be32 rsvd2[0x14];
|
||||
+};
|
||||
+
|
||||
+static inline unsigned int to_mdio_phyaddr_id(unsigned int id)
|
||||
+{
|
||||
+ return 5 - id;
|
||||
+}
|
||||
+
|
||||
+/* Switch xMII control registers */
|
||||
+struct vr9_switch_mii_regs {
|
||||
+ __be32 mii_cfg0; /* xMII port 0 configuration */
|
||||
+ __be32 pcdu0; /* Port 0 clock delay configuration */
|
||||
+ __be32 mii_cfg1; /* xMII port 1 configuration */
|
||||
+ __be32 pcdu1; /* Port 1 clock delay configuration */
|
||||
+ __be32 rsvd0[0x6];
|
||||
+ __be32 mii_cfg5; /* xMII port 5 configuration */
|
||||
+ __be32 pcdu5; /* Port 5 clock delay configuration */
|
||||
+ __be32 rsvd1[0x14];
|
||||
+ __be32 rxb_ctl_0; /* Port 0 receive buffer control */
|
||||
+ __be32 rxb_ctl_1; /* Port 1 receive buffer control */
|
||||
+ __be32 rxb_ctl_5; /* Port 5 receive buffer control */
|
||||
+ __be32 rsvd2[0x28];
|
||||
+ __be32 dbg_ctl; /* Debug control */
|
||||
+};
|
||||
+
|
||||
+/* Switch Pseudo-MAC registers */
|
||||
+struct vr9_switch_pmac_regs {
|
||||
+ __be32 hd_ctl; /* PMAC header control */
|
||||
+ __be32 tl; /* PMAC type/length */
|
||||
+ __be32 sa1; /* PMAC source address 1 */
|
||||
+ __be32 sa2; /* PMAC source address 2 */
|
||||
+ __be32 sa3; /* PMAC source address 3 */
|
||||
+ __be32 da1; /* PMAC destination address 1 */
|
||||
+ __be32 da2; /* PMAC destination address 2 */
|
||||
+ __be32 da3; /* PMAC destination address 3 */
|
||||
+ __be32 vlan; /* PMAC VLAN */
|
||||
+ __be32 rx_ipg; /* PMAC interpacket gap in RX direction */
|
||||
+ __be32 st_etype; /* PMAC special tag ethertype */
|
||||
+ __be32 ewan; /* PMAC ethernet WAN group */
|
||||
+ __be32 ctl; /* PMAC control */
|
||||
+ __be32 rsvd0[0x2];
|
||||
+};
|
||||
+
|
||||
+struct vr9_switch_regs {
|
||||
+ struct vr9_switch_core_regs core;
|
||||
+ struct vr9_switch_bm_regs bm;
|
||||
+ struct vr9_switch_pce_regs pce;
|
||||
+ struct vr9_switch_mac_regs mac;
|
||||
+ struct vr9_switch_fdma_regs fdma;
|
||||
+ struct vr9_switch_sdma_regs sdma;
|
||||
+ struct vr9_switch_mdio_regs mdio;
|
||||
+ struct vr9_switch_mii_regs mii;
|
||||
+ struct vr9_switch_pmac_regs pmac;
|
||||
+};
|
||||
+
|
||||
+#define VR9_SWITCH_REG_OFFSET(reg) (4 * (reg))
|
||||
+
|
||||
+#define BUILD_CHECK_VR9_REG(name, offset) \
|
||||
+ BUILD_BUG_ON(offsetof(struct vr9_switch_regs, name) != (4 * offset))
|
||||
+
|
||||
+static inline void build_check_vr9_registers(void)
|
||||
+{
|
||||
+ BUILD_CHECK_VR9_REG(core, 0x0);
|
||||
+ BUILD_CHECK_VR9_REG(bm.core, 0x40);
|
||||
+ BUILD_CHECK_VR9_REG(bm.core.queue_gctrl, 0x4a);
|
||||
+ BUILD_CHECK_VR9_REG(bm.port[0], 0x80);
|
||||
+ BUILD_CHECK_VR9_REG(bm.queue, 0x100);
|
||||
+ BUILD_CHECK_VR9_REG(bm.shaper, 0x140);
|
||||
+ BUILD_CHECK_VR9_REG(pce.core, 0x438);
|
||||
+ BUILD_CHECK_VR9_REG(pce.core.tbl_ctrl, 0x44f);
|
||||
+ BUILD_CHECK_VR9_REG(pce.core.parser_stat, 0x469);
|
||||
+ BUILD_CHECK_VR9_REG(pce.port[0], 0x480);
|
||||
+ BUILD_CHECK_VR9_REG(pce.meter[0], 0x580);
|
||||
+ BUILD_CHECK_VR9_REG(mac.core, 0x8c0);
|
||||
+ BUILD_CHECK_VR9_REG(mac.port[0].pstat, 0x900);
|
||||
+ BUILD_CHECK_VR9_REG(mac.port[0].ctrl_0, 0x903);
|
||||
+ BUILD_CHECK_VR9_REG(mac.port[1].pstat, 0x90c);
|
||||
+ BUILD_CHECK_VR9_REG(mac.port[1].ctrl_0, 0x90f);
|
||||
+ BUILD_CHECK_VR9_REG(mac.port[2].pstat, 0x918);
|
||||
+ BUILD_CHECK_VR9_REG(mac.port[2].ctrl_0, 0x91b);
|
||||
+ BUILD_CHECK_VR9_REG(fdma.core, 0xa40);
|
||||
+ BUILD_CHECK_VR9_REG(fdma.port[0], 0xa80);
|
||||
+ BUILD_CHECK_VR9_REG(sdma.core, 0xb40);
|
||||
+ BUILD_CHECK_VR9_REG(sdma.port[0], 0xbc0);
|
||||
+ BUILD_CHECK_VR9_REG(mdio, 0xc40);
|
||||
+ BUILD_CHECK_VR9_REG(mii, (0xc40 + 0x36));
|
||||
+ BUILD_CHECK_VR9_REG(pmac, (0xc40 + 0x82));
|
||||
+}
|
||||
+
|
||||
+#define MAC_CTRL0_BM BIT(12)
|
||||
+#define MAC_CTRL0_APADEN BIT(11)
|
||||
+#define MAC_CTRL0_VPAD2EN BIT(10)
|
||||
+#define MAC_CTRL0_VPADEN BIT(9)
|
||||
+#define MAC_CTRL0_PADEN BIT(8)
|
||||
+#define MAC_CTRL0_FCS BIT(7)
|
||||
+#define MAC_CTRL0_FCON_SHIFT 4
|
||||
+#define MAC_CTRL0_FCON_AUTO (0x0 << MAC_CTRL0_FCON_SHIFT)
|
||||
+#define MAC_CTRL0_FCON_RX (0x1 << MAC_CTRL0_FCON_SHIFT)
|
||||
+#define MAC_CTRL0_FCON_TX (0x2 << MAC_CTRL0_FCON_SHIFT)
|
||||
+#define MAC_CTRL0_FCON_RXTX (0x3 << MAC_CTRL0_FCON_SHIFT)
|
||||
+#define MAC_CTRL0_FCON_NONE (0x4 << MAC_CTRL0_FCON_SHIFT)
|
||||
+#define MAC_CTRL0_FDUP_SHIFT 2
|
||||
+#define MAC_CTRL0_FDUP_AUTO (0x0 << MAC_CTRL0_FDUP_SHIFT)
|
||||
+#define MAC_CTRL0_FDUP_EN (0x1 << MAC_CTRL0_FDUP_SHIFT)
|
||||
+#define MAC_CTRL0_FDUP_DIS (0x3 << MAC_CTRL0_FDUP_SHIFT)
|
||||
+#define MAC_CTRL0_GMII_AUTO 0x0
|
||||
+#define MAC_CTRL0_GMII_MII 0x1
|
||||
+#define MAC_CTRL0_GMII_GMII 0x2
|
||||
+#define MAC_CTRL0_GMII_GMII_2G 0x3
|
||||
+
|
||||
+#define MAC_CTRL1_DEFERMODE BIT(15)
|
||||
+#define MAC_CTRL1_SHORTPRE BIT(8)
|
||||
+
|
||||
+#define MAC_CTRL2_MLEN BIT(3)
|
||||
+#define MAC_CTRL2_LCHKL BIT(2)
|
||||
+#define MAC_CTRL2_LCHKS_DIS 0x0
|
||||
+#define MAC_CTRL2_LCHKS_UNTAG 0x1
|
||||
+#define MAC_CTRL2_LCHKS_TAG 0x2
|
||||
+
|
||||
+#define PHY_ADDR_LNKST_SHIFT 13
|
||||
+#define PHY_ADDR_LNKST_AUTO (0x0 << PHY_ADDR_LNKST_SHIFT)
|
||||
+#define PHY_ADDR_LNKST_UP (0x1 << PHY_ADDR_LNKST_SHIFT)
|
||||
+#define PHY_ADDR_LNKST_DOWN (0x2 << PHY_ADDR_LNKST_SHIFT)
|
||||
+#define PHY_ADDR_SPEED_SHIFT 11
|
||||
+#define PHY_ADDR_SPEED_M10 (0x0 << PHY_ADDR_SPEED_SHIFT)
|
||||
+#define PHY_ADDR_SPEED_M100 (0x1 << PHY_ADDR_SPEED_SHIFT)
|
||||
+#define PHY_ADDR_SPEED_G1 (0x2 << PHY_ADDR_SPEED_SHIFT)
|
||||
+#define PHY_ADDR_SPEED_AUTO (0x3 << PHY_ADDR_SPEED_SHIFT)
|
||||
+#define PHY_ADDR_FDUP_SHIFT 9
|
||||
+#define PHY_ADDR_FDUP_AUTO (0x0 << PHY_ADDR_FDUP_SHIFT)
|
||||
+#define PHY_ADDR_FDUP_EN (0x1 << PHY_ADDR_FDUP_SHIFT)
|
||||
+#define PHY_ADDR_FDUP_DIS (0x3 << PHY_ADDR_FDUP_SHIFT)
|
||||
+#define PHY_ADDR_FCONTX_SHIFT 7
|
||||
+#define PHY_ADDR_FCONTX_AUTO (0x0 << PHY_ADDR_FCONTX_SHIFT)
|
||||
+#define PHY_ADDR_FCONTX_EN (0x1 << PHY_ADDR_FCONTX_SHIFT)
|
||||
+#define PHY_ADDR_FCONTX_DIS (0x3 << PHY_ADDR_FCONTX_SHIFT)
|
||||
+#define PHY_ADDR_FCONRX_SHIFT 5
|
||||
+#define PHY_ADDR_FCONRX_AUTO (0x0 << PHY_ADDR_FCONRX_SHIFT)
|
||||
+#define PHY_ADDR_FCONRX_EN (0x1 << PHY_ADDR_FCONRX_SHIFT)
|
||||
+#define PHY_ADDR_FCONRX_DIS (0x3 << PHY_ADDR_FCONRX_SHIFT)
|
||||
+
|
||||
+#define MII_CFG_RES BIT(15)
|
||||
+#define MII_CFG_EN BIT(14)
|
||||
+#define MII_CFG_LDCLKDIS BIT(12)
|
||||
+#define MII_CFG_MIIRATE_SHIFT 4
|
||||
+#define MII_CFG_MIIRATE_MASK (0x7 << MII_CFG_MIIRATE_SHIFT)
|
||||
+#define MII_CFG_MIIRATE_M2P5 (0x0 << MII_CFG_MIIRATE_SHIFT)
|
||||
+#define MII_CFG_MIIRATE_M25 (0x1 << MII_CFG_MIIRATE_SHIFT)
|
||||
+#define MII_CFG_MIIRATE_M125 (0x2 << MII_CFG_MIIRATE_SHIFT)
|
||||
+#define MII_CFG_MIIRATE_M50 (0x3 << MII_CFG_MIIRATE_SHIFT)
|
||||
+#define MII_CFG_MIIRATE_AUTO (0x4 << MII_CFG_MIIRATE_SHIFT)
|
||||
+#define MII_CFG_MIIMODE_MASK 0xf
|
||||
+#define MII_CFG_MIIMODE_MIIP 0x0
|
||||
+#define MII_CFG_MIIMODE_MIIM 0x1
|
||||
+#define MII_CFG_MIIMODE_RMIIP 0x2
|
||||
+#define MII_CFG_MIIMODE_RMIIM 0x3
|
||||
+#define MII_CFG_MIIMODE_RGMII 0x4
|
||||
+
|
||||
+#define PMAC_HD_CTL_FC BIT(10)
|
||||
+#define PMAC_HD_CTL_RST BIT(8)
|
||||
+#define PMAC_HD_CTL_AST BIT(7)
|
||||
+#define PMAC_HD_CTL_RXSH BIT(6)
|
||||
+#define PMAC_HD_CTL_RC BIT(4)
|
||||
+#define PMAC_HD_CTL_AS BIT(3)
|
||||
+#define PMAC_HD_CTL_AC BIT(2)
|
||||
+
|
||||
+#define PCE_PCTRL_0_IGSTEN BIT(11)
|
||||
+
|
||||
+#define FDMA_PCTRL_STEN BIT(1)
|
||||
+#define FDMA_PCTRL_EN BIT(0)
|
||||
+
|
||||
+#define SDMA_PCTRL_EN BIT(0)
|
||||
+
|
||||
+#define MDIO_CTRL_MBUSY BIT(12)
|
||||
+#define MDIO_CTRL_OP_READ BIT(11)
|
||||
+#define MDIO_CTRL_OP_WRITE BIT(10)
|
||||
+#define MDIO_CTRL_PHYAD_SHIFT 5
|
||||
+#define MDIO_CTRL_PHYAD_MASK (0x1f << MDIO_CTRL_PHYAD_SHIFT)
|
||||
+#define MDIO_CTRL_REGAD_MASK 0x1f
|
||||
+
|
||||
+#endif /* __VR9_SWITCH_REGS_H__ */
|
||||
diff --git a/arch/mips/lantiq/xway/xway_phy_fw.c b/arch/mips/lantiq/xway/xway_phy_fw.c
|
||||
new file mode 100644
|
||||
index 0000000..97a6d22
|
||||
--- /dev/null
|
||||
+++ b/arch/mips/lantiq/xway/xway_phy_fw.c
|
||||
@@ -0,0 +1,146 @@
|
||||
+#include <linux/kernel.h>
|
||||
+#include <linux/slab.h>
|
||||
+#include <linux/errno.h>
|
||||
+#include <linux/types.h>
|
||||
+#include <linux/interrupt.h>
|
||||
+#include <linux/uaccess.h>
|
||||
+#include <linux/in.h>
|
||||
+#include <linux/netdevice.h>
|
||||
+#include <linux/etherdevice.h>
|
||||
+#include <linux/phy.h>
|
||||
+#include <linux/ip.h>
|
||||
+#include <linux/tcp.h>
|
||||
+#include <linux/skbuff.h>
|
||||
+#include <linux/mm.h>
|
||||
+#include <linux/ethtool.h>
|
||||
+#include <linux/init.h>
|
||||
+#include <linux/delay.h>
|
||||
+#include <linux/io.h>
|
||||
+#include <linux/dma-mapping.h>
|
||||
+#include <linux/module.h>
|
||||
+#include <linux/firmware.h>
|
||||
+#include <linux/ihex.h>
|
||||
+#include <linux/of_platform.h>
|
||||
+#include <linux/of_net.h>
|
||||
+#include <linux/of_address.h>
|
||||
+#include <linux/of_irq.h>
|
||||
+#include <linux/of_gpio.h>
|
||||
+
|
||||
+#include <asm/checksum.h>
|
||||
+
|
||||
+#include <lantiq_soc.h>
|
||||
+
|
||||
+#include "vr9_switch_regs.h"
|
||||
+
|
||||
+#define XWAY_GPHY_FW_ALIGN (16 * 1024)
|
||||
+#define XWAY_GPHY_FW_NAME_SIZE 32
|
||||
+
|
||||
+struct xway_gphy_core {
|
||||
+ struct device *dev;
|
||||
+ char fw_name[XWAY_GPHY_FW_NAME_SIZE];
|
||||
+ dma_addr_t dev_addr;
|
||||
+ void *fw_addr;
|
||||
+ size_t fw_size;
|
||||
+};
|
||||
+
|
||||
+static int xway_gphy_load(struct platform_device *pdev, struct xway_gphy_core *gphy)
|
||||
+{
|
||||
+ const struct firmware *fw;
|
||||
+ dma_addr_t dev_addr;
|
||||
+ void *fw_addr;
|
||||
+ int err;
|
||||
+ size_t size;
|
||||
+ const char *fw_name;
|
||||
+
|
||||
+ err = of_property_read_string(pdev->dev.of_node, "firmware", &fw_name);
|
||||
+ if (err) {
|
||||
+ dev_err(&pdev->dev, "failed to load firmware filename\n");
|
||||
+ return err;
|
||||
+ }
|
||||
+
|
||||
+ if (strlen(fw_name) >= sizeof(gphy->fw_name)) {
|
||||
+ dev_err(&pdev->dev, "firmware filename too long\n");
|
||||
+ return ENAMETOOLONG;
|
||||
+ }
|
||||
+
|
||||
+ strncpy(gphy->fw_name, fw_name, sizeof(gphy->fw_name));
|
||||
+
|
||||
+ dev_info(&pdev->dev, "requesting %s\n", gphy->fw_name);
|
||||
+ err = request_firmware(&fw, gphy->fw_name, &pdev->dev);
|
||||
+ if (err) {
|
||||
+ dev_err(&pdev->dev, "failed to load firmware: %s\n", gphy->fw_name);
|
||||
+ return err;
|
||||
+ }
|
||||
+
|
||||
+ /*
|
||||
+ * GPHY cores need the firmware code in a persistent and contiguous
|
||||
+ * memory area with a 16 kB boundary aligned start address
|
||||
+ */
|
||||
+ size = fw->size + XWAY_GPHY_FW_ALIGN;
|
||||
+ fw_addr = dma_alloc_coherent(&pdev->dev, size, &dev_addr, GFP_KERNEL);
|
||||
+ if (!fw_addr) {
|
||||
+ dev_err(&pdev->dev, "failed to alloc firmware memory\n");
|
||||
+ goto err_release;
|
||||
+ }
|
||||
+
|
||||
+ fw_addr = PTR_ALIGN(fw_addr, XWAY_GPHY_FW_ALIGN);
|
||||
+ dev_addr = ALIGN(dev_addr, XWAY_GPHY_FW_ALIGN);
|
||||
+
|
||||
+ memcpy(fw_addr, fw->data, fw->size);
|
||||
+ release_firmware(fw);
|
||||
+
|
||||
+ gphy->dev = &pdev->dev;
|
||||
+ gphy->dev_addr = dev_addr;
|
||||
+ gphy->fw_addr = fw_addr;
|
||||
+ gphy->fw_size = size;
|
||||
+
|
||||
+ return 0;
|
||||
+
|
||||
+err_release:
|
||||
+ release_firmware(fw);
|
||||
+
|
||||
+ return err;
|
||||
+}
|
||||
+
|
||||
+static int __devinit xway_phy_fw_probe(struct platform_device *pdev)
|
||||
+{
|
||||
+ struct xway_gphy_core gphy;
|
||||
+ struct property *pp;
|
||||
+ unsigned char *phyids;
|
||||
+ int i, ret;
|
||||
+
|
||||
+ ret = xway_gphy_load(pdev, &gphy);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+ pp = of_find_property(pdev->dev.of_node, "phys", NULL);
|
||||
+ if (!pp)
|
||||
+ return -ENOENT;
|
||||
+ phyids = pp->value;
|
||||
+ for (i = 0; i < pp->length && !ret; i++)
|
||||
+ ret = xrx200_gphy_boot(&pdev->dev, phyids[i], gphy.dev_addr);
|
||||
+ if (!ret)
|
||||
+ mdelay(100);
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static const struct of_device_id xway_phy_match[] = {
|
||||
+ { .compatible = "lantiq,phy-xrx200" },
|
||||
+ {},
|
||||
+};
|
||||
+MODULE_DEVICE_TABLE(of, xway_phy_match);
|
||||
+
|
||||
+static struct platform_driver xway_phy_driver = {
|
||||
+ .probe = xway_phy_fw_probe,
|
||||
+ .driver = {
|
||||
+ .name = "phy-xrx200",
|
||||
+ .owner = THIS_MODULE,
|
||||
+ .of_match_table = xway_phy_match,
|
||||
+ },
|
||||
+};
|
||||
+
|
||||
+module_platform_driver(xway_phy_driver);
|
||||
+
|
||||
+MODULE_AUTHOR("John Crispin <blogic@openwrt.org>");
|
||||
+MODULE_DESCRIPTION("Lantiq XRX200 PHY Firmware Loader");
|
||||
+MODULE_LICENSE("GPL");
|
||||
+
|
||||
--
|
||||
1.7.10.4
|
||||
|
@ -0,0 +1,28 @@
|
||||
From 00b0721cce51988b6dda27b21afb0e09c620bc21 Mon Sep 17 00:00:00 2001
|
||||
From: John Crispin <blogic@openwrt.org>
|
||||
Date: Sat, 27 Oct 2012 09:14:17 +0200
|
||||
Subject: [PATCH 107/113] MIPS: lantiq: add xrx200 ethernet clock
|
||||
|
||||
Signed-off-by: John Crispin <blogic@openwrt.org>
|
||||
---
|
||||
arch/mips/lantiq/xway/sysctrl.c | 4 ++++
|
||||
1 file changed, 4 insertions(+)
|
||||
|
||||
diff --git a/arch/mips/lantiq/xway/sysctrl.c b/arch/mips/lantiq/xway/sysctrl.c
|
||||
index 2917b56..3925e66 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)
|
||||
clkdev_add_pmu("1d900000.pcie", "pdi", 1, PMU1_PCIE_PDI);
|
||||
clkdev_add_pmu("1d900000.pcie", "ctl", 1, PMU1_PCIE_CTL);
|
||||
clkdev_add_pmu("1d900000.pcie", "ahb", 0, PMU_AHBM | PMU_AHBS);
|
||||
+ clkdev_add_pmu("1e108000.eth", NULL, 0,
|
||||
+ PMU_SWITCH | PMU_PPE_DPLUS | PMU_PPE_DPLUM |
|
||||
+ PMU_PPE_EMA | PMU_PPE_TC | PMU_PPE_SLL01 |
|
||||
+ PMU_PPE_QSB | PMU_PPE_TOP);
|
||||
} else if (of_machine_is_compatible("lantiq,ar9")) {
|
||||
clkdev_add_static(ltq_ar9_cpu_hz(), ltq_ar9_fpi_hz(),
|
||||
ltq_ar9_fpi_hz());
|
||||
--
|
||||
1.7.10.4
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,47 @@
|
||||
From 5967e3171d56b7c433587aa418b87ae7fea02f28 Mon Sep 17 00:00:00 2001
|
||||
From: John Crispin <blogic@openwrt.org>
|
||||
Date: Mon, 22 Oct 2012 10:25:39 +0200
|
||||
Subject: [PATCH 109/113] MTD: lantiq: xway: fix NAND reset timeout handling
|
||||
|
||||
Fixes a possible deadlock in the code that resets the NAND flash.
|
||||
|
||||
http://lists.infradead.org/pipermail/linux-mtd/2012-September/044240.html
|
||||
|
||||
Signed-off-by: John Crispin <blogic@openwrt.org>
|
||||
---
|
||||
drivers/mtd/nand/xway_nand.c | 12 ++++++++++--
|
||||
1 file changed, 10 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/drivers/mtd/nand/xway_nand.c b/drivers/mtd/nand/xway_nand.c
|
||||
index 3f81dc8..4731300 100644
|
||||
--- a/drivers/mtd/nand/xway_nand.c
|
||||
+++ b/drivers/mtd/nand/xway_nand.c
|
||||
@@ -58,15 +58,23 @@ static void xway_reset_chip(struct nand_chip *chip)
|
||||
{
|
||||
unsigned long nandaddr = (unsigned long) chip->IO_ADDR_W;
|
||||
unsigned long flags;
|
||||
+ unsigned long timeout;
|
||||
|
||||
nandaddr &= ~NAND_WRITE_ADDR;
|
||||
nandaddr |= NAND_WRITE_CMD;
|
||||
|
||||
/* finish with a reset */
|
||||
+ timeout = jiffies + msecs_to_jiffies(200);
|
||||
+
|
||||
spin_lock_irqsave(&ebu_lock, flags);
|
||||
+
|
||||
writeb(NAND_WRITE_CMD_RESET, (void __iomem *) nandaddr);
|
||||
- while ((ltq_ebu_r32(EBU_NAND_WAIT) & NAND_WAIT_WR_C) == 0)
|
||||
- ;
|
||||
+ do {
|
||||
+ if ((ltq_ebu_r32(EBU_NAND_WAIT) & NAND_WAIT_WR_C) == 0)
|
||||
+ break;
|
||||
+ cond_resched();
|
||||
+ } while (!time_after_eq(jiffies, timeout));
|
||||
+
|
||||
spin_unlock_irqrestore(&ebu_lock, flags);
|
||||
}
|
||||
|
||||
--
|
||||
1.7.10.4
|
||||
|
@ -0,0 +1,228 @@
|
||||
From 2fa550e1ca132377ee4910eaaf331a257190b75e Mon Sep 17 00:00:00 2001
|
||||
From: John Crispin <blogic@openwrt.org>
|
||||
Date: Mon, 22 Oct 2012 09:28:30 +0200
|
||||
Subject: [PATCH 110/113] NET: PHY: adds driver for lantiq PHY11G
|
||||
|
||||
Signed-off-by: John Crispin <blogic@openwrt.org>
|
||||
---
|
||||
drivers/net/phy/Kconfig | 5 ++
|
||||
drivers/net/phy/Makefile | 1 +
|
||||
drivers/net/phy/lantiq.c | 178 ++++++++++++++++++++++++++++++++++++++++++++++
|
||||
3 files changed, 184 insertions(+)
|
||||
create mode 100644 drivers/net/phy/lantiq.c
|
||||
|
||||
diff --git a/drivers/net/phy/Kconfig b/drivers/net/phy/Kconfig
|
||||
index 983bbf4..a7ff1d2 100644
|
||||
--- a/drivers/net/phy/Kconfig
|
||||
+++ b/drivers/net/phy/Kconfig
|
||||
@@ -102,6 +102,11 @@ config MICREL_PHY
|
||||
---help---
|
||||
Supports the KSZ9021, VSC8201, KS8001 PHYs.
|
||||
|
||||
+config LANTIQ_PHY
|
||||
+ tristate "Driver for Lantiq PHYs"
|
||||
+ ---help---
|
||||
+ Supports the 11G and 22E PHYs.
|
||||
+
|
||||
config FIXED_PHY
|
||||
bool "Driver for MDIO Bus/PHY emulation with fixed speed/link PHYs"
|
||||
depends on PHYLIB=y
|
||||
diff --git a/drivers/net/phy/Makefile b/drivers/net/phy/Makefile
|
||||
index 426674d..3aa92bf 100644
|
||||
--- a/drivers/net/phy/Makefile
|
||||
+++ b/drivers/net/phy/Makefile
|
||||
@@ -23,6 +23,7 @@ obj-$(CONFIG_NATIONAL_PHY) += national.o
|
||||
obj-$(CONFIG_DP83640_PHY) += dp83640.o
|
||||
obj-$(CONFIG_STE10XP) += ste10Xp.o
|
||||
obj-$(CONFIG_MICREL_PHY) += micrel.o
|
||||
+obj-$(CONFIG_LANTIQ_PHY) += lantiq.o
|
||||
obj-$(CONFIG_MDIO_OCTEON) += mdio-octeon.o
|
||||
obj-$(CONFIG_MICREL_KS8995MA) += spi_ks8995.o
|
||||
obj-$(CONFIG_AMD_PHY) += amd.o
|
||||
diff --git a/drivers/net/phy/lantiq.c b/drivers/net/phy/lantiq.c
|
||||
new file mode 100644
|
||||
index 0000000..ba4d7b7
|
||||
--- /dev/null
|
||||
+++ b/drivers/net/phy/lantiq.c
|
||||
@@ -0,0 +1,178 @@
|
||||
+/*
|
||||
+ * This program is free software; you can redistribute it and/or modify
|
||||
+ * it under the terms of the GNU General Public License as published by
|
||||
+ * the Free Software Foundation; either version 2 of the License, or
|
||||
+ * (at your option) any later version.
|
||||
+ *
|
||||
+ * This program is distributed in the hope that it will be useful,
|
||||
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
+ * GNU General Public License for more details.
|
||||
+ *
|
||||
+ * You should have received a copy of the GNU General Public License
|
||||
+ * along with this program; if not, write to the Free Software
|
||||
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
|
||||
+ *
|
||||
+ * Copyright (C) 2012 Daniel Schwierzeck <daniel.schwierzeck@googlemail.com>
|
||||
+ */
|
||||
+
|
||||
+#include <linux/module.h>
|
||||
+#include <linux/phy.h>
|
||||
+
|
||||
+#define MII_MMDCTRL 0x0d
|
||||
+#define MII_MMDDATA 0x0e
|
||||
+
|
||||
+#define MII_VR9_11G_IMASK 0x19 /* interrupt mask */
|
||||
+#define MII_VR9_11G_ISTAT 0x1a /* interrupt status */
|
||||
+
|
||||
+#define INT_VR9_11G_WOL BIT(15) /* Wake-On-LAN */
|
||||
+#define INT_VR9_11G_ANE BIT(11) /* Auto-Neg error */
|
||||
+#define INT_VR9_11G_ANC BIT(10) /* Auto-Neg complete */
|
||||
+#define INT_VR9_11G_ADSC BIT(5) /* Link auto-downspeed detect */
|
||||
+#define INT_VR9_11G_DXMC BIT(2) /* Duplex mode change */
|
||||
+#define INT_VR9_11G_LSPC BIT(1) /* Link speed change */
|
||||
+#define INT_VR9_11G_LSTC BIT(0) /* Link state change */
|
||||
+#define INT_VR9_11G_MASK (INT_VR9_11G_LSTC | INT_VR9_11G_ADSC)
|
||||
+
|
||||
+#define ADVERTISED_MPD BIT(10) /* Multi-port device */
|
||||
+
|
||||
+#define MMD_DEVAD 0x1f
|
||||
+#define MMD_ACTYPE_SHIFT 14
|
||||
+#define MMD_ACTYPE_ADDRESS (0 << MMD_ACTYPE_SHIFT)
|
||||
+#define MMD_ACTYPE_DATA (1 << MMD_ACTYPE_SHIFT)
|
||||
+#define MMD_ACTYPE_DATA_PI (2 << MMD_ACTYPE_SHIFT)
|
||||
+#define MMD_ACTYPE_DATA_PIWR (3 << MMD_ACTYPE_SHIFT)
|
||||
+
|
||||
+static __maybe_unused int vr9_gphy_mmd_read(struct phy_device *phydev,
|
||||
+ u16 regnum)
|
||||
+{
|
||||
+ phy_write(phydev, MII_MMDCTRL, MMD_ACTYPE_ADDRESS | MMD_DEVAD);
|
||||
+ phy_write(phydev, MII_MMDDATA, regnum);
|
||||
+ phy_write(phydev, MII_MMDCTRL, MMD_ACTYPE_DATA | MMD_DEVAD);
|
||||
+
|
||||
+ return phy_read(phydev, MII_MMDDATA);
|
||||
+}
|
||||
+
|
||||
+static __maybe_unused int vr9_gphy_mmd_write(struct phy_device *phydev,
|
||||
+ u16 regnum, u16 val)
|
||||
+{
|
||||
+ phy_write(phydev, MII_MMDCTRL, MMD_ACTYPE_ADDRESS | MMD_DEVAD);
|
||||
+ phy_write(phydev, MII_MMDDATA, regnum);
|
||||
+ phy_write(phydev, MII_MMDCTRL, MMD_ACTYPE_DATA | MMD_DEVAD);
|
||||
+ phy_write(phydev, MII_MMDDATA, val);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int vr9_gphy_config_init(struct phy_device *phydev)
|
||||
+{
|
||||
+ int err;
|
||||
+
|
||||
+ dev_dbg(&phydev->dev, "%s\n", __func__);
|
||||
+
|
||||
+ /* Mask all interrupts */
|
||||
+ err = phy_write(phydev, MII_VR9_11G_IMASK, 0);
|
||||
+ if (err)
|
||||
+ return err;
|
||||
+
|
||||
+ /* Clear all pending interrupts */
|
||||
+ phy_read(phydev, MII_VR9_11G_ISTAT);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int vr9_gphy_config_aneg(struct phy_device *phydev)
|
||||
+{
|
||||
+ int reg, err;
|
||||
+
|
||||
+ /* Advertise as multi-port device */
|
||||
+ reg = phy_read(phydev, MII_CTRL1000);
|
||||
+ reg |= ADVERTISED_MPD;
|
||||
+ err = phy_write(phydev, MII_CTRL1000, reg);
|
||||
+ if (err)
|
||||
+ return err;
|
||||
+
|
||||
+ return genphy_config_aneg(phydev);
|
||||
+}
|
||||
+
|
||||
+static int vr9_gphy_ack_interrupt(struct phy_device *phydev)
|
||||
+{
|
||||
+ int reg;
|
||||
+
|
||||
+ /*
|
||||
+ * Possible IRQ numbers:
|
||||
+ * - IM3_IRL18 for GPHY0
|
||||
+ * - IM3_IRL17 for GPHY1
|
||||
+ *
|
||||
+ * Due to a silicon bug IRQ lines are not really independent from
|
||||
+ * each other. Sometimes the two lines are driven at the same time
|
||||
+ * if only one GPHY core raises the interrupt.
|
||||
+ */
|
||||
+
|
||||
+ reg = phy_read(phydev, MII_VR9_11G_ISTAT);
|
||||
+
|
||||
+ return (reg < 0) ? reg : 0;
|
||||
+}
|
||||
+
|
||||
+static int vr9_gphy_did_interrupt(struct phy_device *phydev)
|
||||
+{
|
||||
+ int reg;
|
||||
+
|
||||
+ reg = phy_read(phydev, MII_VR9_11G_ISTAT);
|
||||
+
|
||||
+ return reg > 0;
|
||||
+}
|
||||
+
|
||||
+static int vr9_gphy_config_intr(struct phy_device *phydev)
|
||||
+{
|
||||
+ int err;
|
||||
+
|
||||
+ if (phydev->interrupts == PHY_INTERRUPT_ENABLED)
|
||||
+ err = phy_write(phydev, MII_VR9_11G_IMASK, INT_VR9_11G_MASK);
|
||||
+ else
|
||||
+ err = phy_write(phydev, MII_VR9_11G_IMASK, 0);
|
||||
+
|
||||
+ return err;
|
||||
+}
|
||||
+
|
||||
+/* TODO: add vr9_gphy_22f_driver and drivers for external Lantiq PEF7071 PHYs */
|
||||
+static struct phy_driver vr9_gphy_11g_driver = {
|
||||
+ .phy_id = 0xd565a408,
|
||||
+ .phy_id_mask = 0xfffffff0,
|
||||
+ .name = "Lantiq XWAY VR9 GPHY 11G",
|
||||
+ .features = (PHY_GBIT_FEATURES | SUPPORTED_Pause),
|
||||
+ .flags = 0, /*PHY_HAS_INTERRUPT,*/
|
||||
+ .config_init = vr9_gphy_config_init,
|
||||
+ .config_aneg = vr9_gphy_config_aneg,
|
||||
+ .read_status = genphy_read_status,
|
||||
+ .ack_interrupt = vr9_gphy_ack_interrupt,
|
||||
+ .did_interrupt = vr9_gphy_did_interrupt,
|
||||
+ .config_intr = vr9_gphy_config_intr,
|
||||
+ .driver = { .owner = THIS_MODULE },
|
||||
+};
|
||||
+
|
||||
+static int __init ltq_phy_init(void)
|
||||
+{
|
||||
+ int err;
|
||||
+
|
||||
+ err = phy_driver_register(&vr9_gphy_11g_driver);
|
||||
+ if (err)
|
||||
+ goto err_out;
|
||||
+
|
||||
+ return 0;
|
||||
+
|
||||
+err_out:
|
||||
+ return err;
|
||||
+}
|
||||
+
|
||||
+static void __exit ltq_phy_exit(void)
|
||||
+{
|
||||
+ phy_driver_unregister(&vr9_gphy_11g_driver);
|
||||
+}
|
||||
+
|
||||
+module_init(ltq_phy_init);
|
||||
+module_exit(ltq_phy_exit);
|
||||
+
|
||||
+MODULE_DESCRIPTION("Lantiq PHY drivers");
|
||||
+MODULE_AUTHOR("Daniel Schwierzeck <daniel.schwierzeck@googlemail.com>");
|
||||
+MODULE_LICENSE("GPL");
|
||||
--
|
||||
1.7.10.4
|
||||
|
@ -0,0 +1,807 @@
|
||||
From 6db31b14d4998f480349dd5f1ef83dc68a1fab0c Mon Sep 17 00:00:00 2001
|
||||
From: John Crispin <blogic@openwrt.org>
|
||||
Date: Wed, 24 Oct 2012 19:50:30 +0200
|
||||
Subject: [PATCH 111/113] NET: MIPS: lantiq: update etop driver for devicetree
|
||||
|
||||
---
|
||||
drivers/net/ethernet/lantiq_etop.c | 470 +++++++++++++++++++++++++-----------
|
||||
1 file changed, 333 insertions(+), 137 deletions(-)
|
||||
|
||||
diff --git a/drivers/net/ethernet/lantiq_etop.c b/drivers/net/ethernet/lantiq_etop.c
|
||||
index 003c5bc..dc5457a 100644
|
||||
--- a/drivers/net/ethernet/lantiq_etop.c
|
||||
+++ b/drivers/net/ethernet/lantiq_etop.c
|
||||
@@ -12,7 +12,7 @@
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
|
||||
*
|
||||
- * Copyright (C) 2011 John Crispin <blogic@openwrt.org>
|
||||
+ * Copyright (C) 2011-12 John Crispin <blogic@openwrt.org>
|
||||
*/
|
||||
|
||||
#include <linux/kernel.h>
|
||||
@@ -36,6 +36,10 @@
|
||||
#include <linux/io.h>
|
||||
#include <linux/dma-mapping.h>
|
||||
#include <linux/module.h>
|
||||
+#include <linux/clk.h>
|
||||
+#include <linux/of_net.h>
|
||||
+#include <linux/of_irq.h>
|
||||
+#include <linux/of_platform.h>
|
||||
|
||||
#include <asm/checksum.h>
|
||||
|
||||
@@ -71,25 +75,56 @@
|
||||
#define ETOP_MII_REVERSE 0xe
|
||||
#define ETOP_PLEN_UNDER 0x40
|
||||
#define ETOP_CGEN 0x800
|
||||
-
|
||||
-/* use 2 static channels for TX/RX */
|
||||
-#define LTQ_ETOP_TX_CHANNEL 1
|
||||
-#define LTQ_ETOP_RX_CHANNEL 6
|
||||
-#define IS_TX(x) (x == LTQ_ETOP_TX_CHANNEL)
|
||||
-#define IS_RX(x) (x == LTQ_ETOP_RX_CHANNEL)
|
||||
-
|
||||
+#define ETOP_CFG_MII0 0x01
|
||||
+
|
||||
+#define LTQ_GBIT_MDIO_CTL 0xCC
|
||||
+#define LTQ_GBIT_MDIO_DATA 0xd0
|
||||
+#define LTQ_GBIT_GCTL0 0x68
|
||||
+#define LTQ_GBIT_PMAC_HD_CTL 0x8c
|
||||
+#define LTQ_GBIT_P0_CTL 0x4
|
||||
+#define LTQ_GBIT_PMAC_RX_IPG 0xa8
|
||||
+
|
||||
+#define PMAC_HD_CTL_AS (1 << 19)
|
||||
+#define PMAC_HD_CTL_RXSH (1 << 22)
|
||||
+
|
||||
+/* Switch Enable (0=disable, 1=enable) */
|
||||
+#define GCTL0_SE 0x80000000
|
||||
+/* Disable MDIO auto polling (0=disable, 1=enable) */
|
||||
+#define PX_CTL_DMDIO 0x00400000
|
||||
+
|
||||
+/* register information for the gbit's MDIO bus */
|
||||
+#define MDIO_XR9_REQUEST 0x00008000
|
||||
+#define MDIO_XR9_READ 0x00000800
|
||||
+#define MDIO_XR9_WRITE 0x00000400
|
||||
+#define MDIO_XR9_REG_MASK 0x1f
|
||||
+#define MDIO_XR9_ADDR_MASK 0x1f
|
||||
+#define MDIO_XR9_RD_MASK 0xffff
|
||||
+#define MDIO_XR9_REG_OFFSET 0
|
||||
+#define MDIO_XR9_ADDR_OFFSET 5
|
||||
+#define MDIO_XR9_WR_OFFSET 16
|
||||
+
|
||||
+#define LTQ_DMA_ETOP ((of_machine_is_compatible("lantiq,ase")) ? \
|
||||
+ (INT_NUM_IM3_IRL0) : (INT_NUM_IM2_IRL0))
|
||||
+
|
||||
+/* the newer xway socks have a embedded 3/7 port gbit multiplexer */
|
||||
#define ltq_etop_r32(x) ltq_r32(ltq_etop_membase + (x))
|
||||
#define ltq_etop_w32(x, y) ltq_w32(x, ltq_etop_membase + (y))
|
||||
#define ltq_etop_w32_mask(x, y, z) \
|
||||
ltq_w32_mask(x, y, ltq_etop_membase + (z))
|
||||
|
||||
-#define DRV_VERSION "1.0"
|
||||
+#define ltq_gbit_r32(x) ltq_r32(ltq_gbit_membase + (x))
|
||||
+#define ltq_gbit_w32(x, y) ltq_w32(x, ltq_gbit_membase + (y))
|
||||
+#define ltq_gbit_w32_mask(x, y, z) \
|
||||
+ ltq_w32_mask(x, y, ltq_gbit_membase + (z))
|
||||
+
|
||||
+#define DRV_VERSION "1.2"
|
||||
|
||||
static void __iomem *ltq_etop_membase;
|
||||
+static void __iomem *ltq_gbit_membase;
|
||||
|
||||
struct ltq_etop_chan {
|
||||
- int idx;
|
||||
int tx_free;
|
||||
+ int irq;
|
||||
struct net_device *netdev;
|
||||
struct napi_struct napi;
|
||||
struct ltq_dma_channel dma;
|
||||
@@ -99,22 +134,35 @@ struct ltq_etop_chan {
|
||||
struct ltq_etop_priv {
|
||||
struct net_device *netdev;
|
||||
struct platform_device *pdev;
|
||||
- struct ltq_eth_data *pldata;
|
||||
struct resource *res;
|
||||
|
||||
struct mii_bus *mii_bus;
|
||||
struct phy_device *phydev;
|
||||
|
||||
- struct ltq_etop_chan ch[MAX_DMA_CHAN];
|
||||
- int tx_free[MAX_DMA_CHAN >> 1];
|
||||
+ struct ltq_etop_chan txch;
|
||||
+ struct ltq_etop_chan rxch;
|
||||
+
|
||||
+ int tx_irq;
|
||||
+ int rx_irq;
|
||||
+
|
||||
+ const void *mac;
|
||||
+ int mii_mode;
|
||||
|
||||
spinlock_t lock;
|
||||
+
|
||||
+ struct clk *clk_ppe;
|
||||
+ struct clk *clk_switch;
|
||||
+ struct clk *clk_ephy;
|
||||
+ struct clk *clk_ephycgu;
|
||||
};
|
||||
|
||||
+static int ltq_etop_mdio_wr(struct mii_bus *bus, int phy_addr,
|
||||
+ int phy_reg, u16 phy_data);
|
||||
+
|
||||
static int
|
||||
ltq_etop_alloc_skb(struct ltq_etop_chan *ch)
|
||||
{
|
||||
- ch->skb[ch->dma.desc] = netdev_alloc_skb(ch->netdev, MAX_DMA_DATA_LEN);
|
||||
+ ch->skb[ch->dma.desc] = dev_alloc_skb(MAX_DMA_DATA_LEN);
|
||||
if (!ch->skb[ch->dma.desc])
|
||||
return -ENOMEM;
|
||||
ch->dma.desc_base[ch->dma.desc].addr = dma_map_single(NULL,
|
||||
@@ -149,8 +197,11 @@ ltq_etop_hw_receive(struct ltq_etop_chan *ch)
|
||||
spin_unlock_irqrestore(&priv->lock, flags);
|
||||
|
||||
skb_put(skb, len);
|
||||
+ skb->dev = ch->netdev;
|
||||
skb->protocol = eth_type_trans(skb, ch->netdev);
|
||||
netif_receive_skb(skb);
|
||||
+ ch->netdev->stats.rx_packets++;
|
||||
+ ch->netdev->stats.rx_bytes += len;
|
||||
}
|
||||
|
||||
static int
|
||||
@@ -158,8 +209,10 @@ ltq_etop_poll_rx(struct napi_struct *napi, int budget)
|
||||
{
|
||||
struct ltq_etop_chan *ch = container_of(napi,
|
||||
struct ltq_etop_chan, napi);
|
||||
+ struct ltq_etop_priv *priv = netdev_priv(ch->netdev);
|
||||
int rx = 0;
|
||||
int complete = 0;
|
||||
+ unsigned long flags;
|
||||
|
||||
while ((rx < budget) && !complete) {
|
||||
struct ltq_dma_desc *desc = &ch->dma.desc_base[ch->dma.desc];
|
||||
@@ -173,7 +226,9 @@ ltq_etop_poll_rx(struct napi_struct *napi, int budget)
|
||||
}
|
||||
if (complete || !rx) {
|
||||
napi_complete(&ch->napi);
|
||||
+ spin_lock_irqsave(&priv->lock, flags);
|
||||
ltq_dma_ack_irq(&ch->dma);
|
||||
+ spin_unlock_irqrestore(&priv->lock, flags);
|
||||
}
|
||||
return rx;
|
||||
}
|
||||
@@ -185,12 +240,14 @@ ltq_etop_poll_tx(struct napi_struct *napi, int budget)
|
||||
container_of(napi, struct ltq_etop_chan, napi);
|
||||
struct ltq_etop_priv *priv = netdev_priv(ch->netdev);
|
||||
struct netdev_queue *txq =
|
||||
- netdev_get_tx_queue(ch->netdev, ch->idx >> 1);
|
||||
+ netdev_get_tx_queue(ch->netdev, ch->dma.nr >> 1);
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&priv->lock, flags);
|
||||
while ((ch->dma.desc_base[ch->tx_free].ctl &
|
||||
(LTQ_DMA_OWN | LTQ_DMA_C)) == LTQ_DMA_C) {
|
||||
+ ch->netdev->stats.tx_packets++;
|
||||
+ ch->netdev->stats.tx_bytes += ch->skb[ch->tx_free]->len;
|
||||
dev_kfree_skb_any(ch->skb[ch->tx_free]);
|
||||
ch->skb[ch->tx_free] = NULL;
|
||||
memset(&ch->dma.desc_base[ch->tx_free], 0,
|
||||
@@ -203,7 +260,9 @@ ltq_etop_poll_tx(struct napi_struct *napi, int budget)
|
||||
if (netif_tx_queue_stopped(txq))
|
||||
netif_tx_start_queue(txq);
|
||||
napi_complete(&ch->napi);
|
||||
+ spin_lock_irqsave(&priv->lock, flags);
|
||||
ltq_dma_ack_irq(&ch->dma);
|
||||
+ spin_unlock_irqrestore(&priv->lock, flags);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -211,9 +270,10 @@ static irqreturn_t
|
||||
ltq_etop_dma_irq(int irq, void *_priv)
|
||||
{
|
||||
struct ltq_etop_priv *priv = _priv;
|
||||
- int ch = irq - LTQ_DMA_CH0_INT;
|
||||
-
|
||||
- napi_schedule(&priv->ch[ch].napi);
|
||||
+ if (irq == priv->txch.dma.irq)
|
||||
+ napi_schedule(&priv->txch.napi);
|
||||
+ else
|
||||
+ napi_schedule(&priv->rxch.napi);
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
@@ -225,7 +285,7 @@ ltq_etop_free_channel(struct net_device *dev, struct ltq_etop_chan *ch)
|
||||
ltq_dma_free(&ch->dma);
|
||||
if (ch->dma.irq)
|
||||
free_irq(ch->dma.irq, priv);
|
||||
- if (IS_RX(ch->idx)) {
|
||||
+ if (ch == &priv->txch) {
|
||||
int desc;
|
||||
for (desc = 0; desc < LTQ_DESC_NUM; desc++)
|
||||
dev_kfree_skb_any(ch->skb[ch->dma.desc]);
|
||||
@@ -236,23 +296,55 @@ static void
|
||||
ltq_etop_hw_exit(struct net_device *dev)
|
||||
{
|
||||
struct ltq_etop_priv *priv = netdev_priv(dev);
|
||||
- int i;
|
||||
|
||||
- ltq_pmu_disable(PMU_PPE);
|
||||
- for (i = 0; i < MAX_DMA_CHAN; i++)
|
||||
- if (IS_TX(i) || IS_RX(i))
|
||||
- ltq_etop_free_channel(dev, &priv->ch[i]);
|
||||
+ clk_disable(priv->clk_ppe);
|
||||
+
|
||||
+ if (of_machine_is_compatible("lantiq,ar9"))
|
||||
+ clk_disable(priv->clk_switch);
|
||||
+
|
||||
+ if (of_machine_is_compatible("lantiq,ase")) {
|
||||
+ clk_disable(priv->clk_ephy);
|
||||
+ clk_disable(priv->clk_ephycgu);
|
||||
+ }
|
||||
+
|
||||
+ ltq_etop_free_channel(dev, &priv->txch);
|
||||
+ ltq_etop_free_channel(dev, &priv->rxch);
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+ltq_etop_gbit_init(struct net_device *dev)
|
||||
+{
|
||||
+ struct ltq_etop_priv *priv = netdev_priv(dev);
|
||||
+
|
||||
+ clk_enable(priv->clk_switch);
|
||||
+
|
||||
+ ltq_gbit_w32_mask(0, GCTL0_SE, LTQ_GBIT_GCTL0);
|
||||
+ /** Disable MDIO auto polling mode */
|
||||
+ ltq_gbit_w32_mask(0, PX_CTL_DMDIO, LTQ_GBIT_P0_CTL);
|
||||
+ /* set 1522 packet size */
|
||||
+ ltq_gbit_w32_mask(0x300, 0, LTQ_GBIT_GCTL0);
|
||||
+ /* disable pmac & dmac headers */
|
||||
+ ltq_gbit_w32_mask(PMAC_HD_CTL_AS | PMAC_HD_CTL_RXSH, 0,
|
||||
+ LTQ_GBIT_PMAC_HD_CTL);
|
||||
+ /* Due to traffic halt when burst length 8,
|
||||
+ replace default IPG value with 0x3B */
|
||||
+ ltq_gbit_w32(0x3B, LTQ_GBIT_PMAC_RX_IPG);
|
||||
}
|
||||
|
||||
static int
|
||||
ltq_etop_hw_init(struct net_device *dev)
|
||||
{
|
||||
struct ltq_etop_priv *priv = netdev_priv(dev);
|
||||
- int i;
|
||||
|
||||
- ltq_pmu_enable(PMU_PPE);
|
||||
+ clk_enable(priv->clk_ppe);
|
||||
|
||||
- switch (priv->pldata->mii_mode) {
|
||||
+ if (of_machine_is_compatible("lantiq,ar9")) {
|
||||
+ ltq_etop_gbit_init(dev);
|
||||
+ /* force the etops link to the gbit to MII */
|
||||
+ priv->mii_mode = PHY_INTERFACE_MODE_MII;
|
||||
+ }
|
||||
+
|
||||
+ switch (priv->mii_mode) {
|
||||
case PHY_INTERFACE_MODE_RMII:
|
||||
ltq_etop_w32_mask(ETOP_MII_MASK,
|
||||
ETOP_MII_REVERSE, LTQ_ETOP_CFG);
|
||||
@@ -264,39 +356,68 @@ ltq_etop_hw_init(struct net_device *dev)
|
||||
break;
|
||||
|
||||
default:
|
||||
+ if (of_machine_is_compatible("lantiq,ase")) {
|
||||
+ clk_enable(priv->clk_ephy);
|
||||
+ /* disable external MII */
|
||||
+ ltq_etop_w32_mask(0, ETOP_CFG_MII0, LTQ_ETOP_CFG);
|
||||
+ /* enable clock for internal PHY */
|
||||
+ clk_enable(priv->clk_ephycgu);
|
||||
+ /* we need to write this magic to the internal phy to
|
||||
+ make it work */
|
||||
+ ltq_etop_mdio_wr(NULL, 0x8, 0x12, 0xC020);
|
||||
+ pr_info("Selected EPHY mode\n");
|
||||
+ break;
|
||||
+ }
|
||||
netdev_err(dev, "unknown mii mode %d\n",
|
||||
- priv->pldata->mii_mode);
|
||||
+ priv->mii_mode);
|
||||
return -ENOTSUPP;
|
||||
}
|
||||
|
||||
/* enable crc generation */
|
||||
ltq_etop_w32(PPE32_CGEN, LQ_PPE32_ENET_MAC_CFG);
|
||||
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
+ltq_etop_dma_init(struct net_device *dev)
|
||||
+{
|
||||
+ struct ltq_etop_priv *priv = netdev_priv(dev);
|
||||
+ int tx = priv->tx_irq - LTQ_DMA_ETOP;
|
||||
+ int rx = priv->rx_irq - LTQ_DMA_ETOP;
|
||||
+ int err;
|
||||
+
|
||||
ltq_dma_init_port(DMA_PORT_ETOP);
|
||||
|
||||
- for (i = 0; i < MAX_DMA_CHAN; i++) {
|
||||
- int irq = LTQ_DMA_CH0_INT + i;
|
||||
- struct ltq_etop_chan *ch = &priv->ch[i];
|
||||
-
|
||||
- ch->idx = ch->dma.nr = i;
|
||||
-
|
||||
- if (IS_TX(i)) {
|
||||
- ltq_dma_alloc_tx(&ch->dma);
|
||||
- request_irq(irq, ltq_etop_dma_irq, IRQF_DISABLED,
|
||||
- "etop_tx", priv);
|
||||
- } else if (IS_RX(i)) {
|
||||
- ltq_dma_alloc_rx(&ch->dma);
|
||||
- for (ch->dma.desc = 0; ch->dma.desc < LTQ_DESC_NUM;
|
||||
- ch->dma.desc++)
|
||||
- if (ltq_etop_alloc_skb(ch))
|
||||
- return -ENOMEM;
|
||||
- ch->dma.desc = 0;
|
||||
- request_irq(irq, ltq_etop_dma_irq, IRQF_DISABLED,
|
||||
- "etop_rx", priv);
|
||||
+ priv->txch.dma.nr = tx;
|
||||
+ ltq_dma_alloc_tx(&priv->txch.dma);
|
||||
+ err = request_irq(priv->tx_irq, ltq_etop_dma_irq, IRQF_DISABLED,
|
||||
+ "eth_tx", priv);
|
||||
+ if (err) {
|
||||
+ netdev_err(dev, "failed to allocate tx irq\n");
|
||||
+ goto err_out;
|
||||
+ }
|
||||
+ priv->txch.dma.irq = priv->tx_irq;
|
||||
+
|
||||
+ priv->rxch.dma.nr = rx;
|
||||
+ ltq_dma_alloc_rx(&priv->rxch.dma);
|
||||
+ for (priv->rxch.dma.desc = 0; priv->rxch.dma.desc < LTQ_DESC_NUM;
|
||||
+ priv->rxch.dma.desc++) {
|
||||
+ if (ltq_etop_alloc_skb(&priv->rxch)) {
|
||||
+ netdev_err(dev, "failed to allocate skbs\n");
|
||||
+ err = -ENOMEM;
|
||||
+ goto err_out;
|
||||
}
|
||||
- ch->dma.irq = irq;
|
||||
}
|
||||
- return 0;
|
||||
+ priv->rxch.dma.desc = 0;
|
||||
+ err = request_irq(priv->rx_irq, ltq_etop_dma_irq, IRQF_DISABLED,
|
||||
+ "eth_rx", priv);
|
||||
+ if (err)
|
||||
+ netdev_err(dev, "failed to allocate rx irq\n");
|
||||
+ else
|
||||
+ priv->rxch.dma.irq = priv->rx_irq;
|
||||
+err_out:
|
||||
+ return err;
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -312,7 +433,10 @@ ltq_etop_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
|
||||
{
|
||||
struct ltq_etop_priv *priv = netdev_priv(dev);
|
||||
|
||||
- return phy_ethtool_gset(priv->phydev, cmd);
|
||||
+ if (priv->phydev)
|
||||
+ return phy_ethtool_gset(priv->phydev, cmd);
|
||||
+ else
|
||||
+ return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
@@ -320,7 +444,10 @@ ltq_etop_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
|
||||
{
|
||||
struct ltq_etop_priv *priv = netdev_priv(dev);
|
||||
|
||||
- return phy_ethtool_sset(priv->phydev, cmd);
|
||||
+ if (priv->phydev)
|
||||
+ return phy_ethtool_sset(priv->phydev, cmd);
|
||||
+ else
|
||||
+ return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
@@ -328,7 +455,10 @@ ltq_etop_nway_reset(struct net_device *dev)
|
||||
{
|
||||
struct ltq_etop_priv *priv = netdev_priv(dev);
|
||||
|
||||
- return phy_start_aneg(priv->phydev);
|
||||
+ if (priv->phydev)
|
||||
+ return phy_start_aneg(priv->phydev);
|
||||
+ else
|
||||
+ return 0;
|
||||
}
|
||||
|
||||
static const struct ethtool_ops ltq_etop_ethtool_ops = {
|
||||
@@ -339,6 +469,39 @@ static const struct ethtool_ops ltq_etop_ethtool_ops = {
|
||||
};
|
||||
|
||||
static int
|
||||
+ltq_etop_mdio_wr_xr9(struct mii_bus *bus, int phy_addr,
|
||||
+ int phy_reg, u16 phy_data)
|
||||
+{
|
||||
+ u32 val = MDIO_XR9_REQUEST | MDIO_XR9_WRITE |
|
||||
+ (phy_data << MDIO_XR9_WR_OFFSET) |
|
||||
+ ((phy_addr & MDIO_XR9_ADDR_MASK) << MDIO_XR9_ADDR_OFFSET) |
|
||||
+ ((phy_reg & MDIO_XR9_REG_MASK) << MDIO_XR9_REG_OFFSET);
|
||||
+
|
||||
+ while (ltq_gbit_r32(LTQ_GBIT_MDIO_CTL) & MDIO_XR9_REQUEST)
|
||||
+ ;
|
||||
+ ltq_gbit_w32(val, LTQ_GBIT_MDIO_CTL);
|
||||
+ while (ltq_gbit_r32(LTQ_GBIT_MDIO_CTL) & MDIO_XR9_REQUEST)
|
||||
+ ;
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
+ltq_etop_mdio_rd_xr9(struct mii_bus *bus, int phy_addr, int phy_reg)
|
||||
+{
|
||||
+ u32 val = MDIO_XR9_REQUEST | MDIO_XR9_READ |
|
||||
+ ((phy_addr & MDIO_XR9_ADDR_MASK) << MDIO_XR9_ADDR_OFFSET) |
|
||||
+ ((phy_reg & MDIO_XR9_REG_MASK) << MDIO_XR9_REG_OFFSET);
|
||||
+
|
||||
+ while (ltq_gbit_r32(LTQ_GBIT_MDIO_CTL) & MDIO_XR9_REQUEST)
|
||||
+ ;
|
||||
+ ltq_gbit_w32(val, LTQ_GBIT_MDIO_CTL);
|
||||
+ while (ltq_gbit_r32(LTQ_GBIT_MDIO_CTL) & MDIO_XR9_REQUEST)
|
||||
+ ;
|
||||
+ val = ltq_gbit_r32(LTQ_GBIT_MDIO_DATA) & MDIO_XR9_RD_MASK;
|
||||
+ return val;
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
ltq_etop_mdio_wr(struct mii_bus *bus, int phy_addr, int phy_reg, u16 phy_data)
|
||||
{
|
||||
u32 val = MDIO_REQUEST |
|
||||
@@ -379,14 +542,11 @@ ltq_etop_mdio_probe(struct net_device *dev)
|
||||
{
|
||||
struct ltq_etop_priv *priv = netdev_priv(dev);
|
||||
struct phy_device *phydev = NULL;
|
||||
- int phy_addr;
|
||||
|
||||
- for (phy_addr = 0; phy_addr < PHY_MAX_ADDR; phy_addr++) {
|
||||
- if (priv->mii_bus->phy_map[phy_addr]) {
|
||||
- phydev = priv->mii_bus->phy_map[phy_addr];
|
||||
- break;
|
||||
- }
|
||||
- }
|
||||
+ if (of_machine_is_compatible("lantiq,ase"))
|
||||
+ phydev = priv->mii_bus->phy_map[8];
|
||||
+ else
|
||||
+ phydev = priv->mii_bus->phy_map[0];
|
||||
|
||||
if (!phydev) {
|
||||
netdev_err(dev, "no PHY found\n");
|
||||
@@ -394,7 +554,7 @@ ltq_etop_mdio_probe(struct net_device *dev)
|
||||
}
|
||||
|
||||
phydev = phy_connect(dev, dev_name(&phydev->dev), <q_etop_mdio_link,
|
||||
- 0, priv->pldata->mii_mode);
|
||||
+ 0, priv->mii_mode);
|
||||
|
||||
if (IS_ERR(phydev)) {
|
||||
netdev_err(dev, "Could not attach to PHY\n");
|
||||
@@ -408,6 +568,9 @@ ltq_etop_mdio_probe(struct net_device *dev)
|
||||
| SUPPORTED_Autoneg
|
||||
| SUPPORTED_MII
|
||||
| SUPPORTED_TP);
|
||||
+ if (of_machine_is_compatible("lantiq,ar9"))
|
||||
+ phydev->supported &= SUPPORTED_1000baseT_Half
|
||||
+ | SUPPORTED_1000baseT_Full;
|
||||
|
||||
phydev->advertising = phydev->supported;
|
||||
priv->phydev = phydev;
|
||||
@@ -433,8 +596,13 @@ ltq_etop_mdio_init(struct net_device *dev)
|
||||
}
|
||||
|
||||
priv->mii_bus->priv = dev;
|
||||
- priv->mii_bus->read = ltq_etop_mdio_rd;
|
||||
- priv->mii_bus->write = ltq_etop_mdio_wr;
|
||||
+ if (of_machine_is_compatible("lantiq,ar9")) {
|
||||
+ priv->mii_bus->read = ltq_etop_mdio_rd_xr9;
|
||||
+ priv->mii_bus->write = ltq_etop_mdio_wr_xr9;
|
||||
+ } else {
|
||||
+ priv->mii_bus->read = ltq_etop_mdio_rd;
|
||||
+ priv->mii_bus->write = ltq_etop_mdio_wr;
|
||||
+ }
|
||||
priv->mii_bus->name = "ltq_mii";
|
||||
snprintf(priv->mii_bus->id, MII_BUS_ID_SIZE, "%s-%x",
|
||||
priv->pdev->name, priv->pdev->id);
|
||||
@@ -483,17 +651,19 @@ static int
|
||||
ltq_etop_open(struct net_device *dev)
|
||||
{
|
||||
struct ltq_etop_priv *priv = netdev_priv(dev);
|
||||
- int i;
|
||||
+ unsigned long flags;
|
||||
|
||||
- for (i = 0; i < MAX_DMA_CHAN; i++) {
|
||||
- struct ltq_etop_chan *ch = &priv->ch[i];
|
||||
+ napi_enable(&priv->txch.napi);
|
||||
+ napi_enable(&priv->rxch.napi);
|
||||
+
|
||||
+ spin_lock_irqsave(&priv->lock, flags);
|
||||
+ ltq_dma_open(&priv->txch.dma);
|
||||
+ ltq_dma_open(&priv->rxch.dma);
|
||||
+ spin_unlock_irqrestore(&priv->lock, flags);
|
||||
+
|
||||
+ if (priv->phydev)
|
||||
+ phy_start(priv->phydev);
|
||||
|
||||
- if (!IS_TX(i) && (!IS_RX(i)))
|
||||
- continue;
|
||||
- ltq_dma_open(&ch->dma);
|
||||
- napi_enable(&ch->napi);
|
||||
- }
|
||||
- phy_start(priv->phydev);
|
||||
netif_tx_start_all_queues(dev);
|
||||
return 0;
|
||||
}
|
||||
@@ -502,18 +672,19 @@ static int
|
||||
ltq_etop_stop(struct net_device *dev)
|
||||
{
|
||||
struct ltq_etop_priv *priv = netdev_priv(dev);
|
||||
- int i;
|
||||
+ unsigned long flags;
|
||||
|
||||
netif_tx_stop_all_queues(dev);
|
||||
- phy_stop(priv->phydev);
|
||||
- for (i = 0; i < MAX_DMA_CHAN; i++) {
|
||||
- struct ltq_etop_chan *ch = &priv->ch[i];
|
||||
+ if (priv->phydev)
|
||||
+ phy_stop(priv->phydev);
|
||||
+ napi_disable(&priv->txch.napi);
|
||||
+ napi_disable(&priv->rxch.napi);
|
||||
+
|
||||
+ spin_lock_irqsave(&priv->lock, flags);
|
||||
+ ltq_dma_close(&priv->txch.dma);
|
||||
+ ltq_dma_close(&priv->rxch.dma);
|
||||
+ spin_unlock_irqrestore(&priv->lock, flags);
|
||||
|
||||
- if (!IS_RX(i) && !IS_TX(i))
|
||||
- continue;
|
||||
- napi_disable(&ch->napi);
|
||||
- ltq_dma_close(&ch->dma);
|
||||
- }
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -523,16 +694,16 @@ ltq_etop_tx(struct sk_buff *skb, struct net_device *dev)
|
||||
int queue = skb_get_queue_mapping(skb);
|
||||
struct netdev_queue *txq = netdev_get_tx_queue(dev, queue);
|
||||
struct ltq_etop_priv *priv = netdev_priv(dev);
|
||||
- struct ltq_etop_chan *ch = &priv->ch[(queue << 1) | 1];
|
||||
- struct ltq_dma_desc *desc = &ch->dma.desc_base[ch->dma.desc];
|
||||
- int len;
|
||||
+ struct ltq_dma_desc *desc =
|
||||
+ &priv->txch.dma.desc_base[priv->txch.dma.desc];
|
||||
unsigned long flags;
|
||||
u32 byte_offset;
|
||||
+ int len;
|
||||
|
||||
len = skb->len < ETH_ZLEN ? ETH_ZLEN : skb->len;
|
||||
|
||||
- if ((desc->ctl & (LTQ_DMA_OWN | LTQ_DMA_C)) || ch->skb[ch->dma.desc]) {
|
||||
- dev_kfree_skb_any(skb);
|
||||
+ if ((desc->ctl & (LTQ_DMA_OWN | LTQ_DMA_C)) ||
|
||||
+ priv->txch.skb[priv->txch.dma.desc]) {
|
||||
netdev_err(dev, "tx ring full\n");
|
||||
netif_tx_stop_queue(txq);
|
||||
return NETDEV_TX_BUSY;
|
||||
@@ -540,7 +711,7 @@ ltq_etop_tx(struct sk_buff *skb, struct net_device *dev)
|
||||
|
||||
/* dma needs to start on a 16 byte aligned address */
|
||||
byte_offset = CPHYSADDR(skb->data) % 16;
|
||||
- ch->skb[ch->dma.desc] = skb;
|
||||
+ priv->txch.skb[priv->txch.dma.desc] = skb;
|
||||
|
||||
dev->trans_start = jiffies;
|
||||
|
||||
@@ -550,11 +721,11 @@ ltq_etop_tx(struct sk_buff *skb, struct net_device *dev)
|
||||
wmb();
|
||||
desc->ctl = LTQ_DMA_OWN | LTQ_DMA_SOP | LTQ_DMA_EOP |
|
||||
LTQ_DMA_TX_OFFSET(byte_offset) | (len & LTQ_DMA_SIZE_MASK);
|
||||
- ch->dma.desc++;
|
||||
- ch->dma.desc %= LTQ_DESC_NUM;
|
||||
+ priv->txch.dma.desc++;
|
||||
+ priv->txch.dma.desc %= LTQ_DESC_NUM;
|
||||
spin_unlock_irqrestore(&priv->lock, flags);
|
||||
|
||||
- if (ch->dma.desc_base[ch->dma.desc].ctl & LTQ_DMA_OWN)
|
||||
+ if (priv->txch.dma.desc_base[priv->txch.dma.desc].ctl & LTQ_DMA_OWN)
|
||||
netif_tx_stop_queue(txq);
|
||||
|
||||
return NETDEV_TX_OK;
|
||||
@@ -633,34 +804,32 @@ ltq_etop_init(struct net_device *dev)
|
||||
struct ltq_etop_priv *priv = netdev_priv(dev);
|
||||
struct sockaddr mac;
|
||||
int err;
|
||||
- bool random_mac = false;
|
||||
|
||||
ether_setup(dev);
|
||||
dev->watchdog_timeo = 10 * HZ;
|
||||
err = ltq_etop_hw_init(dev);
|
||||
if (err)
|
||||
goto err_hw;
|
||||
+ err = ltq_etop_dma_init(dev);
|
||||
+ if (err)
|
||||
+ goto err_hw;
|
||||
+
|
||||
ltq_etop_change_mtu(dev, 1500);
|
||||
|
||||
- memcpy(&mac, &priv->pldata->mac, sizeof(struct sockaddr));
|
||||
+ memcpy(&mac.sa_data, priv->mac, ETH_ALEN);
|
||||
if (!is_valid_ether_addr(mac.sa_data)) {
|
||||
pr_warn("etop: invalid MAC, using random\n");
|
||||
- eth_random_addr(mac.sa_data);
|
||||
- random_mac = true;
|
||||
+ random_ether_addr(mac.sa_data);
|
||||
}
|
||||
|
||||
err = ltq_etop_set_mac_address(dev, &mac);
|
||||
if (err)
|
||||
goto err_netdev;
|
||||
-
|
||||
- /* Set addr_assign_type here, ltq_etop_set_mac_address would reset it. */
|
||||
- if (random_mac)
|
||||
- dev->addr_assign_type |= NET_ADDR_RANDOM;
|
||||
-
|
||||
ltq_etop_set_multicast_list(dev);
|
||||
- err = ltq_etop_mdio_init(dev);
|
||||
- if (err)
|
||||
- goto err_netdev;
|
||||
+ if (!ltq_etop_mdio_init(dev))
|
||||
+ dev->ethtool_ops = <q_etop_ethtool_ops;
|
||||
+ else
|
||||
+ pr_warn("etop: mdio probe failed\n");;
|
||||
return 0;
|
||||
|
||||
err_netdev:
|
||||
@@ -680,6 +849,9 @@ ltq_etop_tx_timeout(struct net_device *dev)
|
||||
err = ltq_etop_hw_init(dev);
|
||||
if (err)
|
||||
goto err_hw;
|
||||
+ err = ltq_etop_dma_init(dev);
|
||||
+ if (err)
|
||||
+ goto err_hw;
|
||||
dev->trans_start = jiffies;
|
||||
netif_wake_queue(dev);
|
||||
return;
|
||||
@@ -703,14 +875,19 @@ static const struct net_device_ops ltq_eth_netdev_ops = {
|
||||
.ndo_tx_timeout = ltq_etop_tx_timeout,
|
||||
};
|
||||
|
||||
-static int __init
|
||||
+static int __devinit
|
||||
ltq_etop_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct net_device *dev;
|
||||
struct ltq_etop_priv *priv;
|
||||
- struct resource *res;
|
||||
+ struct resource *res, *gbit_res, irqres[2];
|
||||
int err;
|
||||
- int i;
|
||||
+
|
||||
+ err = of_irq_to_resource_table(pdev->dev.of_node, irqres, 2);
|
||||
+ if (err != 2) {
|
||||
+ dev_err(&pdev->dev, "failed to get etop irqs\n");
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
if (!res) {
|
||||
@@ -736,30 +913,58 @@ ltq_etop_probe(struct platform_device *pdev)
|
||||
goto err_out;
|
||||
}
|
||||
|
||||
- dev = alloc_etherdev_mq(sizeof(struct ltq_etop_priv), 4);
|
||||
- if (!dev) {
|
||||
- err = -ENOMEM;
|
||||
- goto err_out;
|
||||
+ if (of_machine_is_compatible("lantiq,ar9")) {
|
||||
+ gbit_res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
|
||||
+ if (!gbit_res) {
|
||||
+ dev_err(&pdev->dev, "failed to get gbit resource\n");
|
||||
+ err = -ENOENT;
|
||||
+ goto err_out;
|
||||
+ }
|
||||
+ ltq_gbit_membase = devm_ioremap_nocache(&pdev->dev,
|
||||
+ gbit_res->start, resource_size(gbit_res));
|
||||
+ if (!ltq_gbit_membase) {
|
||||
+ dev_err(&pdev->dev, "failed to remap gigabit switch %d\n",
|
||||
+ pdev->id);
|
||||
+ err = -ENOMEM;
|
||||
+ goto err_out;
|
||||
+ }
|
||||
}
|
||||
+
|
||||
+ dev = alloc_etherdev_mq(sizeof(struct ltq_etop_priv), 4);
|
||||
strcpy(dev->name, "eth%d");
|
||||
dev->netdev_ops = <q_eth_netdev_ops;
|
||||
- dev->ethtool_ops = <q_etop_ethtool_ops;
|
||||
priv = netdev_priv(dev);
|
||||
priv->res = res;
|
||||
priv->pdev = pdev;
|
||||
- priv->pldata = dev_get_platdata(&pdev->dev);
|
||||
priv->netdev = dev;
|
||||
+ priv->tx_irq = irqres[0].start;
|
||||
+ priv->rx_irq = irqres[1].start;
|
||||
+ priv->mii_mode = of_get_phy_mode(pdev->dev.of_node);
|
||||
+ priv->mac = of_get_mac_address(pdev->dev.of_node);
|
||||
+
|
||||
+ priv->clk_ppe = clk_get(&pdev->dev, NULL);
|
||||
+ if (IS_ERR(priv->clk_ppe))
|
||||
+ return PTR_ERR(priv->clk_ppe);
|
||||
+ if (of_machine_is_compatible("lantiq,ar9")) {
|
||||
+ priv->clk_switch = clk_get(&pdev->dev, "switch");
|
||||
+ if (IS_ERR(priv->clk_switch))
|
||||
+ return PTR_ERR(priv->clk_switch);
|
||||
+ }
|
||||
+ if (of_machine_is_compatible("lantiq,ase")) {
|
||||
+ priv->clk_ephy = clk_get(&pdev->dev, "ephy");
|
||||
+ if (IS_ERR(priv->clk_ephy))
|
||||
+ return PTR_ERR(priv->clk_ephy);
|
||||
+ priv->clk_ephycgu = clk_get(&pdev->dev, "ephycgu");
|
||||
+ if (IS_ERR(priv->clk_ephycgu))
|
||||
+ return PTR_ERR(priv->clk_ephycgu);
|
||||
+ }
|
||||
+
|
||||
spin_lock_init(&priv->lock);
|
||||
|
||||
- for (i = 0; i < MAX_DMA_CHAN; i++) {
|
||||
- if (IS_TX(i))
|
||||
- netif_napi_add(dev, &priv->ch[i].napi,
|
||||
- ltq_etop_poll_tx, 8);
|
||||
- else if (IS_RX(i))
|
||||
- netif_napi_add(dev, &priv->ch[i].napi,
|
||||
- ltq_etop_poll_rx, 32);
|
||||
- priv->ch[i].netdev = dev;
|
||||
- }
|
||||
+ netif_napi_add(dev, &priv->txch.napi, ltq_etop_poll_tx, 8);
|
||||
+ netif_napi_add(dev, &priv->rxch.napi, ltq_etop_poll_rx, 32);
|
||||
+ priv->txch.netdev = dev;
|
||||
+ priv->rxch.netdev = dev;
|
||||
|
||||
err = register_netdev(dev);
|
||||
if (err)
|
||||
@@ -788,32 +993,23 @@ ltq_etop_remove(struct platform_device *pdev)
|
||||
return 0;
|
||||
}
|
||||
|
||||
+static const struct of_device_id ltq_etop_match[] = {
|
||||
+ { .compatible = "lantiq,etop-xway" },
|
||||
+ {},
|
||||
+};
|
||||
+MODULE_DEVICE_TABLE(of, ltq_etop_match);
|
||||
+
|
||||
static struct platform_driver ltq_mii_driver = {
|
||||
+ .probe = ltq_etop_probe,
|
||||
.remove = __devexit_p(ltq_etop_remove),
|
||||
.driver = {
|
||||
.name = "ltq_etop",
|
||||
.owner = THIS_MODULE,
|
||||
+ .of_match_table = ltq_etop_match,
|
||||
},
|
||||
};
|
||||
|
||||
-int __init
|
||||
-init_ltq_etop(void)
|
||||
-{
|
||||
- int ret = platform_driver_probe(<q_mii_driver, ltq_etop_probe);
|
||||
-
|
||||
- if (ret)
|
||||
- pr_err("ltq_etop: Error registering platform driver!");
|
||||
- return ret;
|
||||
-}
|
||||
-
|
||||
-static void __exit
|
||||
-exit_ltq_etop(void)
|
||||
-{
|
||||
- platform_driver_unregister(<q_mii_driver);
|
||||
-}
|
||||
-
|
||||
-module_init(init_ltq_etop);
|
||||
-module_exit(exit_ltq_etop);
|
||||
+module_platform_driver(ltq_mii_driver);
|
||||
|
||||
MODULE_AUTHOR("John Crispin <blogic@openwrt.org>");
|
||||
MODULE_DESCRIPTION("Lantiq SoC ETOP");
|
||||
--
|
||||
1.7.10.4
|
||||
|
File diff suppressed because it is too large
Load Diff
539
target/linux/lantiq/patches-3.6/0113-EASY80920-dts-file.patch
Normal file
539
target/linux/lantiq/patches-3.6/0113-EASY80920-dts-file.patch
Normal file
@ -0,0 +1,539 @@
|
||||
From b072ba5c8e730b6d6e828cbc7caf99f669667831 Mon Sep 17 00:00:00 2001
|
||||
From: John Crispin <blogic@openwrt.org>
|
||||
Date: Mon, 22 Oct 2012 12:22:10 +0200
|
||||
Subject: [PATCH 113/113] EASY80920 dts file
|
||||
|
||||
---
|
||||
arch/mips/lantiq/Kconfig | 4 +
|
||||
arch/mips/lantiq/dts/Makefile | 1 +
|
||||
arch/mips/lantiq/dts/easy80920.dts | 369 ++++++++++++++++++++++++++++++++++++
|
||||
arch/mips/lantiq/dts/vr9.dtsi | 116 ++++++++++++
|
||||
4 files changed, 490 insertions(+)
|
||||
create mode 100644 arch/mips/lantiq/dts/easy80920.dts
|
||||
create mode 100644 arch/mips/lantiq/dts/vr9.dtsi
|
||||
|
||||
diff --git a/arch/mips/lantiq/Kconfig b/arch/mips/lantiq/Kconfig
|
||||
index d84f361..c9d0984 100644
|
||||
--- a/arch/mips/lantiq/Kconfig
|
||||
+++ b/arch/mips/lantiq/Kconfig
|
||||
@@ -30,6 +30,10 @@ choice
|
||||
config DT_EASY50712
|
||||
bool "Easy50712"
|
||||
depends on SOC_XWAY
|
||||
+
|
||||
+config DT_EASY80920
|
||||
+ bool "Easy80920"
|
||||
+ depends on SOC_XWAY
|
||||
endchoice
|
||||
|
||||
config PCI_LANTIQ
|
||||
diff --git a/arch/mips/lantiq/dts/Makefile b/arch/mips/lantiq/dts/Makefile
|
||||
index 674fca4..0876c97 100644
|
||||
--- a/arch/mips/lantiq/dts/Makefile
|
||||
+++ b/arch/mips/lantiq/dts/Makefile
|
||||
@@ -1,4 +1,5 @@
|
||||
obj-$(CONFIG_DT_EASY50712) := easy50712.dtb.o
|
||||
+obj-$(CONFIG_DT_EASY80920) := easy80920.dtb.o
|
||||
|
||||
$(obj)/%.dtb: $(obj)/%.dts
|
||||
$(call if_changed,dtc)
|
||||
diff --git a/arch/mips/lantiq/dts/easy80920.dts b/arch/mips/lantiq/dts/easy80920.dts
|
||||
new file mode 100644
|
||||
index 0000000..703e768
|
||||
--- /dev/null
|
||||
+++ b/arch/mips/lantiq/dts/easy80920.dts
|
||||
@@ -0,0 +1,369 @@
|
||||
+/dts-v1/;
|
||||
+
|
||||
+
|
||||
+/include/ "vr9.dtsi"
|
||||
+
|
||||
+/ {
|
||||
+ chosen {
|
||||
+ bootargs = "console=ttyLTQ0,115200 init=/etc/preinit";
|
||||
+ };
|
||||
+
|
||||
+ memory@0 {
|
||||
+ reg = <0x0 0x4000000>;
|
||||
+ };
|
||||
+
|
||||
+ fpi@10000000 {
|
||||
+ #address-cells = <1>;
|
||||
+ #size-cells = <1>;
|
||||
+ compatible = "lantiq,fpi", "simple-bus";
|
||||
+ ranges = <0x0 0x10000000 0xEEFFFFF>;
|
||||
+ reg = <0x10000000 0xEF00000>;
|
||||
+
|
||||
+ localbus@0 {
|
||||
+ #address-cells = <2>;
|
||||
+ #size-cells = <1>;
|
||||
+ compatible = "lantiq,localbus", "simple-bus";
|
||||
+
|
||||
+ ranges = <0 0 0x0 0x3ffffff>;
|
||||
+ nor-boot@0 {
|
||||
+ compatible = "lantiq,nor";
|
||||
+ bank-width = <2>;
|
||||
+ reg = <0 0x0 0x2000000>;
|
||||
+ #address-cells = <1>;
|
||||
+ #size-cells = <1>;
|
||||
+
|
||||
+ partition@0 {
|
||||
+ label = "uboot";
|
||||
+ reg = <0x00000 0x10000>;
|
||||
+ };
|
||||
+
|
||||
+ partition@10000 {
|
||||
+ label = "uboot_env";
|
||||
+ reg = <0x10000 0x10000>;
|
||||
+ };
|
||||
+
|
||||
+ partition@20000 {
|
||||
+ label = "linux";
|
||||
+ reg = <0x20000 0x7e0000>;
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
+ /*ranges = <0 0 0x4000000 0x3ffffff>;
|
||||
+ nand-parts@0 {
|
||||
+ compatible = "gen_nand", "lantiq,nand-xway";
|
||||
+ lantiq,cs = <1>;
|
||||
+ bank-width = <2>;
|
||||
+ reg = <0 0x0 0x2000000>;
|
||||
+ #address-cells = <1>;
|
||||
+ #size-cells = <1>;
|
||||
+
|
||||
+ partition@0 {
|
||||
+ label = "uboot";
|
||||
+ reg = <0x00000 0x40000>;
|
||||
+ };
|
||||
+
|
||||
+ partition@10000 {
|
||||
+ label = "uboot_env";
|
||||
+ reg = <0x40000 0x40000>;
|
||||
+ };
|
||||
+
|
||||
+ partition@20000 {
|
||||
+ label = "linux";
|
||||
+ reg = <0x80000 0x3f80000>;
|
||||
+ };
|
||||
+ };*/
|
||||
+ };
|
||||
+
|
||||
+ sflash@E100800 {
|
||||
+ compatible = "lantiq,sflash";
|
||||
+ reg = <0xE100800 0x100>;
|
||||
+ #address-cells = <1>;
|
||||
+ #size-cells = <1>;
|
||||
+
|
||||
+ partition@0 {
|
||||
+ label = "uboot";
|
||||
+ reg = <0x00000 0x10000>;
|
||||
+ };
|
||||
+
|
||||
+ partition@10000 {
|
||||
+ label = "uboot_env";
|
||||
+ reg = <0x10000 0x10000>;
|
||||
+ };
|
||||
+
|
||||
+ partition@20000 {
|
||||
+ label = "linux";
|
||||
+ reg = <0x20000 0x1d0000>;
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
+ gpio: pinmux@E100B10 {
|
||||
+ compatible = "lantiq,pinctrl-xr9";
|
||||
+ pinctrl-names = "default";
|
||||
+ pinctrl-0 = <&state_default>;
|
||||
+
|
||||
+ interrupt-parent = <&icu0>;
|
||||
+ interrupts = <166 135 66 40 41 42 38>;
|
||||
+
|
||||
+ #gpio-cells = <2>;
|
||||
+ gpio-controller;
|
||||
+ reg = <0xE100B10 0xA0>;
|
||||
+
|
||||
+ state_default: pinmux {
|
||||
+ stp {
|
||||
+ lantiq,groups = "stp";
|
||||
+ lantiq,function = "stp";
|
||||
+ };
|
||||
+ /*spi {
|
||||
+ lantiq,groups = "spi", "spi_cs4";
|
||||
+ lantiq,function = "spi";
|
||||
+ };*/
|
||||
+ nand {
|
||||
+ lantiq,groups = "nand cle", "nand ale",
|
||||
+ "nand rd", "nand rdy";
|
||||
+ lantiq,function = "ebu";
|
||||
+ };
|
||||
+ mdio {
|
||||
+ lantiq,groups = "mdio";
|
||||
+ lantiq,function = "mdio";
|
||||
+ };
|
||||
+ pci {
|
||||
+ lantiq,groups = "gnt1", "req1";
|
||||
+ lantiq,function = "pci";
|
||||
+ };
|
||||
+ exin {
|
||||
+ lantiq,groups = "exin3";
|
||||
+ lantiq,function = "exin";
|
||||
+ };
|
||||
+ conf_out {
|
||||
+ lantiq,pins = "io24", "io13", "io49", /* nand cle, ale and rd */
|
||||
+ "io4", "io5", "io6", /* stp */
|
||||
+ "io17", "io18", /* spi dout & clk */
|
||||
+ "io21", /* pci-rst */
|
||||
+ "io38"; /* pcie-rst */
|
||||
+ lantiq,open-drain;
|
||||
+ lantiq,pull = <0>;
|
||||
+ };
|
||||
+ conf_in {
|
||||
+ lantiq,pins = "io39", /* exin3 */
|
||||
+ "io48"; /* nand rdy */
|
||||
+ lantiq,pull = <2>;
|
||||
+ };
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
+ eth@0xE108000 {
|
||||
+ #address-cells = <1>;
|
||||
+ #size-cells = <0>;
|
||||
+ compatible = "lantiq,xrx200-net";
|
||||
+ reg = < 0xE108000 0x3000 /* switch */
|
||||
+ 0xE10B100 0x70 /* mdio */
|
||||
+ 0xE10B1D8 0x30 /* mii */
|
||||
+ 0xE10B308 0x30 /* pmac */
|
||||
+ >;
|
||||
+ interrupt-parent = <&icu0>;
|
||||
+ interrupts = <73 72>;
|
||||
+
|
||||
+ lan: interface@0 {
|
||||
+ compatible = "lantiq,xrx200-pdi";
|
||||
+ #address-cells = <1>;
|
||||
+ #size-cells = <0>;
|
||||
+ reg = <0>;
|
||||
+ mac-address = [ 00 11 22 33 44 55 ];
|
||||
+
|
||||
+ ethernet@0 {
|
||||
+ compatible = "lantiq,xrx200-pdi-port";
|
||||
+ reg = <0>;
|
||||
+ phy-mode = "rgmii";
|
||||
+ phy-handle = <&phy0>;
|
||||
+ };
|
||||
+ ethernet@1 {
|
||||
+ compatible = "lantiq,xrx200-pdi-port";
|
||||
+ reg = <1>;
|
||||
+ phy-mode = "rgmii";
|
||||
+ phy-handle = <&phy1>;
|
||||
+ };
|
||||
+ ethernet@2 {
|
||||
+ compatible = "lantiq,xrx200-pdi-port";
|
||||
+ reg = <2>;
|
||||
+ phy-mode = "gmii";
|
||||
+ phy-handle = <&phy11>;
|
||||
+ };
|
||||
+ ethernet@4 {
|
||||
+ compatible = "lantiq,xrx200-pdi-port";
|
||||
+ reg = <4>;
|
||||
+ phynmode0 = "gmii";
|
||||
+ phy-handle = <&phy13>;
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
+ wan: interface@1 {
|
||||
+ compatible = "lantiq,xrx200-pdi";
|
||||
+ #address-cells = <1>;
|
||||
+ #size-cells = <0>;
|
||||
+ reg = <1>;
|
||||
+ mac-address = [ 00 11 22 33 44 56 ];
|
||||
+
|
||||
+ ethernet@5 {
|
||||
+ compatible = "lantiq,xrx200-pdi-port";
|
||||
+ reg = <5>;
|
||||
+ phy-mode = "rgmii";
|
||||
+ phy-handle = <&phy5>;
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
+ mdio@0 {
|
||||
+ #address-cells = <1>;
|
||||
+ #size-cells = <0>;
|
||||
+ compatible = "lantiq,xrx200-mdio";
|
||||
+ phy0: ethernet-phy@0 {
|
||||
+ reg = <0x0>;
|
||||
+ compatible = "lantiq,phy11g", "ethernet-phy-ieee802.3-c22";
|
||||
+ lantiq,c45-reg-init = <1 0 0 0>;
|
||||
+ };
|
||||
+ phy1: ethernet-phy@1 {
|
||||
+ reg = <0x1>;
|
||||
+ compatible = "lantiq,phy11g", "ethernet-phy-ieee802.3-c22";
|
||||
+ lantiq,c45-reg-init = <1 0 0 0>;
|
||||
+ };
|
||||
+ phy5: ethernet-phy@5 {
|
||||
+ reg = <0x5>;
|
||||
+ compatible = "lantiq,phy11g", "ethernet-phy-ieee802.3-c22";
|
||||
+ lantiq,c45-reg-init = <1 0 0 0>;
|
||||
+ };
|
||||
+ phy11: ethernet-phy@11 {
|
||||
+ reg = <0x11>;
|
||||
+ compatible = "lantiq,phy11g", "ethernet-phy-ieee802.3-c22";
|
||||
+ lantiq,c45-reg-init = <1 0 0 0>;
|
||||
+ };
|
||||
+ phy13: ethernet-phy@13 {
|
||||
+ reg = <0x13>;
|
||||
+ compatible = "lantiq,phy11g", "ethernet-phy-ieee802.3-c22";
|
||||
+ lantiq,c45-reg-init = <1 0 0 0>;
|
||||
+ };
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
+ stp: stp@E100BB0 {
|
||||
+ compatible = "lantiq,gpio-stp-xway";
|
||||
+ reg = <0xE100BB0 0x40>;
|
||||
+ #gpio-cells = <2>;
|
||||
+ gpio-controller;
|
||||
+
|
||||
+ lantiq,shadow = <0xffff>;
|
||||
+ lantiq,groups = <0x7>;
|
||||
+ lantiq,dsl = <0x3>;
|
||||
+ lantiq,phy1 = <0x7>;
|
||||
+ lantiq,phy2 = <0x7>;
|
||||
+ /* lantiq,rising; */
|
||||
+ };
|
||||
+
|
||||
+ pci@E105400 {
|
||||
+ #address-cells = <3>;
|
||||
+ #size-cells = <2>;
|
||||
+ #interrupt-cells = <1>;
|
||||
+ compatible = "lantiq,pci-xway";
|
||||
+ bus-range = <0x0 0x0>;
|
||||
+ ranges = <0x2000000 0 0x8000000 0x8000000 0 0x2000000 /* pci memory */
|
||||
+ 0x1000000 0 0x00000000 0xAE00000 0 0x200000>; /* io space */
|
||||
+ reg = <0x7000000 0x8000 /* config space */
|
||||
+ 0xE105400 0x400>; /* pci bridge */
|
||||
+ lantiq,bus-clock = <33333333>;
|
||||
+ /*lantiq,external-clock;*/
|
||||
+ lantiq,delay-hi = <0>; /* 0ns delay */
|
||||
+ lantiq,delay-lo = <0>; /* 0.0ns delay */
|
||||
+ interrupt-map-mask = <0xf800 0x0 0x0 0x7>;
|
||||
+ interrupt-map = <
|
||||
+ 0x7000 0 0 1 &icu0 29 1 // slot 14, irq 29
|
||||
+ >;
|
||||
+ gpios-reset = <&gpio 21 0>;
|
||||
+ req-mask = <0x1>; /* GNT1 */
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
+ ifxhcd {
|
||||
+ compatible = "lantiq,ifxhcd";
|
||||
+ interrupt-parent = <&icu0>;
|
||||
+ interrupts = <62 91>;
|
||||
+ };
|
||||
+
|
||||
+ gphy-xrx200 {
|
||||
+ compatible = "lantiq,phy-xrx200";
|
||||
+ firmware = "lantiq/vr9_phy11g_a2x.bin";
|
||||
+ phys = [ 00 01 ];
|
||||
+ };
|
||||
+
|
||||
+ gpio-keys-polled {
|
||||
+ compatible = "gpio-keys-polled";
|
||||
+ #address-cells = <1>;
|
||||
+ #size-cells = <0>;
|
||||
+ poll-interval = <100>;
|
||||
+ reset {
|
||||
+ label = "Reset";
|
||||
+ gpios = <&gpio 7 0>;
|
||||
+ linux,code = <0x100>;
|
||||
+ };
|
||||
+ paging {
|
||||
+ label = "paging";
|
||||
+ gpios = <&gpio 11 1>;
|
||||
+ linux,code = <0x100>;
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
+/* gpio-keys {
|
||||
+ compatible = "gpio-keys";
|
||||
+ wps {
|
||||
+ gpios = <&gpio 39 0>;
|
||||
+ linux,code = <0x100>;
|
||||
+ };
|
||||
+ };*/
|
||||
+
|
||||
+ gpio-leds {
|
||||
+ compatible = "gpio-leds";
|
||||
+
|
||||
+ led0 {
|
||||
+ label = "led0";
|
||||
+ gpios = <&stp 9 0>;
|
||||
+ default-state = "on";
|
||||
+ };
|
||||
+ warning {
|
||||
+ label = "warning";
|
||||
+ gpios = <&stp 22 0>;
|
||||
+ default-state = "on";
|
||||
+ };
|
||||
+ fxs1 {
|
||||
+ label = "fxs1";
|
||||
+ gpios = <&stp 21 0>;
|
||||
+ default-state = "on";
|
||||
+ };
|
||||
+ fxs2 {
|
||||
+ label = "fxs2";
|
||||
+ gpios = <&stp 20 0>;
|
||||
+ default-state = "on";
|
||||
+ };
|
||||
+ fxo {
|
||||
+ label = "fxo";
|
||||
+ gpios = <&stp 19 0>;
|
||||
+ default-state = "on";
|
||||
+ };
|
||||
+ usb1 {
|
||||
+ label = "usb1";
|
||||
+ gpios = <&stp 18 0>;
|
||||
+ default-state = "on";
|
||||
+ };
|
||||
+ usb2 {
|
||||
+ label = "usb2";
|
||||
+ gpios = <&stp 15 0>;
|
||||
+ default-state = "on";
|
||||
+ };
|
||||
+ sd {
|
||||
+ label = "sd";
|
||||
+ gpios = <&stp 14 0>;
|
||||
+ default-state = "on";
|
||||
+ };
|
||||
+ wps {
|
||||
+ label = "wps";
|
||||
+ gpios = <&stp 12 0>;
|
||||
+ default-state = "on";
|
||||
+ };
|
||||
+ };
|
||||
+};
|
||||
diff --git a/arch/mips/lantiq/dts/vr9.dtsi b/arch/mips/lantiq/dts/vr9.dtsi
|
||||
new file mode 100644
|
||||
index 0000000..d3adb58
|
||||
--- /dev/null
|
||||
+++ b/arch/mips/lantiq/dts/vr9.dtsi
|
||||
@@ -0,0 +1,116 @@
|
||||
+/ {
|
||||
+ #address-cells = <1>;
|
||||
+ #size-cells = <1>;
|
||||
+ compatible = "lantiq,xway", "lantiq,vr9";
|
||||
+
|
||||
+ cpus {
|
||||
+ cpu@0 {
|
||||
+ compatible = "mips,mips34Kc";
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
+ biu@1F800000 {
|
||||
+ #address-cells = <1>;
|
||||
+ #size-cells = <1>;
|
||||
+ compatible = "lantiq,biu", "simple-bus";
|
||||
+ reg = <0x1F800000 0x800000>;
|
||||
+ ranges = <0x0 0x1F800000 0x7FFFFF>;
|
||||
+
|
||||
+ icu0: icu@80200 {
|
||||
+ #interrupt-cells = <1>;
|
||||
+ interrupt-controller;
|
||||
+ compatible = "lantiq,icu";
|
||||
+ reg = <0x80200 0x28
|
||||
+ 0x80228 0x28
|
||||
+ 0x80250 0x28
|
||||
+ 0x80278 0x28
|
||||
+ 0x802a0 0x28>;
|
||||
+ };
|
||||
+
|
||||
+ watchdog@803F0 {
|
||||
+ compatible = "lantiq,wdt";
|
||||
+ reg = <0x803F0 0x10>;
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
+ sram@1F000000 {
|
||||
+ #address-cells = <1>;
|
||||
+ #size-cells = <1>;
|
||||
+ compatible = "lantiq,sram";
|
||||
+ reg = <0x1F000000 0x800000>;
|
||||
+ ranges = <0x0 0x1F000000 0x7FFFFF>;
|
||||
+
|
||||
+ eiu0: eiu@101000 {
|
||||
+ compatible = "lantiq,eiu";
|
||||
+ #interrupt-cells = <1>;
|
||||
+ interrupt-controller;
|
||||
+ interrupt-parent;
|
||||
+ reg = <0x101000 0x1000>;
|
||||
+ lantiq,count = <6>;
|
||||
+ };
|
||||
+
|
||||
+ pmu0: pmu@102000 {
|
||||
+ compatible = "lantiq,pmu-xway";
|
||||
+ reg = <0x102000 0x1000>;
|
||||
+ };
|
||||
+
|
||||
+ cgu0: cgu@103000 {
|
||||
+ compatible = "lantiq,cgu-xway";
|
||||
+ reg = <0x103000 0x1000>;
|
||||
+ #clock-cells = <1>;
|
||||
+ };
|
||||
+
|
||||
+ rcu0: rcu@203000 {
|
||||
+ compatible = "lantiq,rcu-xway";
|
||||
+ reg = <0x203000 0x1000>;
|
||||
+ /* irq for thermal sensor */
|
||||
+ interrupt-parent = <&icu0>;
|
||||
+ interrupts = <115>;
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
+ fpi@10000000 {
|
||||
+ #address-cells = <1>;
|
||||
+ #size-cells = <1>;
|
||||
+ compatible = "lantiq,fpi", "simple-bus";
|
||||
+ ranges = <0x0 0x10000000 0xEEFFFFF>;
|
||||
+ reg = <0x10000000 0xEF00000>;
|
||||
+
|
||||
+ gptu@E100A00 {
|
||||
+ compatible = "lantiq,gptu-xway";
|
||||
+ reg = <0xE100A00 0x100>;
|
||||
+ interrupt-parent = <&icu0>;
|
||||
+ interrupts = <126 127 128 129 130 131>;
|
||||
+ };
|
||||
+
|
||||
+ asc1: serial@E100C00 {
|
||||
+ compatible = "lantiq,asc";
|
||||
+ reg = <0xE100C00 0x400>;
|
||||
+ interrupt-parent = <&icu0>;
|
||||
+ interrupts = <112 113 114>;
|
||||
+ };
|
||||
+
|
||||
+ dma0: dma@E104100 {
|
||||
+ compatible = "lantiq,dma-xway";
|
||||
+ reg = <0xE104100 0x800>;
|
||||
+ };
|
||||
+
|
||||
+ ebu0: ebu@E105300 {
|
||||
+ compatible = "lantiq,ebu-xway";
|
||||
+ reg = <0xE105300 0x100>;
|
||||
+ };
|
||||
+
|
||||
+ pci0: pci@E105400 {
|
||||
+ #address-cells = <3>;
|
||||
+ #size-cells = <2>;
|
||||
+ #interrupt-cells = <1>;
|
||||
+ compatible = "lantiq,pci-xway";
|
||||
+ bus-range = <0x0 0x0>;
|
||||
+ ranges = <0x2000000 0 0x8000000 0x8000000 0 0x2000000 /* pci memory */
|
||||
+ 0x1000000 0 0x00000000 0xAE00000 0 0x200000>; /* io space */
|
||||
+ reg = <0x7000000 0x8000 /* config space */
|
||||
+ 0xE105400 0x400>; /* pci bridge */
|
||||
+ };
|
||||
+
|
||||
+ };
|
||||
+};
|
||||
--
|
||||
1.7.10.4
|
||||
|
Loading…
Reference in New Issue
Block a user