diff options
| author | nbd <nbd@3c298f89-4303-0410-b956-a3cf2f4a3e73> | 2007-02-04 21:18:10 +0000 | 
|---|---|---|
| committer | nbd <nbd@3c298f89-4303-0410-b956-a3cf2f4a3e73> | 2007-02-04 21:18:10 +0000 | 
| commit | 63b12ffd1bf4012ffb97802ca54a60a3d895903a (patch) | |
| tree | fb5e795f44118b5a4b2408315c93cefae425682f /target/linux/atheros-2.6/files/arch/mips/atheros | |
| parent | 0634ad3b282481a980e7791af560491e662ec426 (diff) | |
update atheros 2.6 port - add support for the older chip generation
git-svn-id: svn://svn.openwrt.org/openwrt/trunk@6265 3c298f89-4303-0410-b956-a3cf2f4a3e73
Diffstat (limited to 'target/linux/atheros-2.6/files/arch/mips/atheros')
10 files changed, 2397 insertions, 0 deletions
diff --git a/target/linux/atheros-2.6/files/arch/mips/atheros/Kconfig b/target/linux/atheros-2.6/files/arch/mips/atheros/Kconfig new file mode 100644 index 000000000..2170fd710 --- /dev/null +++ b/target/linux/atheros-2.6/files/arch/mips/atheros/Kconfig @@ -0,0 +1,13 @@ + +config ATHEROS_AR5312 +	bool "Atheros 5312/2312+ support" +	depends on ATHEROS +	default y + +config ATHEROS_AR5315 +	bool "Atheros 5315/2315+ support" +	depends on ATHEROS +	default y + + + diff --git a/target/linux/atheros-2.6/files/arch/mips/atheros/Makefile b/target/linux/atheros-2.6/files/arch/mips/atheros/Makefile new file mode 100644 index 000000000..aff65d723 --- /dev/null +++ b/target/linux/atheros-2.6/files/arch/mips/atheros/Makefile @@ -0,0 +1,22 @@ +# +# 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) 2003 Atheros Communications, Inc.,  All Rights Reserved. +# Copyright (C) 2006 FON Technology, SL. +# Copyright (C) 2006 Imre Kaloz <kaloz@openwrt.org> +# Copyright (C) 2006 Felix Fietkau <nbd@openwrt.org> +# + +# Makefile for Atheros ar531x boards +# +# Note! Dependencies are done automagically by 'make dep', which also +# removes any old dependencies. DON'T put your own dependencies here +# unless it's something special (ie not a .c file). +# + +obj-y += board.o prom.o irq.o +obj-$(CONFIG_ATHEROS_AR5312) += ar5312.o +obj-$(CONFIG_ATHEROS_AR5315) += ar5315.o + diff --git a/target/linux/atheros-2.6/files/arch/mips/atheros/ar5312.c b/target/linux/atheros-2.6/files/arch/mips/atheros/ar5312.c new file mode 100644 index 000000000..28b9d3f95 --- /dev/null +++ b/target/linux/atheros-2.6/files/arch/mips/atheros/ar5312.c @@ -0,0 +1,471 @@ +/* + * 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) 2003 Atheros Communications, Inc.,  All Rights Reserved. + * Copyright (C) 2006 FON Technology, SL. + * Copyright (C) 2006 Imre Kaloz <kaloz@openwrt.org> + * Copyright (C) 2006 Felix Fietkau <nbd@openwrt.org> + */ + +/* + * Platform devices for Atheros SoCs + */ + +#include <linux/autoconf.h> +#include <linux/init.h> +#include <linux/module.h> +#include <linux/types.h> +#include <linux/string.h> +#include <linux/mtd/physmap.h> +#include <linux/platform_device.h> +#include <linux/kernel.h> +#include <linux/reboot.h> +#include <asm/bootinfo.h> +#include <asm/reboot.h> +#include <asm/time.h> +#include <asm/irq.h> +#include <asm/io.h> +#include "ar531x.h" + + +#define AR531X_IRQ_WLAN0_INTRS  MIPS_CPU_IRQ_BASE+2 /* C0_CAUSE: 0x0400 */ +#define AR531X_IRQ_ENET0_INTRS  MIPS_CPU_IRQ_BASE+3 /* C0_CAUSE: 0x0800 */ +#define AR531X_IRQ_ENET1_INTRS  MIPS_CPU_IRQ_BASE+4 /* C0_CAUSE: 0x1000 */ +#define AR531X_IRQ_WLAN1_INTRS  MIPS_CPU_IRQ_BASE+5 /* C0_CAUSE: 0x2000 */ +#define AR531X_IRQ_MISC_INTRS   MIPS_CPU_IRQ_BASE+6 /* C0_CAUSE: 0x4000 */ + + +static struct platform_device *ar5312_devs[5]; + +static struct resource ar5312_eth0_res[] = { +	{ +		.name = "eth_membase", +		.flags = IORESOURCE_MEM, +		.start = KSEG1ADDR(AR531X_ENET0), +		.end = KSEG1ADDR(AR531X_ENET0 + 0x2000), +	}, +	{ +		.name = "eth_irq", +		.flags = IORESOURCE_IRQ, +		.start = AR531X_IRQ_ENET0_INTRS, +		.end = AR531X_IRQ_ENET0_INTRS, +	}, +}; + + +static struct resource ar5312_eth1_res[] = { +	{ +		.name = "eth_membase", +		.flags = IORESOURCE_MEM, +		.start = KSEG1ADDR(AR531X_ENET1), +		.end = KSEG1ADDR(AR531X_ENET1 + 0x2000), +	}, +	{ +		.name = "eth_irq", +		.flags = IORESOURCE_IRQ, +		.start = AR531X_IRQ_ENET1_INTRS, +		.end = AR531X_IRQ_ENET1_INTRS, +	}, +}; + + +static struct ar531x_eth ar5312_eth0_data = { +	.phy = 0x1f, +	.mac = 0, +	.reset_base = AR531X_RESET, +	.reset_mac = AR531X_RESET_ENET0, +	.reset_phy = AR531X_RESET_EPHY0, +}; + +static struct ar531x_eth ar5312_eth1_data = { +	.phy = 0, +	.mac = 1, +	.reset_base = AR531X_RESET, +	.reset_mac = AR531X_RESET_ENET1, +	.reset_phy = AR531X_RESET_EPHY1, +}; + +static struct platform_device ar5312_eth[] = { +	{ +		.id = 0, +		.name = "ar531x-eth", +		.dev.platform_data = &ar5312_eth0_data, +		.resource = ar5312_eth0_res, +		.num_resources = ARRAY_SIZE(ar5312_eth0_res) +	}, +	{ +		.id = 1, +		.name = "ar531x-eth", +		.dev.platform_data = &ar5312_eth1_data, +		.resource = ar5312_eth1_res, +		.num_resources = ARRAY_SIZE(ar5312_eth1_res) +	}, +}; + +static struct platform_device ar5312_wmac[] = { +	{ +		.id = 0, +		.name = "ar531x-wmac", +	}, +	{ +		.id = 1, +		.name = "ar531x-wmac", +	}, +}; + + +static struct physmap_flash_data ar5312_flash_data = { +	.width	  = 2, +}; + +static struct resource ar5312_flash_resource = { +	.start	= AR531X_FLASH, +	.end	= AR531X_FLASH + 0x400000 - 1, +	.flags	= IORESOURCE_MEM, +}; + +static struct platform_device ar5312_physmap_flash = { +	.name	   = "physmap-flash", +	.id	 = 0, +	.dev		= { +		.platform_data  = &ar5312_flash_data, +	}, +	.num_resources  = 1, +	.resource   = &ar5312_flash_resource, +}; + + +/* + * NB: This mapping size is larger than the actual flash size, + * but this shouldn't be a problem here, because the flash + * will simply be mapped multiple times. + */ +static char __init *ar5312_flash_limit(void) +{ +	u32 ctl; +	/* Configure flash bank 0 */ +	ctl = FLASHCTL_E | +		FLASHCTL_AC_8M | +		FLASHCTL_RBLE | +		(0x01 << FLASHCTL_IDCY_S) | +		(0x07 << FLASHCTL_WST1_S) | +		(0x07 << FLASHCTL_WST2_S) | +		(sysRegRead(AR531X_FLASHCTL0) & FLASHCTL_MW); + +	sysRegWrite(AR531X_FLASHCTL0, ctl); +	 +	/* Disable other flash banks */ +	sysRegWrite(AR531X_FLASHCTL1, +		sysRegRead(AR531X_FLASHCTL1) & ~(FLASHCTL_E | FLASHCTL_AC)); + +	sysRegWrite(AR531X_FLASHCTL2, +		sysRegRead(AR531X_FLASHCTL2) & ~(FLASHCTL_E | FLASHCTL_AC)); + +	return (char *) KSEG1ADDR(AR531X_FLASH + 0x400000); +} + +static struct ar531x_config __init *init_wmac(int unit) +{ +	struct ar531x_config *config; +	 +	config = (struct ar531x_config *) kzalloc(sizeof(struct ar531x_config), GFP_KERNEL); +	config->board = board_config; +	config->radio = radio_config; +	config->unit = unit; +	config->tag = (u_int16_t) ((sysRegRead(AR531X_REV) >> AR531X_REV_WMAC_MIN_S) & AR531X_REV_CHIP); + +	return config; +} +		 +int __init ar5312_init_devices(void) +{ +	char *radio; +	int dev = 0; + +	if (mips_machtype != MACH_ATHEROS_AR5312)  +		return 0; + +	ar531x_find_config(ar5312_flash_limit()); +	ar5312_eth0_data.board_config = board_config; +	ar5312_eth1_data.board_config = board_config; +	ar5312_devs[dev++] = &ar5312_physmap_flash; +	ar5312_devs[dev++] = &ar5312_eth[0]; +	ar5312_devs[dev++] = &ar5312_eth[1]; + +	radio = radio_config + AR531X_RADIO_MASK_OFF; +	if (*((u32 *) radio) & AR531X_RADIO0_MASK) { +		ar5312_wmac[0].dev.platform_data = init_wmac(0); +		ar5312_devs[dev++] = &ar5312_wmac[0]; +	} +	if (*((u32 *) radio) & AR531X_RADIO1_MASK) { +		ar5312_wmac[1].dev.platform_data = init_wmac(1); +		ar5312_devs[dev++] = &ar5312_wmac[1]; +	} + +	return platform_add_devices(ar5312_devs, dev); +} + + +/* + * Called when an interrupt is received, this function + * determines exactly which interrupt it was, and it + * invokes the appropriate handler. + * + * Implicitly, we also define interrupt priority by + * choosing which to dispatch first. + */ +asmlinkage void ar5312_irq_dispatch(void) +{ +	int pending = read_c0_status() & read_c0_cause(); + +	if (pending & CAUSEF_IP2) +		do_IRQ(AR531X_IRQ_WLAN0_INTRS); +	else if (pending & CAUSEF_IP3) +		do_IRQ(AR531X_IRQ_ENET0_INTRS); +	else if (pending & CAUSEF_IP4) +		do_IRQ(AR531X_IRQ_ENET1_INTRS); +	else if (pending & CAUSEF_IP5) +		do_IRQ(AR531X_IRQ_WLAN1_INTRS); +	else if (pending & CAUSEF_IP6) { +		unsigned int ar531x_misc_intrs = sysRegRead(AR531X_ISR) & sysRegRead(AR531X_IMR); + +		if (ar531x_misc_intrs & AR531X_ISR_TIMER) { +			do_IRQ(AR531X_MISC_IRQ_TIMER); +			(void)sysRegRead(AR531X_TIMER); +		} else if (ar531x_misc_intrs & AR531X_ISR_AHBPROC) +			do_IRQ(AR531X_MISC_IRQ_AHB_PROC); +		else if ((ar531x_misc_intrs & AR531X_ISR_UART0)) +			do_IRQ(AR531X_MISC_IRQ_UART0); +		else if (ar531x_misc_intrs & AR531X_ISR_WD) +			do_IRQ(AR531X_MISC_IRQ_WATCHDOG); +		else +			do_IRQ(AR531X_MISC_IRQ_NONE); +	} else if (pending & CAUSEF_IP7) { +		do_IRQ(AR531X_IRQ_CPU_CLOCK); +	} +	else +		do_IRQ(AR531X_IRQ_NONE); +} + +static void ar5312_halt(void) +{ +	 while (1); +} + +static void ar5312_power_off(void) +{ +	 ar5312_halt(); +} + + +static void ar5312_restart(char *command) +{ +	/* reset the system */ +	for(;;) sysRegWrite(AR531X_RESET, AR531X_RESET_SYSTEM); +} + + +/* + * This table is indexed by bits 5..4 of the CLOCKCTL1 register + * to determine the predevisor value. + */ +static int __initdata CLOCKCTL1_PREDIVIDE_TABLE[4] = { +	1, +	2, +	4, +	5 +}; + +		 +static unsigned int __init ar5312_cpu_frequency(void) +{ +	unsigned int result; +	unsigned int predivide_mask, predivide_shift; +	unsigned int multiplier_mask, multiplier_shift; +	unsigned int clockCtl1, preDivideSelect, preDivisor, multiplier; +	unsigned int doubler_mask; +	unsigned int wisoc_revision; + +	/* Trust the bootrom's idea of cpu frequency. */ +	if ((result = sysRegRead(AR5312_SCRATCH))) +		return result; + +	wisoc_revision = (sysRegRead(AR531X_REV) & AR531X_REV_MAJ) >> AR531X_REV_MAJ_S; +	if (wisoc_revision == AR531X_REV_MAJ_AR2313) { +		predivide_mask = AR2313_CLOCKCTL1_PREDIVIDE_MASK; +		predivide_shift = AR2313_CLOCKCTL1_PREDIVIDE_SHIFT; +		multiplier_mask = AR2313_CLOCKCTL1_MULTIPLIER_MASK; +		multiplier_shift = AR2313_CLOCKCTL1_MULTIPLIER_SHIFT; +		doubler_mask = AR2313_CLOCKCTL1_DOUBLER_MASK; +	} else { /* AR5312 and AR2312 */ +		predivide_mask = AR5312_CLOCKCTL1_PREDIVIDE_MASK; +		predivide_shift = AR5312_CLOCKCTL1_PREDIVIDE_SHIFT; +		multiplier_mask = AR5312_CLOCKCTL1_MULTIPLIER_MASK; +		multiplier_shift = AR5312_CLOCKCTL1_MULTIPLIER_SHIFT; +		doubler_mask = AR5312_CLOCKCTL1_DOUBLER_MASK; +	} +	 +	/* +	 * Clocking is derived from a fixed 40MHz input clock. +	 * +	 *  cpuFreq = InputClock * MULT (where MULT is PLL multiplier) +	 *  sysFreq = cpuFreq / 4	   (used for APB clock, serial, +	 *							   flash, Timer, Watchdog Timer) +	 * +	 *  cntFreq = cpuFreq / 2	   (use for CPU count/compare) +	 *  +	 * So, for example, with a PLL multiplier of 5, we have +	 *  +	 *  cpuFreq = 200MHz +	 *  sysFreq = 50MHz +	 *  cntFreq = 100MHz +	 * +	 * We compute the CPU frequency, based on PLL settings. +	 */ + +	clockCtl1 = sysRegRead(AR5312_CLOCKCTL1); +	preDivideSelect = (clockCtl1 & predivide_mask) >> predivide_shift; +	preDivisor = CLOCKCTL1_PREDIVIDE_TABLE[preDivideSelect]; +	multiplier = (clockCtl1 & multiplier_mask) >> multiplier_shift; +	 +	if (clockCtl1 & doubler_mask) { +		multiplier = multiplier << 1; +	} +	return (40000000 / preDivisor) * multiplier; +} + +static inline int ar5312_sys_frequency(void) +{ +	return ar5312_cpu_frequency() / 4; +} + +static void __init ar5312_time_init(void) +{ +	mips_hpt_frequency = ar5312_cpu_frequency() / 2; +} + + +/* Enable the specified AR531X_MISC_IRQ interrupt */ +static void +ar5312_misc_intr_enable(unsigned int irq) +{ +	unsigned int imr; + +	imr = sysRegRead(AR531X_IMR); +	imr |= (1 << (irq - AR531X_MISC_IRQ_BASE - 1)); +	sysRegWrite(AR531X_IMR, imr); +	sysRegRead(AR531X_IMR); /* flush write buffer */ +} + +/* Disable the specified AR531X_MISC_IRQ interrupt */ +static void +ar5312_misc_intr_disable(unsigned int irq) +{ +	unsigned int imr; + +	imr = sysRegRead(AR531X_IMR); +	imr &= ~(1 << (irq - AR531X_MISC_IRQ_BASE - 1)); +	sysRegWrite(AR531X_IMR, imr); +	sysRegRead(AR531X_IMR); /* flush write buffer */ +} + +/* Turn on the specified AR531X_MISC_IRQ interrupt */ +static unsigned int +ar5312_misc_intr_startup(unsigned int irq) +{ +	ar5312_misc_intr_enable(irq); +	return 0; +} + +/* Turn off the specified AR531X_MISC_IRQ interrupt */ +static void +ar5312_misc_intr_shutdown(unsigned int irq) +{ +	ar5312_misc_intr_disable(irq); +} + +static void +ar5312_misc_intr_ack(unsigned int irq) +{ +	ar5312_misc_intr_disable(irq); +} + +static void +ar5312_misc_intr_end(unsigned int irq) +{ +	if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) +		ar5312_misc_intr_enable(irq); +} + +static struct irq_chip ar5312_misc_intr_controller = { +	.typename	= "AR5312 misc", +	.startup	= ar5312_misc_intr_startup, +	.shutdown	= ar5312_misc_intr_shutdown, +	.enable		= ar5312_misc_intr_enable, +	.disable	= ar5312_misc_intr_disable, +	.ack		= ar5312_misc_intr_ack, +	.end		= ar5312_misc_intr_end, +}; + +static irqreturn_t ar5312_ahb_proc_handler(int cpl, void *dev_id) +{ +	u32 proc1 = sysRegRead(AR531X_PROC1); +	u32 procAddr = sysRegRead(AR531X_PROCADDR); /* clears error state */ +	u32 dma1 = sysRegRead(AR531X_DMA1); +	u32 dmaAddr = sysRegRead(AR531X_DMAADDR);   /* clears error state */ + +	printk("AHB interrupt: PROCADDR=0x%8.8x  PROC1=0x%8.8x  DMAADDR=0x%8.8x  DMA1=0x%8.8x\n", +			procAddr, proc1, dmaAddr, dma1); +		 +	machine_restart("AHB error"); /* Catastrophic failure */ +	return IRQ_HANDLED; +} + + +static struct irqaction ar5312_ahb_proc_interrupt  = { +	.handler	= ar5312_ahb_proc_handler, +	.flags		= SA_INTERRUPT, +	.name		= "ar5312_ahb_proc_interrupt", +}; + + +static struct irqaction cascade  = { +	.handler	= no_action, +	.flags		= SA_INTERRUPT, +	.name		= "cascade", +}; + +void __init ar5312_misc_intr_init(int irq_base) +{ +	int i; + +	for (i = irq_base; i < irq_base + AR531X_MISC_IRQ_COUNT; i++) { +		irq_desc[i].status = IRQ_DISABLED; +		irq_desc[i].action = NULL; +		irq_desc[i].depth = 1; +		irq_desc[i].chip = &ar5312_misc_intr_controller; +	} +	setup_irq(AR531X_MISC_IRQ_AHB_PROC, &ar5312_ahb_proc_interrupt); +	setup_irq(AR531X_IRQ_MISC_INTRS, &cascade); +} + + +void __init ar5312_plat_setup(void) +{ +	/* Clear any lingering AHB errors */ +	sysRegRead(AR531X_PROCADDR); +	sysRegRead(AR531X_DMAADDR); +	sysRegWrite(AR531X_WD_CTRL, AR531X_WD_CTRL_IGNORE_EXPIRATION); + +	board_time_init = ar5312_time_init; + +	_machine_restart = ar5312_restart; +	_machine_halt = ar5312_halt; +	pm_power_off = ar5312_power_off; + +	serial_setup(KSEG1ADDR(AR531X_UART0), ar5312_sys_frequency()); +} + +arch_initcall(ar5312_init_devices); diff --git a/target/linux/atheros-2.6/files/arch/mips/atheros/ar5312.h b/target/linux/atheros-2.6/files/arch/mips/atheros/ar5312.h new file mode 100644 index 000000000..b6e71b890 --- /dev/null +++ b/target/linux/atheros-2.6/files/arch/mips/atheros/ar5312.h @@ -0,0 +1,223 @@ +/* + * 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) 2003 Atheros Communications, Inc.,  All Rights Reserved. + * Copyright (C) 2006 Imre Kaloz <kaloz@openwrt.org> + * Copyright (C) 2006 Felix Fietkau <nbd@openwrt.org> + */ + +#ifndef AR5312_H +#define AR5312_H + +#include <asm/addrspace.h> + +/* Address Map */ +#define AR531X_WLAN0            0x18000000 +#define AR531X_WLAN1            0x18500000 +#define AR531X_ENET0            0x18100000 +#define AR531X_ENET1            0x18200000 +#define AR531X_SDRAMCTL         0x18300000 +#define AR531X_FLASHCTL         0x18400000 +#define AR531X_APBBASE		0x1c000000 +#define AR531X_FLASH            0x1e000000 +#define AR531X_UART0            0xbc000003      /* UART MMR */ + +/* + * AR531X_NUM_ENET_MAC defines the number of ethernet MACs that + * should be considered available.  The AR5312 supports 2 enet MACS, + * even though many reference boards only actually use 1 of them + * (i.e. Only MAC 0 is actually connected to an enet PHY or PHY switch. + * The AR2312 supports 1 enet MAC. + */ +#define AR531X_NUM_ENET_MAC             2 + +/* + * Need these defines to determine true number of ethernet MACs + */ +#define AR5212_AR5312_REV2      0x0052          /* AR5312 WMAC (AP31) */ +#define AR5212_AR5312_REV7      0x0057          /* AR5312 WMAC (AP30-040) */ +#define AR5212_AR2313_REV8      0x0058          /* AR2313 WMAC (AP43-030) */ +#define AR531X_RADIO_MASK_OFF  0xc8 +#define AR531X_RADIO0_MASK     0x0003 +#define AR531X_RADIO1_MASK     0x000c +#define AR531X_RADIO1_S        2  + +/* + * AR531X_NUM_WMAC defines the number of Wireless MACs that\ + * should be considered available. + */ +#define AR531X_NUM_WMAC                 2 + +/* Reset/Timer Block Address Map */ +#define AR531X_RESETTMR		(AR531X_APBBASE  + 0x3000) +#define AR531X_TIMER		(AR531X_RESETTMR + 0x0000) /* countdown timer */ +#define AR531X_WD_CTRL          (AR531X_RESETTMR + 0x0008) /* watchdog cntrl */ +#define AR531X_WD_TIMER         (AR531X_RESETTMR + 0x000c) /* watchdog timer */ +#define AR531X_ISR		(AR531X_RESETTMR + 0x0010) /* Intr Status Reg */ +#define AR531X_IMR		(AR531X_RESETTMR + 0x0014) /* Intr Mask Reg */ +#define AR531X_RESET		(AR531X_RESETTMR + 0x0020) +#define AR5312_CLOCKCTL1	(AR531X_RESETTMR + 0x0064) +#define AR5312_SCRATCH   	(AR531X_RESETTMR + 0x006c) +#define AR531X_PROCADDR		(AR531X_RESETTMR + 0x0070) +#define AR531X_PROC1		(AR531X_RESETTMR + 0x0074) +#define AR531X_DMAADDR		(AR531X_RESETTMR + 0x0078) +#define AR531X_DMA1		(AR531X_RESETTMR + 0x007c) +#define AR531X_ENABLE           (AR531X_RESETTMR + 0x0080) /* interface enb */ +#define AR531X_REV		(AR531X_RESETTMR + 0x0090) /* revision */ + +/* AR531X_WD_CTRL register bit field definitions */ +#define AR531X_WD_CTRL_IGNORE_EXPIRATION 0x0000 +#define AR531X_WD_CTRL_NMI               0x0001 +#define AR531X_WD_CTRL_RESET             0x0002 + +/* AR531X_ISR register bit field definitions */ +#define AR531X_ISR_NONE		0x0000 +#define AR531X_ISR_TIMER	0x0001 +#define AR531X_ISR_AHBPROC	0x0002 +#define AR531X_ISR_AHBDMA	0x0004 +#define AR531X_ISR_GPIO		0x0008 +#define AR531X_ISR_UART0	0x0010 +#define AR531X_ISR_UART0DMA	0x0020 +#define AR531X_ISR_WD		0x0040 +#define AR531X_ISR_LOCAL	0x0080 + +/* AR531X_RESET register bit field definitions */ +#define AR531X_RESET_SYSTEM     0x00000001  /* cold reset full system */ +#define AR531X_RESET_PROC       0x00000002  /* cold reset MIPS core */ +#define AR531X_RESET_WLAN0      0x00000004  /* cold reset WLAN MAC and BB */ +#define AR531X_RESET_EPHY0      0x00000008  /* cold reset ENET0 phy */ +#define AR531X_RESET_EPHY1      0x00000010  /* cold reset ENET1 phy */ +#define AR531X_RESET_ENET0      0x00000020  /* cold reset ENET0 mac */ +#define AR531X_RESET_ENET1      0x00000040  /* cold reset ENET1 mac */ +#define AR531X_RESET_UART0      0x00000100  /* cold reset UART0 (high speed) */ +#define AR531X_RESET_WLAN1      0x00000200  /* cold reset WLAN MAC/BB */ +#define AR531X_RESET_APB        0x00000400  /* cold reset APB (ar5312) */ +#define AR531X_RESET_WARM_PROC  0x00001000  /* warm reset MIPS core */ +#define AR531X_RESET_WARM_WLAN0_MAC 0x00002000  /* warm reset WLAN0 MAC */ +#define AR531X_RESET_WARM_WLAN0_BB  0x00004000  /* warm reset WLAN0 BaseBand */ +#define AR531X_RESET_NMI        0x00010000  /* send an NMI to the processor */ +#define AR531X_RESET_WARM_WLAN1_MAC 0x00020000  /* warm reset WLAN1 mac */ +#define AR531X_RESET_WARM_WLAN1_BB  0x00040000  /* warm reset WLAN1 baseband */ +#define AR531X_RESET_LOCAL_BUS  0x00080000  /* reset local bus */ +#define AR531X_RESET_WDOG       0x00100000  /* last reset was a watchdog */ + +#define AR531X_RESET_WMAC0_BITS \ +        AR531X_RESET_WLAN0 |\ +        AR531X_RESET_WARM_WLAN0_MAC |\ +        AR531X_RESET_WARM_WLAN0_BB + +#define AR531X_RESERT_WMAC1_BITS \ +        AR531X_RESET_WLAN1 |\ +        AR531X_RESET_WARM_WLAN1_MAC |\ +        AR531X_RESET_WARM_WLAN1_BB + +/* AR5312_CLOCKCTL1 register bit field definitions */ +#define AR5312_CLOCKCTL1_PREDIVIDE_MASK    0x00000030 +#define AR5312_CLOCKCTL1_PREDIVIDE_SHIFT            4 +#define AR5312_CLOCKCTL1_MULTIPLIER_MASK   0x00001f00 +#define AR5312_CLOCKCTL1_MULTIPLIER_SHIFT           8 +#define AR5312_CLOCKCTL1_DOUBLER_MASK      0x00010000 + +/* Valid for AR5312 and AR2312 */ +#define AR5312_CLOCKCTL1_PREDIVIDE_MASK    0x00000030 +#define AR5312_CLOCKCTL1_PREDIVIDE_SHIFT            4 +#define AR5312_CLOCKCTL1_MULTIPLIER_MASK   0x00001f00 +#define AR5312_CLOCKCTL1_MULTIPLIER_SHIFT           8 +#define AR5312_CLOCKCTL1_DOUBLER_MASK      0x00010000 + +/* Valid for AR2313 */ +#define AR2313_CLOCKCTL1_PREDIVIDE_MASK    0x00003000 +#define AR2313_CLOCKCTL1_PREDIVIDE_SHIFT           12 +#define AR2313_CLOCKCTL1_MULTIPLIER_MASK   0x001f0000 +#define AR2313_CLOCKCTL1_MULTIPLIER_SHIFT          16 +#define AR2313_CLOCKCTL1_DOUBLER_MASK      0x00000000 + + +/* AR531X_ENABLE register bit field definitions */ +#define AR531X_ENABLE_WLAN0              0x0001 +#define AR531X_ENABLE_ENET0              0x0002 +#define AR531X_ENABLE_ENET1              0x0004 +#define AR531X_ENABLE_UART_AND_WLAN1_PIO 0x0008   /* UART, and WLAN1 PIOs */ +#define AR531X_ENABLE_WLAN1_DMA          0x0010   /* WLAN1 DMAs */ +#define AR531X_ENABLE_WLAN1 \ +            (AR531X_ENABLE_UART_AND_WLAN1_PIO | AR531X_ENABLE_WLAN1_DMA) + +/* AR531X_REV register bit field definitions */ +#define AR531X_REV_WMAC_MAJ    0xf000 +#define AR531X_REV_WMAC_MAJ_S  12 +#define AR531X_REV_WMAC_MIN    0x0f00 +#define AR531X_REV_WMAC_MIN_S  8 +#define AR531X_REV_MAJ         0x00f0 +#define AR531X_REV_MAJ_S       4 +#define AR531X_REV_MIN         0x000f +#define AR531X_REV_MIN_S       0 +#define AR531X_REV_CHIP        (REV_MAJ|REV_MIN) + +/* Major revision numbers, bits 7..4 of Revision ID register */ +#define AR531X_REV_MAJ_AR5312          0x4 +#define AR531X_REV_MAJ_AR2313          0x5 + +/* Minor revision numbers, bits 3..0 of Revision ID register */ +#define AR5312_REV_MIN_DUAL     0x0     /* Dual WLAN version */ +#define AR5312_REV_MIN_SINGLE   0x1     /* Single WLAN version */ + +/* AR531X_FLASHCTL register bit field definitions */ +#define FLASHCTL_IDCY   0x0000000f      /* Idle cycle turn around time */ +#define FLASHCTL_IDCY_S 0 +#define FLASHCTL_WST1   0x000003e0      /* Wait state 1 */ +#define FLASHCTL_WST1_S 5 +#define FLASHCTL_RBLE   0x00000400      /* Read byte lane enable */ +#define FLASHCTL_WST2   0x0000f800      /* Wait state 2 */ +#define FLASHCTL_WST2_S 11 +#define FLASHCTL_AC     0x00070000      /* Flash address check (added) */ +#define FLASHCTL_AC_S   16 +#define FLASHCTL_AC_128K 0x00000000 +#define FLASHCTL_AC_256K 0x00010000 +#define FLASHCTL_AC_512K 0x00020000 +#define FLASHCTL_AC_1M   0x00030000 +#define FLASHCTL_AC_2M   0x00040000 +#define FLASHCTL_AC_4M   0x00050000 +#define FLASHCTL_AC_8M   0x00060000 +#define FLASHCTL_AC_RES  0x00070000     /* 16MB is not supported */ +#define FLASHCTL_E      0x00080000      /* Flash bank enable (added) */ +#define FLASHCTL_BUSERR 0x01000000      /* Bus transfer error status flag */ +#define FLASHCTL_WPERR  0x02000000      /* Write protect error status flag */ +#define FLASHCTL_WP     0x04000000      /* Write protect */ +#define FLASHCTL_BM     0x08000000      /* Burst mode */ +#define FLASHCTL_MW     0x30000000      /* Memory width */ +#define FLASHCTL_MWx8   0x00000000      /* Memory width x8 */ +#define FLASHCTL_MWx16  0x10000000      /* Memory width x16 */ +#define FLASHCTL_MWx32  0x20000000      /* Memory width x32 (not supported) */ +#define FLASHCTL_ATNR   0x00000000      /* Access type == no retry */ +#define FLASHCTL_ATR    0x80000000      /* Access type == retry every */ +#define FLASHCTL_ATR4   0xc0000000      /* Access type == retry every 4 */ + +/* ARM Flash Controller -- 3 flash banks with either x8 or x16 devices.  */ +#define AR531X_FLASHCTL0        (AR531X_FLASHCTL + 0x00) +#define AR531X_FLASHCTL1        (AR531X_FLASHCTL + 0x04) +#define AR531X_FLASHCTL2        (AR531X_FLASHCTL + 0x08) + +/* ARM SDRAM Controller -- just enough to determine memory size */ +#define AR531X_MEM_CFG1 (AR531X_SDRAMCTL + 0x04) +#define MEM_CFG1_AC0    0x00000700      /* bank 0: SDRAM addr check (added) */ +#define MEM_CFG1_AC0_S  8 +#define MEM_CFG1_AC1    0x00007000      /* bank 1: SDRAM addr check (added) */ +#define MEM_CFG1_AC1_S  12 + +/* GPIO Address Map */ +#define AR531X_GPIO         (AR531X_APBBASE  + 0x2000) +#define AR531X_GPIO_DO      (AR531X_GPIO + 0x00)        /* output register */ +#define AR531X_GPIO_DI      (AR531X_GPIO + 0x04)        /* intput register */ +#define AR531X_GPIO_CR      (AR531X_GPIO + 0x08)        /* control register */ + +/* GPIO Control Register bit field definitions */ +#define AR531X_GPIO_CR_M(x)    (1 << (x))                      /* mask for i/o */ +#define AR531X_GPIO_CR_O(x)    (0 << (x))                      /* mask for output */ +#define AR531X_GPIO_CR_I(x)    (1 << (x))                      /* mask for input */ +#define AR531X_GPIO_CR_INT(x)  (1 << ((x)+8))                  /* mask for interrupt */ +#define AR531X_GPIO_CR_UART(x) (1 << ((x)+16))                 /* uart multiplex */ + +#endif + diff --git a/target/linux/atheros-2.6/files/arch/mips/atheros/ar5315.c b/target/linux/atheros-2.6/files/arch/mips/atheros/ar5315.c new file mode 100644 index 000000000..78b283591 --- /dev/null +++ b/target/linux/atheros-2.6/files/arch/mips/atheros/ar5315.c @@ -0,0 +1,529 @@ +/* + * 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) 2003 Atheros Communications, Inc.,  All Rights Reserved. + * Copyright (C) 2006 FON Technology, SL. + * Copyright (C) 2006 Imre Kaloz <kaloz@openwrt.org> + * Copyright (C) 2006 Felix Fietkau <nbd@openwrt.org> + */ + +/* + * Platform devices for Atheros SoCs + */ + +#include <linux/autoconf.h> +#include <linux/init.h> +#include <linux/module.h> +#include <linux/types.h> +#include <linux/string.h> +#include <linux/platform_device.h> +#include <linux/kernel.h> +#include <linux/reboot.h> +#include <asm/bootinfo.h> +#include <asm/reboot.h> +#include <asm/time.h> +#include <asm/irq.h> +#include <asm/io.h> +#include "ar531x.h" + +#define AR531X_IRQ_MISC_INTRS   MIPS_CPU_IRQ_BASE+2 /* C0_CAUSE: 0x0400 */ +#define AR531X_IRQ_WLAN0_INTRS  MIPS_CPU_IRQ_BASE+3 /* C0_CAUSE: 0x0800 */ +#define AR531X_IRQ_ENET0_INTRS  MIPS_CPU_IRQ_BASE+4 /* C0_CAUSE: 0x1000 */ +#define AR531X_IRQ_LCBUS_PCI    MIPS_CPU_IRQ_BASE+5 /* C0_CAUSE: 0x2000 */ +#define AR531X_IRQ_WLAN0_POLL   MIPS_CPU_IRQ_BASE+6 /* C0_CAUSE: 0x4000 */ + +static struct resource ar5315_eth_res[] = { +	{ +		.name = "eth_membase", +		.flags = IORESOURCE_MEM, +		.start = AR5315_ENET0, +		.end = AR5315_ENET0 + 0x2000, +	}, +	{ +		.name = "eth_irq", +		.flags = IORESOURCE_IRQ, +		.start = AR531X_IRQ_ENET0_INTRS, +		.end = AR531X_IRQ_ENET0_INTRS, +	}, +}; + +static struct ar531x_eth ar5315_eth_data = { +	.phy = 1, +	.mac = 0, +	.reset_base = AR5315_RESET, +	.reset_mac = AR5315_RESET_ENET0, +	.reset_phy = AR5315_RESET_EPHY0, +}; + +static struct platform_device ar5315_eth = { +	.id = 0, +	.name = "ar531x-eth", +	.dev.platform_data = &ar5315_eth_data, +	.resource = ar5315_eth_res, +	.num_resources = ARRAY_SIZE(ar5315_eth_res) +}; + +static struct platform_device ar5315_wmac = { +	.id = 0, +	.name = "ar531x-wmac", +	/* FIXME: add resources */ +}; + +static struct resource ar5315_spiflash_res[] = { +	{ +		.name = "flash_base", +		.flags = IORESOURCE_MEM, +		.start = KSEG1ADDR(AR5315_SPI_READ), +		.end = KSEG1ADDR(AR5315_SPI_READ) + 0x800000, +	}, +	{ +		.name = "flash_regs", +		.flags = IORESOURCE_MEM, +		.start = 0x11300000, +		.end = 0x11300012, +	}, +}; + +static struct platform_device ar5315_spiflash = { +	.id = 0, +	.name = "spiflash", +	.resource = ar5315_spiflash_res, +	.num_resources = ARRAY_SIZE(ar5315_spiflash_res) +}; + +static __initdata struct platform_device *ar5315_devs[4]; + + + +static void *flash_regs; + +static inline __u32 spiflash_regread32(int reg) +{ +	volatile __u32 *data = (__u32 *)(flash_regs + reg); + +	return (*data); +} + +static inline void spiflash_regwrite32(int reg, __u32 data) +{ +	volatile __u32 *addr = (__u32 *)(flash_regs + reg); + +	*addr = data; +} + +#define SPI_FLASH_CTL      0x00 +#define SPI_FLASH_OPCODE   0x04 +#define SPI_FLASH_DATA     0x08 + +static __u8 spiflash_probe(void) +{ +	 __u32 reg; + +	do { +		reg = spiflash_regread32(SPI_FLASH_CTL); +	} while (reg & SPI_CTL_BUSY); + +	spiflash_regwrite32(SPI_FLASH_OPCODE, 0xab); + +	reg = (reg & ~SPI_CTL_TX_RX_CNT_MASK) | 4 | +        	(1 << 4) | SPI_CTL_START; + +	spiflash_regwrite32(SPI_FLASH_CTL, reg); +  +	do { +  		reg = spiflash_regread32(SPI_FLASH_CTL); +	} while (reg & SPI_CTL_BUSY); + +	reg = (__u32) spiflash_regread32(SPI_FLASH_DATA); +	reg &= 0xff; + +	return (u8) reg; +} + + +#define STM_8MBIT_SIGNATURE     0x13 +#define STM_16MBIT_SIGNATURE    0x14 +#define STM_32MBIT_SIGNATURE    0x15 +#define STM_64MBIT_SIGNATURE    0x16 + + +static char __init *ar5315_flash_limit(void) +{ +	u8 sig; +	u32 flash_size = 0; + +	/* probe the flash chip size */ +	flash_regs = ioremap_nocache(ar5315_spiflash_res[1].start, ar5315_spiflash_res[1].end - ar5315_spiflash_res[1].start); +	sig = spiflash_probe(); +	iounmap(flash_regs); + +	switch(sig) { +		case STM_8MBIT_SIGNATURE: +			flash_size = 0x00100000; +			break; +		case STM_16MBIT_SIGNATURE: +			flash_size = 0x00200000; +			break; +		case STM_32MBIT_SIGNATURE: +			flash_size = 0x00400000; +			break; +		case STM_64MBIT_SIGNATURE: +			flash_size = 0x00800000; +			break; +	} + +	ar5315_spiflash_res[0].end = ar5315_spiflash_res[0].start + flash_size; +	return (char *) ar5315_spiflash_res[0].end; +} + +int __init ar5315_init_devices(void) +{ +	struct ar531x_config *config; +	int dev = 0; + +	if (mips_machtype != MACH_ATHEROS_AR5315)  +		return 0; + +	ar531x_find_config(ar5315_flash_limit()); + +	config = (struct ar531x_config *) kzalloc(sizeof(struct ar531x_config), GFP_KERNEL); +	config->board = board_config; +	config->radio = radio_config; +	config->unit = 0; +	config->tag = (u_int16_t) (sysRegRead(AR5315_SREV) & REV_CHIP); +	 +	ar5315_eth_data.board_config = board_config; +	ar5315_wmac.dev.platform_data = config; +	 +	ar5315_devs[dev++] = &ar5315_eth; +	ar5315_devs[dev++] = &ar5315_wmac; +	ar5315_devs[dev++] = &ar5315_spiflash; + +	return platform_add_devices(ar5315_devs, dev); +} + + +/* + * Called when an interrupt is received, this function + * determines exactly which interrupt it was, and it + * invokes the appropriate handler. + * + * Implicitly, we also define interrupt priority by + * choosing which to dispatch first. + */ +asmlinkage void ar5315_irq_dispatch(void) +{ +	int pending = read_c0_status() & read_c0_cause(); + +	if (pending & CAUSEF_IP3) +		do_IRQ(AR531X_IRQ_WLAN0_INTRS); +	else if (pending & CAUSEF_IP4) +		do_IRQ(AR531X_IRQ_ENET0_INTRS); +	else if (pending & CAUSEF_IP2) { +		unsigned int ar531x_misc_intrs = sysRegRead(AR5315_ISR) & sysRegRead(AR5315_IMR); + +	    if (ar531x_misc_intrs & AR5315_ISR_TIMER) +			do_IRQ(AR531X_MISC_IRQ_TIMER); +		else if (ar531x_misc_intrs & AR5315_ISR_AHB) +			do_IRQ(AR531X_MISC_IRQ_AHB_PROC); +		else if (ar531x_misc_intrs & AR5315_ISR_GPIO) { +			sysRegWrite(AR5315_ISR, sysRegRead(AR5315_IMR) | ~AR5315_ISR_GPIO); +		} else if (ar531x_misc_intrs & AR5315_ISR_UART0) +			do_IRQ(AR531X_MISC_IRQ_UART0); +		else if (ar531x_misc_intrs & AR5315_ISR_WD) +			do_IRQ(AR531X_MISC_IRQ_WATCHDOG); +		else +			do_IRQ(AR531X_MISC_IRQ_NONE); +	} else if (pending & CAUSEF_IP7) +		do_IRQ(AR531X_IRQ_CPU_CLOCK); +	else +		do_IRQ(AR531X_IRQ_NONE); +} + +static void ar5315_halt(void) +{ +	 while (1); +} + +static void ar5315_power_off(void) +{ +	 ar5315_halt(); +} + + +static void ar5315_restart(char *command) +{ +	unsigned int reg; +	for(;;) { +		 +		/* reset the system */ +		sysRegWrite(AR5315_COLD_RESET,AR5317_RESET_SYSTEM); + +		/*  +		 * Cold reset does not work on the AR2315/6, use the GPIO reset bits a workaround. +		 */ + +		reg = sysRegRead(AR5315_GPIO_DO); +		reg &= ~(1 << AR5315_RESET_GPIO); +		sysRegWrite(AR5315_GPIO_DO, reg); +		(void)sysRegRead(AR5315_GPIO_DO); /* flush write to hardware */ +	} +} + + +/* + * This table is indexed by bits 5..4 of the CLOCKCTL1 register + * to determine the predevisor value. + */ +static int __initdata CLOCKCTL1_PREDIVIDE_TABLE[4] = { +    1, +    2, +    4, +    5 +}; + +static int __initdata PLLC_DIVIDE_TABLE[5] = { +    2, +    3, +    4, +    6, +    3 +}; + +static unsigned int __init +ar5315_sys_clk(unsigned int clockCtl) +{ +    unsigned int pllcCtrl,cpuDiv; +    unsigned int pllcOut,refdiv,fdiv,divby2; +	unsigned int clkDiv; + +    pllcCtrl = sysRegRead(AR5315_PLLC_CTL); +    refdiv = (pllcCtrl & PLLC_REF_DIV_M) >> PLLC_REF_DIV_S; +    refdiv = CLOCKCTL1_PREDIVIDE_TABLE[refdiv]; +    fdiv = (pllcCtrl & PLLC_FDBACK_DIV_M) >> PLLC_FDBACK_DIV_S; +    divby2 = (pllcCtrl & PLLC_ADD_FDBACK_DIV_M) >> PLLC_ADD_FDBACK_DIV_S; +    divby2 += 1; +    pllcOut = (40000000/refdiv)*(2*divby2)*fdiv; + + +    /* clkm input selected */ +	switch(clockCtl & CPUCLK_CLK_SEL_M) { +		case 0: +		case 1: +			clkDiv = PLLC_DIVIDE_TABLE[(pllcCtrl & PLLC_CLKM_DIV_M) >> PLLC_CLKM_DIV_S]; +			break; +		case 2: +			clkDiv = PLLC_DIVIDE_TABLE[(pllcCtrl & PLLC_CLKC_DIV_M) >> PLLC_CLKC_DIV_S]; +			break; +		default: +			pllcOut = 40000000; +			clkDiv = 1; +			break; +	} +	cpuDiv = (clockCtl & CPUCLK_CLK_DIV_M) >> CPUCLK_CLK_DIV_S;   +	cpuDiv = cpuDiv * 2 ?: 1; +	return (pllcOut/(clkDiv * cpuDiv)); +} +		 +static inline unsigned int ar5315_cpu_frequency(void) +{ +    return ar5315_sys_clk(sysRegRead(AR5315_CPUCLK)); +} + +static inline unsigned int ar5315_apb_frequency(void) +{ +    return ar5315_sys_clk(sysRegRead(AR5315_AMBACLK)); +} + +static void __init ar5315_time_init(void) +{ +	mips_hpt_frequency = ar5315_cpu_frequency() / 2; +} + + + +/* Enable the specified AR531X_MISC_IRQ interrupt */ +static void +ar5315_misc_intr_enable(unsigned int irq) +{ +	unsigned int imr; + +	imr = sysRegRead(AR5315_IMR); +	switch(irq) +	{ +	   case AR531X_MISC_IRQ_TIMER: +	     imr |= AR5315_ISR_TIMER; +	     break; + +	   case AR531X_MISC_IRQ_AHB_PROC: +	     imr |= AR5315_ISR_AHB; +	     break; + +	   case AR531X_MISC_IRQ_AHB_DMA: +	     imr |= 0/* ?? */; +	     break; + +	   case	AR531X_MISC_IRQ_GPIO: +	     imr |= AR5315_ISR_GPIO; +	     break; + +	   case AR531X_MISC_IRQ_UART0: +	     imr |= AR5315_ISR_UART0; +	     break; + + +	   case	AR531X_MISC_IRQ_WATCHDOG: +	     imr |= AR5315_ISR_WD; +	     break; + +	   case AR531X_MISC_IRQ_LOCAL: +	     imr |= 0/* ?? */; +	     break; + +	} +	sysRegWrite(AR5315_IMR, imr); +	imr=sysRegRead(AR5315_IMR); /* flush write buffer */ +	//printk("enable Interrupt irq 0x%x imr 0x%x \n",irq,imr); + +} + +/* Disable the specified AR531X_MISC_IRQ interrupt */ +static void +ar5315_misc_intr_disable(unsigned int irq) +{ +	unsigned int imr; + +	imr = sysRegRead(AR5315_IMR); +	switch(irq) +	{ +	   case AR531X_MISC_IRQ_TIMER: +	     imr &= (~AR5315_ISR_TIMER); +	     break; + +	   case AR531X_MISC_IRQ_AHB_PROC: +	     imr &= (~AR5315_ISR_AHB); +	     break; + +	   case AR531X_MISC_IRQ_AHB_DMA: +	     imr &= 0/* ?? */; +	     break; + +	   case	AR531X_MISC_IRQ_GPIO: +	     imr &= ~AR5315_ISR_GPIO; +	     break; + +	   case AR531X_MISC_IRQ_UART0: +	     imr &= (~AR5315_ISR_UART0); +	     break; + +	   case	AR531X_MISC_IRQ_WATCHDOG: +	     imr &= (~AR5315_ISR_WD); +	     break; + +	   case AR531X_MISC_IRQ_LOCAL: +	     imr &= ~0/* ?? */; +	     break; + +	} +	sysRegWrite(AR5315_IMR, imr); +	sysRegRead(AR5315_IMR); /* flush write buffer */ +} + +/* Turn on the specified AR531X_MISC_IRQ interrupt */ +static unsigned int +ar5315_misc_intr_startup(unsigned int irq) +{ +	ar5315_misc_intr_enable(irq); +	return 0; +} + +/* Turn off the specified AR531X_MISC_IRQ interrupt */ +static void +ar5315_misc_intr_shutdown(unsigned int irq) +{ +	ar5315_misc_intr_disable(irq); +} + +static void +ar5315_misc_intr_ack(unsigned int irq) +{ +	ar5315_misc_intr_disable(irq); +} + +static void +ar5315_misc_intr_end(unsigned int irq) +{ +	if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) +		ar5315_misc_intr_enable(irq); +} + +static struct irq_chip ar5315_misc_intr_controller = { +	.typename	= "AR5315 misc", +	.startup	= ar5315_misc_intr_startup, +	.shutdown	= ar5315_misc_intr_shutdown, +	.enable		= ar5315_misc_intr_enable, +	.disable	= ar5315_misc_intr_disable, +	.ack		= ar5315_misc_intr_ack, +	.end		= ar5315_misc_intr_end, +}; + +static irqreturn_t ar5315_ahb_proc_handler(int cpl, void *dev_id) +{ +    sysRegWrite(AR5315_AHB_ERR0,AHB_ERROR_DET); +    sysRegRead(AR5315_AHB_ERR1); + +    printk("AHB fatal error\n"); +    machine_restart("AHB error"); /* Catastrophic failure */ + +    return IRQ_HANDLED; +} + +static struct irqaction ar5315_ahb_proc_interrupt  = { +	.handler	= ar5315_ahb_proc_handler, +	.flags		= SA_INTERRUPT, +	.name		= "ar5315_ahb_proc_interrupt", +}; + + +static struct irqaction cascade  = { +	.handler	= no_action, +	.flags		= SA_INTERRUPT, +	.name		= "cascade", +}; + +void ar5315_misc_intr_init(int irq_base) +{ +	int i; + +	for (i = irq_base; i < irq_base + AR531X_MISC_IRQ_COUNT; i++) { +		irq_desc[i].status = IRQ_DISABLED; +		irq_desc[i].action = NULL; +		irq_desc[i].depth = 1; +		irq_desc[i].chip = &ar5315_misc_intr_controller; +	} +	setup_irq(AR531X_MISC_IRQ_AHB_PROC, &ar5315_ahb_proc_interrupt); +	setup_irq(AR531X_IRQ_MISC_INTRS, &cascade); +} + +void __init ar5315_plat_setup(void) +{ +	unsigned int config = read_c0_config(); + +	/* Clear any lingering AHB errors */ +	write_c0_config(config & ~0x3); +	sysRegWrite(AR5315_AHB_ERR0,AHB_ERROR_DET); +	sysRegRead(AR5315_AHB_ERR1); +	sysRegWrite(AR5315_WDC, WDC_IGNORE_EXPIRATION); + +	board_time_init = ar5315_time_init; + +	_machine_restart = ar5315_restart; +	_machine_halt = ar5315_halt; +	pm_power_off = ar5315_power_off; + +	serial_setup(KSEG1ADDR(AR5315_UART0), ar5315_apb_frequency()); +} + +arch_initcall(ar5315_init_devices); diff --git a/target/linux/atheros-2.6/files/arch/mips/atheros/ar5315.h b/target/linux/atheros-2.6/files/arch/mips/atheros/ar5315.h new file mode 100644 index 000000000..b523f8040 --- /dev/null +++ b/target/linux/atheros-2.6/files/arch/mips/atheros/ar5315.h @@ -0,0 +1,678 @@ +/* + * 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) 2003 Atheros Communications, Inc.,  All Rights Reserved. + * Copyright (C) 2006 FON Technology, SL. + * Copyright (C) 2006 Imre Kaloz <kaloz@openwrt.org> + * Copyright (C) 2006 Felix Fietkau <nbd@openwrt.org> + */ + +#ifndef AR5315_H +#define AR5315_H + +/* + * Address map + */ +#define AR5315_SDRAM0           0x00000000      /* DRAM */ +#define AR5315_SPI_READ         0x08000000      /* SPI FLASH */ +#define AR5315_WLAN0            0xB0000000      /* Wireless MMR */ +#define AR5315_PCI              0xB0100000      /* PCI MMR */ +#define AR5315_SDRAMCTL         0xB0300000      /* SDRAM MMR */ +#define AR5315_LOCAL            0xB0400000      /* LOCAL BUS MMR */ +#define AR5315_ENET0            0xB0500000      /* ETHERNET MMR */ +#define AR5315_DSLBASE          0xB1000000      /* RESET CONTROL MMR */ +#define AR5315_UART0            0xB1100003      /* UART MMR */ +#define AR5315_SPI              0xB1300000      /* SPI FLASH MMR */ +#define AR5315_FLASHBT          0xBfc00000      /* ro boot alias to FLASH */ +#define AR5315_RAM1             0x40000000      /* ram alias */ +#define AR5315_PCIEXT           0x80000000      /* pci external */ +#define AR5315_RAM2             0xc0000000      /* ram alias */ +#define AR5315_RAM3             0xe0000000      /* ram alias */ + +/* + * Reset Register + */ +#define AR5315_COLD_RESET       (AR5315_DSLBASE + 0x0000) + +/* Cold Reset */ +#define RESET_COLD_AHB              0x00000001 +#define RESET_COLD_APB              0x00000002 +#define RESET_COLD_CPU              0x00000004 +#define RESET_COLD_CPUWARM          0x00000008 +#define RESET_SYSTEM                (RESET_COLD_CPU | RESET_COLD_APB | RESET_COLD_AHB)      /* full system */ + +#define AR5317_RESET_SYSTEM	    0x00000010 + +/* Warm Reset */ + +#define AR5315_RESET            (AR5315_DSLBASE + 0x0004) + +#define AR5315_RESET_WARM_WLAN0_MAC        0x00000001      /* warm reset WLAN0 MAC */ +#define AR5315_RESET_WARM_WLAN0_BB         0x00000002      /* warm reset WLAN0 BaseBand */ +#define AR5315_RESET_MPEGTS_RSVD           0x00000004      /* warm reset MPEG-TS */ +#define AR5315_RESET_PCIDMA                0x00000008      /* warm reset PCI ahb/dma */ +#define AR5315_RESET_MEMCTL                0x00000010      /* warm reset memory controller */ +#define AR5315_RESET_LOCAL                 0x00000020      /* warm reset local bus */ +#define AR5315_RESET_I2C_RSVD              0x00000040      /* warm reset I2C bus */ +#define AR5315_RESET_SPI                   0x00000080      /* warm reset SPI interface */ +#define AR5315_RESET_UART0                 0x00000100      /* warm reset UART0 */ +#define AR5315_RESET_IR_RSVD               0x00000200      /* warm reset IR interface */ +#define AR5315_RESET_EPHY0                 0x00000400      /* cold reset ENET0 phy */ +#define AR5315_RESET_ENET0                 0x00000800      /* cold reset ENET0 mac */ + +/* + * AHB master arbitration control + */ +#define AR5315_AHB_ARB_CTL      (AR5315_DSLBASE + 0x0008) + +#define ARB_CPU                     0x00000001      /* CPU, default */ +#define ARB_WLAN                    0x00000002      /* WLAN */ +#define ARB_MPEGTS_RSVD             0x00000004      /* MPEG-TS */ +#define ARB_LOCAL                   0x00000008      /* LOCAL */ +#define ARB_PCI                     0x00000010      /* PCI */ +#define ARB_ETHERNET                0x00000020      /* Ethernet */ +#define ARB_RETRY                   0x00000100      /* retry policy, debug only */ + +/* + * Config Register + */ +#define AR5315_ENDIAN_CTL       (AR5315_DSLBASE + 0x000c) + +#define CONFIG_AHB                  0x00000001      /* EC - AHB bridge endianess */ +#define CONFIG_WLAN                 0x00000002      /* WLAN byteswap */ +#define CONFIG_MPEGTS_RSVD          0x00000004      /* MPEG-TS byteswap */ +#define CONFIG_PCI                  0x00000008      /* PCI byteswap */ +#define CONFIG_MEMCTL               0x00000010      /* Memory controller endianess */ +#define CONFIG_LOCAL                0x00000020      /* Local bus byteswap */ +#define CONFIG_ETHERNET             0x00000040      /* Ethernet byteswap */ + +#define CONFIG_MERGE                0x00000200      /* CPU write buffer merge */ +#define CONFIG_CPU                  0x00000400      /* CPU big endian */ +#define CONFIG_PCIAHB               0x00000800 +#define CONFIG_PCIAHB_BRIDGE        0x00001000 +#define CONFIG_SPI                  0x00008000      /* SPI byteswap */ +#define CONFIG_CPU_DRAM             0x00010000 +#define CONFIG_CPU_PCI              0x00020000 +#define CONFIG_CPU_MMR              0x00040000 +#define CONFIG_BIG                  0x00000400       + + +/* + * NMI control + */ +#define AR5315_NMI_CTL          (AR5315_DSLBASE + 0x0010) + +#define NMI_EN  1 + +/* + * Revision Register - Initial value is 0x3010 (WMAC 3.0, AR531X 1.0). + */ +#define AR5315_SREV             (AR5315_DSLBASE + 0x0014) + +#define REV_MAJ                     0x00f0 +#define REV_MAJ_S                   4 +#define REV_MIN                     0x000f +#define REV_MIN_S                   0 +#define REV_CHIP                    (REV_MAJ|REV_MIN) + +/* + * Interface Enable + */ +#define AR5315_IF_CTL           (AR5315_DSLBASE + 0x0018) + +#define IF_MASK                     0x00000007 +#define IF_DISABLED                 0 +#define IF_PCI                      1 +#define IF_TS_LOCAL                 2 +#define IF_ALL                      3   /* only for emulation with separate pins */ +#define IF_LOCAL_HOST               0x00000008 +#define IF_PCI_HOST                 0x00000010 +#define IF_PCI_INTR                 0x00000020 +#define IF_PCI_CLK_MASK             0x00030000 +#define IF_PCI_CLK_INPUT            0  +#define IF_PCI_CLK_OUTPUT_LOW       1 +#define IF_PCI_CLK_OUTPUT_CLK       2 +#define IF_PCI_CLK_OUTPUT_HIGH      3 +#define IF_PCI_CLK_SHIFT            16  +  +                 +/* Major revision numbers, bits 7..4 of Revision ID register */ +#define REV_MAJ_AR5311              0x01 +#define REV_MAJ_AR5312              0x04 +#define REV_MAJ_AR5315              0x0B + +/* + * APB Interrupt control + */ + +#define AR5315_ISR              (AR5315_DSLBASE + 0x0020) +#define AR5315_IMR              (AR5315_DSLBASE + 0x0024) +#define AR5315_GISR             (AR5315_DSLBASE + 0x0028) + +#define AR5315_ISR_UART0                   0x0001           /* high speed UART */ +#define AR5315_ISR_I2C_RSVD                0x0002           /* I2C bus */ +#define AR5315_ISR_SPI                     0x0004           /* SPI bus */ +#define AR5315_ISR_AHB                     0x0008           /* AHB error */ +#define AR5315_ISR_APB                     0x0010           /* APB error */ +#define AR5315_ISR_TIMER                   0x0020           /* timer */ +#define AR5315_ISR_GPIO                    0x0040           /* GPIO */ +#define AR5315_ISR_WD                      0x0080           /* watchdog */ +#define AR5315_ISR_IR_RSVD                 0x0100           /* IR */ +                                 +#define AR5315_GISR_MISC                   0x0001 +#define AR5315_GISR_WLAN0                  0x0002 +#define AR5315_GISR_MPEGTS_RSVD            0x0004 +#define AR5315_GISR_LOCALPCI               0x0008 +#define AR5315_GISR_WMACPOLL               0x0010 +#define AR5315_GISR_TIMER                  0x0020 +#define AR5315_GISR_ETHERNET               0x0040 + +/* + * Interrupt routing from IO to the processor IP bits + * Define our inter mask and level + */ +#define AR5315_INTR_MISCIO      SR_IBIT3 +#define AR5315_INTR_WLAN0       SR_IBIT4 +#define AR5315_INTR_ENET0       SR_IBIT5 +#define AR5315_INTR_LOCALPCI    SR_IBIT6 +#define AR5315_INTR_WMACPOLL    SR_IBIT7 +#define AR5315_INTR_COMPARE     SR_IBIT8 + +/* + * Timers + */ +#define AR5315_TIMER            (AR5315_DSLBASE + 0x0030) +#define AR5315_RELOAD           (AR5315_DSLBASE + 0x0034) +#define AR5315_WD               (AR5315_DSLBASE + 0x0038) +#define AR5315_WDC              (AR5315_DSLBASE + 0x003c) + +#define WDC_RESET                   0x00000002               /* reset on watchdog */ +#define WDC_NMI                     0x00000001               /* NMI on watchdog */ +#define WDC_IGNORE_EXPIRATION       0x00000000 + +/* + * CPU Performance Counters + */ +#define AR5315_PERFCNT0         (AR5315_DSLBASE + 0x0048) +#define AR5315_PERFCNT1         (AR5315_DSLBASE + 0x004c) + +#define PERF_DATAHIT                0x0001  /* Count Data Cache Hits */ +#define PERF_DATAMISS               0x0002  /* Count Data Cache Misses */ +#define PERF_INSTHIT                0x0004  /* Count Instruction Cache Hits */ +#define PERF_INSTMISS               0x0008  /* Count Instruction Cache Misses */ +#define PERF_ACTIVE                 0x0010  /* Count Active Processor Cycles */ +#define PERF_WBHIT                  0x0020  /* Count CPU Write Buffer Hits */ +#define PERF_WBMISS                 0x0040  /* Count CPU Write Buffer Misses */ +                                 +#define PERF_EB_ARDY                0x0001  /* Count EB_ARdy signal */ +#define PERF_EB_AVALID              0x0002  /* Count EB_AValid signal */ +#define PERF_EB_WDRDY               0x0004  /* Count EB_WDRdy signal */ +#define PERF_EB_RDVAL               0x0008  /* Count EB_RdVal signal */ +#define PERF_VRADDR                 0x0010  /* Count valid read address cycles */ +#define PERF_VWADDR                 0x0020  /* Count valid write address cycles */ +#define PERF_VWDATA                 0x0040  /* Count valid write data cycles */ + +/* + * AHB Error Reporting. + */ +#define AR5315_AHB_ERR0         (AR5315_DSLBASE + 0x0050)  /* error  */ +#define AR5315_AHB_ERR1         (AR5315_DSLBASE + 0x0054)  /* haddr  */ +#define AR5315_AHB_ERR2         (AR5315_DSLBASE + 0x0058)  /* hwdata */ +#define AR5315_AHB_ERR3         (AR5315_DSLBASE + 0x005c)  /* hrdata */ +#define AR5315_AHB_ERR4         (AR5315_DSLBASE + 0x0060)  /* status */ + +#define AHB_ERROR_DET               1   /* AHB Error has been detected,          */ +                                        /* write 1 to clear all bits in ERR0     */ +#define AHB_ERROR_OVR               2   /* AHB Error overflow has been detected  */ +#define AHB_ERROR_WDT               4   /* AHB Error due to wdt instead of hresp */ + +#define PROCERR_HMAST               0x0000000f +#define PROCERR_HMAST_DFLT          0 +#define PROCERR_HMAST_WMAC          1 +#define PROCERR_HMAST_ENET          2 +#define PROCERR_HMAST_PCIENDPT      3 +#define PROCERR_HMAST_LOCAL         4 +#define PROCERR_HMAST_CPU           5 +#define PROCERR_HMAST_PCITGT        6 +                                     +#define PROCERR_HMAST_S             0 +#define PROCERR_HWRITE              0x00000010 +#define PROCERR_HSIZE               0x00000060 +#define PROCERR_HSIZE_S             5 +#define PROCERR_HTRANS              0x00000180 +#define PROCERR_HTRANS_S            7 +#define PROCERR_HBURST              0x00000e00 +#define PROCERR_HBURST_S            9 + + + +/* + * Clock Control + */ +#define AR5315_PLLC_CTL         (AR5315_DSLBASE + 0x0064) +#define AR5315_PLLV_CTL         (AR5315_DSLBASE + 0x0068) +#define AR5315_CPUCLK           (AR5315_DSLBASE + 0x006c) +#define AR5315_AMBACLK          (AR5315_DSLBASE + 0x0070) +#define AR5315_SYNCCLK          (AR5315_DSLBASE + 0x0074) +#define AR5315_DSL_SLEEP_CTL    (AR5315_DSLBASE + 0x0080) +#define AR5315_DSL_SLEEP_DUR    (AR5315_DSLBASE + 0x0084) + +/* PLLc Control fields */ +#define PLLC_REF_DIV_M              0x00000003 +#define PLLC_REF_DIV_S              0 +#define PLLC_FDBACK_DIV_M           0x0000007C +#define PLLC_FDBACK_DIV_S           2 +#define PLLC_ADD_FDBACK_DIV_M       0x00000080 +#define PLLC_ADD_FDBACK_DIV_S       7 +#define PLLC_CLKC_DIV_M             0x0001c000 +#define PLLC_CLKC_DIV_S             14 +#define PLLC_CLKM_DIV_M             0x00700000 +#define PLLC_CLKM_DIV_S             20 + +/* CPU CLK Control fields */ +#define CPUCLK_CLK_SEL_M            0x00000003 +#define CPUCLK_CLK_SEL_S            0 +#define CPUCLK_CLK_DIV_M            0x0000000c +#define CPUCLK_CLK_DIV_S            2 + +/* AMBA CLK Control fields */ +#define AMBACLK_CLK_SEL_M           0x00000003 +#define AMBACLK_CLK_SEL_S           0 +#define AMBACLK_CLK_DIV_M           0x0000000c +#define AMBACLK_CLK_DIV_S           2 + +#if defined(COBRA_EMUL) +#define AR5315_AMBA_CLOCK_RATE  20000000 +#define AR5315_CPU_CLOCK_RATE   40000000 +#else +#if defined(DEFAULT_PLL) +#define AR5315_AMBA_CLOCK_RATE  40000000 +#define AR5315_CPU_CLOCK_RATE   40000000 +#else +#define AR5315_AMBA_CLOCK_RATE  92000000 +#define AR5315_CPU_CLOCK_RATE   184000000 +#endif /* ! DEFAULT_PLL */ +#endif /* ! COBRA_EMUL */ + +#define AR5315_UART_CLOCK_RATE  AR5315_AMBA_CLOCK_RATE +#define AR5315_SDRAM_CLOCK_RATE AR5315_AMBA_CLOCK_RATE + +/* + * The UART computes baud rate as: + *   baud = clock / (16 * divisor) + * where divisor is specified as a High Byte (DLM) and a Low Byte (DLL). + */ +#define DESIRED_BAUD_RATE           38400 + + +#define CLOCKCTL_UART0  0x0010  /* enable UART0 external clock */ + + + /* + * Applicable "PCICFG" bits for WLAN(s).  Assoc status and LED mode. + */ +#define ASSOC_STATUS_M              0x00000003 +#define ASSOC_STATUS_NONE           0 +#define ASSOC_STATUS_PENDING        1    +#define ASSOC_STATUS_ASSOCIATED     2 +#define LED_MODE_M                  0x0000001c +#define LED_BLINK_THRESHOLD_M       0x000000e0 +#define LED_SLOW_BLINK_MODE         0x00000100 + +/* + * GPIO + */ + +#define AR5315_GPIO_DI          (AR5315_DSLBASE + 0x0088) +#define AR5315_GPIO_DO          (AR5315_DSLBASE + 0x0090) +#define AR5315_GPIO_CR          (AR5315_DSLBASE + 0x0098) +#define AR5315_GPIO_INT         (AR5315_DSLBASE + 0x00a0) + +#define AR5315_GPIO_CR_M(x)                (1 << (x))                  /* mask for i/o */ +#define AR5315_GPIO_CR_O(x)                (1 << (x))                  /* output */ +#define AR5315_GPIO_CR_I(x)                (0 << (x))                  /* input */ + +#define AR5315_GPIO_INT_S(x,Y)             ((x) << (8 * (Y)))          /* interrupt enable */ +#define AR5315_GPIO_INT_M(Y)               ((0x3F) << (8 * (Y)))       /* mask for int */ +#define AR5315_GPIO_INT_LVL(x,Y)           ((x) << (8 * (Y) + 6))      /* interrupt level */ +#define AR5315_GPIO_INT_LVL_M(Y)           ((0x3) << (8 * (Y) + 6))    /* mask for int level */ + +#define AR5315_RESET_GPIO       5 +#define AR5315_NUM_GPIO         22 + +     +/*  + *  PCI Clock Control + */      +  +#define AR5315_PCICLK           (AR5315_DSLBASE + 0x00a4) + +#define PCICLK_INPUT_M              0x3 +#define PCICLK_INPUT_S              0 +                          +#define PCICLK_PLLC_CLKM            0 +#define PCICLK_PLLC_CLKM1           1 +#define PCICLK_PLLC_CLKC            2 +#define PCICLK_REF_CLK              3  + +#define PCICLK_DIV_M                0xc +#define PCICLK_DIV_S                2 +                          +#define PCICLK_IN_FREQ              0 +#define PCICLK_IN_FREQ_DIV_6        1 +#define PCICLK_IN_FREQ_DIV_8        2 +#define PCICLK_IN_FREQ_DIV_10       3  + +/* + * Observation Control Register + */ +#define AR5315_OCR              (AR5315_DSLBASE + 0x00b0) +#define OCR_GPIO0_IRIN              0x0040 +#define OCR_GPIO1_IROUT             0x0080 +#define OCR_GPIO3_RXCLR             0x0200 + +/*  + *  General Clock Control + */      +  +#define AR5315_MISCCLK          (AR5315_DSLBASE + 0x00b4) +#define MISCCLK_PLLBYPASS_EN        0x00000001 +#define MISCCLK_PROCREFCLK          0x00000002 + +/* + * SDRAM Controller + *   - No read or write buffers are included. + */ +#define AR5315_MEM_CFG          (AR5315_SDRAMCTL + 0x00) +#define AR5315_MEM_CTRL         (AR5315_SDRAMCTL + 0x0c) +#define AR5315_MEM_REF          (AR5315_SDRAMCTL + 0x10) + +#define SDRAM_DATA_WIDTH_M          0x00006000 +#define SDRAM_DATA_WIDTH_S          13 + +#define SDRAM_COL_WIDTH_M           0x00001E00 +#define SDRAM_COL_WIDTH_S           9 + +#define SDRAM_ROW_WIDTH_M           0x000001E0 +#define SDRAM_ROW_WIDTH_S           5 + +#define SDRAM_BANKADDR_BITS_M       0x00000018 +#define SDRAM_BANKADDR_BITS_S       3 + +/* + * SPI Flash Interface Registers + */ + +#define AR5315_SPI_CTL      (AR5315_SPI + 0x00) +#define AR5315_SPI_OPCODE   (AR5315_SPI + 0x04) +#define AR5315_SPI_DATA     (AR5315_SPI + 0x08) + +#define SPI_CTL_START           0x00000100 +#define SPI_CTL_BUSY            0x00010000 +#define SPI_CTL_TXCNT_MASK      0x0000000f +#define SPI_CTL_RXCNT_MASK      0x000000f0 +#define SPI_CTL_TX_RX_CNT_MASK  0x000000ff +#define SPI_CTL_SIZE_MASK       0x00060000 + +#define SPI_CTL_CLK_SEL_MASK    0x03000000 +#define SPI_OPCODE_MASK         0x000000ff + +/*  + * PCI-MAC Configuration registers  + */ +#define PCI_MAC_RC              (AR5315_PCI + 0x4000)  +#define PCI_MAC_SCR             (AR5315_PCI + 0x4004) +#define PCI_MAC_INTPEND         (AR5315_PCI + 0x4008) +#define PCI_MAC_SFR             (AR5315_PCI + 0x400C) +#define PCI_MAC_PCICFG          (AR5315_PCI + 0x4010) +#define PCI_MAC_SREV            (AR5315_PCI + 0x4020) + +#define PCI_MAC_RC_MAC          0x00000001 +#define PCI_MAC_RC_BB           0x00000002 + +#define PCI_MAC_SCR_SLMODE_M    0x00030000 +#define PCI_MAC_SCR_SLMODE_S    16         +#define PCI_MAC_SCR_SLM_FWAKE   0          +#define PCI_MAC_SCR_SLM_FSLEEP  1          +#define PCI_MAC_SCR_SLM_NORMAL  2          + +#define PCI_MAC_SFR_SLEEP       0x00000001 + +#define PCI_MAC_PCICFG_SPWR_DN  0x00010000 + +  +/* + * PCI Bus Interface Registers + */ +#define AR5315_PCI_1MS_REG      (AR5315_PCI + 0x0008) +#define AR5315_PCI_1MS_MASK     0x3FFFF         /* # of AHB clk cycles in 1ms */ + +#define AR5315_PCI_MISC_CONFIG  (AR5315_PCI + 0x000c) +#define AR5315_PCIMISC_TXD_EN   0x00000001      /* Enable TXD for fragments */ +#define AR5315_PCIMISC_CFG_SEL  0x00000002      /* mem or config cycles */ +#define AR5315_PCIMISC_GIG_MASK 0x0000000C      /* bits 31-30 for pci req */ +#define AR5315_PCIMISC_RST_MODE 0x00000030 +#define AR5315_PCIRST_INPUT     0x00000000      /* 4:5=0 rst is input */ +#define AR5315_PCIRST_LOW       0x00000010      /* 4:5=1 rst to GND */ +#define AR5315_PCIRST_HIGH      0x00000020      /* 4:5=2 rst to VDD */ +#define AR5315_PCIGRANT_EN      0x00000000      /* 6:7=0 early grant en */ +#define AR5315_PCIGRANT_FRAME   0x00000040      /* 6:7=1 grant waits 4 frame */ +#define AR5315_PCIGRANT_IDLE    0x00000080      /* 6:7=2 grant waits 4 idle */ +#define AR5315_PCIGRANT_GAP     0x00000000      /* 6:7=2 grant waits 4 idle */ +#define AR5315_PCICACHE_DIS     0x00001000      /* PCI external access cache disable */ + +#define AR5315_PCI_OUT_TSTAMP   (AR5315_PCI + 0x0010) + +#define AR5315_PCI_UNCACHE_CFG  (AR5315_PCI + 0x0014) + +#define AR5315_PCI_IN_EN        (AR5315_PCI + 0x0100) +#define AR5315_PCI_IN_EN0       0x01            /* Enable chain 0 */ +#define AR5315_PCI_IN_EN1       0x02            /* Enable chain 1 */ +#define AR5315_PCI_IN_EN2       0x04            /* Enable chain 2 */ +#define AR5315_PCI_IN_EN3       0x08            /* Enable chain 3 */ + +#define AR5315_PCI_IN_DIS       (AR5315_PCI + 0x0104) +#define AR5315_PCI_IN_DIS0      0x01            /* Disable chain 0 */ +#define AR5315_PCI_IN_DIS1      0x02            /* Disable chain 1 */ +#define AR5315_PCI_IN_DIS2      0x04            /* Disable chain 2 */ +#define AR5315_PCI_IN_DIS3      0x08            /* Disable chain 3 */ + +#define AR5315_PCI_IN_PTR       (AR5315_PCI + 0x0200) + +#define AR5315_PCI_OUT_EN       (AR5315_PCI + 0x0400) +#define AR5315_PCI_OUT_EN0      0x01            /* Enable chain 0 */ + +#define AR5315_PCI_OUT_DIS      (AR5315_PCI + 0x0404) +#define AR5315_PCI_OUT_DIS0     0x01            /* Disable chain 0 */ + +#define AR5315_PCI_OUT_PTR      (AR5315_PCI + 0x0408) + +#define AR5315_PCI_INT_STATUS   (AR5315_PCI + 0x0500)   /* write one to clr */ +#define AR5315_PCI_TXINT        0x00000001      /* Desc In Completed */ +#define AR5315_PCI_TXOK         0x00000002      /* Desc In OK */ +#define AR5315_PCI_TXERR        0x00000004      /* Desc In ERR */ +#define AR5315_PCI_TXEOL        0x00000008      /* Desc In End-of-List */ +#define AR5315_PCI_RXINT        0x00000010      /* Desc Out Completed */ +#define AR5315_PCI_RXOK         0x00000020      /* Desc Out OK */ +#define AR5315_PCI_RXERR        0x00000040      /* Desc Out ERR */ +#define AR5315_PCI_RXEOL        0x00000080      /* Desc Out EOL */ +#define AR5315_PCI_TXOOD        0x00000200      /* Desc In Out-of-Desc */ +#define AR5315_PCI_MASK         0x0000FFFF      /* Desc Mask */ +#define AR5315_PCI_EXT_INT      0x02000000       +#define AR5315_PCI_ABORT_INT    0x04000000       + +#define AR5315_PCI_INT_MASK     (AR5315_PCI + 0x0504)   /* same as INT_STATUS */ + +#define AR5315_PCI_INTEN_REG    (AR5315_PCI + 0x0508) +#define AR5315_PCI_INT_DISABLE  0x00            /* disable pci interrupts */ +#define AR5315_PCI_INT_ENABLE   0x01            /* enable pci interrupts */ + +#define AR5315_PCI_HOST_IN_EN   (AR5315_PCI + 0x0800) +#define AR5315_PCI_HOST_IN_DIS  (AR5315_PCI + 0x0804) +#define AR5315_PCI_HOST_IN_PTR  (AR5315_PCI + 0x0810) +#define AR5315_PCI_HOST_OUT_EN  (AR5315_PCI + 0x0900) +#define AR5315_PCI_HOST_OUT_DIS (AR5315_PCI + 0x0904) +#define AR5315_PCI_HOST_OUT_PTR (AR5315_PCI + 0x0908) + + +/* + * Local Bus Interface Registers + */ +#define AR5315_LB_CONFIG        (AR5315_LOCAL + 0x0000) +#define AR5315_LBCONF_OE        0x00000001      /* =1 OE is low-true */ +#define AR5315_LBCONF_CS0       0x00000002      /* =1 first CS is low-true */ +#define AR5315_LBCONF_CS1       0x00000004      /* =1 2nd CS is low-true */ +#define AR5315_LBCONF_RDY       0x00000008      /* =1 RDY is low-true */ +#define AR5315_LBCONF_WE        0x00000010      /* =1 Write En is low-true */ +#define AR5315_LBCONF_WAIT      0x00000020      /* =1 WAIT is low-true */ +#define AR5315_LBCONF_ADS       0x00000040      /* =1 Adr Strobe is low-true */ +#define AR5315_LBCONF_MOT       0x00000080      /* =0 Intel, =1 Motorola */ +#define AR5315_LBCONF_8CS       0x00000100      /* =1 8 bits CS, 0= 16bits */ +#define AR5315_LBCONF_8DS       0x00000200      /* =1 8 bits Data S, 0=16bits */ +#define AR5315_LBCONF_ADS_EN    0x00000400      /* =1 Enable ADS */ +#define AR5315_LBCONF_ADR_OE    0x00000800      /* =1 Adr cap on OE, WE or DS */ +#define AR5315_LBCONF_ADDT_MUX  0x00001000      /* =1 Adr and Data share bus */ +#define AR5315_LBCONF_DATA_OE   0x00002000      /* =1 Data cap on OE, WE, DS */ +#define AR5315_LBCONF_16DATA    0x00004000      /* =1 Data is 16 bits wide */ +#define AR5315_LBCONF_SWAPDT    0x00008000      /* =1 Byte swap data */ +#define AR5315_LBCONF_SYNC      0x00010000      /* =1 Bus synchronous to clk */ +#define AR5315_LBCONF_INT       0x00020000      /* =1 Intr is low true */ +#define AR5315_LBCONF_INT_CTR0  0x00000000      /* GND high-Z, Vdd is high-Z */ +#define AR5315_LBCONF_INT_CTR1  0x00040000      /* GND drive, Vdd is high-Z */ +#define AR5315_LBCONF_INT_CTR2  0x00080000      /* GND high-Z, Vdd drive */ +#define AR5315_LBCONF_INT_CTR3  0x000C0000      /* GND drive, Vdd drive */ +#define AR5315_LBCONF_RDY_WAIT  0x00100000      /* =1 RDY is negative of WAIT */ +#define AR5315_LBCONF_INT_PULSE 0x00200000      /* =1 Interrupt is a pulse */ +#define AR5315_LBCONF_ENABLE    0x00400000      /* =1 Falcon respond to LB */ + +#define AR5315_LB_CLKSEL        (AR5315_LOCAL + 0x0004) +#define AR5315_LBCLK_EXT        0x0001          /* use external clk for lb */ + +#define AR5315_LB_1MS           (AR5315_LOCAL + 0x0008) +#define AR5315_LB1MS_MASK       0x3FFFF         /* # of AHB clk cycles in 1ms */ + +#define AR5315_LB_MISCCFG       (AR5315_LOCAL + 0x000C) +#define AR5315_LBM_TXD_EN       0x00000001      /* Enable TXD for fragments */ +#define AR5315_LBM_RX_INTEN     0x00000002      /* Enable LB ints on RX ready */ +#define AR5315_LBM_MBOXWR_INTEN 0x00000004      /* Enable LB ints on mbox wr */ +#define AR5315_LBM_MBOXRD_INTEN 0x00000008      /* Enable LB ints on mbox rd */ +#define AR5315_LMB_DESCSWAP_EN  0x00000010      /* Byte swap desc enable */ +#define AR5315_LBM_TIMEOUT_MASK 0x00FFFF80 +#define AR5315_LBM_TIMEOUT_SHFT 7 +#define AR5315_LBM_PORTMUX      0x07000000 + + +#define AR5315_LB_RXTSOFF       (AR5315_LOCAL + 0x0010) + +#define AR5315_LB_TX_CHAIN_EN   (AR5315_LOCAL + 0x0100) +#define AR5315_LB_TXEN_0        0x01 +#define AR5315_LB_TXEN_1        0x02 +#define AR5315_LB_TXEN_2        0x04 +#define AR5315_LB_TXEN_3        0x08 + +#define AR5315_LB_TX_CHAIN_DIS  (AR5315_LOCAL + 0x0104) +#define AR5315_LB_TX_DESC_PTR   (AR5315_LOCAL + 0x0200) + +#define AR5315_LB_RX_CHAIN_EN   (AR5315_LOCAL + 0x0400) +#define AR5315_LB_RXEN          0x01 + +#define AR5315_LB_RX_CHAIN_DIS  (AR5315_LOCAL + 0x0404) +#define AR5315_LB_RX_DESC_PTR   (AR5315_LOCAL + 0x0408) + +#define AR5315_LB_INT_STATUS    (AR5315_LOCAL + 0x0500) +#define AR5315_INT_TX_DESC      0x0001 +#define AR5315_INT_TX_OK        0x0002 +#define AR5315_INT_TX_ERR       0x0004 +#define AR5315_INT_TX_EOF       0x0008 +#define AR5315_INT_RX_DESC      0x0010 +#define AR5315_INT_RX_OK        0x0020 +#define AR5315_INT_RX_ERR       0x0040 +#define AR5315_INT_RX_EOF       0x0080 +#define AR5315_INT_TX_TRUNC     0x0100 +#define AR5315_INT_TX_STARVE    0x0200 +#define AR5315_INT_LB_TIMEOUT   0x0400 +#define AR5315_INT_LB_ERR       0x0800 +#define AR5315_INT_MBOX_WR      0x1000 +#define AR5315_INT_MBOX_RD      0x2000 + +/* Bit definitions for INT MASK are the same as INT_STATUS */ +#define AR5315_LB_INT_MASK      (AR5315_LOCAL + 0x0504) + +#define AR5315_LB_INT_EN        (AR5315_LOCAL + 0x0508) +#define AR5315_LB_MBOX          (AR5315_LOCAL + 0x0600) + + + +/* + * IR Interface Registers + */ +#define AR5315_IR_PKTDATA                   (AR5315_IR + 0x0000) + +#define AR5315_IR_PKTLEN                    (AR5315_IR + 0x07fc) /* 0 - 63 */ + +#define AR5315_IR_CONTROL                   (AR5315_IR + 0x0800) +#define AR5315_IRCTL_TX                     0x00000000  /* use as tranmitter */ +#define AR5315_IRCTL_RX                     0x00000001  /* use as receiver   */ +#define AR5315_IRCTL_SAMPLECLK_MASK         0x00003ffe  /* Sample clk divisor mask */ +#define AR5315_IRCTL_SAMPLECLK_SHFT                  1 +#define AR5315_IRCTL_OUTPUTCLK_MASK         0x03ffc000  /* Output clk divisor mask */ +#define AR5315_IRCTL_OUTPUTCLK_SHFT                 14 + +#define AR5315_IR_STATUS                    (AR5315_IR + 0x0804) +#define AR5315_IRSTS_RX                     0x00000001  /* receive in progress */ +#define AR5315_IRSTS_TX                     0x00000002  /* transmit in progress */ + +#define AR5315_IR_CONFIG                    (AR5315_IR + 0x0808) +#define AR5315_IRCFG_INVIN                  0x00000001  /* invert input polarity */ +#define AR5315_IRCFG_INVOUT                 0x00000002  /* invert output polarity */ +#define AR5315_IRCFG_SEQ_START_WIN_SEL      0x00000004  /* 1 => 28, 0 => 7 */ +#define AR5315_IRCFG_SEQ_START_THRESH       0x000000f0  /*  */ +#define AR5315_IRCFG_SEQ_END_UNIT_SEL       0x00000100  /*  */ +#define AR5315_IRCFG_SEQ_END_UNIT_THRESH    0x00007e00  /*  */ +#define AR5315_IRCFG_SEQ_END_WIN_SEL        0x00008000  /*  */ +#define AR5315_IRCFG_SEQ_END_WIN_THRESH     0x001f0000  /*  */ +#define AR5315_IRCFG_NUM_BACKOFF_WORDS      0x01e00000  /*  */ + +/* + * PCI memory constants: Memory area 1 and 2 are the same size - + * (twice the PCI_TLB_PAGE_SIZE). The definition of + * CPU_TO_PCI_MEM_SIZE is coupled with the TLB setup routine + * sysLib.c/sysTlbInit(), in that it assumes that 2 pages of size + * PCI_TLB_PAGE_SIZE are set up in the TLB for each PCI memory space. + */ +  +#define CPU_TO_PCI_MEM_BASE1    0xE0000000 +#define CPU_TO_PCI_MEM_SIZE1    (2*PCI_TLB_PAGE_SIZE) +  + +/* TLB attributes for PCI transactions */ + +#define PCI_MMU_PAGEMASK        0x00003FFF +#define MMU_PAGE_UNCACHED       0x00000010 +#define MMU_PAGE_DIRTY          0x00000004 +#define MMU_PAGE_VALID          0x00000002 +#define MMU_PAGE_GLOBAL         0x00000001 +#define PCI_MMU_PAGEATTRIB      (MMU_PAGE_UNCACHED|MMU_PAGE_DIRTY|\ +                                 MMU_PAGE_VALID|MMU_PAGE_GLOBAL) +#define PCI_MEMORY_SPACE1_VIRT  0xE0000000      /* Used for non-prefet  mem   */ +#define PCI_MEMORY_SPACE1_PHYS  0x80000000 +#define PCI_TLB_PAGE_SIZE       0x01000000 +#define TLB_HI_MASK             0xFFFFE000 +#define TLB_LO_MASK             0x3FFFFFFF +#define PAGEMASK_SHIFT          11 +#define TLB_LO_SHIFT            6 + +#define PCI_MAX_LATENCY         0xFFF           /* Max PCI latency            */ + +#define HOST_PCI_DEV_ID         3 +#define HOST_PCI_MBAR0          0x10000000 +#define HOST_PCI_MBAR1          0x20000000 +#define HOST_PCI_MBAR2          0x30000000 + +#define HOST_PCI_SDRAM_BASEADDR HOST_PCI_MBAR1 +#define PCI_DEVICE_MEM_SPACE    0x800000 + +#endif + diff --git a/target/linux/atheros-2.6/files/arch/mips/atheros/ar531x.h b/target/linux/atheros-2.6/files/arch/mips/atheros/ar531x.h new file mode 100644 index 000000000..208b0101a --- /dev/null +++ b/target/linux/atheros-2.6/files/arch/mips/atheros/ar531x.h @@ -0,0 +1,106 @@ +#ifndef __AR531X_H +#define __AR531X_H + +#include <ar531x_platform.h> +#include "ar5312.h" +#include "ar5315.h" + +#define MIPS_CPU_IRQ_BASE		0x00 +#define AR531X_HIGH_PRIO                0x10 +#define AR531X_MISC_IRQ_BASE		0x20 +#define AR531X_GPIO_IRQ_BASE            0x30 + +/* Software's idea of interrupts handled by "CPU Interrupt Controller" */ +#define AR531X_IRQ_NONE		MIPS_CPU_IRQ_BASE+0 +#define AR531X_IRQ_CPU_CLOCK	MIPS_CPU_IRQ_BASE+7 /* C0_CAUSE: 0x8000 */ + +/* Miscellaneous interrupts, which share IP6 */ +#define AR531X_MISC_IRQ_NONE		AR531X_MISC_IRQ_BASE+0 +#define AR531X_MISC_IRQ_TIMER		AR531X_MISC_IRQ_BASE+1 +#define AR531X_MISC_IRQ_AHB_PROC	AR531X_MISC_IRQ_BASE+2 +#define AR531X_MISC_IRQ_AHB_DMA		AR531X_MISC_IRQ_BASE+3 +#define AR531X_MISC_IRQ_GPIO		AR531X_MISC_IRQ_BASE+4 +#define AR531X_MISC_IRQ_UART0		AR531X_MISC_IRQ_BASE+5 +#define AR531X_MISC_IRQ_UART0_DMA	AR531X_MISC_IRQ_BASE+6 +#define AR531X_MISC_IRQ_WATCHDOG	AR531X_MISC_IRQ_BASE+7 +#define AR531X_MISC_IRQ_LOCAL		AR531X_MISC_IRQ_BASE+8 +#define AR531X_MISC_IRQ_COUNT		9 + +/* GPIO Interrupts [0..7], share AR531X_MISC_IRQ_GPIO */ +#define AR531X_GPIO_IRQ_NONE            AR531X_MISC_IRQ_BASE+0 +#define AR531X_GPIO_IRQ(n)              AR531X_MISC_IRQ_BASE+(n)+1 +#define AR531X_GPIO_IRQ_COUNT           22 + +#define sysRegRead(phys)	\ +	(*(volatile u32 *)KSEG1ADDR(phys)) + +#define sysRegWrite(phys, val)	\ +	((*(volatile u32 *)KSEG1ADDR(phys)) = (val)) + +/* + * This is board-specific data that is stored in a "fixed" location in flash. + * It is shared across operating systems, so it should not be changed lightly. + * The main reason we need it is in order to extract the ethernet MAC + * address(es). + */ +struct ar531x_boarddata { +    u32 magic;                       /* board data is valid */ +#define AR531X_BD_MAGIC 0x35333131   /* "5311", for all 531x platforms */ +    u16 cksum;                       /* checksum (starting with BD_REV 2) */ +    u16 rev;                         /* revision of this struct */ +#define BD_REV  4 +    char   boardName[64];            /* Name of board */ +    u16 major;                       /* Board major number */ +    u16 minor;                       /* Board minor number */ +    u32 config;                      /* Board configuration */ +#define BD_ENET0        0x00000001   /* ENET0 is stuffed */ +#define BD_ENET1        0x00000002   /* ENET1 is stuffed */ +#define BD_UART1        0x00000004   /* UART1 is stuffed */ +#define BD_UART0        0x00000008   /* UART0 is stuffed (dma) */ +#define BD_RSTFACTORY   0x00000010   /* Reset factory defaults stuffed */ +#define BD_SYSLED       0x00000020   /* System LED stuffed */ +#define BD_EXTUARTCLK   0x00000040   /* External UART clock */ +#define BD_CPUFREQ      0x00000080   /* cpu freq is valid in nvram */ +#define BD_SYSFREQ      0x00000100   /* sys freq is set in nvram */ +#define BD_WLAN0        0x00000200   /* Enable WLAN0 */ +#define BD_MEMCAP       0x00000400   /* CAP SDRAM @ memCap for testing */ +#define BD_DISWATCHDOG  0x00000800   /* disable system watchdog */ +#define BD_WLAN1        0x00001000   /* Enable WLAN1 (ar5212) */ +#define BD_ISCASPER     0x00002000   /* FLAG for AR2312 */ +#define BD_WLAN0_2G_EN  0x00004000   /* FLAG for radio0_2G */ +#define BD_WLAN0_5G_EN  0x00008000   /* FLAG for radio0_2G */ +#define BD_WLAN1_2G_EN  0x00020000   /* FLAG for radio0_2G */ +#define BD_WLAN1_5G_EN  0x00040000   /* FLAG for radio0_2G */ +    u16 resetConfigGpio;             /* Reset factory GPIO pin */ +    u16 sysLedGpio;                  /* System LED GPIO pin */ + +    u32 cpuFreq;                     /* CPU core frequency in Hz */ +    u32 sysFreq;                     /* System frequency in Hz */ +    u32 cntFreq;                     /* Calculated C0_COUNT frequency */ + +    u8  wlan0Mac[6]; +    u8  enet0Mac[6]; +    u8  enet1Mac[6]; + +    u16 pciId;                       /* Pseudo PCIID for common code */ +    u16 memCap;                      /* cap bank1 in MB */ + +    /* version 3 */ +    u8  wlan1Mac[6];                 /* (ar5212) */ +}; + + +extern char *board_config; +extern char *radio_config; +extern void serial_setup(unsigned long mapbase, unsigned int uartclk); +extern int ar531x_find_config(char *flash_limit); + +extern void ar5312_misc_intr_init(int irq_base); +extern void ar5312_irq_dispatch(void); +extern void ar5312_plat_setup(void); + +extern void ar5315_misc_intr_init(int irq_base); +extern asmlinkage void ar5315_irq_dispatch(void); +extern void ar5315_plat_setup(void); + +#endif diff --git a/target/linux/atheros-2.6/files/arch/mips/atheros/board.c b/target/linux/atheros-2.6/files/arch/mips/atheros/board.c new file mode 100644 index 000000000..fe94c3ffc --- /dev/null +++ b/target/linux/atheros-2.6/files/arch/mips/atheros/board.c @@ -0,0 +1,190 @@ +/* + * 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) 2003 Atheros Communications, Inc.,  All Rights Reserved. + * Copyright (C) 2006 FON Technology, SL. + * Copyright (C) 2006 Imre Kaloz <kaloz@openwrt.org> + * Copyright (C) 2006 Felix Fietkau <nbd@openwrt.org> + */ + +/* + * Platform devices for Atheros SoCs + */ + +#include <linux/autoconf.h> +#include <linux/init.h> +#include <linux/module.h> +#include <linux/types.h> +#include <linux/string.h> +#include <linux/platform_device.h> +#include <linux/kernel.h> +#include <linux/serial.h> +#include <linux/serial_core.h> +#include <asm/bootinfo.h> +#include <asm/io.h> +#include "ar531x.h" + +char *board_config, *radio_config; + +static u8 *find_board_config(char *flash_limit) +{ +	char *addr; +	int found = 0; + +	for (addr = (char *) (flash_limit - 0x1000); +		addr >= (char *) (flash_limit - 0x30000); +		addr -= 0x1000) { + +		if ( *(int *)addr == 0x35333131) { +			/* config magic found */ +			found = 1; +			break; +		} +	} + +	if (!found) { +		printk("WARNING: No board configuration data found!\n"); +		addr = NULL; +	} +	 +	return addr; +} + +static u8 *find_radio_config(char *flash_limit, char *board_config) +{ +	int dataFound; +	u32 radio_config; +	 +	/*  +	 * Now find the start of Radio Configuration data, using heuristics: +	 * Search forward from Board Configuration data by 0x1000 bytes +	 * at a time until we find non-0xffffffff. +	 */ +	dataFound = 0; +	for (radio_config = (u32) board_config + 0x1000; +	     (radio_config < (u32) flash_limit); +	     radio_config += 0x1000) { +		if (*(int *)radio_config != 0xffffffff) { +			dataFound = 1; +			break; +		} +	} + +#ifdef CONFIG_ATHEROS_AR5315 +	if (!dataFound) { /* AR2316 relocates radio config to new location */ +	    for (radio_config = (u32) board_config + 0xf8; +	     	(radio_config < (u32) flash_limit - 0x1000 + 0xf8); +			 radio_config += 0x1000) { +			if (*(int *)radio_config != 0xffffffff) { +				dataFound = 1; +				break; +			} +	    } +	} +#endif + +	if (!dataFound) { +		printk("Could not find Radio Configuration data\n"); +		radio_config = 0; +	} + +	return (u8 *) radio_config; +} + +int __init ar531x_find_config(char *flash_limit) +{ +	unsigned int rcfg_size; +	char *bcfg, *rcfg; + +	/* Copy the board and radio data to RAM, because with the new +	 * spiflash driver, accessing the mapped memory directly is no +	 * longer safe */ + +	bcfg = find_board_config(flash_limit); +	if (!bcfg) +		return -ENODEV; + +	board_config = kmalloc(0x1000, GFP_KERNEL); +	memcpy(board_config, bcfg, 0x100); + +	/* Radio config starts 0x100 bytes after board config, regardless +	 * of what the physical layout on the flash chip looks like */ + +	rcfg = find_radio_config(flash_limit, bcfg); +	if (!rcfg) +		return -ENODEV; + +	printk("Radio config found at offset 0x%x\n", rcfg - bcfg); +	radio_config = board_config + 0x100 + ((rcfg - bcfg) & 0xfff); +	rcfg_size = 0x1000 - ((rcfg - bcfg) & 0xfff); +	memcpy(radio_config, rcfg, rcfg_size); +	 +	return 0; +} + +void __init serial_setup(unsigned long mapbase, unsigned int uartclk) +{ +	struct uart_port s; +	 +	memset(&s, 0, sizeof(s)); + +	s.flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST; +	s.iotype = UPIO_MEM; +	s.irq = AR531X_MISC_IRQ_UART0; +	s.regshift = 2; +	s.mapbase = mapbase; +	s.uartclk = uartclk; +	s.membase = (void __iomem *)s.mapbase; + +	early_serial_setup(&s); +} + +void __init plat_mem_setup(void) +{ +	switch(mips_machtype) { +#ifdef CONFIG_ATHEROS_AR5312 +	case MACH_ATHEROS_AR5312: +		ar5312_plat_setup(); +		break; +#endif +#ifdef CONFIG_ATHEROS_AR5315 +	case MACH_ATHEROS_AR5315: +		ar5315_plat_setup(); +		break; +#endif +	} + +	/* Disable data watchpoints */ +	write_c0_watchlo0(0); +} + +const char *get_system_type(void) +{ +	switch (mips_machtype) { +#ifdef CONFIG_ATHEROS_AR5312 +	case MACH_ATHEROS_AR5312: +		return "Atheros AR5312\n"; +#endif +#ifdef CONFIG_ATHEROS_AR5315 +	case MACH_ATHEROS_AR5315: +		return "Atheros AR5315\n"; +#endif +	} +	return "Atheros (unknown)"; +} + +void __init plat_timer_setup(struct irqaction *irq) +{ +	unsigned int count; + +	/* Usually irq is timer_irqaction (timer_interrupt) */ +	setup_irq(AR531X_IRQ_CPU_CLOCK, irq); + +	/* to generate the first CPU timer interrupt */ +	count = read_c0_count(); +	write_c0_compare(count + 1000); +} + + diff --git a/target/linux/atheros-2.6/files/arch/mips/atheros/irq.c b/target/linux/atheros-2.6/files/arch/mips/atheros/irq.c new file mode 100644 index 000000000..99d960b41 --- /dev/null +++ b/target/linux/atheros-2.6/files/arch/mips/atheros/irq.c @@ -0,0 +1,98 @@ +/* + * 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) 2003 Atheros Communications, Inc.,  All Rights Reserved. + * Copyright (C) 2006 FON Technology, SL. + * Copyright (C) 2006 Imre Kaloz <kaloz@openwrt.org> + * Copyright (C) 2006 Felix Fietkau <nbd@openwrt.org> + */ + +/* + * Interrupt support for AR531X WiSOC. + */ + +#include <linux/autoconf.h> +#include <linux/init.h> +#include <linux/kernel_stat.h> +#include <linux/signal.h> +#include <linux/sched.h> +#include <linux/interrupt.h> +#include <linux/slab.h> +#include <linux/random.h> +#include <linux/pm.h> +#include <linux/delay.h> +#include <linux/reboot.h> +#include <linux/irq.h> +#include <asm/bootinfo.h> +#include <asm/mipsregs.h> +#include <asm/irq_cpu.h> +#include "ar531x.h" + + +/* ARGSUSED */ +irqreturn_t +spurious_irq_handler(int cpl, void *dev_id) +{ +    /*  +    printk("spurious_irq_handler: %d  cause=0x%8.8x  status=0x%8.8x\n", +	   cpl, cause_intrs, status_intrs);  +    */ +	return IRQ_NONE; +} + +/* ARGSUSED */ +irqreturn_t +spurious_misc_handler(int cpl, void *dev_id) +{ +    /* +    printk("spurious_misc_handler: 0x%x isr=0x%8.8x imr=0x%8.8x\n", +	   cpl, ar531x_isr, ar531x_imr); +    */ +	return IRQ_NONE; +} + +static struct irqaction spurious_irq  = { +	.handler	= spurious_irq_handler, +	.flags		= SA_INTERRUPT, +	.name		= "spurious_irq", +}; + +static struct irqaction spurious_misc  = { +	.handler	= spurious_misc_handler, +	.flags		= SA_INTERRUPT, +	.name		= "spurious_misc", +}; + +asmlinkage void plat_irq_dispatch(void) +{ +#ifdef CONFIG_ATHEROS_AR5312 +	if (mips_machtype == MACH_ATHEROS_AR5312) +		ar5312_irq_dispatch(); +#endif +#ifdef CONFIG_ATHEROS_AR5315 +	if (mips_machtype == MACH_ATHEROS_AR5315) +		ar5315_irq_dispatch(); +#endif +} + +void __init arch_init_irq(void) +{ +	clear_c0_status(ST0_IM); +	mips_cpu_irq_init(0); + +	/* Initialize interrupt controllers */ +#ifdef CONFIG_ATHEROS_AR5312 +	if (mips_machtype == MACH_ATHEROS_AR5312) +		ar5312_misc_intr_init(AR531X_MISC_IRQ_BASE); +#endif +#ifdef CONFIG_ATHEROS_AR5315 +	if (mips_machtype == MACH_ATHEROS_AR5315) +		ar5315_misc_intr_init(AR531X_MISC_IRQ_BASE); +#endif + +	/* Default "spurious interrupt" handlers */ +	setup_irq(AR531X_IRQ_NONE, &spurious_irq); +	setup_irq(AR531X_MISC_IRQ_NONE, &spurious_misc); +} diff --git a/target/linux/atheros-2.6/files/arch/mips/atheros/prom.c b/target/linux/atheros-2.6/files/arch/mips/atheros/prom.c new file mode 100644 index 000000000..6dfa13c77 --- /dev/null +++ b/target/linux/atheros-2.6/files/arch/mips/atheros/prom.c @@ -0,0 +1,67 @@ +/* + * 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 MontaVista Software Inc + * Copyright (C) 2003 Atheros Communications, Inc.,  All Rights Reserved. + * Copyright (C) 2006 FON Technology, SL. + * Copyright (C) 2006 Imre Kaloz <kaloz@openwrt.org> + * Copyright (C) 2006 Felix Fietkau <nbd@openwrt.org> + */ + +/* + * Prom setup file for ar531x + */ + +#include <linux/init.h> +#include <linux/autoconf.h> +#include <linux/kernel.h> +#include <linux/string.h> +#include <linux/mm.h> +#include <linux/bootmem.h> + +#include <asm/bootinfo.h> +#include <asm/addrspace.h> +#include "ar531x.h" + +void __init prom_init(void) +{ +	u32 memsize, memcfg; + +	mips_machgroup = MACH_GROUP_ATHEROS; +	mips_machtype = -1; + +	/*                                                                              +	 * Atheros CPUs before the AR2315 are using MIPS 4Kc core, later designs are +	 * using MIPS 4KEc R2 core. This makes it easy to determine the board at runtime. +	 */ +                                                                             +	if (current_cpu_data.cputype == CPU_4KEC) { +		mips_machtype = MACH_ATHEROS_AR5315; +		 +		memcfg = sysRegRead(AR5315_MEM_CFG); +		memsize   = 1 + ((memcfg & SDRAM_DATA_WIDTH_M) >> SDRAM_DATA_WIDTH_S); +		memsize <<= 1 + ((memcfg & SDRAM_COL_WIDTH_M) >> SDRAM_COL_WIDTH_S); +		memsize <<= 1 + ((memcfg & SDRAM_ROW_WIDTH_M) >> SDRAM_ROW_WIDTH_S); +		memsize <<= 3; +	} else { +		int bank0AC, bank1AC; + +		mips_machtype = MACH_ATHEROS_AR5312; + +		memcfg = sysRegRead(AR531X_MEM_CFG1); +		bank0AC = (memcfg & MEM_CFG1_AC0) >> MEM_CFG1_AC0_S; +		bank1AC = (memcfg & MEM_CFG1_AC1) >> MEM_CFG1_AC1_S; +		memsize = (bank0AC ? (1 << (bank0AC+1)) : 0) +		        + (bank1AC ? (1 << (bank1AC+1)) : 0); +		memsize <<= 20; +	} + +	add_memory_region(0, memsize, BOOT_MEM_RAM); +	strcpy(arcs_cmdline, "console=ttyS0,9600 rootfstype=squashfs,jffs2"); +} + +void __init prom_free_prom_memory(void) +{ +}  | 
