From 16f70b561dd897dc324b726ebc94e0c87db26f61 Mon Sep 17 00:00:00 2001 From: John Crispin Date: Wed, 2 May 2012 12:27:36 +0200 Subject: MIPS: lantiq: clear all irqs properly on boot Due to missing brackets, the irq modules were not properly reset on boot. Signed-off-by: John Crispin Cc: linux-mips@linux-mips.org Patchwork: https://patchwork.linux-mips.org/patch/3719/ Signed-off-by: Ralf Baechle --- arch/mips/lantiq/irq.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) (limited to 'arch/mips/lantiq') diff --git a/arch/mips/lantiq/irq.c b/arch/mips/lantiq/irq.c index d673731c538a..b6b1c7260c5c 100644 --- a/arch/mips/lantiq/irq.c +++ b/arch/mips/lantiq/irq.c @@ -271,12 +271,13 @@ void __init arch_init_irq(void) if (!ltq_eiu_membase) panic("Failed to remap eiu memory"); - /* make sure all irqs are turned off by default */ - for (i = 0; i < 5; i++) + /* turn off all irqs by default */ + for (i = 0; i < 5; i++) { + /* make sure all irqs are turned off by default */ ltq_icu_w32(0, LTQ_ICU_IM0_IER + (i * LTQ_ICU_OFFSET)); - - /* clear all possibly pending interrupts */ - ltq_icu_w32(~0, LTQ_ICU_IM0_ISR + (i * LTQ_ICU_OFFSET)); + /* clear all possibly pending interrupts */ + ltq_icu_w32(~0, LTQ_ICU_IM0_ISR + (i * LTQ_ICU_OFFSET)); + } mips_cpu_irq_init(); -- cgit v1.2.2 From 59c115798430f644b43123250ae4e1d820c3c18d Mon Sep 17 00:00:00 2001 From: John Crispin Date: Wed, 2 May 2012 12:27:37 +0200 Subject: MIPS: lantiq: enable oprofile support on lantiq targets This patch sets the performance counters irq on Lantiq SoCs. Signed-off-by: John Crispin Cc: linux-mips@linux-mips.org Patchwork: https://patchwork.linux-mips.org/patch/3720/ Signed-off-by: Ralf Baechle --- arch/mips/lantiq/irq.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'arch/mips/lantiq') diff --git a/arch/mips/lantiq/irq.c b/arch/mips/lantiq/irq.c index b6b1c7260c5c..bfd4ad180aac 100644 --- a/arch/mips/lantiq/irq.c +++ b/arch/mips/lantiq/irq.c @@ -40,6 +40,9 @@ #define MAX_EIU 6 +/* the performance counter */ +#define LTQ_PERF_IRQ (INT_NUM_IM4_IRL0 + 31) + /* irqs generated by device attached to the EBU need to be acked in * a special manner */ @@ -316,6 +319,9 @@ void __init arch_init_irq(void) set_c0_status(IE_SW0 | IE_SW1 | IE_IRQ0 | IE_IRQ1 | IE_IRQ2 | IE_IRQ3 | IE_IRQ4 | IE_IRQ5); #endif + + /* tell oprofile which irq to use */ + cp0_perfcount_irq = LTQ_PERF_IRQ; } unsigned int __cpuinit get_c0_compare_int(void) -- cgit v1.2.2 From a8d096ef78c4d9a664754e1fad5e82dec2feec68 Mon Sep 17 00:00:00 2001 From: John Crispin Date: Mon, 30 Apr 2012 11:33:05 +0200 Subject: MIPS: lantiq: add ipi handlers to make vsmp work Add IPI handlers to the interrupt code. This patch makes MIPS_MT_SMP work on lantiq socs. The code is based on the malta implementation. Signed-off-by: John Crispin Cc: linux-mips@linux-mips.org Patchwork: https://patchwork.linux-mips.org/patch/3704/ Signed-off-by: Ralf Baechle --- arch/mips/lantiq/irq.c | 60 +++++++++++++++++++++++++++++++++++++++++++++++++ arch/mips/lantiq/prom.c | 5 +++++ 2 files changed, 65 insertions(+) (limited to 'arch/mips/lantiq') diff --git a/arch/mips/lantiq/irq.c b/arch/mips/lantiq/irq.c index bfd4ad180aac..d227be1c3c4d 100644 --- a/arch/mips/lantiq/irq.c +++ b/arch/mips/lantiq/irq.c @@ -54,6 +54,14 @@ #define ltq_eiu_w32(x, y) ltq_w32((x), ltq_eiu_membase + (y)) #define ltq_eiu_r32(x) ltq_r32(ltq_eiu_membase + (x)) +/* our 2 ipi interrupts for VSMP */ +#define MIPS_CPU_IPI_RESCHED_IRQ 0 +#define MIPS_CPU_IPI_CALL_IRQ 1 + +#if defined(CONFIG_MIPS_MT_SMP) || defined(CONFIG_MIPS_MT_SMTC) +int gic_present; +#endif + static unsigned short ltq_eiu_irq[MAX_EIU] = { LTQ_EIU_IR0, LTQ_EIU_IR1, @@ -219,6 +227,47 @@ static void ltq_hw5_irqdispatch(void) do_IRQ(MIPS_CPU_TIMER_IRQ); } +#ifdef CONFIG_MIPS_MT_SMP +void __init arch_init_ipiirq(int irq, struct irqaction *action) +{ + setup_irq(irq, action); + irq_set_handler(irq, handle_percpu_irq); +} + +static void ltq_sw0_irqdispatch(void) +{ + do_IRQ(MIPS_CPU_IRQ_BASE + MIPS_CPU_IPI_RESCHED_IRQ); +} + +static void ltq_sw1_irqdispatch(void) +{ + do_IRQ(MIPS_CPU_IRQ_BASE + MIPS_CPU_IPI_CALL_IRQ); +} +static irqreturn_t ipi_resched_interrupt(int irq, void *dev_id) +{ + scheduler_ipi(); + return IRQ_HANDLED; +} + +static irqreturn_t ipi_call_interrupt(int irq, void *dev_id) +{ + smp_call_function_interrupt(); + return IRQ_HANDLED; +} + +static struct irqaction irq_resched = { + .handler = ipi_resched_interrupt, + .flags = IRQF_PERCPU, + .name = "IPI_resched" +}; + +static struct irqaction irq_call = { + .handler = ipi_call_interrupt, + .flags = IRQF_PERCPU, + .name = "IPI_call" +}; +#endif + asmlinkage void plat_irq_dispatch(void) { unsigned int pending = read_c0_status() & read_c0_cause() & ST0_IM; @@ -312,6 +361,17 @@ void __init arch_init_irq(void) irq_set_chip_and_handler(i, <q_irq_type, handle_level_irq); +#if defined(CONFIG_MIPS_MT_SMP) + if (cpu_has_vint) { + pr_info("Setting up IPI vectored interrupts\n"); + set_vi_handler(MIPS_CPU_IPI_RESCHED_IRQ, ltq_sw0_irqdispatch); + set_vi_handler(MIPS_CPU_IPI_CALL_IRQ, ltq_sw1_irqdispatch); + } + arch_init_ipiirq(MIPS_CPU_IRQ_BASE + MIPS_CPU_IPI_RESCHED_IRQ, + &irq_resched); + arch_init_ipiirq(MIPS_CPU_IRQ_BASE + MIPS_CPU_IPI_CALL_IRQ, &irq_call); +#endif + #if !defined(CONFIG_MIPS_MT_SMP) && !defined(CONFIG_MIPS_MT_SMTC) set_c0_status(IE_IRQ0 | IE_IRQ1 | IE_IRQ2 | IE_IRQ3 | IE_IRQ4 | IE_IRQ5); diff --git a/arch/mips/lantiq/prom.c b/arch/mips/lantiq/prom.c index e34fcfd0d5ca..664b7b722248 100644 --- a/arch/mips/lantiq/prom.c +++ b/arch/mips/lantiq/prom.c @@ -68,4 +68,9 @@ void __init prom_init(void) soc_info.sys_type[LTQ_SYS_TYPE_LEN - 1] = '\0'; pr_info("SoC: %s\n", soc_info.sys_type); prom_init_cmdline(); + +#if defined(CONFIG_MIPS_MT_SMP) + if (register_vsmp_smp_ops()) + panic("failed to register_vsmp_smp_ops()"); +#endif } -- cgit v1.2.2 From 7705f6867bfc6f2ea42c3965a85df72abf070c86 Mon Sep 17 00:00:00 2001 From: Thomas Langer Date: Wed, 2 May 2012 12:27:38 +0200 Subject: MIPS: lantiq: fix early printk The code was using a 32bit write operations in the early_printk code. This resulted in 3 zero bytes also being written to the serial port. This patch changes the memory access to 8bit. Signed-off-by: Thomas Langer Signed-off-by: John Crispin Cc: linux-mips@linux-mips.org Patchwork: https://patchwork.linux-mips.org/patch/3721/ Signed-off-by: Ralf Baechle --- arch/mips/lantiq/early_printk.c | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) (limited to 'arch/mips/lantiq') diff --git a/arch/mips/lantiq/early_printk.c b/arch/mips/lantiq/early_printk.c index 972e05f87631..9b28d0940ef4 100644 --- a/arch/mips/lantiq/early_printk.c +++ b/arch/mips/lantiq/early_printk.c @@ -6,17 +6,16 @@ * Copyright (C) 2010 John Crispin */ -#include #include - -#include #include -/* no ioremap possible at this early stage, lets use KSEG1 instead */ -#define LTQ_ASC_BASE KSEG1ADDR(LTQ_ASC1_BASE_ADDR) #define ASC_BUF 1024 -#define LTQ_ASC_FSTAT ((u32 *)(LTQ_ASC_BASE + 0x0048)) -#define LTQ_ASC_TBUF ((u32 *)(LTQ_ASC_BASE + 0x0020)) +#define LTQ_ASC_FSTAT ((u32 *)(LTQ_EARLY_ASC + 0x0048)) +#ifdef __BIG_ENDIAN +#define LTQ_ASC_TBUF ((u32 *)(LTQ_EARLY_ASC + 0x0020 + 3)) +#else +#define LTQ_ASC_TBUF ((u32 *)(LTQ_EARLY_ASC + 0x0020)) +#endif #define TXMASK 0x3F00 #define TXOFFSET 8 @@ -27,7 +26,7 @@ void prom_putchar(char c) local_irq_save(flags); do { } while ((ltq_r32(LTQ_ASC_FSTAT) & TXMASK) >> TXOFFSET); if (c == '\n') - ltq_w32('\r', LTQ_ASC_TBUF); - ltq_w32(c, LTQ_ASC_TBUF); + ltq_w8('\r', LTQ_ASC_TBUF); + ltq_w8(c, LTQ_ASC_TBUF); local_irq_restore(flags); } -- cgit v1.2.2 From 730fa039f16df58c2dc3ff2894b7d767f100cf6e Mon Sep 17 00:00:00 2001 From: Thomas Langer Date: Wed, 2 May 2012 12:27:39 +0200 Subject: MIPS: lantiq: fix cmdline parsing The code tested if the KSEG1 mapped address of argv was != 0. We need to use CPHYSADDR instead to make the conditional actually work. Signed-off-by: Thomas Langer Signed-off-by: John Crispin Cc: linux-mips@linux-mips.org Patchwork: https://patchwork.linux-mips.org/patch/3722/ Signed-off-by: Ralf Baechle --- arch/mips/lantiq/prom.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'arch/mips/lantiq') diff --git a/arch/mips/lantiq/prom.c b/arch/mips/lantiq/prom.c index 664b7b722248..cd568921f191 100644 --- a/arch/mips/lantiq/prom.c +++ b/arch/mips/lantiq/prom.c @@ -45,10 +45,12 @@ static void __init prom_init_cmdline(void) char **argv = (char **) KSEG1ADDR(fw_arg1); int i; + arcs_cmdline[0] = '\0'; + for (i = 0; i < argc; i++) { - char *p = (char *) KSEG1ADDR(argv[i]); + char *p = (char *) KSEG1ADDR(argv[i]); - if (p && *p) { + if (CPHYSADDR(p) && *p) { strlcat(arcs_cmdline, p, sizeof(arcs_cmdline)); strlcat(arcs_cmdline, " ", sizeof(arcs_cmdline)); } -- cgit v1.2.2 From 215ed2009c83615896ee060c08fe574894f084a6 Mon Sep 17 00:00:00 2001 From: John Crispin Date: Mon, 30 Apr 2012 11:33:08 +0200 Subject: MIPS: lantiq: add xway soc ids Add the soc ids for additional xway socs. The patch also merges the amazon_se code with the other socs. Signed-off-by: John Crispin Cc: linux-mips@linux-mips.org Patchwork: https://patchwork.linux-mips.org/patch/3707/ Signed-off-by: Ralf Baechle --- arch/mips/lantiq/prom.h | 5 ++ arch/mips/lantiq/xway/Makefile | 6 +- arch/mips/lantiq/xway/prom-ase.c | 39 ------------- arch/mips/lantiq/xway/prom-xway.c | 54 ------------------ arch/mips/lantiq/xway/prom.c | 115 ++++++++++++++++++++++++++++++++++++++ 5 files changed, 123 insertions(+), 96 deletions(-) delete mode 100644 arch/mips/lantiq/xway/prom-ase.c delete mode 100644 arch/mips/lantiq/xway/prom-xway.c create mode 100644 arch/mips/lantiq/xway/prom.c (limited to 'arch/mips/lantiq') diff --git a/arch/mips/lantiq/prom.h b/arch/mips/lantiq/prom.h index b4229d94280f..90070a54adbe 100644 --- a/arch/mips/lantiq/prom.h +++ b/arch/mips/lantiq/prom.h @@ -10,16 +10,21 @@ #define _LTQ_PROM_H__ #define LTQ_SYS_TYPE_LEN 0x100 +#define LTQ_SYS_REV_LEN 0x10 struct ltq_soc_info { unsigned char *name; unsigned int rev; + unsigned char rev_type[LTQ_SYS_REV_LEN]; + unsigned int srev; unsigned int partnum; unsigned int type; unsigned char sys_type[LTQ_SYS_TYPE_LEN]; + unsigned char *compatible; }; extern void ltq_soc_detect(struct ltq_soc_info *i); extern void ltq_soc_setup(void); +extern void ltq_soc_init(void); #endif diff --git a/arch/mips/lantiq/xway/Makefile b/arch/mips/lantiq/xway/Makefile index c517f2e77563..42d5fda4f5c6 100644 --- a/arch/mips/lantiq/xway/Makefile +++ b/arch/mips/lantiq/xway/Makefile @@ -1,7 +1,7 @@ -obj-y := pmu.o ebu.o reset.o gpio.o gpio_stp.o gpio_ebu.o devices.o dma.o +obj-y := prom.o 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-$(CONFIG_SOC_XWAY) += clk-xway.o setup-xway.o +obj-$(CONFIG_SOC_AMAZON_SE) += clk-ase.o setup-ase.o obj-$(CONFIG_LANTIQ_MACH_EASY50712) += mach-easy50712.o obj-$(CONFIG_LANTIQ_MACH_EASY50601) += mach-easy50601.o diff --git a/arch/mips/lantiq/xway/prom-ase.c b/arch/mips/lantiq/xway/prom-ase.c deleted file mode 100644 index ae4959ae865c..000000000000 --- 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 2228133ca356..000000000000 --- 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/prom.c b/arch/mips/lantiq/xway/prom.c new file mode 100644 index 000000000000..248429ab2622 --- /dev/null +++ b/arch/mips/lantiq/xway/prom.c @@ -0,0 +1,115 @@ +/* + * 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_AMAZON_SE "Amazon_SE" +#define SOC_AR9 "AR9" +#define SOC_GR9 "GR9" +#define SOC_VR9 "VR9" + +#define COMP_DANUBE "lantiq,danube" +#define COMP_TWINPASS "lantiq,twinpass" +#define COMP_AMAZON_SE "lantiq,ase" +#define COMP_AR9 "lantiq,ar9" +#define COMP_GR9 "lantiq,gr9" +#define COMP_VR9 "lantiq,vr9" + +#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; + sprintf(i->rev_type, "1.%d", i->rev); + switch (i->partnum) { + case SOC_ID_DANUBE1: + case SOC_ID_DANUBE2: + i->name = SOC_DANUBE; + i->type = SOC_TYPE_DANUBE; + i->compatible = COMP_DANUBE; + break; + + case SOC_ID_TWINPASS: + i->name = SOC_TWINPASS; + i->type = SOC_TYPE_DANUBE; + i->compatible = COMP_TWINPASS; + break; + + case SOC_ID_ARX188: + case SOC_ID_ARX168_1: + case SOC_ID_ARX168_2: + case SOC_ID_ARX182: + i->name = SOC_AR9; + i->type = SOC_TYPE_AR9; + i->compatible = COMP_AR9; + break; + + case SOC_ID_GRX188: + case SOC_ID_GRX168: + i->name = SOC_GR9; + i->type = SOC_TYPE_AR9; + i->compatible = COMP_GR9; + break; + + case SOC_ID_AMAZON_SE_1: + case SOC_ID_AMAZON_SE_2: +#ifdef CONFIG_PCI + panic("ase is only supported for non pci kernels"); +#endif + i->name = SOC_AMAZON_SE; + i->type = SOC_TYPE_AMAZON_SE; + i->compatible = COMP_AMAZON_SE; + break; + + case SOC_ID_VRX282: + case SOC_ID_VRX268: + case SOC_ID_VRX288: + i->name = SOC_VR9; + i->type = SOC_TYPE_VR9; + i->compatible = COMP_VR9; + break; + + case SOC_ID_GRX268: + case SOC_ID_GRX288: + i->name = SOC_GR9; + i->type = SOC_TYPE_VR9; + i->compatible = COMP_GR9; + break; + + case SOC_ID_VRX268_2: + case SOC_ID_VRX288_2: + i->name = SOC_VR9; + i->type = SOC_TYPE_VR9_2; + i->compatible = COMP_VR9; + break; + + case SOC_ID_GRX282_2: + case SOC_ID_GRX288_2: + i->name = SOC_GR9; + i->type = SOC_TYPE_VR9_2; + i->compatible = COMP_GR9; + break; + + default: + unreachable(); + break; + } +} -- cgit v1.2.2 From 6697c6933048aabe94f0049070f7ec09cd52baa8 Mon Sep 17 00:00:00 2001 From: John Crispin Date: Mon, 30 Apr 2012 11:33:09 +0200 Subject: MIPS: lantiq: cleanup reset code Add 2 new soc specifc handlers and remove superflous pr_notice calls. Signed-off-by: John Crispin Cc: linux-mips@linux-mips.org Patchwork: https://patchwork.linux-mips.org/patch/3705/ Signed-off-by: Ralf Baechle --- arch/mips/lantiq/xway/reset.c | 48 ++++++++++++++++++++++++++++++++----------- 1 file changed, 36 insertions(+), 12 deletions(-) (limited to 'arch/mips/lantiq') diff --git a/arch/mips/lantiq/xway/reset.c b/arch/mips/lantiq/xway/reset.c index 8b66bd87f0c1..3327211746ac 100644 --- a/arch/mips/lantiq/xway/reset.c +++ b/arch/mips/lantiq/xway/reset.c @@ -11,19 +11,31 @@ #include #include #include +#include +#include +#include + #include #include +#include "../prom.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 +/* reset request register */ +#define RCU_RST_REQ 0x0010 +/* reset status register */ +#define RCU_RST_STAT 0x0014 -#define LTQ_RCU_RST_STAT 0x0014 -#define LTQ_RCU_STAT_SHIFT 26 +/* reboot bit */ +#define RCU_RD_SRST BIT(30) +/* reset cause */ +#define RCU_STAT_SHIFT 26 +/* boot selection */ +#define RCU_BOOT_SEL_SHIFT 26 +#define RCU_BOOT_SEL_MASK 0x7 static struct resource ltq_rcu_resource = { .name = "rcu", @@ -38,29 +50,41 @@ 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); +/* allow platform code to find out what source we booted from */ +unsigned char ltq_boot_select(void) +{ + u32 val = ltq_rcu_r32(RCU_RST_STAT); + return (val >> RCU_BOOT_SEL_SHIFT) & RCU_BOOT_SEL_MASK; +} + +/* 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); + udelay(u); + 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(); } static void ltq_machine_halt(void) { - pr_notice("System halted.\n"); local_irq_disable(); unreachable(); } static void ltq_machine_power_off(void) { - pr_notice("Please turn off the power now.\n"); local_irq_disable(); unreachable(); } @@ -79,7 +103,7 @@ static int __init mips_reboot_setup(void) ltq_rcu_membase = ioremap_nocache(ltq_rcu_resource.start, resource_size(<q_rcu_resource)); if (!ltq_rcu_membase) - panic("Failed to remap rcu memory"); + panic("Failed to remap core memory"); _machine_restart = ltq_machine_restart; _machine_halt = ltq_machine_halt; -- cgit v1.2.2 From cd93b4895ea51dcd15c96801aa21e71f793e3af3 Mon Sep 17 00:00:00 2001 From: John Crispin Date: Fri, 13 Apr 2012 17:19:42 +0200 Subject: MIPS: lantiq: drop mips_machine support Before we are able to add OF support, we really want to drop all the bloat needed to register all the platform devices. Signed-off-by: John Crispin Cc: linux-mips@linux-mips.org Patchwork: https://patchwork.linux-mips.org/patch/3800/ Signed-off-by: Ralf Baechle --- arch/mips/lantiq/Kconfig | 2 - arch/mips/lantiq/Makefile | 2 +- arch/mips/lantiq/devices.c | 120 --------------------------------- arch/mips/lantiq/devices.h | 23 ------- arch/mips/lantiq/machtypes.h | 20 ------ arch/mips/lantiq/prom.h | 1 - arch/mips/lantiq/setup.c | 23 ------- arch/mips/lantiq/xway/Kconfig | 23 ------- arch/mips/lantiq/xway/Makefile | 9 +-- arch/mips/lantiq/xway/devices.c | 119 -------------------------------- arch/mips/lantiq/xway/devices.h | 20 ------ arch/mips/lantiq/xway/mach-easy50601.c | 57 ---------------- arch/mips/lantiq/xway/mach-easy50712.c | 74 -------------------- arch/mips/lantiq/xway/setup-ase.c | 19 ------ arch/mips/lantiq/xway/setup-xway.c | 20 ------ 15 files changed, 4 insertions(+), 528 deletions(-) delete mode 100644 arch/mips/lantiq/devices.c delete mode 100644 arch/mips/lantiq/devices.h delete mode 100644 arch/mips/lantiq/machtypes.h delete mode 100644 arch/mips/lantiq/xway/Kconfig delete mode 100644 arch/mips/lantiq/xway/devices.c delete mode 100644 arch/mips/lantiq/xway/devices.h delete mode 100644 arch/mips/lantiq/xway/mach-easy50601.c delete mode 100644 arch/mips/lantiq/xway/mach-easy50712.c delete mode 100644 arch/mips/lantiq/xway/setup-ase.c delete mode 100644 arch/mips/lantiq/xway/setup-xway.c (limited to 'arch/mips/lantiq') diff --git a/arch/mips/lantiq/Kconfig b/arch/mips/lantiq/Kconfig index 3fccf2104513..2780461e3258 100644 --- a/arch/mips/lantiq/Kconfig +++ b/arch/mips/lantiq/Kconfig @@ -18,6 +18,4 @@ config SOC_XWAY select HW_HAS_PCI endchoice -source "arch/mips/lantiq/xway/Kconfig" - endif diff --git a/arch/mips/lantiq/Makefile b/arch/mips/lantiq/Makefile index e5dae0e24b00..a268391eb45e 100644 --- a/arch/mips/lantiq/Makefile +++ b/arch/mips/lantiq/Makefile @@ -4,7 +4,7 @@ # under the terms of the GNU General Public License version 2 as published # by the Free Software Foundation. -obj-y := irq.o setup.o clk.o prom.o devices.o +obj-y := irq.o setup.o clk.o prom.o obj-$(CONFIG_EARLY_PRINTK) += early_printk.o diff --git a/arch/mips/lantiq/devices.c b/arch/mips/lantiq/devices.c deleted file mode 100644 index de1cb2bcd79a..000000000000 --- a/arch/mips/lantiq/devices.c +++ /dev/null @@ -1,120 +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 -#include -#include -#include -#include - -#include -#include - -#include - -#include "devices.h" - -/* nor flash */ -static struct resource ltq_nor_resource = { - .name = "nor", - .start = LTQ_FLASH_START, - .end = LTQ_FLASH_START + LTQ_FLASH_MAX - 1, - .flags = IORESOURCE_MEM, -}; - -static struct platform_device ltq_nor = { - .name = "ltq_nor", - .resource = <q_nor_resource, - .num_resources = 1, -}; - -void __init ltq_register_nor(struct physmap_flash_data *data) -{ - ltq_nor.dev.platform_data = data; - platform_device_register(<q_nor); -} - -/* watchdog */ -static struct resource ltq_wdt_resource = { - .name = "watchdog", - .start = LTQ_WDT_BASE_ADDR, - .end = LTQ_WDT_BASE_ADDR + LTQ_WDT_SIZE - 1, - .flags = IORESOURCE_MEM, -}; - -void __init ltq_register_wdt(void) -{ - platform_device_register_simple("ltq_wdt", 0, <q_wdt_resource, 1); -} - -/* asc ports */ -static struct resource ltq_asc0_resources[] = { - { - .name = "asc0", - .start = LTQ_ASC0_BASE_ADDR, - .end = LTQ_ASC0_BASE_ADDR + LTQ_ASC_SIZE - 1, - .flags = IORESOURCE_MEM, - }, - IRQ_RES(tx, LTQ_ASC_TIR(0)), - IRQ_RES(rx, LTQ_ASC_RIR(0)), - IRQ_RES(err, LTQ_ASC_EIR(0)), -}; - -static struct resource ltq_asc1_resources[] = { - { - .name = "asc1", - .start = LTQ_ASC1_BASE_ADDR, - .end = LTQ_ASC1_BASE_ADDR + LTQ_ASC_SIZE - 1, - .flags = IORESOURCE_MEM, - }, - IRQ_RES(tx, LTQ_ASC_TIR(1)), - IRQ_RES(rx, LTQ_ASC_RIR(1)), - IRQ_RES(err, LTQ_ASC_EIR(1)), -}; - -void __init ltq_register_asc(int port) -{ - switch (port) { - case 0: - platform_device_register_simple("ltq_asc", 0, - ltq_asc0_resources, ARRAY_SIZE(ltq_asc0_resources)); - break; - case 1: - platform_device_register_simple("ltq_asc", 1, - ltq_asc1_resources, ARRAY_SIZE(ltq_asc1_resources)); - break; - default: - break; - } -} - -#ifdef CONFIG_PCI -/* pci */ -static struct platform_device ltq_pci = { - .name = "ltq_pci", - .num_resources = 0, -}; - -void __init ltq_register_pci(struct ltq_pci_data *data) -{ - ltq_pci.dev.platform_data = data; - platform_device_register(<q_pci); -} -#else -void __init ltq_register_pci(struct ltq_pci_data *data) -{ - pr_err("kernel is compiled without PCI support\n"); -} -#endif diff --git a/arch/mips/lantiq/devices.h b/arch/mips/lantiq/devices.h deleted file mode 100644 index 2947bb19a528..000000000000 --- a/arch/mips/lantiq/devices.h +++ /dev/null @@ -1,23 +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 - */ - -#ifndef _LTQ_DEVICES_H__ -#define _LTQ_DEVICES_H__ - -#include -#include - -#define IRQ_RES(resname, irq) \ - {.name = #resname, .start = (irq), .flags = IORESOURCE_IRQ} - -extern void ltq_register_nor(struct physmap_flash_data *data); -extern void ltq_register_wdt(void); -extern void ltq_register_asc(int port); -extern void ltq_register_pci(struct ltq_pci_data *data); - -#endif diff --git a/arch/mips/lantiq/machtypes.h b/arch/mips/lantiq/machtypes.h deleted file mode 100644 index 7e01b8c484eb..000000000000 --- a/arch/mips/lantiq/machtypes.h +++ /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) 2010 John Crispin - */ - -#ifndef _LANTIQ_MACH_H__ -#define _LANTIQ_MACH_H__ - -#include - -enum lantiq_mach_type { - LTQ_MACH_GENERIC = 0, - LTQ_MACH_EASY50712, /* Danube evaluation board */ - LTQ_MACH_EASY50601, /* Amazon SE evaluation board */ -}; - -#endif diff --git a/arch/mips/lantiq/prom.h b/arch/mips/lantiq/prom.h index 90070a54adbe..f7c2a7984db7 100644 --- a/arch/mips/lantiq/prom.h +++ b/arch/mips/lantiq/prom.h @@ -24,7 +24,6 @@ struct ltq_soc_info { }; extern void ltq_soc_detect(struct ltq_soc_info *i); -extern void ltq_soc_setup(void); extern void ltq_soc_init(void); #endif diff --git a/arch/mips/lantiq/setup.c b/arch/mips/lantiq/setup.c index 1ff6c9d6cb93..f1c605ab8081 100644 --- a/arch/mips/lantiq/setup.c +++ b/arch/mips/lantiq/setup.c @@ -14,8 +14,6 @@ #include -#include "machtypes.h" -#include "devices.h" #include "prom.h" void __init plat_mem_setup(void) @@ -43,24 +41,3 @@ void __init plat_mem_setup(void) memsize *= 1024 * 1024; add_memory_region(0x00000000, memsize, BOOT_MEM_RAM); } - -static int __init -lantiq_setup(void) -{ - ltq_soc_setup(); - mips_machine_setup(); - return 0; -} - -arch_initcall(lantiq_setup); - -static void __init -lantiq_generic_init(void) -{ - /* Nothing to do */ -} - -MIPS_MACHINE(LTQ_MACH_GENERIC, - "Generic", - "Generic Lantiq based board", - lantiq_generic_init); diff --git a/arch/mips/lantiq/xway/Kconfig b/arch/mips/lantiq/xway/Kconfig deleted file mode 100644 index 2b857de36620..000000000000 --- a/arch/mips/lantiq/xway/Kconfig +++ /dev/null @@ -1,23 +0,0 @@ -if SOC_XWAY - -menu "MIPS Machine" - -config LANTIQ_MACH_EASY50712 - bool "Easy50712 - Danube" - default y - -endmenu - -endif - -if SOC_AMAZON_SE - -menu "MIPS Machine" - -config LANTIQ_MACH_EASY50601 - bool "Easy50601 - Amazon SE" - default y - -endmenu - -endif diff --git a/arch/mips/lantiq/xway/Makefile b/arch/mips/lantiq/xway/Makefile index 42d5fda4f5c6..7a6c30f672f4 100644 --- a/arch/mips/lantiq/xway/Makefile +++ b/arch/mips/lantiq/xway/Makefile @@ -1,7 +1,4 @@ -obj-y := prom.o pmu.o ebu.o reset.o gpio.o gpio_stp.o gpio_ebu.o devices.o dma.o +obj-y := prom.o pmu.o ebu.o reset.o gpio.o gpio_stp.o gpio_ebu.o dma.o -obj-$(CONFIG_SOC_XWAY) += clk-xway.o setup-xway.o -obj-$(CONFIG_SOC_AMAZON_SE) += clk-ase.o setup-ase.o - -obj-$(CONFIG_LANTIQ_MACH_EASY50712) += mach-easy50712.o -obj-$(CONFIG_LANTIQ_MACH_EASY50601) += mach-easy50601.o +obj-$(CONFIG_SOC_XWAY) += clk-xway.o +obj-$(CONFIG_SOC_AMAZON_SE) += clk-ase.o diff --git a/arch/mips/lantiq/xway/devices.c b/arch/mips/lantiq/xway/devices.c deleted file mode 100644 index d614aa7ff07f..000000000000 --- a/arch/mips/lantiq/xway/devices.c +++ /dev/null @@ -1,119 +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 -#include -#include -#include -#include -#include - -#include -#include - -#include -#include -#include - -#include "devices.h" - -/* 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, - } -}; - -void __init ltq_register_gpio(void) -{ - platform_device_register_simple("ltq_gpio", 0, - <q_gpio_resource[0], 1); - platform_device_register_simple("ltq_gpio", 1, - <q_gpio_resource[1], 1); - - /* AR9 and VR9 have an extra gpio block */ - if (ltq_is_ar9() || ltq_is_vr9()) { - platform_device_register_simple("ltq_gpio", 2, - <q_gpio_resource[2], 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, -}; - -void __init ltq_register_gpio_stp(void) -{ - platform_device_register_simple("ltq_stp", 0, <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, - }, - IRQ_RES(tx, LTQ_ASC_ASE_TIR), - IRQ_RES(rx, LTQ_ASC_ASE_RIR), - IRQ_RES(err, LTQ_ASC_ASE_EIR), -}; - -void __init ltq_register_ase_asc(void) -{ - platform_device_register_simple("ltq_asc", 0, - ltq_ase_asc_resources, ARRAY_SIZE(ltq_ase_asc_resources)); -} - -/* 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 platform_device ltq_etop = { - .name = "ltq_etop", - .resource = <q_etop_resources, - .num_resources = 1, -}; - -void __init -ltq_register_etop(struct ltq_eth_data *eth) -{ - if (eth) { - ltq_etop.dev.platform_data = eth; - platform_device_register(<q_etop); - } -} diff --git a/arch/mips/lantiq/xway/devices.h b/arch/mips/lantiq/xway/devices.h deleted file mode 100644 index e90493471bc1..000000000000 --- a/arch/mips/lantiq/xway/devices.h +++ /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) 2010 John Crispin - */ - -#ifndef _LTQ_DEVICES_XWAY_H__ -#define _LTQ_DEVICES_XWAY_H__ - -#include "../devices.h" -#include - -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); - -#endif diff --git a/arch/mips/lantiq/xway/mach-easy50601.c b/arch/mips/lantiq/xway/mach-easy50601.c deleted file mode 100644 index d5aaf637ab19..000000000000 --- a/arch/mips/lantiq/xway/mach-easy50601.c +++ /dev/null @@ -1,57 +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 "../machtypes.h" -#include "devices.h" - -static struct mtd_partition easy50601_partitions[] = { - { - .name = "uboot", - .offset = 0x0, - .size = 0x10000, - }, - { - .name = "uboot_env", - .offset = 0x10000, - .size = 0x10000, - }, - { - .name = "linux", - .offset = 0x20000, - .size = 0xE0000, - }, - { - .name = "rootfs", - .offset = 0x100000, - .size = 0x300000, - }, -}; - -static struct physmap_flash_data easy50601_flash_data = { - .nr_parts = ARRAY_SIZE(easy50601_partitions), - .parts = easy50601_partitions, -}; - -static void __init easy50601_init(void) -{ - ltq_register_nor(&easy50601_flash_data); -} - -MIPS_MACHINE(LTQ_MACH_EASY50601, - "EASY50601", - "EASY50601 Eval Board", - easy50601_init); diff --git a/arch/mips/lantiq/xway/mach-easy50712.c b/arch/mips/lantiq/xway/mach-easy50712.c deleted file mode 100644 index ea5027b3239d..000000000000 --- a/arch/mips/lantiq/xway/mach-easy50712.c +++ /dev/null @@ -1,74 +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 -#include - -#include "../machtypes.h" -#include "devices.h" - -static struct mtd_partition easy50712_partitions[] = { - { - .name = "uboot", - .offset = 0x0, - .size = 0x10000, - }, - { - .name = "uboot_env", - .offset = 0x10000, - .size = 0x10000, - }, - { - .name = "linux", - .offset = 0x20000, - .size = 0xe0000, - }, - { - .name = "rootfs", - .offset = 0x100000, - .size = 0x300000, - }, -}; - -static struct physmap_flash_data easy50712_flash_data = { - .nr_parts = ARRAY_SIZE(easy50712_partitions), - .parts = easy50712_partitions, -}; - -static struct ltq_pci_data ltq_pci_data = { - .clock = PCI_CLOCK_INT, - .gpio = PCI_GNT1 | PCI_REQ1, - .irq = { - [14] = INT_NUM_IM0_IRL0 + 22, - }, -}; - -static struct ltq_eth_data ltq_eth_data = { - .mii_mode = PHY_INTERFACE_MODE_MII, -}; - -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); -} - -MIPS_MACHINE(LTQ_MACH_EASY50712, - "EASY50712", - "EASY50712 Eval Board", - easy50712_init); diff --git a/arch/mips/lantiq/xway/setup-ase.c b/arch/mips/lantiq/xway/setup-ase.c deleted file mode 100644 index f6f326798a39..000000000000 --- 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 c292f643a858..000000000000 --- 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(); -} -- cgit v1.2.2 From a0392222d9a374588803454c4d2211108c64d4e4 Mon Sep 17 00:00:00 2001 From: John Crispin Date: Fri, 13 Apr 2012 20:56:13 +0200 Subject: OF: MIPS: lantiq: implement OF support Activate USE_OF, add a sample DTS file and convert the core soc code to OF. Signed-off-by: John Crispin Cc: linux-mips@linux-mips.org Cc: devicetree-discuss@lists.ozlabs.org Cc: linux-mips@linux-mips.org Patchwork: https://patchwork.linux-mips.org/patch/3803/ Signed-off-by: Ralf Baechle --- arch/mips/lantiq/Kconfig | 9 +++ arch/mips/lantiq/Makefile | 4 +- arch/mips/lantiq/dts/Makefile | 4 ++ arch/mips/lantiq/dts/danube.dtsi | 105 ++++++++++++++++++++++++++++++++++ arch/mips/lantiq/dts/easy50712.dts | 113 +++++++++++++++++++++++++++++++++++++ arch/mips/lantiq/prom.c | 57 ++++++++++++++----- arch/mips/lantiq/prom.h | 2 + arch/mips/lantiq/setup.c | 43 -------------- arch/mips/lantiq/xway/ebu.c | 4 -- arch/mips/lantiq/xway/reset.c | 29 +++++----- 10 files changed, 293 insertions(+), 77 deletions(-) create mode 100644 arch/mips/lantiq/dts/Makefile create mode 100644 arch/mips/lantiq/dts/danube.dtsi create mode 100644 arch/mips/lantiq/dts/easy50712.dts delete mode 100644 arch/mips/lantiq/setup.c (limited to 'arch/mips/lantiq') diff --git a/arch/mips/lantiq/Kconfig b/arch/mips/lantiq/Kconfig index 2780461e3258..9485fe54752b 100644 --- a/arch/mips/lantiq/Kconfig +++ b/arch/mips/lantiq/Kconfig @@ -18,4 +18,13 @@ config SOC_XWAY select HW_HAS_PCI endchoice + +choice + prompt "Devicetree" + +config DT_EASY50712 + bool "Easy50712" + depends on SOC_XWAY +endchoice + endif diff --git a/arch/mips/lantiq/Makefile b/arch/mips/lantiq/Makefile index a268391eb45e..16f1c758616b 100644 --- a/arch/mips/lantiq/Makefile +++ b/arch/mips/lantiq/Makefile @@ -4,7 +4,9 @@ # under the terms of the GNU General Public License version 2 as published # by the Free Software Foundation. -obj-y := irq.o setup.o clk.o prom.o +obj-y := irq.o clk.o prom.o + +obj-y += dts/ obj-$(CONFIG_EARLY_PRINTK) += early_printk.o diff --git a/arch/mips/lantiq/dts/Makefile b/arch/mips/lantiq/dts/Makefile new file mode 100644 index 000000000000..674fca45f72d --- /dev/null +++ b/arch/mips/lantiq/dts/Makefile @@ -0,0 +1,4 @@ +obj-$(CONFIG_DT_EASY50712) := easy50712.dtb.o + +$(obj)/%.dtb: $(obj)/%.dts + $(call if_changed,dtc) diff --git a/arch/mips/lantiq/dts/danube.dtsi b/arch/mips/lantiq/dts/danube.dtsi new file mode 100644 index 000000000000..3a4520f009cf --- /dev/null +++ b/arch/mips/lantiq/dts/danube.dtsi @@ -0,0 +1,105 @@ +/ { + #address-cells = <1>; + #size-cells = <1>; + compatible = "lantiq,xway", "lantiq,danube"; + + cpus { + cpu@0 { + compatible = "mips,mips24Kc"; + }; + }; + + 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 0x120>; + }; + + 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 { + #interrupt-cells = <1>; + interrupt-controller; + interrupt-parent; + compatible = "lantiq,eiu-xway"; + reg = <0x101000 0x1000>; + }; + + 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>; + }; + }; + + 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>; + }; + + 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 */ + }; + }; +}; diff --git a/arch/mips/lantiq/dts/easy50712.dts b/arch/mips/lantiq/dts/easy50712.dts new file mode 100644 index 000000000000..68c17310bc82 --- /dev/null +++ b/arch/mips/lantiq/dts/easy50712.dts @@ -0,0 +1,113 @@ +/dts-v1/; + +/include/ "danube.dtsi" + +/ { + chosen { + bootargs = "console=ttyLTQ0,115200 init=/etc/preinit"; + }; + + memory@0 { + reg = <0x0 0x2000000>; + }; + + fpi@10000000 { + #address-cells = <1>; + #size-cells = <1>; + localbus@0 { + #address-cells = <2>; + #size-cells = <1>; + ranges = <0 0 0x0 0x3ffffff /* addrsel0 */ + 1 0 0x4000000 0x4000010>; /* addsel1 */ + compatible = "lantiq,localbus", "simple-bus"; + + 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>; /* 64 KB */ + }; + + partition@10000 { + label = "uboot_env"; + reg = <0x10000 0x10000>; /* 64 KB */ + }; + + partition@20000 { + label = "linux"; + reg = <0x20000 0x3d0000>; + }; + + partition@400000 { + label = "rootfs"; + reg = <0x400000 0x400000>; + }; + }; + }; + + 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"; + }; + exin { + lantiq,groups = "exin1"; + lantiq,function = "exin"; + }; + pci { + lantiq,groups = "gnt1"; + lantiq,function = "pci"; + }; + conf_out { + lantiq,pins = "io4", "io5", "io6"; /* stp */ + lantiq,open-drain; + lantiq,pull = <0>; + }; + }; + }; + + etop@E180000 { + compatible = "lantiq,etop-xway"; + reg = <0xE180000 0x40000>; + interrupt-parent = <&icu0>; + interrupts = <73 78>; + phy-mode = "rmii"; + mac-address = [ 00 11 22 33 44 55 ]; + }; + + stp0: stp@E100BB0 { + #gpio-cells = <2>; + compatible = "lantiq,gpio-stp-xway"; + gpio-controller; + reg = <0xE100BB0 0x40>; + + lantiq,shadow = <0xfff>; + lantiq,groups = <0x3>; + }; + + pci@E105400 { + lantiq,bus-clock = <33333333>; + 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 */ + }; + + }; +}; diff --git a/arch/mips/lantiq/prom.c b/arch/mips/lantiq/prom.c index cd568921f191..413ed53a4ae1 100644 --- a/arch/mips/lantiq/prom.c +++ b/arch/mips/lantiq/prom.c @@ -8,6 +8,7 @@ #include #include +#include #include #include @@ -16,13 +17,15 @@ #include "prom.h" #include "clk.h" -static struct ltq_soc_info soc_info; +/* access to the ebu needs to be locked between different drivers */ +DEFINE_SPINLOCK(ebu_lock); +EXPORT_SYMBOL_GPL(ebu_lock); -unsigned int ltq_get_cpu_ver(void) -{ - return soc_info.rev; -} -EXPORT_SYMBOL(ltq_get_cpu_ver); +/* + * this struct is filled by the soc specific detection code and holds + * information about the specific soc type, revision and name + */ +static struct ltq_soc_info soc_info; unsigned int ltq_get_soc_type(void) { @@ -57,16 +60,28 @@ static void __init prom_init_cmdline(void) } } -void __init prom_init(void) +void __init plat_mem_setup(void) { - struct clk *clk; + ioport_resource.start = IOPORT_RESOURCE_START; + ioport_resource.end = IOPORT_RESOURCE_END; + iomem_resource.start = IOMEM_RESOURCE_START; + iomem_resource.end = IOMEM_RESOURCE_END; + + set_io_port_base((unsigned long) KSEG1); + + /* + * Load the builtin devicetree. This causes the chosen node to be + * parsed resulting in our memory appearing + */ + __dt_setup_arch(&__dtb_start); +} +void __init prom_init(void) +{ + /* call the soc specific detetcion code and get it to fill soc_info */ ltq_soc_detect(&soc_info); - clk_init(); - clk = clk_get(0, "cpu"); - snprintf(soc_info.sys_type, LTQ_SYS_TYPE_LEN - 1, "%s rev1.%d", - soc_info.name, soc_info.rev); - clk_put(clk); + snprintf(soc_info.sys_type, LTQ_SYS_TYPE_LEN - 1, "%s rev %s", + soc_info.name, soc_info.rev_type); soc_info.sys_type[LTQ_SYS_TYPE_LEN - 1] = '\0'; pr_info("SoC: %s\n", soc_info.sys_type); prom_init_cmdline(); @@ -76,3 +91,19 @@ void __init prom_init(void) panic("failed to register_vsmp_smp_ops()"); #endif } + +int __init plat_of_setup(void) +{ + static struct of_device_id of_ids[3]; + + if (!of_have_populated_dt()) + panic("device tree not present"); + + strncpy(of_ids[0].compatible, soc_info.compatible, + 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); +} + +arch_initcall(plat_of_setup); diff --git a/arch/mips/lantiq/prom.h b/arch/mips/lantiq/prom.h index f7c2a7984db7..a3fa1a2bfaae 100644 --- a/arch/mips/lantiq/prom.h +++ b/arch/mips/lantiq/prom.h @@ -26,4 +26,6 @@ struct ltq_soc_info { extern void ltq_soc_detect(struct ltq_soc_info *i); extern void ltq_soc_init(void); +extern struct boot_param_header __dtb_start; + #endif diff --git a/arch/mips/lantiq/setup.c b/arch/mips/lantiq/setup.c deleted file mode 100644 index f1c605ab8081..000000000000 --- a/arch/mips/lantiq/setup.c +++ /dev/null @@ -1,43 +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 "prom.h" - -void __init plat_mem_setup(void) -{ - /* assume 16M as default incase uboot fails to pass proper ramsize */ - unsigned long memsize = 16; - char **envp = (char **) KSEG1ADDR(fw_arg2); - - ioport_resource.start = IOPORT_RESOURCE_START; - ioport_resource.end = IOPORT_RESOURCE_END; - iomem_resource.start = IOMEM_RESOURCE_START; - iomem_resource.end = IOMEM_RESOURCE_END; - - set_io_port_base((unsigned long) KSEG1); - - while (*envp) { - char *e = (char *)KSEG1ADDR(*envp); - if (!strncmp(e, "memsize=", 8)) { - e += 8; - if (strict_strtoul(e, 0, &memsize)) - pr_warn("bad memsize specified\n"); - } - envp++; - } - memsize *= 1024 * 1024; - add_memory_region(0x00000000, memsize, BOOT_MEM_RAM); -} diff --git a/arch/mips/lantiq/xway/ebu.c b/arch/mips/lantiq/xway/ebu.c index 862e3e830680..419b47b70f32 100644 --- a/arch/mips/lantiq/xway/ebu.c +++ b/arch/mips/lantiq/xway/ebu.c @@ -14,10 +14,6 @@ #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, diff --git a/arch/mips/lantiq/xway/reset.c b/arch/mips/lantiq/xway/reset.c index 3327211746ac..22c55f73aa9d 100644 --- a/arch/mips/lantiq/xway/reset.c +++ b/arch/mips/lantiq/xway/reset.c @@ -37,13 +37,6 @@ #define RCU_BOOT_SEL_SHIFT 26 #define RCU_BOOT_SEL_MASK 0x7 -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, -}; - /* remapped base addr of the reset control unit */ static void __iomem *ltq_rcu_membase; @@ -91,17 +84,21 @@ 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"); + struct resource res; + struct device_node *np = + of_find_compatible_node(NULL, NULL, "lantiq,rcu-xway"); + + /* check if all the reset register range is available */ + if (!np) + panic("Failed to load reset resources from devicetree"); + + if (of_address_to_resource(np, 0, &res)) + panic("Failed to get rcu memory range"); - if (request_mem_region(ltq_rcu_resource.start, - resource_size(<q_rcu_resource), "rcu") < 0) - panic("Failed to request rcu memory"); + if (request_mem_region(res.start, resource_size(&res), res.name) < 0) + pr_err("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 = ioremap_nocache(res.start, resource_size(&res)); if (!ltq_rcu_membase) panic("Failed to remap core memory"); -- cgit v1.2.2 From 3645da0276ae9f6938ff29b13904b803ecb68424 Mon Sep 17 00:00:00 2001 From: John Crispin Date: Tue, 17 Apr 2012 10:18:32 +0200 Subject: OF: MIPS: lantiq: implement irq_domain support Add support for irq_domain on lantiq socs. The conversion is straight forward as the ICU found inside the socs allows the usage of irq_domain_add_linear. Harware IRQ 0->7 are the generic MIPS IRQs. 8->199 are the Lantiq IRQ Modules. Our irq_chip callbacks need to substract 8 (MIPS_CPU_IRQ_CASCADE) from d->hwirq to find out the correct offset into the Interrupt Modules register range. Signed-off-by: John Crispin Cc: devicetree-discuss@lists.ozlabs.org Cc: Grant Likely Cc: linux-mips@linux-mips.org Patchwork: https://patchwork.linux-mips.org/patch/3802/ Signed-off-by: Ralf Baechle --- arch/mips/lantiq/irq.c | 178 ++++++++++++++++++++++++++++--------------------- 1 file changed, 102 insertions(+), 76 deletions(-) (limited to 'arch/mips/lantiq') diff --git a/arch/mips/lantiq/irq.c b/arch/mips/lantiq/irq.c index d227be1c3c4d..57c1a4e51408 100644 --- a/arch/mips/lantiq/irq.c +++ b/arch/mips/lantiq/irq.c @@ -9,6 +9,11 @@ #include #include +#include +#include +#include +#include +#include #include #include @@ -16,7 +21,7 @@ #include #include -/* register definitions */ +/* register definitions - internal irqs */ #define LTQ_ICU_IM0_ISR 0x0000 #define LTQ_ICU_IM0_IER 0x0008 #define LTQ_ICU_IM0_IOSR 0x0010 @@ -25,6 +30,7 @@ #define LTQ_ICU_IM1_ISR 0x0028 #define LTQ_ICU_OFFSET (LTQ_ICU_IM1_ISR - LTQ_ICU_IM0_ISR) +/* register definitions - external irqs */ #define LTQ_EIU_EXIN_C 0x0000 #define LTQ_EIU_EXIN_INIC 0x0004 #define LTQ_EIU_EXIN_INEN 0x000C @@ -37,13 +43,14 @@ #define LTQ_EIU_IR4 (INT_NUM_IM1_IRL0 + 1) #define LTQ_EIU_IR5 (INT_NUM_IM1_IRL0 + 2) #define LTQ_EIU_IR6 (INT_NUM_IM2_IRL0 + 30) - +#define XWAY_EXIN_COUNT 3 #define MAX_EIU 6 /* the performance counter */ #define LTQ_PERF_IRQ (INT_NUM_IM4_IRL0 + 31) -/* irqs generated by device attached to the EBU need to be acked in +/* + * irqs generated by devices attached to the EBU need to be acked in * a special manner */ #define LTQ_ICU_EBU_IRQ 22 @@ -58,6 +65,9 @@ #define MIPS_CPU_IPI_RESCHED_IRQ 0 #define MIPS_CPU_IPI_CALL_IRQ 1 +/* we have a cascade of 8 irqs */ +#define MIPS_CPU_IRQ_CASCADE 8 + #if defined(CONFIG_MIPS_MT_SMP) || defined(CONFIG_MIPS_MT_SMTC) int gic_present; #endif @@ -71,64 +81,51 @@ static unsigned short ltq_eiu_irq[MAX_EIU] = { LTQ_EIU_IR5, }; -static struct resource ltq_icu_resource = { - .name = "icu", - .start = LTQ_ICU_BASE_ADDR, - .end = LTQ_ICU_BASE_ADDR + LTQ_ICU_SIZE - 1, - .flags = IORESOURCE_MEM, -}; - -static struct resource ltq_eiu_resource = { - .name = "eiu", - .start = LTQ_EIU_BASE_ADDR, - .end = LTQ_EIU_BASE_ADDR + LTQ_ICU_SIZE - 1, - .flags = IORESOURCE_MEM, -}; - +static int exin_avail; static void __iomem *ltq_icu_membase; static void __iomem *ltq_eiu_membase; void ltq_disable_irq(struct irq_data *d) { u32 ier = LTQ_ICU_IM0_IER; - int irq_nr = d->irq - INT_NUM_IRQ0; + int offset = d->hwirq - MIPS_CPU_IRQ_CASCADE; - ier += LTQ_ICU_OFFSET * (irq_nr / INT_NUM_IM_OFFSET); - irq_nr %= INT_NUM_IM_OFFSET; - ltq_icu_w32(ltq_icu_r32(ier) & ~(1 << irq_nr), ier); + ier += LTQ_ICU_OFFSET * (offset / INT_NUM_IM_OFFSET); + offset %= INT_NUM_IM_OFFSET; + ltq_icu_w32(ltq_icu_r32(ier) & ~BIT(offset), ier); } void ltq_mask_and_ack_irq(struct irq_data *d) { u32 ier = LTQ_ICU_IM0_IER; u32 isr = LTQ_ICU_IM0_ISR; - int irq_nr = d->irq - INT_NUM_IRQ0; + int offset = d->hwirq - MIPS_CPU_IRQ_CASCADE; - ier += LTQ_ICU_OFFSET * (irq_nr / INT_NUM_IM_OFFSET); - isr += LTQ_ICU_OFFSET * (irq_nr / INT_NUM_IM_OFFSET); - irq_nr %= INT_NUM_IM_OFFSET; - ltq_icu_w32(ltq_icu_r32(ier) & ~(1 << irq_nr), ier); - ltq_icu_w32((1 << irq_nr), isr); + 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); } static void ltq_ack_irq(struct irq_data *d) { u32 isr = LTQ_ICU_IM0_ISR; - int irq_nr = d->irq - INT_NUM_IRQ0; + int offset = d->hwirq - MIPS_CPU_IRQ_CASCADE; - isr += LTQ_ICU_OFFSET * (irq_nr / INT_NUM_IM_OFFSET); - irq_nr %= INT_NUM_IM_OFFSET; - ltq_icu_w32((1 << irq_nr), isr); + isr += LTQ_ICU_OFFSET * (offset / INT_NUM_IM_OFFSET); + offset %= INT_NUM_IM_OFFSET; + ltq_icu_w32(BIT(offset), isr); } void ltq_enable_irq(struct irq_data *d) { u32 ier = LTQ_ICU_IM0_IER; - int irq_nr = d->irq - INT_NUM_IRQ0; + int offset = d->hwirq - MIPS_CPU_IRQ_CASCADE; - ier += LTQ_ICU_OFFSET * (irq_nr / INT_NUM_IM_OFFSET); - irq_nr %= INT_NUM_IM_OFFSET; - ltq_icu_w32(ltq_icu_r32(ier) | (1 << irq_nr), ier); + ier += LTQ_ICU_OFFSET * (offset / INT_NUM_IM_OFFSET); + offset %= INT_NUM_IM_OFFSET; + ltq_icu_w32(ltq_icu_r32(ier) | BIT(offset), ier); } static unsigned int ltq_startup_eiu_irq(struct irq_data *d) @@ -137,15 +134,15 @@ static unsigned int ltq_startup_eiu_irq(struct irq_data *d) ltq_enable_irq(d); for (i = 0; i < MAX_EIU; i++) { - if (d->irq == ltq_eiu_irq[i]) { + if (d->hwirq == ltq_eiu_irq[i]) { /* low level - we should really handle set_type */ ltq_eiu_w32(ltq_eiu_r32(LTQ_EIU_EXIN_C) | (0x6 << (i * 4)), LTQ_EIU_EXIN_C); /* clear all pending */ - ltq_eiu_w32(ltq_eiu_r32(LTQ_EIU_EXIN_INIC) & ~(1 << i), + ltq_eiu_w32(ltq_eiu_r32(LTQ_EIU_EXIN_INIC) & ~BIT(i), LTQ_EIU_EXIN_INIC); /* enable */ - ltq_eiu_w32(ltq_eiu_r32(LTQ_EIU_EXIN_INEN) | (1 << i), + ltq_eiu_w32(ltq_eiu_r32(LTQ_EIU_EXIN_INEN) | BIT(i), LTQ_EIU_EXIN_INEN); break; } @@ -160,9 +157,9 @@ static void ltq_shutdown_eiu_irq(struct irq_data *d) ltq_disable_irq(d); for (i = 0; i < MAX_EIU; i++) { - if (d->irq == ltq_eiu_irq[i]) { + if (d->hwirq == ltq_eiu_irq[i]) { /* disable */ - ltq_eiu_w32(ltq_eiu_r32(LTQ_EIU_EXIN_INEN) & ~(1 << i), + ltq_eiu_w32(ltq_eiu_r32(LTQ_EIU_EXIN_INEN) & ~BIT(i), LTQ_EIU_EXIN_INEN); break; } @@ -199,14 +196,15 @@ static void ltq_hw_irqdispatch(int module) if (irq == 0) return; - /* silicon bug causes only the msb set to 1 to be valid. all + /* + * silicon bug causes only the msb set to 1 to be valid. all * other bits might be bogus */ irq = __fls(irq); - do_IRQ((int)irq + INT_NUM_IM0_IRL0 + (INT_NUM_IM_OFFSET * module)); + do_IRQ((int)irq + MIPS_CPU_IRQ_CASCADE + (INT_NUM_IM_OFFSET * module)); /* if this is a EBU irq, we need to ack it or get a deadlock */ - if ((irq == LTQ_ICU_EBU_IRQ) && (module == 0)) + if ((irq == LTQ_ICU_EBU_IRQ) && (module == 0) && LTQ_EBU_PCC_ISTAT) ltq_ebu_w32(ltq_ebu_r32(LTQ_EBU_PCC_ISTAT) | 0x10, LTQ_EBU_PCC_ISTAT); } @@ -290,38 +288,67 @@ out: return; } +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; + + for (i = 0; i < exin_avail; i++) + if (hw == ltq_eiu_irq[i]) + chip = <q_eiu_type; + + irq_set_chip_and_handler(hw, chip, handle_level_irq); + + return 0; +} + +static const struct irq_domain_ops irq_domain_ops = { + .xlate = irq_domain_xlate_onetwocell, + .map = icu_map, +}; + static struct irqaction cascade = { .handler = no_action, .name = "cascade", }; -void __init arch_init_irq(void) +int __init icu_of_init(struct device_node *node, struct device_node *parent) { + struct device_node *eiu_node; + struct resource res; int i; - if (insert_resource(&iomem_resource, <q_icu_resource) < 0) - panic("Failed to insert icu memory"); + if (of_address_to_resource(node, 0, &res)) + panic("Failed to get icu memory range"); - if (request_mem_region(ltq_icu_resource.start, - resource_size(<q_icu_resource), "icu") < 0) - panic("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(ltq_icu_resource.start, - resource_size(<q_icu_resource)); + ltq_icu_membase = ioremap_nocache(res.start, resource_size(&res)); if (!ltq_icu_membase) panic("Failed to remap icu memory"); - if (insert_resource(&iomem_resource, <q_eiu_resource) < 0) - panic("Failed to insert eiu memory"); - - if (request_mem_region(ltq_eiu_resource.start, - resource_size(<q_eiu_resource), "eiu") < 0) - panic("Failed to request eiu memory"); - - ltq_eiu_membase = ioremap_nocache(ltq_eiu_resource.start, - resource_size(<q_eiu_resource)); - if (!ltq_eiu_membase) - panic("Failed to remap eiu memory"); + /* 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)) { + /* find out how many external irq sources we have */ + const __be32 *count = of_get_property(node, + "lantiq,count", NULL); + + if (count) + exin_avail = *count; + if (exin_avail > MAX_EIU) + exin_avail = MAX_EIU; + + if (request_mem_region(res.start, resource_size(&res), + res.name) < 0) + pr_err("Failed to request eiu memory"); + + ltq_eiu_membase = ioremap_nocache(res.start, + resource_size(&res)); + if (!ltq_eiu_membase) + panic("Failed to remap eiu memory"); + } /* turn off all irqs by default */ for (i = 0; i < 5; i++) { @@ -346,20 +373,8 @@ void __init arch_init_irq(void) set_vi_handler(7, ltq_hw5_irqdispatch); } - for (i = INT_NUM_IRQ0; - i <= (INT_NUM_IRQ0 + (5 * INT_NUM_IM_OFFSET)); i++) - if ((i == LTQ_EIU_IR0) || (i == LTQ_EIU_IR1) || - (i == LTQ_EIU_IR2)) - irq_set_chip_and_handler(i, <q_eiu_type, - handle_level_irq); - /* EIU3-5 only exist on ar9 and vr9 */ - else if (((i == LTQ_EIU_IR3) || (i == LTQ_EIU_IR4) || - (i == LTQ_EIU_IR5)) && (ltq_is_ar9() || ltq_is_vr9())) - irq_set_chip_and_handler(i, <q_eiu_type, - handle_level_irq); - else - irq_set_chip_and_handler(i, <q_irq_type, - handle_level_irq); + irq_domain_add_linear(node, 6 * INT_NUM_IM_OFFSET, + &irq_domain_ops, 0); #if defined(CONFIG_MIPS_MT_SMP) if (cpu_has_vint) { @@ -382,9 +397,20 @@ void __init arch_init_irq(void) /* tell oprofile which irq to use */ cp0_perfcount_irq = LTQ_PERF_IRQ; + return 0; } unsigned int __cpuinit get_c0_compare_int(void) { return CP0_LEGACY_COMPARE_IRQ; } + +static struct of_device_id __initdata of_irq_ids[] = { + { .compatible = "lantiq,icu", .data = icu_of_init }, + {}, +}; + +void __init arch_init_irq(void) +{ + of_irq_init(of_irq_ids); +} -- cgit v1.2.2 From bd51db7f3bf2ba23ff55f6d5fdcec04c74df13e4 Mon Sep 17 00:00:00 2001 From: John Crispin Date: Fri, 11 May 2012 18:45:25 +0200 Subject: MIPS: lantiq: drop ltq_gpio_request() and gpio_to_irq() As part of the conversion to OF we also implement pinctrl drivers. Previously we used ltq_gpio_request() to set pinmuxing. This is now obselete and we can hence drop the function. Additionally we remove gpio_to_irq() from the gpio driver and move it to a header file. Signed-off-by: John Crispin Cc: linux-mips@linux-mips.org Patchwork: https://patchwork.linux-mips.org/patch/3801/ Signed-off-by: Ralf Baechle --- arch/mips/lantiq/xway/gpio.c | 12 ------------ arch/mips/lantiq/xway/gpio_stp.c | 5 ----- 2 files changed, 17 deletions(-) (limited to 'arch/mips/lantiq') diff --git a/arch/mips/lantiq/xway/gpio.c b/arch/mips/lantiq/xway/gpio.c index d2fa98f3c78d..a8b2edc80855 100644 --- a/arch/mips/lantiq/xway/gpio.c +++ b/arch/mips/lantiq/xway/gpio.c @@ -36,18 +36,6 @@ struct ltq_gpio { static struct ltq_gpio ltq_gpio_port[MAX_PORTS]; -int gpio_to_irq(unsigned int gpio) -{ - return -EINVAL; -} -EXPORT_SYMBOL(gpio_to_irq); - -int irq_to_gpio(unsigned int gpio) -{ - return -EINVAL; -} -EXPORT_SYMBOL(irq_to_gpio); - int ltq_gpio_request(unsigned int pin, unsigned int alt0, unsigned int alt1, unsigned int dir, const char *name) { diff --git a/arch/mips/lantiq/xway/gpio_stp.c b/arch/mips/lantiq/xway/gpio_stp.c index ff9991cddeaa..d674f1be237d 100644 --- a/arch/mips/lantiq/xway/gpio_stp.c +++ b/arch/mips/lantiq/xway/gpio_stp.c @@ -78,11 +78,6 @@ static struct gpio_chip ltq_stp_chip = { static int ltq_stp_hw_init(void) { - /* 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"); - /* sane defaults */ ltq_stp_w32(0, LTQ_STP_AR); ltq_stp_w32(0, LTQ_STP_CPU0); -- cgit v1.2.2 From 287e3f3f4e68ca881e3faa413e7aa114fee609d3 Mon Sep 17 00:00:00 2001 From: John Crispin Date: Tue, 17 Apr 2012 15:53:19 +0200 Subject: MIPS: lantiq: implement support for clkdev api This patch unifies all clock generation and gating code into one file. All drivers will now be able to request their clocks via their device. This patch also adds support for the clockout feature, which allows clock generation on external pins. Support for COMMON_CLK will be provided in the next series. Signed-off-by: John Crispin Cc: linux-mips@linux-mips.org Patchwork: https://patchwork.linux-mips.org/patch/3804/ Signed-off-by: Ralf Baechle --- arch/mips/lantiq/clk.c | 146 +++++++++------- arch/mips/lantiq/clk.h | 68 +++++++- 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/clk.c | 151 ++++++++++++++++ arch/mips/lantiq/xway/ebu.c | 48 ----- arch/mips/lantiq/xway/pmu.c | 69 -------- arch/mips/lantiq/xway/sysctrl.c | 367 +++++++++++++++++++++++++++++++++++++++ 9 files changed, 662 insertions(+), 463 deletions(-) delete mode 100644 arch/mips/lantiq/xway/clk-ase.c delete mode 100644 arch/mips/lantiq/xway/clk-xway.c create mode 100644 arch/mips/lantiq/xway/clk.c delete mode 100644 arch/mips/lantiq/xway/ebu.c delete mode 100644 arch/mips/lantiq/xway/pmu.c create mode 100644 arch/mips/lantiq/xway/sysctrl.c (limited to 'arch/mips/lantiq') diff --git a/arch/mips/lantiq/clk.c b/arch/mips/lantiq/clk.c index 412814fdd3ee..d3bcc33f4699 100644 --- a/arch/mips/lantiq/clk.c +++ b/arch/mips/lantiq/clk.c @@ -12,6 +12,7 @@ #include #include #include +#include #include #include @@ -22,44 +23,32 @@ #include #include "clk.h" +#include "prom.h" -struct clk { - const char *name; - unsigned long rate; - unsigned long (*get_rate) (void); -}; +/* lantiq socs have 3 static clocks */ +static struct clk cpu_clk_generic[3]; -static struct clk *cpu_clk; -static int cpu_clk_cnt; +void clkdev_add_static(unsigned long cpu, unsigned long fpi, unsigned long io) +{ + cpu_clk_generic[0].rate = cpu; + cpu_clk_generic[1].rate = fpi; + cpu_clk_generic[2].rate = io; +} -/* lantiq socs have 3 static clocks */ -static struct clk cpu_clk_generic[] = { - { - .name = "cpu", - .get_rate = ltq_get_cpu_hz, - }, { - .name = "fpi", - .get_rate = ltq_get_fpi_hz, - }, { - .name = "io", - .get_rate = ltq_get_io_region_clock, - }, -}; - -static struct resource ltq_cgu_resource = { - .name = "cgu", - .start = LTQ_CGU_BASE_ADDR, - .end = LTQ_CGU_BASE_ADDR + LTQ_CGU_SIZE - 1, - .flags = IORESOURCE_MEM, -}; - -/* remapped clock register range */ -void __iomem *ltq_cgu_membase; - -void clk_init(void) +struct clk *clk_get_cpu(void) +{ + return &cpu_clk_generic[0]; +} + +struct clk *clk_get_fpi(void) +{ + return &cpu_clk_generic[1]; +} +EXPORT_SYMBOL_GPL(clk_get_fpi); + +struct clk *clk_get_io(void) { - cpu_clk = cpu_clk_generic; - cpu_clk_cnt = ARRAY_SIZE(cpu_clk_generic); + return &cpu_clk_generic[2]; } static inline int clk_good(struct clk *clk) @@ -82,38 +71,71 @@ unsigned long clk_get_rate(struct clk *clk) } EXPORT_SYMBOL(clk_get_rate); -struct clk *clk_get(struct device *dev, const char *id) +int clk_set_rate(struct clk *clk, unsigned long rate) { - int i; - - for (i = 0; i < cpu_clk_cnt; i++) - if (!strcmp(id, cpu_clk[i].name)) - return &cpu_clk[i]; - BUG(); - return ERR_PTR(-ENOENT); -} -EXPORT_SYMBOL(clk_get); - -void clk_put(struct clk *clk) -{ - /* not used */ + if (unlikely(!clk_good(clk))) + return 0; + if (clk->rates && *clk->rates) { + unsigned long *r = clk->rates; + + while (*r && (*r != rate)) + r++; + if (!*r) { + pr_err("clk %s.%s: trying to set invalid rate %ld\n", + clk->cl.dev_id, clk->cl.con_id, rate); + return -1; + } + } + clk->rate = rate; + return 0; } -EXPORT_SYMBOL(clk_put); +EXPORT_SYMBOL(clk_set_rate); int clk_enable(struct clk *clk) { - /* not used */ - return 0; + if (unlikely(!clk_good(clk))) + return -1; + + if (clk->enable) + return clk->enable(clk); + + return -1; } EXPORT_SYMBOL(clk_enable); void clk_disable(struct clk *clk) { - /* not used */ + if (unlikely(!clk_good(clk))) + return; + + if (clk->disable) + clk->disable(clk); } EXPORT_SYMBOL(clk_disable); -static inline u32 ltq_get_counter_resolution(void) +int clk_activate(struct clk *clk) +{ + if (unlikely(!clk_good(clk))) + return -1; + + if (clk->activate) + return clk->activate(clk); + + return -1; +} +EXPORT_SYMBOL(clk_activate); + +void clk_deactivate(struct clk *clk) +{ + if (unlikely(!clk_good(clk))) + return; + + if (clk->deactivate) + clk->deactivate(clk); +} +EXPORT_SYMBOL(clk_deactivate); + +static inline u32 get_counter_resolution(void) { u32 res; @@ -133,21 +155,11 @@ void __init plat_time_init(void) { struct clk *clk; - if (insert_resource(&iomem_resource, <q_cgu_resource) < 0) - panic("Failed to insert cgu memory"); + ltq_soc_init(); - if (request_mem_region(ltq_cgu_resource.start, - resource_size(<q_cgu_resource), "cgu") < 0) - panic("Failed to request cgu memory"); - - ltq_cgu_membase = ioremap_nocache(ltq_cgu_resource.start, - resource_size(<q_cgu_resource)); - if (!ltq_cgu_membase) { - pr_err("Failed to remap cgu memory\n"); - unreachable(); - } - clk = clk_get(0, "cpu"); - mips_hpt_frequency = clk_get_rate(clk) / ltq_get_counter_resolution(); + clk = clk_get_cpu(); + mips_hpt_frequency = clk_get_rate(clk) / get_counter_resolution(); write_c0_compare(read_c0_count()); + pr_info("CPU Clock: %ldMHz\n", clk_get_rate(clk) / 1000000); clk_put(clk); } diff --git a/arch/mips/lantiq/clk.h b/arch/mips/lantiq/clk.h index 3328925f2c3f..fa670602b91b 100644 --- a/arch/mips/lantiq/clk.h +++ b/arch/mips/lantiq/clk.h @@ -9,10 +9,70 @@ #ifndef _LTQ_CLK_H__ #define _LTQ_CLK_H__ -extern void clk_init(void); +#include -extern unsigned long ltq_get_cpu_hz(void); -extern unsigned long ltq_get_fpi_hz(void); -extern unsigned long ltq_get_io_region_clock(void); +/* clock speeds */ +#define CLOCK_33M 33333333 +#define CLOCK_60M 60000000 +#define CLOCK_62_5M 62500000 +#define CLOCK_83M 83333333 +#define CLOCK_83_5M 83500000 +#define CLOCK_98_304M 98304000 +#define CLOCK_100M 100000000 +#define CLOCK_111M 111111111 +#define CLOCK_125M 125000000 +#define CLOCK_133M 133333333 +#define CLOCK_150M 150000000 +#define CLOCK_166M 166666666 +#define CLOCK_167M 166666667 +#define CLOCK_196_608M 196608000 +#define CLOCK_200M 200000000 +#define CLOCK_250M 250000000 +#define CLOCK_266M 266666666 +#define CLOCK_300M 300000000 +#define CLOCK_333M 333333333 +#define CLOCK_393M 393215332 +#define CLOCK_400M 400000000 +#define CLOCK_500M 500000000 +#define CLOCK_600M 600000000 + +/* clock out speeds */ +#define CLOCK_32_768K 32768 +#define CLOCK_1_536M 1536000 +#define CLOCK_2_5M 2500000 +#define CLOCK_12M 12000000 +#define CLOCK_24M 24000000 +#define CLOCK_25M 25000000 +#define CLOCK_30M 30000000 +#define CLOCK_40M 40000000 +#define CLOCK_48M 48000000 +#define CLOCK_50M 50000000 +#define CLOCK_60M 60000000 + +struct clk { + struct clk_lookup cl; + unsigned long rate; + unsigned long *rates; + unsigned int module; + unsigned int bits; + unsigned long (*get_rate) (void); + int (*enable) (struct clk *clk); + void (*disable) (struct clk *clk); + int (*activate) (struct clk *clk); + void (*deactivate) (struct clk *clk); + void (*reboot) (struct clk *clk); +}; + +extern void clkdev_add_static(unsigned long cpu, unsigned long fpi, + unsigned long io); + +extern unsigned long ltq_danube_cpu_hz(void); +extern unsigned long ltq_danube_fpi_hz(void); + +extern unsigned long ltq_ar9_cpu_hz(void); +extern unsigned long ltq_ar9_fpi_hz(void); + +extern unsigned long ltq_vr9_cpu_hz(void); +extern unsigned long ltq_vr9_fpi_hz(void); #endif diff --git a/arch/mips/lantiq/xway/Makefile b/arch/mips/lantiq/xway/Makefile index 7a6c30f672f4..edef6c582fce 100644 --- a/arch/mips/lantiq/xway/Makefile +++ b/arch/mips/lantiq/xway/Makefile @@ -1,4 +1 @@ -obj-y := prom.o pmu.o ebu.o reset.o gpio.o gpio_stp.o gpio_ebu.o dma.o - -obj-$(CONFIG_SOC_XWAY) += clk-xway.o -obj-$(CONFIG_SOC_AMAZON_SE) += clk-ase.o +obj-y := prom.o sysctrl.o clk.o reset.o gpio.o gpio_stp.o gpio_ebu.o dma.o diff --git a/arch/mips/lantiq/xway/clk-ase.c b/arch/mips/lantiq/xway/clk-ase.c deleted file mode 100644 index 652258309c9c..000000000000 --- 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 696b1a3e0642..000000000000 --- 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/clk.c b/arch/mips/lantiq/xway/clk.c new file mode 100644 index 000000000000..9aa17f79a742 --- /dev/null +++ b/arch/mips/lantiq/xway/clk.c @@ -0,0 +1,151 @@ +/* + * 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 + +#include "../clk.h" + +static unsigned int ram_clocks[] = { + CLOCK_167M, CLOCK_133M, CLOCK_111M, CLOCK_83M }; +#define DDR_HZ ram_clocks[ltq_cgu_r32(CGU_SYS) & 0x3] + +/* legacy xway clock */ +#define CGU_SYS 0x10 + +/* vr9 clock */ +#define CGU_SYS_VR9 0x0c +#define CGU_IF_CLK_VR9 0x24 + +unsigned long ltq_danube_fpi_hz(void) +{ + unsigned long ddr_clock = DDR_HZ; + + if (ltq_cgu_r32(CGU_SYS) & 0x40) + return ddr_clock >> 1; + return ddr_clock; +} + +unsigned long ltq_danube_cpu_hz(void) +{ + switch (ltq_cgu_r32(CGU_SYS) & 0xc) { + case 0: + return CLOCK_333M; + case 4: + return DDR_HZ; + case 8: + return DDR_HZ << 1; + default: + return DDR_HZ >> 1; + } +} + +unsigned long ltq_ar9_sys_hz(void) +{ + if (((ltq_cgu_r32(CGU_SYS) >> 3) & 0x3) == 0x2) + return CLOCK_393M; + return CLOCK_333M; +} + +unsigned long ltq_ar9_fpi_hz(void) +{ + unsigned long sys = ltq_ar9_sys_hz(); + + if (ltq_cgu_r32(CGU_SYS) & BIT(0)) + return sys; + return sys >> 1; +} + +unsigned long ltq_ar9_cpu_hz(void) +{ + if (ltq_cgu_r32(CGU_SYS) & BIT(2)) + return ltq_ar9_fpi_hz(); + else + return ltq_ar9_sys_hz(); +} + +unsigned long ltq_vr9_cpu_hz(void) +{ + unsigned int cpu_sel; + unsigned long clk; + + cpu_sel = (ltq_cgu_r32(CGU_SYS_VR9) >> 4) & 0xf; + + switch (cpu_sel) { + case 0: + clk = CLOCK_600M; + break; + case 1: + clk = CLOCK_500M; + break; + case 2: + clk = CLOCK_393M; + break; + case 3: + clk = CLOCK_333M; + break; + case 5: + case 6: + clk = CLOCK_196_608M; + break; + case 7: + clk = CLOCK_167M; + break; + case 4: + case 8: + case 9: + clk = CLOCK_125M; + break; + default: + clk = 0; + break; + } + + return clk; +} + +unsigned long ltq_vr9_fpi_hz(void) +{ + unsigned int ocp_sel, cpu_clk; + unsigned long clk; + + cpu_clk = ltq_vr9_cpu_hz(); + ocp_sel = ltq_cgu_r32(CGU_SYS_VR9) & 0x3; + + switch (ocp_sel) { + case 0: + /* OCP ratio 1 */ + clk = cpu_clk; + break; + case 2: + /* OCP ratio 2 */ + clk = cpu_clk / 2; + break; + case 3: + /* OCP ratio 2.5 */ + clk = (cpu_clk * 2) / 5; + break; + case 4: + /* OCP ratio 3 */ + clk = cpu_clk / 3; + break; + default: + clk = 0; + break; + } + + return clk; +} diff --git a/arch/mips/lantiq/xway/ebu.c b/arch/mips/lantiq/xway/ebu.c deleted file mode 100644 index 419b47b70f32..000000000000 --- a/arch/mips/lantiq/xway/ebu.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. - * - * EBU - the external bus unit attaches PCI, NOR and NAND - * - * Copyright (C) 2010 John Crispin - */ - -#include -#include -#include - -#include - -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/pmu.c b/arch/mips/lantiq/xway/pmu.c deleted file mode 100644 index fe85361e032e..000000000000 --- 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/sysctrl.c b/arch/mips/lantiq/xway/sysctrl.c new file mode 100644 index 000000000000..4d6aac693535 --- /dev/null +++ b/arch/mips/lantiq/xway/sysctrl.c @@ -0,0 +1,367 @@ +/* + * 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-2012 John Crispin + */ + +#include +#include +#include +#include +#include +#include + +#include + +#include "../clk.h" +#include "../prom.h" + +/* clock control register */ +#define CGU_IFCCR 0x0018 +/* system clock register */ +#define CGU_SYS 0x0010 +/* pci control register */ +#define CGU_PCICR 0x0034 +/* ephy configuration register */ +#define CGU_EPHY 0x10 +/* power control register */ +#define PMU_PWDCR 0x1C +/* power status register */ +#define PMU_PWDSR 0x20 +/* power control register */ +#define PMU_PWDCR1 0x24 +/* power status register */ +#define PMU_PWDSR1 0x28 +/* power control register */ +#define PWDCR(x) ((x) ? (PMU_PWDCR1) : (PMU_PWDCR)) +/* power status register */ +#define PWDSR(x) ((x) ? (PMU_PWDSR1) : (PMU_PWDSR)) + +/* clock gates that we can en/disable */ +#define PMU_USB0_P BIT(0) +#define PMU_PCI BIT(4) +#define PMU_USB0 BIT(6) +#define PMU_ASC0 BIT(7) +#define PMU_EPHY BIT(7) /* ase */ +#define PMU_SPI BIT(8) +#define PMU_DFE BIT(9) +#define PMU_EBU BIT(10) +#define PMU_STP BIT(11) +#define PMU_AHBS BIT(13) /* vr9 */ +#define PMU_AHBM BIT(15) +#define PMU_ASC1 BIT(17) +#define PMU_PPE_QSB BIT(18) +#define PMU_PPE_SLL01 BIT(19) +#define PMU_PPE_TC BIT(21) +#define PMU_PPE_EMA BIT(22) +#define PMU_PPE_DPLUM BIT(23) +#define PMU_PPE_DPLUS BIT(24) +#define PMU_USB1_P BIT(26) +#define PMU_USB1 BIT(27) +#define PMU_PPE_TOP BIT(29) +#define PMU_GPHY BIT(30) +#define PMU_PCIE_CLK BIT(31) + +#define PMU1_PCIE_PHY BIT(0) +#define PMU1_PCIE_CTL BIT(1) +#define PMU1_PCIE_PDI BIT(4) +#define PMU1_PCIE_MSI BIT(5) + +#define pmu_w32(x, y) ltq_w32((x), pmu_membase + (y)) +#define pmu_r32(x) ltq_r32(pmu_membase + (x)) + +static void __iomem *pmu_membase; +void __iomem *ltq_cgu_membase; +void __iomem *ltq_ebu_membase; + +/* legacy function kept alive to ease clkdev transition */ +void ltq_pmu_enable(unsigned int module) +{ + int err = 1000000; + + pmu_w32(pmu_r32(PMU_PWDCR) & ~module, PMU_PWDCR); + do {} while (--err && (pmu_r32(PMU_PWDSR) & module)); + + if (!err) + panic("activating PMU module failed!"); +} +EXPORT_SYMBOL(ltq_pmu_enable); + +/* legacy function kept alive to ease clkdev transition */ +void ltq_pmu_disable(unsigned int module) +{ + pmu_w32(pmu_r32(PMU_PWDCR) | module, PMU_PWDCR); +} +EXPORT_SYMBOL(ltq_pmu_disable); + +/* enable a hw clock */ +static int cgu_enable(struct clk *clk) +{ + ltq_cgu_w32(ltq_cgu_r32(CGU_IFCCR) | clk->bits, CGU_IFCCR); + return 0; +} + +/* disable a hw clock */ +static void cgu_disable(struct clk *clk) +{ + ltq_cgu_w32(ltq_cgu_r32(CGU_IFCCR) & ~clk->bits, CGU_IFCCR); +} + +/* enable a clock gate */ +static int pmu_enable(struct clk *clk) +{ + int retry = 1000000; + + pmu_w32(pmu_r32(PWDCR(clk->module)) & ~clk->bits, + PWDCR(clk->module)); + do {} while (--retry && (pmu_r32(PWDSR(clk->module)) & clk->bits)); + + if (!retry) + panic("activating PMU module failed!\n"); + + return 0; +} + +/* disable a clock gate */ +static void pmu_disable(struct clk *clk) +{ + pmu_w32(pmu_r32(PWDCR(clk->module)) | clk->bits, + PWDCR(clk->module)); +} + +/* the pci enable helper */ +static int pci_enable(struct clk *clk) +{ + unsigned int ifccr = ltq_cgu_r32(CGU_IFCCR); + /* set bus clock speed */ + if (of_machine_is_compatible("lantiq,ar9")) { + ifccr &= ~0x1f00000; + if (clk->rate == CLOCK_33M) + ifccr |= 0xe00000; + else + ifccr |= 0x700000; /* 62.5M */ + } else { + ifccr &= ~0xf00000; + if (clk->rate == CLOCK_33M) + ifccr |= 0x800000; + else + ifccr |= 0x400000; /* 62.5M */ + } + ltq_cgu_w32(ifccr, CGU_IFCCR); + pmu_enable(clk); + return 0; +} + +/* enable the external clock as a source */ +static int pci_ext_enable(struct clk *clk) +{ + ltq_cgu_w32(ltq_cgu_r32(CGU_IFCCR) & ~(1 << 16), + CGU_IFCCR); + ltq_cgu_w32((1 << 30), CGU_PCICR); + return 0; +} + +/* disable the external clock as a source */ +static void pci_ext_disable(struct clk *clk) +{ + ltq_cgu_w32(ltq_cgu_r32(CGU_IFCCR) | (1 << 16), + CGU_IFCCR); + ltq_cgu_w32((1 << 31) | (1 << 30), CGU_PCICR); +} + +/* enable a clockout source */ +static int clkout_enable(struct clk *clk) +{ + int i; + + /* get the correct rate */ + for (i = 0; i < 4; i++) { + if (clk->rates[i] == clk->rate) { + int shift = 14 - (2 * clk->module); + unsigned int ifccr = ltq_cgu_r32(CGU_IFCCR); + + ifccr &= ~(3 << shift); + ifccr |= i << shift; + ltq_cgu_w32(ifccr, CGU_IFCCR); + return 0; + } + } + return -1; +} + +/* manage the clock gates via PMU */ +static void clkdev_add_pmu(const char *dev, const char *con, + unsigned int module, unsigned int bits) +{ + struct clk *clk = kzalloc(sizeof(struct clk), GFP_KERNEL); + + clk->cl.dev_id = dev; + clk->cl.con_id = con; + clk->cl.clk = clk; + clk->enable = pmu_enable; + clk->disable = pmu_disable; + clk->module = module; + clk->bits = bits; + clkdev_add(&clk->cl); +} + +/* manage the clock generator */ +static void clkdev_add_cgu(const char *dev, const char *con, + unsigned int bits) +{ + struct clk *clk = kzalloc(sizeof(struct clk), GFP_KERNEL); + + clk->cl.dev_id = dev; + clk->cl.con_id = con; + clk->cl.clk = clk; + clk->enable = cgu_enable; + clk->disable = cgu_disable; + clk->bits = bits; + clkdev_add(&clk->cl); +} + +/* pci needs its own enable function as the setup is a bit more complex */ +static unsigned long valid_pci_rates[] = {CLOCK_33M, CLOCK_62_5M, 0}; + +static void clkdev_add_pci(void) +{ + struct clk *clk = kzalloc(sizeof(struct clk), GFP_KERNEL); + struct clk *clk_ext = kzalloc(sizeof(struct clk), GFP_KERNEL); + + /* main pci clock */ + clk->cl.dev_id = "17000000.pci"; + clk->cl.con_id = NULL; + clk->cl.clk = clk; + clk->rate = CLOCK_33M; + clk->rates = valid_pci_rates; + clk->enable = pci_enable; + clk->disable = pmu_disable; + clk->module = 0; + clk->bits = PMU_PCI; + clkdev_add(&clk->cl); + + /* use internal/external bus clock */ + clk_ext->cl.dev_id = "17000000.pci"; + clk_ext->cl.con_id = "external"; + clk_ext->cl.clk = clk_ext; + clk_ext->enable = pci_ext_enable; + clk_ext->disable = pci_ext_disable; + clkdev_add(&clk_ext->cl); +} + +/* xway socs can generate clocks on gpio pins */ +static unsigned long valid_clkout_rates[4][5] = { + {CLOCK_32_768K, CLOCK_1_536M, CLOCK_2_5M, CLOCK_12M, 0}, + {CLOCK_40M, CLOCK_12M, CLOCK_24M, CLOCK_48M, 0}, + {CLOCK_25M, CLOCK_40M, CLOCK_30M, CLOCK_60M, 0}, + {CLOCK_12M, CLOCK_50M, CLOCK_32_768K, CLOCK_25M, 0}, +}; + +static void clkdev_add_clkout(void) +{ + int i; + + for (i = 0; i < 4; i++) { + struct clk *clk; + char *name; + + name = kzalloc(sizeof("clkout0"), GFP_KERNEL); + sprintf(name, "clkout%d", i); + + clk = kzalloc(sizeof(struct clk), GFP_KERNEL); + clk->cl.dev_id = "1f103000.cgu"; + clk->cl.con_id = name; + clk->cl.clk = clk; + clk->rate = 0; + clk->rates = valid_clkout_rates[i]; + clk->enable = clkout_enable; + clk->module = i; + clkdev_add(&clk->cl); + } +} + +/* bring up all register ranges that we need for basic system control */ +void __init ltq_soc_init(void) +{ + struct resource res_pmu, res_cgu, res_ebu; + struct device_node *np_pmu = + of_find_compatible_node(NULL, NULL, "lantiq,pmu-xway"); + struct device_node *np_cgu = + of_find_compatible_node(NULL, NULL, "lantiq,cgu-xway"); + struct device_node *np_ebu = + of_find_compatible_node(NULL, NULL, "lantiq,ebu-xway"); + + /* check if all the core register ranges are available */ + if (!np_pmu || !np_cgu || !np_ebu) + panic("Failed to load core nodess from devicetree"); + + if (of_address_to_resource(np_pmu, 0, &res_pmu) || + of_address_to_resource(np_cgu, 0, &res_cgu) || + of_address_to_resource(np_ebu, 0, &res_ebu)) + panic("Failed to get core resources"); + + if ((request_mem_region(res_pmu.start, resource_size(&res_pmu), + res_pmu.name) < 0) || + (request_mem_region(res_cgu.start, resource_size(&res_cgu), + res_cgu.name) < 0) || + (request_mem_region(res_ebu.start, resource_size(&res_ebu), + res_ebu.name) < 0)) + pr_err("Failed to request core reources"); + + pmu_membase = ioremap_nocache(res_pmu.start, resource_size(&res_pmu)); + ltq_cgu_membase = ioremap_nocache(res_cgu.start, + resource_size(&res_cgu)); + ltq_ebu_membase = ioremap_nocache(res_ebu.start, + resource_size(&res_ebu)); + if (!pmu_membase || !ltq_cgu_membase || !ltq_ebu_membase) + panic("Failed to remap core resources"); + + /* 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); + + /* add our generic xway clocks */ + clkdev_add_pmu("10000000.fpi", NULL, 0, PMU_FPI); + clkdev_add_pmu("1e100400.serial", NULL, 0, PMU_ASC0); + clkdev_add_pmu("1e100a00.gptu", NULL, 0, PMU_GPT); + clkdev_add_pmu("1e100bb0.stp", NULL, 0, PMU_STP); + clkdev_add_pmu("1e104100.dma", NULL, 0, PMU_DMA); + clkdev_add_pmu("1e100800.spi", NULL, 0, PMU_SPI); + clkdev_add_pmu("1e105300.ebu", NULL, 0, PMU_EBU); + clkdev_add_clkout(); + + /* add the soc dependent clocks */ + if (!of_machine_is_compatible("lantiq,vr9")) + clkdev_add_pmu("1e180000.etop", NULL, 0, PMU_PPE); + + if (!of_machine_is_compatible("lantiq,ase")) { + clkdev_add_pmu("1e100c00.serial", NULL, 0, PMU_ASC1); + clkdev_add_pci(); + } + + if (of_machine_is_compatible("lantiq,ase")) { + if (ltq_cgu_r32(CGU_SYS) & (1 << 5)) + clkdev_add_static(CLOCK_266M, CLOCK_133M, CLOCK_133M); + else + clkdev_add_static(CLOCK_133M, CLOCK_133M, CLOCK_133M); + clkdev_add_cgu("1e180000.etop", "ephycgu", CGU_EPHY), + clkdev_add_pmu("1e180000.etop", "ephy", 0, PMU_EPHY); + } else if (of_machine_is_compatible("lantiq,vr9")) { + clkdev_add_static(ltq_vr9_cpu_hz(), ltq_vr9_fpi_hz(), + ltq_vr9_fpi_hz()); + clkdev_add_pmu("1d900000.pcie", "phy", 1, PMU1_PCIE_PHY); + clkdev_add_pmu("1d900000.pcie", "bus", 0, PMU_PCIE_CLK); + clkdev_add_pmu("1d900000.pcie", "msi", 1, PMU1_PCIE_MSI); + 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); + } else if (of_machine_is_compatible("lantiq,ar9")) { + clkdev_add_static(ltq_ar9_cpu_hz(), ltq_ar9_fpi_hz(), + ltq_ar9_fpi_hz()); + clkdev_add_pmu("1e180000.etop", "switch", 0, PMU_SWITCH); + } else { + clkdev_add_static(ltq_danube_cpu_hz(), ltq_danube_fpi_hz(), + ltq_danube_fpi_hz()); + } +} -- cgit v1.2.2 From ddd4eeca961cc6b1d57e0ca2f264403d690b6882 Mon Sep 17 00:00:00 2001 From: John Crispin Date: Thu, 12 Apr 2012 21:12:19 +0200 Subject: MIPS: lantiq: convert dma to platform driver Add code to make the dma driver load as a platform device from the devicetree. Signed-off-by: John Crispin Cc: linux-mips@linux-mips.org Patchwork: https://patchwork.linux-mips.org/patch/3824/ Signed-off-by: Ralf Baechle --- arch/mips/lantiq/xway/dma.c | 61 +++++++++++++++++++++++++++++---------------- 1 file changed, 39 insertions(+), 22 deletions(-) (limited to 'arch/mips/lantiq') diff --git a/arch/mips/lantiq/xway/dma.c b/arch/mips/lantiq/xway/dma.c index b210e936c7c3..55d2c4fa4714 100644 --- a/arch/mips/lantiq/xway/dma.c +++ b/arch/mips/lantiq/xway/dma.c @@ -19,7 +19,8 @@ #include #include #include -#include +#include +#include #include #include @@ -55,13 +56,6 @@ #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 void __iomem *ltq_dma_membase; void @@ -215,27 +209,28 @@ ltq_dma_init_port(int p) } EXPORT_SYMBOL_GPL(ltq_dma_init_port); -int __init -ltq_dma_init(void) +static int __devinit +ltq_dma_init(struct platform_device *pdev) { + struct clk *clk; + struct resource *res; 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"); + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res) + panic("Failed to get dma resource"); /* remap dma register range */ - ltq_dma_membase = ioremap_nocache(ltq_dma_resource.start, - resource_size(<q_dma_resource)); + ltq_dma_membase = devm_request_and_ioremap(&pdev->dev, res); if (!ltq_dma_membase) - panic("Failed to remap dma memory"); + panic("Failed to remap dma resource"); /* power up and reset the dma engine */ - ltq_pmu_enable(PMU_DMA); + clk = clk_get(&pdev->dev, NULL); + if (IS_ERR(clk)) + panic("Failed to get dma clock"); + + clk_enable(clk); ltq_dma_w32_mask(0, DMA_RESET, LTQ_DMA_CTRL); /* disable all interrupts */ @@ -248,7 +243,29 @@ ltq_dma_init(void) ltq_dma_w32(DMA_POLL | DMA_CLK_DIV4, LTQ_DMA_CPOLL); ltq_dma_w32_mask(DMA_CHAN_ON, 0, LTQ_DMA_CCTRL); } + dev_info(&pdev->dev, "init done\n"); return 0; } -postcore_initcall(ltq_dma_init); +static const struct of_device_id dma_match[] = { + { .compatible = "lantiq,dma-xway" }, + {}, +}; +MODULE_DEVICE_TABLE(of, dma_match); + +static struct platform_driver dma_driver = { + .probe = ltq_dma_init, + .driver = { + .name = "dma-xway", + .owner = THIS_MODULE, + .of_match_table = dma_match, + }, +}; + +int __init +dma_init(void) +{ + return platform_driver_register(&dma_driver); +} + +postcore_initcall(dma_init); -- cgit v1.2.2 From 57c8cb8f242988b8048a7058cd1edde025c6f232 Mon Sep 17 00:00:00 2001 From: John Crispin Date: Fri, 11 May 2012 18:47:30 +0200 Subject: MIPS: pci: convert lantiq driver to OF Implement support for OF inside the lantiq PCI driver. The patch also splits pcibios_plat_dev_init and pcibios_map_irq out into their own file to accomodate coexistance with the upcoming pcie driver. Signed-off-by: John Crispin Cc: linux-mips@linux-mips.org Patchwork: https://patchwork.linux-mips.org/patch/3806/ Signed-off-by: Ralf Baechle --- arch/mips/lantiq/Kconfig | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'arch/mips/lantiq') diff --git a/arch/mips/lantiq/Kconfig b/arch/mips/lantiq/Kconfig index 9485fe54752b..7389098fd983 100644 --- a/arch/mips/lantiq/Kconfig +++ b/arch/mips/lantiq/Kconfig @@ -18,7 +18,6 @@ config SOC_XWAY select HW_HAS_PCI endchoice - choice prompt "Devicetree" @@ -27,4 +26,8 @@ config DT_EASY50712 depends on SOC_XWAY endchoice +config PCI_LANTIQ + bool "PCI Support" + depends on SOC_XWAY && PCI + endif -- cgit v1.2.2 From 5238f7bc356670ba702057c7de7f07909133f788 Mon Sep 17 00:00:00 2001 From: John Crispin Date: Fri, 11 May 2012 18:48:39 +0200 Subject: GPIO: MIPS: lantiq: move gpio-stp and gpio-ebu to the subsystem folder Move the 2 drivers from arch/mips/lantiq/xway/ to the subsystem and make them buildable. The following 2 patches will convert the drivers to OF. Signed-off-by: John Crispin Cc: linux-kernel@vger.kernel.org Cc: linux-mips@linux-mips.org Acked-by: Grant Likely Patchwork: https://patchwork.linux-mips.org/patch/3838/ Signed-off-by: Ralf Baechle --- arch/mips/lantiq/xway/Makefile | 2 +- arch/mips/lantiq/xway/gpio_ebu.c | 126 -------------------------------- arch/mips/lantiq/xway/gpio_stp.c | 152 --------------------------------------- 3 files changed, 1 insertion(+), 279 deletions(-) delete mode 100644 arch/mips/lantiq/xway/gpio_ebu.c delete mode 100644 arch/mips/lantiq/xway/gpio_stp.c (limited to 'arch/mips/lantiq') diff --git a/arch/mips/lantiq/xway/Makefile b/arch/mips/lantiq/xway/Makefile index edef6c582fce..dc3194f6ee42 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 gpio_stp.o gpio_ebu.o dma.o +obj-y := prom.o sysctrl.o clk.o reset.o gpio.o dma.o diff --git a/arch/mips/lantiq/xway/gpio_ebu.c b/arch/mips/lantiq/xway/gpio_ebu.c deleted file mode 100644 index b91c7f17f10f..000000000000 --- a/arch/mips/lantiq/xway/gpio_ebu.c +++ /dev/null @@ -1,126 +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 - -/* - * By attaching hardware latches to the EBU it is possible to create output - * only gpios. This driver configures a special memory address, which when - * written to outputs 16 bit to the latches. - */ - -#define LTQ_EBU_BUSCON 0x1e7ff /* 16 bit access, slowest timing */ -#define LTQ_EBU_WP 0x80000000 /* write protect bit */ - -/* we keep a shadow value of the last value written to the ebu */ -static int ltq_ebu_gpio_shadow = 0x0; -static void __iomem *ltq_ebu_gpio_membase; - -static void ltq_ebu_apply(void) -{ - unsigned long flags; - - spin_lock_irqsave(&ebu_lock, flags); - ltq_ebu_w32(LTQ_EBU_BUSCON, LTQ_EBU_BUSCON1); - *((__u16 *)ltq_ebu_gpio_membase) = ltq_ebu_gpio_shadow; - ltq_ebu_w32(LTQ_EBU_BUSCON | LTQ_EBU_WP, LTQ_EBU_BUSCON1); - spin_unlock_irqrestore(&ebu_lock, flags); -} - -static void ltq_ebu_set(struct gpio_chip *chip, unsigned offset, int value) -{ - if (value) - ltq_ebu_gpio_shadow |= (1 << offset); - else - ltq_ebu_gpio_shadow &= ~(1 << offset); - ltq_ebu_apply(); -} - -static int ltq_ebu_direction_output(struct gpio_chip *chip, unsigned offset, - int value) -{ - ltq_ebu_set(chip, offset, value); - - return 0; -} - -static struct gpio_chip ltq_ebu_chip = { - .label = "ltq_ebu", - .direction_output = ltq_ebu_direction_output, - .set = ltq_ebu_set, - .base = 72, - .ngpio = 16, - .can_sleep = 1, - .owner = THIS_MODULE, -}; - -static int ltq_ebu_probe(struct platform_device *pdev) -{ - int ret = 0; - struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - - if (!res) { - dev_err(&pdev->dev, "failed to get memory resource\n"); - return -ENOENT; - } - - res = devm_request_mem_region(&pdev->dev, res->start, - resource_size(res), dev_name(&pdev->dev)); - if (!res) { - dev_err(&pdev->dev, "failed to request memory resource\n"); - return -EBUSY; - } - - ltq_ebu_gpio_membase = devm_ioremap_nocache(&pdev->dev, res->start, - resource_size(res)); - if (!ltq_ebu_gpio_membase) { - dev_err(&pdev->dev, "Failed to ioremap mem region\n"); - return -ENOMEM; - } - - /* grab the default shadow value passed form the platform code */ - ltq_ebu_gpio_shadow = (unsigned int) pdev->dev.platform_data; - - /* tell the ebu controller which memory address we will be using */ - ltq_ebu_w32(pdev->resource->start | 0x1, LTQ_EBU_ADDRSEL1); - - /* write protect the region */ - ltq_ebu_w32(LTQ_EBU_BUSCON | LTQ_EBU_WP, LTQ_EBU_BUSCON1); - - ret = gpiochip_add(<q_ebu_chip); - if (!ret) - ltq_ebu_apply(); - return ret; -} - -static struct platform_driver ltq_ebu_driver = { - .probe = ltq_ebu_probe, - .driver = { - .name = "ltq_ebu", - .owner = THIS_MODULE, - }, -}; - -static int __init ltq_ebu_init(void) -{ - int ret = platform_driver_register(<q_ebu_driver); - - if (ret) - pr_info("ltq_ebu : Error registering platfom driver!"); - return ret; -} - -postcore_initcall(ltq_ebu_init); diff --git a/arch/mips/lantiq/xway/gpio_stp.c b/arch/mips/lantiq/xway/gpio_stp.c deleted file mode 100644 index d674f1be237d..000000000000 --- a/arch/mips/lantiq/xway/gpio_stp.c +++ /dev/null @@ -1,152 +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) 2007 John Crispin - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#define LTQ_STP_CON0 0x00 -#define LTQ_STP_CON1 0x04 -#define LTQ_STP_CPU0 0x08 -#define LTQ_STP_CPU1 0x0C -#define LTQ_STP_AR 0x10 - -#define LTQ_STP_CON_SWU (1 << 31) -#define LTQ_STP_2HZ 0 -#define LTQ_STP_4HZ (1 << 23) -#define LTQ_STP_8HZ (2 << 23) -#define LTQ_STP_10HZ (3 << 23) -#define LTQ_STP_SPEED_MASK (0xf << 23) -#define LTQ_STP_UPD_FPI (1 << 31) -#define LTQ_STP_UPD_MASK (3 << 30) -#define LTQ_STP_ADSL_SRC (3 << 24) - -#define LTQ_STP_GROUP0 (1 << 0) - -#define LTQ_STP_RISING 0 -#define LTQ_STP_FALLING (1 << 26) -#define LTQ_STP_EDGE_MASK (1 << 26) - -#define ltq_stp_r32(reg) __raw_readl(ltq_stp_membase + reg) -#define ltq_stp_w32(val, reg) __raw_writel(val, ltq_stp_membase + reg) -#define ltq_stp_w32_mask(clear, set, reg) \ - ltq_w32((ltq_r32(ltq_stp_membase + reg) & ~(clear)) | (set), \ - ltq_stp_membase + (reg)) - -static int ltq_stp_shadow = 0xffff; -static void __iomem *ltq_stp_membase; - -static void ltq_stp_set(struct gpio_chip *chip, unsigned offset, int value) -{ - if (value) - ltq_stp_shadow |= (1 << offset); - else - ltq_stp_shadow &= ~(1 << offset); - ltq_stp_w32(ltq_stp_shadow, LTQ_STP_CPU0); -} - -static int ltq_stp_direction_output(struct gpio_chip *chip, unsigned offset, - int value) -{ - ltq_stp_set(chip, offset, value); - - return 0; -} - -static struct gpio_chip ltq_stp_chip = { - .label = "ltq_stp", - .direction_output = ltq_stp_direction_output, - .set = ltq_stp_set, - .base = 48, - .ngpio = 24, - .can_sleep = 1, - .owner = THIS_MODULE, -}; - -static int ltq_stp_hw_init(void) -{ - /* sane defaults */ - ltq_stp_w32(0, LTQ_STP_AR); - ltq_stp_w32(0, LTQ_STP_CPU0); - ltq_stp_w32(0, LTQ_STP_CPU1); - ltq_stp_w32(LTQ_STP_CON_SWU, LTQ_STP_CON0); - ltq_stp_w32(0, LTQ_STP_CON1); - - /* 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); - - /* 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); - return 0; -} - -static int __devinit ltq_stp_probe(struct platform_device *pdev) -{ - struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - int ret = 0; - - if (!res) - return -ENOENT; - res = devm_request_mem_region(&pdev->dev, res->start, - resource_size(res), dev_name(&pdev->dev)); - if (!res) { - dev_err(&pdev->dev, "failed to request STP memory\n"); - return -EBUSY; - } - ltq_stp_membase = devm_ioremap_nocache(&pdev->dev, res->start, - resource_size(res)); - if (!ltq_stp_membase) { - dev_err(&pdev->dev, "failed to remap STP memory\n"); - return -ENOMEM; - } - ret = gpiochip_add(<q_stp_chip); - if (!ret) - ret = ltq_stp_hw_init(); - - return ret; -} - -static struct platform_driver ltq_stp_driver = { - .probe = ltq_stp_probe, - .driver = { - .name = "ltq_stp", - .owner = THIS_MODULE, - }, -}; - -int __init ltq_stp_init(void) -{ - int ret = platform_driver_register(<q_stp_driver); - - if (ret) - pr_info("ltq_stp: error registering platfom driver"); - return ret; -} - -postcore_initcall(ltq_stp_init); -- cgit v1.2.2 From d41ced01f21ddd2c3a01531bb9edf6c41064e9fc Mon Sep 17 00:00:00 2001 From: John Crispin Date: Thu, 19 Apr 2012 16:16:11 +0200 Subject: MIPS: lantiq: implement support for FALCON soc Adds support for the FALCON SoC. This SoC is from the FTTH/GPON SoC family. Signed-off-by: Thomas Langer Signed-off-by: John Crispin Cc: linux-mips@linux-mips.org Patchwork: https://patchwork.linux-mips.org/patch/3814/ Signed-off-by: Ralf Baechle --- arch/mips/lantiq/Kconfig | 4 + arch/mips/lantiq/Makefile | 1 + arch/mips/lantiq/Platform | 1 + arch/mips/lantiq/falcon/Makefile | 1 + arch/mips/lantiq/falcon/prom.c | 87 +++++++++++++ arch/mips/lantiq/falcon/reset.c | 90 +++++++++++++ arch/mips/lantiq/falcon/sysctrl.c | 260 ++++++++++++++++++++++++++++++++++++++ 7 files changed, 444 insertions(+) create mode 100644 arch/mips/lantiq/falcon/Makefile create mode 100644 arch/mips/lantiq/falcon/prom.c create mode 100644 arch/mips/lantiq/falcon/reset.c create mode 100644 arch/mips/lantiq/falcon/sysctrl.c (limited to 'arch/mips/lantiq') diff --git a/arch/mips/lantiq/Kconfig b/arch/mips/lantiq/Kconfig index 7389098fd983..20bdf40b3efa 100644 --- a/arch/mips/lantiq/Kconfig +++ b/arch/mips/lantiq/Kconfig @@ -16,6 +16,10 @@ config SOC_XWAY bool "XWAY" select SOC_TYPE_XWAY select HW_HAS_PCI + +config SOC_FALCON + bool "FALCON" + endchoice choice diff --git a/arch/mips/lantiq/Makefile b/arch/mips/lantiq/Makefile index 16f1c758616b..d6bdc579419f 100644 --- a/arch/mips/lantiq/Makefile +++ b/arch/mips/lantiq/Makefile @@ -11,3 +11,4 @@ obj-y += dts/ obj-$(CONFIG_EARLY_PRINTK) += early_printk.o obj-$(CONFIG_SOC_TYPE_XWAY) += xway/ +obj-$(CONFIG_SOC_FALCON) += falcon/ diff --git a/arch/mips/lantiq/Platform b/arch/mips/lantiq/Platform index f3dff05722de..b3ec49838fd7 100644 --- a/arch/mips/lantiq/Platform +++ b/arch/mips/lantiq/Platform @@ -6,3 +6,4 @@ platform-$(CONFIG_LANTIQ) += lantiq/ cflags-$(CONFIG_LANTIQ) += -I$(srctree)/arch/mips/include/asm/mach-lantiq load-$(CONFIG_LANTIQ) = 0xffffffff80002000 cflags-$(CONFIG_SOC_TYPE_XWAY) += -I$(srctree)/arch/mips/include/asm/mach-lantiq/xway +cflags-$(CONFIG_SOC_FALCON) += -I$(srctree)/arch/mips/include/asm/mach-lantiq/falcon diff --git a/arch/mips/lantiq/falcon/Makefile b/arch/mips/lantiq/falcon/Makefile new file mode 100644 index 000000000000..ff220f97693d --- /dev/null +++ b/arch/mips/lantiq/falcon/Makefile @@ -0,0 +1 @@ +obj-y := prom.o reset.o sysctrl.o diff --git a/arch/mips/lantiq/falcon/prom.c b/arch/mips/lantiq/falcon/prom.c new file mode 100644 index 000000000000..c1d278f05a3a --- /dev/null +++ b/arch/mips/lantiq/falcon/prom.c @@ -0,0 +1,87 @@ +/* + * 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 + * Copyright (C) 2012 John Crispin + */ + +#include +#include + +#include + +#include "../prom.h" + +#define SOC_FALCON "Falcon" +#define SOC_FALCON_D "Falcon-D" +#define SOC_FALCON_V "Falcon-V" +#define SOC_FALCON_M "Falcon-M" + +#define COMP_FALCON "lantiq,falcon" + +#define PART_SHIFT 12 +#define PART_MASK 0x0FFFF000 +#define REV_SHIFT 28 +#define REV_MASK 0xF0000000 +#define SREV_SHIFT 22 +#define SREV_MASK 0x03C00000 +#define TYPE_SHIFT 26 +#define TYPE_MASK 0x3C000000 + +/* reset, nmi and ejtag exception vectors */ +#define BOOT_REG_BASE (KSEG1 | 0x1F200000) +#define BOOT_RVEC (BOOT_REG_BASE | 0x00) +#define BOOT_NVEC (BOOT_REG_BASE | 0x04) +#define BOOT_EVEC (BOOT_REG_BASE | 0x08) + +void __init ltq_soc_nmi_setup(void) +{ + extern void (*nmi_handler)(void); + + ltq_w32((unsigned long)&nmi_handler, (void *)BOOT_NVEC); +} + +void __init ltq_soc_ejtag_setup(void) +{ + extern void (*ejtag_debug_handler)(void); + + ltq_w32((unsigned long)&ejtag_debug_handler, (void *)BOOT_EVEC); +} + +void __init ltq_soc_detect(struct ltq_soc_info *i) +{ + u32 type; + i->partnum = (ltq_r32(FALCON_CHIPID) & PART_MASK) >> PART_SHIFT; + i->rev = (ltq_r32(FALCON_CHIPID) & REV_MASK) >> REV_SHIFT; + i->srev = ((ltq_r32(FALCON_CHIPCONF) & SREV_MASK) >> SREV_SHIFT); + i->compatible = COMP_FALCON; + i->type = SOC_TYPE_FALCON; + sprintf(i->rev_type, "%c%d%d", (i->srev & 0x4) ? ('B') : ('A'), + i->rev & 0x7, (i->srev & 0x3) + 1); + + switch (i->partnum) { + case SOC_ID_FALCON: + type = (ltq_r32(FALCON_CHIPTYPE) & TYPE_MASK) >> TYPE_SHIFT; + switch (type) { + case 0: + i->name = SOC_FALCON_D; + break; + case 1: + i->name = SOC_FALCON_V; + break; + case 2: + i->name = SOC_FALCON_M; + break; + default: + i->name = SOC_FALCON; + break; + } + break; + + default: + unreachable(); + break; + } +} diff --git a/arch/mips/lantiq/falcon/reset.c b/arch/mips/lantiq/falcon/reset.c new file mode 100644 index 000000000000..568248253426 --- /dev/null +++ b/arch/mips/lantiq/falcon/reset.c @@ -0,0 +1,90 @@ +/* + * 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 + * Copyright (C) 2012 John Crispin + */ + +#include +#include +#include +#include +#include + +#include + +/* CPU0 Reset Source Register */ +#define SYS1_CPU0RS 0x0040 +/* reset cause mask */ +#define CPU0RS_MASK 0x0003 +/* CPU0 Boot Mode Register */ +#define SYS1_BM 0x00a0 +/* boot mode mask */ +#define BM_MASK 0x0005 + +/* allow platform code to find out what surce we booted from */ +unsigned char ltq_boot_select(void) +{ + return ltq_sys1_r32(SYS1_BM) & BM_MASK; +} + +/* allow the watchdog driver to find out what the boot reason was */ +int ltq_reset_cause(void) +{ + return ltq_sys1_r32(SYS1_CPU0RS) & CPU0RS_MASK; +} +EXPORT_SYMBOL_GPL(ltq_reset_cause); + +#define BOOT_REG_BASE (KSEG1 | 0x1F200000) +#define BOOT_PW1_REG (BOOT_REG_BASE | 0x20) +#define BOOT_PW2_REG (BOOT_REG_BASE | 0x24) +#define BOOT_PW1 0x4C545100 +#define BOOT_PW2 0x0051544C + +#define WDT_REG_BASE (KSEG1 | 0x1F8803F0) +#define WDT_PW1 0x00BE0000 +#define WDT_PW2 0x00DC0000 + +static void machine_restart(char *command) +{ + local_irq_disable(); + + /* reboot magic */ + ltq_w32(BOOT_PW1, (void *)BOOT_PW1_REG); /* 'LTQ\0' */ + ltq_w32(BOOT_PW2, (void *)BOOT_PW2_REG); /* '\0QTL' */ + ltq_w32(0, (void *)BOOT_REG_BASE); /* reset Bootreg RVEC */ + + /* watchdog magic */ + ltq_w32(WDT_PW1, (void *)WDT_REG_BASE); + ltq_w32(WDT_PW2 | + (0x3 << 26) | /* PWL */ + (0x2 << 24) | /* CLKDIV */ + (0x1 << 31) | /* enable */ + (1), /* reload */ + (void *)WDT_REG_BASE); + unreachable(); +} + +static void machine_halt(void) +{ + local_irq_disable(); + unreachable(); +} + +static void machine_power_off(void) +{ + local_irq_disable(); + unreachable(); +} + +static int __init mips_reboot_setup(void) +{ + _machine_restart = machine_restart; + _machine_halt = machine_halt; + pm_power_off = machine_power_off; + return 0; +} + +arch_initcall(mips_reboot_setup); diff --git a/arch/mips/lantiq/falcon/sysctrl.c b/arch/mips/lantiq/falcon/sysctrl.c new file mode 100644 index 000000000000..ba0123d13d40 --- /dev/null +++ b/arch/mips/lantiq/falcon/sysctrl.c @@ -0,0 +1,260 @@ +/* + * 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 Thomas Langer + * Copyright (C) 2011 John Crispin + */ + +#include +#include +#include +#include +#include + +#include + +#include "../clk.h" + +/* infrastructure control register */ +#define SYS1_INFRAC 0x00bc +/* Configuration fuses for drivers and pll */ +#define STATUS_CONFIG 0x0040 + +/* GPE frequency selection */ +#define GPPC_OFFSET 24 +#define GPEFREQ_MASK 0x00000C0 +#define GPEFREQ_OFFSET 10 +/* Clock status register */ +#define SYSCTL_CLKS 0x0000 +/* Clock enable register */ +#define SYSCTL_CLKEN 0x0004 +/* Clock clear register */ +#define SYSCTL_CLKCLR 0x0008 +/* Activation Status Register */ +#define SYSCTL_ACTS 0x0020 +/* Activation Register */ +#define SYSCTL_ACT 0x0024 +/* Deactivation Register */ +#define SYSCTL_DEACT 0x0028 +/* reboot Register */ +#define SYSCTL_RBT 0x002c +/* CPU0 Clock Control Register */ +#define SYS1_CPU0CC 0x0040 +/* HRST_OUT_N Control Register */ +#define SYS1_HRSTOUTC 0x00c0 +/* clock divider bit */ +#define CPU0CC_CPUDIV 0x0001 + +/* Activation Status Register */ +#define ACTS_ASC1_ACT 0x00000800 +#define ACTS_I2C_ACT 0x00004000 +#define ACTS_P0 0x00010000 +#define ACTS_P1 0x00010000 +#define ACTS_P2 0x00020000 +#define ACTS_P3 0x00020000 +#define ACTS_P4 0x00040000 +#define ACTS_PADCTRL0 0x00100000 +#define ACTS_PADCTRL1 0x00100000 +#define ACTS_PADCTRL2 0x00200000 +#define ACTS_PADCTRL3 0x00200000 +#define ACTS_PADCTRL4 0x00400000 + +#define sysctl_w32(m, x, y) ltq_w32((x), sysctl_membase[m] + (y)) +#define sysctl_r32(m, x) ltq_r32(sysctl_membase[m] + (x)) +#define sysctl_w32_mask(m, clear, set, reg) \ + sysctl_w32(m, (sysctl_r32(m, reg) & ~(clear)) | (set), reg) + +#define status_w32(x, y) ltq_w32((x), status_membase + (y)) +#define status_r32(x) ltq_r32(status_membase + (x)) + +static void __iomem *sysctl_membase[3], *status_membase; +void __iomem *ltq_sys1_membase, *ltq_ebu_membase; + +void falcon_trigger_hrst(int level) +{ + sysctl_w32(SYSCTL_SYS1, level & 1, SYS1_HRSTOUTC); +} + +static inline void sysctl_wait(struct clk *clk, + unsigned int test, unsigned int reg) +{ + int err = 1000000; + + do {} while (--err && ((sysctl_r32(clk->module, reg) + & clk->bits) != test)); + if (!err) + pr_err("module de/activation failed %d %08X %08X %08X\n", + clk->module, clk->bits, test, + sysctl_r32(clk->module, reg) & clk->bits); +} + +static int sysctl_activate(struct clk *clk) +{ + sysctl_w32(clk->module, clk->bits, SYSCTL_CLKEN); + sysctl_w32(clk->module, clk->bits, SYSCTL_ACT); + sysctl_wait(clk, clk->bits, SYSCTL_ACTS); + return 0; +} + +static void sysctl_deactivate(struct clk *clk) +{ + sysctl_w32(clk->module, clk->bits, SYSCTL_CLKCLR); + sysctl_w32(clk->module, clk->bits, SYSCTL_DEACT); + sysctl_wait(clk, 0, SYSCTL_ACTS); +} + +static int sysctl_clken(struct clk *clk) +{ + sysctl_w32(clk->module, clk->bits, SYSCTL_CLKEN); + sysctl_wait(clk, clk->bits, SYSCTL_CLKS); + return 0; +} + +static void sysctl_clkdis(struct clk *clk) +{ + sysctl_w32(clk->module, clk->bits, SYSCTL_CLKCLR); + sysctl_wait(clk, 0, SYSCTL_CLKS); +} + +static void sysctl_reboot(struct clk *clk) +{ + unsigned int act; + unsigned int bits; + + act = sysctl_r32(clk->module, SYSCTL_ACT); + bits = ~act & clk->bits; + if (bits != 0) { + sysctl_w32(clk->module, bits, SYSCTL_CLKEN); + sysctl_w32(clk->module, bits, SYSCTL_ACT); + sysctl_wait(clk, bits, SYSCTL_ACTS); + } + sysctl_w32(clk->module, act & clk->bits, SYSCTL_RBT); + sysctl_wait(clk, clk->bits, SYSCTL_ACTS); +} + +/* enable the ONU core */ +static void falcon_gpe_enable(void) +{ + unsigned int freq; + unsigned int status; + + /* if if the clock is already enabled */ + status = sysctl_r32(SYSCTL_SYS1, SYS1_INFRAC); + if (status & (1 << (GPPC_OFFSET + 1))) + return; + + if (status_r32(STATUS_CONFIG) == 0) + freq = 1; /* use 625MHz on unfused chip */ + else + freq = (status_r32(STATUS_CONFIG) & + GPEFREQ_MASK) >> + GPEFREQ_OFFSET; + + /* apply new frequency */ + sysctl_w32_mask(SYSCTL_SYS1, 7 << (GPPC_OFFSET + 1), + freq << (GPPC_OFFSET + 2) , SYS1_INFRAC); + udelay(1); + + /* enable new frequency */ + sysctl_w32_mask(SYSCTL_SYS1, 0, 1 << (GPPC_OFFSET + 1), SYS1_INFRAC); + udelay(1); +} + +static inline void clkdev_add_sys(const char *dev, unsigned int module, + unsigned int bits) +{ + struct clk *clk = kzalloc(sizeof(struct clk), GFP_KERNEL); + + clk->cl.dev_id = dev; + clk->cl.con_id = NULL; + clk->cl.clk = clk; + clk->module = module; + clk->activate = sysctl_activate; + clk->deactivate = sysctl_deactivate; + clk->enable = sysctl_clken; + clk->disable = sysctl_clkdis; + clk->reboot = sysctl_reboot; + clkdev_add(&clk->cl); +} + +void __init ltq_soc_init(void) +{ + struct device_node *np_status = + of_find_compatible_node(NULL, NULL, "lantiq,status-falcon"); + struct device_node *np_ebu = + of_find_compatible_node(NULL, NULL, "lantiq,ebu-falcon"); + struct device_node *np_sys1 = + of_find_compatible_node(NULL, NULL, "lantiq,sys1-falcon"); + struct device_node *np_syseth = + of_find_compatible_node(NULL, NULL, "lantiq,syseth-falcon"); + struct device_node *np_sysgpe = + of_find_compatible_node(NULL, NULL, "lantiq,sysgpe-falcon"); + struct resource res_status, res_ebu, res_sys[3]; + int i; + + /* check if all the core register ranges are available */ + if (!np_status || !np_ebu || !np_sys1 || !np_syseth || !np_sysgpe) + panic("Failed to load core nodes from devicetree"); + + if (of_address_to_resource(np_status, 0, &res_status) || + of_address_to_resource(np_ebu, 0, &res_ebu) || + of_address_to_resource(np_sys1, 0, &res_sys[0]) || + of_address_to_resource(np_syseth, 0, &res_sys[1]) || + of_address_to_resource(np_sysgpe, 0, &res_sys[2])) + panic("Failed to get core resources"); + + if ((request_mem_region(res_status.start, resource_size(&res_status), + res_status.name) < 0) || + (request_mem_region(res_ebu.start, resource_size(&res_ebu), + res_ebu.name) < 0) || + (request_mem_region(res_sys[0].start, + resource_size(&res_sys[0]), + res_sys[0].name) < 0) || + (request_mem_region(res_sys[1].start, + resource_size(&res_sys[1]), + res_sys[1].name) < 0) || + (request_mem_region(res_sys[2].start, + resource_size(&res_sys[2]), + res_sys[2].name) < 0)) + pr_err("Failed to request core reources"); + + status_membase = ioremap_nocache(res_status.start, + resource_size(&res_status)); + ltq_ebu_membase = ioremap_nocache(res_ebu.start, + resource_size(&res_ebu)); + + if (!status_membase || !ltq_ebu_membase) + panic("Failed to remap core resources"); + + for (i = 0; i < 3; i++) { + sysctl_membase[i] = ioremap_nocache(res_sys[i].start, + resource_size(&res_sys[i])); + if (!sysctl_membase[i]) + panic("Failed to remap sysctrl resources"); + } + ltq_sys1_membase = sysctl_membase[0]; + + falcon_gpe_enable(); + + /* get our 3 static rates for cpu, fpi and io clocks */ + if (ltq_sys1_r32(SYS1_CPU0CC) & CPU0CC_CPUDIV) + clkdev_add_static(CLOCK_200M, CLOCK_100M, CLOCK_200M); + else + clkdev_add_static(CLOCK_400M, CLOCK_100M, CLOCK_200M); + + /* add our clock domains */ + clkdev_add_sys("1d810000.gpio", SYSCTL_SYSETH, ACTS_P0); + clkdev_add_sys("1d810100.gpio", SYSCTL_SYSETH, ACTS_P2); + clkdev_add_sys("1e800100.gpio", SYSCTL_SYS1, ACTS_P1); + clkdev_add_sys("1e800200.gpio", SYSCTL_SYS1, ACTS_P3); + clkdev_add_sys("1e800300.gpio", SYSCTL_SYS1, ACTS_P4); + clkdev_add_sys("1db01000.pad", SYSCTL_SYSETH, ACTS_PADCTRL0); + clkdev_add_sys("1db02000.pad", SYSCTL_SYSETH, ACTS_PADCTRL2); + clkdev_add_sys("1e800400.pad", SYSCTL_SYS1, ACTS_PADCTRL1); + clkdev_add_sys("1e800500.pad", SYSCTL_SYS1, ACTS_PADCTRL3); + clkdev_add_sys("1e800600.pad", SYSCTL_SYS1, ACTS_PADCTRL4); + clkdev_add_sys("1e100C00.serial", SYSCTL_SYS1, ACTS_ASC1_ACT); + clkdev_add_sys("1e200000.i2c", SYSCTL_SYS1, ACTS_I2C_ACT); +} -- cgit v1.2.2 From 009d6914f14d6c12a073e9ff8506a53047c308e7 Mon Sep 17 00:00:00 2001 From: John Crispin Date: Thu, 19 Apr 2012 16:23:14 +0200 Subject: MIPS: lantiq: remove orphaned code Now that all drivers are converted to OF we are able to remove some remaining pieces of orphaned code. Signed-off-by: John Crispin Cc: linux-mips@linux-mips.org Patchwork: https://patchwork.linux-mips.org/patch/3841/ Signed-off-by: Ralf Baechle --- arch/mips/lantiq/prom.c | 6 ------ arch/mips/lantiq/xway/sysctrl.c | 4 ++++ 2 files changed, 4 insertions(+), 6 deletions(-) (limited to 'arch/mips/lantiq') diff --git a/arch/mips/lantiq/prom.c b/arch/mips/lantiq/prom.c index 413ed53a4ae1..d185e8477fdf 100644 --- a/arch/mips/lantiq/prom.c +++ b/arch/mips/lantiq/prom.c @@ -27,12 +27,6 @@ EXPORT_SYMBOL_GPL(ebu_lock); */ static struct ltq_soc_info soc_info; -unsigned int ltq_get_soc_type(void) -{ - return soc_info.type; -} -EXPORT_SYMBOL(ltq_get_soc_type); - const char *get_system_type(void) { return soc_info.sys_type; diff --git a/arch/mips/lantiq/xway/sysctrl.c b/arch/mips/lantiq/xway/sysctrl.c index 4d6aac693535..83780f7c842b 100644 --- a/arch/mips/lantiq/xway/sysctrl.c +++ b/arch/mips/lantiq/xway/sysctrl.c @@ -42,6 +42,7 @@ /* clock gates that we can en/disable */ #define PMU_USB0_P BIT(0) #define PMU_PCI BIT(4) +#define PMU_DMA BIT(5) #define PMU_USB0 BIT(6) #define PMU_ASC0 BIT(7) #define PMU_EPHY BIT(7) /* ase */ @@ -49,7 +50,9 @@ #define PMU_DFE BIT(9) #define PMU_EBU BIT(10) #define PMU_STP BIT(11) +#define PMU_GPT BIT(12) #define PMU_AHBS BIT(13) /* vr9 */ +#define PMU_FPI BIT(14) #define PMU_AHBM BIT(15) #define PMU_ASC1 BIT(17) #define PMU_PPE_QSB BIT(18) @@ -60,6 +63,7 @@ #define PMU_PPE_DPLUS BIT(24) #define PMU_USB1_P BIT(26) #define PMU_USB1 BIT(27) +#define PMU_SWITCH BIT(28) #define PMU_PPE_TOP BIT(29) #define PMU_GPHY BIT(30) #define PMU_PCIE_CLK BIT(31) -- cgit v1.2.2