diff options
Diffstat (limited to 'target/linux/ramips/files/arch/mips/ralink')
22 files changed, 1405 insertions, 0 deletions
| 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 000000000..e180eabd6 --- /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 000000000..dd0659626 --- /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 000000000..4c22a6dc8 --- /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 000000000..9fd7adb54 --- /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 000000000..47a537400 --- /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 000000000..dd05e48e1 --- /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 000000000..a68628696 --- /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 000000000..80ef719e0 --- /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 000000000..cd429a1c0 --- /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 000000000..186db29d1 --- /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 000000000..3b5e15e1b --- /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 000000000..981498e85 --- /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 000000000..5dd1022b9 --- /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 000000000..0a90b3a4e --- /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 000000000..602df863e --- /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 000000000..168b2390b --- /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 000000000..3b2b70298 --- /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 000000000..b1f6dafab --- /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 000000000..4ce0fdeab --- /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 000000000..756f237ea --- /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 000000000..9d940a2f5 --- /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 000000000..4af495b78 --- /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); | 
