initial support for RT288x/RT305x
SVN-Revision: 17439
This commit is contained in:
51
target/linux/ramips/files/arch/mips/ralink/Kconfig
Normal file
51
target/linux/ramips/files/arch/mips/ralink/Kconfig
Normal file
@@ -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
|
||||
11
target/linux/ramips/files/arch/mips/ralink/rt288x/Kconfig
Normal file
11
target/linux/ramips/files/arch/mips/ralink/rt288x/Kconfig
Normal file
@@ -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
|
||||
15
target/linux/ramips/files/arch/mips/ralink/rt288x/Makefile
Normal file
15
target/linux/ramips/files/arch/mips/ralink/rt288x/Makefile
Normal file
@@ -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
|
||||
@@ -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);
|
||||
}
|
||||
125
target/linux/ramips/files/arch/mips/ralink/rt288x/irq.c
Normal file
125
target/linux/ramips/files/arch/mips/ralink/rt288x/irq.c
Normal file
@@ -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();
|
||||
}
|
||||
@@ -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);
|
||||
97
target/linux/ramips/files/arch/mips/ralink/rt288x/platform.c
Normal file
97
target/linux/ramips/files/arch/mips/ralink/rt288x/platform.c
Normal file
@@ -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++;
|
||||
}
|
||||
37
target/linux/ramips/files/arch/mips/ralink/rt288x/prom.c
Normal file
37
target/linux/ramips/files/arch/mips/ralink/rt288x/prom.c
Normal file
@@ -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 */
|
||||
}
|
||||
|
||||
77
target/linux/ramips/files/arch/mips/ralink/rt288x/rt288x.c
Normal file
77
target/linux/ramips/files/arch/mips/ralink/rt288x/rt288x.c
Normal file
@@ -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;
|
||||
}
|
||||
|
||||
142
target/linux/ramips/files/arch/mips/ralink/rt288x/setup.c
Normal file
142
target/linux/ramips/files/arch/mips/ralink/rt288x/setup.c
Normal file
@@ -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);
|
||||
15
target/linux/ramips/files/arch/mips/ralink/rt305x/Kconfig
Normal file
15
target/linux/ramips/files/arch/mips/ralink/rt305x/Kconfig
Normal file
@@ -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
|
||||
15
target/linux/ramips/files/arch/mips/ralink/rt305x/Makefile
Normal file
15
target/linux/ramips/files/arch/mips/ralink/rt305x/Makefile
Normal file
@@ -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
|
||||
96
target/linux/ramips/files/arch/mips/ralink/rt305x/devices.c
Normal file
96
target/linux/ramips/files/arch/mips/ralink/rt305x/devices.c
Normal file
@@ -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++;
|
||||
}
|
||||
20
target/linux/ramips/files/arch/mips/ralink/rt305x/devices.h
Normal file
20
target/linux/ramips/files/arch/mips/ralink/rt305x/devices.h
Normal file
@@ -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 */
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
118
target/linux/ramips/files/arch/mips/ralink/rt305x/irq.c
Normal file
118
target/linux/ramips/files/arch/mips/ralink/rt305x/irq.c
Normal file
@@ -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();
|
||||
}
|
||||
@@ -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);
|
||||
@@ -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);
|
||||
16
target/linux/ramips/files/arch/mips/ralink/rt305x/machine.h
Normal file
16
target/linux/ramips/files/arch/mips/ralink/rt305x/machine.h
Normal file
@@ -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;
|
||||
147
target/linux/ramips/files/arch/mips/ralink/rt305x/prom.c
Normal file
147
target/linux/ramips/files/arch/mips/ralink/rt305x/prom.c
Normal file
@@ -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 */
|
||||
}
|
||||
70
target/linux/ramips/files/arch/mips/ralink/rt305x/rt305x.c
Normal file
70
target/linux/ramips/files/arch/mips/ralink/rt305x/rt305x.c
Normal file
@@ -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;
|
||||
}
|
||||
137
target/linux/ramips/files/arch/mips/ralink/rt305x/setup.c
Normal file
137
target/linux/ramips/files/arch/mips/ralink/rt305x/setup.c
Normal file
@@ -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);
|
||||
Reference in New Issue
Block a user