add patches for v3.8

Signed-off-by: John Crsipin <blogic@openwrt.org>

SVN-Revision: 36163
This commit is contained in:
John Crispin 2013-04-03 09:59:10 +00:00
parent 4f86ea43ca
commit 46f141637c
47 changed files with 36324 additions and 0 deletions

View file

@ -0,0 +1,148 @@
From 8563991026ee98bb5e477167236972a45dfea0e3 Mon Sep 17 00:00:00 2001
From: John Crispin <blogic@openwrt.org>
Date: Mon, 21 Jan 2013 18:25:59 +0100
Subject: [PATCH 01/14] MIPS: ralink: adds include files
Before we start adding the platform code we add the common include files.
Signed-off-by: John Crispin <blogic@openwrt.org>
Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
Patchwork: http://patchwork.linux-mips.org/patch/4893/
---
arch/mips/include/asm/mach-ralink/ralink_regs.h | 39 ++++++++++++++++++++
arch/mips/include/asm/mach-ralink/war.h | 25 +++++++++++++
arch/mips/ralink/common.h | 44 +++++++++++++++++++++++
3 files changed, 108 insertions(+)
create mode 100644 arch/mips/include/asm/mach-ralink/ralink_regs.h
create mode 100644 arch/mips/include/asm/mach-ralink/war.h
create mode 100644 arch/mips/ralink/common.h
diff --git a/arch/mips/include/asm/mach-ralink/ralink_regs.h b/arch/mips/include/asm/mach-ralink/ralink_regs.h
new file mode 100644
index 0000000..5a508f9
--- /dev/null
+++ b/arch/mips/include/asm/mach-ralink/ralink_regs.h
@@ -0,0 +1,39 @@
+/*
+ * Ralink SoC register definitions
+ *
+ * Copyright (C) 2013 John Crispin <blogic@openwrt.org>
+ * Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org>
+ * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
+ *
+ * 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.
+ */
+
+#ifndef _RALINK_REGS_H_
+#define _RALINK_REGS_H_
+
+extern __iomem void *rt_sysc_membase;
+extern __iomem void *rt_memc_membase;
+
+static inline void rt_sysc_w32(u32 val, unsigned reg)
+{
+ __raw_writel(val, rt_sysc_membase + reg);
+}
+
+static inline u32 rt_sysc_r32(unsigned reg)
+{
+ return __raw_readl(rt_sysc_membase + reg);
+}
+
+static inline void rt_memc_w32(u32 val, unsigned reg)
+{
+ __raw_writel(val, rt_memc_membase + reg);
+}
+
+static inline u32 rt_memc_r32(unsigned reg)
+{
+ return __raw_readl(rt_memc_membase + reg);
+}
+
+#endif /* _RALINK_REGS_H_ */
diff --git a/arch/mips/include/asm/mach-ralink/war.h b/arch/mips/include/asm/mach-ralink/war.h
new file mode 100644
index 0000000..a7b712c
--- /dev/null
+++ b/arch/mips/include/asm/mach-ralink/war.h
@@ -0,0 +1,25 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2002, 2004, 2007 by Ralf Baechle <ralf@linux-mips.org>
+ */
+#ifndef __ASM_MACH_RALINK_WAR_H
+#define __ASM_MACH_RALINK_WAR_H
+
+#define R4600_V1_INDEX_ICACHEOP_WAR 0
+#define R4600_V1_HIT_CACHEOP_WAR 0
+#define R4600_V2_HIT_CACHEOP_WAR 0
+#define R5432_CP0_INTERRUPT_WAR 0
+#define BCM1250_M3_WAR 0
+#define SIBYTE_1956_WAR 0
+#define MIPS4K_ICACHE_REFILL_WAR 0
+#define MIPS_CACHE_SYNC_WAR 0
+#define TX49XX_ICACHE_INDEX_INV_WAR 0
+#define RM9000_CDEX_SMP_WAR 0
+#define ICACHE_REFILLS_WORKAROUND_WAR 0
+#define R10000_LLSC_WAR 0
+#define MIPS34K_MISSED_ITLB_WAR 0
+
+#endif /* __ASM_MACH_RALINK_WAR_H */
diff --git a/arch/mips/ralink/common.h b/arch/mips/ralink/common.h
new file mode 100644
index 0000000..3009903
--- /dev/null
+++ b/arch/mips/ralink/common.h
@@ -0,0 +1,44 @@
+/*
+ * 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) 2013 John Crispin <blogic@openwrt.org>
+ */
+
+#ifndef _RALINK_COMMON_H__
+#define _RALINK_COMMON_H__
+
+#define RAMIPS_SYS_TYPE_LEN 32
+
+struct ralink_pinmux_grp {
+ const char *name;
+ u32 mask;
+ int gpio_first;
+ int gpio_last;
+};
+
+struct ralink_pinmux {
+ struct ralink_pinmux_grp *mode;
+ struct ralink_pinmux_grp *uart;
+ int uart_shift;
+ void (*wdt_reset)(void);
+};
+extern struct ralink_pinmux gpio_pinmux;
+
+struct ralink_soc_info {
+ unsigned char sys_type[RAMIPS_SYS_TYPE_LEN];
+ unsigned char *compatible;
+};
+extern struct ralink_soc_info soc_info;
+
+extern void ralink_of_remap(void);
+
+extern void ralink_clk_init(void);
+extern void ralink_clk_add(const char *dev, unsigned long rate);
+
+extern void prom_soc_init(struct ralink_soc_info *soc_info);
+
+__iomem void *plat_of_remap_node(const char *node);
+
+#endif /* _RALINK_COMMON_H__ */
--
1.7.10.4

View file

@ -0,0 +1,201 @@
From 19d3814e7b325f8965fd71f329b3467a97f8d217 Mon Sep 17 00:00:00 2001
From: John Crispin <blogic@openwrt.org>
Date: Sun, 20 Jan 2013 22:00:50 +0100
Subject: [PATCH 02/14] MIPS: ralink: adds irq code
All of the Ralink Wifi SoC currently supported by this series share the same
interrupt controller (INTC).
Signed-off-by: John Crispin <blogic@openwrt.org>
Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
Patchwork: http://patchwork.linux-mips.org/patch/4890/
---
arch/mips/ralink/irq.c | 176 ++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 176 insertions(+)
create mode 100644 arch/mips/ralink/irq.c
diff --git a/arch/mips/ralink/irq.c b/arch/mips/ralink/irq.c
new file mode 100644
index 0000000..e62c975
--- /dev/null
+++ b/arch/mips/ralink/irq.c
@@ -0,0 +1,176 @@
+/*
+ * 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) 2009 Gabor Juhos <juhosg@openwrt.org>
+ * Copyright (C) 2013 John Crispin <blogic@openwrt.org>
+ */
+
+#include <linux/io.h>
+#include <linux/bitops.h>
+#include <linux/of_platform.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
+#include <linux/irqdomain.h>
+#include <linux/interrupt.h>
+
+#include <asm/irq_cpu.h>
+#include <asm/mipsregs.h>
+
+#include "common.h"
+
+/* INTC register offsets */
+#define INTC_REG_STATUS0 0x00
+#define INTC_REG_STATUS1 0x04
+#define INTC_REG_TYPE 0x20
+#define INTC_REG_RAW_STATUS 0x30
+#define INTC_REG_ENABLE 0x34
+#define INTC_REG_DISABLE 0x38
+
+#define INTC_INT_GLOBAL BIT(31)
+
+#define RALINK_CPU_IRQ_INTC (MIPS_CPU_IRQ_BASE + 2)
+#define RALINK_CPU_IRQ_FE (MIPS_CPU_IRQ_BASE + 5)
+#define RALINK_CPU_IRQ_WIFI (MIPS_CPU_IRQ_BASE + 6)
+#define RALINK_CPU_IRQ_COUNTER (MIPS_CPU_IRQ_BASE + 7)
+
+/* we have a cascade of 8 irqs */
+#define RALINK_INTC_IRQ_BASE 8
+
+/* we have 32 SoC irqs */
+#define RALINK_INTC_IRQ_COUNT 32
+
+#define RALINK_INTC_IRQ_PERFC (RALINK_INTC_IRQ_BASE + 9)
+
+static void __iomem *rt_intc_membase;
+
+static inline void rt_intc_w32(u32 val, unsigned reg)
+{
+ __raw_writel(val, rt_intc_membase + reg);
+}
+
+static inline u32 rt_intc_r32(unsigned reg)
+{
+ return __raw_readl(rt_intc_membase + reg);
+}
+
+static void ralink_intc_irq_unmask(struct irq_data *d)
+{
+ rt_intc_w32(BIT(d->hwirq), INTC_REG_ENABLE);
+}
+
+static void ralink_intc_irq_mask(struct irq_data *d)
+{
+ rt_intc_w32(BIT(d->hwirq), INTC_REG_DISABLE);
+}
+
+static struct irq_chip ralink_intc_irq_chip = {
+ .name = "INTC",
+ .irq_unmask = ralink_intc_irq_unmask,
+ .irq_mask = ralink_intc_irq_mask,
+ .irq_mask_ack = ralink_intc_irq_mask,
+};
+
+unsigned int __cpuinit get_c0_compare_int(void)
+{
+ return CP0_LEGACY_COMPARE_IRQ;
+}
+
+static void ralink_intc_irq_handler(unsigned int irq, struct irq_desc *desc)
+{
+ u32 pending = rt_intc_r32(INTC_REG_STATUS0);
+
+ if (pending) {
+ struct irq_domain *domain = irq_get_handler_data(irq);
+ generic_handle_irq(irq_find_mapping(domain, __ffs(pending)));
+ } else {
+ spurious_interrupt();
+ }
+}
+
+asmlinkage void plat_irq_dispatch(void)
+{
+ unsigned long pending;
+
+ pending = read_c0_status() & read_c0_cause() & ST0_IM;
+
+ if (pending & STATUSF_IP7)
+ do_IRQ(RALINK_CPU_IRQ_COUNTER);
+
+ else if (pending & STATUSF_IP5)
+ do_IRQ(RALINK_CPU_IRQ_FE);
+
+ else if (pending & STATUSF_IP6)
+ do_IRQ(RALINK_CPU_IRQ_WIFI);
+
+ else if (pending & STATUSF_IP2)
+ do_IRQ(RALINK_CPU_IRQ_INTC);
+
+ else
+ spurious_interrupt();
+}
+
+static int intc_map(struct irq_domain *d, unsigned int irq, irq_hw_number_t hw)
+{
+ irq_set_chip_and_handler(irq, &ralink_intc_irq_chip, handle_level_irq);
+
+ return 0;
+}
+
+static const struct irq_domain_ops irq_domain_ops = {
+ .xlate = irq_domain_xlate_onecell,
+ .map = intc_map,
+};
+
+static int __init intc_of_init(struct device_node *node,
+ struct device_node *parent)
+{
+ struct resource res;
+ struct irq_domain *domain;
+
+ mips_cpu_irq_init();
+
+ if (of_address_to_resource(node, 0, &res))
+ panic("Failed to get intc memory range");
+
+ if (request_mem_region(res.start, resource_size(&res),
+ res.name) < 0)
+ pr_err("Failed to request intc memory");
+
+ rt_intc_membase = ioremap_nocache(res.start,
+ resource_size(&res));
+ if (!rt_intc_membase)
+ panic("Failed to remap intc memory");
+
+ /* disable all interrupts */
+ rt_intc_w32(~0, INTC_REG_DISABLE);
+
+ /* route all INTC interrupts to MIPS HW0 interrupt */
+ rt_intc_w32(0, INTC_REG_TYPE);
+
+ domain = irq_domain_add_legacy(node, RALINK_INTC_IRQ_COUNT,
+ RALINK_INTC_IRQ_BASE, 0, &irq_domain_ops, NULL);
+ if (!domain)
+ panic("Failed to add irqdomain");
+
+ rt_intc_w32(INTC_INT_GLOBAL, INTC_REG_ENABLE);
+
+ irq_set_chained_handler(RALINK_CPU_IRQ_INTC, ralink_intc_irq_handler);
+ irq_set_handler_data(RALINK_CPU_IRQ_INTC, domain);
+
+ cp0_perfcount_irq = irq_create_mapping(domain, 9);
+
+ return 0;
+}
+
+static struct of_device_id __initdata of_irq_ids[] = {
+ { .compatible = "ralink,rt2880-intc", .data = intc_of_init },
+ {},
+};
+
+void __init arch_init_irq(void)
+{
+ of_irq_init(of_irq_ids);
+}
+
--
1.7.10.4

View file

@ -0,0 +1,68 @@
From c06e836ada59fbc6d1109277e693e5b3e056ac12 Mon Sep 17 00:00:00 2001
From: John Crispin <blogic@openwrt.org>
Date: Sun, 20 Jan 2013 22:00:57 +0100
Subject: [PATCH 03/14] MIPS: ralink: adds reset code
Resetting these SoCs requires no real magic. The code is straight forward.
Signed-off-by: John Crispin <blogic@openwrt.org>
Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
Patchwork: http://patchwork.linux-mips.org/patch/4891/
---
arch/mips/ralink/reset.c | 44 ++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 44 insertions(+)
create mode 100644 arch/mips/ralink/reset.c
diff --git a/arch/mips/ralink/reset.c b/arch/mips/ralink/reset.c
new file mode 100644
index 0000000..22120e5
--- /dev/null
+++ b/arch/mips/ralink/reset.c
@@ -0,0 +1,44 @@
+/*
+ * 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) 2008-2009 Gabor Juhos <juhosg@openwrt.org>
+ * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
+ * Copyright (C) 2013 John Crispin <blogic@openwrt.org>
+ */
+
+#include <linux/pm.h>
+#include <linux/io.h>
+
+#include <asm/reboot.h>
+
+#include <asm/mach-ralink/ralink_regs.h>
+
+/* Reset Control */
+#define SYSC_REG_RESET_CTRL 0x034
+#define RSTCTL_RESET_SYSTEM BIT(0)
+
+static void ralink_restart(char *command)
+{
+ local_irq_disable();
+ rt_sysc_w32(RSTCTL_RESET_SYSTEM, SYSC_REG_RESET_CTRL);
+ unreachable();
+}
+
+static void ralink_halt(void)
+{
+ local_irq_disable();
+ unreachable();
+}
+
+static int __init mips_reboot_setup(void)
+{
+ _machine_restart = ralink_restart;
+ _machine_halt = ralink_halt;
+ pm_power_off = ralink_halt;
+
+ return 0;
+}
+
+arch_initcall(mips_reboot_setup);
--
1.7.10.4

View file

@ -0,0 +1,93 @@
From 7e47cefa69c8ed2c889522ce29fcce73ce8cf08e Mon Sep 17 00:00:00 2001
From: John Crispin <blogic@openwrt.org>
Date: Sun, 20 Jan 2013 22:01:05 +0100
Subject: [PATCH 04/14] MIPS: ralink: adds prom and cmdline code
Add minimal code to handle commandlines.
Signed-off-by: John Crispin <blogic@openwrt.org>
Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
Patchwork: http://patchwork.linux-mips.org/patch/4892/
---
arch/mips/ralink/prom.c | 69 +++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 69 insertions(+)
create mode 100644 arch/mips/ralink/prom.c
diff --git a/arch/mips/ralink/prom.c b/arch/mips/ralink/prom.c
new file mode 100644
index 0000000..9c64f02
--- /dev/null
+++ b/arch/mips/ralink/prom.c
@@ -0,0 +1,69 @@
+/*
+ * 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) 2009 Gabor Juhos <juhosg@openwrt.org>
+ * Copyright (C) 2010 Joonas Lahtinen <joonas.lahtinen@gmail.com>
+ * Copyright (C) 2013 John Crispin <blogic@openwrt.org>
+ */
+
+#include <linux/string.h>
+#include <linux/of_fdt.h>
+#include <linux/of_platform.h>
+
+#include <asm/bootinfo.h>
+#include <asm/addrspace.h>
+
+#include "common.h"
+
+struct ralink_soc_info soc_info;
+
+const char *get_system_type(void)
+{
+ return soc_info.sys_type;
+}
+
+static __init void prom_init_cmdline(int argc, char **argv)
+{
+ int i;
+
+ pr_debug("prom: fw_arg0=%08x fw_arg1=%08x fw_arg2=%08x fw_arg3=%08x\n",
+ (unsigned int)fw_arg0, (unsigned int)fw_arg1,
+ (unsigned int)fw_arg2, (unsigned int)fw_arg3);
+
+ argc = fw_arg0;
+ argv = (char **) KSEG1ADDR(fw_arg1);
+
+ if (!argv) {
+ pr_debug("argv=%p is invalid, skipping\n",
+ argv);
+ return;
+ }
+
+ for (i = 0; i < argc; i++) {
+ char *p = (char *) KSEG1ADDR(argv[i]);
+
+ if (CPHYSADDR(p) && *p) {
+ pr_debug("argv[%d]: %s\n", i, p);
+ strlcat(arcs_cmdline, " ", sizeof(arcs_cmdline));
+ strlcat(arcs_cmdline, p, sizeof(arcs_cmdline));
+ }
+ }
+}
+
+void __init prom_init(void)
+{
+ int argc;
+ char **argv;
+
+ prom_soc_init(&soc_info);
+
+ pr_info("SoC Type: %s\n", get_system_type());
+
+ prom_init_cmdline(argc, argv);
+}
+
+void __init prom_free_prom_memory(void)
+{
+}
--
1.7.10.4

View file

@ -0,0 +1,97 @@
From 3f0a06b0368d25608841843e9d65a7289ad9f14a Mon Sep 17 00:00:00 2001
From: John Crispin <blogic@openwrt.org>
Date: Sun, 20 Jan 2013 22:01:29 +0100
Subject: [PATCH 05/14] MIPS: ralink: adds clkdev code
These SoCs have a limited number of fixed rate clocks. Add support for the
clk and clkdev api.
Signed-off-by: John Crispin <blogic@openwrt.org>
Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
Patchwork: http://patchwork.linux-mips.org/patch/4894/
---
arch/mips/ralink/clk.c | 72 ++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 72 insertions(+)
create mode 100644 arch/mips/ralink/clk.c
diff --git a/arch/mips/ralink/clk.c b/arch/mips/ralink/clk.c
new file mode 100644
index 0000000..8dfa22f
--- /dev/null
+++ b/arch/mips/ralink/clk.c
@@ -0,0 +1,72 @@
+/*
+ * 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 Gabor Juhos <juhosg@openwrt.org>
+ * Copyright (C) 2013 John Crispin <blogic@openwrt.org>
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/clkdev.h>
+#include <linux/clk.h>
+
+#include <asm/time.h>
+
+#include "common.h"
+
+struct clk {
+ struct clk_lookup cl;
+ unsigned long rate;
+};
+
+void ralink_clk_add(const char *dev, unsigned long rate)
+{
+ struct clk *clk = kzalloc(sizeof(struct clk), GFP_KERNEL);
+
+ if (!clk)
+ panic("failed to add clock\n");
+
+ clk->cl.dev_id = dev;
+ clk->cl.clk = clk;
+
+ clk->rate = rate;
+
+ clkdev_add(&clk->cl);
+}
+
+/*
+ * Linux clock API
+ */
+int clk_enable(struct clk *clk)
+{
+ return 0;
+}
+EXPORT_SYMBOL_GPL(clk_enable);
+
+void clk_disable(struct clk *clk)
+{
+}
+EXPORT_SYMBOL_GPL(clk_disable);
+
+unsigned long clk_get_rate(struct clk *clk)
+{
+ return clk->rate;
+}
+EXPORT_SYMBOL_GPL(clk_get_rate);
+
+void __init plat_time_init(void)
+{
+ struct clk *clk;
+
+ ralink_of_remap();
+
+ ralink_clk_init();
+ clk = clk_get_sys("cpu", NULL);
+ if (IS_ERR(clk))
+ panic("unable to get CPU clock, err=%ld", PTR_ERR(clk));
+ pr_info("CPU Clock: %ldMHz\n", clk_get_rate(clk) / 1000000);
+ mips_hpt_frequency = clk_get_rate(clk) / 2;
+ clk_put(clk);
+}
--
1.7.10.4

View file

@ -0,0 +1,133 @@
From 3a5bfe7bdbfd37c9206d7c6dfd7eb9664ccc5038 Mon Sep 17 00:00:00 2001
From: John Crispin <blogic@openwrt.org>
Date: Sun, 20 Jan 2013 22:02:01 +0100
Subject: [PATCH 06/14] MIPS: ralink: adds OF code
Until there is a generic MIPS way of handing the DTB over from bootloader to
kernel we rely on a built in devicetrees. The OF code also remaps those register
ranges that we use global in our drivers.
Signed-off-by: John Crispin <blogic@openwrt.org>
Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
Patchwork: http://patchwork.linux-mips.org/patch/4895/
---
arch/mips/ralink/of.c | 107 +++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 107 insertions(+)
create mode 100644 arch/mips/ralink/of.c
diff --git a/arch/mips/ralink/of.c b/arch/mips/ralink/of.c
new file mode 100644
index 0000000..4165e70
--- /dev/null
+++ b/arch/mips/ralink/of.c
@@ -0,0 +1,107 @@
+/*
+ * 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) 2008 Imre Kaloz <kaloz@openwrt.org>
+ * Copyright (C) 2008-2009 Gabor Juhos <juhosg@openwrt.org>
+ * Copyright (C) 2013 John Crispin <blogic@openwrt.org>
+ */
+
+#include <linux/io.h>
+#include <linux/clk.h>
+#include <linux/init.h>
+#include <linux/of_fdt.h>
+#include <linux/kernel.h>
+#include <linux/bootmem.h>
+#include <linux/of_platform.h>
+#include <linux/of_address.h>
+
+#include <asm/reboot.h>
+#include <asm/bootinfo.h>
+#include <asm/addrspace.h>
+
+#include "common.h"
+
+__iomem void *rt_sysc_membase;
+__iomem void *rt_memc_membase;
+
+extern struct boot_param_header __dtb_start;
+
+__iomem void *plat_of_remap_node(const char *node)
+{
+ struct resource res;
+ struct device_node *np;
+
+ np = of_find_compatible_node(NULL, NULL, node);
+ if (!np)
+ panic("Failed to find %s node", node);
+
+ if (of_address_to_resource(np, 0, &res))
+ panic("Failed to get resource for %s", node);
+
+ if ((request_mem_region(res.start,
+ resource_size(&res),
+ res.name) < 0))
+ panic("Failed to request resources for %s", node);
+
+ return ioremap_nocache(res.start, resource_size(&res));
+}
+
+void __init device_tree_init(void)
+{
+ unsigned long base, size;
+ void *fdt_copy;
+
+ if (!initial_boot_params)
+ return;
+
+ base = virt_to_phys((void *)initial_boot_params);
+ size = be32_to_cpu(initial_boot_params->totalsize);
+
+ /* Before we do anything, lets reserve the dt blob */
+ reserve_bootmem(base, size, BOOTMEM_DEFAULT);
+
+ /* The strings in the flattened tree are referenced directly by the
+ * device tree, so copy the flattened device tree from init memory
+ * to regular memory.
+ */
+ fdt_copy = alloc_bootmem(size);
+ memcpy(fdt_copy, initial_boot_params, size);
+ initial_boot_params = fdt_copy;
+
+ unflatten_device_tree();
+
+ /* free the space reserved for the dt blob */
+ free_bootmem(base, size);
+}
+
+void __init plat_mem_setup(void)
+{
+ set_io_port_base(KSEG1);
+
+ /*
+ * Load the builtin devicetree. This causes the chosen node to be
+ * parsed resulting in our memory appearing
+ */
+ __dt_setup_arch(&__dtb_start);
+}
+
+static int __init plat_of_setup(void)
+{
+ static struct of_device_id of_ids[3];
+ int len = sizeof(of_ids[0].compatible);
+
+ if (!of_have_populated_dt())
+ panic("device tree not present");
+
+ strncpy(of_ids[0].compatible, soc_info.compatible, len);
+ strncpy(of_ids[1].compatible, "palmbus", len);
+
+ if (of_platform_populate(NULL, of_ids, NULL, NULL))
+ panic("failed to populate DT\n");
+
+ return 0;
+}
+
+arch_initcall(plat_of_setup);
--
1.7.10.4

View file

@ -0,0 +1,68 @@
From 5fff610b7c60195de98e68bec00c357f393ce634 Mon Sep 17 00:00:00 2001
From: John Crispin <blogic@openwrt.org>
Date: Sun, 20 Jan 2013 22:02:55 +0100
Subject: [PATCH 07/14] MIPS: ralink: adds early_printk support
Add the code needed to make early printk work.
Signed-off-by: John Crispin <blogic@openwrt.org>
Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
Patchwork: http://patchwork.linux-mips.org/patch/4897/
---
arch/mips/ralink/early_printk.c | 44 +++++++++++++++++++++++++++++++++++++++
1 file changed, 44 insertions(+)
create mode 100644 arch/mips/ralink/early_printk.c
diff --git a/arch/mips/ralink/early_printk.c b/arch/mips/ralink/early_printk.c
new file mode 100644
index 0000000..c4ae47e
--- /dev/null
+++ b/arch/mips/ralink/early_printk.c
@@ -0,0 +1,44 @@
+/*
+ * 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 Gabor Juhos <juhosg@openwrt.org>
+ */
+
+#include <linux/io.h>
+#include <linux/serial_reg.h>
+
+#include <asm/addrspace.h>
+
+#define EARLY_UART_BASE 0x10000c00
+
+#define UART_REG_RX 0x00
+#define UART_REG_TX 0x04
+#define UART_REG_IER 0x08
+#define UART_REG_IIR 0x0c
+#define UART_REG_FCR 0x10
+#define UART_REG_LCR 0x14
+#define UART_REG_MCR 0x18
+#define UART_REG_LSR 0x1c
+
+static __iomem void *uart_membase = (__iomem void *) KSEG1ADDR(EARLY_UART_BASE);
+
+static inline void uart_w32(u32 val, unsigned reg)
+{
+ __raw_writel(val, uart_membase + reg);
+}
+
+static inline u32 uart_r32(unsigned reg)
+{
+ return __raw_readl(uart_membase + reg);
+}
+
+void prom_putchar(unsigned char ch)
+{
+ while ((uart_r32(UART_REG_LSR) & UART_LSR_THRE) == 0)
+ ;
+ uart_w32(ch, UART_REG_TX);
+ while ((uart_r32(UART_REG_LSR) & UART_LSR_THRE) == 0)
+ ;
+}
--
1.7.10.4

View file

@ -0,0 +1,415 @@
From 2809b31770d7fd934a748692e1922a5e613f06e5 Mon Sep 17 00:00:00 2001
From: John Crispin <blogic@openwrt.org>
Date: Sun, 20 Jan 2013 22:03:46 +0100
Subject: [PATCH 08/14] MIPS: ralink: adds support for RT305x SoC family
Add support code for rt3050, rt3052, rt3350, rt3352 and rt5350 SOC.
The code detects the SoC and registers the clk / pinmux settings.
Signed-off-by: John Crispin <blogic@openwrt.org>
Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
Patchwork: http://patchwork.linux-mips.org/patch/4896/
---
arch/mips/include/asm/mach-ralink/rt305x.h | 139 ++++++++++++++++
arch/mips/ralink/rt305x.c | 242 ++++++++++++++++++++++++++++
2 files changed, 381 insertions(+)
create mode 100644 arch/mips/include/asm/mach-ralink/rt305x.h
create mode 100644 arch/mips/ralink/rt305x.c
diff --git a/arch/mips/include/asm/mach-ralink/rt305x.h b/arch/mips/include/asm/mach-ralink/rt305x.h
new file mode 100644
index 0000000..7d344f2
--- /dev/null
+++ b/arch/mips/include/asm/mach-ralink/rt305x.h
@@ -0,0 +1,139 @@
+/*
+ * 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.
+ *
+ * Parts of this file are based on Ralink's 2.6.21 BSP
+ *
+ * Copyright (C) 2008-2011 Gabor Juhos <juhosg@openwrt.org>
+ * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
+ * Copyright (C) 2013 John Crispin <blogic@openwrt.org>
+ */
+
+#ifndef _RT305X_REGS_H_
+#define _RT305X_REGS_H_
+
+enum rt305x_soc_type {
+ RT305X_SOC_UNKNOWN = 0,
+ RT305X_SOC_RT3050,
+ RT305X_SOC_RT3052,
+ RT305X_SOC_RT3350,
+ RT305X_SOC_RT3352,
+ RT305X_SOC_RT5350,
+};
+
+extern enum rt305x_soc_type rt305x_soc;
+
+static inline int soc_is_rt3050(void)
+{
+ return rt305x_soc == RT305X_SOC_RT3050;
+}
+
+static inline int soc_is_rt3052(void)
+{
+ return rt305x_soc == RT305X_SOC_RT3052;
+}
+
+static inline int soc_is_rt305x(void)
+{
+ return soc_is_rt3050() || soc_is_rt3052();
+}
+
+static inline int soc_is_rt3350(void)
+{
+ return rt305x_soc == RT305X_SOC_RT3350;
+}
+
+static inline int soc_is_rt3352(void)
+{
+ return rt305x_soc == RT305X_SOC_RT3352;
+}
+
+static inline int soc_is_rt5350(void)
+{
+ return rt305x_soc == RT305X_SOC_RT5350;
+}
+
+#define RT305X_SYSC_BASE 0x10000000
+
+#define SYSC_REG_CHIP_NAME0 0x00
+#define SYSC_REG_CHIP_NAME1 0x04
+#define SYSC_REG_CHIP_ID 0x0c
+#define SYSC_REG_SYSTEM_CONFIG 0x10
+
+#define RT3052_CHIP_NAME0 0x30335452
+#define RT3052_CHIP_NAME1 0x20203235
+
+#define RT3350_CHIP_NAME0 0x33335452
+#define RT3350_CHIP_NAME1 0x20203035
+
+#define RT3352_CHIP_NAME0 0x33335452
+#define RT3352_CHIP_NAME1 0x20203235
+
+#define RT5350_CHIP_NAME0 0x33355452
+#define RT5350_CHIP_NAME1 0x20203035
+
+#define CHIP_ID_ID_MASK 0xff
+#define CHIP_ID_ID_SHIFT 8
+#define CHIP_ID_REV_MASK 0xff
+
+#define RT305X_SYSCFG_CPUCLK_SHIFT 18
+#define RT305X_SYSCFG_CPUCLK_MASK 0x1
+#define RT305X_SYSCFG_CPUCLK_LOW 0x0
+#define RT305X_SYSCFG_CPUCLK_HIGH 0x1
+
+#define RT305X_SYSCFG_SRAM_CS0_MODE_SHIFT 2
+#define RT305X_SYSCFG_CPUCLK_MASK 0x1
+#define RT305X_SYSCFG_SRAM_CS0_MODE_WDT 0x1
+
+#define RT3352_SYSCFG0_CPUCLK_SHIFT 8
+#define RT3352_SYSCFG0_CPUCLK_MASK 0x1
+#define RT3352_SYSCFG0_CPUCLK_LOW 0x0
+#define RT3352_SYSCFG0_CPUCLK_HIGH 0x1
+
+#define RT5350_SYSCFG0_CPUCLK_SHIFT 8
+#define RT5350_SYSCFG0_CPUCLK_MASK 0x3
+#define RT5350_SYSCFG0_CPUCLK_360 0x0
+#define RT5350_SYSCFG0_CPUCLK_320 0x2
+#define RT5350_SYSCFG0_CPUCLK_300 0x3
+
+/* multi function gpio pins */
+#define RT305X_GPIO_I2C_SD 1
+#define RT305X_GPIO_I2C_SCLK 2
+#define RT305X_GPIO_SPI_EN 3
+#define RT305X_GPIO_SPI_CLK 4
+/* GPIO 7-14 is shared between UART0, PCM and I2S interfaces */
+#define RT305X_GPIO_7 7
+#define RT305X_GPIO_10 10
+#define RT305X_GPIO_14 14
+#define RT305X_GPIO_UART1_TXD 15
+#define RT305X_GPIO_UART1_RXD 16
+#define RT305X_GPIO_JTAG_TDO 17
+#define RT305X_GPIO_JTAG_TDI 18
+#define RT305X_GPIO_MDIO_MDC 22
+#define RT305X_GPIO_MDIO_MDIO 23
+#define RT305X_GPIO_SDRAM_MD16 24
+#define RT305X_GPIO_SDRAM_MD31 39
+#define RT305X_GPIO_GE0_TXD0 40
+#define RT305X_GPIO_GE0_RXCLK 51
+
+#define RT305X_GPIO_MODE_I2C BIT(0)
+#define RT305X_GPIO_MODE_SPI BIT(1)
+#define RT305X_GPIO_MODE_UART0_SHIFT 2
+#define RT305X_GPIO_MODE_UART0_MASK 0x7
+#define RT305X_GPIO_MODE_UART0(x) ((x) << RT305X_GPIO_MODE_UART0_SHIFT)
+#define RT305X_GPIO_MODE_UARTF 0x0
+#define RT305X_GPIO_MODE_PCM_UARTF 0x1
+#define RT305X_GPIO_MODE_PCM_I2S 0x2
+#define RT305X_GPIO_MODE_I2S_UARTF 0x3
+#define RT305X_GPIO_MODE_PCM_GPIO 0x4
+#define RT305X_GPIO_MODE_GPIO_UARTF 0x5
+#define RT305X_GPIO_MODE_GPIO_I2S 0x6
+#define RT305X_GPIO_MODE_GPIO 0x7
+#define RT305X_GPIO_MODE_UART1 BIT(5)
+#define RT305X_GPIO_MODE_JTAG BIT(6)
+#define RT305X_GPIO_MODE_MDIO BIT(7)
+#define RT305X_GPIO_MODE_SDRAM BIT(8)
+#define RT305X_GPIO_MODE_RGMII BIT(9)
+
+#endif
diff --git a/arch/mips/ralink/rt305x.c b/arch/mips/ralink/rt305x.c
new file mode 100644
index 0000000..0a4bbdc
--- /dev/null
+++ b/arch/mips/ralink/rt305x.c
@@ -0,0 +1,242 @@
+/*
+ * 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.
+ *
+ * Parts of this file are based on Ralink's 2.6.21 BSP
+ *
+ * Copyright (C) 2008-2011 Gabor Juhos <juhosg@openwrt.org>
+ * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
+ * Copyright (C) 2013 John Crispin <blogic@openwrt.org>
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/module.h>
+
+#include <asm/mipsregs.h>
+#include <asm/mach-ralink/ralink_regs.h>
+#include <asm/mach-ralink/rt305x.h>
+
+#include "common.h"
+
+enum rt305x_soc_type rt305x_soc;
+
+struct ralink_pinmux_grp mode_mux[] = {
+ {
+ .name = "i2c",
+ .mask = RT305X_GPIO_MODE_I2C,
+ .gpio_first = RT305X_GPIO_I2C_SD,
+ .gpio_last = RT305X_GPIO_I2C_SCLK,
+ }, {
+ .name = "spi",
+ .mask = RT305X_GPIO_MODE_SPI,
+ .gpio_first = RT305X_GPIO_SPI_EN,
+ .gpio_last = RT305X_GPIO_SPI_CLK,
+ }, {
+ .name = "uartlite",
+ .mask = RT305X_GPIO_MODE_UART1,
+ .gpio_first = RT305X_GPIO_UART1_TXD,
+ .gpio_last = RT305X_GPIO_UART1_RXD,
+ }, {
+ .name = "jtag",
+ .mask = RT305X_GPIO_MODE_JTAG,
+ .gpio_first = RT305X_GPIO_JTAG_TDO,
+ .gpio_last = RT305X_GPIO_JTAG_TDI,
+ }, {
+ .name = "mdio",
+ .mask = RT305X_GPIO_MODE_MDIO,
+ .gpio_first = RT305X_GPIO_MDIO_MDC,
+ .gpio_last = RT305X_GPIO_MDIO_MDIO,
+ }, {
+ .name = "sdram",
+ .mask = RT305X_GPIO_MODE_SDRAM,
+ .gpio_first = RT305X_GPIO_SDRAM_MD16,
+ .gpio_last = RT305X_GPIO_SDRAM_MD31,
+ }, {
+ .name = "rgmii",
+ .mask = RT305X_GPIO_MODE_RGMII,
+ .gpio_first = RT305X_GPIO_GE0_TXD0,
+ .gpio_last = RT305X_GPIO_GE0_RXCLK,
+ }, {0}
+};
+
+struct ralink_pinmux_grp uart_mux[] = {
+ {
+ .name = "uartf",
+ .mask = RT305X_GPIO_MODE_UARTF,
+ .gpio_first = RT305X_GPIO_7,
+ .gpio_last = RT305X_GPIO_14,
+ }, {
+ .name = "pcm uartf",
+ .mask = RT305X_GPIO_MODE_PCM_UARTF,
+ .gpio_first = RT305X_GPIO_7,
+ .gpio_last = RT305X_GPIO_14,
+ }, {
+ .name = "pcm i2s",
+ .mask = RT305X_GPIO_MODE_PCM_I2S,
+ .gpio_first = RT305X_GPIO_7,
+ .gpio_last = RT305X_GPIO_14,
+ }, {
+ .name = "i2s uartf",
+ .mask = RT305X_GPIO_MODE_I2S_UARTF,
+ .gpio_first = RT305X_GPIO_7,
+ .gpio_last = RT305X_GPIO_14,
+ }, {
+ .name = "pcm gpio",
+ .mask = RT305X_GPIO_MODE_PCM_GPIO,
+ .gpio_first = RT305X_GPIO_10,
+ .gpio_last = RT305X_GPIO_14,
+ }, {
+ .name = "gpio uartf",
+ .mask = RT305X_GPIO_MODE_GPIO_UARTF,
+ .gpio_first = RT305X_GPIO_7,
+ .gpio_last = RT305X_GPIO_14,
+ }, {
+ .name = "gpio i2s",
+ .mask = RT305X_GPIO_MODE_GPIO_I2S,
+ .gpio_first = RT305X_GPIO_7,
+ .gpio_last = RT305X_GPIO_14,
+ }, {
+ .name = "gpio",
+ .mask = RT305X_GPIO_MODE_GPIO,
+ }, {0}
+};
+
+void rt305x_wdt_reset(void)
+{
+ u32 t;
+
+ /* enable WDT reset output on pin SRAM_CS_N */
+ t = rt_sysc_r32(SYSC_REG_SYSTEM_CONFIG);
+ t |= RT305X_SYSCFG_SRAM_CS0_MODE_WDT <<
+ RT305X_SYSCFG_SRAM_CS0_MODE_SHIFT;
+ rt_sysc_w32(t, SYSC_REG_SYSTEM_CONFIG);
+}
+
+struct ralink_pinmux gpio_pinmux = {
+ .mode = mode_mux,
+ .uart = uart_mux,
+ .uart_shift = RT305X_GPIO_MODE_UART0_SHIFT,
+ .wdt_reset = rt305x_wdt_reset,
+};
+
+void __init ralink_clk_init(void)
+{
+ unsigned long cpu_rate, sys_rate, wdt_rate, uart_rate;
+ u32 t = rt_sysc_r32(SYSC_REG_SYSTEM_CONFIG);
+
+ if (soc_is_rt305x() || soc_is_rt3350()) {
+ t = (t >> RT305X_SYSCFG_CPUCLK_SHIFT) &
+ RT305X_SYSCFG_CPUCLK_MASK;
+ switch (t) {
+ case RT305X_SYSCFG_CPUCLK_LOW:
+ cpu_rate = 320000000;
+ break;
+ case RT305X_SYSCFG_CPUCLK_HIGH:
+ cpu_rate = 384000000;
+ break;
+ }
+ sys_rate = uart_rate = wdt_rate = cpu_rate / 3;
+ } else if (soc_is_rt3352()) {
+ t = (t >> RT3352_SYSCFG0_CPUCLK_SHIFT) &
+ RT3352_SYSCFG0_CPUCLK_MASK;
+ switch (t) {
+ case RT3352_SYSCFG0_CPUCLK_LOW:
+ cpu_rate = 384000000;
+ break;
+ case RT3352_SYSCFG0_CPUCLK_HIGH:
+ cpu_rate = 400000000;
+ break;
+ }
+ sys_rate = wdt_rate = cpu_rate / 3;
+ uart_rate = 40000000;
+ } else if (soc_is_rt5350()) {
+ t = (t >> RT5350_SYSCFG0_CPUCLK_SHIFT) &
+ RT5350_SYSCFG0_CPUCLK_MASK;
+ switch (t) {
+ case RT5350_SYSCFG0_CPUCLK_360:
+ cpu_rate = 360000000;
+ sys_rate = cpu_rate / 3;
+ break;
+ case RT5350_SYSCFG0_CPUCLK_320:
+ cpu_rate = 320000000;
+ sys_rate = cpu_rate / 4;
+ break;
+ case RT5350_SYSCFG0_CPUCLK_300:
+ cpu_rate = 300000000;
+ sys_rate = cpu_rate / 3;
+ break;
+ default:
+ BUG();
+ }
+ uart_rate = 40000000;
+ wdt_rate = sys_rate;
+ } else {
+ BUG();
+ }
+
+ ralink_clk_add("cpu", cpu_rate);
+ ralink_clk_add("10000b00.spi", sys_rate);
+ ralink_clk_add("10000100.timer", wdt_rate);
+ ralink_clk_add("10000500.uart", uart_rate);
+ ralink_clk_add("10000c00.uartlite", uart_rate);
+}
+
+void __init ralink_of_remap(void)
+{
+ rt_sysc_membase = plat_of_remap_node("ralink,rt3050-sysc");
+ rt_memc_membase = plat_of_remap_node("ralink,rt3050-memc");
+
+ if (!rt_sysc_membase || !rt_memc_membase)
+ panic("Failed to remap core resources");
+}
+
+void prom_soc_init(struct ralink_soc_info *soc_info)
+{
+ void __iomem *sysc = (void __iomem *) KSEG1ADDR(RT305X_SYSC_BASE);
+ unsigned char *name;
+ u32 n0;
+ u32 n1;
+ u32 id;
+
+ n0 = __raw_readl(sysc + SYSC_REG_CHIP_NAME0);
+ n1 = __raw_readl(sysc + SYSC_REG_CHIP_NAME1);
+
+ if (n0 == RT3052_CHIP_NAME0 && n1 == RT3052_CHIP_NAME1) {
+ unsigned long icache_sets;
+
+ icache_sets = (read_c0_config1() >> 22) & 7;
+ if (icache_sets == 1) {
+ rt305x_soc = RT305X_SOC_RT3050;
+ name = "RT3050";
+ soc_info->compatible = "ralink,rt3050-soc";
+ } else {
+ rt305x_soc = RT305X_SOC_RT3052;
+ name = "RT3052";
+ soc_info->compatible = "ralink,rt3052-soc";
+ }
+ } else if (n0 == RT3350_CHIP_NAME0 && n1 == RT3350_CHIP_NAME1) {
+ rt305x_soc = RT305X_SOC_RT3350;
+ name = "RT3350";
+ soc_info->compatible = "ralink,rt3350-soc";
+ } else if (n0 == RT3352_CHIP_NAME0 && n1 == RT3352_CHIP_NAME1) {
+ rt305x_soc = RT305X_SOC_RT3352;
+ name = "RT3352";
+ soc_info->compatible = "ralink,rt3352-soc";
+ } else if (n0 == RT5350_CHIP_NAME0 && n1 == RT5350_CHIP_NAME1) {
+ rt305x_soc = RT305X_SOC_RT5350;
+ name = "RT5350";
+ soc_info->compatible = "ralink,rt5350-soc";
+ } else {
+ panic("rt305x: unknown SoC, n0:%08x n1:%08x\n", n0, n1);
+ }
+
+ id = __raw_readl(sysc + SYSC_REG_CHIP_ID);
+
+ snprintf(soc_info->sys_type, RAMIPS_SYS_TYPE_LEN,
+ "Ralink %s id:%u rev:%u",
+ name,
+ (id >> CHIP_ID_ID_SHIFT) & CHIP_ID_ID_MASK,
+ (id & CHIP_ID_REV_MASK));
+}
--
1.7.10.4

View file

@ -0,0 +1,180 @@
From 5644da4f635a30fc03b4f12d81b2197d716d9cef Mon Sep 17 00:00:00 2001
From: John Crispin <blogic@openwrt.org>
Date: Tue, 22 Jan 2013 20:19:33 +0100
Subject: [PATCH 09/14] MIPS: ralink: adds rt305x devicetree
This adds the devicetree file that describes the rt305x evaluation kit.
Signed-off-by: John Crispin <blogic@openwrt.org>
Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
Patchwork: http://patchwork.linux-mips.org/patch/4898/
---
arch/mips/ralink/dts/rt3050.dtsi | 96 ++++++++++++++++++++++++++++++++++
arch/mips/ralink/dts/rt3052_eval.dts | 52 ++++++++++++++++++
2 files changed, 148 insertions(+)
create mode 100644 arch/mips/ralink/dts/rt3050.dtsi
create mode 100644 arch/mips/ralink/dts/rt3052_eval.dts
diff --git a/arch/mips/ralink/dts/rt3050.dtsi b/arch/mips/ralink/dts/rt3050.dtsi
new file mode 100644
index 0000000..fd49daa
--- /dev/null
+++ b/arch/mips/ralink/dts/rt3050.dtsi
@@ -0,0 +1,96 @@
+/ {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "ralink,rt3050-soc", "ralink,rt3052-soc";
+
+ cpus {
+ cpu@0 {
+ compatible = "mips,mips24KEc";
+ };
+ };
+
+ chosen {
+ bootargs = "console=ttyS0,57600 init=/init";
+ };
+
+ palmbus@10000000 {
+ compatible = "palmbus";
+ reg = <0x10000000 0x200000>;
+ ranges = <0x0 0x10000000 0x1FFFFF>;
+
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ sysc@0 {
+ compatible = "ralink,rt3052-sysc", "ralink,rt3050-sysc";
+ reg = <0x0 0x100>;
+ };
+
+ timer@100 {
+ compatible = "ralink,rt3052-wdt", "ralink,rt2880-wdt";
+ reg = <0x100 0x100>;
+ };
+
+ intc: intc@200 {
+ compatible = "ralink,rt3052-intc", "ralink,rt2880-intc";
+ reg = <0x200 0x100>;
+
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ };
+
+ memc@300 {
+ compatible = "ralink,rt3052-memc", "ralink,rt3050-memc";
+ reg = <0x300 0x100>;
+ };
+
+ gpio0: gpio@600 {
+ compatible = "ralink,rt3052-gpio", "ralink,rt2880-gpio";
+ reg = <0x600 0x34>;
+
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ ralink,ngpio = <24>;
+ ralink,regs = [ 00 04 08 0c
+ 20 24 28 2c
+ 30 34 ];
+ };
+
+ gpio1: gpio@638 {
+ compatible = "ralink,rt3052-gpio", "ralink,rt2880-gpio";
+ reg = <0x638 0x24>;
+
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ ralink,ngpio = <16>;
+ ralink,regs = [ 00 04 08 0c
+ 10 14 18 1c
+ 20 24 ];
+ };
+
+ gpio2: gpio@660 {
+ compatible = "ralink,rt3052-gpio", "ralink,rt2880-gpio";
+ reg = <0x660 0x24>;
+
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ ralink,ngpio = <12>;
+ ralink,regs = [ 00 04 08 0c
+ 10 14 18 1c
+ 20 24 ];
+ };
+
+ uartlite@c00 {
+ compatible = "ralink,rt3052-uart", "ralink,rt2880-uart", "ns16550a";
+ reg = <0xc00 0x100>;
+
+ interrupt-parent = <&intc>;
+ interrupts = <12>;
+
+ reg-shift = <2>;
+ };
+ };
+};
diff --git a/arch/mips/ralink/dts/rt3052_eval.dts b/arch/mips/ralink/dts/rt3052_eval.dts
new file mode 100644
index 0000000..148a590
--- /dev/null
+++ b/arch/mips/ralink/dts/rt3052_eval.dts
@@ -0,0 +1,52 @@
+/dts-v1/;
+
+/include/ "rt3050.dtsi"
+
+/ {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "ralink,rt3052-eval-board", "ralink,rt3052-soc";
+ model = "Ralink RT3052 evaluation board";
+
+ memory@0 {
+ reg = <0x0 0x2000000>;
+ };
+
+ palmbus@10000000 {
+ sysc@0 {
+ ralink,pinmmux = "uartlite", "spi";
+ ralink,uartmux = "gpio";
+ ralink,wdtmux = <0>;
+ };
+ };
+
+ cfi@1f000000 {
+ compatible = "cfi-flash";
+ reg = <0x1f000000 0x800000>;
+
+ bank-width = <2>;
+ device-width = <2>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ partition@0 {
+ label = "uboot";
+ reg = <0x0 0x30000>;
+ read-only;
+ };
+ partition@30000 {
+ label = "uboot-env";
+ reg = <0x30000 0x10000>;
+ read-only;
+ };
+ partition@40000 {
+ label = "calibration";
+ reg = <0x40000 0x10000>;
+ read-only;
+ };
+ partition@50000 {
+ label = "linux";
+ reg = <0x50000 0x7b0000>;
+ };
+ };
+};
--
1.7.10.4

View file

@ -0,0 +1,156 @@
From ae2b5bb6570481b50a7175c64176b82da0a81836 Mon Sep 17 00:00:00 2001
From: John Crispin <blogic@openwrt.org>
Date: Sun, 20 Jan 2013 22:05:30 +0100
Subject: [PATCH 10/14] MIPS: ralink: adds Kbuild files
Add the Kbuild symbols and Makefiles needed to actually build the ralink code
from this series
Signed-off-by: John Crispin <blogic@openwrt.org>
Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
Patchwork: http://patchwork.linux-mips.org/patch/4899/
---
arch/mips/Kbuild.platforms | 1 +
arch/mips/Kconfig | 17 +++++++++++++++++
arch/mips/ralink/Kconfig | 32 ++++++++++++++++++++++++++++++++
arch/mips/ralink/Makefile | 15 +++++++++++++++
arch/mips/ralink/Platform | 10 ++++++++++
arch/mips/ralink/dts/Makefile | 1 +
6 files changed, 76 insertions(+)
create mode 100644 arch/mips/ralink/Kconfig
create mode 100644 arch/mips/ralink/Makefile
create mode 100644 arch/mips/ralink/Platform
create mode 100644 arch/mips/ralink/dts/Makefile
diff --git a/arch/mips/Kbuild.platforms b/arch/mips/Kbuild.platforms
index 91b9d69..9a73ce6 100644
--- a/arch/mips/Kbuild.platforms
+++ b/arch/mips/Kbuild.platforms
@@ -22,6 +22,7 @@ platforms += pmc-sierra
platforms += pnx833x
platforms += pnx8550
platforms += powertv
+platforms += ralink
platforms += rb532
platforms += sgi-ip22
platforms += sgi-ip27
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index 8f8666c..79ad1d0 100644
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -437,6 +437,22 @@ config POWERTV
help
This enables support for the Cisco PowerTV Platform.
+config RALINK
+ bool "Ralink based machines"
+ select CEVT_R4K
+ select CSRC_R4K
+ select BOOT_RAW
+ select DMA_NONCOHERENT
+ select IRQ_CPU
+ select USE_OF
+ select SYS_HAS_CPU_MIPS32_R1
+ select SYS_HAS_CPU_MIPS32_R2
+ select SYS_SUPPORTS_32BIT_KERNEL
+ select SYS_SUPPORTS_LITTLE_ENDIAN
+ select SYS_HAS_EARLY_PRINTK
+ select HAVE_MACH_CLKDEV
+ select CLKDEV_LOOKUP
+
config SGI_IP22
bool "SGI IP22 (Indy/Indigo2)"
select FW_ARC
@@ -849,6 +865,7 @@ source "arch/mips/lantiq/Kconfig"
source "arch/mips/lasat/Kconfig"
source "arch/mips/pmc-sierra/Kconfig"
source "arch/mips/powertv/Kconfig"
+source "arch/mips/ralink/Kconfig"
source "arch/mips/sgi-ip27/Kconfig"
source "arch/mips/sibyte/Kconfig"
source "arch/mips/txx9/Kconfig"
diff --git a/arch/mips/ralink/Kconfig b/arch/mips/ralink/Kconfig
new file mode 100644
index 0000000..a0b0197
--- /dev/null
+++ b/arch/mips/ralink/Kconfig
@@ -0,0 +1,32 @@
+if RALINK
+
+choice
+ prompt "Ralink SoC selection"
+ default SOC_RT305X
+ help
+ Select Ralink MIPS SoC type.
+
+ config SOC_RT305X
+ bool "RT305x"
+ select USB_ARCH_HAS_HCD
+ select USB_ARCH_HAS_OHCI
+ select USB_ARCH_HAS_EHCI
+
+endchoice
+
+choice
+ prompt "Devicetree selection"
+ default DTB_RT_NONE
+ help
+ Select the devicetree.
+
+ config DTB_RT_NONE
+ bool "None"
+
+ config DTB_RT305X_EVAL
+ bool "RT305x eval kit"
+ depends on SOC_RT305X
+
+endchoice
+
+endif
diff --git a/arch/mips/ralink/Makefile b/arch/mips/ralink/Makefile
new file mode 100644
index 0000000..939757f
--- /dev/null
+++ b/arch/mips/ralink/Makefile
@@ -0,0 +1,15 @@
+# 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.#
+# Makefile for the Ralink common stuff
+#
+# Copyright (C) 2009-2011 Gabor Juhos <juhosg@openwrt.org>
+# Copyright (C) 2013 John Crispin <blogic@openwrt.org>
+
+obj-y := prom.o of.o reset.o clk.o irq.o
+
+obj-$(CONFIG_SOC_RT305X) += rt305x.o
+
+obj-$(CONFIG_EARLY_PRINTK) += early_printk.o
+
+obj-y += dts/
diff --git a/arch/mips/ralink/Platform b/arch/mips/ralink/Platform
new file mode 100644
index 0000000..6babd65
--- /dev/null
+++ b/arch/mips/ralink/Platform
@@ -0,0 +1,10 @@
+#
+# Ralink SoC common stuff
+#
+core-$(CONFIG_RALINK) += arch/mips/ralink/
+cflags-$(CONFIG_RALINK) += -I$(srctree)/arch/mips/include/asm/mach-ralink
+
+#
+# Ralink RT305x
+#
+load-$(CONFIG_SOC_RT305X) += 0xffffffff80000000
diff --git a/arch/mips/ralink/dts/Makefile b/arch/mips/ralink/dts/Makefile
new file mode 100644
index 0000000..1a69fb3
--- /dev/null
+++ b/arch/mips/ralink/dts/Makefile
@@ -0,0 +1 @@
+obj-$(CONFIG_DTB_RT305X_EVAL) := rt3052_eval.dtb.o
--
1.7.10.4

View file

@ -0,0 +1,187 @@
From 6d63d70f9fe4c1b3d293ac3b9d2fcaf937d95cea Mon Sep 17 00:00:00 2001
From: John Crispin <blogic@openwrt.org>
Date: Fri, 1 Feb 2013 12:50:49 +0100
Subject: [PATCH 11/14] MIPS: ralink: adds default config file
Signed-off-by: John Crispin <blogic@openwrt.org>
---
arch/mips/configs/rt305x_defconfig | 167 ++++++++++++++++++++++++++++++++++++
1 file changed, 167 insertions(+)
create mode 100644 arch/mips/configs/rt305x_defconfig
diff --git a/arch/mips/configs/rt305x_defconfig b/arch/mips/configs/rt305x_defconfig
new file mode 100644
index 0000000..d1741bc
--- /dev/null
+++ b/arch/mips/configs/rt305x_defconfig
@@ -0,0 +1,167 @@
+CONFIG_RALINK=y
+CONFIG_DTB_RT305X_EVAL=y
+CONFIG_CPU_MIPS32_R2=y
+# CONFIG_COMPACTION is not set
+# CONFIG_CROSS_MEMORY_ATTACH is not set
+CONFIG_HZ_100=y
+# CONFIG_SECCOMP is not set
+CONFIG_EXPERIMENTAL=y
+# CONFIG_LOCALVERSION_AUTO is not set
+CONFIG_SYSVIPC=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_INITRAMFS_ROOT_UID=1000
+CONFIG_INITRAMFS_ROOT_GID=1000
+# CONFIG_RD_GZIP is not set
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_KALLSYMS_ALL=y
+# CONFIG_AIO is not set
+CONFIG_EMBEDDED=y
+# CONFIG_VM_EVENT_COUNTERS is not set
+# CONFIG_SLUB_DEBUG is not set
+# CONFIG_COMPAT_BRK is not set
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_BLK_DEV_BSG is not set
+CONFIG_PARTITION_ADVANCED=y
+# CONFIG_IOSCHED_CFQ is not set
+# CONFIG_COREDUMP is not set
+# CONFIG_SUSPEND is not set
+CONFIG_NET=y
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+CONFIG_IP_ADVANCED_ROUTER=y
+CONFIG_IP_MULTIPLE_TABLES=y
+CONFIG_IP_ROUTE_MULTIPATH=y
+CONFIG_IP_ROUTE_VERBOSE=y
+CONFIG_IP_MROUTE=y
+CONFIG_IP_MROUTE_MULTIPLE_TABLES=y
+CONFIG_ARPD=y
+CONFIG_SYN_COOKIES=y
+# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
+# CONFIG_INET_XFRM_MODE_TUNNEL is not set
+# CONFIG_INET_XFRM_MODE_BEET is not set
+# CONFIG_INET_LRO is not set
+# CONFIG_INET_DIAG is not set
+CONFIG_TCP_CONG_ADVANCED=y
+# CONFIG_TCP_CONG_BIC is not set
+# CONFIG_TCP_CONG_WESTWOOD is not set
+# CONFIG_TCP_CONG_HTCP is not set
+# CONFIG_IPV6 is not set
+CONFIG_NETFILTER=y
+# CONFIG_BRIDGE_NETFILTER is not set
+CONFIG_NF_CONNTRACK=m
+CONFIG_NF_CONNTRACK_FTP=m
+CONFIG_NF_CONNTRACK_IRC=m
+CONFIG_NETFILTER_XT_TARGET_CT=m
+CONFIG_NETFILTER_XT_TARGET_LOG=m
+CONFIG_NETFILTER_XT_TARGET_TCPMSS=m
+CONFIG_NETFILTER_XT_MATCH_COMMENT=m
+CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m
+CONFIG_NETFILTER_XT_MATCH_LIMIT=m
+CONFIG_NETFILTER_XT_MATCH_MAC=m
+CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m
+CONFIG_NETFILTER_XT_MATCH_STATE=m
+CONFIG_NF_CONNTRACK_IPV4=m
+# CONFIG_NF_CONNTRACK_PROC_COMPAT is not set
+CONFIG_IP_NF_IPTABLES=m
+CONFIG_IP_NF_FILTER=m
+CONFIG_IP_NF_TARGET_REJECT=m
+CONFIG_IP_NF_MANGLE=m
+CONFIG_IP_NF_RAW=m
+CONFIG_BRIDGE=y
+# CONFIG_BRIDGE_IGMP_SNOOPING is not set
+CONFIG_VLAN_8021Q=y
+CONFIG_NET_SCHED=y
+CONFIG_HAMRADIO=y
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+# CONFIG_FIRMWARE_IN_KERNEL is not set
+CONFIG_MTD=y
+CONFIG_MTD_CMDLINE_PARTS=y
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLOCK=y
+CONFIG_MTD_CFI=y
+CONFIG_MTD_CFI_AMDSTD=y
+CONFIG_MTD_COMPLEX_MAPPINGS=y
+CONFIG_MTD_PHYSMAP=y
+CONFIG_MTD_PHYSMAP_OF=y
+CONFIG_MTD_M25P80=y
+CONFIG_EEPROM_93CX6=m
+CONFIG_SCSI=y
+CONFIG_BLK_DEV_SD=y
+CONFIG_NETDEVICES=y
+# CONFIG_NET_VENDOR_WIZNET is not set
+CONFIG_PHYLIB=y
+CONFIG_PPP=m
+CONFIG_PPP_FILTER=y
+CONFIG_PPP_MULTILINK=y
+CONFIG_PPPOE=m
+CONFIG_PPP_ASYNC=m
+CONFIG_ISDN=y
+CONFIG_INPUT=m
+CONFIG_INPUT_POLLDEV=m
+# CONFIG_INPUT_MOUSEDEV is not set
+# CONFIG_KEYBOARD_ATKBD is not set
+# CONFIG_INPUT_MOUSE is not set
+CONFIG_INPUT_MISC=y
+# CONFIG_SERIO is not set
+# CONFIG_VT is not set
+# CONFIG_LEGACY_PTYS is not set
+# CONFIG_DEVKMEM is not set
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_RUNTIME_UARTS=2
+CONFIG_SERIAL_OF_PLATFORM=y
+CONFIG_SPI=y
+# CONFIG_HWMON is not set
+CONFIG_WATCHDOG=y
+# CONFIG_HID is not set
+# CONFIG_USB_HID is not set
+CONFIG_USB=y
+CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
+CONFIG_USB_STORAGE=y
+CONFIG_USB_STORAGE_DEBUG=y
+CONFIG_NEW_LEDS=y
+CONFIG_LEDS_CLASS=y
+CONFIG_LEDS_TRIGGERS=y
+CONFIG_LEDS_TRIGGER_TIMER=y
+CONFIG_LEDS_TRIGGER_DEFAULT_ON=y
+CONFIG_STAGING=y
+# CONFIG_IOMMU_SUPPORT is not set
+# CONFIG_DNOTIFY is not set
+# CONFIG_PROC_PAGE_MONITOR is not set
+CONFIG_TMPFS=y
+CONFIG_TMPFS_XATTR=y
+CONFIG_JFFS2_FS=y
+CONFIG_JFFS2_SUMMARY=y
+CONFIG_JFFS2_FS_XATTR=y
+# CONFIG_JFFS2_FS_POSIX_ACL is not set
+# CONFIG_JFFS2_FS_SECURITY is not set
+CONFIG_JFFS2_COMPRESSION_OPTIONS=y
+# CONFIG_JFFS2_ZLIB is not set
+CONFIG_SQUASHFS=y
+# CONFIG_SQUASHFS_ZLIB is not set
+CONFIG_SQUASHFS_XZ=y
+CONFIG_PRINTK_TIME=y
+# CONFIG_ENABLE_MUST_CHECK is not set
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_STRIP_ASM_SYMS=y
+CONFIG_DEBUG_FS=y
+# CONFIG_SCHED_DEBUG is not set
+# CONFIG_FTRACE is not set
+CONFIG_CMDLINE_BOOL=y
+CONFIG_CRYPTO_MANAGER=m
+CONFIG_CRYPTO_ARC4=m
+# CONFIG_CRYPTO_ANSI_CPRNG is not set
+CONFIG_CRC_ITU_T=m
+CONFIG_CRC32_SARWATE=y
+# CONFIG_XZ_DEC_X86 is not set
+# CONFIG_XZ_DEC_POWERPC is not set
+# CONFIG_XZ_DEC_IA64 is not set
+# CONFIG_XZ_DEC_ARM is not set
+# CONFIG_XZ_DEC_ARMTHUMB is not set
+# CONFIG_XZ_DEC_SPARC is not set
+CONFIG_AVERAGE=y
--
1.7.10.4

View file

@ -0,0 +1,70 @@
From dcc7310e144c3bf17a86d2f058d60fb525d4b34a Mon Sep 17 00:00:00 2001
From: John Crispin <blogic@openwrt.org>
Date: Thu, 31 Jan 2013 13:44:10 +0100
Subject: [PATCH 12/14] Document: devicetree: add OF documents for MIPS
interrupt controller
Signed-off-by: John Crispin <blogic@openwrt.org>
Acked-by: David Daney <david.daney@cavium.com>
Patchwork: http://patchwork.linux-mips.org/patch/4901/
---
Documentation/devicetree/bindings/mips/cpu_irq.txt | 47 ++++++++++++++++++++
1 file changed, 47 insertions(+)
create mode 100644 Documentation/devicetree/bindings/mips/cpu_irq.txt
diff --git a/Documentation/devicetree/bindings/mips/cpu_irq.txt b/Documentation/devicetree/bindings/mips/cpu_irq.txt
new file mode 100644
index 0000000..13aa4b6
--- /dev/null
+++ b/Documentation/devicetree/bindings/mips/cpu_irq.txt
@@ -0,0 +1,47 @@
+MIPS CPU interrupt controller
+
+On MIPS the mips_cpu_intc_init() helper can be used to initialize the 8 CPU
+IRQs from a devicetree file and create a irq_domain for IRQ controller.
+
+With the irq_domain in place we can describe how the 8 IRQs are wired to the
+platforms internal interrupt controller cascade.
+
+Below is an example of a platform describing the cascade inside the devicetree
+and the code used to load it inside arch_init_irq().
+
+Required properties:
+- compatible : Should be "mti,cpu-interrupt-controller"
+
+Example devicetree:
+ cpu-irq: cpu-irq@0 {
+ #address-cells = <0>;
+
+ interrupt-controller;
+ #interrupt-cells = <1>;
+
+ compatible = "mti,cpu-interrupt-controller";
+ };
+
+ intc: intc@200 {
+ compatible = "ralink,rt2880-intc";
+ reg = <0x200 0x100>;
+
+ interrupt-controller;
+ #interrupt-cells = <1>;
+
+ interrupt-parent = <&cpu-irq>;
+ interrupts = <2>;
+ };
+
+
+Example platform irq.c:
+static struct of_device_id __initdata of_irq_ids[] = {
+ { .compatible = "mti,cpu-interrupt-controller", .data = mips_cpu_intc_init },
+ { .compatible = "ralink,rt2880-intc", .data = intc_of_init },
+ {},
+};
+
+void __init arch_init_irq(void)
+{
+ of_irq_init(of_irq_ids);
+}
--
1.7.10.4

View file

@ -0,0 +1,92 @@
From 0916b46962cbcac9465d253d0a398435b3965fd5 Mon Sep 17 00:00:00 2001
From: Gabor Juhos <juhosg@openwrt.org>
Date: Thu, 31 Jan 2013 12:20:43 +0000
Subject: [PATCH 13/14] MIPS: add irqdomain support for the CPU IRQ controller
Add code to load a irq_domain for the MIPS IRQ controller from a devicetree
file.
Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
Signed-off-by: John Crispin <blogic@openwrt.org>
Acked-by: David Daney <david.daney@cavium.com>
Patchwork: http://patchwork.linux-mips.org/patch/4902/
---
arch/mips/include/asm/irq_cpu.h | 6 ++++++
arch/mips/kernel/irq_cpu.c | 42 +++++++++++++++++++++++++++++++++++++++
2 files changed, 48 insertions(+)
diff --git a/arch/mips/include/asm/irq_cpu.h b/arch/mips/include/asm/irq_cpu.h
index ef6a07c..3f11fdb 100644
--- a/arch/mips/include/asm/irq_cpu.h
+++ b/arch/mips/include/asm/irq_cpu.h
@@ -17,4 +17,10 @@ extern void mips_cpu_irq_init(void);
extern void rm7k_cpu_irq_init(void);
extern void rm9k_cpu_irq_init(void);
+#ifdef CONFIG_IRQ_DOMAIN
+struct device_node;
+extern int mips_cpu_intc_init(struct device_node *of_node,
+ struct device_node *parent);
+#endif
+
#endif /* _ASM_IRQ_CPU_H */
diff --git a/arch/mips/kernel/irq_cpu.c b/arch/mips/kernel/irq_cpu.c
index 972263b..49bc9ca 100644
--- a/arch/mips/kernel/irq_cpu.c
+++ b/arch/mips/kernel/irq_cpu.c
@@ -31,6 +31,7 @@
#include <linux/interrupt.h>
#include <linux/kernel.h>
#include <linux/irq.h>
+#include <linux/irqdomain.h>
#include <asm/irq_cpu.h>
#include <asm/mipsregs.h>
@@ -113,3 +114,44 @@ void __init mips_cpu_irq_init(void)
irq_set_chip_and_handler(i, &mips_cpu_irq_controller,
handle_percpu_irq);
}
+
+#ifdef CONFIG_IRQ_DOMAIN
+static int mips_cpu_intc_map(struct irq_domain *d, unsigned int irq,
+ irq_hw_number_t hw)
+{
+ static struct irq_chip *chip;
+
+ if (hw < 2 && cpu_has_mipsmt) {
+ /* Software interrupts are used for MT/CMT IPI */
+ chip = &mips_mt_cpu_irq_controller;
+ } else {
+ chip = &mips_cpu_irq_controller;
+ }
+
+ irq_set_chip_and_handler(irq, chip, handle_percpu_irq);
+
+ return 0;
+}
+
+static const struct irq_domain_ops mips_cpu_intc_irq_domain_ops = {
+ .map = mips_cpu_intc_map,
+ .xlate = irq_domain_xlate_onecell,
+};
+
+int __init mips_cpu_intc_init(struct device_node *of_node,
+ struct device_node *parent)
+{
+ struct irq_domain *domain;
+
+ /* Mask interrupts. */
+ clear_c0_status(ST0_IM);
+ clear_c0_cause(CAUSEF_IP);
+
+ domain = irq_domain_add_legacy(of_node, 8, MIPS_CPU_IRQ_BASE, 0,
+ &mips_cpu_intc_irq_domain_ops, NULL);
+ if (!domain)
+ panic("Failed to add irqdomain for MIPS CPU\n");
+
+ return 0;
+}
+#endif /* CONFIG_IRQ_DOMAIN */
--
1.7.10.4

View file

@ -0,0 +1,85 @@
From d3d2b4200b5a42851365e903d101f8f0882eb9eb Mon Sep 17 00:00:00 2001
From: Gabor Juhos <juhosg@openwrt.org>
Date: Thu, 31 Jan 2013 20:43:30 +0100
Subject: [PATCH 14/14] MIPS: ralink: add CPU interrupt controller to
of_irq_ids
Convert the ralink IRQ code to make use of the new MIPS IRQ controller OF
mappings.
Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
Signed-off-by: John Crispin <blogic@openwrt.org>
Acked-by: David Daney <david.daney@cavium.com>
Patchwork: http://patchwork.linux-mips.org/patch/4900/
---
arch/mips/ralink/dts/rt3050.dtsi | 10 ++++++++++
arch/mips/ralink/irq.c | 10 +++++++---
2 files changed, 17 insertions(+), 3 deletions(-)
diff --git a/arch/mips/ralink/dts/rt3050.dtsi b/arch/mips/ralink/dts/rt3050.dtsi
index fd49daa..069d066 100644
--- a/arch/mips/ralink/dts/rt3050.dtsi
+++ b/arch/mips/ralink/dts/rt3050.dtsi
@@ -13,6 +13,13 @@
bootargs = "console=ttyS0,57600 init=/init";
};
+ cpuintc: cpuintc@0 {
+ #address-cells = <0>;
+ #interrupt-cells = <1>;
+ interrupt-controller;
+ compatible = "mti,cpu-interrupt-controller";
+ };
+
palmbus@10000000 {
compatible = "palmbus";
reg = <0x10000000 0x200000>;
@@ -37,6 +44,9 @@
interrupt-controller;
#interrupt-cells = <1>;
+
+ interrupt-parent = <&cpuintc>;
+ interrupts = <2>;
};
memc@300 {
diff --git a/arch/mips/ralink/irq.c b/arch/mips/ralink/irq.c
index e62c975..6d054c5 100644
--- a/arch/mips/ralink/irq.c
+++ b/arch/mips/ralink/irq.c
@@ -128,8 +128,11 @@ static int __init intc_of_init(struct device_node *node,
{
struct resource res;
struct irq_domain *domain;
+ int irq;
- mips_cpu_irq_init();
+ irq = irq_of_parse_and_map(node, 0);
+ if (!irq)
+ panic("Failed to get INTC IRQ");
if (of_address_to_resource(node, 0, &res))
panic("Failed to get intc memory range");
@@ -156,8 +159,8 @@ static int __init intc_of_init(struct device_node *node,
rt_intc_w32(INTC_INT_GLOBAL, INTC_REG_ENABLE);
- irq_set_chained_handler(RALINK_CPU_IRQ_INTC, ralink_intc_irq_handler);
- irq_set_handler_data(RALINK_CPU_IRQ_INTC, domain);
+ irq_set_chained_handler(irq, ralink_intc_irq_handler);
+ irq_set_handler_data(irq, domain);
cp0_perfcount_irq = irq_create_mapping(domain, 9);
@@ -165,6 +168,7 @@ static int __init intc_of_init(struct device_node *node,
}
static struct of_device_id __initdata of_irq_ids[] = {
+ { .compatible = "mti,cpu-interrupt-controller", .data = mips_cpu_intc_init },
{ .compatible = "ralink,rt2880-intc", .data = intc_of_init },
{},
};
--
1.7.10.4

View file

@ -0,0 +1,74 @@
From c420811f117a59a4a7d4e34b362437b91c7fafa1 Mon Sep 17 00:00:00 2001
From: John Crispin <blogic@openwrt.org>
Date: Fri, 25 Jan 2013 19:39:51 +0100
Subject: [PATCH] serial: ralink: adds support for the serial core found on
ralink wisoc
The MIPS based Ralink WiSoC platform has 1 or more 8250 compatible serial cores.
To make them work we require the same quirks that are used by AU1x00.
Signed-off-by: John Crispin <blogic@openwrt.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/tty/serial/8250/8250.c | 6 +++---
drivers/tty/serial/8250/Kconfig | 8 ++++++++
include/linux/serial_core.h | 2 +-
3 files changed, 12 insertions(+), 4 deletions(-)
diff --git a/drivers/tty/serial/8250/8250.c b/drivers/tty/serial/8250/8250.c
index 24939ca..0efc815 100644
--- a/drivers/tty/serial/8250/8250.c
+++ b/drivers/tty/serial/8250/8250.c
@@ -317,9 +317,9 @@ static void default_serial_dl_write(struct uart_8250_port *up, int value)
serial_out(up, UART_DLM, value >> 8 & 0xff);
}
-#ifdef CONFIG_MIPS_ALCHEMY
+#if defined(CONFIG_MIPS_ALCHEMY) || defined(CONFIG_SERIAL_8250_RT288X)
-/* Au1x00 UART hardware has a weird register layout */
+/* Au1x00/RT288x UART hardware has a weird register layout */
static const u8 au_io_in_map[] = {
[UART_RX] = 0,
[UART_IER] = 2,
@@ -440,7 +440,7 @@ static void set_io_from_upio(struct uart_port *p)
p->serial_out = mem32_serial_out;
break;
-#ifdef CONFIG_MIPS_ALCHEMY
+#if defined(CONFIG_MIPS_ALCHEMY) || defined(CONFIG_SERIAL_8250_RT288X)
case UPIO_AU:
p->serial_in = au_serial_in;
p->serial_out = au_serial_out;
diff --git a/drivers/tty/serial/8250/Kconfig b/drivers/tty/serial/8250/Kconfig
index d31f4c6..2ef9537 100644
--- a/drivers/tty/serial/8250/Kconfig
+++ b/drivers/tty/serial/8250/Kconfig
@@ -276,3 +276,11 @@ config SERIAL_8250_EM
Selecting this option will add support for the integrated serial
port hardware found on the Emma Mobile line of processors.
If unsure, say N.
+
+config SERIAL_8250_RT288X
+ bool "Ralink RT288x/RT305x/RT3662/RT3883 serial port support"
+ depends on SERIAL_8250 && (SOC_RT288X || SOC_RT305X || SOC_RT3883)
+ help
+ If you have a Ralink RT288x/RT305x SoC based board and want to use the
+ serial port, say Y to this option. The driver can handle up to 2 serial
+ ports. If unsure, say N.
diff --git a/include/linux/serial_core.h b/include/linux/serial_core.h
index 82aebc8..d971421 100644
--- a/include/linux/serial_core.h
+++ b/include/linux/serial_core.h
@@ -134,7 +134,7 @@ struct uart_port {
#define UPIO_HUB6 (1)
#define UPIO_MEM (2)
#define UPIO_MEM32 (3)
-#define UPIO_AU (4) /* Au1x00 type IO */
+#define UPIO_AU (4) /* Au1x00 and RT288x type IO */
#define UPIO_TSI (5) /* Tsi108/109 type IO */
unsigned int read_status_mask; /* driver specific */
--
1.7.10.4

View file

@ -0,0 +1,52 @@
From eb8d7fbba907df0a51e504930c00b2c9ec837b54 Mon Sep 17 00:00:00 2001
From: John Crispin <blogic@openwrt.org>
Date: Fri, 22 Mar 2013 19:25:59 +0100
Subject: [PATCH 100/121] MIPS: ralink: fix RT305x clock setup
Add a few missing clocks and remove the unused sys clock.
Signed-off-by: John Crispin <blogic@openwrt.org>
---
arch/mips/ralink/rt305x.c | 14 ++++++++++++++
1 file changed, 14 insertions(+)
diff --git a/arch/mips/ralink/rt305x.c b/arch/mips/ralink/rt305x.c
index 0a4bbdc..856ebff 100644
--- a/arch/mips/ralink/rt305x.c
+++ b/arch/mips/ralink/rt305x.c
@@ -125,6 +125,7 @@ void __init ralink_clk_init(void)
{
unsigned long cpu_rate, sys_rate, wdt_rate, uart_rate;
u32 t = rt_sysc_r32(SYSC_REG_SYSTEM_CONFIG);
+ int wmac_20mhz = 0;
if (soc_is_rt305x() || soc_is_rt3350()) {
t = (t >> RT305X_SYSCFG_CPUCLK_SHIFT) &
@@ -176,11 +177,24 @@ void __init ralink_clk_init(void)
BUG();
}
+ if (soc_is_rt3352() || soc_is_rt5350()) {
+ u32 val = rt_sysc_r32(RT3352_SYSC_REG_SYSCFG0);
+ if ((val & RT3352_CLKCFG0_XTAL_SEL) == 0)
+ wmac_20mhz = 1;
+ }
+
ralink_clk_add("cpu", cpu_rate);
ralink_clk_add("10000b00.spi", sys_rate);
ralink_clk_add("10000100.timer", wdt_rate);
+ ralink_clk_add("10000120.watchdog", wdt_rate);
ralink_clk_add("10000500.uart", uart_rate);
ralink_clk_add("10000c00.uartlite", uart_rate);
+ ralink_clk_add("10100000.ethernet", sys_rate);
+
+ if (wmac_20mhz)
+ ralink_clk_add("10180000.wmac", 20000000);
+ else
+ ralink_clk_add("10180000.wmac", 40000000);
}
void __init ralink_of_remap(void)
--
1.7.10.4

View file

@ -0,0 +1,27 @@
From 68dba842ed23c9688340444b44951c448f4ff9ba Mon Sep 17 00:00:00 2001
From: John Crispin <blogic@openwrt.org>
Date: Sat, 16 Mar 2013 16:28:54 +0100
Subject: [PATCH 101/121] MIPS: ralink: add missing comment in irq driver
Trivial patch that adds a comment that makes the code more readable.
Signed-off-by: John Crispin <blogic@openwrt.org>
---
arch/mips/ralink/irq.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/arch/mips/ralink/irq.c b/arch/mips/ralink/irq.c
index 6d054c5..ed613b0 100644
--- a/arch/mips/ralink/irq.c
+++ b/arch/mips/ralink/irq.c
@@ -162,6 +162,7 @@ static int __init intc_of_init(struct device_node *node,
irq_set_chained_handler(irq, ralink_intc_irq_handler);
irq_set_handler_data(irq, domain);
+ /* tell the kernel which irq is used for performance monitoring */
cp0_perfcount_irq = irq_create_mapping(domain, 9);
return 0;
--
1.7.10.4

View file

@ -0,0 +1,35 @@
From ac2614707be7ddceb0f0b623d55d200f28695d5f Mon Sep 17 00:00:00 2001
From: John Crispin <blogic@openwrt.org>
Date: Mon, 25 Mar 2013 11:19:58 +0100
Subject: [PATCH 102/121] MIPS: ralink: add RT5350 sdram register defines
Add a few missing defines that are needed to make memory detection work on the
RT5350.
Signed-off-by: John Crispin <blogic@openwrt.org>
---
arch/mips/include/asm/mach-ralink/rt305x.h | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/arch/mips/include/asm/mach-ralink/rt305x.h b/arch/mips/include/asm/mach-ralink/rt305x.h
index 7d344f2..4e62cef 100644
--- a/arch/mips/include/asm/mach-ralink/rt305x.h
+++ b/arch/mips/include/asm/mach-ralink/rt305x.h
@@ -97,6 +97,14 @@ static inline int soc_is_rt5350(void)
#define RT5350_SYSCFG0_CPUCLK_320 0x2
#define RT5350_SYSCFG0_CPUCLK_300 0x3
+#define RT5350_SYSCFG0_DRAM_SIZE_SHIFT 12
+#define RT5350_SYSCFG0_DRAM_SIZE_MASK 7
+#define RT5350_SYSCFG0_DRAM_SIZE_2M 0
+#define RT5350_SYSCFG0_DRAM_SIZE_8M 1
+#define RT5350_SYSCFG0_DRAM_SIZE_16M 2
+#define RT5350_SYSCFG0_DRAM_SIZE_32M 3
+#define RT5350_SYSCFG0_DRAM_SIZE_64M 4
+
/* multi function gpio pins */
#define RT305X_GPIO_I2C_SD 1
#define RT305X_GPIO_I2C_SCLK 2
--
1.7.10.4

View file

@ -0,0 +1,36 @@
From 5157985fbc0f071276b0c3381ac8ed191878358a Mon Sep 17 00:00:00 2001
From: John Crispin <blogic@openwrt.org>
Date: Thu, 21 Mar 2013 19:01:49 +0100
Subject: [PATCH 103/121] MIPS: ralink: add RT3352 usb register defines
Add a few missing defines that are needed to make USB work on the RT3352
and RT5350.
Signed-off-by: John Crispin <blogic@openwrt.org>
---
arch/mips/include/asm/mach-ralink/rt305x.h | 11 +++++++++++
1 file changed, 11 insertions(+)
Index: linux-3.8.3/arch/mips/include/asm/mach-ralink/rt305x.h
===================================================================
--- linux-3.8.3.orig/arch/mips/include/asm/mach-ralink/rt305x.h 2013-04-02 13:30:35.601424833 +0200
+++ linux-3.8.3/arch/mips/include/asm/mach-ralink/rt305x.h 2013-04-02 13:39:37.721437754 +0200
@@ -144,4 +144,18 @@
#define RT305X_GPIO_MODE_SDRAM BIT(8)
#define RT305X_GPIO_MODE_RGMII BIT(9)
+#define RT3352_SYSC_REG_SYSCFG1 0x014
+#define RT3352_SYSC_REG_CLKCFG1 0x030
+#define RT3352_SYSC_REG_RSTCTRL 0x034
+#define RT3352_SYSC_REG_USB_PS 0x05c
+
+#define RT3352_CLKCFG1_UPHY0_CLK_EN BIT(18)
+#define RT3352_CLKCFG1_UPHY1_CLK_EN BIT(20)
+#define RT3352_RSTCTRL_UHST BIT(22)
+#define RT3352_RSTCTRL_UDEV BIT(25)
+#define RT3352_SYSCFG1_USB0_HOST_MODE BIT(10)
+
+#define RT3352_SYSC_REG_SYSCFG0 0x010
+#define RT3352_CLKCFG0_XTAL_SEL BIT(20)
+
#endif

View file

@ -0,0 +1,180 @@
From 806a489c720767f63bf5046c2ccd87ded9549c1c Mon Sep 17 00:00:00 2001
From: John Crispin <blogic@openwrt.org>
Date: Sat, 16 Mar 2013 00:50:57 +0100
Subject: [PATCH 104/121] MIPS: ralink: add pinmux driver
Add code to setup the pinmux on ralonk SoC. The SoC has a single 32 bit register
for this functionality with simple on/off bits. Building a full featured pinctrl
driver would be overkill.
Signed-off-by: John Crispin <blogic@openwrt.org>
---
arch/mips/ralink/Makefile | 2 +-
arch/mips/ralink/common.h | 5 ++-
arch/mips/ralink/of.c | 2 ++
arch/mips/ralink/pinmux.c | 76 +++++++++++++++++++++++++++++++++++++++++++++
arch/mips/ralink/rt305x.c | 6 ++--
5 files changed, 85 insertions(+), 6 deletions(-)
create mode 100644 arch/mips/ralink/pinmux.c
diff --git a/arch/mips/ralink/Makefile b/arch/mips/ralink/Makefile
index 939757f..39ef249 100644
--- a/arch/mips/ralink/Makefile
+++ b/arch/mips/ralink/Makefile
@@ -6,7 +6,7 @@
# Copyright (C) 2009-2011 Gabor Juhos <juhosg@openwrt.org>
# Copyright (C) 2013 John Crispin <blogic@openwrt.org>
-obj-y := prom.o of.o reset.o clk.o irq.o
+obj-y := prom.o of.o reset.o clk.o irq.o pinmux.o
obj-$(CONFIG_SOC_RT305X) += rt305x.o
diff --git a/arch/mips/ralink/common.h b/arch/mips/ralink/common.h
index 3009903..ed99f23 100644
--- a/arch/mips/ralink/common.h
+++ b/arch/mips/ralink/common.h
@@ -22,9 +22,10 @@ struct ralink_pinmux {
struct ralink_pinmux_grp *mode;
struct ralink_pinmux_grp *uart;
int uart_shift;
+ u32 uart_mask;
void (*wdt_reset)(void);
};
-extern struct ralink_pinmux gpio_pinmux;
+extern struct ralink_pinmux rt_pinmux;
struct ralink_soc_info {
unsigned char sys_type[RAMIPS_SYS_TYPE_LEN];
@@ -41,4 +42,6 @@ extern void prom_soc_init(struct ralink_soc_info *soc_info);
__iomem void *plat_of_remap_node(const char *node);
+void ralink_pinmux(void);
+
#endif /* _RALINK_COMMON_H__ */
diff --git a/arch/mips/ralink/of.c b/arch/mips/ralink/of.c
index 4165e70..ecf1482 100644
--- a/arch/mips/ralink/of.c
+++ b/arch/mips/ralink/of.c
@@ -101,6 +101,8 @@ static int __init plat_of_setup(void)
if (of_platform_populate(NULL, of_ids, NULL, NULL))
panic("failed to populate DT\n");
+ ralink_pinmux();
+
return 0;
}
diff --git a/arch/mips/ralink/pinmux.c b/arch/mips/ralink/pinmux.c
new file mode 100644
index 0000000..7477deb
--- /dev/null
+++ b/arch/mips/ralink/pinmux.c
@@ -0,0 +1,76 @@
+/*
+ * 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) 2013 John Crispin <blogic@openwrt.org>
+ */
+
+#include <linux/kernel.h>
+#include <linux/of.h>
+
+#include <asm/mach-ralink/ralink_regs.h>
+
+#include "common.h"
+
+#define SYSC_REG_GPIO_MODE 0x60
+
+static u32 ralink_mux_mask(const char *name, struct ralink_pinmux_grp *grps)
+{
+ for (; grps->name; grps++)
+ if (!strcmp(grps->name, name))
+ return grps->mask;
+
+ return 0;
+}
+
+void ralink_pinmux(void)
+{
+ const __be32 *wdt;
+ struct device_node *np;
+ struct property *prop;
+ const char *uart, *pin;
+ u32 mode = 0;
+
+ np = of_find_compatible_node(NULL, NULL, "ralink,rt3050-sysc");
+ if (!np)
+ return;
+
+ of_property_for_each_string(np, "ralink,gpiomux", prop, pin) {
+ int m = ralink_mux_mask(pin, rt_pinmux.mode);
+ if (m) {
+ mode |= m;
+ pr_debug("pinmux: registered gpiomux \"%s\"\n", pin);
+ } else {
+ pr_err("pinmux: failed to load \"%s\"\n", pin);
+ }
+ }
+
+ of_property_for_each_string(np, "ralink,pinmmux", prop, pin) {
+ int m = ralink_mux_mask(pin, rt_pinmux.mode);
+ if (m) {
+ mode &= ~m;
+ pr_debug("pinmux: registered pinmux \"%s\"\n", pin);
+ } else {
+ pr_err("pinmux: failed to load group \"%s\"\n", pin);
+ }
+ }
+
+ of_property_read_string(np, "ralink,uartmux", &uart);
+ if (uart) {
+ int m = ralink_mux_mask(uart, rt_pinmux.uart);
+ mode |= rt_pinmux.uart_mask << rt_pinmux.uart_shift;
+ if (m) {
+ mode &= ~(m << rt_pinmux.uart_shift);
+ pr_debug("pinmux: registered uartmux \"%s\"\n", uart);
+ } else {
+ pr_debug("pinmux: registered uartmux \"gpio\"\n");
+ }
+ }
+
+ wdt = of_get_property(np, "ralink,wdtmux", NULL);
+ if (wdt && *wdt && rt_pinmux.wdt_reset)
+ rt_pinmux.wdt_reset();
+
+ rt_sysc_w32(mode, SYSC_REG_GPIO_MODE);
+}
diff --git a/arch/mips/ralink/rt305x.c b/arch/mips/ralink/rt305x.c
index 856ebff..d9ea53d 100644
--- a/arch/mips/ralink/rt305x.c
+++ b/arch/mips/ralink/rt305x.c
@@ -97,9 +97,6 @@ struct ralink_pinmux_grp uart_mux[] = {
.mask = RT305X_GPIO_MODE_GPIO_I2S,
.gpio_first = RT305X_GPIO_7,
.gpio_last = RT305X_GPIO_14,
- }, {
- .name = "gpio",
- .mask = RT305X_GPIO_MODE_GPIO,
}, {0}
};
@@ -114,10 +111,11 @@ void rt305x_wdt_reset(void)
rt_sysc_w32(t, SYSC_REG_SYSTEM_CONFIG);
}
-struct ralink_pinmux gpio_pinmux = {
+struct ralink_pinmux rt_pinmux = {
.mode = mode_mux,
.uart = uart_mux,
.uart_shift = RT305X_GPIO_MODE_UART0_SHIFT,
+ .uart_mask = RT305X_GPIO_MODE_GPIO,
.wdt_reset = rt305x_wdt_reset,
};
--
1.7.10.4

View file

@ -0,0 +1,164 @@
From 45e797ec7555c50775d9ac7fc7a17a544344aa3f Mon Sep 17 00:00:00 2001
From: John Crispin <blogic@openwrt.org>
Date: Thu, 21 Mar 2013 17:47:07 +0100
Subject: [PATCH 105/121] MIPS: extend RT3050 dtsi file
Add some additional properties to the dtsi file for ethernet and wifi.
Signed-off-by: John Crispin <blogic@openwrt.org>
---
arch/mips/ralink/dts/rt3050.dtsi | 96 ++++++++++++++++++++++++++++++++------
1 file changed, 81 insertions(+), 15 deletions(-)
diff --git a/arch/mips/ralink/dts/rt3050.dtsi b/arch/mips/ralink/dts/rt3050.dtsi
index 069d066..5aede8d 100644
--- a/arch/mips/ralink/dts/rt3050.dtsi
+++ b/arch/mips/ralink/dts/rt3050.dtsi
@@ -1,7 +1,7 @@
/ {
#address-cells = <1>;
#size-cells = <1>;
- compatible = "ralink,rt3050-soc", "ralink,rt3052-soc";
+ compatible = "ralink,rt3050-soc", "ralink,rt3052-soc", "ralink,rt3350-soc";
cpus {
cpu@0 {
@@ -23,7 +23,7 @@
palmbus@10000000 {
compatible = "palmbus";
reg = <0x10000000 0x200000>;
- ranges = <0x0 0x10000000 0x1FFFFF>;
+ ranges = <0x0 0x10000000 0x1FFFFF>;
#address-cells = <1>;
#size-cells = <1>;
@@ -34,8 +34,18 @@
};
timer@100 {
+ compatible = "ralink,rt3052-timer", "ralink,rt2880-timer";
+ reg = <0x100 0x20>;
+
+ interrupt-parent = <&intc>;
+ interrupts = <1>;
+
+ status = "disabled";
+ };
+
+ watchdog@120 {
compatible = "ralink,rt3052-wdt", "ralink,rt2880-wdt";
- reg = <0x100 0x100>;
+ reg = <0x120 0x10>;
};
intc: intc@200 {
@@ -61,10 +71,12 @@
gpio-controller;
#gpio-cells = <2>;
- ralink,ngpio = <24>;
- ralink,regs = [ 00 04 08 0c
- 20 24 28 2c
- 30 34 ];
+ ralink,num-gpios = <24>;
+ ralink,register-map = [ 00 04 08 0c
+ 20 24 28 2c
+ 30 34 ];
+
+ status = "disabled";
};
gpio1: gpio@638 {
@@ -74,10 +86,12 @@
gpio-controller;
#gpio-cells = <2>;
- ralink,ngpio = <16>;
- ralink,regs = [ 00 04 08 0c
- 10 14 18 1c
- 20 24 ];
+ ralink,num-gpios = <16>;
+ ralink,register-map = [ 00 04 08 0c
+ 10 14 18 1c
+ 20 24 ];
+
+ status = "disabled";
};
gpio2: gpio@660 {
@@ -87,10 +101,21 @@
gpio-controller;
#gpio-cells = <2>;
- ralink,ngpio = <12>;
- ralink,regs = [ 00 04 08 0c
- 10 14 18 1c
- 20 24 ];
+ ralink,num-gpios = <12>;
+ ralink,register-map = [ 00 04 08 0c
+ 10 14 18 1c
+ 20 24 ];
+
+ status = "disabled";
+ };
+
+ spi@b00 {
+ compatible = "ralink,rt3050-spi", "ralink,rt2880-spi";
+ reg = <0xb00 0x100>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ status = "disabled";
};
uartlite@c00 {
@@ -102,5 +127,46 @@
reg-shift = <2>;
};
+
+ };
+
+ ethernet@10100000 {
+ compatible = "ralink,rt3050-eth";
+ reg = <0x10100000 10000>;
+
+ interrupt-parent = <&cpuintc>;
+ interrupts = <5>;
+
+ status = "disabled";
+ };
+
+ esw@10110000 {
+ compatible = "ralink,rt3050-esw";
+ reg = <0x10110000 8000>;
+
+ interrupt-parent = <&intc>;
+ interrupts = <17>;
+
+ status = "disabled";
+ };
+
+ wmac@10180000 {
+ compatible = "ralink,rt3050-wmac", "ralink,rt2880-wmac";
+ reg = <0x10180000 40000>;
+
+ interrupt-parent = <&cpuintc>;
+ interrupts = <6>;
+
+ status = "disabled";
+ };
+
+ otg@101c0000 {
+ compatible = "ralink,rt3050-otg";
+ reg = <0x101c0000 40000>;
+
+ interrupt-parent = <&intc>;
+ interrupts = <18>;
+
+ status = "disabled";
};
};
--
1.7.10.4

View file

@ -0,0 +1,204 @@
From 1238d973f3828a65ccf9aead437b4e04925b100e Mon Sep 17 00:00:00 2001
From: John Crispin <blogic@openwrt.org>
Date: Thu, 21 Mar 2013 17:47:24 +0100
Subject: [PATCH 106/121] MIPS: add RT5350 dtsi file
Add a dtsi file for RT5350 Soc. This SoC is almost the same as RT3050 but has
OHCI/EHCI in favour of the Synopsis DWC2 core.
Signed-off-by: John Crispin <blogic@openwrt.org>
---
arch/mips/ralink/dts/rt5350.dtsi | 181 ++++++++++++++++++++++++++++++++++++++
1 file changed, 181 insertions(+)
create mode 100644 arch/mips/ralink/dts/rt5350.dtsi
diff --git a/arch/mips/ralink/dts/rt5350.dtsi b/arch/mips/ralink/dts/rt5350.dtsi
new file mode 100644
index 0000000..9ca95a3
--- /dev/null
+++ b/arch/mips/ralink/dts/rt5350.dtsi
@@ -0,0 +1,181 @@
+/ {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "ralink,rt5350-soc";
+
+ cpus {
+ cpu@0 {
+ compatible = "mips,mips24KEc";
+ };
+ };
+
+ chosen {
+ bootargs = "console=ttyS0,57600 init=/init";
+ };
+
+ cpuintc: cpuintc@0 {
+ #address-cells = <0>;
+ #interrupt-cells = <1>;
+ interrupt-controller;
+ compatible = "mti,cpu-interrupt-controller";
+ };
+
+ palmbus@10000000 {
+ compatible = "palmbus";
+ reg = <0x10000000 0x200000>;
+ ranges = <0x0 0x10000000 0x1FFFFF>;
+
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ sysc@0 {
+ compatible = "ralink,rt5350-sysc", "ralink,rt3050-sysc";
+ reg = <0x0 0x100>;
+ };
+
+ timer@100 {
+ compatible = "ralink,rt5350-timer", "ralink,rt2880-timer";
+ reg = <0x100 0x20>;
+
+ interrupt-parent = <&intc>;
+ interrupts = <1>;
+
+ status = "disabled";
+ };
+
+ watchdog@120 {
+ compatible = "ralink,rt5350-wdt", "ralink,rt2880-wdt";
+ reg = <0x120 0x10>;
+ };
+
+ intc: intc@200 {
+ compatible = "ralink,rt5350-intc", "ralink,rt2880-intc";
+ reg = <0x200 0x100>;
+
+ interrupt-controller;
+ #interrupt-cells = <1>;
+
+ interrupt-parent = <&cpuintc>;
+ interrupts = <2>;
+ };
+
+ memc@300 {
+ compatible = "ralink,rt5350-memc", "ralink,rt3050-memc";
+ reg = <0x300 0x100>;
+ };
+
+ gpio0: gpio@600 {
+ compatible = "ralink,rt5350-gpio", "ralink,rt2880-gpio";
+ reg = <0x600 0x34>;
+
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ ralink,num-gpios = <24>;
+ ralink,register-map = [ 00 04 08 0c
+ 20 24 28 2c
+ 30 34 ];
+
+ status = "disabled";
+ };
+
+ gpio1: gpio@638 {
+ compatible = "ralink,rt5350-gpio", "ralink,rt2880-gpio";
+ reg = <0x638 0x24>;
+
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ ralink,num-gpios = <16>;
+ ralink,register-map = [ 00 04 08 0c
+ 10 14 18 1c
+ 20 24 ];
+
+ status = "disabled";
+ };
+
+ gpio2: gpio@660 {
+ compatible = "ralink,rt5350-gpio", "ralink,rt2880-gpio";
+ reg = <0x660 0x24>;
+
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ ralink,num-gpios = <12>;
+ ralink,register-map = [ 00 04 08 0c
+ 10 14 18 1c
+ 20 24 ];
+
+ status = "disabled";
+ };
+
+ spi@b00 {
+ compatible = "ralink,rt5350-spi", "ralink,rt2880-spi";
+ reg = <0xb00 0x100>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ status = "disabled";
+ };
+
+ uartlite@c00 {
+ compatible = "ralink,rt5350-uart", "ralink,rt2880-uart", "ns16550a";
+ reg = <0xc00 0x100>;
+
+ interrupt-parent = <&intc>;
+ interrupts = <12>;
+
+ reg-shift = <2>;
+ };
+ };
+
+ ethernet@10100000 {
+ compatible = "ralink,rt5350-eth", "ralink,rt3050-eth";
+ reg = <0x10100000 10000>;
+
+ interrupt-parent = <&cpuintc>;
+ interrupts = <5>;
+
+ status = "disabled";
+ };
+
+ esw@10110000 {
+ compatible = "ralink,rt5350-esw", "ralink,rt3050-esw";
+ reg = <0x10110000 8000>;
+
+ interrupt-parent = <&intc>;
+ interrupts = <17>;
+
+ status = "disabled";
+ };
+
+ wmac@10180000 {
+ compatible = "ralink,rt5350-wmac", "ralink,rt2880-wmac";
+ reg = <0x10180000 40000>;
+
+ interrupt-parent = <&cpuintc>;
+ interrupts = <6>;
+
+ status = "disabled";
+ };
+
+ ehci@101c0000 {
+ compatible = "ralink,rt5350-ehci", "ehci-platform";
+ reg = <0x101c0000 0x1000>;
+
+ interrupt-parent = <&intc>;
+ interrupts = <18>;
+
+ status = "disabled";
+ };
+
+ ohci@101c1000 {
+ compatible = "ralink,rt5350-ohci", "ohci-platform";
+ reg = <0x101c1000 0x1000>;
+
+ interrupt-parent = <&intc>;
+ interrupts = <18>;
+
+ status = "disabled";
+ };
+};
--
1.7.10.4

View file

@ -0,0 +1,281 @@
From f63a0ea6c115e7b78bce70d78aaa813615e3d434 Mon Sep 17 00:00:00 2001
From: John Crispin <blogic@openwrt.org>
Date: Sun, 27 Jan 2013 09:17:20 +0100
Subject: [PATCH 107/121] MIPS: ralink: adds support for RT2880 SoC family
Add support code for rt2880 SOC.
The code detects the SoC and registers the clk / pinmux settings.
Signed-off-by: John Crispin <blogic@openwrt.org>
---
arch/mips/Kconfig | 2 +-
arch/mips/include/asm/mach-ralink/rt288x.h | 49 ++++++++++
arch/mips/ralink/Kconfig | 3 +
arch/mips/ralink/Makefile | 1 +
arch/mips/ralink/Platform | 5 +
arch/mips/ralink/rt288x.c | 141 ++++++++++++++++++++++++++++
6 files changed, 200 insertions(+), 1 deletion(-)
create mode 100644 arch/mips/include/asm/mach-ralink/rt288x.h
create mode 100644 arch/mips/ralink/rt288x.c
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index cd2e21f..490d769 100644
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -1152,7 +1152,7 @@ config BOOT_ELF32
config MIPS_L1_CACHE_SHIFT
int
- default "4" if MACH_DECSTATION || MIKROTIK_RB532 || PMC_MSP4200_EVAL
+ default "4" if MACH_DECSTATION || MIKROTIK_RB532 || PMC_MSP4200_EVAL || SOC_RT288X
default "6" if MIPS_CPU_SCACHE
default "7" if SGI_IP22 || SGI_IP27 || SGI_IP28 || SNI_RM || CPU_CAVIUM_OCTEON
default "5"
diff --git a/arch/mips/include/asm/mach-ralink/rt288x.h b/arch/mips/include/asm/mach-ralink/rt288x.h
new file mode 100644
index 0000000..ad8b42d
--- /dev/null
+++ b/arch/mips/include/asm/mach-ralink/rt288x.h
@@ -0,0 +1,49 @@
+/*
+ * 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.
+ *
+ * Parts of this file are based on Ralink's 2.6.21 BSP
+ *
+ * Copyright (C) 2008-2011 Gabor Juhos <juhosg@openwrt.org>
+ * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
+ * Copyright (C) 2013 John Crispin <blogic@openwrt.org>
+ */
+
+#ifndef _RT288X_REGS_H_
+#define _RT288X_REGS_H_
+
+#define RT2880_SYSC_BASE 0x00300000
+
+#define SYSC_REG_CHIP_NAME0 0x00
+#define SYSC_REG_CHIP_NAME1 0x04
+#define SYSC_REG_CHIP_ID 0x0c
+#define SYSC_REG_SYSTEM_CONFIG 0x10
+#define SYSC_REG_CLKCFG 0x30
+
+#define RT2880_CHIP_NAME0 0x38325452
+#define RT2880_CHIP_NAME1 0x20203038
+
+#define CHIP_ID_ID_MASK 0xff
+#define CHIP_ID_ID_SHIFT 8
+#define CHIP_ID_REV_MASK 0xff
+
+#define SYSTEM_CONFIG_CPUCLK_SHIFT 20
+#define SYSTEM_CONFIG_CPUCLK_MASK 0x3
+#define SYSTEM_CONFIG_CPUCLK_250 0x0
+#define SYSTEM_CONFIG_CPUCLK_266 0x1
+#define SYSTEM_CONFIG_CPUCLK_280 0x2
+#define SYSTEM_CONFIG_CPUCLK_300 0x3
+
+#define RT2880_GPIO_MODE_I2C BIT(0)
+#define RT2880_GPIO_MODE_UART0 BIT(1)
+#define RT2880_GPIO_MODE_SPI BIT(2)
+#define RT2880_GPIO_MODE_UART1 BIT(3)
+#define RT2880_GPIO_MODE_JTAG BIT(4)
+#define RT2880_GPIO_MODE_MDIO BIT(5)
+#define RT2880_GPIO_MODE_SDRAM BIT(6)
+#define RT2880_GPIO_MODE_PCI BIT(7)
+
+#define CLKCFG_SRAM_CS_N_WDT BIT(9)
+
+#endif
diff --git a/arch/mips/ralink/Kconfig b/arch/mips/ralink/Kconfig
index a0b0197..6723b94 100644
--- a/arch/mips/ralink/Kconfig
+++ b/arch/mips/ralink/Kconfig
@@ -6,6 +6,9 @@ choice
help
Select Ralink MIPS SoC type.
+ config SOC_RT288X
+ bool "RT288x"
+
config SOC_RT305X
bool "RT305x"
select USB_ARCH_HAS_HCD
diff --git a/arch/mips/ralink/Makefile b/arch/mips/ralink/Makefile
index 39ef249..ce83bfc 100644
--- a/arch/mips/ralink/Makefile
+++ b/arch/mips/ralink/Makefile
@@ -8,6 +8,7 @@
obj-y := prom.o of.o reset.o clk.o irq.o pinmux.o
+obj-$(CONFIG_SOC_RT288X) += rt288x.o
obj-$(CONFIG_SOC_RT305X) += rt305x.o
obj-$(CONFIG_EARLY_PRINTK) += early_printk.o
diff --git a/arch/mips/ralink/Platform b/arch/mips/ralink/Platform
index 6babd65..3f49e51 100644
--- a/arch/mips/ralink/Platform
+++ b/arch/mips/ralink/Platform
@@ -5,6 +5,11 @@ core-$(CONFIG_RALINK) += arch/mips/ralink/
cflags-$(CONFIG_RALINK) += -I$(srctree)/arch/mips/include/asm/mach-ralink
#
+# Ralink RT288x
+#
+load-$(CONFIG_SOC_RT288X) += 0xffffffff88000000
+
+#
# Ralink RT305x
#
load-$(CONFIG_SOC_RT305X) += 0xffffffff80000000
diff --git a/arch/mips/ralink/rt288x.c b/arch/mips/ralink/rt288x.c
new file mode 100644
index 0000000..37faff0
--- /dev/null
+++ b/arch/mips/ralink/rt288x.c
@@ -0,0 +1,141 @@
+/*
+ * 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.
+ *
+ * Parts of this file are based on Ralink's 2.6.21 BSP
+ *
+ * Copyright (C) 2008-2011 Gabor Juhos <juhosg@openwrt.org>
+ * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
+ * Copyright (C) 2013 John Crispin <blogic@openwrt.org>
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/module.h>
+
+#include <asm/mipsregs.h>
+#include <asm/mach-ralink/ralink_regs.h>
+#include <asm/mach-ralink/rt288x.h>
+
+#include "common.h"
+
+struct ralink_pinmux_grp mode_mux[] = {
+ {
+ .name = "i2c",
+ .mask = RT2880_GPIO_MODE_I2C,
+ .gpio_first = 1,
+ .gpio_last = 2,
+ }, {
+ .name = "spi",
+ .mask = RT2880_GPIO_MODE_SPI,
+ .gpio_first = 3,
+ .gpio_last = 6,
+ }, {
+ .name = "uartlite",
+ .mask = RT2880_GPIO_MODE_UART0,
+ .gpio_first = 7,
+ .gpio_last = 14,
+ }, {
+ .name = "jtag",
+ .mask = RT2880_GPIO_MODE_JTAG,
+ .gpio_first = 17,
+ .gpio_last = 21,
+ }, {
+ .name = "mdio",
+ .mask = RT2880_GPIO_MODE_MDIO,
+ .gpio_first = 22,
+ .gpio_last = 23,
+ }, {
+ .name = "sdram",
+ .mask = RT2880_GPIO_MODE_SDRAM,
+ .gpio_first = 24,
+ .gpio_last = 39,
+ }, {
+ .name = "pci",
+ .mask = RT2880_GPIO_MODE_PCI,
+ .gpio_first = 40,
+ .gpio_last = 71,
+ }, {0}
+};
+
+void rt288x_wdt_reset(void)
+{
+ u32 t;
+
+ /* enable WDT reset output on pin SRAM_CS_N */
+ t = rt_sysc_r32(SYSC_REG_CLKCFG);
+ t |= CLKCFG_SRAM_CS_N_WDT;
+ rt_sysc_w32(t, SYSC_REG_CLKCFG);
+}
+
+struct ralink_pinmux rt_pinmux = {
+ .mode = mode_mux,
+ .wdt_reset = rt288x_wdt_reset,
+};
+
+void ralink_usb_platform(void)
+{
+}
+
+void __init ralink_clk_init(void)
+{
+ unsigned long cpu_rate;
+ u32 t = rt_sysc_r32(SYSC_REG_SYSTEM_CONFIG);
+ t = ((t >> SYSTEM_CONFIG_CPUCLK_SHIFT) & SYSTEM_CONFIG_CPUCLK_MASK);
+
+ switch (t) {
+ case SYSTEM_CONFIG_CPUCLK_250:
+ cpu_rate = 250000000;
+ break;
+ case SYSTEM_CONFIG_CPUCLK_266:
+ cpu_rate = 266666667;
+ break;
+ case SYSTEM_CONFIG_CPUCLK_280:
+ cpu_rate = 280000000;
+ break;
+ case SYSTEM_CONFIG_CPUCLK_300:
+ cpu_rate = 300000000;
+ break;
+ }
+
+ ralink_clk_add("cpu", cpu_rate);
+ ralink_clk_add("10000100.timer", cpu_rate / 2);
+ ralink_clk_add("10000500.uart", cpu_rate / 2);
+ ralink_clk_add("10000c00.uartlite", cpu_rate / 2);
+}
+
+void __init ralink_of_remap(void)
+{
+ rt_sysc_membase = plat_of_remap_node("ralink,rt288x-sysc");
+ rt_memc_membase = plat_of_remap_node("ralink,rt288x-memc");
+
+ if (!rt_sysc_membase || !rt_memc_membase)
+ panic("Failed to remap core resources");
+}
+
+void prom_soc_init(struct ralink_soc_info *soc_info)
+{
+ void __iomem *sysc = (void __iomem *) KSEG1ADDR(RT2880_SYSC_BASE);
+ const char *name;
+ u32 n0;
+ u32 n1;
+ u32 id;
+
+ n0 = __raw_readl(sysc + SYSC_REG_CHIP_NAME0);
+ n1 = __raw_readl(sysc + SYSC_REG_CHIP_NAME1);
+ id = __raw_readl(sysc + SYSC_REG_CHIP_ID);
+
+ if (n0 == RT2880_CHIP_NAME0 && n1 == RT2880_CHIP_NAME1) {
+ soc_info->compatible = "ralink,r2880-soc";
+ name = "RT2880";
+ } else {
+ panic("rt288x: unknown SoC, n0:%08x n1:%08x", n0, n1);
+ }
+
+ snprintf(soc_info->sys_type, RAMIPS_SYS_TYPE_LEN,
+ "Ralink %s id:%u rev:%u",
+ name,
+ (id >> CHIP_ID_ID_SHIFT) & CHIP_ID_ID_MASK,
+ (id & CHIP_ID_REV_MASK));
+}
--
1.7.10.4

View file

@ -0,0 +1,223 @@
From b72ae753b73cbc4b488dcdbf997faec199c8bb3f Mon Sep 17 00:00:00 2001
From: John Crispin <blogic@openwrt.org>
Date: Thu, 21 Mar 2013 18:29:02 +0100
Subject: [PATCH 108/121] MIPS: add rt2880 dts files
Add a dtsi file for RT2880 SoC and a sample dts file. This SoC is first one that
was released in this SoC family.
Signed-off-by: John Crispin <blogic@openwrt.org>
---
arch/mips/ralink/Kconfig | 4 ++
arch/mips/ralink/dts/Makefile | 1 +
arch/mips/ralink/dts/rt2880.dtsi | 116 ++++++++++++++++++++++++++++++++++
arch/mips/ralink/dts/rt2880_eval.dts | 52 +++++++++++++++
4 files changed, 173 insertions(+)
create mode 100644 arch/mips/ralink/dts/rt2880.dtsi
create mode 100644 arch/mips/ralink/dts/rt2880_eval.dts
diff --git a/arch/mips/ralink/Kconfig b/arch/mips/ralink/Kconfig
index 6723b94..0d312fc 100644
--- a/arch/mips/ralink/Kconfig
+++ b/arch/mips/ralink/Kconfig
@@ -26,6 +26,10 @@ choice
config DTB_RT_NONE
bool "None"
+ config DTB_RT2880_EVAL
+ bool "RT2880 eval kit"
+ depends on SOC_RT288X
+
config DTB_RT305X_EVAL
bool "RT305x eval kit"
depends on SOC_RT305X
diff --git a/arch/mips/ralink/dts/Makefile b/arch/mips/ralink/dts/Makefile
index 1a69fb3..f635a01 100644
--- a/arch/mips/ralink/dts/Makefile
+++ b/arch/mips/ralink/dts/Makefile
@@ -1 +1,2 @@
+obj-$(CONFIG_DTB_RT2880_EVAL) := rt2880_eval.dtb.o
obj-$(CONFIG_DTB_RT305X_EVAL) := rt3052_eval.dtb.o
diff --git a/arch/mips/ralink/dts/rt2880.dtsi b/arch/mips/ralink/dts/rt2880.dtsi
new file mode 100644
index 0000000..b51c227
--- /dev/null
+++ b/arch/mips/ralink/dts/rt2880.dtsi
@@ -0,0 +1,116 @@
+/ {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "ralink,rt2880-soc";
+
+ cpus {
+ cpu@0 {
+ compatible = "mips,mips24KEc";
+ };
+ };
+
+ chosen {
+ bootargs = "console=ttyS0,57600 init=/init";
+ };
+
+ cpuintc: cpuintc@0 {
+ #address-cells = <0>;
+ #interrupt-cells = <1>;
+ interrupt-controller;
+ compatible = "mti,cpu-interrupt-controller";
+ };
+
+ palmbus@10000000 {
+ compatible = "palmbus";
+ reg = <0x10000000 0x200000>;
+ ranges = <0x0 0x10000000 0x1FFFFF>;
+
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ sysc@300000 {
+ compatible = "ralink,rt2880-sysc";
+ reg = <0x300000 0x100>;
+ };
+
+ timer@300100 {
+ compatible = "ralink,rt2880-timer";
+ reg = <0x300100 0x20>;
+
+ interrupt-parent = <&intc>;
+ interrupts = <1>;
+
+ status = "disabled";
+ };
+
+ watchdog@300120 {
+ compatible = "ralink,rt2880-wdt";
+ reg = <0x300120 0x10>;
+ };
+
+ intc: intc@300200 {
+ compatible = "ralink,rt2880-intc";
+ reg = <0x300200 0x100>;
+
+ interrupt-controller;
+ #interrupt-cells = <1>;
+
+ interrupt-parent = <&cpuintc>;
+ interrupts = <2>;
+ };
+
+ memc@300300 {
+ compatible = "ralink,rt2880-memc";
+ reg = <0x300300 0x100>;
+ };
+
+ gpio0: gpio@300600 {
+ compatible = "ralink,rt2880-gpio";
+ reg = <0x300600 0x34>;
+
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ ralink,num-gpios = <24>;
+ ralink,register-map = [ 00 04 08 0c
+ 20 24 28 2c
+ 30 34 ];
+ };
+
+ gpio1: gpio@300638 {
+ compatible = "ralink,rt2880-gpio";
+ reg = <0x300638 0x24>;
+
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ ralink,num-gpios = <16>;
+ ralink,register-map = [ 00 04 08 0c
+ 10 14 18 1c
+ 20 24 ];
+ };
+
+ gpio2: gpio@300660 {
+ compatible = "ralink,rt2880-gpio";
+ reg = <0x300660 0x24>;
+
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ ralink,num-gpios = <32>;
+ ralink,register-map = [ 00 04 08 0c
+ 10 14 18 1c
+ 20 24 ];
+ };
+
+ uartlite@300c00 {
+ compatible = "ralink,rt2880-uart", "ns16550a";
+ reg = <0x300c00 0x100>;
+
+ interrupt-parent = <&intc>;
+ interrupts = <12>;
+
+ reg-shift = <2>;
+ };
+ };
+};
diff --git a/arch/mips/ralink/dts/rt2880_eval.dts b/arch/mips/ralink/dts/rt2880_eval.dts
new file mode 100644
index 0000000..7c74e16
--- /dev/null
+++ b/arch/mips/ralink/dts/rt2880_eval.dts
@@ -0,0 +1,52 @@
+/dts-v1/;
+
+/include/ "rt2880.dtsi"
+
+/ {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "ralink,rt2880-eval-board", "ralink,rt2880-soc";
+ model = "Ralink RT2880 evaluation board";
+
+ memory@8000000 {
+ reg = <0x0 0x2000000>;
+ };
+
+ palmbus@10000000 {
+ sysc@300000 {
+ ralink,pinmmux = "uartlite", "spi";
+ ralink,uartmux = "gpio";
+ ralink,wdtmux = <0>;
+ };
+ };
+
+ cfi@1f000000 {
+ compatible = "cfi-flash";
+ reg = <0x1f000000 0x800000>;
+
+ bank-width = <2>;
+ device-width = <2>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ partition@0 {
+ label = "uboot";
+ reg = <0x0 0x30000>;
+ read-only;
+ };
+ partition@30000 {
+ label = "uboot-env";
+ reg = <0x30000 0x10000>;
+ read-only;
+ };
+ partition@40000 {
+ label = "calibration";
+ reg = <0x40000 0x10000>;
+ read-only;
+ };
+ partition@50000 {
+ label = "linux";
+ reg = <0x50000 0x7b0000>;
+ };
+ };
+};
--
1.7.10.4

View file

@ -0,0 +1,530 @@
From 45a8644332a85e8b099df9d467a719ded741e749 Mon Sep 17 00:00:00 2001
From: John Crispin <blogic@openwrt.org>
Date: Sun, 27 Jan 2013 09:39:02 +0100
Subject: [PATCH 109/121] MIPS: ralink: adds support for RT3883 SoC family
Add support code for rt3883 SOC.
The code detects the SoC and registers the clk / pinmux settings.
Signed-off-by: John Crispin <blogic@openwrt.org>
---
arch/mips/include/asm/mach-ralink/rt3883.h | 247 ++++++++++++++++++++++++++++
arch/mips/ralink/Kconfig | 5 +
arch/mips/ralink/Makefile | 1 +
arch/mips/ralink/Platform | 5 +
arch/mips/ralink/rt3883.c | 207 +++++++++++++++++++++++
5 files changed, 465 insertions(+)
create mode 100644 arch/mips/include/asm/mach-ralink/rt3883.h
create mode 100644 arch/mips/ralink/rt3883.c
diff --git a/arch/mips/include/asm/mach-ralink/rt3883.h b/arch/mips/include/asm/mach-ralink/rt3883.h
new file mode 100644
index 0000000..b91c6c1
--- /dev/null
+++ b/arch/mips/include/asm/mach-ralink/rt3883.h
@@ -0,0 +1,247 @@
+/*
+ * Ralink RT3662/RT3883 SoC register definitions
+ *
+ * Copyright (C) 2011-2012 Gabor Juhos <juhosg@openwrt.org>
+ *
+ * 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.
+ */
+
+#ifndef _RT3883_REGS_H_
+#define _RT3883_REGS_H_
+
+#include <linux/bitops.h>
+
+#define RT3883_SDRAM_BASE 0x00000000
+#define RT3883_SYSC_BASE 0x10000000
+#define RT3883_TIMER_BASE 0x10000100
+#define RT3883_INTC_BASE 0x10000200
+#define RT3883_MEMC_BASE 0x10000300
+#define RT3883_UART0_BASE 0x10000500
+#define RT3883_PIO_BASE 0x10000600
+#define RT3883_FSCC_BASE 0x10000700
+#define RT3883_NANDC_BASE 0x10000810
+#define RT3883_I2C_BASE 0x10000900
+#define RT3883_I2S_BASE 0x10000a00
+#define RT3883_SPI_BASE 0x10000b00
+#define RT3883_UART1_BASE 0x10000c00
+#define RT3883_PCM_BASE 0x10002000
+#define RT3883_GDMA_BASE 0x10002800
+#define RT3883_CODEC1_BASE 0x10003000
+#define RT3883_CODEC2_BASE 0x10003800
+#define RT3883_FE_BASE 0x10100000
+#define RT3883_ROM_BASE 0x10118000
+#define RT3883_USBDEV_BASE 0x10112000
+#define RT3883_PCI_BASE 0x10140000
+#define RT3883_WLAN_BASE 0x10180000
+#define RT3883_USBHOST_BASE 0x101c0000
+#define RT3883_BOOT_BASE 0x1c000000
+#define RT3883_SRAM_BASE 0x1e000000
+#define RT3883_PCIMEM_BASE 0x20000000
+
+#define RT3883_EHCI_BASE (RT3883_USBHOST_BASE)
+#define RT3883_OHCI_BASE (RT3883_USBHOST_BASE + 0x1000)
+
+#define RT3883_SYSC_SIZE 0x100
+#define RT3883_TIMER_SIZE 0x100
+#define RT3883_INTC_SIZE 0x100
+#define RT3883_MEMC_SIZE 0x100
+#define RT3883_UART0_SIZE 0x100
+#define RT3883_UART1_SIZE 0x100
+#define RT3883_PIO_SIZE 0x100
+#define RT3883_FSCC_SIZE 0x100
+#define RT3883_NANDC_SIZE 0x0f0
+#define RT3883_I2C_SIZE 0x100
+#define RT3883_I2S_SIZE 0x100
+#define RT3883_SPI_SIZE 0x100
+#define RT3883_PCM_SIZE 0x800
+#define RT3883_GDMA_SIZE 0x800
+#define RT3883_CODEC1_SIZE 0x800
+#define RT3883_CODEC2_SIZE 0x800
+#define RT3883_FE_SIZE 0x10000
+#define RT3883_ROM_SIZE 0x4000
+#define RT3883_USBDEV_SIZE 0x4000
+#define RT3883_PCI_SIZE 0x40000
+#define RT3883_WLAN_SIZE 0x40000
+#define RT3883_USBHOST_SIZE 0x40000
+#define RT3883_BOOT_SIZE (32 * 1024 * 1024)
+#define RT3883_SRAM_SIZE (32 * 1024 * 1024)
+
+/* SYSC registers */
+#define RT3883_SYSC_REG_CHIPID0_3 0x00 /* Chip ID 0 */
+#define RT3883_SYSC_REG_CHIPID4_7 0x04 /* Chip ID 1 */
+#define RT3883_SYSC_REG_REVID 0x0c /* Chip Revision Identification */
+#define RT3883_SYSC_REG_SYSCFG0 0x10 /* System Configuration 0 */
+#define RT3883_SYSC_REG_SYSCFG1 0x14 /* System Configuration 1 */
+#define RT3883_SYSC_REG_CLKCFG0 0x2c /* Clock Configuration 0 */
+#define RT3883_SYSC_REG_CLKCFG1 0x30 /* Clock Configuration 1 */
+#define RT3883_SYSC_REG_RSTCTRL 0x34 /* Reset Control*/
+#define RT3883_SYSC_REG_RSTSTAT 0x38 /* Reset Status*/
+#define RT3883_SYSC_REG_USB_PS 0x5c /* USB Power saving control */
+#define RT3883_SYSC_REG_GPIO_MODE 0x60 /* GPIO Purpose Select */
+#define RT3883_SYSC_REG_PCIE_CLK_GEN0 0x7c
+#define RT3883_SYSC_REG_PCIE_CLK_GEN1 0x80
+#define RT3883_SYSC_REG_PCIE_CLK_GEN2 0x84
+#define RT3883_SYSC_REG_PMU 0x88
+#define RT3883_SYSC_REG_PMU1 0x8c
+
+#define RT3883_CHIP_NAME0 0x38335452
+#define RT3883_CHIP_NAME1 0x20203338
+
+#define RT3883_REVID_VER_ID_MASK 0x0f
+#define RT3883_REVID_VER_ID_SHIFT 8
+#define RT3883_REVID_ECO_ID_MASK 0x0f
+
+#define RT3883_SYSCFG0_DRAM_TYPE_DDR2 BIT(17)
+#define RT3883_SYSCFG0_CPUCLK_SHIFT 8
+#define RT3883_SYSCFG0_CPUCLK_MASK 0x3
+#define RT3883_SYSCFG0_CPUCLK_250 0x0
+#define RT3883_SYSCFG0_CPUCLK_384 0x1
+#define RT3883_SYSCFG0_CPUCLK_480 0x2
+#define RT3883_SYSCFG0_CPUCLK_500 0x3
+
+#define RT3883_SYSCFG1_USB0_HOST_MODE BIT(10)
+#define RT3883_SYSCFG1_PCIE_RC_MODE BIT(8)
+#define RT3883_SYSCFG1_PCI_HOST_MODE BIT(7)
+#define RT3883_SYSCFG1_PCI_66M_MODE BIT(6)
+#define RT3883_SYSCFG1_GPIO2_AS_WDT_OUT BIT(2)
+
+#define RT3883_CLKCFG1_PCIE_CLK_EN BIT(21)
+#define RT3883_CLKCFG1_UPHY1_CLK_EN BIT(20)
+#define RT3883_CLKCFG1_PCI_CLK_EN BIT(19)
+#define RT3883_CLKCFG1_UPHY0_CLK_EN BIT(18)
+
+#define RT3883_GPIO_MODE_I2C BIT(0)
+#define RT3883_GPIO_MODE_SPI BIT(1)
+#define RT3883_GPIO_MODE_UART0_SHIFT 2
+#define RT3883_GPIO_MODE_UART0_MASK 0x7
+#define RT3883_GPIO_MODE_UART0(x) ((x) << RT3883_GPIO_MODE_UART0_SHIFT)
+#define RT3883_GPIO_MODE_UARTF 0x0
+#define RT3883_GPIO_MODE_PCM_UARTF 0x1
+#define RT3883_GPIO_MODE_PCM_I2S 0x2
+#define RT3883_GPIO_MODE_I2S_UARTF 0x3
+#define RT3883_GPIO_MODE_PCM_GPIO 0x4
+#define RT3883_GPIO_MODE_GPIO_UARTF 0x5
+#define RT3883_GPIO_MODE_GPIO_I2S 0x6
+#define RT3883_GPIO_MODE_GPIO 0x7
+#define RT3883_GPIO_MODE_UART1 BIT(5)
+#define RT3883_GPIO_MODE_JTAG BIT(6)
+#define RT3883_GPIO_MODE_MDIO BIT(7)
+#define RT3883_GPIO_MODE_GE1 BIT(9)
+#define RT3883_GPIO_MODE_GE2 BIT(10)
+#define RT3883_GPIO_MODE_PCI_SHIFT 11
+#define RT3883_GPIO_MODE_PCI_MASK 0x7
+#define RT3883_GPIO_MODE_PCI (RT3883_GPIO_MODE_PCI_MASK << RT3883_GPIO_MODE_PCI_SHIFT)
+#define RT3883_GPIO_MODE_LNA_A_SHIFT 16
+#define RT3883_GPIO_MODE_LNA_A_MASK 0x3
+#define _RT3883_GPIO_MODE_LNA_A(_x) ((_x) << RT3883_GPIO_MODE_LNA_A_SHIFT)
+#define RT3883_GPIO_MODE_LNA_A_GPIO 0x3
+#define RT3883_GPIO_MODE_LNA_A _RT3883_GPIO_MODE_LNA_A(RT3883_GPIO_MODE_LNA_A_MASK)
+#define RT3883_GPIO_MODE_LNA_G_SHIFT 18
+#define RT3883_GPIO_MODE_LNA_G_MASK 0x3
+#define _RT3883_GPIO_MODE_LNA_G(_x) ((_x) << RT3883_GPIO_MODE_LNA_G_SHIFT)
+#define RT3883_GPIO_MODE_LNA_G_GPIO 0x3
+#define RT3883_GPIO_MODE_LNA_G _RT3883_GPIO_MODE_LNA_G(RT3883_GPIO_MODE_LNA_G_MASK)
+
+#define RT3883_GPIO_I2C_SD 1
+#define RT3883_GPIO_I2C_SCLK 2
+#define RT3883_GPIO_SPI_CS0 3
+#define RT3883_GPIO_SPI_CLK 4
+#define RT3883_GPIO_SPI_MOSI 5
+#define RT3883_GPIO_SPI_MISO 6
+#define RT3883_GPIO_7 7
+#define RT3883_GPIO_10 10
+#define RT3883_GPIO_14 14
+#define RT3883_GPIO_UART1_TXD 15
+#define RT3883_GPIO_UART1_RXD 16
+#define RT3883_GPIO_JTAG_TDO 17
+#define RT3883_GPIO_JTAG_TDI 18
+#define RT3883_GPIO_JTAG_TMS 19
+#define RT3883_GPIO_JTAG_TCLK 20
+#define RT3883_GPIO_JTAG_TRST_N 21
+#define RT3883_GPIO_MDIO_MDC 22
+#define RT3883_GPIO_MDIO_MDIO 23
+#define RT3883_GPIO_LNA_PE_A0 32
+#define RT3883_GPIO_LNA_PE_A1 33
+#define RT3883_GPIO_LNA_PE_A2 34
+#define RT3883_GPIO_LNA_PE_G0 35
+#define RT3883_GPIO_LNA_PE_G1 36
+#define RT3883_GPIO_LNA_PE_G2 37
+#define RT3883_GPIO_PCI_AD0 40
+#define RT3883_GPIO_PCI_AD31 71
+#define RT3883_GPIO_GE2_TXD0 72
+#define RT3883_GPIO_GE2_TXD1 73
+#define RT3883_GPIO_GE2_TXD2 74
+#define RT3883_GPIO_GE2_TXD3 75
+#define RT3883_GPIO_GE2_TXEN 76
+#define RT3883_GPIO_GE2_TXCLK 77
+#define RT3883_GPIO_GE2_RXD0 78
+#define RT3883_GPIO_GE2_RXD1 79
+#define RT3883_GPIO_GE2_RXD2 80
+#define RT3883_GPIO_GE2_RXD3 81
+#define RT3883_GPIO_GE2_RXDV 82
+#define RT3883_GPIO_GE2_RXCLK 83
+#define RT3883_GPIO_GE1_TXD0 84
+#define RT3883_GPIO_GE1_TXD1 85
+#define RT3883_GPIO_GE1_TXD2 86
+#define RT3883_GPIO_GE1_TXD3 87
+#define RT3883_GPIO_GE1_TXEN 88
+#define RT3883_GPIO_GE1_TXCLK 89
+#define RT3883_GPIO_GE1_RXD0 90
+#define RT3883_GPIO_GE1_RXD1 91
+#define RT3883_GPIO_GE1_RXD2 92
+#define RT3883_GPIO_GE1_RXD3 93
+#define RT3883_GPIO_GE1_RXDV 94
+#define RT3883_GPIO_GE1_RXCLK 95
+
+#define RT3883_RSTCTRL_PCIE_PCI_PDM BIT(27)
+#define RT3883_RSTCTRL_FLASH BIT(26)
+#define RT3883_RSTCTRL_UDEV BIT(25)
+#define RT3883_RSTCTRL_PCI BIT(24)
+#define RT3883_RSTCTRL_PCIE BIT(23)
+#define RT3883_RSTCTRL_UHST BIT(22)
+#define RT3883_RSTCTRL_FE BIT(21)
+#define RT3883_RSTCTRL_WLAN BIT(20)
+#define RT3883_RSTCTRL_UART1 BIT(29)
+#define RT3883_RSTCTRL_SPI BIT(18)
+#define RT3883_RSTCTRL_I2S BIT(17)
+#define RT3883_RSTCTRL_I2C BIT(16)
+#define RT3883_RSTCTRL_NAND BIT(15)
+#define RT3883_RSTCTRL_DMA BIT(14)
+#define RT3883_RSTCTRL_PIO BIT(13)
+#define RT3883_RSTCTRL_UART BIT(12)
+#define RT3883_RSTCTRL_PCM BIT(11)
+#define RT3883_RSTCTRL_MC BIT(10)
+#define RT3883_RSTCTRL_INTC BIT(9)
+#define RT3883_RSTCTRL_TIMER BIT(8)
+#define RT3883_RSTCTRL_SYS BIT(0)
+
+#define RT3883_INTC_INT_SYSCTL BIT(0)
+#define RT3883_INTC_INT_TIMER0 BIT(1)
+#define RT3883_INTC_INT_TIMER1 BIT(2)
+#define RT3883_INTC_INT_IA BIT(3)
+#define RT3883_INTC_INT_PCM BIT(4)
+#define RT3883_INTC_INT_UART0 BIT(5)
+#define RT3883_INTC_INT_PIO BIT(6)
+#define RT3883_INTC_INT_DMA BIT(7)
+#define RT3883_INTC_INT_NAND BIT(8)
+#define RT3883_INTC_INT_PERFC BIT(9)
+#define RT3883_INTC_INT_I2S BIT(10)
+#define RT3883_INTC_INT_UART1 BIT(12)
+#define RT3883_INTC_INT_UHST BIT(18)
+#define RT3883_INTC_INT_UDEV BIT(19)
+
+/* FLASH/SRAM/Codec Controller registers */
+#define RT3883_FSCC_REG_FLASH_CFG0 0x00
+#define RT3883_FSCC_REG_FLASH_CFG1 0x04
+#define RT3883_FSCC_REG_CODEC_CFG0 0x40
+#define RT3883_FSCC_REG_CODEC_CFG1 0x44
+
+#define RT3883_FLASH_CFG_WIDTH_SHIFT 26
+#define RT3883_FLASH_CFG_WIDTH_MASK 0x3
+#define RT3883_FLASH_CFG_WIDTH_8BIT 0x0
+#define RT3883_FLASH_CFG_WIDTH_16BIT 0x1
+#define RT3883_FLASH_CFG_WIDTH_32BIT 0x2
+
+#endif /* _RT3883_REGS_H_ */
diff --git a/arch/mips/ralink/Kconfig b/arch/mips/ralink/Kconfig
index 0d312fc..f21cbaa 100644
--- a/arch/mips/ralink/Kconfig
+++ b/arch/mips/ralink/Kconfig
@@ -15,6 +15,11 @@ choice
select USB_ARCH_HAS_OHCI
select USB_ARCH_HAS_EHCI
+ config SOC_RT3883
+ bool "RT3883"
+ select USB_ARCH_HAS_OHCI
+ select USB_ARCH_HAS_EHCI
+
endchoice
choice
diff --git a/arch/mips/ralink/Makefile b/arch/mips/ralink/Makefile
index ce83bfc..87f6ca9 100644
--- a/arch/mips/ralink/Makefile
+++ b/arch/mips/ralink/Makefile
@@ -10,6 +10,7 @@ obj-y := prom.o of.o reset.o clk.o irq.o pinmux.o
obj-$(CONFIG_SOC_RT288X) += rt288x.o
obj-$(CONFIG_SOC_RT305X) += rt305x.o
+obj-$(CONFIG_SOC_RT3883) += rt3883.o
obj-$(CONFIG_EARLY_PRINTK) += early_printk.o
diff --git a/arch/mips/ralink/Platform b/arch/mips/ralink/Platform
index 3f49e51..f67c08d 100644
--- a/arch/mips/ralink/Platform
+++ b/arch/mips/ralink/Platform
@@ -13,3 +13,8 @@ load-$(CONFIG_SOC_RT288X) += 0xffffffff88000000
# Ralink RT305x
#
load-$(CONFIG_SOC_RT305X) += 0xffffffff80000000
+
+#
+# Ralink RT3883
+#
+load-$(CONFIG_SOC_RT3883) += 0xffffffff80000000
diff --git a/arch/mips/ralink/rt3883.c b/arch/mips/ralink/rt3883.c
new file mode 100644
index 0000000..10a8150
--- /dev/null
+++ b/arch/mips/ralink/rt3883.c
@@ -0,0 +1,207 @@
+/*
+ * 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.
+ *
+ * Parts of this file are based on Ralink's 2.6.21 BSP
+ *
+ * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
+ * Copyright (C) 2008-2011 Gabor Juhos <juhosg@openwrt.org>
+ * Copyright (C) 2013 John Crispin <blogic@openwrt.org>
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/module.h>
+
+#include <asm/mipsregs.h>
+#include <asm/mach-ralink/ralink_regs.h>
+#include <asm/mach-ralink/rt3883.h>
+
+#include "common.h"
+
+struct ralink_pinmux_grp mode_mux[] = {
+ {
+ .name = "i2c",
+ .mask = RT3883_GPIO_MODE_I2C,
+ .gpio_first = RT3883_GPIO_I2C_SD,
+ .gpio_last = RT3883_GPIO_I2C_SCLK,
+ }, {
+ .name = "spi",
+ .mask = RT3883_GPIO_MODE_SPI,
+ .gpio_first = RT3883_GPIO_SPI_CS0,
+ .gpio_last = RT3883_GPIO_SPI_MISO,
+ }, {
+ .name = "uartlite",
+ .mask = RT3883_GPIO_MODE_UART1,
+ .gpio_first = RT3883_GPIO_UART1_TXD,
+ .gpio_last = RT3883_GPIO_UART1_RXD,
+ }, {
+ .name = "jtag",
+ .mask = RT3883_GPIO_MODE_JTAG,
+ .gpio_first = RT3883_GPIO_JTAG_TDO,
+ .gpio_last = RT3883_GPIO_JTAG_TCLK,
+ }, {
+ .name = "mdio",
+ .mask = RT3883_GPIO_MODE_MDIO,
+ .gpio_first = RT3883_GPIO_MDIO_MDC,
+ .gpio_last = RT3883_GPIO_MDIO_MDIO,
+ }, {
+ .name = "ge1",
+ .mask = RT3883_GPIO_MODE_GE1,
+ .gpio_first = RT3883_GPIO_GE1_TXD0,
+ .gpio_last = RT3883_GPIO_GE1_RXCLK,
+ }, {
+ .name = "ge2",
+ .mask = RT3883_GPIO_MODE_GE2,
+ .gpio_first = RT3883_GPIO_GE2_TXD0,
+ .gpio_last = RT3883_GPIO_GE2_RXCLK,
+ }, {
+ .name = "pci",
+ .mask = RT3883_GPIO_MODE_PCI,
+ .gpio_first = RT3883_GPIO_PCI_AD0,
+ .gpio_last = RT3883_GPIO_PCI_AD31,
+ }, {
+ .name = "lna a",
+ .mask = RT3883_GPIO_MODE_LNA_A,
+ .gpio_first = RT3883_GPIO_LNA_PE_A0,
+ .gpio_last = RT3883_GPIO_LNA_PE_A2,
+ }, {
+ .name = "lna g",
+ .mask = RT3883_GPIO_MODE_LNA_G,
+ .gpio_first = RT3883_GPIO_LNA_PE_G0,
+ .gpio_last = RT3883_GPIO_LNA_PE_G2,
+ }, {0}
+};
+
+struct ralink_pinmux_grp uart_mux[] = {
+ {
+ .name = "uartf",
+ .mask = RT3883_GPIO_MODE_UARTF,
+ .gpio_first = RT3883_GPIO_7,
+ .gpio_last = RT3883_GPIO_14,
+ }, {
+ .name = "pcm uartf",
+ .mask = RT3883_GPIO_MODE_PCM_UARTF,
+ .gpio_first = RT3883_GPIO_7,
+ .gpio_last = RT3883_GPIO_14,
+ }, {
+ .name = "pcm i2s",
+ .mask = RT3883_GPIO_MODE_PCM_I2S,
+ .gpio_first = RT3883_GPIO_7,
+ .gpio_last = RT3883_GPIO_14,
+ }, {
+ .name = "i2s uartf",
+ .mask = RT3883_GPIO_MODE_I2S_UARTF,
+ .gpio_first = RT3883_GPIO_7,
+ .gpio_last = RT3883_GPIO_14,
+ }, {
+ .name = "pcm gpio",
+ .mask = RT3883_GPIO_MODE_PCM_GPIO,
+ .gpio_first = RT3883_GPIO_10,
+ .gpio_last = RT3883_GPIO_14,
+ }, {
+ .name = "gpio uartf",
+ .mask = RT3883_GPIO_MODE_GPIO_UARTF,
+ .gpio_first = RT3883_GPIO_7,
+ .gpio_last = RT3883_GPIO_14,
+ }, {
+ .name = "gpio i2s",
+ .mask = RT3883_GPIO_MODE_GPIO_I2S,
+ .gpio_first = RT3883_GPIO_7,
+ .gpio_last = RT3883_GPIO_14,
+ }, {0}
+};
+
+static void rt3883_wdt_reset(void)
+{
+ u32 t;
+
+ /* enable WDT reset output on GPIO 2 */
+ t = rt_sysc_r32(RT3883_SYSC_REG_SYSCFG1);
+ t |= RT3883_SYSCFG1_GPIO2_AS_WDT_OUT;
+ rt_sysc_w32(t, RT3883_SYSC_REG_SYSCFG1);
+}
+
+struct ralink_pinmux rt_pinmux = {
+ .mode = mode_mux,
+ .uart = uart_mux,
+ .uart_shift = RT3883_GPIO_MODE_UART0_SHIFT,
+ .uart_mask = RT3883_GPIO_MODE_GPIO,
+ .wdt_reset = rt3883_wdt_reset,
+};
+
+void __init ralink_clk_init(void)
+{
+ unsigned long cpu_rate, sys_rate;
+ u32 syscfg0;
+ u32 clksel;
+ u32 ddr2;
+
+ syscfg0 = rt_sysc_r32(RT3883_SYSC_REG_SYSCFG0);
+ clksel = ((syscfg0 >> RT3883_SYSCFG0_CPUCLK_SHIFT) &
+ RT3883_SYSCFG0_CPUCLK_MASK);
+ ddr2 = syscfg0 & RT3883_SYSCFG0_DRAM_TYPE_DDR2;
+
+ switch (clksel) {
+ case RT3883_SYSCFG0_CPUCLK_250:
+ cpu_rate = 250000000;
+ sys_rate = (ddr2) ? 125000000 : 83000000;
+ break;
+ case RT3883_SYSCFG0_CPUCLK_384:
+ cpu_rate = 384000000;
+ sys_rate = (ddr2) ? 128000000 : 96000000;
+ break;
+ case RT3883_SYSCFG0_CPUCLK_480:
+ cpu_rate = 480000000;
+ sys_rate = (ddr2) ? 160000000 : 120000000;
+ break;
+ case RT3883_SYSCFG0_CPUCLK_500:
+ cpu_rate = 500000000;
+ sys_rate = (ddr2) ? 166000000 : 125000000;
+ break;
+ }
+
+ ralink_clk_add("cpu", cpu_rate);
+ ralink_clk_add("10000100.timer", sys_rate);
+ ralink_clk_add("10000120.watchdog", sys_rate);
+ ralink_clk_add("10000500.uart", 40000000);
+ ralink_clk_add("10000b00.spi", sys_rate);
+ ralink_clk_add("10000c00.uartlite", 40000000);
+ ralink_clk_add("10100000.ethernet", sys_rate);
+}
+
+void __init ralink_of_remap(void)
+{
+ rt_sysc_membase = plat_of_remap_node("ralink,rt3883-sysc");
+ rt_memc_membase = plat_of_remap_node("ralink,rt3883-memc");
+
+ if (!rt_sysc_membase || !rt_memc_membase)
+ panic("Failed to remap core resources");
+}
+
+void prom_soc_init(struct ralink_soc_info *soc_info)
+{
+ void __iomem *sysc = (void __iomem *) KSEG1ADDR(RT3883_SYSC_BASE);
+ const char *name;
+ u32 n0;
+ u32 n1;
+ u32 id;
+
+ n0 = __raw_readl(sysc + RT3883_SYSC_REG_CHIPID0_3);
+ n1 = __raw_readl(sysc + RT3883_SYSC_REG_CHIPID4_7);
+ id = __raw_readl(sysc + RT3883_SYSC_REG_REVID);
+
+ if (n0 == RT3883_CHIP_NAME0 && n1 == RT3883_CHIP_NAME1) {
+ soc_info->compatible = "ralink,rt3883-soc";
+ name = "RT3883";
+ } else {
+ panic("rt3883: unknown SoC, n0:%08x n1:%08x", n0, n1);
+ }
+
+ snprintf(soc_info->sys_type, RAMIPS_SYS_TYPE_LEN,
+ "Ralink %s ver:%u eco:%u",
+ name,
+ (id >> RT3883_REVID_VER_ID_SHIFT) & RT3883_REVID_VER_ID_MASK,
+ (id & RT3883_REVID_ECO_ID_MASK));
+}
--
1.7.10.4

View file

@ -0,0 +1,295 @@
From 9d13fedc08f4e2cd9640983c2af8b9e9c64c094b Mon Sep 17 00:00:00 2001
From: John Crispin <blogic@openwrt.org>
Date: Thu, 21 Mar 2013 18:37:00 +0100
Subject: [PATCH 110/121] MIPS: add rt3883 dts files
Add a dtsi file for RT3883 SoC. This SoC is almost the same as RT3050 but has
OHCI/EHCI in favour of the Synopsis DWC2 core. There is also a 3x3 802.11n
wifi core.
Signed-off-by: John Crispin <blogic@openwrt.org>
---
arch/mips/ralink/Kconfig | 4 +
arch/mips/ralink/dts/Makefile | 1 +
arch/mips/ralink/dts/rt3883.dtsi | 186 ++++++++++++++++++++++++++++++++++
arch/mips/ralink/dts/rt3883_eval.dts | 52 ++++++++++
4 files changed, 243 insertions(+)
create mode 100644 arch/mips/ralink/dts/rt3883.dtsi
create mode 100644 arch/mips/ralink/dts/rt3883_eval.dts
diff --git a/arch/mips/ralink/Kconfig b/arch/mips/ralink/Kconfig
index f21cbaa..2ef69ee 100644
--- a/arch/mips/ralink/Kconfig
+++ b/arch/mips/ralink/Kconfig
@@ -39,6 +39,10 @@ choice
bool "RT305x eval kit"
depends on SOC_RT305X
+ config DTB_RT3883_EVAL
+ bool "RT3883 eval kit"
+ depends on SOC_RT3883
+
endchoice
endif
diff --git a/arch/mips/ralink/dts/Makefile b/arch/mips/ralink/dts/Makefile
index f635a01..040a986 100644
--- a/arch/mips/ralink/dts/Makefile
+++ b/arch/mips/ralink/dts/Makefile
@@ -1,2 +1,3 @@
obj-$(CONFIG_DTB_RT2880_EVAL) := rt2880_eval.dtb.o
obj-$(CONFIG_DTB_RT305X_EVAL) := rt3052_eval.dtb.o
+obj-$(CONFIG_DTB_RT3883_EVAL) := rt3883_eval.dtb.o
diff --git a/arch/mips/ralink/dts/rt3883.dtsi b/arch/mips/ralink/dts/rt3883.dtsi
new file mode 100644
index 0000000..1e80ad3
--- /dev/null
+++ b/arch/mips/ralink/dts/rt3883.dtsi
@@ -0,0 +1,186 @@
+/ {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "ralink,rt3883-soc";
+
+ cpus {
+ cpu@0 {
+ compatible = "mips,mips74Kc";
+ };
+ };
+
+ chosen {
+ bootargs = "console=ttyS0,57600 init=/init";
+ };
+
+ cpuintc: cpuintc@0 {
+ #address-cells = <0>;
+ #interrupt-cells = <1>;
+ interrupt-controller;
+ compatible = "mti,cpu-interrupt-controller";
+ };
+
+ palmbus@10000000 {
+ compatible = "palmbus";
+ reg = <0x10000000 0x200000>;
+ ranges = <0x0 0x10000000 0x1FFFFF>;
+
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ sysc@0 {
+ compatible = "ralink,rt3883-sysc", "ralink,rt3050-sysc";
+ reg = <0x0 0x100>;
+ };
+
+ timer@100 {
+ compatible = "ralink,rt3883-timer", "ralink,rt2880-timer";
+ reg = <0x100 0x20>;
+
+ interrupt-parent = <&intc>;
+ interrupts = <1>;
+
+ status = "disabled";
+ };
+
+ watchdog@120 {
+ compatible = "ralink,rt3883-wdt", "ralink,rt2880-wdt";
+ reg = <0x120 0x10>;
+ };
+
+ intc: intc@200 {
+ compatible = "ralink,rt3883-intc", "ralink,rt2880-intc";
+ reg = <0x200 0x100>;
+
+ interrupt-controller;
+ #interrupt-cells = <1>;
+
+ interrupt-parent = <&cpuintc>;
+ interrupts = <2>;
+ };
+
+ memc@300 {
+ compatible = "ralink,rt3883-memc", "ralink,rt3050-memc";
+ reg = <0x300 0x100>;
+ };
+
+ gpio0: gpio@600 {
+ compatible = "ralink,rt3883-gpio", "ralink,rt2880-gpio";
+ reg = <0x600 0x34>;
+
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ ralink,num-gpios = <24>;
+ ralink,register-map = [ 00 04 08 0c
+ 20 24 28 2c
+ 30 34 ];
+
+ status = "disabled";
+ };
+
+ gpio1: gpio@638 {
+ compatible = "ralink,rt3883-gpio", "ralink,rt2880-gpio";
+ reg = <0x638 0x24>;
+
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ ralink,num-gpios = <16>;
+ ralink,register-map = [ 00 04 08 0c
+ 10 14 18 1c
+ 20 24 ];
+
+ status = "disabled";
+ };
+
+ gpio2: gpio@660 {
+ compatible = "ralink,rt3883-gpio", "ralink,rt2880-gpio";
+ reg = <0x660 0x24>;
+
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ ralink,num-gpios = <32>;
+ ralink,register-map = [ 00 04 08 0c
+ 10 14 18 1c
+ 20 24 ];
+
+ status = "disabled";
+ };
+
+ gpio3: gpio@688 {
+ compatible = "ralink,rt3883-gpio", "ralink,rt2880-gpio";
+ reg = <0x688 0x24>;
+
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ ralink,num-gpios = <24>;
+ ralink,register-map = [ 00 04 08 0c
+ 10 14 18 1c
+ 20 24 ];
+
+ status = "disabled";
+ };
+
+ spi@b00 {
+ compatible = "ralink,rt3883-spi", "ralink,rt2880-spi";
+ reg = <0xb00 0x100>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ status = "disabled";
+ };
+
+ uartlite@c00 {
+ compatible = "ralink,rt3883-uart", "ralink,rt2880-uart", "ns16550a";
+ reg = <0xc00 0x100>;
+
+ interrupt-parent = <&intc>;
+ interrupts = <12>;
+
+ reg-shift = <2>;
+ };
+ };
+
+ ethernet@10100000 {
+ compatible = "ralink,rt3883-eth";
+ reg = <0x10100000 10000>;
+
+ interrupt-parent = <&cpuintc>;
+ interrupts = <5>;
+
+ status = "disabled";
+ };
+
+ wmac@10180000 {
+ compatible = "ralink,rt3883-wmac", "ralink,rt2880-wmac";
+ reg = <0x10180000 40000>;
+
+ interrupt-parent = <&cpuintc>;
+ interrupts = <6>;
+
+ status = "disabled";
+ };
+
+ ehci@101c0000 {
+ compatible = "ralink,rt3883-ehci", "ehci-platform";
+ reg = <0x101c0000 0x1000>;
+
+ interrupt-parent = <&intc>;
+ interrupts = <18>;
+
+ status = "disabled";
+ };
+
+ ohci@101c1000 {
+ compatible = "ralink,rt3883-ohci", "ohci-platform";
+ reg = <0x101c1000 0x1000>;
+
+ interrupt-parent = <&intc>;
+ interrupts = <18>;
+
+ status = "disabled";
+ };
+};
diff --git a/arch/mips/ralink/dts/rt3883_eval.dts b/arch/mips/ralink/dts/rt3883_eval.dts
new file mode 100644
index 0000000..d4c06ed
--- /dev/null
+++ b/arch/mips/ralink/dts/rt3883_eval.dts
@@ -0,0 +1,52 @@
+/dts-v1/;
+
+/include/ "rt3883.dtsi"
+
+/ {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "ralink,rt3883-eval-board", "ralink,rt3883-soc";
+ model = "Ralink RT3883 evaluation board";
+
+ memory@0 {
+ reg = <0x0 0x4000000>;
+ };
+
+ palmbus@10000000 {
+ sysc@0 {
+ ralink,pinmmux = "uartlite", "spi";
+ ralink,uartmux = "gpio";
+ ralink,wdtmux = <0>;
+ };
+ };
+
+ cfi@1f000000 {
+ compatible = "cfi-flash";
+ reg = <0x1f000000 0x800000>;
+
+ bank-width = <2>;
+ device-width = <2>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ partition@0 {
+ label = "uboot";
+ reg = <0x0 0x30000>;
+ read-only;
+ };
+ partition@30000 {
+ label = "uboot-env";
+ reg = <0x30000 0x10000>;
+ read-only;
+ };
+ partition@40000 {
+ label = "calibration";
+ reg = <0x40000 0x10000>;
+ read-only;
+ };
+ partition@50000 {
+ label = "linux";
+ reg = <0x50000 0x7b0000>;
+ };
+ };
+};
--
1.7.10.4

View file

@ -0,0 +1,355 @@
From 8831277e0167cdcf3dc3ecc5d5a67d4fd9d0ed77 Mon Sep 17 00:00:00 2001
From: John Crispin <blogic@openwrt.org>
Date: Thu, 21 Mar 2013 17:49:02 +0100
Subject: [PATCH 111/121] MIPS: ralink: adds support for MT7620 SoC family
Add support code for mt7620 SOC.
The code detects the SoC and registers the clk / pinmux settings.
Signed-off-by: John Crispin <blogic@openwrt.org>
---
arch/mips/include/asm/mach-ralink/mt7620.h | 66 +++++++++
arch/mips/ralink/Kconfig | 3 +
arch/mips/ralink/Makefile | 1 +
arch/mips/ralink/Platform | 5 +
arch/mips/ralink/mt7620.c | 215 ++++++++++++++++++++++++++++
5 files changed, 290 insertions(+)
create mode 100644 arch/mips/include/asm/mach-ralink/mt7620.h
create mode 100644 arch/mips/ralink/mt7620.c
diff --git a/arch/mips/include/asm/mach-ralink/mt7620.h b/arch/mips/include/asm/mach-ralink/mt7620.h
new file mode 100644
index 0000000..3d51235
--- /dev/null
+++ b/arch/mips/include/asm/mach-ralink/mt7620.h
@@ -0,0 +1,66 @@
+/*
+ * 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.
+ *
+ * Parts of this file are based on Ralink's 2.6.21 BSP
+ *
+ * Copyright (C) 2008-2011 Gabor Juhos <juhosg@openwrt.org>
+ * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
+ * Copyright (C) 2013 John Crispin <blogic@openwrt.org>
+ */
+
+#ifndef _MT7620_REGS_H_
+#define _MT7620_REGS_H_
+
+#define MT7620_SYSC_BASE 0x10000000
+
+#define SYSC_REG_CHIP_NAME0 0x00
+#define SYSC_REG_CHIP_NAME1 0x04
+#define SYSC_REG_CHIP_REV 0x0c
+#define SYSC_REG_SYSTEM_CONFIG0 0x10
+#define SYSC_REG_SYSTEM_CONFIG1 0x14
+#define SYSC_REG_CPLL_CONFIG0 0x54
+#define SYSC_REG_CPLL_CONFIG1 0x58
+
+#define MT7620N_CHIP_NAME0 0x33365452
+#define MT7620N_CHIP_NAME1 0x20203235
+
+#define MT7620A_CHIP_NAME0 0x3637544d
+#define MT7620A_CHIP_NAME1 0x20203032
+
+#define CHIP_REV_PKG_MASK 0x1
+#define CHIP_REV_PKG_SHIFT 16
+#define CHIP_REV_VER_MASK 0xf
+#define CHIP_REV_VER_SHIFT 8
+#define CHIP_REV_ECO_MASK 0xf
+
+#define MT7620_CPLL_SW_CONFIG_SHIFT 31
+#define MT7620_CPLL_SW_CONFIG_MASK 0x1
+#define MT7620_CPLL_CPU_CLK_SHIFT 24
+#define MT7620_CPLL_CPU_CLK_MASK 0x1
+
+#define MT7620_GPIO_MODE_I2C BIT(0)
+#define MT7620_GPIO_MODE_UART0_SHIFT 2
+#define MT7620_GPIO_MODE_UART0_MASK 0x7
+#define MT7620_GPIO_MODE_UART0(x) ((x) << MT7620_GPIO_MODE_UART0_SHIFT)
+#define MT7620_GPIO_MODE_UARTF 0x0
+#define MT7620_GPIO_MODE_PCM_UARTF 0x1
+#define MT7620_GPIO_MODE_PCM_I2S 0x2
+#define MT7620_GPIO_MODE_I2S_UARTF 0x3
+#define MT7620_GPIO_MODE_PCM_GPIO 0x4
+#define MT7620_GPIO_MODE_GPIO_UARTF 0x5
+#define MT7620_GPIO_MODE_GPIO_I2S 0x6
+#define MT7620_GPIO_MODE_GPIO 0x7
+#define MT7620_GPIO_MODE_UART1 BIT(5)
+#define MT7620_GPIO_MODE_MDIO BIT(8)
+#define MT7620_GPIO_MODE_RGMII1 BIT(9)
+#define MT7620_GPIO_MODE_RGMII2 BIT(10)
+#define MT7620_GPIO_MODE_SPI BIT(11)
+#define MT7620_GPIO_MODE_SPI_REF_CLK BIT(12)
+#define MT7620_GPIO_MODE_WLED BIT(13)
+#define MT7620_GPIO_MODE_JTAG BIT(15)
+#define MT7620_GPIO_MODE_EPHY BIT(15)
+#define MT7620_GPIO_MODE_WDT BIT(22)
+
+#endif
diff --git a/arch/mips/ralink/Kconfig b/arch/mips/ralink/Kconfig
index 2ef69ee..493411f 100644
--- a/arch/mips/ralink/Kconfig
+++ b/arch/mips/ralink/Kconfig
@@ -20,6 +20,9 @@ choice
select USB_ARCH_HAS_OHCI
select USB_ARCH_HAS_EHCI
+ config SOC_MT7620
+ bool "MT7620"
+
endchoice
choice
diff --git a/arch/mips/ralink/Makefile b/arch/mips/ralink/Makefile
index 87f6ca9..341b4de 100644
--- a/arch/mips/ralink/Makefile
+++ b/arch/mips/ralink/Makefile
@@ -11,6 +11,7 @@ obj-y := prom.o of.o reset.o clk.o irq.o pinmux.o
obj-$(CONFIG_SOC_RT288X) += rt288x.o
obj-$(CONFIG_SOC_RT305X) += rt305x.o
obj-$(CONFIG_SOC_RT3883) += rt3883.o
+obj-$(CONFIG_SOC_MT7620) += mt7620.o
obj-$(CONFIG_EARLY_PRINTK) += early_printk.o
diff --git a/arch/mips/ralink/Platform b/arch/mips/ralink/Platform
index f67c08d..b2cbf16 100644
--- a/arch/mips/ralink/Platform
+++ b/arch/mips/ralink/Platform
@@ -18,3 +18,8 @@ load-$(CONFIG_SOC_RT305X) += 0xffffffff80000000
# Ralink RT3883
#
load-$(CONFIG_SOC_RT3883) += 0xffffffff80000000
+
+#
+# Ralink MT7620
+#
+load-$(CONFIG_SOC_MT7620) += 0xffffffff80000000
diff --git a/arch/mips/ralink/mt7620.c b/arch/mips/ralink/mt7620.c
new file mode 100644
index 0000000..9d0dc8b
--- /dev/null
+++ b/arch/mips/ralink/mt7620.c
@@ -0,0 +1,215 @@
+/*
+ * 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.
+ *
+ * Parts of this file are based on Ralink's 2.6.21 BSP
+ *
+ * Copyright (C) 2008-2011 Gabor Juhos <juhosg@openwrt.org>
+ * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
+ * Copyright (C) 2013 John Crispin <blogic@openwrt.org>
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/module.h>
+
+#include <asm/mipsregs.h>
+#include <asm/mach-ralink/ralink_regs.h>
+#include <asm/mach-ralink/mt7620.h>
+
+#include "common.h"
+
+
+struct ralink_pinmux_grp mode_mux[] = {
+ {
+ .name = "i2c",
+ .mask = MT7620_GPIO_MODE_I2C,
+ .gpio_first = 1,
+ .gpio_last = 2,
+ }, {
+ .name = "spi",
+ .mask = MT7620_GPIO_MODE_SPI,
+ .gpio_first = 3,
+ .gpio_last = 6,
+ }, {
+ .name = "uartlite",
+ .mask = MT7620_GPIO_MODE_UART1,
+ .gpio_first = 15,
+ .gpio_last = 16,
+ }, {
+ .name = "wdt",
+ .mask = MT7620_GPIO_MODE_WDT,
+ .gpio_first = 17,
+ .gpio_last = 17,
+ }, {
+ .name = "mdio",
+ .mask = MT7620_GPIO_MODE_MDIO,
+ .gpio_first = 22,
+ .gpio_last = 23,
+ }, {
+ .name = "rgmii1",
+ .mask = MT7620_GPIO_MODE_RGMII1,
+ .gpio_first = 24,
+ .gpio_last = 35,
+ }, {
+ .name = "spi refclk",
+ .mask = MT7620_GPIO_MODE_SPI_REF_CLK,
+ .gpio_first = 37,
+ .gpio_last = 39,
+ }, {
+ .name = "jtag",
+ .mask = MT7620_GPIO_MODE_JTAG,
+ .gpio_first = 40,
+ .gpio_last = 44,
+ }, {
+ /* shared lines with jtag */
+ .name = "ephy",
+ .mask = MT7620_GPIO_MODE_EPHY,
+ .gpio_first = 40,
+ .gpio_last = 44,
+ }, {
+ .name = "nand",
+ .mask = MT7620_GPIO_MODE_JTAG,
+ .gpio_first = 45,
+ .gpio_last = 59,
+ }, {
+ .name = "rgmii2",
+ .mask = MT7620_GPIO_MODE_RGMII2,
+ .gpio_first = 60,
+ .gpio_last = 71,
+ }, {
+ .name = "wled",
+ .mask = MT7620_GPIO_MODE_WLED,
+ .gpio_first = 72,
+ .gpio_last = 72,
+ }, {0}
+};
+
+
+struct ralink_pinmux_grp uart_mux[] = {
+ {
+ .name = "uartf",
+ .mask = MT7620_GPIO_MODE_UARTF,
+ .gpio_first = 7,
+ .gpio_last = 14,
+ }, {
+ .name = "pcm uartf",
+ .mask = MT7620_GPIO_MODE_PCM_UARTF,
+ .gpio_first = 7,
+ .gpio_last = 14,
+ }, {
+ .name = "pcm i2s",
+ .mask = MT7620_GPIO_MODE_PCM_I2S,
+ .gpio_first = 7,
+ .gpio_last = 14,
+ }, {
+ .name = "i2s uartf",
+ .mask = MT7620_GPIO_MODE_I2S_UARTF,
+ .gpio_first = 7,
+ .gpio_last = 14,
+ }, {
+ .name = "pcm gpio",
+ .mask = MT7620_GPIO_MODE_PCM_GPIO,
+ .gpio_first = 11,
+ .gpio_last = 14,
+ }, {
+ .name = "gpio uartf",
+ .mask = MT7620_GPIO_MODE_GPIO_UARTF,
+ .gpio_first = 7,
+ .gpio_last = 10,
+ }, {
+ .name = "gpio i2s",
+ .mask = MT7620_GPIO_MODE_GPIO_I2S,
+ .gpio_first = 7,
+ .gpio_last = 10,
+ }, {
+ .name = "gpio",
+ .mask = MT7620_GPIO_MODE_GPIO,
+ }, {0}
+};
+/*
+void rt305x_wdt_reset(void)
+{
+ u32 t;
+
+ t = rt_sysc_r32(SYSC_REG_SYSTEM_CONFIG);
+ t |= RT305X_SYSCFG_SRAM_CS0_MODE_WDT <<
+ RT305X_SYSCFG_SRAM_CS0_MODE_SHIFT;
+ rt_sysc_w32(t, SYSC_REG_SYSTEM_CONFIG);
+}
+*/
+struct ralink_pinmux rt_pinmux = {
+ .mode = mode_mux,
+ .uart = uart_mux,
+ .uart_shift = MT7620_GPIO_MODE_UART0_SHIFT,
+// .wdt_reset = rt305x_wdt_reset,
+};
+
+void __init ralink_clk_init(void)
+{
+ unsigned long cpu_rate, sys_rate;
+ u32 c0 = rt_sysc_r32(SYSC_REG_CPLL_CONFIG0);
+ u32 c1 = rt_sysc_r32(SYSC_REG_CPLL_CONFIG1);
+
+ c0 = (c0 >> MT7620_CPLL_SW_CONFIG_SHIFT) &
+ MT7620_CPLL_SW_CONFIG_MASK;
+ c1 = (c1 >> MT7620_CPLL_CPU_CLK_SHIFT) &
+ MT7620_CPLL_CPU_CLK_MASK;
+ if (c1 == 0x01) {
+ cpu_rate = 480000000;
+ } else {
+ if (c1 == 0x0) {
+ cpu_rate = 600000000;
+ } else {
+ /* TODO calculate custom clock from pll settings */
+ BUG();
+ }
+ }
+ /* FIXME SDR - 4, DDR - 3 */
+ sys_rate = cpu_rate / 4;
+
+ ralink_clk_add("cpu", cpu_rate);
+ ralink_clk_add("10000100.timer", 40000000);
+ ralink_clk_add("10000500.uart", 40000000);
+ ralink_clk_add("10000c00.uartlite", 40000000);
+}
+
+void __init ralink_of_remap(void)
+{
+ rt_sysc_membase = plat_of_remap_node("ralink,mt7620-sysc");
+ rt_memc_membase = plat_of_remap_node("ralink,mt7620-memc");
+
+ if (!rt_sysc_membase || !rt_memc_membase)
+ panic("Failed to remap core resources");
+}
+
+void prom_soc_init(struct ralink_soc_info *soc_info)
+{
+ void __iomem *sysc = (void __iomem *) KSEG1ADDR(MT7620_SYSC_BASE);
+ unsigned char *name = NULL;
+ u32 n0;
+ u32 n1;
+ u32 rev;
+
+ n0 = __raw_readl(sysc + SYSC_REG_CHIP_NAME0);
+ n1 = __raw_readl(sysc + SYSC_REG_CHIP_NAME1);
+
+ if (n0 == MT7620N_CHIP_NAME0 && n1 == MT7620N_CHIP_NAME1) {
+ name = "MT7620N";
+ soc_info->compatible = "ralink,mt7620n-soc";
+ } else if (n0 == MT7620A_CHIP_NAME0 && n1 == MT7620A_CHIP_NAME1) {
+ name = "MT7620A";
+ soc_info->compatible = "ralink,mt7620a-soc";
+ } else {
+ printk("mt7620: unknown SoC, n0:%08x n1:%08x\n", n0, n1);
+ }
+
+ rev = __raw_readl(sysc + SYSC_REG_CHIP_REV);
+
+ snprintf(soc_info->sys_type, RAMIPS_SYS_TYPE_LEN,
+ "Ralink %s ver:%u eco:%u",
+ name,
+ (rev >> CHIP_REV_VER_SHIFT) & CHIP_REV_VER_MASK,
+ (rev & CHIP_REV_ECO_MASK));
+}
--
1.7.10.4

View file

@ -0,0 +1,217 @@
From 9c83b58b49f88a48565fad6acea921a0ae222856 Mon Sep 17 00:00:00 2001
From: John Crispin <blogic@openwrt.org>
Date: Thu, 21 Mar 2013 17:50:05 +0100
Subject: [PATCH 112/121] MIPS: add MT7620 dts files
Adds the dtsi file for MT7620 SoC. This is the latest and greatest SoC shipped
by Mediatek.
Signed-off-by: John Crispin <blogic@openwrt.org>
---
arch/mips/ralink/Kconfig | 4 +
arch/mips/ralink/dts/Makefile | 1 +
arch/mips/ralink/dts/mt7620.dtsi | 138 ++++++++++++++++++++++++++++++++++
arch/mips/ralink/dts/mt7620_eval.dts | 22 ++++++
4 files changed, 165 insertions(+)
create mode 100644 arch/mips/ralink/dts/mt7620.dtsi
create mode 100644 arch/mips/ralink/dts/mt7620_eval.dts
diff --git a/arch/mips/ralink/Kconfig b/arch/mips/ralink/Kconfig
index 493411f..8254502 100644
--- a/arch/mips/ralink/Kconfig
+++ b/arch/mips/ralink/Kconfig
@@ -46,6 +46,10 @@ choice
bool "RT3883 eval kit"
depends on SOC_RT3883
+ config DTB_MT7620_EVAL
+ bool "MT7620 eval kit"
+ depends on SOC_MT7620
+
endchoice
endif
diff --git a/arch/mips/ralink/dts/Makefile b/arch/mips/ralink/dts/Makefile
index 040a986..036603a 100644
--- a/arch/mips/ralink/dts/Makefile
+++ b/arch/mips/ralink/dts/Makefile
@@ -1,3 +1,4 @@
obj-$(CONFIG_DTB_RT2880_EVAL) := rt2880_eval.dtb.o
obj-$(CONFIG_DTB_RT305X_EVAL) := rt3052_eval.dtb.o
obj-$(CONFIG_DTB_RT3883_EVAL) := rt3883_eval.dtb.o
+obj-$(CONFIG_DTB_MT7620_EVAL) := mt7620_eval.dtb.o
diff --git a/arch/mips/ralink/dts/mt7620.dtsi b/arch/mips/ralink/dts/mt7620.dtsi
new file mode 100644
index 0000000..59f057f
--- /dev/null
+++ b/arch/mips/ralink/dts/mt7620.dtsi
@@ -0,0 +1,138 @@
+/ {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "ralink,mtk7620n-soc", "ralink,mt7620-soc";
+
+ cpus {
+ cpu@0 {
+ compatible = "mips,mips24KEc";
+ };
+ };
+
+ chosen {
+ bootargs = "console=ttyS0,57600 init=/init";
+ };
+
+ cpuintc: cpuintc@0 {
+ #address-cells = <0>;
+ #interrupt-cells = <1>;
+ interrupt-controller;
+ compatible = "mti,cpu-interrupt-controller";
+ };
+
+ palmbus@10000000 {
+ compatible = "palmbus";
+ reg = <0x10000000 0x200000>;
+ ranges = <0x0 0x10000000 0x1FFFFF>;
+
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ sysc@0 {
+ compatible = "ralink,mt7620-sysc", "ralink,mt7620n-sysc";
+ reg = <0x0 0x100>;
+ };
+
+ timer@100 {
+ compatible = "ralink,mt7620-timer", "ralink,rt2880-timer";
+ reg = <0x100 0x20>;
+
+ interrupt-parent = <&intc>;
+ interrupts = <1>;
+
+ status = "disabled";
+ };
+
+ watchdog@120 {
+ compatible = "ralink,mt7620-wdt", "ralink,rt2880-wdt";
+ reg = <0x120 0x10>;
+ };
+
+ intc: intc@200 {
+ compatible = "ralink,mt7620-intc", "ralink,rt2880-intc";
+ reg = <0x200 0x100>;
+
+ interrupt-controller;
+ #interrupt-cells = <1>;
+
+ interrupt-parent = <&cpuintc>;
+ interrupts = <2>;
+ };
+
+ memc@300 {
+ compatible = "ralink,mt7620-memc", "ralink,rt3050-memc";
+ reg = <0x300 0x100>;
+ };
+
+ gpio0: gpio@600 {
+ compatible = "ralink,mt7620-gpio", "ralink,rt2880-gpio";
+ reg = <0x600 0x34>;
+
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ ralink,num-gpios = <24>;
+ ralink,register-map = [ 00 04 08 0c
+ 20 24 28 2c
+ 30 34 ];
+ };
+
+ gpio1: gpio@638 {
+ compatible = "ralink,mt7620-gpio", "ralink,rt2880-gpio";
+ reg = <0x638 0x24>;
+
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ ralink,num-gpios = <16>;
+ ralink,register-map = [ 00 04 08 0c
+ 10 14 18 1c
+ 20 24 ];
+ };
+
+ gpio2: gpio@660 {
+ compatible = "ralink,mt7620-gpio", "ralink,rt2880-gpio";
+ reg = <0x660 0x24>;
+
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ ralink,num-gpios = <32>;
+ ralink,register-map = [ 00 04 08 0c
+ 10 14 18 1c
+ 20 24 ];
+ };
+
+ gpio3: gpio@688 {
+ compatible = "ralink,mt7620-gpio", "ralink,rt2880-gpio";
+ reg = <0x688 0x24>;
+
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ ralink,num-gpios = <1>;
+ ralink,register-map = [ 00 04 08 0c
+ 10 14 18 1c
+ 20 24 ];
+ };
+
+ spi@b00 {
+ compatible = "ralink,rt3883-spi", "ralink,rt2880-spi";
+ reg = <0xb00 0x100>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ status = "disabled";
+ };
+
+ uartlite@c00 {
+ compatible = "ralink,mt7620-uart", "ralink,rt2880-uart", "ns16550a";
+ reg = <0xc00 0x100>;
+
+ interrupt-parent = <&intc>;
+ interrupts = <12>;
+
+ reg-shift = <2>;
+ };
+ };
+};
diff --git a/arch/mips/ralink/dts/mt7620_eval.dts b/arch/mips/ralink/dts/mt7620_eval.dts
new file mode 100644
index 0000000..dda0f4d
--- /dev/null
+++ b/arch/mips/ralink/dts/mt7620_eval.dts
@@ -0,0 +1,22 @@
+/dts-v1/;
+
+/include/ "mt7620.dtsi"
+
+/ {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "ralink,mt7620a-eval-board", "ralink,mt7620a-soc";
+ model = "Ralink MT7620 evaluation board";
+
+ memory@0 {
+ reg = <0x0 0x4000000>;
+ };
+
+ palmbus@10000000 {
+ sysc@0 {
+ ralink,pinmmux = "uartlite", "spi";
+ ralink,uartmux = "gpio";
+ ralink,wdtmux = <0>;
+ };
+ };
+};
--
1.7.10.4

View file

@ -0,0 +1,228 @@
From cdbc5a9dbd78a771edb6c211edbc677596cbd17f Mon Sep 17 00:00:00 2001
From: John Crispin <blogic@openwrt.org>
Date: Sat, 23 Mar 2013 19:44:41 +0100
Subject: [PATCH 113/121] MIPS: ralink: add support for periodic timer irq
Adds a driver for the periodic timer found on Ralink SoC.
Signed-off-by: John Crispin <blogic@openwrt.org>
---
arch/mips/ralink/Makefile | 2 +-
arch/mips/ralink/timer.c | 192 +++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 193 insertions(+), 1 deletion(-)
create mode 100644 arch/mips/ralink/timer.c
diff --git a/arch/mips/ralink/Makefile b/arch/mips/ralink/Makefile
index 341b4de..cae7d88 100644
--- a/arch/mips/ralink/Makefile
+++ b/arch/mips/ralink/Makefile
@@ -6,7 +6,7 @@
# Copyright (C) 2009-2011 Gabor Juhos <juhosg@openwrt.org>
# Copyright (C) 2013 John Crispin <blogic@openwrt.org>
-obj-y := prom.o of.o reset.o clk.o irq.o pinmux.o
+obj-y := prom.o of.o reset.o clk.o irq.o pinmux.o timer.o
obj-$(CONFIG_SOC_RT288X) += rt288x.o
obj-$(CONFIG_SOC_RT305X) += rt305x.o
diff --git a/arch/mips/ralink/timer.c b/arch/mips/ralink/timer.c
new file mode 100644
index 0000000..9a943e8
--- /dev/null
+++ b/arch/mips/ralink/timer.c
@@ -0,0 +1,192 @@
+/*
+ * 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) 2013 John Crispin <blogic@openwrt.org>
+*/
+
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/interrupt.h>
+#include <linux/timer.h>
+#include <linux/of_gpio.h>
+#include <linux/clk.h>
+
+#include <asm/mach-ralink/ralink_regs.h>
+
+#define TIMER_REG_TMRSTAT 0x00
+#define TIMER_REG_TMR0LOAD 0x10
+#define TIMER_REG_TMR0CTL 0x18
+
+#define TMRSTAT_TMR0INT BIT(0)
+
+#define TMR0CTL_ENABLE BIT(7)
+#define TMR0CTL_MODE_PERIODIC BIT(4)
+#define TMR0CTL_PRESCALER 1
+#define TMR0CTL_PRESCALE_VAL (0xf - TMR0CTL_PRESCALER)
+#define TMR0CTL_PRESCALE_DIV (65536 / BIT(TMR0CTL_PRESCALER))
+
+struct rt_timer {
+ struct device *dev;
+ void __iomem *membase;
+ int irq;
+ unsigned long timer_freq;
+ unsigned long timer_div;
+};
+
+static inline void rt_timer_w32(struct rt_timer *rt, u8 reg, u32 val)
+{
+ __raw_writel(val, rt->membase + reg);
+}
+
+static inline u32 rt_timer_r32(struct rt_timer *rt, u8 reg)
+{
+ return __raw_readl(rt->membase + reg);
+}
+
+static irqreturn_t rt_timer_irq(int irq, void *_rt)
+{
+ struct rt_timer *rt = (struct rt_timer *) _rt;
+
+ rt_timer_w32(rt, TIMER_REG_TMR0LOAD, rt->timer_freq / rt->timer_div);
+ rt_timer_w32(rt, TIMER_REG_TMRSTAT, TMRSTAT_TMR0INT);
+
+ return IRQ_HANDLED;
+}
+
+
+static int rt_timer_request(struct rt_timer *rt)
+{
+ int err = request_irq(rt->irq, rt_timer_irq, IRQF_DISABLED,
+ dev_name(rt->dev), rt);
+ if (err) {
+ dev_err(rt->dev, "failed to request irq\n");
+ } else {
+ u32 t = TMR0CTL_MODE_PERIODIC | TMR0CTL_PRESCALE_VAL;
+ rt_timer_w32(rt, TIMER_REG_TMR0CTL, t);
+ }
+ return err;
+}
+
+static void rt_timer_free(struct rt_timer *rt)
+{
+ free_irq(rt->irq, rt);
+}
+
+static int rt_timer_config(struct rt_timer *rt, unsigned long divisor)
+{
+ if (rt->timer_freq < divisor)
+ rt->timer_div = rt->timer_freq;
+ else
+ rt->timer_div = divisor;
+
+ rt_timer_w32(rt, TIMER_REG_TMR0LOAD, rt->timer_freq / rt->timer_div);
+
+ return 0;
+}
+
+static int rt_timer_enable(struct rt_timer *rt)
+{
+ u32 t;
+
+ rt_timer_w32(rt, TIMER_REG_TMR0LOAD, rt->timer_freq / rt->timer_div);
+
+ t = rt_timer_r32(rt, TIMER_REG_TMR0CTL);
+ t |= TMR0CTL_ENABLE;
+ rt_timer_w32(rt, TIMER_REG_TMR0CTL, t);
+
+ return 0;
+}
+
+static void rt_timer_disable(struct rt_timer *rt)
+{
+ u32 t;
+
+ t = rt_timer_r32(rt, TIMER_REG_TMR0CTL);
+ t &= ~TMR0CTL_ENABLE;
+ rt_timer_w32(rt, TIMER_REG_TMR0CTL, t);
+}
+
+static int rt_timer_probe(struct platform_device *pdev)
+{
+ struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ struct rt_timer *rt;
+ struct clk *clk;
+
+ if (!res) {
+ dev_err(&pdev->dev, "no memory resource found\n");
+ return -EINVAL;
+ }
+
+ rt = devm_kzalloc(&pdev->dev, sizeof(*rt), GFP_KERNEL);
+ if (!rt) {
+ dev_err(&pdev->dev, "failed to allocate memory\n");
+ return -ENOMEM;
+ }
+
+ rt->irq = platform_get_irq(pdev, 0);
+ if (!rt->irq) {
+ dev_err(&pdev->dev, "failed to load irq\n");
+ return -ENOENT;
+ }
+
+ rt->membase = devm_request_and_ioremap(&pdev->dev, res);
+ if (!rt->membase) {
+ dev_err(&pdev->dev, "failed to ioremap\n");
+ return -ENOMEM;
+ }
+
+ clk = devm_clk_get(&pdev->dev, NULL);
+ if (IS_ERR(clk)) {
+ dev_err(&pdev->dev, "failed get clock rate\n");
+ return PTR_ERR(clk);
+ }
+
+ rt->timer_freq = clk_get_rate(clk) / TMR0CTL_PRESCALE_DIV;
+ if (!rt->timer_freq)
+ return -EINVAL;
+
+ rt->dev = &pdev->dev;
+ platform_set_drvdata(pdev, rt);
+
+ rt_timer_request(rt);
+ rt_timer_config(rt, 2);
+ rt_timer_enable(rt);
+
+ dev_info(&pdev->dev, "maximum frequncy is %luHz\n", rt->timer_freq);
+
+ return 0;
+}
+
+static int rt_timer_remove(struct platform_device *pdev)
+{
+ struct rt_timer *rt = platform_get_drvdata(pdev);
+
+ rt_timer_disable(rt);
+ rt_timer_free(rt);
+
+ return 0;
+}
+
+static const struct of_device_id rt_timer_match[] = {
+ { .compatible = "ralink,rt2880-timer" },
+ {},
+};
+MODULE_DEVICE_TABLE(of, rt_timer_match);
+
+static struct platform_driver rt_timer_driver = {
+ .probe = rt_timer_probe,
+ .remove = rt_timer_remove,
+ .driver = {
+ .name = "rt-timer",
+ .owner = THIS_MODULE,
+ .of_match_table = rt_timer_match
+ },
+};
+
+module_platform_driver(rt_timer_driver);
+
+MODULE_DESCRIPTION("Ralink RT2880 timer");
+MODULE_AUTHOR("John Crispin <blogic@openwrt.org");
+MODULE_LICENSE("GPL");
--
1.7.10.4

View file

@ -0,0 +1,275 @@
From f22c157f44c93d61058d2e2aa5626ee2899fde5a Mon Sep 17 00:00:00 2001
From: John Crispin <blogic@openwrt.org>
Date: Tue, 22 Jan 2013 18:24:34 +0100
Subject: [PATCH 114/121] GPIO: MIPS: ralink: adds ralink gpio support
Add gpio driver for Ralink SoC. This driver makes the gpio core on
RT2880, RT305x, rt3352, rt3662, rt3883, rt5350 and mt7620 work.
Signed-off-by: John Crispin <blogic@openwrt.org>
---
arch/mips/Kconfig | 1 +
arch/mips/include/asm/mach-ralink/gpio.h | 24 ++++
drivers/gpio/Kconfig | 6 +
drivers/gpio/Makefile | 1 +
drivers/gpio/gpio-ralink.c | 176 ++++++++++++++++++++++++++++++
5 files changed, 208 insertions(+)
create mode 100644 arch/mips/include/asm/mach-ralink/gpio.h
create mode 100644 drivers/gpio/gpio-ralink.c
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index 490d769..1db6ce9 100644
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -443,6 +443,7 @@ config RALINK
select SYS_HAS_EARLY_PRINTK
select HAVE_MACH_CLKDEV
select CLKDEV_LOOKUP
+ select ARCH_REQUIRE_GPIOLIB
config SGI_IP22
bool "SGI IP22 (Indy/Indigo2)"
diff --git a/arch/mips/include/asm/mach-ralink/gpio.h b/arch/mips/include/asm/mach-ralink/gpio.h
new file mode 100644
index 0000000..f68ee16
--- /dev/null
+++ b/arch/mips/include/asm/mach-ralink/gpio.h
@@ -0,0 +1,24 @@
+/*
+ * Ralink SoC GPIO API support
+ *
+ * Copyright (C) 2008-2009 Gabor Juhos <juhosg@openwrt.org>
+ * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
+ *
+ * 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.
+ *
+ */
+
+#ifndef __ASM_MACH_RALINK_GPIO_H
+#define __ASM_MACH_RALINK_GPIO_H
+
+#define ARCH_NR_GPIOS 128
+#include <asm-generic/gpio.h>
+
+#define gpio_get_value __gpio_get_value
+#define gpio_set_value __gpio_set_value
+#define gpio_cansleep __gpio_cansleep
+#define gpio_to_irq __gpio_to_irq
+
+#endif /* __ASM_MACH_RALINK_GPIO_H */
diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index 93aaadf..29add97 100644
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -204,6 +204,12 @@ config GPIO_PXA
help
Say yes here to support the PXA GPIO device
+config GPIO_RALINK
+ bool "Ralink GPIO Support"
+ depends on RALINK
+ help
+ Say yes here to support the Ralink SoC GPIO device
+
config GPIO_SPEAR_SPICS
bool "ST SPEAr13xx SPI Chip Select as GPIO support"
depends on PLAT_SPEAR
diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile
index 22e07bc..f7b6603 100644
--- a/drivers/gpio/Makefile
+++ b/drivers/gpio/Makefile
@@ -55,6 +55,7 @@ obj-$(CONFIG_GPIO_PCF857X) += gpio-pcf857x.o
obj-$(CONFIG_GPIO_PCH) += gpio-pch.o
obj-$(CONFIG_GPIO_PL061) += gpio-pl061.o
obj-$(CONFIG_GPIO_PXA) += gpio-pxa.o
+obj-$(CONFIG_GPIO_RALINK) += gpio-ralink.o
obj-$(CONFIG_GPIO_RC5T583) += gpio-rc5t583.o
obj-$(CONFIG_GPIO_RDC321X) += gpio-rdc321x.o
obj-$(CONFIG_PLAT_SAMSUNG) += gpio-samsung.o
diff --git a/drivers/gpio/gpio-ralink.c b/drivers/gpio/gpio-ralink.c
new file mode 100644
index 0000000..26e8441
--- /dev/null
+++ b/drivers/gpio/gpio-ralink.c
@@ -0,0 +1,176 @@
+/*
+ * 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) 2009-2011 Gabor Juhos <juhosg@openwrt.org>
+ * Copyright (C) 2013 John Crispin <blogic@openwrt.org>
+ */
+
+#include <linux/module.h>
+#include <linux/io.h>
+#include <linux/gpio.h>
+#include <linux/spinlock.h>
+#include <linux/platform_device.h>
+
+enum ralink_gpio_reg {
+ GPIO_REG_INT = 0,
+ GPIO_REG_EDGE,
+ GPIO_REG_RENA,
+ GPIO_REG_FENA,
+ GPIO_REG_DATA,
+ GPIO_REG_DIR,
+ GPIO_REG_POL,
+ GPIO_REG_SET,
+ GPIO_REG_RESET,
+ GPIO_REG_TOGGLE,
+ GPIO_REG_MAX
+};
+
+struct ralink_gpio_chip {
+ struct gpio_chip chip;
+ u8 regs[GPIO_REG_MAX];
+
+ spinlock_t lock;
+ void __iomem *membase;
+};
+
+static inline struct ralink_gpio_chip *to_ralink_gpio(struct gpio_chip *chip)
+{
+ struct ralink_gpio_chip *rg;
+
+ rg = container_of(chip, struct ralink_gpio_chip, chip);
+ return rg;
+}
+
+static inline void rt_gpio_w32(struct ralink_gpio_chip *rg, u8 reg, u32 val)
+{
+ iowrite32(val, rg->membase + rg->regs[reg]);
+}
+
+static inline u32 rt_gpio_r32(struct ralink_gpio_chip *rg, u8 reg)
+{
+ return ioread32(rg->membase + rg->regs[reg]);
+}
+
+static void ralink_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
+{
+ struct ralink_gpio_chip *rg = to_ralink_gpio(chip);
+
+ rt_gpio_w32(rg, (value) ? GPIO_REG_SET : GPIO_REG_RESET, BIT(offset));
+}
+
+static int ralink_gpio_get(struct gpio_chip *chip, unsigned offset)
+{
+ struct ralink_gpio_chip *rg = to_ralink_gpio(chip);
+
+ return !!(rt_gpio_r32(rg, GPIO_REG_DATA) & BIT(offset));
+}
+
+static int ralink_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
+{
+ struct ralink_gpio_chip *rg = to_ralink_gpio(chip);
+ unsigned long flags;
+ u32 t;
+
+ spin_lock_irqsave(&rg->lock, flags);
+ t = rt_gpio_r32(rg, GPIO_REG_DIR);
+ t &= ~BIT(offset);
+ rt_gpio_w32(rg, GPIO_REG_DIR, t);
+ spin_unlock_irqrestore(&rg->lock, flags);
+
+ return 0;
+}
+
+static int ralink_gpio_direction_output(struct gpio_chip *chip,
+ unsigned offset, int value)
+{
+ struct ralink_gpio_chip *rg = to_ralink_gpio(chip);
+ unsigned long flags;
+ u32 t;
+
+ spin_lock_irqsave(&rg->lock, flags);
+ ralink_gpio_set(chip, offset, value);
+ t = rt_gpio_r32(rg, GPIO_REG_DIR);
+ t |= BIT(offset);
+ rt_gpio_w32(rg, GPIO_REG_DIR, t);
+ spin_unlock_irqrestore(&rg->lock, flags);
+
+ return 0;
+}
+
+static int ralink_gpio_probe(struct platform_device *pdev)
+{
+ struct device_node *np = pdev->dev.of_node;
+ struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ struct ralink_gpio_chip *gc;
+ const __be32 *ngpio;
+
+ if (!res) {
+ dev_err(&pdev->dev, "failed to find resource\n");
+ return -ENOMEM;
+ }
+
+ gc = devm_kzalloc(&pdev->dev,
+ sizeof(struct ralink_gpio_chip), GFP_KERNEL);
+ if (!gc)
+ return -ENOMEM;
+
+ gc->membase = devm_request_and_ioremap(&pdev->dev, res);
+ if (!gc->membase) {
+ dev_err(&pdev->dev, "cannot remap I/O memory region\n");
+ return -ENOMEM;
+ }
+
+ if (of_property_read_u8_array(np, "ralink,register-map",
+ gc->regs, GPIO_REG_MAX)) {
+ dev_err(&pdev->dev, "failed to read register definition\n");
+ return -EINVAL;
+ }
+
+ ngpio = of_get_property(np, "ralink,num-gpios", NULL);
+ if (!ngpio) {
+ dev_err(&pdev->dev, "failed to read number of pins\n");
+ return -EINVAL;
+ }
+
+ spin_lock_init(&gc->lock);
+
+ gc->chip.label = dev_name(&pdev->dev);
+ gc->chip.of_node = np;
+ gc->chip.base = -1;
+ gc->chip.ngpio = be32_to_cpu(*ngpio);
+ gc->chip.direction_input = ralink_gpio_direction_input;
+ gc->chip.direction_output = ralink_gpio_direction_output;
+ gc->chip.get = ralink_gpio_get;
+ gc->chip.set = ralink_gpio_set;
+
+ /* set polarity to low for all lines */
+ rt_gpio_w32(gc, GPIO_REG_POL, 0);
+
+ dev_info(&pdev->dev, "registering %d gpios\n", gc->chip.ngpio);
+
+ return gpiochip_add(&gc->chip);
+}
+
+static const struct of_device_id ralink_gpio_match[] = {
+ { .compatible = "ralink,rt2880-gpio" },
+ {},
+};
+MODULE_DEVICE_TABLE(of, ralink_gpio_match);
+
+static struct platform_driver ralink_gpio_driver = {
+ .probe = ralink_gpio_probe,
+ .driver = {
+ .name = "rt2880_gpio",
+ .owner = THIS_MODULE,
+ .of_match_table = ralink_gpio_match,
+ },
+};
+
+static int __init ralink_gpio_init(void)
+{
+ return platform_driver_register(&ralink_gpio_driver);
+}
+
+subsys_initcall(ralink_gpio_init);
--
1.7.10.4

View file

@ -0,0 +1,525 @@
e8c5ebbd743dac63178807c0f68fe1b75680474a3 Mon Sep 17 00:00:00 2001
From: John Crispin <blogic@openwrt.org>
Date: Wed, 30 Jan 2013 17:58:15 +0100
Subject: [PATCH 115/121] SPI: ralink: add Ralink SoC spi driver
Add the driver needed to make SPI work on Ralink SoC.
Signed-off-by: John Crispin <blogic@openwrt.org>
---
drivers/spi/Kconfig | 6 +
drivers/spi/Makefile | 1 +
drivers/spi/spi-ralink.c | 472 ++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 479 insertions(+)
create mode 100644 drivers/spi/spi-ralink.c
diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig
index f80eee7..301dbad 100644
--- a/drivers/spi/Kconfig
+++ b/drivers/spi/Kconfig
@@ -326,6 +326,12 @@ config SPI_RSPI
help
SPI driver for Renesas RSPI blocks.
+config SPI_RALINK
+ tristate "Ralink RT288x/RT305x/RT3662 SPI Controller"
+ depends on (SOC_RT288X || SOC_RT305X || SOC_RT3883)
+ help
+ This selects a driver for the Ralink RT288x/RT305x SPI Controller.
+
config SPI_S3C24XX
tristate "Samsung S3C24XX series SPI"
depends on ARCH_S3C24XX
diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile
index e53c309..a4b3c5b 100644
--- a/drivers/spi/Makefile
+++ b/drivers/spi/Makefile
@@ -53,6 +53,7 @@ spi-pxa2xx-platform-$(CONFIG_SPI_PXA2XX_DMA) += spi-pxa2xx-dma.o
obj-$(CONFIG_SPI_PXA2XX) += spi-pxa2xx-platform.o
obj-$(CONFIG_SPI_PXA2XX_PCI) += spi-pxa2xx-pci.o
obj-$(CONFIG_SPI_RSPI) += spi-rspi.o
+obj-$(CONFIG_SPI_RALINK) += spi-ralink.o
obj-$(CONFIG_SPI_S3C24XX) += spi-s3c24xx-hw.o
spi-s3c24xx-hw-y := spi-s3c24xx.o
spi-s3c24xx-hw-$(CONFIG_SPI_S3C24XX_FIQ) += spi-s3c24xx-fiq.o
diff --git a/drivers/spi/spi-ralink.c b/drivers/spi/spi-ralink.c
new file mode 100644
index 0000000..8d89cab
--- /dev/null
+++ b/drivers/spi/spi-ralink.c
@@ -0,0 +1,472 @@
+/*
+ * spi-ralink.c -- Ralink RT288x/RT305x SPI controller driver
+ *
+ * Copyright (C) 2011 Sergiy <piratfm@gmail.com>
+ * Copyright (C) 2011-2013 Gabor Juhos <juhosg@openwrt.org>
+ *
+ * Some parts are based on spi-orion.c:
+ * Author: Shadi Ammouri <shadi@marvell.com>
+ * Copyright (C) 2007-2008 Marvell Ltd.
+ *
+ * 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.
+ */
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/clk.h>
+#include <linux/err.h>
+#include <linux/delay.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+#include <linux/spi/spi.h>
+
+#define DRIVER_NAME "spi-ralink"
+#define RALINK_NUM_CHIPSELECTS 1 /* only one slave is supported*/
+#define RALINK_SPI_WAIT_RDY_MAX_LOOP 2000 /* in usec */
+
+#define RAMIPS_SPI_STAT 0x00
+#define RAMIPS_SPI_CFG 0x10
+#define RAMIPS_SPI_CTL 0x14
+#define RAMIPS_SPI_DATA 0x20
+
+/* SPISTAT register bit field */
+#define SPISTAT_BUSY BIT(0)
+
+/* SPICFG register bit field */
+#define SPICFG_LSBFIRST 0
+#define SPICFG_MSBFIRST BIT(8)
+#define SPICFG_SPICLKPOL BIT(6)
+#define SPICFG_RXCLKEDGE_FALLING BIT(5)
+#define SPICFG_TXCLKEDGE_FALLING BIT(4)
+#define SPICFG_SPICLK_PRESCALE_MASK 0x7
+#define SPICFG_SPICLK_DIV2 0
+#define SPICFG_SPICLK_DIV4 1
+#define SPICFG_SPICLK_DIV8 2
+#define SPICFG_SPICLK_DIV16 3
+#define SPICFG_SPICLK_DIV32 4
+#define SPICFG_SPICLK_DIV64 5
+#define SPICFG_SPICLK_DIV128 6
+#define SPICFG_SPICLK_DISABLE 7
+
+/* SPICTL register bit field */
+#define SPICTL_HIZSDO BIT(3)
+#define SPICTL_STARTWR BIT(2)
+#define SPICTL_STARTRD BIT(1)
+#define SPICTL_SPIENA BIT(0)
+
+#ifdef DEBUG
+#define spi_debug(args...) printk(args)
+#else
+#define spi_debug(args...)
+#endif
+
+struct ralink_spi {
+ struct spi_master *master;
+ void __iomem *base;
+ unsigned int sys_freq;
+ unsigned int speed;
+ struct clk *clk;
+};
+
+static inline struct ralink_spi *spidev_to_ralink_spi(struct spi_device *spi)
+{
+ return spi_master_get_devdata(spi->master);
+}
+
+static inline u32 ralink_spi_read(struct ralink_spi *rs, u32 reg)
+{
+ return ioread32(rs->base + reg);
+}
+
+static inline void ralink_spi_write(struct ralink_spi *rs, u32 reg, u32 val)
+{
+ iowrite32(val, rs->base + reg);
+}
+
+static inline void ralink_spi_setbits(struct ralink_spi *rs, u32 reg, u32 mask)
+{
+ void __iomem *addr = rs->base + reg;
+ u32 val;
+
+ val = ioread32(addr);
+ val |= mask;
+ iowrite32(val, addr);
+}
+
+static inline void ralink_spi_clrbits(struct ralink_spi *rs, u32 reg, u32 mask)
+{
+ void __iomem *addr = rs->base + reg;
+ u32 val;
+
+ val = ioread32(addr);
+ val &= ~mask;
+ iowrite32(val, addr);
+}
+
+static int ralink_spi_baudrate_set(struct spi_device *spi, unsigned int speed)
+{
+ struct ralink_spi *rs = spidev_to_ralink_spi(spi);
+ u32 rate;
+ u32 prescale;
+ u32 reg;
+
+ spi_debug("%s: speed:%u\n", __func__, speed);
+
+ /*
+ * the supported rates are: 2, 4, 8, ... 128
+ * round up as we look for equal or less speed
+ */
+ rate = DIV_ROUND_UP(rs->sys_freq, speed);
+ spi_debug("%s: rate-1:%u\n", __func__, rate);
+ rate = roundup_pow_of_two(rate);
+ spi_debug("%s: rate-2:%u\n", __func__, rate);
+
+ /* check if requested speed is too small */
+ if (rate > 128)
+ return -EINVAL;
+
+ if (rate < 2)
+ rate = 2;
+
+ /* Convert the rate to SPI clock divisor value. */
+ prescale = ilog2(rate/2);
+ spi_debug("%s: prescale:%u\n", __func__, prescale);
+
+ reg = ralink_spi_read(rs, RAMIPS_SPI_CFG);
+ reg = ((reg & ~SPICFG_SPICLK_PRESCALE_MASK) | prescale);
+ ralink_spi_write(rs, RAMIPS_SPI_CFG, reg);
+ rs->speed = speed;
+ return 0;
+}
+
+/*
+ * called only when no transfer is active on the bus
+ */
+static int
+ralink_spi_setup_transfer(struct spi_device *spi, struct spi_transfer *t)
+{
+ struct ralink_spi *rs = spidev_to_ralink_spi(spi);
+ unsigned int speed = spi->max_speed_hz;
+ int rc;
+ unsigned int bits_per_word = 8;
+
+ if ((t != NULL) && t->speed_hz)
+ speed = t->speed_hz;
+
+ if ((t != NULL) && t->bits_per_word)
+ bits_per_word = t->bits_per_word;
+
+ if (rs->speed != speed) {
+ spi_debug("%s: speed_hz:%u\n", __func__, speed);
+ rc = ralink_spi_baudrate_set(spi, speed);
+ if (rc)
+ return rc;
+ }
+
+ if (bits_per_word != 8) {
+ spi_debug("%s: bad bits_per_word: %u\n", __func__,
+ bits_per_word);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static void ralink_spi_set_cs(struct ralink_spi *rs, int enable)
+{
+ if (enable)
+ ralink_spi_clrbits(rs, RAMIPS_SPI_CTL, SPICTL_SPIENA);
+ else
+ ralink_spi_setbits(rs, RAMIPS_SPI_CTL, SPICTL_SPIENA);
+}
+
+static inline int ralink_spi_wait_till_ready(struct ralink_spi *rs)
+{
+ int i;
+
+ for (i = 0; i < RALINK_SPI_WAIT_RDY_MAX_LOOP; i++) {
+ u32 status;
+
+ status = ralink_spi_read(rs, RAMIPS_SPI_STAT);
+ if ((status & SPISTAT_BUSY) == 0)
+ return 0;
+
+ udelay(1);
+ }
+
+ return -ETIMEDOUT;
+}
+
+static unsigned int
+ralink_spi_write_read(struct spi_device *spi, struct spi_transfer *xfer)
+{
+ struct ralink_spi *rs = spidev_to_ralink_spi(spi);
+ unsigned count = 0;
+ u8 *rx = xfer->rx_buf;
+ const u8 *tx = xfer->tx_buf;
+ int err;
+
+ spi_debug("%s(%d): %s %s\n", __func__, xfer->len,
+ (tx != NULL) ? "tx" : " ",
+ (rx != NULL) ? "rx" : " ");
+
+ if (tx) {
+ for (count = 0; count < xfer->len; count++) {
+ ralink_spi_write(rs, RAMIPS_SPI_DATA, tx[count]);
+ ralink_spi_setbits(rs, RAMIPS_SPI_CTL, SPICTL_STARTWR);
+ err = ralink_spi_wait_till_ready(rs);
+ if (err) {
+ dev_err(&spi->dev, "TX failed, err=%d\n", err);
+ goto out;
+ }
+ }
+ }
+
+ if (rx) {
+ for (count = 0; count < xfer->len; count++) {
+ ralink_spi_setbits(rs, RAMIPS_SPI_CTL, SPICTL_STARTRD);
+ err = ralink_spi_wait_till_ready(rs);
+ if (err) {
+ dev_err(&spi->dev, "RX failed, err=%d\n", err);
+ goto out;
+ }
+ rx[count] = (u8) ralink_spi_read(rs, RAMIPS_SPI_DATA);
+ }
+ }
+
+out:
+ return count;
+}
+
+static int ralink_spi_transfer_one_message(struct spi_master *master,
+ struct spi_message *m)
+{
+ struct ralink_spi *rs = spi_master_get_devdata(master);
+ struct spi_device *spi = m->spi;
+ struct spi_transfer *t = NULL;
+ int par_override = 0;
+ int status = 0;
+ int cs_active = 0;
+
+ /* Load defaults */
+ status = ralink_spi_setup_transfer(spi, NULL);
+ if (status < 0)
+ goto msg_done;
+
+ list_for_each_entry(t, &m->transfers, transfer_list) {
+ unsigned int bits_per_word = spi->bits_per_word;
+
+ if (t->tx_buf == NULL && t->rx_buf == NULL && t->len) {
+ dev_err(&spi->dev,
+ "message rejected: invalid transfer data buffers\n");
+ status = -EIO;
+ goto msg_done;
+ }
+
+ if (t->bits_per_word)
+ bits_per_word = t->bits_per_word;
+
+ if (bits_per_word != 8) {
+ dev_err(&spi->dev,
+ "message rejected: invalid transfer bits_per_word (%d bits)\n",
+ bits_per_word);
+ status = -EIO;
+ goto msg_done;
+ }
+
+ if (t->speed_hz && t->speed_hz < (rs->sys_freq / 128)) {
+ dev_err(&spi->dev,
+ "message rejected: device min speed (%d Hz) exceeds required transfer speed (%d Hz)\n",
+ (rs->sys_freq / 128), t->speed_hz);
+ status = -EIO;
+ goto msg_done;
+ }
+
+ if (par_override || t->speed_hz || t->bits_per_word) {
+ par_override = 1;
+ status = ralink_spi_setup_transfer(spi, t);
+ if (status < 0)
+ goto msg_done;
+ if (!t->speed_hz && !t->bits_per_word)
+ par_override = 0;
+ }
+
+ if (!cs_active) {
+ ralink_spi_set_cs(rs, 1);
+ cs_active = 1;
+ }
+
+ if (t->len)
+ m->actual_length += ralink_spi_write_read(spi, t);
+
+ if (t->delay_usecs)
+ udelay(t->delay_usecs);
+
+ if (t->cs_change) {
+ ralink_spi_set_cs(rs, 0);
+ cs_active = 0;
+ }
+ }
+
+msg_done:
+ if (cs_active)
+ ralink_spi_set_cs(rs, 0);
+
+ m->status = status;
+ spi_finalize_current_message(master);
+
+ return 0;
+}
+
+static int ralink_spi_setup(struct spi_device *spi)
+{
+ struct ralink_spi *rs = spidev_to_ralink_spi(spi);
+
+ if ((spi->max_speed_hz == 0) ||
+ (spi->max_speed_hz > (rs->sys_freq / 2)))
+ spi->max_speed_hz = (rs->sys_freq / 2);
+
+ if (spi->max_speed_hz < (rs->sys_freq / 128)) {
+ dev_err(&spi->dev, "setup: requested speed is too low %d Hz\n",
+ spi->max_speed_hz);
+ return -EINVAL;
+ }
+
+ if (spi->bits_per_word != 0 && spi->bits_per_word != 8) {
+ dev_err(&spi->dev,
+ "setup: requested bits per words - os wrong %d bpw\n",
+ spi->bits_per_word);
+ return -EINVAL;
+ }
+
+ if (spi->bits_per_word == 0)
+ spi->bits_per_word = 8;
+
+ /*
+ * baudrate & width will be set ralink_spi_setup_transfer
+ */
+ return 0;
+}
+
+static void ralink_spi_reset(struct ralink_spi *rs)
+{
+ ralink_spi_write(rs, RAMIPS_SPI_CFG,
+ SPICFG_MSBFIRST | SPICFG_TXCLKEDGE_FALLING |
+ SPICFG_SPICLK_DIV16 | SPICFG_SPICLKPOL);
+ ralink_spi_write(rs, RAMIPS_SPI_CTL, SPICTL_HIZSDO | SPICTL_SPIENA);
+}
+
+static int ralink_spi_probe(struct platform_device *pdev)
+{
+ struct spi_master *master;
+ struct ralink_spi *rs;
+ struct resource *r;
+ int status = 0;
+
+ master = spi_alloc_master(&pdev->dev, sizeof(*rs));
+ if (master == NULL) {
+ dev_dbg(&pdev->dev, "master allocation failed\n");
+ return -ENOMEM;
+ }
+
+ //if (pdev->id != -1)
+ master->bus_num = 0;
+
+ /* we support only mode 0, and no options */
+ master->mode_bits = 0;
+
+ master->setup = ralink_spi_setup;
+ master->transfer_one_message = ralink_spi_transfer_one_message;
+ master->num_chipselect = RALINK_NUM_CHIPSELECTS;
+ master->dev.of_node = pdev->dev.of_node;
+
+ dev_set_drvdata(&pdev->dev, master);
+
+ rs = spi_master_get_devdata(master);
+ rs->master = master;
+
+ rs->clk = clk_get(&pdev->dev, NULL);
+ if (IS_ERR(rs->clk)) {
+ status = PTR_ERR(rs->clk);
+ dev_err(&pdev->dev, "unable to get SYS clock, err=%d\n",
+ status);
+ goto out_put_master;
+ }
+
+ status = clk_enable(rs->clk);
+ if (status)
+ goto out_put_clk;
+
+ rs->sys_freq = clk_get_rate(rs->clk);
+ spi_debug("%s: sys_freq: %u\n", __func__, rs->sys_freq);
+
+ r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (r == NULL) {
+ status = -ENODEV;
+ goto out_disable_clk;
+ }
+
+ rs->base = devm_request_and_ioremap(&pdev->dev, r);
+ if (!rs->base) {
+ status = -EADDRNOTAVAIL;
+ goto out_disable_clk;
+ }
+
+ ralink_spi_reset(rs);
+
+ status = spi_register_master(master);
+ if (status)
+ goto out_disable_clk;
+
+ return 0;
+
+out_disable_clk:
+ clk_disable(rs->clk);
+out_put_clk:
+ clk_put(rs->clk);
+out_put_master:
+ spi_master_put(master);
+ return status;
+}
+
+static int ralink_spi_remove(struct platform_device *pdev)
+{
+ struct spi_master *master;
+ struct ralink_spi *rs;
+
+ master = dev_get_drvdata(&pdev->dev);
+ rs = spi_master_get_devdata(master);
+
+ clk_disable(rs->clk);
+ clk_put(rs->clk);
+ spi_unregister_master(master);
+
+ return 0;
+}
+
+MODULE_ALIAS("platform:" DRIVER_NAME);
+
+static const struct of_device_id ralink_spi_match[] = {
+ { .compatible = "ralink,rt2880-spi" },
+ {},
+};
+MODULE_DEVICE_TABLE(of, ralink_spi_match);
+
+static struct platform_driver ralink_spi_driver = {
+ .driver = {
+ .name = DRIVER_NAME,
+ .owner = THIS_MODULE,
+ .of_match_table = ralink_spi_match,
+ },
+ .probe = ralink_spi_probe,
+ .remove = ralink_spi_remove,
+};
+
+module_platform_driver(ralink_spi_driver);
+
+MODULE_DESCRIPTION("Ralink SPI driver");
+MODULE_AUTHOR("Sergiy <piratfm@gmail.com>");
+MODULE_AUTHOR("Gabor Juhos <juhosg@openwrt.org>");
+MODULE_LICENSE("GPL");
--
1.7.10.4

View file

@ -0,0 +1,32 @@
From 6ffb42870411ca082e8e46d96d72bc5d8881ce8d Mon Sep 17 00:00:00 2001
From: John Crispin <blogic@openwrt.org>
Date: Tue, 22 Jan 2013 16:01:07 +0100
Subject: [PATCH 116/121] serial: of: allow au1x00 and rt288x to load from OF
In order to make serial_8250 loadable via OF on Au1x00 and Ralink WiSoC we need
to default the iotype to UPIO_AU.
Signed-off-by: John Crispin <blogic@openwrt.org>
---
drivers/tty/serial/of_serial.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/drivers/tty/serial/of_serial.c b/drivers/tty/serial/of_serial.c
index b025d54..42f8550 100644
--- a/drivers/tty/serial/of_serial.c
+++ b/drivers/tty/serial/of_serial.c
@@ -98,7 +98,10 @@ static int of_platform_serial_setup(struct platform_device *ofdev,
port->regshift = prop;
port->irq = irq_of_parse_and_map(np, 0);
- port->iotype = UPIO_MEM;
+ if (of_device_is_compatible(np, "ralink,rt2880-uart"))
+ port->iotype = UPIO_AU;
+ else
+ port->iotype = UPIO_MEM;
if (of_property_read_u32(np, "reg-io-width", &prop) == 0) {
switch (prop) {
case 1:
--
1.7.10.4

View file

@ -0,0 +1,28 @@
From c1e24bf32404bec0032221b9ea37d6fd8c45dbdd Mon Sep 17 00:00:00 2001
From: John Crispin <blogic@openwrt.org>
Date: Fri, 15 Mar 2013 18:16:01 +0100
Subject: [PATCH 117/121] serial: ralink: adds mt7620 serial
Add the config symbol for Mediatek7620 SoC to SERIAL_8250_RT288X
Signed-off-by: John Crispin <blogic@openwrt.org>
---
drivers/tty/serial/8250/Kconfig | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/tty/serial/8250/Kconfig b/drivers/tty/serial/8250/Kconfig
index 2ef9537..1038cdb 100644
--- a/drivers/tty/serial/8250/Kconfig
+++ b/drivers/tty/serial/8250/Kconfig
@@ -279,7 +279,7 @@ config SERIAL_8250_EM
config SERIAL_8250_RT288X
bool "Ralink RT288x/RT305x/RT3662/RT3883 serial port support"
- depends on SERIAL_8250 && (SOC_RT288X || SOC_RT305X || SOC_RT3883)
+ depends on SERIAL_8250 && (SOC_RT288X || SOC_RT305X || SOC_RT3883 || SOC_MT7620)
help
If you have a Ralink RT288x/RT305x SoC based board and want to use the
serial port, say Y to this option. The driver can handle up to 2 serial
--
1.7.10.4

View file

@ -0,0 +1,329 @@
From 028f340b63bf722e8807b31ef955484acf2cce47 Mon Sep 17 00:00:00 2001
From: John Crispin <blogic@openwrt.org>
Date: Thu, 21 Mar 2013 18:27:29 +0100
Subject: [PATCH 118/121] PCI: MIPS: adds rt2880 pci support
Add support for the pci found on the rt2880 SoC.
Signed-off-by: John Crispin <blogic@openwrt.org>
---
arch/mips/pci/Makefile | 1 +
arch/mips/pci/pci-rt2880.c | 281 ++++++++++++++++++++++++++++++++++++++++++++
arch/mips/ralink/Kconfig | 1 +
3 files changed, 283 insertions(+)
create mode 100644 arch/mips/pci/pci-rt2880.c
diff --git a/arch/mips/pci/Makefile b/arch/mips/pci/Makefile
index 2cb1d31..77974ba 100644
--- a/arch/mips/pci/Makefile
+++ b/arch/mips/pci/Makefile
@@ -41,6 +41,7 @@ obj-$(CONFIG_SIBYTE_BCM1x80) += pci-bcm1480.o pci-bcm1480ht.o
obj-$(CONFIG_SNI_RM) += fixup-sni.o ops-sni.o
obj-$(CONFIG_LANTIQ) += fixup-lantiq.o
obj-$(CONFIG_PCI_LANTIQ) += pci-lantiq.o ops-lantiq.o
+obj-$(CONFIG_SOC_RT2880) += pci-rt2880.o
obj-$(CONFIG_TANBAC_TB0219) += fixup-tb0219.o
obj-$(CONFIG_TANBAC_TB0226) += fixup-tb0226.o
obj-$(CONFIG_TANBAC_TB0287) += fixup-tb0287.o
diff --git a/arch/mips/pci/pci-rt2880.c b/arch/mips/pci/pci-rt2880.c
new file mode 100644
index 0000000..e2c4730
--- /dev/null
+++ b/arch/mips/pci/pci-rt2880.c
@@ -0,0 +1,281 @@
+/*
+ * Ralink RT288x SoC PCI register definitions
+ *
+ * Copyright (C) 2009 John Crispin <blogic@openwrt.org>
+ * Copyright (C) 2009 Gabor Juhos <juhosg@openwrt.org>
+ *
+ * Parts of this file are based on Ralink's 2.6.21 BSP
+ *
+ * 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.
+ */
+
+#include <linux/types.h>
+#include <linux/pci.h>
+#include <linux/io.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/of_platform.h>
+#include <linux/of_irq.h>
+#include <linux/of_pci.h>
+
+#include <asm/mach-ralink/rt288x.h>
+
+#define RT2880_PCI_BASE 0x00440000
+#define RT288X_CPU_IRQ_PCI 4
+
+#define RT2880_PCI_MEM_BASE 0x20000000
+#define RT2880_PCI_MEM_SIZE 0x10000000
+#define RT2880_PCI_IO_BASE 0x00460000
+#define RT2880_PCI_IO_SIZE 0x00010000
+
+#define RT2880_PCI_REG_PCICFG_ADDR 0x00
+#define RT2880_PCI_REG_PCIMSK_ADDR 0x0c
+#define RT2880_PCI_REG_BAR0SETUP_ADDR 0x10
+#define RT2880_PCI_REG_IMBASEBAR0_ADDR 0x18
+#define RT2880_PCI_REG_CONFIG_ADDR 0x20
+#define RT2880_PCI_REG_CONFIG_DATA 0x24
+#define RT2880_PCI_REG_MEMBASE 0x28
+#define RT2880_PCI_REG_IOBASE 0x2c
+#define RT2880_PCI_REG_ID 0x30
+#define RT2880_PCI_REG_CLASS 0x34
+#define RT2880_PCI_REG_SUBID 0x38
+#define RT2880_PCI_REG_ARBCTL 0x80
+
+static void __iomem *rt2880_pci_base;
+static DEFINE_SPINLOCK(rt2880_pci_lock);
+
+static u32 rt2880_pci_reg_read(u32 reg)
+{
+ return readl(rt2880_pci_base + reg);
+}
+
+static void rt2880_pci_reg_write(u32 val, u32 reg)
+{
+ writel(val, rt2880_pci_base + reg);
+}
+
+static inline u32 rt2880_pci_get_cfgaddr(unsigned int bus, unsigned int slot,
+ unsigned int func, unsigned int where)
+{
+ return ((bus << 16) | (slot << 11) | (func << 8) | (where & 0xfc) |
+ 0x80000000);
+}
+
+static int rt2880_pci_config_read(struct pci_bus *bus, unsigned int devfn,
+ int where, int size, u32 *val)
+{
+ unsigned long flags;
+ u32 address;
+ u32 data;
+
+ address = rt2880_pci_get_cfgaddr(bus->number, PCI_SLOT(devfn),
+ PCI_FUNC(devfn), where);
+
+ spin_lock_irqsave(&rt2880_pci_lock, flags);
+ rt2880_pci_reg_write(address, RT2880_PCI_REG_CONFIG_ADDR);
+ data = rt2880_pci_reg_read(RT2880_PCI_REG_CONFIG_DATA);
+ spin_unlock_irqrestore(&rt2880_pci_lock, flags);
+
+ switch (size) {
+ case 1:
+ *val = (data >> ((where & 3) << 3)) & 0xff;
+ break;
+ case 2:
+ *val = (data >> ((where & 3) << 3)) & 0xffff;
+ break;
+ case 4:
+ *val = data;
+ break;
+ }
+
+ return PCIBIOS_SUCCESSFUL;
+}
+
+static int rt2880_pci_config_write(struct pci_bus *bus, unsigned int devfn,
+ int where, int size, u32 val)
+{
+ unsigned long flags;
+ u32 address;
+ u32 data;
+
+ address = rt2880_pci_get_cfgaddr(bus->number, PCI_SLOT(devfn),
+ PCI_FUNC(devfn), where);
+
+ spin_lock_irqsave(&rt2880_pci_lock, flags);
+ rt2880_pci_reg_write(address, RT2880_PCI_REG_CONFIG_ADDR);
+ data = rt2880_pci_reg_read(RT2880_PCI_REG_CONFIG_DATA);
+
+ switch (size) {
+ case 1:
+ data = (data & ~(0xff << ((where & 3) << 3))) |
+ (val << ((where & 3) << 3));
+ break;
+ case 2:
+ data = (data & ~(0xffff << ((where & 3) << 3))) |
+ (val << ((where & 3) << 3));
+ break;
+ case 4:
+ data = val;
+ break;
+ }
+
+ rt2880_pci_reg_write(data, RT2880_PCI_REG_CONFIG_DATA);
+ spin_unlock_irqrestore(&rt2880_pci_lock, flags);
+
+ return PCIBIOS_SUCCESSFUL;
+}
+
+static struct pci_ops rt2880_pci_ops = {
+ .read = rt2880_pci_config_read,
+ .write = rt2880_pci_config_write,
+};
+
+static struct resource rt2880_pci_mem_resource = {
+ .name = "PCI MEM space",
+ .start = RT2880_PCI_MEM_BASE,
+ .end = RT2880_PCI_MEM_BASE + RT2880_PCI_MEM_SIZE - 1,
+ .flags = IORESOURCE_MEM,
+};
+
+static struct resource rt2880_pci_io_resource = {
+ .name = "PCI IO space",
+ .start = RT2880_PCI_IO_BASE,
+ .end = RT2880_PCI_IO_BASE + RT2880_PCI_IO_SIZE - 1,
+ .flags = IORESOURCE_IO,
+};
+
+static struct pci_controller rt2880_pci_controller = {
+ .pci_ops = &rt2880_pci_ops,
+ .mem_resource = &rt2880_pci_mem_resource,
+ .io_resource = &rt2880_pci_io_resource,
+};
+
+static inline u32 rt2880_pci_read_u32(unsigned long reg)
+{
+ unsigned long flags;
+ u32 address;
+ u32 ret;
+
+ address = rt2880_pci_get_cfgaddr(0, 0, 0, reg);
+
+ spin_lock_irqsave(&rt2880_pci_lock, flags);
+ rt2880_pci_reg_write(address, RT2880_PCI_REG_CONFIG_ADDR);
+ ret = rt2880_pci_reg_read(RT2880_PCI_REG_CONFIG_DATA);
+ spin_unlock_irqrestore(&rt2880_pci_lock, flags);
+
+ return ret;
+}
+
+static inline void rt2880_pci_write_u32(unsigned long reg, u32 val)
+{
+ unsigned long flags;
+ u32 address;
+
+ address = rt2880_pci_get_cfgaddr(0, 0, 0, reg);
+
+ spin_lock_irqsave(&rt2880_pci_lock, flags);
+ rt2880_pci_reg_write(address, RT2880_PCI_REG_CONFIG_ADDR);
+ rt2880_pci_reg_write(val, RT2880_PCI_REG_CONFIG_DATA);
+ spin_unlock_irqrestore(&rt2880_pci_lock, flags);
+}
+
+int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
+{
+ u16 cmd;
+ int irq = -1;
+
+ if (dev->bus->number != 0)
+ return irq;
+
+ switch (PCI_SLOT(dev->devfn)) {
+ case 0x00:
+ rt2880_pci_write_u32(PCI_BASE_ADDRESS_0, 0x08000000);
+ (void) rt2880_pci_read_u32(PCI_BASE_ADDRESS_0);
+ break;
+ case 0x11:
+ irq = RT288X_CPU_IRQ_PCI;
+ break;
+ default:
+ printk("%s:%s[%d] trying to alloc unknown pci irq\n",
+ __FILE__, __func__, __LINE__);
+ BUG();
+ break;
+ }
+
+ pci_write_config_byte((struct pci_dev*)dev, PCI_CACHE_LINE_SIZE, 0x14);
+ pci_write_config_byte((struct pci_dev*)dev, PCI_LATENCY_TIMER, 0xFF);
+ pci_read_config_word((struct pci_dev*)dev, PCI_COMMAND, &cmd);
+ cmd |= PCI_COMMAND_MASTER | PCI_COMMAND_IO | PCI_COMMAND_MEMORY |
+ PCI_COMMAND_INVALIDATE | PCI_COMMAND_FAST_BACK |
+ PCI_COMMAND_SERR | PCI_COMMAND_WAIT | PCI_COMMAND_PARITY;
+ pci_write_config_word((struct pci_dev*)dev, PCI_COMMAND, cmd);
+ pci_write_config_byte((struct pci_dev*)dev, PCI_INTERRUPT_LINE,
+ dev->irq);
+ return irq;
+}
+
+static int rt288x_pci_probe(struct platform_device *pdev)
+{
+ void __iomem *io_map_base;
+ int i;
+
+ rt2880_pci_base = ioremap_nocache(RT2880_PCI_BASE, PAGE_SIZE);
+
+ io_map_base = ioremap(RT2880_PCI_IO_BASE, RT2880_PCI_IO_SIZE);
+ rt2880_pci_controller.io_map_base = (unsigned long) io_map_base;
+ set_io_port_base((unsigned long) io_map_base);
+
+ ioport_resource.start = RT2880_PCI_IO_BASE;
+ ioport_resource.end = RT2880_PCI_IO_BASE + RT2880_PCI_IO_SIZE - 1;
+
+ rt2880_pci_reg_write(0, RT2880_PCI_REG_PCICFG_ADDR);
+ for(i = 0; i < 0xfffff; i++) {}
+
+ rt2880_pci_reg_write(0x79, RT2880_PCI_REG_ARBCTL);
+ rt2880_pci_reg_write(0x07FF0001, RT2880_PCI_REG_BAR0SETUP_ADDR);
+ rt2880_pci_reg_write(RT2880_PCI_MEM_BASE, RT2880_PCI_REG_MEMBASE);
+ rt2880_pci_reg_write(RT2880_PCI_IO_BASE, RT2880_PCI_REG_IOBASE);
+ rt2880_pci_reg_write(0x08000000, RT2880_PCI_REG_IMBASEBAR0_ADDR);
+ rt2880_pci_reg_write(0x08021814, RT2880_PCI_REG_ID);
+ rt2880_pci_reg_write(0x00800001, RT2880_PCI_REG_CLASS);
+ rt2880_pci_reg_write(0x28801814, RT2880_PCI_REG_SUBID);
+ rt2880_pci_reg_write(0x000c0000, RT2880_PCI_REG_PCIMSK_ADDR);
+
+ rt2880_pci_write_u32(PCI_BASE_ADDRESS_0, 0x08000000);
+ (void) rt2880_pci_read_u32(PCI_BASE_ADDRESS_0);
+
+ register_pci_controller(&rt2880_pci_controller);
+ return 0;
+}
+
+int pcibios_plat_dev_init(struct pci_dev *dev)
+{
+ return 0;
+}
+
+static const struct of_device_id rt288x_pci_match[] = {
+ { .compatible = "ralink,rt288x-pci" },
+ {},
+};
+MODULE_DEVICE_TABLE(of, rt288x_pci_match);
+
+static struct platform_driver rt288x_pci_driver = {
+ .probe = rt288x_pci_probe,
+ .driver = {
+ .name = "rt288x-pci",
+ .owner = THIS_MODULE,
+ .of_match_table = rt288x_pci_match,
+ },
+};
+
+int __init pcibios_init(void)
+{
+ int ret = platform_driver_register(&rt288x_pci_driver);
+ if (ret)
+ pr_info("rt288x-pci: Error registering platform driver!");
+ return ret;
+}
+
+arch_initcall(pcibios_init);
diff --git a/arch/mips/ralink/Kconfig b/arch/mips/ralink/Kconfig
index 8254502..a3eec2a 100644
--- a/arch/mips/ralink/Kconfig
+++ b/arch/mips/ralink/Kconfig
@@ -8,6 +8,7 @@ choice
config SOC_RT288X
bool "RT288x"
+ select HW_HAS_PCI
config SOC_RT305X
bool "RT305x"
--
1.7.10.4

View file

@ -0,0 +1,535 @@
From f01830fcc57273bd9ec5f6733ab3d28adeb71955 Mon Sep 17 00:00:00 2001
From: John Crispin <blogic@openwrt.org>
Date: Thu, 21 Mar 2013 17:34:08 +0100
Subject: [PATCH 119/121] PCI: MIPS: adds rt3883 pci support
Add support for the pcie found on the rt3883 SoC.
Signed-off-by: John Crispin <blogic@openwrt.org>
---
arch/mips/pci/Makefile | 1 +
arch/mips/pci/pci-rt3883.c | 487 ++++++++++++++++++++++++++++++++++++++++++++
arch/mips/ralink/Kconfig | 1 +
3 files changed, 489 insertions(+)
create mode 100644 arch/mips/pci/pci-rt3883.c
diff --git a/arch/mips/pci/Makefile b/arch/mips/pci/Makefile
index 77974ba..3cbfd9b 100644
--- a/arch/mips/pci/Makefile
+++ b/arch/mips/pci/Makefile
@@ -42,6 +42,7 @@ obj-$(CONFIG_SNI_RM) += fixup-sni.o ops-sni.o
obj-$(CONFIG_LANTIQ) += fixup-lantiq.o
obj-$(CONFIG_PCI_LANTIQ) += pci-lantiq.o ops-lantiq.o
obj-$(CONFIG_SOC_RT2880) += pci-rt2880.o
+obj-$(CONFIG_SOC_RT3883) += pci-rt3883.o
obj-$(CONFIG_TANBAC_TB0219) += fixup-tb0219.o
obj-$(CONFIG_TANBAC_TB0226) += fixup-tb0226.o
obj-$(CONFIG_TANBAC_TB0287) += fixup-tb0287.o
diff --git a/arch/mips/pci/pci-rt3883.c b/arch/mips/pci/pci-rt3883.c
new file mode 100644
index 0000000..8a4c8ce
--- /dev/null
+++ b/arch/mips/pci/pci-rt3883.c
@@ -0,0 +1,487 @@
+/*
+ * Ralink RT3883 SoC PCI support
+ *
+ * Copyright (C) 2011-2012 Gabor Juhos <juhosg@openwrt.org>
+ *
+ * Parts of this file are based on Ralink's 2.6.21 BSP
+ *
+ * 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.
+ */
+
+#include <linux/types.h>
+#include <linux/pci.h>
+#include <linux/io.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+
+#include <asm/mach-ralink/rt3883.h>
+#include <asm/mach-ralink/rt3883_regs.h>
+
+#define RT3883_MEMORY_BASE 0x00000000
+#define RT3883_MEMORY_SIZE 0x02000000
+
+#define RT3883_PCI_MEM_BASE 0x20000000
+#define RT3883_PCI_MEM_SIZE 0x10000000
+#define RT3883_PCI_IO_BASE 0x10160000
+#define RT3883_PCI_IO_SIZE 0x00010000
+
+#define RT3883_PCI_REG_PCICFG_ADDR 0x00
+#define RT3883_PCI_REG_PCIRAW_ADDR 0x04
+#define RT3883_PCI_REG_PCIINT_ADDR 0x08
+#define RT3883_PCI_REG_PCIMSK_ADDR 0x0c
+#define RT3833_PCI_PCIINT_PCIE BIT(20)
+#define RT3833_PCI_PCIINT_PCI1 BIT(19)
+#define RT3833_PCI_PCIINT_PCI0 BIT(18)
+
+#define RT3883_PCI_REG_CONFIG_ADDR 0x20
+#define RT3883_PCI_REG_CONFIG_DATA 0x24
+#define RT3883_PCI_REG_MEMBASE 0x28
+#define RT3883_PCI_REG_IOBASE 0x2c
+#define RT3883_PCI_REG_ARBCTL 0x80
+
+#define RT3883_PCI_REG_BASE(_x) (0x1000 + (_x) * 0x1000)
+#define RT3883_PCI_REG_BAR0SETUP_ADDR(_x) (RT3883_PCI_REG_BASE((_x)) + 0x10)
+#define RT3883_PCI_REG_IMBASEBAR0_ADDR(_x) (RT3883_PCI_REG_BASE((_x)) + 0x18)
+#define RT3883_PCI_REG_ID(_x) (RT3883_PCI_REG_BASE((_x)) + 0x30)
+#define RT3883_PCI_REG_CLASS(_x) (RT3883_PCI_REG_BASE((_x)) + 0x34)
+#define RT3883_PCI_REG_SUBID(_x) (RT3883_PCI_REG_BASE((_x)) + 0x38)
+#define RT3883_PCI_REG_STATUS(_x) (RT3883_PCI_REG_BASE((_x)) + 0x50)
+
+static int (*rt3883_pci_plat_dev_init)(struct pci_dev *dev);
+static void __iomem *rt3883_pci_base;
+static DEFINE_SPINLOCK(rt3883_pci_lock);
+
+static inline u32 rt3883_pci_rr(unsigned reg)
+{
+ return readl(rt3883_pci_base + reg);
+}
+
+static inline void rt3883_pci_wr(u32 val, unsigned reg)
+{
+ writel(val, rt3883_pci_base + reg);
+}
+
+static inline u32 rt3883_pci_get_cfgaddr(unsigned int bus, unsigned int slot,
+ unsigned int func, unsigned int where)
+{
+ return ((bus << 16) | (slot << 11) | (func << 8) | (where & 0xfc) |
+ 0x80000000);
+}
+
+static u32 rt3883_pci_read_u32(unsigned bus, unsigned slot,
+ unsigned func, unsigned reg)
+{
+ unsigned long flags;
+ u32 address;
+ u32 ret;
+
+ address = rt3883_pci_get_cfgaddr(bus, slot, func, reg);
+
+ spin_lock_irqsave(&rt3883_pci_lock, flags);
+ rt3883_pci_wr(address, RT3883_PCI_REG_CONFIG_ADDR);
+ ret = rt3883_pci_rr(RT3883_PCI_REG_CONFIG_DATA);
+ spin_unlock_irqrestore(&rt3883_pci_lock, flags);
+
+ return ret;
+}
+
+static void rt3883_pci_write_u32(unsigned bus, unsigned slot,
+ unsigned func, unsigned reg, u32 val)
+{
+ unsigned long flags;
+ u32 address;
+
+ address = rt3883_pci_get_cfgaddr(bus, slot, func, reg);
+
+ spin_lock_irqsave(&rt3883_pci_lock, flags);
+ rt3883_pci_wr(address, RT3883_PCI_REG_CONFIG_ADDR);
+ rt3883_pci_wr(val, RT3883_PCI_REG_CONFIG_DATA);
+ spin_unlock_irqrestore(&rt3883_pci_lock, flags);
+}
+
+static void rt3883_pci_irq_handler(unsigned int irq, struct irq_desc *desc)
+{
+ u32 pending;
+
+ pending = rt3883_pci_rr(RT3883_PCI_REG_PCIINT_ADDR) &
+ rt3883_pci_rr(RT3883_PCI_REG_PCIMSK_ADDR);
+
+ if (!pending) {
+ spurious_interrupt();
+ return;
+ }
+
+ if (pending & RT3833_PCI_PCIINT_PCI0)
+ generic_handle_irq(RT3883_PCI_IRQ_PCI0);
+
+ if (pending & RT3833_PCI_PCIINT_PCI1)
+ generic_handle_irq(RT3883_PCI_IRQ_PCI1);
+
+ if (pending & RT3833_PCI_PCIINT_PCIE)
+ generic_handle_irq(RT3883_PCI_IRQ_PCIE);
+}
+
+static void rt3883_pci_irq_unmask(struct irq_data *d)
+{
+ int irq = d->irq;
+ u32 mask;
+ u32 t;
+
+ switch (irq) {
+ case RT3883_PCI_IRQ_PCI0:
+ mask = RT3833_PCI_PCIINT_PCI0;
+ break;
+ case RT3883_PCI_IRQ_PCI1:
+ mask = RT3833_PCI_PCIINT_PCI1;
+ break;
+ case RT3883_PCI_IRQ_PCIE:
+ mask = RT3833_PCI_PCIINT_PCIE;
+ break;
+ default:
+ BUG();
+ }
+
+ t = rt3883_pci_rr(RT3883_PCI_REG_PCIMSK_ADDR);
+ rt3883_pci_wr(t | mask, RT3883_PCI_REG_PCIMSK_ADDR);
+ /* flush write */
+ rt3883_pci_rr(RT3883_PCI_REG_PCIMSK_ADDR);
+}
+
+static void rt3883_pci_irq_mask(struct irq_data *d)
+{
+ int irq = d->irq;
+ u32 mask;
+ u32 t;
+
+ switch (irq) {
+ case RT3883_PCI_IRQ_PCI0:
+ mask = RT3833_PCI_PCIINT_PCI0;
+ break;
+ case RT3883_PCI_IRQ_PCI1:
+ mask = RT3833_PCI_PCIINT_PCI1;
+ break;
+ case RT3883_PCI_IRQ_PCIE:
+ mask = RT3833_PCI_PCIINT_PCIE;
+ break;
+ default:
+ BUG();
+ }
+
+ t = rt3883_pci_rr(RT3883_PCI_REG_PCIMSK_ADDR);
+ rt3883_pci_wr(t & ~mask, RT3883_PCI_REG_PCIMSK_ADDR);
+ /* flush write */
+ rt3883_pci_rr(RT3883_PCI_REG_PCIMSK_ADDR);
+}
+
+static struct irq_chip rt3883_pci_irq_chip = {
+ .name = "RT3883 PCI",
+ .irq_mask = rt3883_pci_irq_mask,
+ .irq_unmask = rt3883_pci_irq_unmask,
+ .irq_mask_ack = rt3883_pci_irq_mask,
+};
+
+static void __init rt3883_pci_irq_init(void)
+{
+ int i;
+
+ /* disable all interrupts */
+ rt3883_pci_wr(0, RT3883_PCI_REG_PCIMSK_ADDR);
+
+ for (i = RT3883_PCI_IRQ_BASE;
+ i < RT3883_PCI_IRQ_BASE + RT3883_PCI_IRQ_COUNT; i++) {
+ irq_set_chip_and_handler(i, &rt3883_pci_irq_chip,
+ handle_level_irq);
+ }
+
+ irq_set_chained_handler(RT3883_CPU_IRQ_PCI, rt3883_pci_irq_handler);
+}
+
+static int rt3883_pci_config_read(struct pci_bus *bus, unsigned int devfn,
+ int where, int size, u32 *val)
+{
+ unsigned long flags;
+ u32 address;
+ u32 data;
+
+ address = rt3883_pci_get_cfgaddr(bus->number, PCI_SLOT(devfn),
+ PCI_FUNC(devfn), where);
+
+ spin_lock_irqsave(&rt3883_pci_lock, flags);
+ rt3883_pci_wr(address, RT3883_PCI_REG_CONFIG_ADDR);
+ data = rt3883_pci_rr(RT3883_PCI_REG_CONFIG_DATA);
+ spin_unlock_irqrestore(&rt3883_pci_lock, flags);
+
+ switch (size) {
+ case 1:
+ *val = (data >> ((where & 3) << 3)) & 0xff;
+ break;
+ case 2:
+ *val = (data >> ((where & 3) << 3)) & 0xffff;
+ break;
+ case 4:
+ *val = data;
+ break;
+ }
+
+ return PCIBIOS_SUCCESSFUL;
+}
+
+static int rt3883_pci_config_write(struct pci_bus *bus, unsigned int devfn,
+ int where, int size, u32 val)
+{
+ unsigned long flags;
+ u32 address;
+ u32 data;
+
+ address = rt3883_pci_get_cfgaddr(bus->number, PCI_SLOT(devfn),
+ PCI_FUNC(devfn), where);
+
+ spin_lock_irqsave(&rt3883_pci_lock, flags);
+ rt3883_pci_wr(address, RT3883_PCI_REG_CONFIG_ADDR);
+ data = rt3883_pci_rr(RT3883_PCI_REG_CONFIG_DATA);
+
+ switch (size) {
+ case 1:
+ data = (data & ~(0xff << ((where & 3) << 3))) |
+ (val << ((where & 3) << 3));
+ break;
+ case 2:
+ data = (data & ~(0xffff << ((where & 3) << 3))) |
+ (val << ((where & 3) << 3));
+ break;
+ case 4:
+ data = val;
+ break;
+ }
+
+ rt3883_pci_wr(data, RT3883_PCI_REG_CONFIG_DATA);
+ spin_unlock_irqrestore(&rt3883_pci_lock, flags);
+
+ return PCIBIOS_SUCCESSFUL;
+}
+
+static struct pci_ops rt3883_pci_ops = {
+ .read = rt3883_pci_config_read,
+ .write = rt3883_pci_config_write,
+};
+
+static struct resource rt3883_pci_mem_resource = {
+ .name = "PCI MEM space",
+ .start = RT3883_PCI_MEM_BASE,
+ .end = RT3883_PCI_MEM_BASE + RT3883_PCI_MEM_SIZE - 1,
+ .flags = IORESOURCE_MEM,
+};
+
+static struct resource rt3883_pci_io_resource = {
+ .name = "PCI IO space",
+ .start = RT3883_PCI_IO_BASE,
+ .end = RT3883_PCI_IO_BASE + RT3883_PCI_IO_SIZE - 1,
+ .flags = IORESOURCE_IO,
+};
+
+static struct pci_controller rt3883_pci_controller = {
+ .pci_ops = &rt3883_pci_ops,
+ .mem_resource = &rt3883_pci_mem_resource,
+ .io_resource = &rt3883_pci_io_resource,
+};
+
+static void rt3883_pci_preinit(unsigned mode)
+{
+ u32 syscfg1;
+ u32 rstctrl;
+ u32 clkcfg1;
+
+ if (mode & RT3883_PCI_MODE_PCIE) {
+ u32 val;
+
+ val = rt3883_sysc_rr(RT3883_SYSC_REG_SYSCFG1);
+ val &= ~(0x30);
+ val |= (2 << 4);
+ rt3883_sysc_wr(val, RT3883_SYSC_REG_SYSCFG1);
+
+ val = rt3883_sysc_rr(RT3883_SYSC_REG_PCIE_CLK_GEN0);
+ val &= ~BIT(31);
+ rt3883_sysc_wr(val, RT3883_SYSC_REG_PCIE_CLK_GEN0);
+
+ val = rt3883_sysc_rr(RT3883_SYSC_REG_PCIE_CLK_GEN1);
+ val &= 0x80ffffff;
+ rt3883_sysc_wr(val, RT3883_SYSC_REG_PCIE_CLK_GEN1);
+
+ val = rt3883_sysc_rr(RT3883_SYSC_REG_PCIE_CLK_GEN1);
+ val |= 0xa << 24;
+ rt3883_sysc_wr(val, RT3883_SYSC_REG_PCIE_CLK_GEN1);
+
+ val = rt3883_sysc_rr(RT3883_SYSC_REG_PCIE_CLK_GEN0);
+ val |= BIT(31);
+ rt3883_sysc_wr(val, RT3883_SYSC_REG_PCIE_CLK_GEN0);
+
+ msleep(50);
+ }
+
+ syscfg1 = rt3883_sysc_rr(RT3883_SYSC_REG_SYSCFG1);
+ syscfg1 &= ~(RT3883_SYSCFG1_PCIE_RC_MODE |
+ RT3883_SYSCFG1_PCI_HOST_MODE);
+
+ rstctrl = rt3883_sysc_rr(RT3883_SYSC_REG_RSTCTRL);
+ rstctrl |= (RT3883_RSTCTRL_PCI | RT3883_RSTCTRL_PCIE);
+
+ clkcfg1 = rt3883_sysc_rr(RT3883_SYSC_REG_CLKCFG1);
+ clkcfg1 &= ~(RT3883_CLKCFG1_PCI_CLK_EN |
+ RT3883_CLKCFG1_PCIE_CLK_EN);
+
+ if (mode & RT3883_PCI_MODE_PCI) {
+ syscfg1 |= RT3883_SYSCFG1_PCI_HOST_MODE;
+ clkcfg1 |= RT3883_CLKCFG1_PCI_CLK_EN;
+ rstctrl &= ~RT3883_RSTCTRL_PCI;
+ }
+ if (mode & RT3883_PCI_MODE_PCIE) {
+ syscfg1 |= RT3883_SYSCFG1_PCI_HOST_MODE |
+ RT3883_SYSCFG1_PCIE_RC_MODE;
+ clkcfg1 |= RT3883_CLKCFG1_PCIE_CLK_EN;
+ rstctrl &= ~RT3883_RSTCTRL_PCIE;
+ }
+
+ rt3883_sysc_wr(syscfg1, RT3883_SYSC_REG_SYSCFG1);
+ rt3883_sysc_wr(rstctrl, RT3883_SYSC_REG_RSTCTRL);
+ rt3883_sysc_wr(clkcfg1, RT3883_SYSC_REG_CLKCFG1);
+
+ msleep(500);
+}
+
+static int rt3883_pcie_ready(void)
+{
+ u32 status;
+
+ msleep(500);
+
+ status = rt3883_pci_rr(RT3883_PCI_REG_STATUS(1));
+ if (status & BIT(0))
+ return 0;
+
+ /* TODO: reset PCIe and turn off PCIe clock */
+
+ return -ENODEV;
+}
+
+void __init rt3883_pci_init(unsigned mode)
+{
+ u32 val;
+ int err;
+
+ rt3883_pci_preinit(mode);
+
+ rt3883_pci_base = ioremap(RT3883_PCI_BASE, PAGE_SIZE);
+ if (rt3883_pci_base == NULL) {
+ pr_err("failed to ioremap PCI registers\n");
+ return;
+ }
+
+ rt3883_pci_wr(0, RT3883_PCI_REG_PCICFG_ADDR);
+ if (mode & RT3883_PCI_MODE_PCI)
+ rt3883_pci_wr(BIT(16), RT3883_PCI_REG_PCICFG_ADDR);
+
+ msleep(500);
+
+ if (mode & RT3883_PCI_MODE_PCIE) {
+ err = rt3883_pcie_ready();
+ if (err)
+ return;
+ }
+
+ if (mode & RT3883_PCI_MODE_PCI)
+ rt3883_pci_wr(0x79, RT3883_PCI_REG_ARBCTL);
+
+ rt3883_pci_wr(RT3883_PCI_MEM_BASE, RT3883_PCI_REG_MEMBASE);
+ rt3883_pci_wr(RT3883_PCI_IO_BASE, RT3883_PCI_REG_IOBASE);
+
+ /* PCI */
+ rt3883_pci_wr(0x03ff0000, RT3883_PCI_REG_BAR0SETUP_ADDR(0));
+ rt3883_pci_wr(RT3883_MEMORY_BASE, RT3883_PCI_REG_IMBASEBAR0_ADDR(0));
+ rt3883_pci_wr(0x08021814, RT3883_PCI_REG_ID(0));
+ rt3883_pci_wr(0x00800001, RT3883_PCI_REG_CLASS(0));
+ rt3883_pci_wr(0x28801814, RT3883_PCI_REG_SUBID(0));
+
+ /* PCIe */
+ rt3883_pci_wr(0x01ff0000, RT3883_PCI_REG_BAR0SETUP_ADDR(1));
+ rt3883_pci_wr(RT3883_MEMORY_BASE, RT3883_PCI_REG_IMBASEBAR0_ADDR(1));
+ rt3883_pci_wr(0x08021814, RT3883_PCI_REG_ID(1));
+ rt3883_pci_wr(0x06040001, RT3883_PCI_REG_CLASS(1));
+ rt3883_pci_wr(0x28801814, RT3883_PCI_REG_SUBID(1));
+
+ rt3883_pci_irq_init();
+
+ /* PCIe */
+ val = rt3883_pci_read_u32(0, 0x01, 0, PCI_COMMAND);
+ val |= 0x7;
+ rt3883_pci_write_u32(0, 0x01, 0, PCI_COMMAND, val);
+
+ /* PCI */
+ val = rt3883_pci_read_u32(0, 0x00, 0, PCI_COMMAND);
+ val |= 0x7;
+ rt3883_pci_write_u32(0, 0x00, 0, PCI_COMMAND, val);
+
+ ioport_resource.start = rt3883_pci_io_resource.start;
+ ioport_resource.end = rt3883_pci_io_resource.end;
+
+ register_pci_controller(&rt3883_pci_controller);
+}
+
+int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
+{
+ int irq = -1;
+
+ switch (dev->bus->number) {
+ case 0:
+ switch (PCI_SLOT(dev->devfn)) {
+ case 0x00:
+ rt3883_pci_wr(0x03ff0001,
+ RT3883_PCI_REG_BAR0SETUP_ADDR(0));
+ rt3883_pci_wr(0x03ff0001,
+ RT3883_PCI_REG_BAR0SETUP_ADDR(1));
+
+ rt3883_pci_write_u32(0, 0x00, 0, PCI_BASE_ADDRESS_0,
+ RT3883_MEMORY_BASE);
+ rt3883_pci_read_u32(0, 0x00, 0, PCI_BASE_ADDRESS_0);
+
+ irq = RT3883_CPU_IRQ_PCI;
+ break;
+ case 0x01:
+ rt3883_pci_write_u32(0, 0x01, 0, PCI_IO_BASE,
+ 0x00000101);
+ break;
+ case 0x11:
+ irq = RT3883_PCI_IRQ_PCI0;
+ break;
+ case 0x12:
+ irq = RT3883_PCI_IRQ_PCI1;
+ break;
+ }
+ break;
+
+ case 1:
+ irq = RT3883_PCI_IRQ_PCIE;
+ break;
+
+ default:
+ dev_err(&dev->dev, "no IRQ specified\n");
+ return irq;
+ }
+
+ return irq;
+}
+
+void __init rt3883_pci_set_plat_dev_init(int (*f)(struct pci_dev *dev))
+{
+ rt3883_pci_plat_dev_init = f;
+}
+
+int pcibios_plat_dev_init(struct pci_dev *dev)
+{
+ if (rt3883_pci_plat_dev_init)
+ return rt3883_pci_plat_dev_init(dev);
+
+ return 0;
+}
diff --git a/arch/mips/ralink/Kconfig b/arch/mips/ralink/Kconfig
index a3eec2a..2b7b70a 100644
--- a/arch/mips/ralink/Kconfig
+++ b/arch/mips/ralink/Kconfig
@@ -20,6 +20,7 @@ choice
bool "RT3883"
select USB_ARCH_HAS_OHCI
select USB_ARCH_HAS_EHCI
+ select HW_HAS_PCI
config SOC_MT7620
bool "MT7620"
--
1.7.10.4

View file

@ -0,0 +1,405 @@
From 8dd2c6ae6d9c858d9c4c4d55aa4bf180669ddfe9 Mon Sep 17 00:00:00 2001
From: John Crispin <blogic@openwrt.org>
Date: Tue, 22 Jan 2013 18:23:50 +0100
Subject: [PATCH 121/121] watchdog: adds ralink wdt
Adds the watchdog driver for ralink SoC.
Signed-off-by: John Crispin <blogic@openwrt.org>
---
drivers/watchdog/Kconfig | 6 +
drivers/watchdog/Makefile | 1 +
drivers/watchdog/ralink_wdt.c | 352 +++++++++++++++++++++++++++++++++++++++++
3 files changed, 359 insertions(+)
create mode 100644 drivers/watchdog/ralink_wdt.c
diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig
index 9fcc70c..c4b508e 100644
--- a/drivers/watchdog/Kconfig
+++ b/drivers/watchdog/Kconfig
@@ -1104,6 +1104,12 @@ config LANTIQ_WDT
help
Hardware driver for the Lantiq SoC Watchdog Timer.
+config RALINK_WDT
+ tristate "Ralink SoC watchdog"
+ depends on RALINK
+ help
+ Hardware driver for the Ralink SoC Watchdog Timer.
+
# PARISC Architecture
# POWERPC Architecture
diff --git a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile
index a300b94..3a8ad6a 100644
--- a/drivers/watchdog/Makefile
+++ b/drivers/watchdog/Makefile
@@ -134,6 +134,7 @@ obj-$(CONFIG_TXX9_WDT) += txx9wdt.o
obj-$(CONFIG_OCTEON_WDT) += octeon-wdt.o
octeon-wdt-y := octeon-wdt-main.o octeon-wdt-nmi.o
obj-$(CONFIG_LANTIQ_WDT) += lantiq_wdt.o
+obj-$(CONFIG_RALINK_WDT) += ralink_wdt.o
# PARISC Architecture
diff --git a/drivers/watchdog/ralink_wdt.c b/drivers/watchdog/ralink_wdt.c
new file mode 100644
index 0000000..8a8dc76
--- /dev/null
+++ b/drivers/watchdog/ralink_wdt.c
@@ -0,0 +1,352 @@
+/*
+ * Ralink RT288X/RT305X built-in hardware watchdog timer
+ *
+ * Copyright (C) 2011 Gabor Juhos <juhosg@openwrt.org>
+ *
+ * This driver was based on: drivers/watchdog/ixp4xx_wdt.c
+ * Author: Deepak Saxena <dsaxena@plexity.net>
+ * Copyright 2004 (c) MontaVista, Software, Inc.
+ *
+ * which again was based on sa1100 driver,
+ * Copyright (C) 2000 Oleg Drokin <green@crimea.edu>
+ *
+ * parts of the driver are based on Ralink's 2.6.21 BSP
+ *
+ * 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.
+ */
+
+#include <linux/bitops.h>
+#include <linux/errno.h>
+#include <linux/fs.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/miscdevice.h>
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/platform_device.h>
+#include <linux/types.h>
+#include <linux/watchdog.h>
+#include <linux/clk.h>
+#include <linux/err.h>
+
+#define DRIVER_NAME "ralink-wdt"
+
+#define RALINK_WDT_TIMEOUT 30 /* seconds */
+#define RALINK_WDT_PRESCALE 65536
+
+#define TIMER_REG_TMR1LOAD 0x00
+#define TIMER_REG_TMR1CTL 0x08
+
+#define TMRSTAT_TMR1RST BIT(5)
+
+#define TMR1CTL_ENABLE BIT(7)
+#define TMR1CTL_MODE_SHIFT 4
+#define TMR1CTL_MODE_MASK 0x3
+#define TMR1CTL_MODE_FREE_RUNNING 0x0
+#define TMR1CTL_MODE_PERIODIC 0x1
+#define TMR1CTL_MODE_TIMEOUT 0x2
+#define TMR1CTL_MODE_WDT 0x3
+#define TMR1CTL_PRESCALE_MASK 0xf
+#define TMR1CTL_PRESCALE_65536 0xf
+
+static int nowayout = WATCHDOG_NOWAYOUT;
+module_param(nowayout, int, 0);
+MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started "
+ "(default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
+
+static int ralink_wdt_timeout = RALINK_WDT_TIMEOUT;
+module_param_named(timeout, ralink_wdt_timeout, int, 0);
+MODULE_PARM_DESC(timeout, "Watchdog timeout in seconds, 0 means use maximum "
+ "(default=" __MODULE_STRING(RALINK_WDT_TIMEOUT) "s)");
+
+static unsigned long ralink_wdt_flags;
+
+#define WDT_FLAGS_BUSY 0
+#define WDT_FLAGS_EXPECT_CLOSE 1
+
+static struct clk *ralink_wdt_clk;
+static unsigned long ralink_wdt_freq;
+static int ralink_wdt_max_timeout;
+static void __iomem *ralink_wdt_base;
+
+static inline void rt_wdt_w32(unsigned reg, u32 val)
+{
+ __raw_writel(val, ralink_wdt_base + reg);
+}
+
+static inline u32 rt_wdt_r32(unsigned reg)
+{
+ return __raw_readl(ralink_wdt_base + reg);
+}
+
+static inline void ralink_wdt_keepalive(void)
+{
+ rt_wdt_w32(TIMER_REG_TMR1LOAD, ralink_wdt_timeout * ralink_wdt_freq);
+}
+
+static inline void ralink_wdt_enable(void)
+{
+ u32 t;
+
+ ralink_wdt_keepalive();
+
+ t = rt_wdt_r32(TIMER_REG_TMR1CTL);
+ t |= TMR1CTL_ENABLE;
+ rt_wdt_w32(TIMER_REG_TMR1CTL, t);
+}
+
+static inline void ralink_wdt_disable(void)
+{
+ u32 t;
+
+ ralink_wdt_keepalive();
+
+ t = rt_wdt_r32(TIMER_REG_TMR1CTL);
+ t &= ~TMR1CTL_ENABLE;
+ rt_wdt_w32(TIMER_REG_TMR1CTL, t);
+}
+
+static int ralink_wdt_set_timeout(int val)
+{
+ if (val < 1 || val > ralink_wdt_max_timeout) {
+ pr_warn(DRIVER_NAME
+ ": timeout value %d must be 0 < timeout <= %d, using %d\n",
+ val, ralink_wdt_max_timeout, ralink_wdt_timeout);
+ return -EINVAL;
+ }
+
+ ralink_wdt_timeout = val;
+ ralink_wdt_keepalive();
+
+ return 0;
+}
+
+static int ralink_wdt_open(struct inode *inode, struct file *file)
+{
+ u32 t;
+
+ if (test_and_set_bit(WDT_FLAGS_BUSY, &ralink_wdt_flags))
+ return -EBUSY;
+
+ clear_bit(WDT_FLAGS_EXPECT_CLOSE, &ralink_wdt_flags);
+
+ t = rt_wdt_r32(TIMER_REG_TMR1CTL);
+ t &= ~(TMR1CTL_MODE_MASK << TMR1CTL_MODE_SHIFT |
+ TMR1CTL_PRESCALE_MASK);
+ t |= (TMR1CTL_MODE_WDT << TMR1CTL_MODE_SHIFT |
+ TMR1CTL_PRESCALE_65536);
+ rt_wdt_w32(TIMER_REG_TMR1CTL, t);
+
+ ralink_wdt_enable();
+
+ return nonseekable_open(inode, file);
+}
+
+static int ralink_wdt_release(struct inode *inode, struct file *file)
+{
+ if (test_bit(WDT_FLAGS_EXPECT_CLOSE, &ralink_wdt_flags))
+ ralink_wdt_disable();
+ else {
+ pr_crit(DRIVER_NAME ": device closed unexpectedly, "
+ "watchdog timer will not stop!\n");
+ ralink_wdt_keepalive();
+ }
+
+ clear_bit(WDT_FLAGS_BUSY, &ralink_wdt_flags);
+ clear_bit(WDT_FLAGS_EXPECT_CLOSE, &ralink_wdt_flags);
+
+ return 0;
+}
+
+static ssize_t rt_wdt_w32ite(struct file *file, const char *data,
+ size_t len, loff_t *ppos)
+{
+ if (len) {
+ if (!nowayout) {
+ size_t i;
+
+ clear_bit(WDT_FLAGS_EXPECT_CLOSE, &ralink_wdt_flags);
+
+ for (i = 0; i != len; i++) {
+ char c;
+
+ if (get_user(c, data + i))
+ return -EFAULT;
+
+ if (c == 'V')
+ set_bit(WDT_FLAGS_EXPECT_CLOSE,
+ &ralink_wdt_flags);
+ }
+ }
+
+ ralink_wdt_keepalive();
+ }
+
+ return len;
+}
+
+static const struct watchdog_info ralink_wdt_info = {
+ .options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING |
+ WDIOF_MAGICCLOSE,
+ .firmware_version = 0,
+ .identity = "RALINK watchdog",
+};
+
+static long ralink_wdt_ioctl(struct file *file, unsigned int cmd,
+ unsigned long arg)
+{
+ void __user *argp = (void __user *)arg;
+ int __user *p = argp;
+ int err;
+ int t;
+
+ switch (cmd) {
+ case WDIOC_GETSUPPORT:
+ err = copy_to_user(argp, &ralink_wdt_info,
+ sizeof(ralink_wdt_info)) ? -EFAULT : 0;
+ break;
+
+ case WDIOC_GETSTATUS:
+ err = put_user(0, p);
+ break;
+
+ case WDIOC_KEEPALIVE:
+ ralink_wdt_keepalive();
+ err = 0;
+ break;
+
+ case WDIOC_SETTIMEOUT:
+ err = get_user(t, p);
+ if (err)
+ break;
+
+ err = ralink_wdt_set_timeout(t);
+ if (err)
+ break;
+
+ /* fallthrough */
+ case WDIOC_GETTIMEOUT:
+ err = put_user(ralink_wdt_timeout, p);
+ break;
+
+ default:
+ err = -ENOTTY;
+ break;
+ }
+
+ return err;
+}
+
+static const struct file_operations ralink_wdt_fops = {
+ .owner = THIS_MODULE,
+ .llseek = no_llseek,
+ .write = rt_wdt_w32ite,
+ .unlocked_ioctl = ralink_wdt_ioctl,
+ .open = ralink_wdt_open,
+ .release = ralink_wdt_release,
+};
+
+static struct miscdevice ralink_wdt_miscdev = {
+ .minor = WATCHDOG_MINOR,
+ .name = "watchdog",
+ .fops = &ralink_wdt_fops,
+};
+
+static int ralink_wdt_probe(struct platform_device *pdev)
+{
+ struct resource *res;
+ int err;
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!res) {
+ dev_err(&pdev->dev, "no memory resource found\n");
+ return -EINVAL;
+ }
+
+ ralink_wdt_base = ioremap(res->start, resource_size(res));
+ if (!ralink_wdt_base)
+ return -ENOMEM;
+
+ ralink_wdt_clk = clk_get(&pdev->dev, NULL);
+ if (IS_ERR(ralink_wdt_clk)) {
+ err = PTR_ERR(ralink_wdt_clk);
+ goto err_unmap;
+ }
+
+ err = clk_enable(ralink_wdt_clk);
+ if (err)
+ goto err_clk_put;
+
+ ralink_wdt_freq = clk_get_rate(ralink_wdt_clk) / RALINK_WDT_PRESCALE;
+ if (!ralink_wdt_freq) {
+ err = -EINVAL;
+ goto err_clk_disable;
+ }
+
+ ralink_wdt_max_timeout = (0xfffful / ralink_wdt_freq);
+ if (ralink_wdt_timeout < 1 ||
+ ralink_wdt_timeout > ralink_wdt_max_timeout) {
+ ralink_wdt_timeout = ralink_wdt_max_timeout;
+ dev_info(&pdev->dev,
+ "timeout value must be 0 < timeout <= %d, using %d\n",
+ ralink_wdt_max_timeout, ralink_wdt_timeout);
+ }
+
+ err = misc_register(&ralink_wdt_miscdev);
+ if (err) {
+ dev_err(&pdev->dev,
+ "unable to register misc device, err=%d\n", err);
+ goto err_clk_disable;
+ }
+
+ return 0;
+
+err_clk_disable:
+ clk_disable(ralink_wdt_clk);
+err_clk_put:
+ clk_put(ralink_wdt_clk);
+err_unmap:
+ iounmap(ralink_wdt_base);
+ return err;
+}
+
+static int ralink_wdt_remove(struct platform_device *pdev)
+{
+ misc_deregister(&ralink_wdt_miscdev);
+ clk_disable(ralink_wdt_clk);
+ clk_put(ralink_wdt_clk);
+ iounmap(ralink_wdt_base);
+ return 0;
+}
+
+static void ralink_wdt_shutdown(struct platform_device *pdev)
+{
+ ralink_wdt_disable();
+}
+
+static const struct of_device_id ralink_wdt_match[] = {
+ { .compatible = "ralink,rt2880-wdt" },
+ {},
+};
+MODULE_DEVICE_TABLE(of, ralink_wdt_match);
+
+static struct platform_driver ralink_wdt_driver = {
+ .probe = ralink_wdt_probe,
+ .remove = ralink_wdt_remove,
+ .shutdown = ralink_wdt_shutdown,
+ .driver = {
+ .name = DRIVER_NAME,
+ .owner = THIS_MODULE,
+ .of_match_table = ralink_wdt_match,
+ },
+};
+
+module_platform_driver(ralink_wdt_driver);
+
+MODULE_DESCRIPTION("MediaTek/Ralink RT288X/RT305X hardware watchdog driver");
+MODULE_AUTHOR("Gabor Juhos <juhosg@openwrt.org");
+MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("platform:" DRIVER_NAME);
+MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);
--
1.7.10.4

View file

@ -0,0 +1,107 @@
From 0184f7b64c68fe9606559e86bdd288de01c87a85 Mon Sep 17 00:00:00 2001
From: John Crispin <blogic@openwrt.org>
Date: Sun, 17 Mar 2013 10:30:48 +0100
Subject: [PATCH 200/208] MIPS: read the mips_machine name from OF and output
it in /proc/cpuinfo
This allows the userland to be compatible to the devive probing of mips_machine.
Signed-off-by: John Crispin <blogic@openwrt.org>
---
arch/mips/include/asm/prom.h | 3 +++
arch/mips/kernel/proc.c | 6 +++++-
arch/mips/kernel/prom.c | 24 ++++++++++++++++++++++++
3 files changed, 32 insertions(+), 1 deletion(-)
diff --git a/arch/mips/include/asm/prom.h b/arch/mips/include/asm/prom.h
index 8808bf5..a4ad354 100644
--- a/arch/mips/include/asm/prom.h
+++ b/arch/mips/include/asm/prom.h
@@ -44,8 +44,11 @@ extern void __dt_setup_arch(struct boot_param_header *bph);
__dt_setup_arch(&__dtb_##sym##_begin); \
})
+extern char *of_mips_get_machine_name(void);
+
#else /* CONFIG_OF */
static inline void device_tree_init(void) { }
+static char *of_mips_get_machine_name(void) { return NULL; }
#endif /* CONFIG_OF */
#endif /* __ASM_PROM_H */
diff --git a/arch/mips/kernel/proc.c b/arch/mips/kernel/proc.c
index 135c4aa..9ab3d13 100644
--- a/arch/mips/kernel/proc.c
+++ b/arch/mips/kernel/proc.c
@@ -12,6 +12,7 @@
#include <asm/cpu-features.h>
#include <asm/mipsregs.h>
#include <asm/processor.h>
+#include <asm/prom.h>
#include <asm/mips_machine.h>
unsigned int vced_count, vcei_count;
@@ -34,7 +35,10 @@ static int show_cpuinfo(struct seq_file *m, void *v)
*/
if (n == 0) {
seq_printf(m, "system type\t\t: %s\n", get_system_type());
- if (mips_get_machine_name())
+ if (of_mips_get_machine_name())
+ seq_printf(m, "machine\t\t\t: %s\n",
+ of_mips_get_machine_name());
+ else if (mips_get_machine_name())
seq_printf(m, "machine\t\t\t: %s\n",
mips_get_machine_name());
}
diff --git a/arch/mips/kernel/prom.c b/arch/mips/kernel/prom.c
index 028f6f8..1aa68a2 100644
--- a/arch/mips/kernel/prom.c
+++ b/arch/mips/kernel/prom.c
@@ -23,6 +23,13 @@
#include <asm/page.h>
#include <asm/prom.h>
+static char of_mips_machine_name[64] = "Unknown";
+
+char *of_mips_get_machine_name(void)
+{
+ return of_mips_machine_name;
+}
+
int __init early_init_dt_scan_memory_arch(unsigned long node,
const char *uname, int depth,
void *data)
@@ -50,6 +57,20 @@ void __init early_init_dt_setup_initrd_arch(unsigned long start,
}
#endif
+int __init early_init_dt_scan_model(unsigned long node,
+ const char *uname, int depth,
+ void *data)
+{
+ if (!depth) {
+ char *model = of_get_flat_dt_prop(node, "model", NULL);
+ if (model) {
+ snprintf(of_mips_machine_name, sizeof(of_mips_machine_name), model);
+ pr_info("MIPS: machine is %s\n", of_mips_machine_name);
+ }
+ }
+ return 0;
+}
+
void __init early_init_devtree(void *params)
{
/* Setup flat device-tree pointer */
@@ -65,6 +86,9 @@ void __init early_init_devtree(void *params)
/* Scan memory nodes */
of_scan_flat_dt(early_init_dt_scan_root, NULL);
of_scan_flat_dt(early_init_dt_scan_memory_arch, NULL);
+
+ /* try to load the mips machine name */
+ of_scan_flat_dt(early_init_dt_scan_model, NULL);
}
void __init __dt_setup_arch(struct boot_param_header *bph)
--
1.7.10.4

View file

@ -0,0 +1,83 @@
From 1809af0f73208ec67363347ddf5370e1f08222e8 Mon Sep 17 00:00:00 2001
From: John Crispin <blogic@openwrt.org>
Date: Sun, 17 Mar 2013 09:29:15 +0100
Subject: [PATCH 201/208] owrt: OF: NET: add of_get_mac_address_mtd()
Many embedded devices have information such as mac addresses stored inside mtd
devices. This patch allows us to add a property inside a node describing a
network interface. The new property points at a mtd partition with an offset
where the mac address can be found.
Signed-off-by: John Crispin <blogic@openwrt.org>
---
drivers/of/of_net.c | 37 +++++++++++++++++++++++++++++++++++++
include/linux/of_net.h | 1 +
2 files changed, 38 insertions(+)
diff --git a/drivers/of/of_net.c b/drivers/of/of_net.c
index ffab033..15f4a71 100644
--- a/drivers/of/of_net.c
+++ b/drivers/of/of_net.c
@@ -10,6 +10,7 @@
#include <linux/of_net.h>
#include <linux/phy.h>
#include <linux/export.h>
+#include <linux/mtd/mtd.h>
/**
* It maps 'enum phy_interface_t' found in include/linux/phy.h
@@ -92,3 +93,39 @@ const void *of_get_mac_address(struct device_node *np)
return NULL;
}
EXPORT_SYMBOL(of_get_mac_address);
+
+int of_get_mac_address_mtd(struct device_node *np, void *mac)
+{
+ struct device_node *mtd_np = NULL;
+ size_t retlen;
+ int size, ret;
+ struct mtd_info *mtd;
+ const char *part;
+ const __be32 *list;
+ phandle phandle;
+
+ list = of_get_property(np, "mtd-mac-address", &size);
+ if (!list || (size != (2 * sizeof(*list))))
+ return -ENOENT;
+
+ phandle = be32_to_cpup(list++);
+ if (phandle)
+ mtd_np = of_find_node_by_phandle(phandle);
+
+ if (!mtd_np)
+ return -ENOENT;
+
+ part = of_get_property(mtd_np, "label", NULL);
+ if (!part)
+ part = mtd_np->name;
+
+ mtd = get_mtd_device_nm(part);
+ if (IS_ERR(mtd))
+ return PTR_ERR(mtd);
+
+ ret = mtd_read(mtd, be32_to_cpup(list), 6, &retlen, (u_char *) mac);
+ put_mtd_device(mtd);
+
+ return ret;
+}
+EXPORT_SYMBOL_GPL(of_get_mac_address_mtd);
diff --git a/include/linux/of_net.h b/include/linux/of_net.h
index f474641..9d3304f 100644
--- a/include/linux/of_net.h
+++ b/include/linux/of_net.h
@@ -11,6 +11,7 @@
#include <linux/of.h>
extern const int of_get_phy_mode(struct device_node *np);
extern const void *of_get_mac_address(struct device_node *np);
+extern int of_get_mac_address_mtd(struct device_node *np, void *mac);
#endif
#endif /* __LINUX_OF_NET_H */
--
1.7.10.4

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,66 @@
From 3c99a50d689cb4811b13b9810d18c9316587216f Mon Sep 17 00:00:00 2001
From: John Crispin <blogic@openwrt.org>
Date: Mon, 18 Mar 2013 20:51:21 +0100
Subject: [PATCH 203/208] owrt: OF: USB: add OF binding for ehci and ohci
platform driver
Make ohci-platform and ehci-platform loadable from OF.
Signed-off-by: John Crispin <blogic@openwrt.org>
---
drivers/usb/host/ehci-platform.c | 7 +++++++
drivers/usb/host/ohci-platform.c | 7 +++++++
2 files changed, 14 insertions(+)
diff --git a/drivers/usb/host/ehci-platform.c b/drivers/usb/host/ehci-platform.c
index ca75063..fdddce1 100644
--- a/drivers/usb/host/ehci-platform.c
+++ b/drivers/usb/host/ehci-platform.c
@@ -183,6 +183,12 @@ static int ehci_platform_resume(struct device *dev)
#define ehci_platform_resume NULL
#endif /* CONFIG_PM */
+static const struct of_device_id ehci_match_table[] = {
+ { .compatible = "ehci-platform" },
+ {},
+};
+MODULE_DEVICE_TABLE(of, ehci_match_table);
+
static const struct platform_device_id ehci_platform_table[] = {
{ "ehci-platform", 0 },
{ }
@@ -203,6 +209,7 @@ static struct platform_driver ehci_platform_driver = {
.owner = THIS_MODULE,
.name = "ehci-platform",
.pm = &ehci_platform_pm_ops,
+ .of_match_table = ehci_match_table,
}
};
diff --git a/drivers/usb/host/ohci-platform.c b/drivers/usb/host/ohci-platform.c
index c3e7287..6d7d30b 100644
--- a/drivers/usb/host/ohci-platform.c
+++ b/drivers/usb/host/ohci-platform.c
@@ -201,6 +201,12 @@ static int ohci_platform_resume(struct device *dev)
#define ohci_platform_resume NULL
#endif /* CONFIG_PM */
+static const struct of_device_id ohci_match_table[] = {
+ { .compatible = "ohci-platform" },
+ {},
+};
+MODULE_DEVICE_TABLE(of, ohci_match_table);
+
static const struct platform_device_id ohci_platform_table[] = {
{ "ohci-platform", 0 },
{ }
@@ -221,5 +227,6 @@ static struct platform_driver ohci_platform_driver = {
.owner = THIS_MODULE,
.name = "ohci-platform",
.pm = &ohci_platform_pm_ops,
+ .of_match_table = ohci_match_table,
}
};
--
1.7.10.4

View file

@ -0,0 +1,328 @@
From d7e679017ec92824145b275572f6ef83d461f076 Mon Sep 17 00:00:00 2001
From: John Crispin <blogic@openwrt.org>
Date: Tue, 19 Mar 2013 09:26:22 +0100
Subject: [PATCH 204/208] owrt: MIPS: ralink: add usb platform support
Add code to load the platform ehci/ohci driver on Ralink SoC. For the usb core
to work we need to populate the platform_data during boot, prior to the usb
driver being loaded.
Signed-off-by: John Crispin <blogic@openwrt.org>
---
arch/mips/ralink/Makefile | 4 +-
arch/mips/ralink/common.h | 1 +
arch/mips/ralink/mt7620.c | 5 ++
arch/mips/ralink/of.c | 1 +
arch/mips/ralink/rt305x-usb.c | 120 +++++++++++++++++++++++++++++++++++++++++
arch/mips/ralink/rt3883-usb.c | 118 ++++++++++++++++++++++++++++++++++++++++
6 files changed, 247 insertions(+), 2 deletions(-)
create mode 100644 arch/mips/ralink/rt305x-usb.c
create mode 100644 arch/mips/ralink/rt3883-usb.c
diff --git a/arch/mips/ralink/Makefile b/arch/mips/ralink/Makefile
index cae7d88..8572538 100644
--- a/arch/mips/ralink/Makefile
+++ b/arch/mips/ralink/Makefile
@@ -9,8 +9,8 @@
obj-y := prom.o of.o reset.o clk.o irq.o pinmux.o timer.o
obj-$(CONFIG_SOC_RT288X) += rt288x.o
-obj-$(CONFIG_SOC_RT305X) += rt305x.o
-obj-$(CONFIG_SOC_RT3883) += rt3883.o
+obj-$(CONFIG_SOC_RT305X) += rt305x.o rt305x-usb.o
+obj-$(CONFIG_SOC_RT3883) += rt3883.o rt3883-usb.o
obj-$(CONFIG_SOC_MT7620) += mt7620.o
obj-$(CONFIG_EARLY_PRINTK) += early_printk.o
diff --git a/arch/mips/ralink/common.h b/arch/mips/ralink/common.h
index ed99f23..14a101c 100644
--- a/arch/mips/ralink/common.h
+++ b/arch/mips/ralink/common.h
@@ -43,5 +43,6 @@ extern void prom_soc_init(struct ralink_soc_info *soc_info);
__iomem void *plat_of_remap_node(const char *node);
void ralink_pinmux(void);
+void ralink_usb_platform(void);
#endif /* _RALINK_COMMON_H__ */
diff --git a/arch/mips/ralink/mt7620.c b/arch/mips/ralink/mt7620.c
index 9d0dc8b..19b28c5 100644
--- a/arch/mips/ralink/mt7620.c
+++ b/arch/mips/ralink/mt7620.c
@@ -146,6 +146,11 @@ struct ralink_pinmux rt_pinmux = {
// .wdt_reset = rt305x_wdt_reset,
};
+void ralink_usb_platform(void)
+{
+
+}
+
void __init ralink_clk_init(void)
{
unsigned long cpu_rate, sys_rate;
diff --git a/arch/mips/ralink/of.c b/arch/mips/ralink/of.c
index ecf1482..f438145 100644
--- a/arch/mips/ralink/of.c
+++ b/arch/mips/ralink/of.c
@@ -102,6 +102,7 @@ static int __init plat_of_setup(void)
panic("failed to populate DT\n");
ralink_pinmux();
+ ralink_usb_platform();
return 0;
}
diff --git a/arch/mips/ralink/rt305x-usb.c b/arch/mips/ralink/rt305x-usb.c
new file mode 100644
index 0000000..793fc82
--- /dev/null
+++ b/arch/mips/ralink/rt305x-usb.c
@@ -0,0 +1,120 @@
+/*
+ * 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) 2008-2011 Gabor Juhos <juhosg@openwrt.org>
+ * Copyright (C) 2013 John Crispin <blogic@openwrt.org>
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/module.h>
+
+#include <linux/delay.h>
+#include <linux/of_platform.h>
+#include <linux/dma-mapping.h>
+#include <linux/usb/ehci_pdriver.h>
+#include <linux/usb/ohci_pdriver.h>
+
+#include <asm/mach-ralink/ralink_regs.h>
+#include <asm/mach-ralink/rt305x.h>
+
+static atomic_t rt3352_usb_pwr_ref = ATOMIC_INIT(0);
+
+static int rt3352_usb_power_on(struct platform_device *pdev)
+{
+
+ if (atomic_inc_return(&rt3352_usb_pwr_ref) == 1) {
+ u32 t;
+
+ t = rt_sysc_r32(RT3352_SYSC_REG_USB_PS);
+
+ /* enable clock for port0's and port1's phys */
+ t = rt_sysc_r32(RT3352_SYSC_REG_CLKCFG1);
+ t |= RT3352_CLKCFG1_UPHY0_CLK_EN | RT3352_CLKCFG1_UPHY1_CLK_EN;
+ rt_sysc_w32(t, RT3352_SYSC_REG_CLKCFG1);
+ mdelay(500);
+
+ /* pull USBHOST and USBDEV out from reset */
+ t = rt_sysc_r32(RT3352_SYSC_REG_RSTCTRL);
+ t &= ~(RT3352_RSTCTRL_UHST | RT3352_RSTCTRL_UDEV);
+ rt_sysc_w32(t, RT3352_SYSC_REG_RSTCTRL);
+ mdelay(500);
+
+ /* enable host mode */
+ t = rt_sysc_r32(RT3352_SYSC_REG_SYSCFG1);
+ t |= RT3352_SYSCFG1_USB0_HOST_MODE;
+ rt_sysc_w32(t, RT3352_SYSC_REG_SYSCFG1);
+
+ t = rt_sysc_r32(RT3352_SYSC_REG_USB_PS);
+ }
+
+ return 0;
+}
+
+static void rt3352_usb_power_off(struct platform_device *pdev)
+{
+ if (atomic_dec_return(&rt3352_usb_pwr_ref) == 0) {
+ u32 t;
+
+ /* put USBHOST and USBDEV into reset */
+ t = rt_sysc_r32(RT3352_SYSC_REG_RSTCTRL);
+ t |= RT3352_RSTCTRL_UHST | RT3352_RSTCTRL_UDEV;
+ rt_sysc_w32(t, RT3352_SYSC_REG_RSTCTRL);
+ udelay(10000);
+
+ /* disable clock for port0's and port1's phys*/
+ t = rt_sysc_r32(RT3352_SYSC_REG_CLKCFG1);
+ t &= ~(RT3352_CLKCFG1_UPHY0_CLK_EN | RT3352_CLKCFG1_UPHY1_CLK_EN);
+ rt_sysc_w32(t, RT3352_SYSC_REG_CLKCFG1);
+ udelay(10000);
+ }
+}
+
+static struct usb_ehci_pdata rt3352_ehci_data = {
+ .power_on = rt3352_usb_power_on,
+ .power_off = rt3352_usb_power_off,
+};
+
+static struct usb_ohci_pdata rt3352_ohci_data = {
+ .power_on = rt3352_usb_power_on,
+ .power_off = rt3352_usb_power_off,
+};
+
+static void ralink_add_usb(char *name, void *pdata, u64 *mask)
+{
+ struct device_node *node;
+ struct platform_device *pdev;
+
+ node = of_find_compatible_node(NULL, NULL, name);
+ if (!node)
+ return;
+
+ pdev = of_find_device_by_node(node);
+ if (!pdev)
+ goto error_out;
+
+ if (pdata)
+ pdev->dev.platform_data = pdata;
+ if (mask) {
+ pdev->dev.dma_mask = mask;
+ pdev->dev.coherent_dma_mask = *mask;
+ }
+
+error_out:
+ of_node_put(node);
+}
+
+static u64 rt3352_ohci_dmamask = DMA_BIT_MASK(32);
+static u64 rt3352_ehci_dmamask = DMA_BIT_MASK(32);
+
+void ralink_usb_platform(void)
+{
+ if (soc_is_rt3352() || soc_is_rt5350()) {
+ ralink_add_usb("ohci-platform",
+ &rt3352_ohci_data, &rt3352_ohci_dmamask);
+ ralink_add_usb("ehci-platform",
+ &rt3352_ehci_data, &rt3352_ehci_dmamask);
+ }
+}
diff --git a/arch/mips/ralink/rt3883-usb.c b/arch/mips/ralink/rt3883-usb.c
new file mode 100644
index 0000000..1d948a9
--- /dev/null
+++ b/arch/mips/ralink/rt3883-usb.c
@@ -0,0 +1,118 @@
+/*
+ * 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) 2008-2011 Gabor Juhos <juhosg@openwrt.org>
+ * Copyright (C) 2013 John Crispin <blogic@openwrt.org>
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/module.h>
+
+#include <linux/delay.h>
+#include <linux/of_platform.h>
+#include <linux/dma-mapping.h>
+#include <linux/usb/ehci_pdriver.h>
+#include <linux/usb/ohci_pdriver.h>
+
+#include <asm/mach-ralink/ralink_regs.h>
+#include <asm/mach-ralink/rt3883.h>
+
+static atomic_t rt3883_usb_pwr_ref = ATOMIC_INIT(0);
+
+static int rt3883_usb_power_on(struct platform_device *pdev)
+{
+ if (atomic_inc_return(&rt3883_usb_pwr_ref) == 1) {
+ u32 t;
+
+ t = rt_sysc_r32(RT3883_SYSC_REG_USB_PS);
+
+ /* enable clock for port0's and port1's phys */
+ t = rt_sysc_r32(RT3883_SYSC_REG_CLKCFG1);
+ t |= RT3883_CLKCFG1_UPHY0_CLK_EN | RT3883_CLKCFG1_UPHY1_CLK_EN;
+ rt_sysc_w32(t, RT3883_SYSC_REG_CLKCFG1);
+ mdelay(500);
+
+ /* pull USBHOST and USBDEV out from reset */
+ t = rt_sysc_r32(RT3883_SYSC_REG_RSTCTRL);
+ t &= ~(RT3883_RSTCTRL_UHST | RT3883_RSTCTRL_UDEV);
+ rt_sysc_w32(t, RT3883_SYSC_REG_RSTCTRL);
+ mdelay(500);
+
+ /* enable host mode */
+ t = rt_sysc_r32(RT3883_SYSC_REG_SYSCFG1);
+ t |= RT3883_SYSCFG1_USB0_HOST_MODE;
+ rt_sysc_w32(t, RT3883_SYSC_REG_SYSCFG1);
+
+ t = rt_sysc_r32(RT3883_SYSC_REG_USB_PS);
+ }
+
+ return 0;
+}
+
+static void rt3883_usb_power_off(struct platform_device *pdev)
+{
+ if (atomic_dec_return(&rt3883_usb_pwr_ref) == 0) {
+ u32 t;
+
+ /* put USBHOST and USBDEV into reset */
+ t = rt_sysc_r32(RT3883_SYSC_REG_RSTCTRL);
+ t |= RT3883_RSTCTRL_UHST | RT3883_RSTCTRL_UDEV;
+ rt_sysc_w32(t, RT3883_SYSC_REG_RSTCTRL);
+ udelay(10000);
+
+ /* disable clock for port0's and port1's phys*/
+ t = rt_sysc_r32(RT3883_SYSC_REG_CLKCFG1);
+ t &= ~(RT3883_CLKCFG1_UPHY0_CLK_EN |
+ RT3883_CLKCFG1_UPHY1_CLK_EN);
+ rt_sysc_w32(t, RT3883_SYSC_REG_CLKCFG1);
+ udelay(10000);
+ }
+}
+
+static struct usb_ohci_pdata rt3883_ohci_data = {
+ .power_on = rt3883_usb_power_on,
+ .power_off = rt3883_usb_power_off,
+};
+
+static struct usb_ehci_pdata rt3883_ehci_data = {
+ .power_on = rt3883_usb_power_on,
+ .power_off = rt3883_usb_power_off,
+};
+
+static void ralink_add_usb(char *name, void *pdata, u64 *mask)
+{
+ struct device_node *node;
+ struct platform_device *pdev;
+
+ node = of_find_compatible_node(NULL, NULL, name);
+ if (!node)
+ return;
+
+ pdev = of_find_device_by_node(node);
+ if (!pdev)
+ goto error_out;
+
+ if (pdata)
+ pdev->dev.platform_data = pdata;
+ if (mask) {
+ pdev->dev.dma_mask = mask;
+ pdev->dev.coherent_dma_mask = *mask;
+ }
+
+error_out:
+ of_node_put(node);
+}
+
+static u64 rt3883_ohci_dmamask = DMA_BIT_MASK(32);
+static u64 rt3883_ehci_dmamask = DMA_BIT_MASK(32);
+
+void ralink_usb_platform(void)
+{
+ ralink_add_usb("ohci-platform",
+ &rt3883_ohci_data, &rt3883_ohci_dmamask);
+ ralink_add_usb("ehci-platform",
+ &rt3883_ehci_data, &rt3883_ehci_dmamask);
+}
--
1.7.10.4

View file

@ -0,0 +1,61 @@
From 6beb1af1b1475478c8f275b9579c9ebe4dad2904 Mon Sep 17 00:00:00 2001
From: John Crispin <blogic@openwrt.org>
Date: Tue, 19 Mar 2013 10:16:42 +0100
Subject: [PATCH 205/208] owrt: MIPS: add OWRTDTB secion
Signed-off-by: John Crispin <blogic@openwrt.org>
---
arch/mips/kernel/head.S | 3 +++
arch/mips/ralink/Makefile | 2 +-
arch/mips/ralink/of.c | 4 +++-
3 files changed, 7 insertions(+), 2 deletions(-)
diff --git a/arch/mips/kernel/head.S b/arch/mips/kernel/head.S
index c61cdae..b4e55bb 100644
--- a/arch/mips/kernel/head.S
+++ b/arch/mips/kernel/head.S
@@ -140,6 +140,9 @@ FEXPORT(__kernel_entry)
j kernel_entry
#endif
+ .ascii "OWRTDTB:"
+ EXPORT(__image_dtb)
+ .fill 0x4000
__REF
NESTED(kernel_entry, 16, sp) # kernel entry point
diff --git a/arch/mips/ralink/Makefile b/arch/mips/ralink/Makefile
index 8572538..9e58aa1 100644
--- a/arch/mips/ralink/Makefile
+++ b/arch/mips/ralink/Makefile
@@ -15,4 +15,4 @@ obj-$(CONFIG_SOC_MT7620) += mt7620.o
obj-$(CONFIG_EARLY_PRINTK) += early_printk.o
-obj-y += dts/
+#obj-y += dts/
diff --git a/arch/mips/ralink/of.c b/arch/mips/ralink/of.c
index f438145..ee998b7 100644
--- a/arch/mips/ralink/of.c
+++ b/arch/mips/ralink/of.c
@@ -76,6 +76,8 @@ void __init device_tree_init(void)
free_bootmem(base, size);
}
+extern struct boot_param_header __image_dtb;
+
void __init plat_mem_setup(void)
{
set_io_port_base(KSEG1);
@@ -84,7 +86,7 @@ void __init plat_mem_setup(void)
* Load the builtin devicetree. This causes the chosen node to be
* parsed resulting in our memory appearing
*/
- __dt_setup_arch(&__dtb_start);
+ __dt_setup_arch(&__image_dtb);
}
static int __init plat_of_setup(void)
--
1.7.10.4

View file

@ -0,0 +1,306 @@
From b35a0a294d39316c20f85004335c02f33a70ab68 Mon Sep 17 00:00:00 2001
From: John Crispin <blogic@openwrt.org>
Date: Sun, 24 Mar 2013 17:17:17 +0100
Subject: [PATCH 206/208] owrt: MIPS: ralink: add pseudo pwm led trigger based
on timer0
Signed-off-by: John Crispin <blogic@openwrt.org>
---
arch/mips/ralink/timer.c | 213 ++++++++++++++++++++++++++++++++++++++++++----
1 file changed, 197 insertions(+), 16 deletions(-)
diff --git a/arch/mips/ralink/timer.c b/arch/mips/ralink/timer.c
index 9a943e8..33b2a04 100644
--- a/arch/mips/ralink/timer.c
+++ b/arch/mips/ralink/timer.c
@@ -12,6 +12,8 @@
#include <linux/timer.h>
#include <linux/of_gpio.h>
#include <linux/clk.h>
+#include <linux/leds.h>
+#include <linux/slab.h>
#include <asm/mach-ralink/ralink_regs.h>
@@ -23,16 +25,34 @@
#define TMR0CTL_ENABLE BIT(7)
#define TMR0CTL_MODE_PERIODIC BIT(4)
-#define TMR0CTL_PRESCALER 1
+#define TMR0CTL_PRESCALER 2
#define TMR0CTL_PRESCALE_VAL (0xf - TMR0CTL_PRESCALER)
#define TMR0CTL_PRESCALE_DIV (65536 / BIT(TMR0CTL_PRESCALER))
+struct rt_timer_gpio {
+ struct list_head list;
+ struct led_classdev *led;
+};
+
struct rt_timer {
- struct device *dev;
- void __iomem *membase;
- int irq;
- unsigned long timer_freq;
- unsigned long timer_div;
+ struct device *dev;
+ void __iomem *membase;
+ int irq;
+
+ unsigned long timer_freq;
+ unsigned long timer_div;
+
+ struct list_head gpios;
+ struct led_trigger led_trigger;
+ unsigned int duty_cycle;
+ unsigned int duty;
+
+ unsigned int fade;
+ unsigned int fade_min;
+ unsigned int fade_max;
+ unsigned int fade_speed;
+ unsigned int fade_dir;
+ unsigned int fade_count;
};
static inline void rt_timer_w32(struct rt_timer *rt, u8 reg, u32 val)
@@ -48,18 +68,46 @@ static inline u32 rt_timer_r32(struct rt_timer *rt, u8 reg)
static irqreturn_t rt_timer_irq(int irq, void *_rt)
{
struct rt_timer *rt = (struct rt_timer *) _rt;
+ struct rt_timer_gpio *gpio;
+ unsigned int val;
- rt_timer_w32(rt, TIMER_REG_TMR0LOAD, rt->timer_freq / rt->timer_div);
+ if (rt->fade && (rt->fade_count++ > rt->fade_speed)) {
+ rt->fade_count = 0;
+ if (rt->duty_cycle <= rt->fade_min)
+ rt->fade_dir = 1;
+ else if (rt->duty_cycle >= rt->fade_max)
+ rt->fade_dir = 0;
+
+ if (rt->fade_dir)
+ rt->duty_cycle += 1;
+ else
+ rt->duty_cycle -= 1;
+
+ }
+
+ val = rt->timer_freq / rt->timer_div;
+ if (rt->duty)
+ val *= rt->duty_cycle;
+ else
+ val *= (100 - rt->duty_cycle);
+ val /= 100;
+
+ if (!list_empty(&rt->gpios))
+ list_for_each_entry(gpio, &rt->gpios, list)
+ led_set_brightness(gpio->led, !!rt->duty);
+
+ rt->duty = !rt->duty;
+
+ rt_timer_w32(rt, TIMER_REG_TMR0LOAD, val + 1);
rt_timer_w32(rt, TIMER_REG_TMRSTAT, TMRSTAT_TMR0INT);
return IRQ_HANDLED;
}
-
static int rt_timer_request(struct rt_timer *rt)
{
- int err = request_irq(rt->irq, rt_timer_irq, IRQF_DISABLED,
- dev_name(rt->dev), rt);
+ int err = devm_request_irq(rt->dev, rt->irq, rt_timer_irq,
+ IRQF_DISABLED, dev_name(rt->dev), rt);
if (err) {
dev_err(rt->dev, "failed to request irq\n");
} else {
@@ -81,8 +129,6 @@ static int rt_timer_config(struct rt_timer *rt, unsigned long divisor)
else
rt->timer_div = divisor;
- rt_timer_w32(rt, TIMER_REG_TMR0LOAD, rt->timer_freq / rt->timer_div);
-
return 0;
}
@@ -108,11 +154,128 @@ static void rt_timer_disable(struct rt_timer *rt)
rt_timer_w32(rt, TIMER_REG_TMR0CTL, t);
}
+static ssize_t led_fade_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct led_classdev *led_cdev = dev_get_drvdata(dev);
+ struct rt_timer *rt = container_of(led_cdev->trigger, struct rt_timer, led_trigger);
+
+ return sprintf(buf, "speed: %d, min: %d, max: %d\n", rt->fade_speed, rt->fade_min, rt->fade_max);
+}
+
+static ssize_t led_fade_store(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t size)
+{
+ struct led_classdev *led_cdev = dev_get_drvdata(dev);
+ struct rt_timer *rt = container_of(led_cdev->trigger, struct rt_timer, led_trigger);
+ unsigned int speed = 0, min = 0, max = 0;
+ ssize_t ret = -EINVAL;
+
+ ret = sscanf(buf, "%u %u %u", &speed, &min, &max);
+
+ if (ret == 3) {
+ rt->fade_speed = speed;
+ rt->fade_min = min;
+ rt->fade_max = max;
+ rt->fade = 1;
+ } else {
+ rt->fade = 0;
+ }
+
+ return size;
+}
+
+static DEVICE_ATTR(fade, 0644, led_fade_show, led_fade_store);
+
+static ssize_t led_duty_cycle_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct led_classdev *led_cdev = dev_get_drvdata(dev);
+ struct rt_timer *rt = container_of(led_cdev->trigger, struct rt_timer, led_trigger);
+
+ return sprintf(buf, "%u\n", rt->duty_cycle);
+}
+
+static ssize_t led_duty_cycle_store(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t size)
+{
+ struct led_classdev *led_cdev = dev_get_drvdata(dev);
+ struct rt_timer *rt = container_of(led_cdev->trigger, struct rt_timer, led_trigger);
+ unsigned long state;
+ ssize_t ret = -EINVAL;
+
+ ret = kstrtoul(buf, 10, &state);
+ if (ret)
+ return ret;
+
+ if (state <= 100)
+ rt->duty_cycle = state;
+ else
+ rt->duty_cycle = 100;
+
+ rt->fade = 0;
+
+ return size;
+}
+
+static DEVICE_ATTR(duty_cycle, 0644, led_duty_cycle_show, led_duty_cycle_store);
+
+static void rt_timer_trig_activate(struct led_classdev *led_cdev)
+{
+ struct rt_timer *rt = container_of(led_cdev->trigger, struct rt_timer, led_trigger);
+ struct rt_timer_gpio *gpio_data;
+ int rc;
+
+ led_cdev->trigger_data = NULL;
+ gpio_data = kzalloc(sizeof(*gpio_data), GFP_KERNEL);
+ if (!gpio_data)
+ return;
+
+ rc = device_create_file(led_cdev->dev, &dev_attr_duty_cycle);
+ if (rc)
+ goto err_gpio;
+ rc = device_create_file(led_cdev->dev, &dev_attr_fade);
+ if (rc)
+ goto err_out_duty_cycle;
+
+ led_cdev->activated = true;
+ led_cdev->trigger_data = gpio_data;
+ gpio_data->led = led_cdev;
+ list_add(&gpio_data->list, &rt->gpios);
+ led_cdev->trigger_data = gpio_data;
+ rt_timer_enable(rt);
+ return;
+
+err_out_duty_cycle:
+ device_remove_file(led_cdev->dev, &dev_attr_duty_cycle);
+
+err_gpio:
+ kfree(gpio_data);
+}
+
+static void rt_timer_trig_deactivate(struct led_classdev *led_cdev)
+{
+ struct rt_timer *rt = container_of(led_cdev->trigger, struct rt_timer, led_trigger);
+ struct rt_timer_gpio *gpio_data = (struct rt_timer_gpio*) led_cdev->trigger_data;
+
+ if (led_cdev->activated) {
+ device_remove_file(led_cdev->dev, &dev_attr_duty_cycle);
+ device_remove_file(led_cdev->dev, &dev_attr_fade);
+ led_cdev->activated = false;
+ }
+
+ list_del(&gpio_data->list);
+ rt_timer_disable(rt);
+ led_set_brightness(led_cdev, LED_OFF);
+}
+
static int rt_timer_probe(struct platform_device *pdev)
{
struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ const __be32 *divisor;
struct rt_timer *rt;
struct clk *clk;
+ int ret;
if (!res) {
dev_err(&pdev->dev, "no memory resource found\n");
@@ -147,12 +310,29 @@ static int rt_timer_probe(struct platform_device *pdev)
if (!rt->timer_freq)
return -EINVAL;
+ rt->duty_cycle = 100;
rt->dev = &pdev->dev;
platform_set_drvdata(pdev, rt);
- rt_timer_request(rt);
- rt_timer_config(rt, 2);
- rt_timer_enable(rt);
+ ret = rt_timer_request(rt);
+ if (ret)
+ return ret;
+
+ divisor = of_get_property(pdev->dev.of_node, "ralink,divisor", NULL);
+ if (divisor)
+ rt_timer_config(rt, be32_to_cpu(*divisor));
+ else
+ rt_timer_config(rt, 200);
+
+ rt->led_trigger.name = "pwmtimer",
+ rt->led_trigger.activate = rt_timer_trig_activate,
+ rt->led_trigger.deactivate = rt_timer_trig_deactivate,
+
+ ret = led_trigger_register(&rt->led_trigger);
+ if (ret)
+ return ret;
+
+ INIT_LIST_HEAD(&rt->gpios);
dev_info(&pdev->dev, "maximum frequncy is %luHz\n", rt->timer_freq);
@@ -163,6 +343,7 @@ static int rt_timer_remove(struct platform_device *pdev)
{
struct rt_timer *rt = platform_get_drvdata(pdev);
+ led_trigger_unregister(&rt->led_trigger);
rt_timer_disable(rt);
rt_timer_free(rt);
@@ -187,6 +368,6 @@ static struct platform_driver rt_timer_driver = {
module_platform_driver(rt_timer_driver);
-MODULE_DESCRIPTION("Ralink RT2880 timer");
+MODULE_DESCRIPTION("Ralink RT2880 timer / pseudo pwm");
MODULE_AUTHOR("John Crispin <blogic@openwrt.org");
MODULE_LICENSE("GPL");
--
1.7.10.4

View file

@ -0,0 +1,188 @@
From bcd97dbdcb7bc0300397db481872252e8849307b Mon Sep 17 00:00:00 2001
From: John Crispin <blogic@openwrt.org>
Date: Mon, 25 Mar 2013 10:50:53 +0100
Subject: [PATCH 207/208] owrt: MIPS: ralink: add support for runtime memory
detection
This allows us to add a device_node called "memorydetect" to the DT with
information about the memory windoe of the SoC. Based on this the memory is
detected ar runtime.
Signed-off-by: John Crispin <blogic@openwrt.org>
---
arch/mips/include/asm/prom.h | 3 ++
arch/mips/kernel/prom.c | 3 ++
arch/mips/ralink/Makefile | 2 +-
arch/mips/ralink/memory.c | 119 ++++++++++++++++++++++++++++++++++++++++++
4 files changed, 126 insertions(+), 1 deletion(-)
create mode 100644 arch/mips/ralink/memory.c
diff --git a/arch/mips/include/asm/prom.h b/arch/mips/include/asm/prom.h
index a4ad354..91e83e3 100644
--- a/arch/mips/include/asm/prom.h
+++ b/arch/mips/include/asm/prom.h
@@ -20,6 +20,9 @@
extern int early_init_dt_scan_memory_arch(unsigned long node,
const char *uname, int depth, void *data);
+extern int early_init_dt_detect_memory(unsigned long node,
+ const char *uname, int depth, void *data);
+
extern void device_tree_init(void);
static inline unsigned long pci_address_to_pio(phys_addr_t address)
diff --git a/arch/mips/kernel/prom.c b/arch/mips/kernel/prom.c
index 1aa68a2..feac917 100644
--- a/arch/mips/kernel/prom.c
+++ b/arch/mips/kernel/prom.c
@@ -88,6 +88,9 @@ void __init early_init_devtree(void *params)
of_scan_flat_dt(early_init_dt_scan_memory_arch, NULL);
/* try to load the mips machine name */
+ of_scan_flat_dt(early_init_dt_detect_memory, NULL);
+
+ /* try to load the mips machine name */
of_scan_flat_dt(early_init_dt_scan_model, NULL);
}
diff --git a/arch/mips/ralink/Makefile b/arch/mips/ralink/Makefile
index 9e58aa1..800f98b 100644
--- a/arch/mips/ralink/Makefile
+++ b/arch/mips/ralink/Makefile
@@ -6,7 +6,7 @@
# Copyright (C) 2009-2011 Gabor Juhos <juhosg@openwrt.org>
# Copyright (C) 2013 John Crispin <blogic@openwrt.org>
-obj-y := prom.o of.o reset.o clk.o irq.o pinmux.o timer.o
+obj-y := prom.o of.o reset.o clk.o irq.o pinmux.o timer.o memory.o
obj-$(CONFIG_SOC_RT288X) += rt288x.o
obj-$(CONFIG_SOC_RT305X) += rt305x.o rt305x-usb.o
diff --git a/arch/mips/ralink/memory.c b/arch/mips/ralink/memory.c
new file mode 100644
index 0000000..54da31d
--- /dev/null
+++ b/arch/mips/ralink/memory.c
@@ -0,0 +1,119 @@
+/*
+ * 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) 2009 Gabor Juhos <juhosg@openwrt.org>
+ * Copyright (C) 2013 John Crispin <blogic@openwrt.org>
+ */
+
+#include <linux/string.h>
+#include <linux/of_fdt.h>
+#include <linux/of_platform.h>
+
+#include <asm/bootinfo.h>
+#include <asm/addrspace.h>
+
+#include "common.h"
+
+#define MB (1024 * 1024)
+
+unsigned long ramips_mem_base;
+unsigned long ramips_mem_size_min;
+unsigned long ramips_mem_size_max;
+
+#ifdef CONFIG_SOC_RT305X
+
+#include <asm/mach-ralink/rt305x.h>
+
+static unsigned long rt5350_get_mem_size(void)
+{
+ void __iomem *sysc = (void __iomem *) KSEG1ADDR(RT305X_SYSC_BASE);
+ unsigned long ret;
+ u32 t;
+
+ t = __raw_readl(sysc + SYSC_REG_SYSTEM_CONFIG);
+ t = (t >> RT5350_SYSCFG0_DRAM_SIZE_SHIFT) &
+ RT5350_SYSCFG0_DRAM_SIZE_MASK;
+
+ switch (t) {
+ case RT5350_SYSCFG0_DRAM_SIZE_2M:
+ ret = 2 * 1024 * 1024;
+ break;
+ case RT5350_SYSCFG0_DRAM_SIZE_8M:
+ ret = 8 * 1024 * 1024;
+ break;
+ case RT5350_SYSCFG0_DRAM_SIZE_16M:
+ ret = 16 * 1024 * 1024;
+ break;
+ case RT5350_SYSCFG0_DRAM_SIZE_32M:
+ ret = 32 * 1024 * 1024;
+ break;
+ case RT5350_SYSCFG0_DRAM_SIZE_64M:
+ ret = 64 * 1024 * 1024;
+ break;
+ default:
+ panic("rt5350: invalid DRAM size: %u", t);
+ break;
+ }
+
+ return ret;
+}
+
+#endif
+
+static void __init detect_mem_size(void)
+{
+ unsigned long size;
+
+#ifdef CONFIG_SOC_RT305X
+ if (soc_is_rt5350()) {
+ size = rt5350_get_mem_size();
+ } else
+#endif
+ {
+ void *base;
+
+ base = (void *) KSEG1ADDR(detect_mem_size);
+ for (size = ramips_mem_size_min; size < ramips_mem_size_max;
+ size <<= 1 ) {
+ if (!memcmp(base, base + size, 1024))
+ break;
+ }
+ }
+
+ pr_info("memory detected: %uMB\n", (unsigned int) size / MB);
+
+ add_memory_region(ramips_mem_base, size, BOOT_MEM_RAM);
+}
+
+int __init early_init_dt_detect_memory(unsigned long node, const char *uname,
+ int depth, void *data)
+{
+ unsigned long l;
+ __be32 *mem;
+
+ /* We are scanning "memorydetect" nodes only */
+ if (depth != 1 || strcmp(uname, "memorydetect") != 0)
+ return 0;
+
+ mem = of_get_flat_dt_prop(node, "ralink,memory", &l);
+ if (mem == NULL)
+ return 0;
+
+ if ((l / sizeof(__be32)) != 3)
+ panic("invalid memorydetect node\n");
+
+ ramips_mem_base = dt_mem_next_cell(dt_root_addr_cells, &mem);
+ ramips_mem_size_min = dt_mem_next_cell(dt_root_size_cells, &mem);
+ ramips_mem_size_max = dt_mem_next_cell(dt_root_size_cells, &mem);
+
+ pr_info("memory window: 0x%llx, min: %uMB, max: %uMB\n",
+ (unsigned long long) ramips_mem_base,
+ (unsigned int) ramips_mem_size_min / MB,
+ (unsigned int) ramips_mem_size_max / MB);
+
+ detect_mem_size();
+
+ return 0;
+}
--
1.7.10.4

View file

@ -0,0 +1,155 @@
From 2a295753a10823a47542c779a25bbb1f52c71281 Mon Sep 17 00:00:00 2001
From: John Crispin <blogic@openwrt.org>
Date: Fri, 3 Aug 2012 10:27:13 +0200
Subject: [PATCH 19/25] owrt mtd split
---
.../mips/include/asm/mach-lantiq/xway/lantiq_soc.h | 1 +
arch/mips/lantiq/setup.c | 7 +
drivers/mtd/Kconfig | 4 +
drivers/mtd/mtdpart.c | 173 +++++++++++++++++++-
4 files changed, 184 insertions(+), 1 deletions(-)
Index: linux-3.9-rc4/drivers/mtd/Kconfig
===================================================================
--- linux-3.9-rc4.orig/drivers/mtd/Kconfig 2013-03-27 09:26:32.005789709 +0100
+++ linux-3.9-rc4/drivers/mtd/Kconfig 2013-03-27 09:26:35.669789796 +0100
@@ -31,6 +31,10 @@
bool "Automatically split 'rootfs' partition for squashfs"
default y
+config MTD_UIMAGE_SPLIT
+ bool "Automatically split 'linux' partition into 'kernel' and 'rootfs'"
+ default y
+
config MTD_REDBOOT_PARTS
tristate "RedBoot partition table parsing"
---help---
Index: linux-3.9-rc4/drivers/mtd/mtdpart.c
===================================================================
--- linux-3.9-rc4.orig/drivers/mtd/mtdpart.c 2013-03-27 09:26:32.281789715 +0100
+++ linux-3.9-rc4/drivers/mtd/mtdpart.c 2013-03-27 17:20:12.874466937 +0100
@@ -844,6 +844,99 @@
}
#endif /* CONFIG_MTD_ROOTFS_SPLIT */
+#ifdef CONFIG_MTD_UIMAGE_SPLIT
+static unsigned long find_uimage_size(struct mtd_info *mtd,
+ unsigned long offset)
+{
+#define UBOOT_MAGIC 0x56190527
+ unsigned long magic = 0;
+ unsigned long temp;
+ size_t len;
+ int ret;
+
+ ret = mtd_read(mtd, offset, 4, &len, (void *)&magic);
+ if (ret || len != sizeof(magic))
+ return 0;
+
+ if (le32_to_cpu(magic) != UBOOT_MAGIC)
+ return 0;
+
+ ret = mtd_read(mtd, offset + 12, 4, &len, (void *)&temp);
+ if (ret || len != sizeof(temp))
+ return 0;
+
+ return be32_to_cpu(temp) + 0x40;
+}
+
+static int detect_squashfs_partition(struct mtd_info *mtd, unsigned long offset)
+{
+ unsigned long temp;
+ size_t len;
+ int ret;
+
+ ret = mtd_read(mtd, offset, 4, &len, (void *)&temp);
+ if (ret || len != sizeof(temp))
+ return 0;
+
+ return le32_to_cpu(temp) == SQUASHFS_MAGIC;
+}
+
+static unsigned long find_squashfs_offset(struct mtd_info *mtd, unsigned long _offset)
+{
+ /* scan the first 2MB at 64K offsets */
+ int i;
+
+ for (i = 0; i < 32; i++) {
+ unsigned long offset = i * 64 * 1024;
+ if (detect_squashfs_partition(mtd, _offset + offset))
+ return offset;
+ }
+ return 0;
+}
+
+static int split_uimage(struct mtd_info *mtd,
+ const struct mtd_partition *part)
+{
+ static struct mtd_partition split_partitions[] = {
+ {
+ .name = "kernel",
+ .offset = 0x0,
+ .size = 0x0,
+ }, {
+ .name = "rootfs",
+ .offset = 0x0,
+ .size = 0x0,
+ },
+ };
+
+ split_partitions[0].size = find_uimage_size(mtd, part->offset);
+ if (!split_partitions[0].size) {
+ split_partitions[0].size = find_squashfs_offset(mtd, part->offset);
+ if (!split_partitions[0].size) {
+ pr_err("failed to split firmware partition\n");
+ return -1;
+ }
+ }
+
+ if (!detect_squashfs_partition(mtd,
+ part->offset
+ + split_partitions[0].size)) {
+ split_partitions[0].size &= ~(mtd->erasesize - 1);
+ split_partitions[0].size += mtd->erasesize;
+ } else {
+ pr_info("found squashfs behind kernel\n");
+ }
+
+ split_partitions[0].offset = part->offset;
+ split_partitions[1].offset = part->offset + split_partitions[0].size;
+ split_partitions[1].size = part->size - split_partitions[0].size;
+
+ add_mtd_partitions(mtd, split_partitions, 2);
+
+ return 0;
+}
+#endif
+
/*
* This function, given a master MTD object and a partition table, creates
* and registers slave MTD objects which are bound to the master according to
@@ -860,7 +953,7 @@
struct mtd_part *slave;
uint64_t cur_offset = 0;
int i;
-#ifdef CONFIG_MTD_ROOTFS_SPLIT
+#if defined(CONFIG_MTD_ROOTFS_SPLIT) || defined(CONFIG_MTD_UIMAGE_SPLIT)
int ret;
#endif
@@ -877,6 +970,14 @@
add_mtd_device(&slave->mtd);
+#ifdef CONFIG_MTD_UIMAGE_SPLIT
+ if (!strcmp(parts[i].name, "firmware")) {
+ ret = split_uimage(master, &parts[i]);
+ if (ret)
+ printk(KERN_WARNING "Can't split firmware partition\n");
+ }
+#endif
+
if (!strcmp(parts[i].name, "rootfs")) {
#ifdef CONFIG_MTD_ROOTFS_ROOT_DEV
if (ROOT_DEV == 0) {

View file

@ -0,0 +1,266 @@
From eda15425bcd2703ea1cfeebd65847305c17e5f0a Mon Sep 17 00:00:00 2001
From: John Crispin <blogic@openwrt.org>
Date: Wed, 27 Mar 2013 18:38:48 +0100
Subject: [PATCH] owrt: GPIO: add gpio_export_with_name
http://lists.infradead.org/pipermail/linux-arm-kernel/2012-November/133856.html
Signed-off-by: John Crispin <blogic@openwrt.org>
---
Documentation/devicetree/bindings/gpio/gpio.txt | 60 ++++++++++++++++++++++
drivers/gpio/gpiolib-of.c | 61 +++++++++++++++++++++++
drivers/gpio/gpiolib.c | 18 +++++--
include/asm-generic/gpio.h | 6 ++-
include/linux/gpio.h | 23 ++++++++-
5 files changed, 160 insertions(+), 8 deletions(-)
Index: linux-3.8.3/Documentation/devicetree/bindings/gpio/gpio.txt
===================================================================
--- linux-3.8.3.orig/Documentation/devicetree/bindings/gpio/gpio.txt 2013-03-14 19:27:14.000000000 +0100
+++ linux-3.8.3/Documentation/devicetree/bindings/gpio/gpio.txt 2013-04-01 11:11:42.151167467 +0200
@@ -112,3 +112,63 @@
The pinctrl node must have "#gpio-range-cells" property to show number of
arguments to pass with phandle from gpio controllers node.
+
+3) gpio-export
+--------------
+
+gpio-export will allow you to automatically export gpio
+
+required properties:
+- compatible: Should be "gpio-export"
+
+in each child node will reprensent a gpio or if no name is specified
+a list of gpio to export
+
+required properties:
+- gpios: gpio to export
+
+optional properties:
+ - gpio-export,name: export name
+ - gpio-export,output: to set the as output with default value
+ if no present gpio as input
+ - pio-export,direction_may_change: boolean to allow the direction to be controllable
+
+Example:
+
+
+gpio_export {
+ compatible = "gpio-export";
+ #size-cells = <0>;
+
+ in {
+ gpio-export,name = "in";
+ gpios = <&pioC 20 0>;
+ };
+
+ out {
+ gpio-export,name = "out";
+ gpio-export,output = <1>;
+ gpio-export,direction_may_change;
+ gpios = <&pioC 21 0>;
+ };
+
+ in_out {
+ gpio-export,name = "in_out";
+ gpio-export,direction_may_change;
+ gpios = <&pioC 21 0>;
+ };
+
+ gpios_in {
+ gpios = <&pioB 0 0
+ &pioB 3 0
+ &pioC 4 0>;
+ gpio-export,direction_may_change;
+ };
+
+ gpios_out {
+ gpios = <&pioB 1 0
+ &pioB 2 0
+ &pioC 3 0>;
+ gpio-export,output = <1>;
+ };
+};
Index: linux-3.8.3/drivers/gpio/gpiolib-of.c
===================================================================
--- linux-3.8.3.orig/drivers/gpio/gpiolib-of.c 2013-03-14 19:27:14.000000000 +0100
+++ linux-3.8.3/drivers/gpio/gpiolib-of.c 2013-04-01 11:11:42.151167467 +0200
@@ -21,6 +21,8 @@
#include <linux/of_gpio.h>
#include <linux/pinctrl/pinctrl.h>
#include <linux/slab.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
/* Private data structure for of_gpiochip_find_and_xlate */
struct gg_data {
@@ -289,3 +291,62 @@
if (chip->of_node)
of_node_put(chip->of_node);
}
+
+static struct of_device_id gpio_export_ids[] = {
+ { .compatible = "gpio-export" },
+ { /* sentinel */ }
+};
+
+static int __init of_gpio_export_probe(struct platform_device *pdev)
+{
+ struct device_node *np = pdev->dev.of_node;
+ struct device_node *cnp;
+ u32 val;
+ int nb = 0;
+
+ for_each_child_of_node(np, cnp) {
+ const char *name = NULL;
+ int gpio;
+ bool dmc;
+ int max_gpio = 1;
+ int i;
+
+ of_property_read_string(cnp, "gpio-export,name", &name);
+
+ if (!name)
+ max_gpio = of_gpio_count(cnp);
+
+ for (i = 0; i < max_gpio; i++) {
+ gpio = of_get_gpio(cnp, i);
+ if (devm_gpio_request(&pdev->dev, gpio, name ? name : of_node_full_name(np)))
+ continue;
+
+ if (!of_property_read_u32(cnp, "gpio-export,output", &val))
+ gpio_direction_output(gpio, val);
+ else
+ gpio_direction_input(gpio);
+
+ dmc = of_property_read_bool(np, "gpio-export,direction_may_change");
+ gpio_export_with_name(gpio, dmc, name);
+ nb++;
+ }
+ }
+
+ dev_info(&pdev->dev, "%d gpio(s) exported\n", nb);
+
+ return 0;
+}
+
+static struct platform_driver gpio_export_driver = {
+ .driver = {
+ .name = "gpio-export",
+ .owner = THIS_MODULE,
+ .of_match_table = of_match_ptr(gpio_export_ids),
+ },
+};
+
+static int __init of_gpio_export_init(void)
+{
+ return platform_driver_probe(&gpio_export_driver, of_gpio_export_probe);
+}
+device_initcall(of_gpio_export_init);
Index: linux-3.8.3/drivers/gpio/gpiolib.c
===================================================================
--- linux-3.8.3.orig/drivers/gpio/gpiolib.c 2013-03-14 19:27:14.000000000 +0100
+++ linux-3.8.3/drivers/gpio/gpiolib.c 2013-04-01 11:12:29.263168590 +0200
@@ -714,9 +714,10 @@
/**
- * gpio_export - export a GPIO through sysfs
+ * gpio_export_with_name - export a GPIO through sysfs
* @gpio: gpio to make available, already requested
* @direction_may_change: true if userspace may change gpio direction
+ * @name: gpio name
* Context: arch_initcall or later
*
* When drivers want to make a GPIO accessible to userspace after they
@@ -728,7 +729,7 @@
*
* Returns zero on success, else an error.
*/
-int gpio_export(unsigned gpio, bool direction_may_change)
+int gpio_export_with_name(unsigned gpio, bool direction_may_change, const char *name)
{
unsigned long flags;
struct gpio_desc *desc;
@@ -762,6 +763,8 @@
goto fail_unlock;
}
+ if (name)
+ ioname = name;
if (!desc->chip->direction_input || !desc->chip->direction_output)
direction_may_change = false;
spin_unlock_irqrestore(&gpio_lock, flags);
@@ -804,7 +807,7 @@
pr_debug("%s: gpio%d status %d\n", __func__, gpio, status);
return status;
}
-EXPORT_SYMBOL_GPL(gpio_export);
+EXPORT_SYMBOL_GPL(gpio_export_with_name);
static int match_export(struct device *dev, void *data)
{
Index: linux-3.8.3/include/asm-generic/gpio.h
===================================================================
--- linux-3.8.3.orig/include/asm-generic/gpio.h 2013-03-14 19:27:14.000000000 +0100
+++ linux-3.8.3/include/asm-generic/gpio.h 2013-04-01 11:11:42.155167467 +0200
@@ -204,7 +204,8 @@
* A sysfs interface can be exported by individual drivers if they want,
* but more typically is configured entirely from userspace.
*/
-extern int gpio_export(unsigned gpio, bool direction_may_change);
+extern int gpio_export_with_name(unsigned gpio, bool direction_may_change,
+ const char *name);
extern int gpio_export_link(struct device *dev, const char *name,
unsigned gpio);
extern int gpio_sysfs_set_active_low(unsigned gpio, int value);
@@ -249,7 +250,8 @@
/* sysfs support is only available with gpiolib, where it's optional */
-static inline int gpio_export(unsigned gpio, bool direction_may_change)
+static inline int gpio_export_with_name(unsigned gpio,
+ bool direction_may_change, const char *name)
{
return -ENOSYS;
}
Index: linux-3.8.3/include/linux/gpio.h
===================================================================
--- linux-3.8.3.orig/include/linux/gpio.h 2013-03-14 19:27:14.000000000 +0100
+++ linux-3.8.3/include/linux/gpio.h 2013-04-01 11:11:42.159167467 +0200
@@ -189,7 +189,8 @@
WARN_ON(1);
}
-static inline int gpio_export(unsigned gpio, bool direction_may_change)
+static inline int gpio_export_with_name(unsigned gpio,
+ bool direction_may_change, const char *name)
{
/* GPIO can never have been requested or set as {in,out}put */
WARN_ON(1);
@@ -248,4 +249,24 @@
#endif /* ! CONFIG_GENERIC_GPIO */
+/**
+ * gpio_export - export a GPIO through sysfs
+ * @gpio: gpio to make available, already requested
+ * @direction_may_change: true if userspace may change gpio direction
+ * Context: arch_initcall or later
+ *
+ * When drivers want to make a GPIO accessible to userspace after they
+ * have requested it -- perhaps while debugging, or as part of their
+ * public interface -- they may use this routine. If the GPIO can
+ * change direction (some can't) and the caller allows it, userspace
+ * will see "direction" sysfs attribute which may be used to change
+ * the gpio's direction. A "value" attribute will always be provided.
+ *
+ * Returns zero on success, else an error.
+ */
+static inline int gpio_export(unsigned gpio,bool direction_may_change)
+{
+ return gpio_export_with_name(gpio, direction_may_change, NULL);
+}
+
#endif /* __LINUX_GPIO_H */