From cf678877a86e03302686d0364c982d573daa6e2c Mon Sep 17 00:00:00 2001 From: John Crispin 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 - */ - -#include -#include -#include -#include - -#include -#include -#include - -#include - -/* 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 - */ - -#include -#include -#include -#include - -#include -#include -#include - -#include - -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 #include #include +#include #include #include +#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 - */ - -#include -#include -#include - -#include - -/* 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 #include #include +#include +#include #include @@ -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<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 - */ - -#include -#include -#include - -#include - -/* 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 - */ - -#include -#include -#include -#include - -#include - -#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 - */ - -#include -#include -#include -#include - -#include - -#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 #include #include +#include #include #include +#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 - */ - -#include - -#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 - */ - -#include - -#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