aboutsummaryrefslogtreecommitdiffstats
path: root/target/linux/ramips/files/arch/mips
diff options
context:
space:
mode:
Diffstat (limited to 'target/linux/ramips/files/arch/mips')
-rw-r--r--target/linux/ramips/files/arch/mips/include/asm/mach-ralink/cpu-feature-overrides.h56
-rw-r--r--target/linux/ramips/files/arch/mips/include/asm/mach-ralink/gpio.h52
-rw-r--r--target/linux/ramips/files/arch/mips/include/asm/mach-ralink/irq.h17
-rw-r--r--target/linux/ramips/files/arch/mips/include/asm/mach-ralink/platform.h20
-rw-r--r--target/linux/ramips/files/arch/mips/include/asm/mach-ralink/rt288x.h89
-rw-r--r--target/linux/ramips/files/arch/mips/include/asm/mach-ralink/rt288x_regs.h121
-rw-r--r--target/linux/ramips/files/arch/mips/include/asm/mach-ralink/rt305x.h91
-rw-r--r--target/linux/ramips/files/arch/mips/include/asm/mach-ralink/rt305x_regs.h132
-rw-r--r--target/linux/ramips/files/arch/mips/include/asm/mach-ralink/war.h25
-rw-r--r--target/linux/ramips/files/arch/mips/ralink/Kconfig51
-rw-r--r--target/linux/ramips/files/arch/mips/ralink/rt288x/Kconfig11
-rw-r--r--target/linux/ramips/files/arch/mips/ralink/rt288x/Makefile15
-rw-r--r--target/linux/ramips/files/arch/mips/ralink/rt288x/early_printk.c30
-rw-r--r--target/linux/ramips/files/arch/mips/ralink/rt288x/irq.c125
-rw-r--r--target/linux/ramips/files/arch/mips/ralink/rt288x/mach-generic.c65
-rw-r--r--target/linux/ramips/files/arch/mips/ralink/rt288x/platform.c97
-rw-r--r--target/linux/ramips/files/arch/mips/ralink/rt288x/prom.c37
-rw-r--r--target/linux/ramips/files/arch/mips/ralink/rt288x/rt288x.c77
-rw-r--r--target/linux/ramips/files/arch/mips/ralink/rt288x/setup.c142
-rw-r--r--target/linux/ramips/files/arch/mips/ralink/rt305x/Kconfig15
-rw-r--r--target/linux/ramips/files/arch/mips/ralink/rt305x/Makefile15
-rw-r--r--target/linux/ramips/files/arch/mips/ralink/rt305x/devices.c96
-rw-r--r--target/linux/ramips/files/arch/mips/ralink/rt305x/devices.h20
-rw-r--r--target/linux/ramips/files/arch/mips/ralink/rt305x/early_printk.c29
-rw-r--r--target/linux/ramips/files/arch/mips/ralink/rt305x/irq.c118
-rw-r--r--target/linux/ramips/files/arch/mips/ralink/rt305x/mach-generic.c21
-rw-r--r--target/linux/ramips/files/arch/mips/ralink/rt305x/mach-whr-g300n.c71
-rw-r--r--target/linux/ramips/files/arch/mips/ralink/rt305x/machine.h16
-rw-r--r--target/linux/ramips/files/arch/mips/ralink/rt305x/prom.c147
-rw-r--r--target/linux/ramips/files/arch/mips/ralink/rt305x/rt305x.c70
-rw-r--r--target/linux/ramips/files/arch/mips/ralink/rt305x/setup.c137
31 files changed, 2008 insertions, 0 deletions
diff --git a/target/linux/ramips/files/arch/mips/include/asm/mach-ralink/cpu-feature-overrides.h b/target/linux/ramips/files/arch/mips/include/asm/mach-ralink/cpu-feature-overrides.h
new file mode 100644
index 0000000000..6c41da851f
--- /dev/null
+++ b/target/linux/ramips/files/arch/mips/include/asm/mach-ralink/cpu-feature-overrides.h
@@ -0,0 +1,56 @@
+/*
+ * Ralink RT288x/RT305x specific CPU feature overrides
+ *
+ * Copyright (C) 2008-2009 Gabor Juhos <juhosg@openwrt.org>
+ * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
+ *
+ * This file was derived from: include/asm-mips/cpu-features.h
+ * Copyright (C) 2003, 2004 Ralf Baechle
+ * Copyright (C) 2004 Maciej W. Rozycki
+ *
+ * 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_CPU_FEATURE_OVERRIDES_H
+#define __ASM_MACH_RALINK_CPU_FEATURE_OVERRIDES_H
+
+#define cpu_has_tlb 1
+#define cpu_has_4kex 1
+#define cpu_has_3k_cache 0
+#define cpu_has_4k_cache 1
+#define cpu_has_tx39_cache 0
+#define cpu_has_sb1_cache 0
+#define cpu_has_fpu 0
+#define cpu_has_32fpr 0
+#define cpu_has_counter 1
+#define cpu_has_watch 1
+#define cpu_has_divec 1
+
+#define cpu_has_prefetch 1
+#define cpu_has_ejtag 1
+#define cpu_has_llsc 1
+
+#define cpu_has_mips16 1
+#define cpu_has_mdmx 0
+#define cpu_has_mips3d 0
+#define cpu_has_smartmips 0
+
+#define cpu_has_mips32r1 1
+#define cpu_has_mips32r2 1
+#define cpu_has_mips64r1 0
+#define cpu_has_mips64r2 0
+
+#define cpu_has_dsp 0
+#define cpu_has_mipsmt 0
+
+#define cpu_has_64bits 0
+#define cpu_has_64bit_zero_reg 0
+#define cpu_has_64bit_gp_regs 0
+#define cpu_has_64bit_addresses 0
+
+#define cpu_dcache_line_size() 32
+#define cpu_icache_line_size() 32
+
+#endif /* __ASM_MACH_RALINK_CPU_FEATURE_OVERRIDES_H */
diff --git a/target/linux/ramips/files/arch/mips/include/asm/mach-ralink/gpio.h b/target/linux/ramips/files/arch/mips/include/asm/mach-ralink/gpio.h
new file mode 100644
index 0000000000..e8a0836a32
--- /dev/null
+++ b/target/linux/ramips/files/arch/mips/include/asm/mach-ralink/gpio.h
@@ -0,0 +1,52 @@
+/*
+ * Ralink RT288x GPIO API definitions
+ *
+ * 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_RT288X_GPIO_H
+#define __ASM_MACH_RT288X_GPIO_H
+
+#define ARCH_NR_GPIOS 64
+#include <asm-generic/gpio.h>
+
+#include <asm/mach-ralink/rt288x.h>
+
+extern void __rt288x_gpio_set_value(unsigned gpio, int value);
+extern int __rt288x_gpio_get_value(unsigned gpio);
+
+static inline int gpio_to_irq(unsigned gpio)
+{
+ return RT288X_GPIO_IRQ(gpio);
+}
+
+static inline int irq_to_gpio(unsigned irq)
+{
+ return irq - RT288X_GPIO_IRQ_BASE;
+}
+
+static inline int gpio_get_value(unsigned gpio)
+{
+ if (gpio < RT288X_GPIO_COUNT)
+ return __rt288x_gpio_get_value(gpio);
+
+ return __gpio_get_value(gpio);
+}
+
+static inline void gpio_set_value(unsigned gpio, int value)
+{
+ if (gpio < RT288X_GPIO_COUNT)
+ __rt288x_gpio_set_value(gpio, value);
+ else
+ __gpio_set_value(gpio, value);
+}
+
+#define gpio_cansleep __gpio_cansleep
+
+#endif /* __ASM_MACH_RT288X_GPIO_H */
diff --git a/target/linux/ramips/files/arch/mips/include/asm/mach-ralink/irq.h b/target/linux/ramips/files/arch/mips/include/asm/mach-ralink/irq.h
new file mode 100644
index 0000000000..90bfea3715
--- /dev/null
+++ b/target/linux/ramips/files/arch/mips/include/asm/mach-ralink/irq.h
@@ -0,0 +1,17 @@
+/*
+ * Copyright (C) 2008 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_RT288X_IRQ_H
+#define __ASM_MACH_RT288X_IRQ_H
+
+#define MIPS_CPU_IRQ_BASE 0
+#define NR_IRQS 48
+
+#include_next <irq.h>
+
+#endif /* __ASM_MACH_RT288X_IRQ_H */
diff --git a/target/linux/ramips/files/arch/mips/include/asm/mach-ralink/platform.h b/target/linux/ramips/files/arch/mips/include/asm/mach-ralink/platform.h
new file mode 100644
index 0000000000..4585d8b56f
--- /dev/null
+++ b/target/linux/ramips/files/arch/mips/include/asm/mach-ralink/platform.h
@@ -0,0 +1,20 @@
+/*
+ * Ralink RT288x SoC specific platform definitions
+ *
+ * Copyright (C) 2008 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_RT288X_PLATFORM_H
+#define __ASM_MACH_RT288X_PLATFORM_H
+
+struct physmap_flash_data;
+
+extern void rt288x_register_flash(unsigned int id,
+ struct physmap_flash_data *pdata) __init;
+
+#endif /* __ASM_MACH_RT288X_PLATFORM_H */
diff --git a/target/linux/ramips/files/arch/mips/include/asm/mach-ralink/rt288x.h b/target/linux/ramips/files/arch/mips/include/asm/mach-ralink/rt288x.h
new file mode 100644
index 0000000000..9b218de025
--- /dev/null
+++ b/target/linux/ramips/files/arch/mips/include/asm/mach-ralink/rt288x.h
@@ -0,0 +1,89 @@
+/*
+ * Ralink RT288x SoC specific definitions
+ *
+ * Copyright (C) 2008 Gabor Juhos <juhosg@openwrt.org>
+ * Copyright (C) 2008 Imre Kaloz <kaloz@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.
+ */
+
+#ifndef _RT288X_H_
+#define _RT288X_H_
+
+#include <linux/init.h>
+#include <linux/io.h>
+
+void rt288x_detect_sys_type(void) __init;
+
+#define RT288X_SYS_TYPE_LEN 64
+extern unsigned char rt288x_sys_type[RT288X_SYS_TYPE_LEN];
+
+void rt288x_detect_sys_freq(void) __init;
+
+extern unsigned long rt288x_cpu_freq;
+extern unsigned long rt288x_sys_freq;
+
+extern unsigned long rt288x_mach_type;
+#define RT288X_MACH_GENERIC 0
+
+#define RT288X_CPU_IRQ_BASE 0
+#define RT288X_INTC_IRQ_BASE 8
+#define RT288X_INTC_IRQ_COUNT 32
+#define RT288X_GPIO_IRQ_BASE 40
+
+#define RT288X_CPU_IRQ_INTC (RT288X_CPU_IRQ_BASE + 2)
+#define RT288X_CPU_IRQ_PCI (RT288X_CPU_IRQ_BASE + 4)
+#define RT288X_CPU_IRQ_FE (RT288X_CPU_IRQ_BASE + 5)
+#define RT288X_CPU_IRQ_WNIC (RT288X_CPU_IRQ_BASE + 6)
+#define RT288X_CPU_IRQ_COUNTER (RT288X_CPU_IRQ_BASE + 7)
+
+#define RT2880_INTC_IRQ_TIMER0 (RT288X_INTC_IRQ_BASE + 0)
+#define RT2880_INTC_IRQ_TIMER1 (RT288X_INTC_IRQ_BASE + 1)
+#define RT2880_INTC_IRQ_UART0 (RT288X_INTC_IRQ_BASE + 2)
+#define RT2880_INTC_IRQ_PIO (RT288X_INTC_IRQ_BASE + 3)
+#define RT2880_INTC_IRQ_PCM (RT288X_INTC_IRQ_BASE + 4)
+#define RT2880_INTC_IRQ_UART1 (RT288X_INTC_IRQ_BASE + 8)
+#define RT2880_INTC_IRQ_IA (RT288X_INTC_IRQ_BASE + 23)
+
+#define RT288X_GPIO_IRQ(x) (RT288X_GPIO_IRQ_BASE + (x))
+#define RT288X_GPIO_COUNT 32
+
+extern void __iomem *rt288x_sysc_base;
+extern void __iomem *rt288x_intc_base;
+extern void __iomem *rt288x_memc_base;
+
+static inline void rt288x_sysc_wr(u32 val, unsigned reg)
+{
+ __raw_writel(val, rt288x_sysc_base + reg);
+}
+
+static inline u32 rt288x_sysc_rr(unsigned reg)
+{
+ return __raw_readl(rt288x_sysc_base + reg);
+}
+
+static inline void rt288x_intc_wr(u32 val, unsigned reg)
+{
+ __raw_writel(val, rt288x_intc_base + reg);
+}
+
+static inline u32 rt288x_intc_rr(unsigned reg)
+{
+ return __raw_readl(rt288x_intc_base + reg);
+}
+
+static inline void rt288x_memc_wr(u32 val, unsigned reg)
+{
+ __raw_writel(val, rt288x_memc_base + reg);
+}
+
+static inline u32 rt288x_memc_rr(unsigned reg)
+{
+ return __raw_readl(rt288x_memc_base + reg);
+}
+
+#endif /* _RT228X_H_ */
diff --git a/target/linux/ramips/files/arch/mips/include/asm/mach-ralink/rt288x_regs.h b/target/linux/ramips/files/arch/mips/include/asm/mach-ralink/rt288x_regs.h
new file mode 100644
index 0000000000..4431a65df8
--- /dev/null
+++ b/target/linux/ramips/files/arch/mips/include/asm/mach-ralink/rt288x_regs.h
@@ -0,0 +1,121 @@
+/*
+ * Ralink RT288x SoC register definitions
+ *
+ * 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 _RT288X_REGS_H_
+#define _RT288X_REGS_H_
+
+#include <linux/bitops.h>
+
+#define RT2880_SYSC_BASE 0x00300000
+#define RT2880_TIMER_BASE 0x00300100
+#define RT2880_INTC_BASE 0x00300200
+#define RT2880_MEMC_BASE 0x00300300
+#define RT2880_UART0_BASE 0x00300500
+#define RT2880_PIO_BASE 0x00300600
+#define RT2880_I2C_BASE 0x00300900
+#define RT2880_SPI_BASE 0x00300b00
+#define RT2880_UART1_BASE 0x00300c00
+#define RT2880_FE_BASE 0x00310000
+#define RT2880_ROM_BASE 0x00400000
+#define RT2880_PCI_BASE 0x00500000
+#define RT2880_WMAC_BASE 0x00600000
+#define RT2880_FLASH1_BASE 0x01000000
+#define RT2880_FLASH0_BASE 0x1fc00000
+#define RT2880_SDRAM_BASE 0x08000000
+
+#define RT2880_SYSC_SIZE 0x100
+#define RT2880_INTC_SIZE 0x100
+#define RT2880_MEMC_SIZE 0x100
+#define RT2880_UART0_SIZE 0x100
+#define RT2880_UART1_SIZE 0x100
+#define RT2880_FLASH1_SIZE (16 * 1024 * 1024)
+#define RT2880_FLASH0_SIZE (4 * 1024 * 1024)
+
+/* SYSC registers */
+#define SYSC_REG_CHIP_NAME0 0x000 /* Chip Name 0 */
+#define SYSC_REG_CHIP_NAME1 0x004 /* Chip Name 1 */
+#define SYSC_REG_CHIP_ID 0x00c /* Chip Identification */
+#define SYSC_REG_SYSTEM_CONFIG 0x010 /* System Configuration */
+#define SYSC_REG_RESET_CTRL 0x034 /* Reset Control*/
+#define SYSC_REG_RESET_STATUS 0x038 /* Reset Status*/
+#define SYSC_REG_IA_ADDRESS 0x310 /* Illegal Access Address */
+#define SYSC_REG_IA_TYPE 0x314 /* Illegal Access Type */
+
+#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_RESET_SYSTEM BIT(0)
+#define RT2880_RESET_TIMER BIT(1)
+#define RT2880_RESET_INTC BIT(2)
+#define RT2880_RESET_MEMC BIT(3)
+#define RT2880_RESET_CPU BIT(4)
+#define RT2880_RESET_UART0 BIT(5)
+#define RT2880_RESET_PIO BIT(6)
+#define RT2880_RESET_I2C BIT(9)
+#define RT2880_RESET_SPI BIT(11)
+#define RT2880_RESET_UART1 BIT(12)
+#define RT2880_RESET_PCI BIT(16)
+#define RT2880_RESET_WMAC BIT(17)
+#define RT2880_RESET_FE BIT(18)
+#define RT2880_RESET_PCM BIT(19)
+
+/* TIMER registers */
+
+/* INTC register */
+#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 RT2880_INTC_INT_TIMER0 BIT(0)
+#define RT2880_INTC_INT_TIMER1 BIT(1)
+#define RT2880_INTC_INT_UART0 BIT(2)
+#define RT2880_INTC_INT_PIO BIT(3)
+#define RT2880_INTC_INT_PCM BIT(4)
+#define RT2880_INTC_INT_UART1 BIT(8)
+#define RT2880_INTC_INT_IA BIT(23)
+#define RT2880_INTC_INT_GLOBAL BIT(31)
+
+/* MEMC registers */
+#define MEMC_REG_SDRAM_CFG0 0x00
+#define MEMC_REG_SDRAM_CFG1 0x04
+#define MEMC_REG_FLASH_CFG0 0x08
+#define MEMC_REG_FLASH_CFG1 0x0c
+#define MEMC_REG_IA_ADDR 0x10
+#define MEMC_REG_IA_TYPE 0x14
+
+#define FLASH_CFG_WIDTH_SHIFT 26
+#define FLASH_CFG_WIDTH_MASK 0x3
+#define FLASH_CFG_WIDTH_8BIT 0x0
+#define FLASH_CFG_WIDTH_16BIT 0x1
+#define FLASH_CFG_WIDTH_32BIT 0x2
+
+/* UART registers */
+#define UART_REG_RX 0
+#define UART_REG_TX 1
+#define UART_REG_IER 2
+#define UART_REG_IIR 3
+#define UART_REG_FCR 4
+#define UART_REG_LCR 5
+#define UART_REG_MCR 6
+#define UART_REG_LSR 7
+
+#endif /* _RT288X_REGS_H_ */
diff --git a/target/linux/ramips/files/arch/mips/include/asm/mach-ralink/rt305x.h b/target/linux/ramips/files/arch/mips/include/asm/mach-ralink/rt305x.h
new file mode 100644
index 0000000000..7dcef168a9
--- /dev/null
+++ b/target/linux/ramips/files/arch/mips/include/asm/mach-ralink/rt305x.h
@@ -0,0 +1,91 @@
+/*
+ * Ralink RT305x SoC specific definitions
+ *
+ * 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.
+ */
+
+#ifndef _RT305X_H_
+#define _RT305X_H_
+
+#include <linux/init.h>
+#include <linux/io.h>
+
+void rt305x_detect_sys_type(void) __init;
+
+#define RT305X_SYS_TYPE_LEN 64
+extern unsigned char rt305x_sys_type[RT305X_SYS_TYPE_LEN];
+
+void rt305x_detect_sys_freq(void) __init;
+
+extern unsigned long rt305x_cpu_freq;
+extern unsigned long rt305x_sys_freq;
+
+#define RT305X_MEM_SIZE_MIN (2 * 1024 * 1024)
+#define RT305X_MEM_SIZE_MAX (64 * 1024 * 1024)
+
+#define RT305X_CPU_IRQ_BASE 0
+#define RT305X_INTC_IRQ_BASE 8
+#define RT305X_INTC_IRQ_COUNT 32
+#define RT305X_GPIO_IRQ_BASE 40
+
+#define RT305X_CPU_IRQ_INTC (RT305X_CPU_IRQ_BASE + 2)
+#define RT305X_CPU_IRQ_FE (RT305X_CPU_IRQ_BASE + 5)
+#define RT305X_CPU_IRQ_WNIC (RT305X_CPU_IRQ_BASE + 6)
+#define RT305X_CPU_IRQ_COUNTER (RT305X_CPU_IRQ_BASE + 7)
+
+#define RT305X_INTC_IRQ_SYSCTL (RT305X_INTC_IRQ_BASE + 0)
+#define RT305X_INTC_IRQ_TIMER0 (RT305X_INTC_IRQ_BASE + 1)
+#define RT305X_INTC_IRQ_TIMER1 (RT305X_INTC_IRQ_BASE + 2)
+#define RT305X_INTC_IRQ_IA (RT305X_INTC_IRQ_BASE + 3)
+#define RT305X_INTC_IRQ_PCM (RT305X_INTC_IRQ_BASE + 4)
+#define RT305X_INTC_IRQ_UART0 (RT305X_INTC_IRQ_BASE + 5)
+#define RT305X_INTC_IRQ_PIO (RT305X_INTC_IRQ_BASE + 6)
+#define RT305X_INTC_IRQ_DMA (RT305X_INTC_IRQ_BASE + 7)
+#define RT305X_INTC_IRQ_NAND (RT305X_INTC_IRQ_BASE + 8)
+#define RT305X_INTC_IRQ_PERFC (RT305X_INTC_IRQ_BASE + 9)
+#define RT305X_INTC_IRQ_I2S (RT305X_INTC_IRQ_BASE + 10)
+#define RT305X_INTC_IRQ_UART1 (RT305X_INTC_IRQ_BASE + 12)
+#define RT305X_INTC_IRQ_ESW (RT305X_INTC_IRQ_BASE + 17)
+#define RT305X_INTC_IRQ_OTG (RT305X_INTC_IRQ_BASE + 18)
+
+extern void __iomem *rt305x_sysc_base;
+extern void __iomem *rt305x_intc_base;
+extern void __iomem *rt305x_memc_base;
+
+static inline void rt305x_sysc_wr(u32 val, unsigned reg)
+{
+ __raw_writel(val, rt305x_sysc_base + reg);
+}
+
+static inline u32 rt305x_sysc_rr(unsigned reg)
+{
+ return __raw_readl(rt305x_sysc_base + reg);
+}
+
+static inline void rt305x_intc_wr(u32 val, unsigned reg)
+{
+ __raw_writel(val, rt305x_intc_base + reg);
+}
+
+static inline u32 rt305x_intc_rr(unsigned reg)
+{
+ return __raw_readl(rt305x_intc_base + reg);
+}
+
+static inline void rt305x_memc_wr(u32 val, unsigned reg)
+{
+ __raw_writel(val, rt305x_memc_base + reg);
+}
+
+static inline u32 rt305x_memc_rr(unsigned reg)
+{
+ return __raw_readl(rt305x_memc_base + reg);
+}
+
+#endif /* _RT305X_H_ */
diff --git a/target/linux/ramips/files/arch/mips/include/asm/mach-ralink/rt305x_regs.h b/target/linux/ramips/files/arch/mips/include/asm/mach-ralink/rt305x_regs.h
new file mode 100644
index 0000000000..7dd9765b80
--- /dev/null
+++ b/target/linux/ramips/files/arch/mips/include/asm/mach-ralink/rt305x_regs.h
@@ -0,0 +1,132 @@
+/*
+ * Ralink RT305 SoC register definitions
+ *
+ * Copyright (C) 2009 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 _RT305X_REGS_H_
+#define _RT305X_REGS_H_
+
+#include <linux/bitops.h>
+
+#define RT305X_SDRAM_BASE 0x00000000
+#define RT305X_SYSC_BASE 0x10000000
+#define RT305X_TIMER_BASE 0x10000100
+#define RT305X_INTC_BASE 0x10000200
+#define RT305X_MEMC_BASE 0x10000300
+#define RT305X_PCM_BASE 0x10000400
+#define RT305X_UART0_BASE 0x10000500
+#define RT305X_PIO_BASE 0x10000600
+#define RT305X_GDMA_BASE 0x10000700
+#define RT305X_NANDC_BASE 0x10000800
+#define RT305X_I2C_BASE 0x10000900
+#define RT305X_I2S_BASE 0x10000a00
+#define RT305X_SPI_BASE 0x10000b00
+#define RT305X_UART1_BASE 0x10000c00
+#define RT305X_FE_BASE 0x10010000
+#define RT305X_SWITCH_BASE 0x10110000
+#define RT305X_WMAC_BASE 0x00180000
+#define RT305X_OTG_BASE 0x101c0000
+#define RT305X_ROM_BASE 0x00400000
+#define RT305X_FLASH1_BASE 0x1b000000
+#define RT305X_FLASH0_BASE 0x1f000000
+
+#define RT305X_SYSC_SIZE 0x100
+#define RT305X_INTC_SIZE 0x100
+#define RT305X_MEMC_SIZE 0x100
+#define RT305X_UART0_SIZE 0x100
+#define RT305X_UART1_SIZE 0x100
+#define RT305X_FLASH1_SIZE (16 * 1024 * 1024)
+#define RT305X_FLASH0_SIZE (4 * 1024 * 1024)
+
+/* SYSC registers */
+#define SYSC_REG_CHIP_NAME0 0x000 /* Chip Name 0 */
+#define SYSC_REG_CHIP_NAME1 0x004 /* Chip Name 1 */
+#define SYSC_REG_CHIP_ID 0x00c /* Chip Identification */
+#define SYSC_REG_SYSTEM_CONFIG 0x010 /* System Configuration */
+#define SYSC_REG_RESET_CTRL 0x034 /* Reset Control*/
+#define SYSC_REG_RESET_STATUS 0x038 /* Reset Status*/
+#define SYSC_REG_IA_ADDRESS 0x310 /* Illegal Access Address */
+#define SYSC_REG_IA_TYPE 0x314 /* Illegal Access Type */
+
+#define CHIP_ID_ID_MASK 0xff
+#define CHIP_ID_ID_SHIFT 8
+#define CHIP_ID_REV_MASK 0xff
+
+#define SYSTEM_CONFIG_CPUCLK_SHIFT 18
+#define SYSTEM_CONFIG_CPUCLK_MASK 0x1
+#define SYSTEM_CONFIG_CPUCLK_320 0x0
+#define SYSTEM_CONFIG_CPUCLK_384 0x1
+
+#define RT305X_RESET_SYSTEM BIT(0)
+#define RT305X_RESET_TIMER BIT(8)
+#define RT305X_RESET_INTC BIT(9)
+#define RT305X_RESET_MEMC BIT(10)
+#define RT305X_RESET_PCM BIT(11)
+#define RT305X_RESET_UART0 BIT(12)
+#define RT305X_RESET_PIO BIT(13)
+#define RT305X_RESET_DMA BIT(14)
+#define RT305X_RESET_I2C BIT(16)
+#define RT305X_RESET_I2S BIT(17)
+#define RT305X_RESET_SPI BIT(18)
+#define RT305X_RESET_UART1 BIT(19)
+#define RT305X_RESET_WNIC BIT(20)
+#define RT305X_RESET_FE BIT(21)
+#define RT305X_RESET_OTG BIT(22)
+#define RT305X_RESET_ESW BIT(23)
+
+/* TIMER registers */
+
+/* INTC register */
+#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 RT305X_INTC_INT_SYSCTL BIT(0)
+#define RT305X_INTC_INT_TIMER0 BIT(1)
+#define RT305X_INTC_INT_TIMER1 BIT(2)
+#define RT305X_INTC_INT_IA BIT(3)
+#define RT305X_INTC_INT_PCM BIT(4)
+#define RT305X_INTC_INT_UART0 BIT(5)
+#define RT305X_INTC_INT_PIO BIT(6)
+#define RT305X_INTC_INT_DMA BIT(7)
+#define RT305X_INTC_INT_NAND BIT(8)
+#define RT305X_INTC_INT_PERFC BIT(9)
+#define RT305X_INTC_INT_I2S BIT(10)
+#define RT305X_INTC_INT_UART1 BIT(12)
+#define RT305X_INTC_INT_ESW BIT(17)
+#define RT305X_INTC_INT_OTG BIT(18)
+#define RT305X_INTC_INT_GLOBAL BIT(31)
+
+/* MEMC registers */
+#define MEMC_REG_SDRAM_CFG0 0x00
+#define MEMC_REG_SDRAM_CFG1 0x04
+#define MEMC_REG_FLASH_CFG0 0x08
+#define MEMC_REG_FLASH_CFG1 0x0c
+#define MEMC_REG_IA_ADDR 0x10
+#define MEMC_REG_IA_TYPE 0x14
+
+#define FLASH_CFG_WIDTH_SHIFT 26
+#define FLASH_CFG_WIDTH_MASK 0x3
+#define FLASH_CFG_WIDTH_8BIT 0x0
+#define FLASH_CFG_WIDTH_16BIT 0x1
+#define FLASH_CFG_WIDTH_32BIT 0x2
+
+/* UART registers */
+#define UART_REG_RX 0
+#define UART_REG_TX 1
+#define UART_REG_IER 2
+#define UART_REG_IIR 3
+#define UART_REG_FCR 4
+#define UART_REG_LCR 5
+#define UART_REG_MCR 6
+#define UART_REG_LSR 7
+
+#endif /* _RT305X_REGS_H_ */
diff --git a/target/linux/ramips/files/arch/mips/include/asm/mach-ralink/war.h b/target/linux/ramips/files/arch/mips/include/asm/mach-ralink/war.h
new file mode 100644
index 0000000000..e27cb28648
--- /dev/null
+++ b/target/linux/ramips/files/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_RT288X_WAR_H
+#define __ASM_MACH_RT288X_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_RT288X_WAR_H */
diff --git a/target/linux/ramips/files/arch/mips/ralink/Kconfig b/target/linux/ramips/files/arch/mips/ralink/Kconfig
new file mode 100644
index 0000000000..e180eabd65
--- /dev/null
+++ b/target/linux/ramips/files/arch/mips/ralink/Kconfig
@@ -0,0 +1,51 @@
+if MIPS_RALINK
+
+choice
+ prompt "Ralink SoC selection"
+ default SOC_RT288X
+ help
+ Select Ralink MIPS SoC type.
+
+ config RALINK_RT288X
+ bool "RT288x"
+ select SOC_RT288X
+
+ config RALINK_RT305X
+ bool "RT305x"
+ select SOC_RT305X
+
+endchoice
+
+source "arch/mips/ralink/rt288x/Kconfig"
+source "arch/mips/ralink/rt305x/Kconfig"
+
+config SOC_RT288X
+ bool
+ select CEVT_R4K
+ select CSRC_R4K
+ select DMA_NONCOHERENT
+ select IRQ_CPU
+ select ARCH_REQUIRE_GPIOLIB
+ 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 HW_HAS_PCI
+ select MIPS_MACHINE
+
+config SOC_RT305X
+ bool
+ select CEVT_R4K
+ select CSRC_R4K
+ select DMA_NONCOHERENT
+ select IRQ_CPU
+ select ARCH_REQUIRE_GPIOLIB
+ 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 MIPS_MACHINE
+
+endif
diff --git a/target/linux/ramips/files/arch/mips/ralink/rt288x/Kconfig b/target/linux/ramips/files/arch/mips/ralink/rt288x/Kconfig
new file mode 100644
index 0000000000..dd06596261
--- /dev/null
+++ b/target/linux/ramips/files/arch/mips/ralink/rt288x/Kconfig
@@ -0,0 +1,11 @@
+if RALINK_RT288X
+
+menu "Ralink RT288x machine selection"
+
+config RT288X_MACH_GENERIC
+ bool "Generic RT288x based machine support"
+ default y
+
+endmenu
+
+endif
diff --git a/target/linux/ramips/files/arch/mips/ralink/rt288x/Makefile b/target/linux/ramips/files/arch/mips/ralink/rt288x/Makefile
new file mode 100644
index 0000000000..4c22a6dc8a
--- /dev/null
+++ b/target/linux/ramips/files/arch/mips/ralink/rt288x/Makefile
@@ -0,0 +1,15 @@
+#
+# Makefile for the Ralink RT288x SoC specific parts of the kernel
+#
+# 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.
+
+obj-y := prom.o irq.o setup.o rt288x.o platform.o
+
+obj-$(CONFIG_EARLY_PRINTK) += early_printk.o
+
+obj-$(CONFIG_RT288X_MACH_GENERIC) += mach-generic.o
diff --git a/target/linux/ramips/files/arch/mips/ralink/rt288x/early_printk.c b/target/linux/ramips/files/arch/mips/ralink/rt288x/early_printk.c
new file mode 100644
index 0000000000..9fd7adb543
--- /dev/null
+++ b/target/linux/ramips/files/arch/mips/ralink/rt288x/early_printk.c
@@ -0,0 +1,30 @@
+/*
+ * Ralink RT288x SoC early printk support
+ *
+ * Copyright (C) 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.
+ */
+
+#include <linux/io.h>
+#include <linux/serial_reg.h>
+
+#include <asm/addrspace.h>
+
+#include <asm/mach-ralink/rt288x_regs.h>
+
+#define UART_READ(r) \
+ __raw_readl((void __iomem *)(KSEG1ADDR(RT2880_UART1_BASE) + 4 * (r)))
+
+#define UART_WRITE(r, v) \
+ __raw_writel((v), (void __iomem *)(KSEG1ADDR(RT2880_UART1_BASE) + 4 * (r)))
+
+void prom_putchar(unsigned char ch)
+{
+ while (((UART_READ(UART_REG_LSR)) & UART_LSR_THRE) == 0);
+ UART_WRITE(UART_REG_TX, ch);
+ while (((UART_READ(UART_REG_LSR)) & UART_LSR_THRE) == 0);
+}
diff --git a/target/linux/ramips/files/arch/mips/ralink/rt288x/irq.c b/target/linux/ramips/files/arch/mips/ralink/rt288x/irq.c
new file mode 100644
index 0000000000..47a5374009
--- /dev/null
+++ b/target/linux/ramips/files/arch/mips/ralink/rt288x/irq.c
@@ -0,0 +1,125 @@
+/*
+ * Ralink RT288x SoC specific interrupt handling
+ *
+ * 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.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+
+#include <asm/irq_cpu.h>
+#include <asm/mipsregs.h>
+
+#include <asm/mach-ralink/rt288x.h>
+#include <asm/mach-ralink/rt288x_regs.h>
+
+static void rt288x_intc_irq_dispatch(void)
+{
+ u32 pending;
+
+ pending = rt288x_intc_rr(INTC_REG_STATUS0);
+
+ if (pending & RT2880_INTC_INT_TIMER0)
+ do_IRQ(RT2880_INTC_IRQ_TIMER0);
+
+ else if (pending & RT2880_INTC_INT_TIMER1)
+ do_IRQ(RT2880_INTC_IRQ_TIMER1);
+
+ else if (pending & RT2880_INTC_INT_UART0)
+ do_IRQ(RT2880_INTC_IRQ_UART0);
+
+ else if (pending & RT2880_INTC_INT_PCM)
+ do_IRQ(RT2880_INTC_IRQ_PCM);
+
+ else if (pending & RT2880_INTC_INT_UART1)
+ do_IRQ(RT2880_INTC_IRQ_UART1);
+
+ /* TODO: handle PIO interrupts as well */
+
+ else
+ spurious_interrupt();
+}
+
+static void rt288x_intc_irq_unmask(unsigned int irq)
+{
+ irq -= RT288X_INTC_IRQ_BASE;
+ rt288x_intc_wr((1 << irq), INTC_REG_ENABLE);
+}
+
+static void rt288x_intc_irq_mask(unsigned int irq)
+{
+ irq -= RT288X_INTC_IRQ_BASE;
+ rt288x_intc_wr((1 << irq), INTC_REG_DISABLE);
+}
+
+struct irq_chip rt288x_intc_irq_chip = {
+ .name = "RT288X INTC",
+ .unmask = rt288x_intc_irq_unmask,
+ .mask = rt288x_intc_irq_mask,
+ .mask_ack = rt288x_intc_irq_mask,
+};
+
+static struct irqaction rt288x_intc_irqaction = {
+ .handler = no_action,
+ .name = "cascade [RT288X INTC]",
+};
+
+static void __init rt288x_intc_irq_init(void)
+{
+ int i;
+
+ /* disable all interrupts */
+ rt288x_intc_wr(~0, INTC_REG_DISABLE);
+
+ /* route all INTC interrupts to MIPS HW0 interrupt */
+ rt288x_intc_wr(0, INTC_REG_TYPE);
+
+ for (i = RT288X_INTC_IRQ_BASE;
+ i < RT288X_INTC_IRQ_BASE + RT288X_INTC_IRQ_COUNT; i++) {
+ irq_desc[i].status = IRQ_DISABLED;
+ set_irq_chip_and_handler(i, &rt288x_intc_irq_chip,
+ handle_level_irq);
+ }
+
+ setup_irq(RT288X_CPU_IRQ_INTC, &rt288x_intc_irqaction);
+
+ rt288x_intc_wr(RT2880_INTC_INT_GLOBAL, INTC_REG_ENABLE);
+}
+
+asmlinkage void plat_irq_dispatch(void)
+{
+ unsigned long pending;
+
+ pending = read_c0_status() & read_c0_cause() & ST0_IM;
+
+ if (pending & STATUSF_IP7)
+ do_IRQ(RT288X_CPU_IRQ_COUNTER);
+
+ else if (pending & STATUSF_IP4)
+ do_IRQ(RT288X_CPU_IRQ_PCI);
+
+ else if (pending & STATUSF_IP5)
+ do_IRQ(RT288X_CPU_IRQ_FE);
+
+ else if (pending & STATUSF_IP6)
+ do_IRQ(RT288X_CPU_IRQ_WNIC);
+
+ else if (pending & STATUSF_IP2)
+ rt288x_intc_irq_dispatch();
+
+ else
+ spurious_interrupt();
+}
+
+void __init arch_init_irq(void)
+{
+ mips_cpu_irq_init();
+ rt288x_intc_irq_init();
+}
diff --git a/target/linux/ramips/files/arch/mips/ralink/rt288x/mach-generic.c b/target/linux/ramips/files/arch/mips/ralink/rt288x/mach-generic.c
new file mode 100644
index 0000000000..dd05e48e19
--- /dev/null
+++ b/target/linux/ramips/files/arch/mips/ralink/rt288x/mach-generic.c
@@ -0,0 +1,65 @@
+/*
+ * Generic RT288x machine setup
+ *
+ * Copyright (C) 2008 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.
+ */
+
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <linux/mtd/physmap.h>
+
+#include <asm/mips_machine.h>
+#include <asm/mach-ralink/rt288x.h>
+#include <asm/mach-ralink/platform.h>
+
+#ifdef CONFIG_MTD_PARTITIONS
+static struct mtd_partition generic_partitions[] = {
+ {
+ .name = "u-boot",
+ .offset = 0,
+ .size = 0x030000,
+ .mask_flags = MTD_WRITEABLE,
+ }, {
+ .name = "config",
+ .offset = 0x030000,
+ .size = 0x010000,
+ .mask_flags = MTD_WRITEABLE,
+ }, {
+ .name = "defconfig",
+ .offset = 0x040000,
+ .size = 0x010000,
+ .mask_flags = MTD_WRITEABLE,
+ }, {
+ .name = "kernel",
+ .offset = 0x050000,
+ .size = 0x100000,
+ }, {
+ .name = "rootfs",
+// .offset = MTDPART_OFS_NXTBLK,
+// .size = MTDPART_SIZ_FULL,
+ .offset = 0x150000,
+ .size = 0x2B0000,
+ }
+};
+#endif /* CONFIG_MTD_PARTITIONS */
+
+static struct physmap_flash_data generic_flash_data = {
+#ifdef CONFIG_MTD_PARTITIONS
+ .nr_parts = ARRAY_SIZE(generic_partitions),
+ .parts = generic_partitions,
+#endif
+};
+
+static void __init rt288x_generic_init(void)
+{
+ rt288x_register_flash(0, &generic_flash_data);
+}
+
+MIPS_MACHINE(RT288X_MACH_GENERIC, "Generic RT288x board", rt288x_generic_init);
diff --git a/target/linux/ramips/files/arch/mips/ralink/rt288x/platform.c b/target/linux/ramips/files/arch/mips/ralink/rt288x/platform.c
new file mode 100644
index 0000000000..a686286968
--- /dev/null
+++ b/target/linux/ramips/files/arch/mips/ralink/rt288x/platform.c
@@ -0,0 +1,97 @@
+/*
+ * Ralink RT288x SoC platform device registration
+ *
+ * Copyright (C) 2008 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.
+ */
+
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/physmap.h>
+
+#include <asm/addrspace.h>
+
+#include <asm/mach-ralink/rt288x.h>
+#include <asm/mach-ralink/rt288x_regs.h>
+#include <asm/mach-ralink/platform.h>
+
+static struct resource rt288x_flash0_resources[] = {
+ {
+ .flags = IORESOURCE_MEM,
+ .start = KSEG1ADDR(RT2880_FLASH0_BASE),
+ .end = KSEG1ADDR(RT2880_FLASH0_BASE) +
+ RT2880_FLASH0_SIZE - 1,
+ },
+};
+
+static struct platform_device rt288x_flash0_device = {
+ .name = "physmap-flash",
+ .resource = rt288x_flash0_resources,
+ .num_resources = ARRAY_SIZE(rt288x_flash0_resources),
+};
+
+static struct resource rt288x_flash1_resources[] = {
+ {
+ .flags = IORESOURCE_MEM,
+ .start = KSEG1ADDR(RT2880_FLASH1_BASE),
+ .end = KSEG1ADDR(RT2880_FLASH1_BASE) +
+ RT2880_FLASH1_SIZE - 1,
+ },
+};
+
+static struct platform_device rt288x_flash1_device = {
+ .name = "physmap-flash",
+ .resource = rt288x_flash1_resources,
+ .num_resources = ARRAY_SIZE(rt288x_flash1_resources),
+};
+
+static int rt288x_flash_instance __initdata;
+void __init rt288x_register_flash(unsigned int id,
+ struct physmap_flash_data *pdata)
+{
+ struct platform_device *pdev;
+ u32 t;
+ int reg;
+
+ switch (id) {
+ case 0:
+ pdev = &rt288x_flash0_device;
+ reg = MEMC_REG_FLASH_CFG0;
+ break;
+ case 1:
+ pdev = &rt288x_flash1_device;
+ reg = MEMC_REG_FLASH_CFG1;
+ break;
+ default:
+ return;
+ }
+
+ t = rt288x_memc_rr(reg);
+ t = (t >> FLASH_CFG_WIDTH_SHIFT) & FLASH_CFG_WIDTH_MASK;
+
+ switch (t) {
+ case FLASH_CFG_WIDTH_8BIT:
+ pdata->width = 1;
+ break;
+ case FLASH_CFG_WIDTH_16BIT:
+ pdata->width = 2;
+ break;
+ case FLASH_CFG_WIDTH_32BIT:
+ pdata->width = 4;
+ break;
+ default:
+ printk(KERN_ERR "RT288x: flash bank%u witdh is invalid\n", id);
+ return;
+ }
+
+ pdev->dev.platform_data = pdata;
+ pdev->id = rt288x_flash_instance;
+
+ platform_device_register(pdev);
+ rt288x_flash_instance++;
+}
diff --git a/target/linux/ramips/files/arch/mips/ralink/rt288x/prom.c b/target/linux/ramips/files/arch/mips/ralink/rt288x/prom.c
new file mode 100644
index 0000000000..80ef719e0c
--- /dev/null
+++ b/target/linux/ramips/files/arch/mips/ralink/rt288x/prom.c
@@ -0,0 +1,37 @@
+/*
+ * Ralink RT288x SoC specific prom routines
+ *
+ * Copyright (C) 2008 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.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/serial_reg.h>
+
+#include <asm/bootinfo.h>
+#include <asm/addrspace.h>
+
+#include <asm/mach-ralink/rt288x.h>
+#include <asm/mach-ralink/rt288x_regs.h>
+
+void __init prom_init(void)
+{
+ printk(KERN_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);
+
+ rt288x_mach_type = RT288X_MACH_GENERIC;
+}
+
+void __init prom_free_prom_memory(void)
+{
+ /* We do not have to prom memory to free */
+}
+
diff --git a/target/linux/ramips/files/arch/mips/ralink/rt288x/rt288x.c b/target/linux/ramips/files/arch/mips/ralink/rt288x/rt288x.c
new file mode 100644
index 0000000000..cd429a1c05
--- /dev/null
+++ b/target/linux/ramips/files/arch/mips/ralink/rt288x/rt288x.c
@@ -0,0 +1,77 @@
+/*
+ * Ralink RT288x SoC specific setup
+ *
+ * Copyright (C) 2008 Gabor Juhos <juhosg@openwrt.org>
+ * Copyright (C) 2008 Imre Kaloz <kaloz@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/kernel.h>
+#include <linux/init.h>
+#include <linux/module.h>
+
+#include <asm/mach-ralink/rt288x.h>
+#include <asm/mach-ralink/rt288x_regs.h>
+
+unsigned char rt288x_sys_type[RT288X_SYS_TYPE_LEN];
+
+unsigned long rt288x_cpu_freq;
+EXPORT_SYMBOL_GPL(rt288x_cpu_freq);
+
+unsigned long rt288x_sys_freq;
+EXPORT_SYMBOL_GPL(rt288x_sys_freq);
+
+void __iomem * rt288x_intc_base;
+void __iomem * rt288x_sysc_base;
+void __iomem * rt288x_memc_base;
+
+void __init rt288x_detect_sys_type(void)
+{
+ u32 n0;
+ u32 n1;
+ u32 id;
+
+ n0 = rt288x_sysc_rr(SYSC_REG_CHIP_NAME0);
+ n1 = rt288x_sysc_rr(SYSC_REG_CHIP_NAME1);
+ id = rt288x_sysc_rr(SYSC_REG_CHIP_ID);
+
+ snprintf(rt288x_sys_type, RT288X_SYS_TYPE_LEN,
+ "Ralink %c%c%c%c%c%c%c%c id:%u rev:%u",
+ (char) (n0 & 0xff), (char) ((n0 >> 8) & 0xff),
+ (char) ((n0 >> 16) & 0xff), (char) ((n0 >> 24) & 0xff),
+ (char) (n1 & 0xff), (char) ((n1 >> 8) & 0xff),
+ (char) ((n1 >> 16) & 0xff), (char) ((n1 >> 24) & 0xff),
+ (id >> CHIP_ID_ID_SHIFT) & CHIP_ID_ID_MASK,
+ (id & CHIP_ID_REV_MASK));
+}
+
+void __init rt288x_detect_sys_freq(void)
+{
+ u32 t;
+
+ t = rt288x_sysc_rr(SYSC_REG_SYSTEM_CONFIG);
+ t = ((t >> SYSTEM_CONFIG_CPUCLK_SHIFT) & SYSTEM_CONFIG_CPUCLK_MASK);
+
+ switch (t) {
+ case SYSTEM_CONFIG_CPUCLK_250:
+ rt288x_cpu_freq = 250000000;
+ break;
+ case SYSTEM_CONFIG_CPUCLK_266:
+ rt288x_cpu_freq = 266666667;
+ break;
+ case SYSTEM_CONFIG_CPUCLK_280:
+ rt288x_cpu_freq = 280000000;
+ break;
+ case SYSTEM_CONFIG_CPUCLK_300:
+ rt288x_cpu_freq = 300000000;
+ break;
+ }
+
+ rt288x_sys_freq = rt288x_cpu_freq / 2;
+}
+
diff --git a/target/linux/ramips/files/arch/mips/ralink/rt288x/setup.c b/target/linux/ramips/files/arch/mips/ralink/rt288x/setup.c
new file mode 100644
index 0000000000..186db29d11
--- /dev/null
+++ b/target/linux/ramips/files/arch/mips/ralink/rt288x/setup.c
@@ -0,0 +1,142 @@
+/*
+ * Ralink RT288x SoC specific setup
+ *
+ * Copyright (C) 2008 Gabor Juhos <juhosg@openwrt.org>
+ * Copyright (C) 2008 Imre Kaloz <kaloz@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/kernel.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/serial_8250.h>
+
+#include <asm/bootinfo.h>
+#include <asm/mips_machine.h>
+#include <asm/reboot.h>
+#include <asm/time.h>
+
+#include <asm/mach-ralink/rt288x.h>
+#include <asm/mach-ralink/rt288x_regs.h>
+
+#define RT288X_MEM_SIZE_MIN (2 * 1024 * 1024)
+#define RT288X_MEM_SIZE_MAX (128 * 1024 * 1024)
+
+unsigned long rt288x_mach_type;
+
+static void rt288x_restart(char *command)
+{
+ rt288x_sysc_wr(RT2880_RESET_SYSTEM, SYSC_REG_RESET_CTRL);
+ while (1)
+ if (cpu_wait)
+ cpu_wait();
+}
+
+static void rt288x_halt(void)
+{
+ while (1)
+ cpu_wait();
+}
+
+static void __init rt288x_detect_mem_size(void)
+{
+ unsigned long size;
+
+ for (size = RT288X_MEM_SIZE_MIN; size < RT288X_MEM_SIZE_MAX;
+ size <<= 1 ) {
+ if (!memcmp(rt288x_detect_mem_size,
+ rt288x_detect_mem_size + size, 1024))
+ break;
+ }
+
+ add_memory_region(RT2880_SDRAM_BASE, size, BOOT_MEM_RAM);
+}
+
+#ifdef CONFIG_RT288X_EARLY_SERIAL
+static void __init rt288x_early_serial_setup(void)
+{
+ struct uart_port p;
+ int err;
+
+ memset(&p, 0, sizeof(p));
+ p.flags = UPF_SKIP_TEST;
+ p.iotype = UPIO_AU;
+ p.uartclk = rt288x_sys_freq;
+ p.regshift = 2;
+ p.type = PORT_16550A;
+
+ p.mapbase = RT2880_UART0_BASE;
+ p.membase = ioremap_nocache(p.mapbase, RT2880_UART0_SIZE);
+ p.line = 0;
+ p.irq = RT2880_INTC_IRQ_UART0;
+
+ err = early_serial_setup(&p);
+ if (err)
+ printk(KERN_ERR "RT288x: early UART0 registration failed %d\n",
+ err);
+
+ p.mapbase = RT2880_UART1_BASE;
+ p.membase = ioremap_nocache(p.mapbase, RT2880_UART1_SIZE);
+ p.line = 1;
+ p.irq = RT2880_INTC_IRQ_UART1;
+
+ err = early_serial_setup(&p);
+ if (err)
+ printk(KERN_ERR "RT288x: early UART1 registration failed %d\n",
+ err);
+}
+#else
+static inline void rt288x_early_serial_setup(void) {};
+#endif /* CONFIG_RT288X_EARLY_SERIAL */
+
+const char *get_system_type(void)
+{
+ return rt288x_sys_type;
+}
+
+unsigned int __cpuinit get_c0_compare_irq(void)
+{
+ return CP0_LEGACY_COMPARE_IRQ;
+}
+
+void __init plat_mem_setup(void)
+{
+ set_io_port_base(KSEG1);
+
+ rt288x_intc_base = ioremap_nocache(RT2880_INTC_BASE, RT2880_INTC_SIZE);
+ rt288x_sysc_base = ioremap_nocache(RT2880_SYSC_BASE, RT2880_SYSC_SIZE);
+ rt288x_memc_base = ioremap_nocache(RT2880_MEMC_BASE, RT2880_MEMC_SIZE);
+
+ rt288x_detect_mem_size();
+ rt288x_detect_sys_type();
+ rt288x_detect_sys_freq();
+
+ printk(KERN_INFO "%s running at %lu.%02lu MHz\n", get_system_type(),
+ rt288x_cpu_freq / 1000000,
+ (rt288x_cpu_freq % 1000000) * 100 / 1000000);
+
+ _machine_restart = rt288x_restart;
+ _machine_halt = rt288x_halt;
+ pm_power_off = rt288x_halt;
+
+ rt288x_early_serial_setup();
+}
+
+void __init plat_time_init(void)
+{
+ mips_hpt_frequency = rt288x_cpu_freq / 2;
+}
+
+static int __init rt288x_machine_setup(void)
+{
+ mips_machine_setup(rt288x_mach_type);
+
+ return 0;
+}
+
+arch_initcall(rt288x_machine_setup);
diff --git a/target/linux/ramips/files/arch/mips/ralink/rt305x/Kconfig b/target/linux/ramips/files/arch/mips/ralink/rt305x/Kconfig
new file mode 100644
index 0000000000..3b5e15e1b8
--- /dev/null
+++ b/target/linux/ramips/files/arch/mips/ralink/rt305x/Kconfig
@@ -0,0 +1,15 @@
+if RALINK_RT305X
+
+menu "Ralink RT350x machine selection"
+
+config RT305X_MACH_GENERIC
+ bool "Generic RT350x based machine support"
+ default y
+
+config RT305X_MACH_WHR_G300N
+ bool "Buffalo WHR-G300N support"
+ default y
+
+endmenu
+
+endif
diff --git a/target/linux/ramips/files/arch/mips/ralink/rt305x/Makefile b/target/linux/ramips/files/arch/mips/ralink/rt305x/Makefile
new file mode 100644
index 0000000000..981498e858
--- /dev/null
+++ b/target/linux/ramips/files/arch/mips/ralink/rt305x/Makefile
@@ -0,0 +1,15 @@
+#
+# Makefile for the Ralink RT305x SoC specific parts of the kernel
+#
+# Copyright (C) 2009 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.
+
+obj-y := prom.o irq.o setup.o devices.o rt305x.o
+
+obj-$(CONFIG_EARLY_PRINTK) += early_printk.o
+
+obj-$(CONFIG_RT305X_MACH_GENERIC) += mach-generic.o
+obj-$(CONFIG_RT305X_MACH_WHR_G300N) += mach-whr-g300n.o
diff --git a/target/linux/ramips/files/arch/mips/ralink/rt305x/devices.c b/target/linux/ramips/files/arch/mips/ralink/rt305x/devices.c
new file mode 100644
index 0000000000..5dd1022b97
--- /dev/null
+++ b/target/linux/ramips/files/arch/mips/ralink/rt305x/devices.c
@@ -0,0 +1,96 @@
+/*
+ * Ralink RT305x SoC platform device registration
+ *
+ * Copyright (C) 2009 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.
+ */
+
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/physmap.h>
+
+#include <asm/addrspace.h>
+
+#include <asm/mach-ralink/rt305x.h>
+#include <asm/mach-ralink/rt305x_regs.h>
+#include "devices.h"
+
+static struct resource rt305x_flash0_resources[] = {
+ {
+ .flags = IORESOURCE_MEM,
+ .start = KSEG1ADDR(RT305X_FLASH0_BASE),
+ .end = KSEG1ADDR(RT305X_FLASH0_BASE) +
+ RT305X_FLASH0_SIZE - 1,
+ },
+};
+
+static struct platform_device rt305x_flash0_device = {
+ .name = "physmap-flash",
+ .resource = rt305x_flash0_resources,
+ .num_resources = ARRAY_SIZE(rt305x_flash0_resources),
+};
+
+static struct resource rt305x_flash1_resources[] = {
+ {
+ .flags = IORESOURCE_MEM,
+ .start = KSEG1ADDR(RT305X_FLASH1_BASE),
+ .end = KSEG1ADDR(RT305X_FLASH1_BASE) +
+ RT305X_FLASH1_SIZE - 1,
+ },
+};
+
+static struct platform_device rt305x_flash1_device = {
+ .name = "physmap-flash",
+ .resource = rt305x_flash1_resources,
+ .num_resources = ARRAY_SIZE(rt305x_flash1_resources),
+};
+
+static int rt305x_flash_instance __initdata;
+void __init rt305x_register_flash(unsigned int id,
+ struct physmap_flash_data *pdata)
+{
+ struct platform_device *pdev;
+ u32 t;
+ int reg;
+
+ switch (id) {
+ case 0:
+ pdev = &rt305x_flash0_device;
+ reg = MEMC_REG_FLASH_CFG0;
+ break;
+ case 1:
+ pdev = &rt305x_flash1_device;
+ reg = MEMC_REG_FLASH_CFG1;
+ break;
+ default:
+ return;
+ }
+
+ t = rt305x_memc_rr(reg);
+ t = (t >> FLASH_CFG_WIDTH_SHIFT) & FLASH_CFG_WIDTH_MASK;
+
+ switch (t) {
+ case FLASH_CFG_WIDTH_8BIT:
+ pdata->width = 1;
+ break;
+ case FLASH_CFG_WIDTH_16BIT:
+ pdata->width = 2;
+ break;
+ case FLASH_CFG_WIDTH_32BIT:
+ pdata->width = 4;
+ break;
+ default:
+ printk(KERN_ERR "RT305x: flash bank%u witdh is invalid\n", id);
+ return;
+ }
+
+ pdev->dev.platform_data = pdata;
+ pdev->id = rt305x_flash_instance;
+
+ platform_device_register(pdev);
+ rt305x_flash_instance++;
+}
diff --git a/target/linux/ramips/files/arch/mips/ralink/rt305x/devices.h b/target/linux/ramips/files/arch/mips/ralink/rt305x/devices.h
new file mode 100644
index 0000000000..0a90b3a4e1
--- /dev/null
+++ b/target/linux/ramips/files/arch/mips/ralink/rt305x/devices.h
@@ -0,0 +1,20 @@
+/*
+ * Ralink RT305x SoC specific platform device definitions
+ *
+ * Copyright (C) 2009 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 __RT305X_DEVICES_H
+#define __RT305X_DEVICES_H
+
+struct physmap_flash_data;
+
+extern void rt305x_register_flash(unsigned int id,
+ struct physmap_flash_data *pdata) __init;
+
+#endif /* __RT305X_DEVICES_H */
+
diff --git a/target/linux/ramips/files/arch/mips/ralink/rt305x/early_printk.c b/target/linux/ramips/files/arch/mips/ralink/rt305x/early_printk.c
new file mode 100644
index 0000000000..602df863ef
--- /dev/null
+++ b/target/linux/ramips/files/arch/mips/ralink/rt305x/early_printk.c
@@ -0,0 +1,29 @@
+/*
+ * Ralink RT305x SoC early printk support
+ *
+ * Copyright (C) 2009 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.
+ */
+
+#include <linux/io.h>
+#include <linux/serial_reg.h>
+
+#include <asm/addrspace.h>
+
+#include <asm/mach-ralink/rt305x_regs.h>
+
+#define UART_READ(r) \
+ __raw_readl((void __iomem *)(KSEG1ADDR(RT305X_UART1_BASE) + 4 * (r)))
+
+#define UART_WRITE(r, v) \
+ __raw_writel((v), (void __iomem *)(KSEG1ADDR(RT305X_UART1_BASE) + 4 * (r)))
+
+void prom_putchar(unsigned char ch)
+{
+ while (((UART_READ(UART_REG_LSR)) & UART_LSR_THRE) == 0);
+ UART_WRITE(UART_REG_TX, ch);
+ while (((UART_READ(UART_REG_LSR)) & UART_LSR_THRE) == 0);
+}
diff --git a/target/linux/ramips/files/arch/mips/ralink/rt305x/irq.c b/target/linux/ramips/files/arch/mips/ralink/rt305x/irq.c
new file mode 100644
index 0000000000..168b2390b9
--- /dev/null
+++ b/target/linux/ramips/files/arch/mips/ralink/rt305x/irq.c
@@ -0,0 +1,118 @@
+/*
+ * Ralink RT305x SoC specific interrupt handling
+ *
+ * Copyright (C) 2009 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.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+
+#include <asm/irq_cpu.h>
+#include <asm/mipsregs.h>
+
+#include <asm/mach-ralink/rt305x.h>
+#include <asm/mach-ralink/rt305x_regs.h>
+
+static void rt305x_intc_irq_dispatch(void)
+{
+ u32 pending;
+
+ pending = rt305x_intc_rr(INTC_REG_STATUS0);
+
+ if (pending & RT305X_INTC_INT_TIMER0)
+ do_IRQ(RT305X_INTC_IRQ_TIMER0);
+
+ else if (pending & RT305X_INTC_INT_TIMER1)
+ do_IRQ(RT305X_INTC_IRQ_TIMER1);
+
+ else if (pending & RT305X_INTC_INT_UART0)
+ do_IRQ(RT305X_INTC_IRQ_UART0);
+
+ else if (pending & RT305X_INTC_INT_UART1)
+ do_IRQ(RT305X_INTC_IRQ_UART1);
+
+ /* TODO: handle PIO interrupts as well */
+
+ else
+ spurious_interrupt();
+}
+
+static void rt305x_intc_irq_unmask(unsigned int irq)
+{
+ irq -= RT305X_INTC_IRQ_BASE;
+ rt305x_intc_wr((1 << irq), INTC_REG_ENABLE);
+}
+
+static void rt305x_intc_irq_mask(unsigned int irq)
+{
+ irq -= RT305X_INTC_IRQ_BASE;
+ rt305x_intc_wr((1 << irq), INTC_REG_DISABLE);
+}
+
+struct irq_chip rt305x_intc_irq_chip = {
+ .name = "RT305X INTC",
+ .unmask = rt305x_intc_irq_unmask,
+ .mask = rt305x_intc_irq_mask,
+ .mask_ack = rt305x_intc_irq_mask,
+};
+
+static struct irqaction rt305x_intc_irqaction = {
+ .handler = no_action,
+ .name = "cascade [RT305X INTC]",
+};
+
+static void __init rt305x_intc_irq_init(void)
+{
+ int i;
+
+ /* disable all interrupts */
+ rt305x_intc_wr(~0, INTC_REG_DISABLE);
+
+ /* route all INTC interrupts to MIPS HW0 interrupt */
+ rt305x_intc_wr(0, INTC_REG_TYPE);
+
+ for (i = RT305X_INTC_IRQ_BASE;
+ i < RT305X_INTC_IRQ_BASE + RT305X_INTC_IRQ_COUNT; i++) {
+ set_irq_chip_and_handler(i, &rt305x_intc_irq_chip,
+ handle_level_irq);
+ }
+
+ setup_irq(RT305X_CPU_IRQ_INTC, &rt305x_intc_irqaction);
+
+ /* enable interrupt masking */
+ rt305x_intc_wr(RT305X_INTC_INT_GLOBAL, INTC_REG_ENABLE);
+}
+
+asmlinkage void plat_irq_dispatch(void)
+{
+ unsigned long pending;
+
+ pending = read_c0_status() & read_c0_cause() & ST0_IM;
+
+ if (pending & STATUSF_IP7)
+ do_IRQ(RT305X_CPU_IRQ_COUNTER);
+
+ else if (pending & STATUSF_IP5)
+ do_IRQ(RT305X_CPU_IRQ_FE);
+
+ else if (pending & STATUSF_IP6)
+ do_IRQ(RT305X_CPU_IRQ_WNIC);
+
+ else if (pending & STATUSF_IP2)
+ rt305x_intc_irq_dispatch();
+
+ else
+ spurious_interrupt();
+}
+
+void __init arch_init_irq(void)
+{
+ mips_cpu_irq_init();
+ rt305x_intc_irq_init();
+}
diff --git a/target/linux/ramips/files/arch/mips/ralink/rt305x/mach-generic.c b/target/linux/ramips/files/arch/mips/ralink/rt305x/mach-generic.c
new file mode 100644
index 0000000000..3b2b70298d
--- /dev/null
+++ b/target/linux/ramips/files/arch/mips/ralink/rt305x/mach-generic.c
@@ -0,0 +1,21 @@
+/*
+ * Generic RT305x machine setup
+ *
+ * Copyright (C) 2009 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.
+ */
+
+#include <linux/init.h>
+
+#include <asm/mips_machine.h>
+
+#include "machine.h"
+
+static void __init rt305x_generic_init(void)
+{
+}
+
+MIPS_MACHINE(RT305X_MACH_GENERIC, "Generic RT305x board", rt305x_generic_init);
diff --git a/target/linux/ramips/files/arch/mips/ralink/rt305x/mach-whr-g300n.c b/target/linux/ramips/files/arch/mips/ralink/rt305x/mach-whr-g300n.c
new file mode 100644
index 0000000000..b1f6dafabc
--- /dev/null
+++ b/target/linux/ramips/files/arch/mips/ralink/rt305x/mach-whr-g300n.c
@@ -0,0 +1,71 @@
+/*
+ * Generic RT305x machine setup
+ *
+ * Copyright (C) 2009 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.
+ */
+
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <linux/mtd/physmap.h>
+
+#include <asm/mips_machine.h>
+
+#include "machine.h"
+#include "devices.h"
+
+#ifdef CONFIG_MTD_PARTITIONS
+static struct mtd_partition whr_g300n_partitions[] = {
+ {
+ .name = "u-boot",
+ .offset = 0,
+ .size = 0x030000,
+ .mask_flags = MTD_WRITEABLE,
+ }, {
+ .name = "u-boot-env",
+ .offset = 0x030000,
+ .size = 0x010000,
+ .mask_flags = MTD_WRITEABLE,
+ }, {
+ .name = "factory",
+ .offset = 0x040000,
+ .size = 0x010000,
+ .mask_flags = MTD_WRITEABLE,
+ }, {
+ .name = "kernel",
+ .offset = 0x050000,
+ .size = 0x090000,
+ }, {
+ .name = "rootfs",
+ .offset = 0x140000,
+ .size = 0x2B0000,
+ }, {
+ .name = "user",
+ .offset = 0x3f0000,
+ .size = 0x010000,
+ }, {
+ .name = "openwrt",
+ .offset = 0x050000,
+ .size = 0x3a0000,
+ }
+};
+#endif /* CONFIG_MTD_PARTITIONS */
+
+static struct physmap_flash_data whr_g300n_flash_data = {
+#ifdef CONFIG_MTD_PARTITIONS
+ .nr_parts = ARRAY_SIZE(whr_g300n_partitions),
+ .parts = whr_g300n_partitions,
+#endif
+};
+
+static void __init whr_g300n_init(void)
+{
+ rt305x_register_flash(0, &whr_g300n_flash_data);
+}
+
+MIPS_MACHINE(RT305X_MACH_WHR_G300N, "Buffalo WHR-G300N", whr_g300n_init);
diff --git a/target/linux/ramips/files/arch/mips/ralink/rt305x/machine.h b/target/linux/ramips/files/arch/mips/ralink/rt305x/machine.h
new file mode 100644
index 0000000000..4ce0fdeabb
--- /dev/null
+++ b/target/linux/ramips/files/arch/mips/ralink/rt305x/machine.h
@@ -0,0 +1,16 @@
+/*
+ * Ralink RT305x SoC specific setup
+ *
+ * Copyright (C) 2009 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.
+ */
+
+enum rt305x_mach_type {
+ RT305X_MACH_GENERIC,
+ RT305X_MACH_WHR_G300N, /* Buffalo WHR-G300N */
+};
+
+extern enum rt305x_mach_type rt305x_mach;
diff --git a/target/linux/ramips/files/arch/mips/ralink/rt305x/prom.c b/target/linux/ramips/files/arch/mips/ralink/rt305x/prom.c
new file mode 100644
index 0000000000..756f237eab
--- /dev/null
+++ b/target/linux/ramips/files/arch/mips/ralink/rt305x/prom.c
@@ -0,0 +1,147 @@
+/*
+ * Ralink RT305x SoC specific prom routines
+ *
+ * Copyright (C) 2009 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.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+
+#include <asm/bootinfo.h>
+
+#include <asm/mach-ralink/rt305x.h>
+#include <asm/mach-ralink/rt305x_regs.h>
+
+#include "machine.h"
+
+struct board_rec {
+ char *name;
+ enum rt305x_mach_type mach_type;
+};
+
+static int rt305x_prom_argc __initdata;
+static char **rt305x_prom_argv __initdata;
+static char **rt305x_prom_envp __initdata;
+
+static struct board_rec boards[] __initdata = {
+ {
+ .name = "WHR-G300N",
+ .mach_type = RT305X_MACH_WHR_G300N,
+ }
+};
+
+static inline void *to_ram_addr(void *addr)
+{
+ u32 base;
+
+ base = KSEG0ADDR(RT305X_SDRAM_BASE);
+ if (((u32) addr > base) &&
+ ((u32) addr < (base + RT305X_MEM_SIZE_MAX)))
+ return addr;
+
+ base = KSEG1ADDR(RT305X_SDRAM_BASE);
+ if (((u32) addr > base) &&
+ ((u32) addr < (base + RT305X_MEM_SIZE_MAX)))
+ return addr;
+
+ /* some U-Boot variants uses physical addresses */
+ base = RT305X_SDRAM_BASE;
+ if (((u32) addr > base) &&
+ ((u32) addr < (base + RT305X_MEM_SIZE_MAX)))
+ return (void *)KSEG0ADDR(addr);
+
+ return NULL;
+}
+
+static __init char *rt305x_prom_getargv(const char *name)
+{
+ int len = strlen(name);
+ int i;
+
+ if (!rt305x_prom_argv) {
+ printk(KERN_DEBUG "argv=%p is invalid, skipping\n",
+ rt305x_prom_argv);
+ return NULL;
+ }
+
+ for (i = 0; i < rt305x_prom_argc; i++) {
+ char *argv = to_ram_addr(rt305x_prom_argv[i]);
+
+ if (!argv) {
+ printk(KERN_DEBUG
+ "argv[%d]=%p is invalid, skipping\n",
+ i, rt305x_prom_argv[i]);
+ continue;
+ }
+
+ printk(KERN_DEBUG "argv[i]: %s\n", argv);
+ if (strncmp(name, argv, len) == 0 && (argv)[len] == '=')
+ return argv + len + 1;
+ }
+
+ return NULL;
+}
+
+static __init char *rt305x_prom_getenv(const char *envname)
+{
+ int len = strlen(envname);
+ char **env;
+ char *p;
+
+ env = rt305x_prom_envp;
+ if (!env) {
+ printk(KERN_DEBUG "envp=%p is not in RAM, skipping\n",
+ rt305x_prom_envp);
+ return NULL;
+ }
+
+ for (p = to_ram_addr(*env); p; env++) {
+ printk(KERN_DEBUG "env: %s\n", *env);
+ if (strncmp(envname, p, len) == 0 && (p)[len] == '=')
+ return p + len + 1;
+ }
+
+ return NULL;
+}
+
+static __init void find_board_byname(char *name)
+{
+ int i;
+
+ rt305x_mach = RT305X_MACH_GENERIC;
+
+ for (i = 0; i < ARRAY_SIZE(boards); i++)
+ if (strcmp(name, boards[i].name) == 0) {
+ rt305x_mach = boards[i].mach_type;
+ break;
+ }
+}
+
+void __init prom_init(void)
+{
+ char *p;
+
+ printk(KERN_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);
+
+ rt305x_prom_argc = fw_arg0;
+ rt305x_prom_argv = to_ram_addr((void *)fw_arg1);
+ rt305x_prom_envp = to_ram_addr((void *)fw_arg2);
+
+ p = rt305x_prom_getargv("board");
+ if (!p)
+ p = rt305x_prom_getenv("board");
+ if (p)
+ find_board_byname(p);
+}
+
+void __init prom_free_prom_memory(void)
+{
+ /* We do not have to prom memory to free */
+}
diff --git a/target/linux/ramips/files/arch/mips/ralink/rt305x/rt305x.c b/target/linux/ramips/files/arch/mips/ralink/rt305x/rt305x.c
new file mode 100644
index 0000000000..9d940a2f54
--- /dev/null
+++ b/target/linux/ramips/files/arch/mips/ralink/rt305x/rt305x.c
@@ -0,0 +1,70 @@
+/*
+ * Ralink RT305x SoC specific setup
+ *
+ * Copyright (C) 2008-2009 Gabor Juhos <juhosg@openwrt.org>
+ * Copyright (C) 2008 Imre Kaloz <kaloz@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/kernel.h>
+#include <linux/init.h>
+#include <linux/module.h>
+
+#include <asm/mach-ralink/rt305x.h>
+#include <asm/mach-ralink/rt305x_regs.h>
+
+unsigned char rt305x_sys_type[RT305X_SYS_TYPE_LEN];
+
+unsigned long rt305x_cpu_freq;
+EXPORT_SYMBOL_GPL(rt305x_cpu_freq);
+
+unsigned long rt305x_sys_freq;
+EXPORT_SYMBOL_GPL(rt305x_sys_freq);
+
+void __iomem * rt305x_intc_base;
+void __iomem * rt305x_sysc_base;
+void __iomem * rt305x_memc_base;
+
+void __init rt305x_detect_sys_type(void)
+{
+ u32 n0;
+ u32 n1;
+ u32 id;
+
+ n0 = rt305x_sysc_rr(SYSC_REG_CHIP_NAME0);
+ n1 = rt305x_sysc_rr(SYSC_REG_CHIP_NAME1);
+ id = rt305x_sysc_rr(SYSC_REG_CHIP_ID);
+
+ snprintf(rt305x_sys_type, RT305X_SYS_TYPE_LEN,
+ "Ralink %c%c%c%c%c%c%c%c id:%u rev:%u",
+ (char) (n0 & 0xff), (char) ((n0 >> 8) & 0xff),
+ (char) ((n0 >> 16) & 0xff), (char) ((n0 >> 24) & 0xff),
+ (char) (n1 & 0xff), (char) ((n1 >> 8) & 0xff),
+ (char) ((n1 >> 16) & 0xff), (char) ((n1 >> 24) & 0xff),
+ (id >> CHIP_ID_ID_SHIFT) & CHIP_ID_ID_MASK,
+ (id & CHIP_ID_REV_MASK));
+}
+
+void __init rt305x_detect_sys_freq(void)
+{
+ u32 t;
+
+ t = rt305x_sysc_rr(SYSC_REG_SYSTEM_CONFIG);
+ t = ((t >> SYSTEM_CONFIG_CPUCLK_SHIFT) & SYSTEM_CONFIG_CPUCLK_MASK);
+
+ switch (t) {
+ case SYSTEM_CONFIG_CPUCLK_320:
+ rt305x_cpu_freq = 320000000;
+ break;
+ case SYSTEM_CONFIG_CPUCLK_384:
+ rt305x_cpu_freq = 384000000;
+ break;
+ }
+
+ rt305x_sys_freq = rt305x_cpu_freq / 3;
+}
diff --git a/target/linux/ramips/files/arch/mips/ralink/rt305x/setup.c b/target/linux/ramips/files/arch/mips/ralink/rt305x/setup.c
new file mode 100644
index 0000000000..4af495b78b
--- /dev/null
+++ b/target/linux/ramips/files/arch/mips/ralink/rt305x/setup.c
@@ -0,0 +1,137 @@
+/*
+ * Ralink RT305x SoC specific setup
+ *
+ * Copyright (C) 2008 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/kernel.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/serial_8250.h>
+
+#include <asm/bootinfo.h>
+#include <asm/mips_machine.h>
+#include <asm/reboot.h>
+#include <asm/time.h>
+
+#include <asm/mach-ralink/rt305x.h>
+#include <asm/mach-ralink/rt305x_regs.h>
+
+#include "machine.h"
+
+enum rt305x_mach_type rt305x_mach;
+
+static void rt305x_restart(char *command)
+{
+ rt305x_sysc_wr(RT305X_RESET_SYSTEM, SYSC_REG_RESET_CTRL);
+ while (1)
+ if (cpu_wait)
+ cpu_wait();
+}
+
+static void rt305x_halt(void)
+{
+ while (1)
+ if (cpu_wait)
+ cpu_wait();
+}
+
+static void __init rt305x_detect_mem_size(void)
+{
+ unsigned long size;
+
+ for (size = RT305X_MEM_SIZE_MIN; size < RT305X_MEM_SIZE_MAX;
+ size <<= 1 ) {
+ if (!memcmp(rt305x_detect_mem_size,
+ rt305x_detect_mem_size + size, 1024))
+ break;
+ }
+
+ add_memory_region(RT305X_SDRAM_BASE, size, BOOT_MEM_RAM);
+}
+
+static void __init rt305x_early_serial_setup(void)
+{
+ struct uart_port p;
+ int err;
+
+ memset(&p, 0, sizeof(p));
+ p.flags = UPF_SKIP_TEST;
+ p.iotype = UPIO_AU;
+ p.uartclk = rt305x_sys_freq;
+ p.regshift = 2;
+ p.type = PORT_16550A;
+
+ p.mapbase = RT305X_UART0_BASE;
+ p.membase = ioremap_nocache(p.mapbase, RT305X_UART0_SIZE);
+ p.line = 0;
+ p.irq = RT305X_INTC_IRQ_UART0;
+
+ err = early_serial_setup(&p);
+ if (err)
+ printk(KERN_ERR "RT305x: early UART0 registration failed %d\n",
+ err);
+
+ p.mapbase = RT305X_UART1_BASE;
+ p.membase = ioremap_nocache(p.mapbase, RT305X_UART1_SIZE);
+ p.line = 1;
+ p.irq = RT305X_INTC_IRQ_UART1;
+
+ err = early_serial_setup(&p);
+ if (err)
+ printk(KERN_ERR "RT305x: early UART1 registration failed %d\n",
+ err);
+}
+
+const char *get_system_type(void)
+{
+ return rt305x_sys_type;
+}
+
+unsigned int __cpuinit get_c0_compare_irq(void)
+{
+ return CP0_LEGACY_COMPARE_IRQ;
+}
+
+void __init plat_mem_setup(void)
+{
+ set_io_port_base(KSEG1);
+
+ rt305x_intc_base = ioremap_nocache(RT305X_INTC_BASE, PAGE_SIZE);
+ rt305x_sysc_base = ioremap_nocache(RT305X_SYSC_BASE, PAGE_SIZE);
+ rt305x_memc_base = ioremap_nocache(RT305X_MEMC_BASE, PAGE_SIZE);
+
+ rt305x_detect_mem_size();
+ rt305x_detect_sys_type();
+ rt305x_detect_sys_freq();
+
+ printk(KERN_INFO "%s running at %lu.%02lu MHz\n", get_system_type(),
+ rt305x_cpu_freq / 1000000,
+ (rt305x_cpu_freq % 1000000) * 100 / 1000000);
+
+ _machine_restart = rt305x_restart;
+ _machine_halt = rt305x_halt;
+ pm_power_off = rt305x_halt;
+
+ rt305x_early_serial_setup();
+}
+
+void __init plat_time_init(void)
+{
+ mips_hpt_frequency = rt305x_cpu_freq / 2;
+}
+
+static int __init rt305x_machine_setup(void)
+{
+ mips_machine_setup(rt305x_mach);
+
+ return 0;
+}
+
+arch_initcall(rt305x_machine_setup);