diff options
Diffstat (limited to 'target/linux/lantiq/patches-3.3/0002-xway-support.patch')
-rw-r--r-- | target/linux/lantiq/patches-3.3/0002-xway-support.patch | 1586 |
1 files changed, 1586 insertions, 0 deletions
diff --git a/target/linux/lantiq/patches-3.3/0002-xway-support.patch b/target/linux/lantiq/patches-3.3/0002-xway-support.patch new file mode 100644 index 0000000..b3b9599 --- /dev/null +++ b/target/linux/lantiq/patches-3.3/0002-xway-support.patch @@ -0,0 +1,1586 @@ +From cf678877a86e03302686d0364c982d573daa6e2c Mon Sep 17 00:00:00 2001 +From: John Crispin <blogic@openwrt.org> +Date: Fri, 3 Aug 2012 09:49:04 +0200 +Subject: [PATCH 02/25] xway support + +--- + .../mips/include/asm/mach-lantiq/xway/lantiq_irq.h | 31 +-- + .../mips/include/asm/mach-lantiq/xway/lantiq_soc.h | 96 +++++++-- + arch/mips/lantiq/xway/Kconfig | 21 ++ + arch/mips/lantiq/xway/Makefile | 5 +- + arch/mips/lantiq/xway/clk-ase.c | 48 ----- + arch/mips/lantiq/xway/clk-xway.c | 223 -------------------- + arch/mips/lantiq/xway/devices.c | 72 ++++--- + arch/mips/lantiq/xway/devices.h | 2 + + arch/mips/lantiq/xway/dma.c | 27 +-- + arch/mips/lantiq/xway/ebu.c | 52 ----- + arch/mips/lantiq/xway/gpio.c | 92 +++++++-- + arch/mips/lantiq/xway/gpio_ebu.c | 3 +- + arch/mips/lantiq/xway/gpio_stp.c | 49 +++-- + arch/mips/lantiq/xway/mach-easy50601.c | 15 +- + arch/mips/lantiq/xway/mach-easy50712.c | 17 +- + arch/mips/lantiq/xway/pmu.c | 69 ------ + arch/mips/lantiq/xway/prom-ase.c | 39 ---- + arch/mips/lantiq/xway/prom-xway.c | 54 ----- + arch/mips/lantiq/xway/reset.c | 92 ++++++--- + arch/mips/lantiq/xway/setup-ase.c | 19 -- + arch/mips/lantiq/xway/setup-xway.c | 20 -- + 21 files changed, 349 insertions(+), 697 deletions(-) + delete mode 100644 arch/mips/lantiq/xway/clk-ase.c + delete mode 100644 arch/mips/lantiq/xway/clk-xway.c + delete mode 100644 arch/mips/lantiq/xway/ebu.c + delete mode 100644 arch/mips/lantiq/xway/pmu.c + delete mode 100644 arch/mips/lantiq/xway/prom-ase.c + delete mode 100644 arch/mips/lantiq/xway/prom-xway.c + delete mode 100644 arch/mips/lantiq/xway/setup-ase.c + delete mode 100644 arch/mips/lantiq/xway/setup-xway.c + +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 b4465a8..4f69ff0 100644 +--- a/arch/mips/include/asm/mach-lantiq/xway/lantiq_irq.h ++++ b/arch/mips/include/asm/mach-lantiq/xway/lantiq_irq.h +@@ -9,6 +9,8 @@ + #ifndef _LANTIQ_XWAY_IRQ_H__ + #define _LANTIQ_XWAY_IRQ_H__ + ++#define IM_NUM 5 ++ + #define INT_NUM_IRQ0 8 + #define INT_NUM_IM0_IRL0 (INT_NUM_IRQ0 + 0) + #define INT_NUM_IM1_IRL0 (INT_NUM_IRQ0 + 32) +@@ -27,37 +29,26 @@ + + #define LTQ_SSC_TIR (INT_NUM_IM0_IRL0 + 15) + #define LTQ_SSC_RIR (INT_NUM_IM0_IRL0 + 14) ++#define LTQ_SSC_TIR_AR9 (INT_NUM_IM0_IRL0 + 14) ++#define LTQ_SSC_RIR_AR9 (INT_NUM_IM0_IRL0 + 15) + #define LTQ_SSC_EIR (INT_NUM_IM0_IRL0 + 16) ++#define LTQ_SSC_RIR_ASE (INT_NUM_IM0_IRL0 + 16) ++#define LTQ_SSC_TIR_ASE (INT_NUM_IM0_IRL0 + 17) ++#define LTQ_SSC_EIR_ASE (INT_NUM_IM0_IRL0 + 18) ++#define LTQ_SSC_FIR_ASE (INT_NUM_IM0_IRL0 + 19) + + #define LTQ_MEI_DYING_GASP_INT (INT_NUM_IM1_IRL0 + 21) + #define LTQ_MEI_INT (INT_NUM_IM1_IRL0 + 23) + + #define LTQ_TIMER6_INT (INT_NUM_IM1_IRL0 + 23) + #define LTQ_USB_INT (INT_NUM_IM1_IRL0 + 22) ++#define LTQ_USB_ASE_INT (INT_NUM_IM0_IRL0 + 31) + #define LTQ_USB_OC_INT (INT_NUM_IM4_IRL0 + 23) + + #define MIPS_CPU_TIMER_IRQ 7 + +-#define LTQ_DMA_CH0_INT (INT_NUM_IM2_IRL0) +-#define LTQ_DMA_CH1_INT (INT_NUM_IM2_IRL0 + 1) +-#define LTQ_DMA_CH2_INT (INT_NUM_IM2_IRL0 + 2) +-#define LTQ_DMA_CH3_INT (INT_NUM_IM2_IRL0 + 3) +-#define LTQ_DMA_CH4_INT (INT_NUM_IM2_IRL0 + 4) +-#define LTQ_DMA_CH5_INT (INT_NUM_IM2_IRL0 + 5) +-#define LTQ_DMA_CH6_INT (INT_NUM_IM2_IRL0 + 6) +-#define LTQ_DMA_CH7_INT (INT_NUM_IM2_IRL0 + 7) +-#define LTQ_DMA_CH8_INT (INT_NUM_IM2_IRL0 + 8) +-#define LTQ_DMA_CH9_INT (INT_NUM_IM2_IRL0 + 9) +-#define LTQ_DMA_CH10_INT (INT_NUM_IM2_IRL0 + 10) +-#define LTQ_DMA_CH11_INT (INT_NUM_IM2_IRL0 + 11) +-#define LTQ_DMA_CH12_INT (INT_NUM_IM2_IRL0 + 25) +-#define LTQ_DMA_CH13_INT (INT_NUM_IM2_IRL0 + 26) +-#define LTQ_DMA_CH14_INT (INT_NUM_IM2_IRL0 + 27) +-#define LTQ_DMA_CH15_INT (INT_NUM_IM2_IRL0 + 28) +-#define LTQ_DMA_CH16_INT (INT_NUM_IM2_IRL0 + 29) +-#define LTQ_DMA_CH17_INT (INT_NUM_IM2_IRL0 + 30) +-#define LTQ_DMA_CH18_INT (INT_NUM_IM2_IRL0 + 16) +-#define LTQ_DMA_CH19_INT (INT_NUM_IM2_IRL0 + 21) ++#define LTQ_DMA_ETOP ((ltq_is_ase()) ? \ ++ (INT_NUM_IM3_IRL0) : (INT_NUM_IM2_IRL0)) + + #define LTQ_PPE_MBOX_INT (INT_NUM_IM2_IRL0 + 24) + +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 8a3c6be..1ec8f2a 100644 +--- a/arch/mips/include/asm/mach-lantiq/xway/lantiq_soc.h ++++ b/arch/mips/include/asm/mach-lantiq/xway/lantiq_soc.h +@@ -17,23 +17,44 @@ + #define SOC_ID_DANUBE1 0x129 + #define SOC_ID_DANUBE2 0x12B + #define SOC_ID_TWINPASS 0x12D +-#define SOC_ID_AMAZON_SE 0x152 ++#define SOC_ID_AMAZON_SE_1 0x152 /* 50601 */ ++#define SOC_ID_AMAZON_SE_2 0x153 /* 50600 */ + #define SOC_ID_ARX188 0x16C +-#define SOC_ID_ARX168 0x16D ++#define SOC_ID_ARX168_1 0x16D ++#define SOC_ID_ARX168_2 0x16E + #define SOC_ID_ARX182 0x16F ++#define SOC_ID_GRX188 0x170 ++#define SOC_ID_GRX168 0x171 ++ ++#define SOC_ID_VRX288 0x1C0 /* v1.1 */ ++#define SOC_ID_VRX282 0x1C1 /* v1.1 */ ++#define SOC_ID_VRX268 0x1C2 /* v1.1 */ ++#define SOC_ID_GRX268 0x1C8 /* v1.1 */ ++#define SOC_ID_GRX288 0x1C9 /* v1.1 */ ++#define SOC_ID_VRX288_2 0x00B /* v1.2 */ ++#define SOC_ID_VRX268_2 0x00C /* v1.2 */ ++#define SOC_ID_GRX288_2 0x00D /* v1.2 */ ++#define SOC_ID_GRX282_2 0x00E /* v1.2 */ + + /* SoC Types */ + #define SOC_TYPE_DANUBE 0x01 + #define SOC_TYPE_TWINPASS 0x02 + #define SOC_TYPE_AR9 0x03 +-#define SOC_TYPE_VR9 0x04 +-#define SOC_TYPE_AMAZON_SE 0x05 ++#define SOC_TYPE_VR9_1 0x04 /* v1.1 */ ++#define SOC_TYPE_VR9_2 0x05 /* v1.2 */ ++#define SOC_TYPE_AMAZON_SE 0x06 + + /* ASC0/1 - serial port */ + #define LTQ_ASC0_BASE_ADDR 0x1E100400 + #define LTQ_ASC1_BASE_ADDR 0x1E100C00 + #define LTQ_ASC_SIZE 0x400 + ++/* ++ * during early_printk no ioremap is possible ++ * lets use KSEG1 instead ++ */ ++#define LTQ_EARLY_ASC KSEG1ADDR(LTQ_ASC1_BASE_ADDR) ++ + /* RCU - reset control unit */ + #define LTQ_RCU_BASE_ADDR 0x1F203000 + #define LTQ_RCU_SIZE 0x1000 +@@ -61,6 +82,8 @@ + #define LTQ_CGU_BASE_ADDR 0x1F103000 + #define LTQ_CGU_SIZE 0x1000 + ++#define CGU_EPHY 0x10 ++ + /* ICU - interrupt control unit */ + #define LTQ_ICU_BASE_ADDR 0x1F880200 + #define LTQ_ICU_SIZE 0x100 +@@ -73,18 +96,14 @@ + #define LTQ_PMU_BASE_ADDR 0x1F102000 + #define LTQ_PMU_SIZE 0x1000 + +-#define PMU_DMA 0x0020 +-#define PMU_USB 0x8041 +-#define PMU_LED 0x0800 +-#define PMU_GPT 0x1000 +-#define PMU_PPE 0x2000 +-#define PMU_FPI 0x4000 +-#define PMU_SWITCH 0x10000000 +- + /* ETOP - ethernet */ + #define LTQ_ETOP_BASE_ADDR 0x1E180000 + #define LTQ_ETOP_SIZE 0x40000 + ++/* GBIT - gigabit switch */ ++#define LTQ_GBIT_BASE_ADDR 0x1E108000 ++#define LTQ_GBIT_SIZE 0x4000 ++ + /* DMA */ + #define LTQ_DMA_BASE_ADDR 0x1E104100 + #define LTQ_DMA_SIZE 0x800 +@@ -97,6 +116,8 @@ + #define LTQ_WDT_BASE_ADDR 0x1F8803F0 + #define LTQ_WDT_SIZE 0x10 + ++#define LTQ_RST_CAUSE_WDTRST 0x20 ++ + /* STP - serial to parallel conversion unit */ + #define LTQ_STP_BASE_ADDR 0x1E100BB0 + #define LTQ_STP_SIZE 0x40 +@@ -105,7 +126,9 @@ + #define LTQ_GPIO0_BASE_ADDR 0x1E100B10 + #define LTQ_GPIO1_BASE_ADDR 0x1E100B40 + #define LTQ_GPIO2_BASE_ADDR 0x1E100B70 ++#define LTQ_GPIO3_BASE_ADDR 0x1E100BA0 + #define LTQ_GPIO_SIZE 0x30 ++#define LTQ_GPIO3_SIZE 0x10 + + /* SSC */ + #define LTQ_SSC_BASE_ADDR 0x1e100800 +@@ -121,20 +144,57 @@ + #define LTQ_MPS_BASE_ADDR (KSEG1 + 0x1F107000) + #define LTQ_MPS_CHIPID ((u32 *)(LTQ_MPS_BASE_ADDR + 0x0344)) + +-/* request a non-gpio and set the PIO config */ +-extern int ltq_gpio_request(unsigned int pin, unsigned int alt0, +- unsigned int alt1, unsigned int dir, const char *name); +-extern void ltq_pmu_enable(unsigned int module); +-extern void ltq_pmu_disable(unsigned int module); ++/* BOOT_SEL - find what boot media we have */ ++#define BS_EXT_ROM 0x0 ++#define BS_FLASH 0x1 ++#define BS_MII0 0x2 ++#define BS_PCI 0x3 ++#define BS_UART1 0x4 ++#define BS_SPI 0x5 ++#define BS_NAND 0x6 ++#define BS_RMII0 0x7 ++ ++extern unsigned char ltq_boot_select(void); ++ ++/* register access macros for EBU and CGU */ ++#define ltq_ebu_w32(x, y) ltq_w32((x), ltq_ebu_membase + (y)) ++#define ltq_ebu_r32(x) ltq_r32(ltq_ebu_membase + (x)) ++#define ltq_ebu_w32_mask(x, y, z) \ ++ ltq_w32_mask(x, y, ltq_ebu_membase + (z)) ++#define ltq_cgu_w32(x, y) ltq_w32((x), ltq_cgu_membase + (y)) ++#define ltq_cgu_r32(x) ltq_r32(ltq_cgu_membase + (x)) ++ ++extern __iomem void *ltq_ebu_membase; ++extern __iomem void *ltq_cgu_membase; ++ ++static inline int ltq_is_ase(void) ++{ ++ return (ltq_get_soc_type() == SOC_TYPE_AMAZON_SE); ++} + + static inline int ltq_is_ar9(void) + { + return (ltq_get_soc_type() == SOC_TYPE_AR9); + } + ++static inline int ltq_is_vr9_1(void) ++{ ++ return (ltq_get_soc_type() == SOC_TYPE_VR9_1); ++} ++ ++static inline int ltq_is_vr9_2(void) ++{ ++ return (ltq_get_soc_type() == SOC_TYPE_VR9_2); ++} ++ + static inline int ltq_is_vr9(void) + { +- return (ltq_get_soc_type() == SOC_TYPE_VR9); ++ return (ltq_is_vr9_1() || ltq_is_vr9_2()); ++} ++ ++static inline int ltq_is_falcon(void) ++{ ++ return 0; + } + + #endif /* CONFIG_SOC_TYPE_XWAY */ +diff --git a/arch/mips/lantiq/xway/Kconfig b/arch/mips/lantiq/xway/Kconfig +index 2b857de..54a51ff 100644 +--- a/arch/mips/lantiq/xway/Kconfig ++++ b/arch/mips/lantiq/xway/Kconfig +@@ -8,6 +8,27 @@ config LANTIQ_MACH_EASY50712 + + endmenu + ++choice ++ prompt "PCI" ++ default PCI_LANTIQ_NONE ++ ++config PCI_LANTIQ_NONE ++ bool "None" ++ ++config PCI_LANTIQ ++ bool "PCI Support" ++ depends on PCI ++ ++config PCIE_LANTIQ ++ bool "PCIE Support" ++ select ARCH_SUPPORTS_MSI ++ ++endchoice ++ ++config PCIE_LANTIQ_MSI ++ bool ++ depends on PCIE_LANTIQ && PCI_MSI ++ default y + endif + + if SOC_AMAZON_SE +diff --git a/arch/mips/lantiq/xway/Makefile b/arch/mips/lantiq/xway/Makefile +index c517f2e..c9baf91 100644 +--- a/arch/mips/lantiq/xway/Makefile ++++ b/arch/mips/lantiq/xway/Makefile +@@ -1,7 +1,4 @@ +-obj-y := pmu.o ebu.o reset.o gpio.o gpio_stp.o gpio_ebu.o devices.o dma.o +- +-obj-$(CONFIG_SOC_XWAY) += clk-xway.o prom-xway.o setup-xway.o +-obj-$(CONFIG_SOC_AMAZON_SE) += clk-ase.o prom-ase.o setup-ase.o ++obj-y := sysctrl.o reset.o gpio.o gpio_stp.o gpio_ebu.o devices.o dma.o clk.o prom.o nand.o timer.o dev-ifxhcd.o + + obj-$(CONFIG_LANTIQ_MACH_EASY50712) += mach-easy50712.o + obj-$(CONFIG_LANTIQ_MACH_EASY50601) += mach-easy50601.o +diff --git a/arch/mips/lantiq/xway/clk-ase.c b/arch/mips/lantiq/xway/clk-ase.c +deleted file mode 100644 +index 6522583..0000000 +--- a/arch/mips/lantiq/xway/clk-ase.c ++++ /dev/null +@@ -1,48 +0,0 @@ +-/* +- * 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) 2011 John Crispin <blogic@openwrt.org> +- */ +- +-#include <linux/io.h> +-#include <linux/export.h> +-#include <linux/init.h> +-#include <linux/clk.h> +- +-#include <asm/time.h> +-#include <asm/irq.h> +-#include <asm/div64.h> +- +-#include <lantiq_soc.h> +- +-/* cgu registers */ +-#define LTQ_CGU_SYS 0x0010 +- +-unsigned int ltq_get_io_region_clock(void) +-{ +- return CLOCK_133M; +-} +-EXPORT_SYMBOL(ltq_get_io_region_clock); +- +-unsigned int ltq_get_fpi_bus_clock(int fpi) +-{ +- return CLOCK_133M; +-} +-EXPORT_SYMBOL(ltq_get_fpi_bus_clock); +- +-unsigned int ltq_get_cpu_hz(void) +-{ +- if (ltq_cgu_r32(LTQ_CGU_SYS) & (1 << 5)) +- return CLOCK_266M; +- else +- return CLOCK_133M; +-} +-EXPORT_SYMBOL(ltq_get_cpu_hz); +- +-unsigned int ltq_get_fpi_hz(void) +-{ +- return CLOCK_133M; +-} +-EXPORT_SYMBOL(ltq_get_fpi_hz); +diff --git a/arch/mips/lantiq/xway/clk-xway.c b/arch/mips/lantiq/xway/clk-xway.c +deleted file mode 100644 +index 696b1a3..0000000 +--- a/arch/mips/lantiq/xway/clk-xway.c ++++ /dev/null +@@ -1,223 +0,0 @@ +-/* +- * 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) 2010 John Crispin <blogic@openwrt.org> +- */ +- +-#include <linux/io.h> +-#include <linux/export.h> +-#include <linux/init.h> +-#include <linux/clk.h> +- +-#include <asm/time.h> +-#include <asm/irq.h> +-#include <asm/div64.h> +- +-#include <lantiq_soc.h> +- +-static unsigned int ltq_ram_clocks[] = { +- CLOCK_167M, CLOCK_133M, CLOCK_111M, CLOCK_83M }; +-#define DDR_HZ ltq_ram_clocks[ltq_cgu_r32(LTQ_CGU_SYS) & 0x3] +- +-#define BASIC_FREQUENCY_1 35328000 +-#define BASIC_FREQUENCY_2 36000000 +-#define BASIS_REQUENCY_USB 12000000 +- +-#define GET_BITS(x, msb, lsb) \ +- (((x) & ((1 << ((msb) + 1)) - 1)) >> (lsb)) +- +-#define LTQ_CGU_PLL0_CFG 0x0004 +-#define LTQ_CGU_PLL1_CFG 0x0008 +-#define LTQ_CGU_PLL2_CFG 0x000C +-#define LTQ_CGU_SYS 0x0010 +-#define LTQ_CGU_UPDATE 0x0014 +-#define LTQ_CGU_IF_CLK 0x0018 +-#define LTQ_CGU_OSC_CON 0x001C +-#define LTQ_CGU_SMD 0x0020 +-#define LTQ_CGU_CT1SR 0x0028 +-#define LTQ_CGU_CT2SR 0x002C +-#define LTQ_CGU_PCMCR 0x0030 +-#define LTQ_CGU_PCI_CR 0x0034 +-#define LTQ_CGU_PD_PC 0x0038 +-#define LTQ_CGU_FMR 0x003C +- +-#define CGU_PLL0_PHASE_DIVIDER_ENABLE \ +- (ltq_cgu_r32(LTQ_CGU_PLL0_CFG) & (1 << 31)) +-#define CGU_PLL0_BYPASS \ +- (ltq_cgu_r32(LTQ_CGU_PLL0_CFG) & (1 << 30)) +-#define CGU_PLL0_CFG_DSMSEL \ +- (ltq_cgu_r32(LTQ_CGU_PLL0_CFG) & (1 << 28)) +-#define CGU_PLL0_CFG_FRAC_EN \ +- (ltq_cgu_r32(LTQ_CGU_PLL0_CFG) & (1 << 27)) +-#define CGU_PLL1_SRC \ +- (ltq_cgu_r32(LTQ_CGU_PLL1_CFG) & (1 << 31)) +-#define CGU_PLL2_PHASE_DIVIDER_ENABLE \ +- (ltq_cgu_r32(LTQ_CGU_PLL2_CFG) & (1 << 20)) +-#define CGU_SYS_FPI_SEL (1 << 6) +-#define CGU_SYS_DDR_SEL 0x3 +-#define CGU_PLL0_SRC (1 << 29) +- +-#define CGU_PLL0_CFG_PLLK GET_BITS(ltq_cgu_r32(LTQ_CGU_PLL0_CFG), 26, 17) +-#define CGU_PLL0_CFG_PLLN GET_BITS(ltq_cgu_r32(LTQ_CGU_PLL0_CFG), 12, 6) +-#define CGU_PLL0_CFG_PLLM GET_BITS(ltq_cgu_r32(LTQ_CGU_PLL0_CFG), 5, 2) +-#define CGU_PLL2_SRC GET_BITS(ltq_cgu_r32(LTQ_CGU_PLL2_CFG), 18, 17) +-#define CGU_PLL2_CFG_INPUT_DIV GET_BITS(ltq_cgu_r32(LTQ_CGU_PLL2_CFG), 16, 13) +- +-static unsigned int ltq_get_pll0_fdiv(void); +- +-static inline unsigned int get_input_clock(int pll) +-{ +- switch (pll) { +- case 0: +- if (ltq_cgu_r32(LTQ_CGU_PLL0_CFG) & CGU_PLL0_SRC) +- return BASIS_REQUENCY_USB; +- else if (CGU_PLL0_PHASE_DIVIDER_ENABLE) +- return BASIC_FREQUENCY_1; +- else +- return BASIC_FREQUENCY_2; +- case 1: +- if (CGU_PLL1_SRC) +- return BASIS_REQUENCY_USB; +- else if (CGU_PLL0_PHASE_DIVIDER_ENABLE) +- return BASIC_FREQUENCY_1; +- else +- return BASIC_FREQUENCY_2; +- case 2: +- switch (CGU_PLL2_SRC) { +- case 0: +- return ltq_get_pll0_fdiv(); +- case 1: +- return CGU_PLL2_PHASE_DIVIDER_ENABLE ? +- BASIC_FREQUENCY_1 : +- BASIC_FREQUENCY_2; +- case 2: +- return BASIS_REQUENCY_USB; +- } +- default: +- return 0; +- } +-} +- +-static inline unsigned int cal_dsm(int pll, unsigned int num, unsigned int den) +-{ +- u64 res, clock = get_input_clock(pll); +- +- res = num * clock; +- do_div(res, den); +- return res; +-} +- +-static inline unsigned int mash_dsm(int pll, unsigned int M, unsigned int N, +- unsigned int K) +-{ +- unsigned int num = ((N + 1) << 10) + K; +- unsigned int den = (M + 1) << 10; +- +- return cal_dsm(pll, num, den); +-} +- +-static inline unsigned int ssff_dsm_1(int pll, unsigned int M, unsigned int N, +- unsigned int K) +-{ +- unsigned int num = ((N + 1) << 11) + K + 512; +- unsigned int den = (M + 1) << 11; +- +- return cal_dsm(pll, num, den); +-} +- +-static inline unsigned int ssff_dsm_2(int pll, unsigned int M, unsigned int N, +- unsigned int K) +-{ +- unsigned int num = K >= 512 ? +- ((N + 1) << 12) + K - 512 : ((N + 1) << 12) + K + 3584; +- unsigned int den = (M + 1) << 12; +- +- return cal_dsm(pll, num, den); +-} +- +-static inline unsigned int dsm(int pll, unsigned int M, unsigned int N, +- unsigned int K, unsigned int dsmsel, unsigned int phase_div_en) +-{ +- if (!dsmsel) +- return mash_dsm(pll, M, N, K); +- else if (!phase_div_en) +- return mash_dsm(pll, M, N, K); +- else +- return ssff_dsm_2(pll, M, N, K); +-} +- +-static inline unsigned int ltq_get_pll0_fosc(void) +-{ +- if (CGU_PLL0_BYPASS) +- return get_input_clock(0); +- else +- return !CGU_PLL0_CFG_FRAC_EN +- ? dsm(0, CGU_PLL0_CFG_PLLM, CGU_PLL0_CFG_PLLN, 0, +- CGU_PLL0_CFG_DSMSEL, +- CGU_PLL0_PHASE_DIVIDER_ENABLE) +- : dsm(0, CGU_PLL0_CFG_PLLM, CGU_PLL0_CFG_PLLN, +- CGU_PLL0_CFG_PLLK, CGU_PLL0_CFG_DSMSEL, +- CGU_PLL0_PHASE_DIVIDER_ENABLE); +-} +- +-static unsigned int ltq_get_pll0_fdiv(void) +-{ +- unsigned int div = CGU_PLL2_CFG_INPUT_DIV + 1; +- +- return (ltq_get_pll0_fosc() + (div >> 1)) / div; +-} +- +-unsigned int ltq_get_io_region_clock(void) +-{ +- unsigned int ret = ltq_get_pll0_fosc(); +- +- switch (ltq_cgu_r32(LTQ_CGU_PLL2_CFG) & CGU_SYS_DDR_SEL) { +- default: +- case 0: +- return (ret + 1) / 2; +- case 1: +- return (ret * 2 + 2) / 5; +- case 2: +- return (ret + 1) / 3; +- case 3: +- return (ret + 2) / 4; +- } +-} +-EXPORT_SYMBOL(ltq_get_io_region_clock); +- +-unsigned int ltq_get_fpi_bus_clock(int fpi) +-{ +- unsigned int ret = ltq_get_io_region_clock(); +- +- if ((fpi == 2) && (ltq_cgu_r32(LTQ_CGU_SYS) & CGU_SYS_FPI_SEL)) +- ret >>= 1; +- return ret; +-} +-EXPORT_SYMBOL(ltq_get_fpi_bus_clock); +- +-unsigned int ltq_get_cpu_hz(void) +-{ +- switch (ltq_cgu_r32(LTQ_CGU_SYS) & 0xc) { +- case 0: +- return CLOCK_333M; +- case 4: +- return DDR_HZ; +- case 8: +- return DDR_HZ << 1; +- default: +- return DDR_HZ >> 1; +- } +-} +-EXPORT_SYMBOL(ltq_get_cpu_hz); +- +-unsigned int ltq_get_fpi_hz(void) +-{ +- unsigned int ddr_clock = DDR_HZ; +- +- if (ltq_cgu_r32(LTQ_CGU_SYS) & 0x40) +- return ddr_clock >> 1; +- return ddr_clock; +-} +-EXPORT_SYMBOL(ltq_get_fpi_hz); +diff --git a/arch/mips/lantiq/xway/devices.c b/arch/mips/lantiq/xway/devices.c +index d614aa7..5d4650d 100644 +--- a/arch/mips/lantiq/xway/devices.c ++++ b/arch/mips/lantiq/xway/devices.c +@@ -31,22 +31,10 @@ + + /* gpio */ + static struct resource ltq_gpio_resource[] = { +- { +- .name = "gpio0", +- .start = LTQ_GPIO0_BASE_ADDR, +- .end = LTQ_GPIO0_BASE_ADDR + LTQ_GPIO_SIZE - 1, +- .flags = IORESOURCE_MEM, +- }, { +- .name = "gpio1", +- .start = LTQ_GPIO1_BASE_ADDR, +- .end = LTQ_GPIO1_BASE_ADDR + LTQ_GPIO_SIZE - 1, +- .flags = IORESOURCE_MEM, +- }, { +- .name = "gpio2", +- .start = LTQ_GPIO2_BASE_ADDR, +- .end = LTQ_GPIO2_BASE_ADDR + LTQ_GPIO_SIZE - 1, +- .flags = IORESOURCE_MEM, +- } ++ MEM_RES("gpio0", LTQ_GPIO0_BASE_ADDR, LTQ_GPIO_SIZE), ++ MEM_RES("gpio1", LTQ_GPIO1_BASE_ADDR, LTQ_GPIO_SIZE), ++ MEM_RES("gpio2", LTQ_GPIO2_BASE_ADDR, LTQ_GPIO_SIZE), ++ MEM_RES("gpio3", LTQ_GPIO3_BASE_ADDR, LTQ_GPIO3_SIZE), + }; + + void __init ltq_register_gpio(void) +@@ -60,30 +48,23 @@ void __init ltq_register_gpio(void) + if (ltq_is_ar9() || ltq_is_vr9()) { + platform_device_register_simple("ltq_gpio", 2, + <q_gpio_resource[2], 1); ++ platform_device_register_simple("ltq_gpio", 3, ++ <q_gpio_resource[3], 1); + } + } + + /* serial to parallel conversion */ +-static struct resource ltq_stp_resource = { +- .name = "stp", +- .start = LTQ_STP_BASE_ADDR, +- .end = LTQ_STP_BASE_ADDR + LTQ_STP_SIZE - 1, +- .flags = IORESOURCE_MEM, +-}; ++static struct resource ltq_stp_resource = ++ MEM_RES("stp", LTQ_STP_BASE_ADDR, LTQ_STP_SIZE); + + void __init ltq_register_gpio_stp(void) + { +- platform_device_register_simple("ltq_stp", 0, <q_stp_resource, 1); ++ platform_device_register_simple("ltq_stp", -1, <q_stp_resource, 1); + } + + /* asc ports - amazon se has its own serial mapping */ + static struct resource ltq_ase_asc_resources[] = { +- { +- .name = "asc0", +- .start = LTQ_ASC1_BASE_ADDR, +- .end = LTQ_ASC1_BASE_ADDR + LTQ_ASC_SIZE - 1, +- .flags = IORESOURCE_MEM, +- }, ++ MEM_RES("asc0", LTQ_ASC1_BASE_ADDR, LTQ_ASC_SIZE), + IRQ_RES(tx, LTQ_ASC_ASE_TIR), + IRQ_RES(rx, LTQ_ASC_ASE_RIR), + IRQ_RES(err, LTQ_ASC_ASE_EIR), +@@ -96,24 +77,45 @@ void __init ltq_register_ase_asc(void) + } + + /* ethernet */ +-static struct resource ltq_etop_resources = { +- .name = "etop", +- .start = LTQ_ETOP_BASE_ADDR, +- .end = LTQ_ETOP_BASE_ADDR + LTQ_ETOP_SIZE - 1, +- .flags = IORESOURCE_MEM, ++static struct resource ltq_etop_resources[] = { ++ MEM_RES("etop", LTQ_ETOP_BASE_ADDR, LTQ_ETOP_SIZE), ++ MEM_RES("gbit", LTQ_GBIT_BASE_ADDR, LTQ_GBIT_SIZE), + }; + + static struct platform_device ltq_etop = { + .name = "ltq_etop", +- .resource = <q_etop_resources, ++ .resource = ltq_etop_resources, + .num_resources = 1, ++ .id = -1, + }; + + void __init + ltq_register_etop(struct ltq_eth_data *eth) + { ++ /* only register the gphy on socs that have one */ ++ if (ltq_is_ar9() | ltq_is_vr9()) ++ ltq_etop.num_resources = 2; + if (eth) { + ltq_etop.dev.platform_data = eth; + platform_device_register(<q_etop); + } + } ++ ++/* ethernet */ ++static struct resource ltq_vrx200_resources[] = { ++ MEM_RES("gbit", LTQ_GBIT_BASE_ADDR, LTQ_GBIT_SIZE), ++}; ++ ++static struct platform_device ltq_vrx200 = { ++ .name = "ltq_vrx200", ++ .resource = ltq_vrx200_resources, ++ .num_resources = 1, ++ .id = -1, ++}; ++ ++void __init ++ltq_register_vrx200(struct ltq_eth_data *eth) ++{ ++ ltq_vrx200.dev.platform_data = eth; ++ platform_device_register(<q_vrx200); ++} +diff --git a/arch/mips/lantiq/xway/devices.h b/arch/mips/lantiq/xway/devices.h +index e904934..08befd9 100644 +--- a/arch/mips/lantiq/xway/devices.h ++++ b/arch/mips/lantiq/xway/devices.h +@@ -16,5 +16,7 @@ extern void ltq_register_gpio(void); + extern void ltq_register_gpio_stp(void); + extern void ltq_register_ase_asc(void); + extern void ltq_register_etop(struct ltq_eth_data *eth); ++extern void xway_register_nand(struct mtd_partition *parts, int count); ++extern void ltq_register_vrx200(struct ltq_eth_data *eth); + + #endif +diff --git a/arch/mips/lantiq/xway/dma.c b/arch/mips/lantiq/xway/dma.c +index b210e93..ce86529 100644 +--- a/arch/mips/lantiq/xway/dma.c ++++ b/arch/mips/lantiq/xway/dma.c +@@ -20,10 +20,13 @@ + #include <linux/io.h> + #include <linux/dma-mapping.h> + #include <linux/export.h> ++#include <linux/clk.h> + + #include <lantiq_soc.h> + #include <xway_dma.h> + ++#include "../devices.h" ++ + #define LTQ_DMA_CTRL 0x10 + #define LTQ_DMA_CPOLL 0x14 + #define LTQ_DMA_CS 0x18 +@@ -55,12 +58,8 @@ + #define ltq_dma_w32_mask(x, y, z) ltq_w32_mask(x, y, \ + ltq_dma_membase + (z)) + +-static struct resource ltq_dma_resource = { +- .name = "dma", +- .start = LTQ_DMA_BASE_ADDR, +- .end = LTQ_DMA_BASE_ADDR + LTQ_DMA_SIZE - 1, +- .flags = IORESOURCE_MEM, +-}; ++static struct resource ltq_dma_resource = ++ MEM_RES("dma", LTQ_DMA_BASE_ADDR, LTQ_DMA_SIZE); + + static void __iomem *ltq_dma_membase; + +@@ -218,24 +217,18 @@ EXPORT_SYMBOL_GPL(ltq_dma_init_port); + int __init + ltq_dma_init(void) + { ++ struct clk *clk; + int i; + +- /* insert and request the memory region */ +- if (insert_resource(&iomem_resource, <q_dma_resource) < 0) +- panic("Failed to insert dma memory"); +- +- if (request_mem_region(ltq_dma_resource.start, +- resource_size(<q_dma_resource), "dma") < 0) +- panic("Failed to request dma memory"); +- + /* remap dma register range */ +- ltq_dma_membase = ioremap_nocache(ltq_dma_resource.start, +- resource_size(<q_dma_resource)); ++ ltq_dma_membase = ltq_remap_resource(<q_dma_resource); + if (!ltq_dma_membase) + panic("Failed to remap dma memory"); + + /* power up and reset the dma engine */ +- ltq_pmu_enable(PMU_DMA); ++ clk = clk_get_sys("ltq_dma", NULL); ++ WARN_ON(!clk); ++ clk_enable(clk); + ltq_dma_w32_mask(0, DMA_RESET, LTQ_DMA_CTRL); + + /* disable all interrupts */ +diff --git a/arch/mips/lantiq/xway/ebu.c b/arch/mips/lantiq/xway/ebu.c +deleted file mode 100644 +index 862e3e8..0000000 +--- a/arch/mips/lantiq/xway/ebu.c ++++ /dev/null +@@ -1,52 +0,0 @@ +-/* +- * 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. +- * +- * EBU - the external bus unit attaches PCI, NOR and NAND +- * +- * Copyright (C) 2010 John Crispin <blogic@openwrt.org> +- */ +- +-#include <linux/kernel.h> +-#include <linux/module.h> +-#include <linux/ioport.h> +- +-#include <lantiq_soc.h> +- +-/* all access to the ebu must be locked */ +-DEFINE_SPINLOCK(ebu_lock); +-EXPORT_SYMBOL_GPL(ebu_lock); +- +-static struct resource ltq_ebu_resource = { +- .name = "ebu", +- .start = LTQ_EBU_BASE_ADDR, +- .end = LTQ_EBU_BASE_ADDR + LTQ_EBU_SIZE - 1, +- .flags = IORESOURCE_MEM, +-}; +- +-/* remapped base addr of the clock unit and external bus unit */ +-void __iomem *ltq_ebu_membase; +- +-static int __init lantiq_ebu_init(void) +-{ +- /* insert and request the memory region */ +- if (insert_resource(&iomem_resource, <q_ebu_resource) < 0) +- panic("Failed to insert ebu memory"); +- +- if (request_mem_region(ltq_ebu_resource.start, +- resource_size(<q_ebu_resource), "ebu") < 0) +- panic("Failed to request ebu memory"); +- +- /* remap ebu register range */ +- ltq_ebu_membase = ioremap_nocache(ltq_ebu_resource.start, +- resource_size(<q_ebu_resource)); +- if (!ltq_ebu_membase) +- panic("Failed to remap ebu memory"); +- +- /* make sure to unprotect the memory region where flash is located */ +- ltq_ebu_w32(ltq_ebu_r32(LTQ_EBU_BUSCON0) & ~EBU_WRDIS, LTQ_EBU_BUSCON0); +- return 0; +-} +- +-postcore_initcall(lantiq_ebu_init); +diff --git a/arch/mips/lantiq/xway/gpio.c b/arch/mips/lantiq/xway/gpio.c +index d2fa98f..375329b 100644 +--- a/arch/mips/lantiq/xway/gpio.c ++++ b/arch/mips/lantiq/xway/gpio.c +@@ -21,9 +21,19 @@ + #define LTQ_GPIO_ALTSEL0 0x0C + #define LTQ_GPIO_ALTSEL1 0x10 + #define LTQ_GPIO_OD 0x14 +- ++#define LTQ_GPIO_PUDSEL 0x1C ++#define LTQ_GPIO_PUDEN 0x20 ++#define LTQ_GPIO3_OD 0x24 ++#define LTQ_GPIO3_ALTSEL1 0x24 ++#define LTQ_GPIO3_PUDSEL 0x28 ++#define LTQ_GPIO3_PUDEN 0x2C ++ ++/* PORT3 only has 8 pins and its register layout ++ is slightly different */ + #define PINS_PER_PORT 16 +-#define MAX_PORTS 3 ++#define PINS_PORT3 8 ++#define MAX_PORTS 4 ++#define MAX_PIN 56 + + #define ltq_gpio_getbit(m, r, p) (!!(ltq_r32(m + r) & (1 << p))) + #define ltq_gpio_setbit(m, r, p) ltq_w32_mask(0, (1 << p), m + r) +@@ -48,14 +58,14 @@ int irq_to_gpio(unsigned int gpio) + } + EXPORT_SYMBOL(irq_to_gpio); + +-int ltq_gpio_request(unsigned int pin, unsigned int alt0, +- unsigned int alt1, unsigned int dir, const char *name) ++int ltq_gpio_request(struct device *dev, unsigned int pin, unsigned int mux, ++ unsigned int dir, const char *name) + { + int id = 0; + +- if (pin >= (MAX_PORTS * PINS_PER_PORT)) ++ if (pin >= MAX_PIN) + return -EINVAL; +- if (gpio_request(pin, name)) { ++ if (devm_gpio_request(dev, pin, name)) { + pr_err("failed to setup lantiq gpio: %s\n", name); + return -EBUSY; + } +@@ -67,18 +77,27 @@ int ltq_gpio_request(unsigned int pin, unsigned int alt0, + pin -= PINS_PER_PORT; + id++; + } +- if (alt0) ++ if (mux & 0x2) + ltq_gpio_setbit(ltq_gpio_port[id].membase, + LTQ_GPIO_ALTSEL0, pin); + else + ltq_gpio_clearbit(ltq_gpio_port[id].membase, + LTQ_GPIO_ALTSEL0, pin); +- if (alt1) +- ltq_gpio_setbit(ltq_gpio_port[id].membase, +- LTQ_GPIO_ALTSEL1, pin); +- else +- ltq_gpio_clearbit(ltq_gpio_port[id].membase, +- LTQ_GPIO_ALTSEL1, pin); ++ if (id == 3) { ++ if (mux & 0x1) ++ ltq_gpio_setbit(ltq_gpio_port[1].membase, ++ LTQ_GPIO3_ALTSEL1, pin); ++ else ++ ltq_gpio_clearbit(ltq_gpio_port[1].membase, ++ LTQ_GPIO3_ALTSEL1, pin); ++ } else { ++ if (mux & 0x1) ++ ltq_gpio_setbit(ltq_gpio_port[id].membase, ++ LTQ_GPIO_ALTSEL1, pin); ++ else ++ ltq_gpio_clearbit(ltq_gpio_port[id].membase, ++ LTQ_GPIO_ALTSEL1, pin); ++ } + return 0; + } + EXPORT_SYMBOL(ltq_gpio_request); +@@ -104,7 +123,18 @@ static int ltq_gpio_direction_input(struct gpio_chip *chip, unsigned int offset) + { + struct ltq_gpio *ltq_gpio = container_of(chip, struct ltq_gpio, chip); + +- ltq_gpio_clearbit(ltq_gpio->membase, LTQ_GPIO_OD, offset); ++ if (chip->ngpio == PINS_PORT3) { ++ ltq_gpio_clearbit(ltq_gpio_port[0].membase, ++ LTQ_GPIO3_OD, offset); ++ ltq_gpio_setbit(ltq_gpio_port[0].membase, ++ LTQ_GPIO3_PUDSEL, offset); ++ ltq_gpio_setbit(ltq_gpio_port[0].membase, ++ LTQ_GPIO3_PUDEN, offset); ++ } else { ++ ltq_gpio_clearbit(ltq_gpio->membase, LTQ_GPIO_OD, offset); ++ ltq_gpio_setbit(ltq_gpio->membase, LTQ_GPIO_PUDSEL, offset); ++ ltq_gpio_setbit(ltq_gpio->membase, LTQ_GPIO_PUDEN, offset); ++ } + ltq_gpio_clearbit(ltq_gpio->membase, LTQ_GPIO_DIR, offset); + + return 0; +@@ -115,7 +145,18 @@ static int ltq_gpio_direction_output(struct gpio_chip *chip, + { + struct ltq_gpio *ltq_gpio = container_of(chip, struct ltq_gpio, chip); + +- ltq_gpio_setbit(ltq_gpio->membase, LTQ_GPIO_OD, offset); ++ if (chip->ngpio == PINS_PORT3) { ++ ltq_gpio_setbit(ltq_gpio_port[0].membase, ++ LTQ_GPIO3_OD, offset); ++ ltq_gpio_clearbit(ltq_gpio_port[0].membase, ++ LTQ_GPIO3_PUDSEL, offset); ++ ltq_gpio_clearbit(ltq_gpio_port[0].membase, ++ LTQ_GPIO3_PUDEN, offset); ++ } else { ++ ltq_gpio_setbit(ltq_gpio->membase, LTQ_GPIO_OD, offset); ++ ltq_gpio_clearbit(ltq_gpio->membase, LTQ_GPIO_PUDSEL, offset); ++ ltq_gpio_clearbit(ltq_gpio->membase, LTQ_GPIO_PUDEN, offset); ++ } + ltq_gpio_setbit(ltq_gpio->membase, LTQ_GPIO_DIR, offset); + ltq_gpio_set(chip, offset, value); + +@@ -127,7 +168,11 @@ static int ltq_gpio_req(struct gpio_chip *chip, unsigned offset) + struct ltq_gpio *ltq_gpio = container_of(chip, struct ltq_gpio, chip); + + ltq_gpio_clearbit(ltq_gpio->membase, LTQ_GPIO_ALTSEL0, offset); +- ltq_gpio_clearbit(ltq_gpio->membase, LTQ_GPIO_ALTSEL1, offset); ++ if (chip->ngpio == PINS_PORT3) ++ ltq_gpio_clearbit(ltq_gpio_port[1].membase, ++ LTQ_GPIO3_ALTSEL1, offset); ++ else ++ ltq_gpio_clearbit(ltq_gpio->membase, LTQ_GPIO_ALTSEL1, offset); + return 0; + } + +@@ -140,6 +185,16 @@ static int ltq_gpio_probe(struct platform_device *pdev) + pdev->id); + return -EINVAL; + } ++ ++ /* dirty hack - The registers of port3 are not mapped linearly. ++ Port 3 may only load if Port 1/2 are mapped */ ++ if ((pdev->id == 3) && (!ltq_gpio_port[1].membase ++ || !ltq_gpio_port[2].membase)) { ++ dev_err(&pdev->dev, ++ "ports 1/2 need to be loaded before port 3 works\n"); ++ return -ENOMEM; ++ } ++ + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res) { + dev_err(&pdev->dev, "failed to get memory for gpio port %d\n", +@@ -169,7 +224,10 @@ static int ltq_gpio_probe(struct platform_device *pdev) + ltq_gpio_port[pdev->id].chip.set = ltq_gpio_set; + ltq_gpio_port[pdev->id].chip.request = ltq_gpio_req; + ltq_gpio_port[pdev->id].chip.base = PINS_PER_PORT * pdev->id; +- ltq_gpio_port[pdev->id].chip.ngpio = PINS_PER_PORT; ++ if (pdev->id == 3) ++ ltq_gpio_port[pdev->id].chip.ngpio = PINS_PORT3; ++ else ++ ltq_gpio_port[pdev->id].chip.ngpio = PINS_PER_PORT; + platform_set_drvdata(pdev, <q_gpio_port[pdev->id]); + return gpiochip_add(<q_gpio_port[pdev->id].chip); + } +diff --git a/arch/mips/lantiq/xway/gpio_ebu.c b/arch/mips/lantiq/xway/gpio_ebu.c +index b91c7f1..bc5696b 100644 +--- a/arch/mips/lantiq/xway/gpio_ebu.c ++++ b/arch/mips/lantiq/xway/gpio_ebu.c +@@ -61,9 +61,8 @@ static struct gpio_chip ltq_ebu_chip = { + .label = "ltq_ebu", + .direction_output = ltq_ebu_direction_output, + .set = ltq_ebu_set, +- .base = 72, ++ .base = 100, + .ngpio = 16, +- .can_sleep = 1, + .owner = THIS_MODULE, + }; + +diff --git a/arch/mips/lantiq/xway/gpio_stp.c b/arch/mips/lantiq/xway/gpio_stp.c +index ff9991c..791beeb 100644 +--- a/arch/mips/lantiq/xway/gpio_stp.c ++++ b/arch/mips/lantiq/xway/gpio_stp.c +@@ -15,6 +15,8 @@ + #include <linux/mutex.h> + #include <linux/io.h> + #include <linux/gpio.h> ++#include <linux/clk.h> ++#include <linux/err.h> + + #include <lantiq_soc.h> + +@@ -25,6 +27,7 @@ + #define LTQ_STP_AR 0x10 + + #define LTQ_STP_CON_SWU (1 << 31) ++#define LTQ_STP_SWU_MASK (1 << 31) + #define LTQ_STP_2HZ 0 + #define LTQ_STP_4HZ (1 << 23) + #define LTQ_STP_8HZ (2 << 23) +@@ -35,6 +38,8 @@ + #define LTQ_STP_ADSL_SRC (3 << 24) + + #define LTQ_STP_GROUP0 (1 << 0) ++#define LTQ_STP_GROUP1 (1 << 1) ++#define LTQ_STP_GROUP2 (1 << 2) + + #define LTQ_STP_RISING 0 + #define LTQ_STP_FALLING (1 << 26) +@@ -56,6 +61,12 @@ static void ltq_stp_set(struct gpio_chip *chip, unsigned offset, int value) + else + ltq_stp_shadow &= ~(1 << offset); + ltq_stp_w32(ltq_stp_shadow, LTQ_STP_CPU0); ++ ltq_stp_w32_mask(LTQ_STP_SWU_MASK, LTQ_STP_CON_SWU, LTQ_STP_CON0); ++} ++ ++static int ltq_stp_get(struct gpio_chip *chip, unsigned offset) ++{ ++ return !!(ltq_stp_r32(LTQ_STP_CPU0) & (1<<offset)); + } + + static int ltq_stp_direction_output(struct gpio_chip *chip, unsigned offset, +@@ -70,18 +81,15 @@ static struct gpio_chip ltq_stp_chip = { + .label = "ltq_stp", + .direction_output = ltq_stp_direction_output, + .set = ltq_stp_set, +- .base = 48, ++ .get = ltq_stp_get, ++ .base = 200, + .ngpio = 24, +- .can_sleep = 1, + .owner = THIS_MODULE, + }; + +-static int ltq_stp_hw_init(void) ++static int ltq_stp_hw_init(struct device *dev) + { +- /* the 3 pins used to control the external stp */ +- ltq_gpio_request(4, 1, 0, 1, "stp-st"); +- ltq_gpio_request(5, 1, 0, 1, "stp-d"); +- ltq_gpio_request(6, 1, 0, 1, "stp-sh"); ++ struct clk *clk; + + /* sane defaults */ + ltq_stp_w32(0, LTQ_STP_AR); +@@ -93,21 +101,18 @@ static int ltq_stp_hw_init(void) + /* rising or falling edge */ + ltq_stp_w32_mask(LTQ_STP_EDGE_MASK, LTQ_STP_FALLING, LTQ_STP_CON0); + +- /* per default stp 15-0 are set */ +- ltq_stp_w32_mask(0, LTQ_STP_GROUP0, LTQ_STP_CON1); +- +- /* stp are update periodically by the FPI bus */ +- ltq_stp_w32_mask(LTQ_STP_UPD_MASK, LTQ_STP_UPD_FPI, LTQ_STP_CON1); +- +- /* set stp update speed */ +- ltq_stp_w32_mask(LTQ_STP_SPEED_MASK, LTQ_STP_8HZ, LTQ_STP_CON1); ++ /* enable all three led groups */ ++ ltq_stp_w32_mask(0, LTQ_STP_GROUP0 | LTQ_STP_GROUP1 | LTQ_STP_GROUP2, ++ LTQ_STP_CON1); + + /* tell the hardware that pin (led) 0 and 1 are controlled + * by the dsl arc + */ + ltq_stp_w32_mask(0, LTQ_STP_ADSL_SRC, LTQ_STP_CON0); + +- ltq_pmu_enable(PMU_LED); ++ clk = clk_get(dev, NULL); ++ WARN_ON(IS_ERR(clk)); ++ clk_enable(clk); + return 0; + } + +@@ -115,6 +120,7 @@ static int __devinit ltq_stp_probe(struct platform_device *pdev) + { + struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + int ret = 0; ++ int pin; + + if (!res) + return -ENOENT; +@@ -130,9 +136,18 @@ static int __devinit ltq_stp_probe(struct platform_device *pdev) + dev_err(&pdev->dev, "failed to remap STP memory\n"); + return -ENOMEM; + } ++ ++ /* the 3 pins used to control the external stp */ ++ pin = ltq_is_ase() ? 1 : 4; ++ if (ltq_gpio_request(&pdev->dev, pin, 2, 1, "stp-st") || ++ ltq_gpio_request(&pdev->dev, pin+1, 2, 1, "stp-d") || ++ ltq_gpio_request(&pdev->dev, pin+2, 2, 1, "stp-sh")) { ++ dev_err(&pdev->dev, "failed to request needed gpios\n"); ++ return -EBUSY; ++ } + ret = gpiochip_add(<q_stp_chip); + if (!ret) +- ret = ltq_stp_hw_init(); ++ ret = ltq_stp_hw_init(&pdev->dev); + + return ret; + } +diff --git a/arch/mips/lantiq/xway/mach-easy50601.c b/arch/mips/lantiq/xway/mach-easy50601.c +index d5aaf63..e76c29a 100644 +--- a/arch/mips/lantiq/xway/mach-easy50601.c ++++ b/arch/mips/lantiq/xway/mach-easy50601.c +@@ -32,12 +32,7 @@ static struct mtd_partition easy50601_partitions[] = { + { + .name = "linux", + .offset = 0x20000, +- .size = 0xE0000, +- }, +- { +- .name = "rootfs", +- .offset = 0x100000, +- .size = 0x300000, ++ .size = 0x3d0000, + }, + }; + +@@ -46,9 +41,15 @@ static struct physmap_flash_data easy50601_flash_data = { + .parts = easy50601_partitions, + }; + +-static void __init easy50601_init(void) ++static struct ltq_eth_data ltq_eth_data = { ++ .mii_mode = -1, /* use EPHY */ ++}; ++ ++static void __init ++easy50601_init(void) + { + ltq_register_nor(&easy50601_flash_data); ++ ltq_register_etop(<q_eth_data); + } + + MIPS_MACHINE(LTQ_MACH_EASY50601, +diff --git a/arch/mips/lantiq/xway/mach-easy50712.c b/arch/mips/lantiq/xway/mach-easy50712.c +index ea5027b..581aa76 100644 +--- a/arch/mips/lantiq/xway/mach-easy50712.c ++++ b/arch/mips/lantiq/xway/mach-easy50712.c +@@ -34,12 +34,7 @@ static struct mtd_partition easy50712_partitions[] = { + { + .name = "linux", + .offset = 0x20000, +- .size = 0xe0000, +- }, +- { +- .name = "rootfs", +- .offset = 0x100000, +- .size = 0x300000, ++ .size = 0x3d0000, + }, + }; + +@@ -60,15 +55,17 @@ static struct ltq_eth_data ltq_eth_data = { + .mii_mode = PHY_INTERFACE_MODE_MII, + }; + +-static void __init easy50712_init(void) ++static void __init ++easy50712_init(void) + { + ltq_register_gpio_stp(); + ltq_register_nor(&easy50712_flash_data); + ltq_register_pci(<q_pci_data); + ltq_register_etop(<q_eth_data); ++ ltq_register_tapi(); + } + + MIPS_MACHINE(LTQ_MACH_EASY50712, +- "EASY50712", +- "EASY50712 Eval Board", +- easy50712_init); ++ "EASY50712", ++ "EASY50712 Eval Board", ++ easy50712_init); +diff --git a/arch/mips/lantiq/xway/pmu.c b/arch/mips/lantiq/xway/pmu.c +deleted file mode 100644 +index fe85361..0000000 +--- a/arch/mips/lantiq/xway/pmu.c ++++ /dev/null +@@ -1,69 +0,0 @@ +-/* +- * 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) 2010 John Crispin <blogic@openwrt.org> +- */ +- +-#include <linux/kernel.h> +-#include <linux/module.h> +-#include <linux/ioport.h> +- +-#include <lantiq_soc.h> +- +-/* PMU - the power management unit allows us to turn part of the core +- * on and off +- */ +- +-/* the enable / disable registers */ +-#define LTQ_PMU_PWDCR 0x1C +-#define LTQ_PMU_PWDSR 0x20 +- +-#define ltq_pmu_w32(x, y) ltq_w32((x), ltq_pmu_membase + (y)) +-#define ltq_pmu_r32(x) ltq_r32(ltq_pmu_membase + (x)) +- +-static struct resource ltq_pmu_resource = { +- .name = "pmu", +- .start = LTQ_PMU_BASE_ADDR, +- .end = LTQ_PMU_BASE_ADDR + LTQ_PMU_SIZE - 1, +- .flags = IORESOURCE_MEM, +-}; +- +-static void __iomem *ltq_pmu_membase; +- +-void ltq_pmu_enable(unsigned int module) +-{ +- int err = 1000000; +- +- ltq_pmu_w32(ltq_pmu_r32(LTQ_PMU_PWDCR) & ~module, LTQ_PMU_PWDCR); +- do {} while (--err && (ltq_pmu_r32(LTQ_PMU_PWDSR) & module)); +- +- if (!err) +- panic("activating PMU module failed!"); +-} +-EXPORT_SYMBOL(ltq_pmu_enable); +- +-void ltq_pmu_disable(unsigned int module) +-{ +- ltq_pmu_w32(ltq_pmu_r32(LTQ_PMU_PWDCR) | module, LTQ_PMU_PWDCR); +-} +-EXPORT_SYMBOL(ltq_pmu_disable); +- +-int __init ltq_pmu_init(void) +-{ +- if (insert_resource(&iomem_resource, <q_pmu_resource) < 0) +- panic("Failed to insert pmu memory"); +- +- if (request_mem_region(ltq_pmu_resource.start, +- resource_size(<q_pmu_resource), "pmu") < 0) +- panic("Failed to request pmu memory"); +- +- ltq_pmu_membase = ioremap_nocache(ltq_pmu_resource.start, +- resource_size(<q_pmu_resource)); +- if (!ltq_pmu_membase) +- panic("Failed to remap pmu memory"); +- return 0; +-} +- +-core_initcall(ltq_pmu_init); +diff --git a/arch/mips/lantiq/xway/prom-ase.c b/arch/mips/lantiq/xway/prom-ase.c +deleted file mode 100644 +index ae4959a..0000000 +--- a/arch/mips/lantiq/xway/prom-ase.c ++++ /dev/null +@@ -1,39 +0,0 @@ +-/* +- * 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) 2010 John Crispin <blogic@openwrt.org> +- */ +- +-#include <linux/export.h> +-#include <linux/clk.h> +-#include <asm/bootinfo.h> +-#include <asm/time.h> +- +-#include <lantiq_soc.h> +- +-#include "../prom.h" +- +-#define SOC_AMAZON_SE "Amazon_SE" +- +-#define PART_SHIFT 12 +-#define PART_MASK 0x0FFFFFFF +-#define REV_SHIFT 28 +-#define REV_MASK 0xF0000000 +- +-void __init ltq_soc_detect(struct ltq_soc_info *i) +-{ +- i->partnum = (ltq_r32(LTQ_MPS_CHIPID) & PART_MASK) >> PART_SHIFT; +- i->rev = (ltq_r32(LTQ_MPS_CHIPID) & REV_MASK) >> REV_SHIFT; +- switch (i->partnum) { +- case SOC_ID_AMAZON_SE: +- i->name = SOC_AMAZON_SE; +- i->type = SOC_TYPE_AMAZON_SE; +- break; +- +- default: +- unreachable(); +- break; +- } +-} +diff --git a/arch/mips/lantiq/xway/prom-xway.c b/arch/mips/lantiq/xway/prom-xway.c +deleted file mode 100644 +index 2228133..0000000 +--- a/arch/mips/lantiq/xway/prom-xway.c ++++ /dev/null +@@ -1,54 +0,0 @@ +-/* +- * 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) 2010 John Crispin <blogic@openwrt.org> +- */ +- +-#include <linux/export.h> +-#include <linux/clk.h> +-#include <asm/bootinfo.h> +-#include <asm/time.h> +- +-#include <lantiq_soc.h> +- +-#include "../prom.h" +- +-#define SOC_DANUBE "Danube" +-#define SOC_TWINPASS "Twinpass" +-#define SOC_AR9 "AR9" +- +-#define PART_SHIFT 12 +-#define PART_MASK 0x0FFFFFFF +-#define REV_SHIFT 28 +-#define REV_MASK 0xF0000000 +- +-void __init ltq_soc_detect(struct ltq_soc_info *i) +-{ +- i->partnum = (ltq_r32(LTQ_MPS_CHIPID) & PART_MASK) >> PART_SHIFT; +- i->rev = (ltq_r32(LTQ_MPS_CHIPID) & REV_MASK) >> REV_SHIFT; +- switch (i->partnum) { +- case SOC_ID_DANUBE1: +- case SOC_ID_DANUBE2: +- i->name = SOC_DANUBE; +- i->type = SOC_TYPE_DANUBE; +- break; +- +- case SOC_ID_TWINPASS: +- i->name = SOC_TWINPASS; +- i->type = SOC_TYPE_DANUBE; +- break; +- +- case SOC_ID_ARX188: +- case SOC_ID_ARX168: +- case SOC_ID_ARX182: +- i->name = SOC_AR9; +- i->type = SOC_TYPE_AR9; +- break; +- +- default: +- unreachable(); +- break; +- } +-} +diff --git a/arch/mips/lantiq/xway/reset.c b/arch/mips/lantiq/xway/reset.c +index 8b66bd8..970ca17 100644 +--- a/arch/mips/lantiq/xway/reset.c ++++ b/arch/mips/lantiq/xway/reset.c +@@ -11,26 +11,62 @@ + #include <linux/ioport.h> + #include <linux/pm.h> + #include <linux/export.h> ++#include <linux/delay.h> + #include <asm/reboot.h> + + #include <lantiq_soc.h> + ++#include "../devices.h" ++ + #define ltq_rcu_w32(x, y) ltq_w32((x), ltq_rcu_membase + (y)) + #define ltq_rcu_r32(x) ltq_r32(ltq_rcu_membase + (x)) + +-/* register definitions */ +-#define LTQ_RCU_RST 0x0010 +-#define LTQ_RCU_RST_ALL 0x40000000 +- +-#define LTQ_RCU_RST_STAT 0x0014 +-#define LTQ_RCU_STAT_SHIFT 26 +- +-static struct resource ltq_rcu_resource = { +- .name = "rcu", +- .start = LTQ_RCU_BASE_ADDR, +- .end = LTQ_RCU_BASE_ADDR + LTQ_RCU_SIZE - 1, +- .flags = IORESOURCE_MEM, +-}; ++/* reset request register */ ++#define RCU_RST_REQ 0x0010 ++/* reset status register */ ++#define RCU_RST_STAT 0x0014 ++ ++/* reset cause */ ++#define RCU_STAT_SHIFT 26 ++/* boot selection */ ++#define RCU_BOOT_SEL_SHIFT 26 ++#define RCU_BOOT_SEL_MASK 0x7 ++ ++/* Global SW Reset */ ++#define RCU_RD_SRST BIT(30) ++/* Memory Controller */ ++#define RCU_RD_MC BIT(14) ++/* PCI core */ ++#define RCU_RD_PCI BIT(13) ++/* Voice DFE/AFE */ ++#define RCU_RD_DFE_AFE BIT(12) ++/* DSL AFE */ ++#define RCU_RD_DSL_AFE BIT(11) ++/* SDIO core */ ++#define RCU_RD_SDIO BIT(10) ++/* DMA core */ ++#define RCU_RD_DMA BIT(9) ++/* PPE core */ ++#define RCU_RD_PPE BIT(8) ++/* ARC/DFE core */ ++#define RCU_RD_ARC_DFE BIT(7) ++/* AHB bus */ ++#define RCU_RD_AHB BIT(6) ++/* Ethernet MAC1 */ ++#define RCU_RD_ENET_MAC1 BIT(5) ++/* USB and Phy core */ ++#define RCU_RD_USB BIT(4) ++/* CPU1 subsystem */ ++#define RCU_RD_CPU1 BIT(3) ++/* FPI bus */ ++#define RCU_RD_FPI BIT(2) ++/* CPU0 subsystem */ ++#define RCU_RD_CPU0 BIT(1) ++/* HW reset via HRST pin */ ++#define RCU_RD_HRST BIT(0) ++ ++static struct resource ltq_rcu_resource = ++ MEM_RES("rcu", LTQ_RCU_BASE_ADDR, LTQ_RCU_SIZE); + + /* remapped base addr of the reset control unit */ + static void __iomem *ltq_rcu_membase; +@@ -38,16 +74,29 @@ static void __iomem *ltq_rcu_membase; + /* This function is used by the watchdog driver */ + int ltq_reset_cause(void) + { +- u32 val = ltq_rcu_r32(LTQ_RCU_RST_STAT); +- return val >> LTQ_RCU_STAT_SHIFT; ++ u32 val = ltq_rcu_r32(RCU_RST_STAT); ++ return val >> RCU_STAT_SHIFT; + } + EXPORT_SYMBOL_GPL(ltq_reset_cause); + ++unsigned char ltq_boot_select(void) ++{ ++ u32 val = ltq_rcu_r32(RCU_RST_STAT); ++ return (val >> RCU_BOOT_SEL_SHIFT) & RCU_BOOT_SEL_MASK; ++} ++ ++void ltq_reset_once(unsigned int module, ulong usec) ++{ ++ ltq_rcu_w32(ltq_rcu_r32(RCU_RST_REQ) | module, RCU_RST_REQ); ++ udelay(usec); ++ ltq_rcu_w32(ltq_rcu_r32(RCU_RST_REQ) & ~module, RCU_RST_REQ); ++} ++ + static void ltq_machine_restart(char *command) + { + pr_notice("System restart\n"); + local_irq_disable(); +- ltq_rcu_w32(ltq_rcu_r32(LTQ_RCU_RST) | LTQ_RCU_RST_ALL, LTQ_RCU_RST); ++ ltq_rcu_w32(ltq_rcu_r32(RCU_RST_REQ) | RCU_RD_SRST, RCU_RST_REQ); + unreachable(); + } + +@@ -67,17 +116,8 @@ static void ltq_machine_power_off(void) + + static int __init mips_reboot_setup(void) + { +- /* insert and request the memory region */ +- if (insert_resource(&iomem_resource, <q_rcu_resource) < 0) +- panic("Failed to insert rcu memory"); +- +- if (request_mem_region(ltq_rcu_resource.start, +- resource_size(<q_rcu_resource), "rcu") < 0) +- panic("Failed to request rcu memory"); +- + /* remap rcu register range */ +- ltq_rcu_membase = ioremap_nocache(ltq_rcu_resource.start, +- resource_size(<q_rcu_resource)); ++ ltq_rcu_membase = ltq_remap_resource(<q_rcu_resource); + if (!ltq_rcu_membase) + panic("Failed to remap rcu memory"); + +diff --git a/arch/mips/lantiq/xway/setup-ase.c b/arch/mips/lantiq/xway/setup-ase.c +deleted file mode 100644 +index f6f3267..0000000 +--- a/arch/mips/lantiq/xway/setup-ase.c ++++ /dev/null +@@ -1,19 +0,0 @@ +-/* +- * 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) 2011 John Crispin <blogic@openwrt.org> +- */ +- +-#include <lantiq_soc.h> +- +-#include "../prom.h" +-#include "devices.h" +- +-void __init ltq_soc_setup(void) +-{ +- ltq_register_ase_asc(); +- ltq_register_gpio(); +- ltq_register_wdt(); +-} +diff --git a/arch/mips/lantiq/xway/setup-xway.c b/arch/mips/lantiq/xway/setup-xway.c +deleted file mode 100644 +index c292f64..0000000 +--- a/arch/mips/lantiq/xway/setup-xway.c ++++ /dev/null +@@ -1,20 +0,0 @@ +-/* +- * 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) 2011 John Crispin <blogic@openwrt.org> +- */ +- +-#include <lantiq_soc.h> +- +-#include "../prom.h" +-#include "devices.h" +- +-void __init ltq_soc_setup(void) +-{ +- ltq_register_asc(0); +- ltq_register_asc(1); +- ltq_register_gpio(); +- ltq_register_wdt(); +-} +-- +1.7.9.1 + |