Merge branch 'upstream' of git://git.linux-mips.org/pub/scm/upstream-linus

* 'upstream' of git://git.linux-mips.org/pub/scm/upstream-linus: (48 commits)
  MIPS: Move arch_get_unmapped_area and gang to new file.
  MIPS: Cleanup arch_get_unmapped_area
  MIPS: Octeon: Don't request interrupts for unused IPI mailbox bits.
  Octeon: Fix interrupt irq settings for performance counters.
  MIPS: Fix build warnings on defconfigs
  MIPS: Lemote 2F, Malta: Fix build warning
  MIPS: Set ELF AT_PLATFORM string for Loongson2 processors
  MIPS: Set ELF AT_PLATFORM string for BMIPS processors
  MIPS: Introduce set_elf_platform() helper function
  MIPS: JZ4740: setup: Autodetect physical memory.
  MIPS: BCM47xx: Fix MAC address parsing.
  MIPS: BCM47xx: Extend the filling of SPROM from NVRAM
  MIPS: BCM47xx: Register SSB fallback sprom callback
  MIPS: BCM47xx: Extend bcm47xx_fill_sprom with prefix.
  SSB: Change fallback sprom to callback mechanism.
  MIPS: Alchemy: Clean up GPIO registers and accessors
  MIPS: Alchemy: Cleanup DMA addresses
  MIPS: Alchemy: Rewrite ethernet platform setup
  MIPS: Alchemy: Rewrite UART setup and constants.
  MIPS: Alchemy: Convert dbdma.c to syscore_ops
  ...
This commit is contained in:
Linus Torvalds 2011-05-19 16:40:47 -07:00
commit fce4a1dda2
138 changed files with 9333 additions and 927 deletions

View file

@ -11,6 +11,7 @@ platforms += dec
platforms += emma
platforms += jazz
platforms += jz4740
platforms += lantiq
platforms += lasat
platforms += loongson
platforms += mipssim

View file

@ -212,6 +212,24 @@ config MACH_JZ4740
select HAVE_PWM
select HAVE_CLK
config LANTIQ
bool "Lantiq based platforms"
select DMA_NONCOHERENT
select IRQ_CPU
select CEVT_R4K
select CSRC_R4K
select SYS_HAS_CPU_MIPS32_R1
select SYS_HAS_CPU_MIPS32_R2
select SYS_SUPPORTS_BIG_ENDIAN
select SYS_SUPPORTS_32BIT_KERNEL
select SYS_SUPPORTS_MULTITHREADING
select SYS_HAS_EARLY_PRINTK
select ARCH_REQUIRE_GPIOLIB
select SWAP_IO_SPACE
select BOOT_RAW
select HAVE_CLK
select MIPS_MACHINE
config LASAT
bool "LASAT Networks platforms"
select CEVT_R4K
@ -736,6 +754,33 @@ config CAVIUM_OCTEON_REFERENCE_BOARD
Hikari
Say Y here for most Octeon reference boards.
config NLM_XLR_BOARD
bool "Netlogic XLR/XLS based systems"
depends on EXPERIMENTAL
select BOOT_ELF32
select NLM_COMMON
select NLM_XLR
select SYS_HAS_CPU_XLR
select SYS_SUPPORTS_SMP
select HW_HAS_PCI
select SWAP_IO_SPACE
select SYS_SUPPORTS_32BIT_KERNEL
select SYS_SUPPORTS_64BIT_KERNEL
select 64BIT_PHYS_ADDR
select SYS_SUPPORTS_BIG_ENDIAN
select SYS_SUPPORTS_HIGHMEM
select DMA_COHERENT
select NR_CPUS_DEFAULT_32
select CEVT_R4K
select CSRC_R4K
select IRQ_CPU
select ZONE_DMA if 64BIT
select SYNC_R4K
select SYS_HAS_EARLY_PRINTK
help
Support for systems based on Netlogic XLR and XLS processors.
Say Y here if you have a XLR or XLS based board.
endchoice
source "arch/mips/alchemy/Kconfig"
@ -743,6 +788,7 @@ source "arch/mips/ath79/Kconfig"
source "arch/mips/bcm63xx/Kconfig"
source "arch/mips/jazz/Kconfig"
source "arch/mips/jz4740/Kconfig"
source "arch/mips/lantiq/Kconfig"
source "arch/mips/lasat/Kconfig"
source "arch/mips/pmc-sierra/Kconfig"
source "arch/mips/powertv/Kconfig"
@ -752,6 +798,7 @@ source "arch/mips/txx9/Kconfig"
source "arch/mips/vr41xx/Kconfig"
source "arch/mips/cavium-octeon/Kconfig"
source "arch/mips/loongson/Kconfig"
source "arch/mips/netlogic/Kconfig"
endmenu
@ -1420,6 +1467,17 @@ config CPU_BMIPS5000
help
Broadcom BMIPS5000 processors.
config CPU_XLR
bool "Netlogic XLR SoC"
depends on SYS_HAS_CPU_XLR
select CPU_SUPPORTS_32BIT_KERNEL
select CPU_SUPPORTS_64BIT_KERNEL
select CPU_SUPPORTS_HIGHMEM
select WEAK_ORDERING
select WEAK_REORDERING_BEYOND_LLSC
select CPU_SUPPORTS_HUGEPAGES
help
Netlogic Microsystems XLR/XLS processors.
endchoice
if CPU_LOONGSON2F
@ -1550,6 +1608,9 @@ config SYS_HAS_CPU_BMIPS4380
config SYS_HAS_CPU_BMIPS5000
bool
config SYS_HAS_CPU_XLR
bool
#
# CPU may reorder R->R, R->W, W->R, W->W
# Reordering beyond LL and SC is handled in WEAK_REORDERING_BEYOND_LLSC

View file

@ -191,6 +191,18 @@ endif
#
include $(srctree)/arch/mips/Kbuild.platforms
#
# NETLOGIC SOC Common (common)
#
cflags-$(CONFIG_NLM_COMMON) += -I$(srctree)/arch/mips/include/asm/mach-netlogic
cflags-$(CONFIG_NLM_COMMON) += -I$(srctree)/arch/mips/include/asm/netlogic
#
# NETLOGIC XLR/XLS SoC, Simulator and boards
#
core-$(CONFIG_NLM_XLR) += arch/mips/netlogic/xlr/
load-$(CONFIG_NLM_XLR_BOARD) += 0xffffffff84000000
cflags-y += -I$(srctree)/arch/mips/include/asm/mach-generic
drivers-$(CONFIG_PCI) += arch/mips/pci/

View file

@ -36,7 +36,7 @@
#include <linux/spinlock.h>
#include <linux/interrupt.h>
#include <linux/module.h>
#include <linux/sysdev.h>
#include <linux/syscore_ops.h>
#include <asm/mach-au1x00/au1000.h>
#include <asm/mach-au1x00/au1xxx_dbdma.h>
@ -58,7 +58,8 @@ static DEFINE_SPINLOCK(au1xxx_dbdma_spin_lock);
/* I couldn't find a macro that did this... */
#define ALIGN_ADDR(x, a) ((((u32)(x)) + (a-1)) & ~(a-1))
static dbdma_global_t *dbdma_gptr = (dbdma_global_t *)DDMA_GLOBAL_BASE;
static dbdma_global_t *dbdma_gptr =
(dbdma_global_t *)KSEG1ADDR(AU1550_DBDMA_CONF_PHYS_ADDR);
static int dbdma_initialized;
static dbdev_tab_t dbdev_tab[] = {
@ -299,7 +300,7 @@ u32 au1xxx_dbdma_chan_alloc(u32 srcid, u32 destid,
if (ctp != NULL) {
memset(ctp, 0, sizeof(chan_tab_t));
ctp->chan_index = chan = i;
dcp = DDMA_CHANNEL_BASE;
dcp = KSEG1ADDR(AU1550_DBDMA_PHYS_ADDR);
dcp += (0x0100 * chan);
ctp->chan_ptr = (au1x_dma_chan_t *)dcp;
cp = (au1x_dma_chan_t *)dcp;
@ -958,105 +959,75 @@ u32 au1xxx_dbdma_put_dscr(u32 chanid, au1x_ddma_desc_t *dscr)
}
struct alchemy_dbdma_sysdev {
struct sys_device sysdev;
u32 pm_regs[NUM_DBDMA_CHANS + 1][6];
};
static unsigned long alchemy_dbdma_pm_data[NUM_DBDMA_CHANS + 1][6];
static int alchemy_dbdma_suspend(struct sys_device *dev,
pm_message_t state)
static int alchemy_dbdma_suspend(void)
{
struct alchemy_dbdma_sysdev *sdev =
container_of(dev, struct alchemy_dbdma_sysdev, sysdev);
int i;
u32 addr;
void __iomem *addr;
addr = DDMA_GLOBAL_BASE;
sdev->pm_regs[0][0] = au_readl(addr + 0x00);
sdev->pm_regs[0][1] = au_readl(addr + 0x04);
sdev->pm_regs[0][2] = au_readl(addr + 0x08);
sdev->pm_regs[0][3] = au_readl(addr + 0x0c);
addr = (void __iomem *)KSEG1ADDR(AU1550_DBDMA_CONF_PHYS_ADDR);
alchemy_dbdma_pm_data[0][0] = __raw_readl(addr + 0x00);
alchemy_dbdma_pm_data[0][1] = __raw_readl(addr + 0x04);
alchemy_dbdma_pm_data[0][2] = __raw_readl(addr + 0x08);
alchemy_dbdma_pm_data[0][3] = __raw_readl(addr + 0x0c);
/* save channel configurations */
for (i = 1, addr = DDMA_CHANNEL_BASE; i <= NUM_DBDMA_CHANS; i++) {
sdev->pm_regs[i][0] = au_readl(addr + 0x00);
sdev->pm_regs[i][1] = au_readl(addr + 0x04);
sdev->pm_regs[i][2] = au_readl(addr + 0x08);
sdev->pm_regs[i][3] = au_readl(addr + 0x0c);
sdev->pm_regs[i][4] = au_readl(addr + 0x10);
sdev->pm_regs[i][5] = au_readl(addr + 0x14);
addr = (void __iomem *)KSEG1ADDR(AU1550_DBDMA_PHYS_ADDR);
for (i = 1; i <= NUM_DBDMA_CHANS; i++) {
alchemy_dbdma_pm_data[i][0] = __raw_readl(addr + 0x00);
alchemy_dbdma_pm_data[i][1] = __raw_readl(addr + 0x04);
alchemy_dbdma_pm_data[i][2] = __raw_readl(addr + 0x08);
alchemy_dbdma_pm_data[i][3] = __raw_readl(addr + 0x0c);
alchemy_dbdma_pm_data[i][4] = __raw_readl(addr + 0x10);
alchemy_dbdma_pm_data[i][5] = __raw_readl(addr + 0x14);
/* halt channel */
au_writel(sdev->pm_regs[i][0] & ~1, addr + 0x00);
au_sync();
while (!(au_readl(addr + 0x14) & 1))
au_sync();
__raw_writel(alchemy_dbdma_pm_data[i][0] & ~1, addr + 0x00);
wmb();
while (!(__raw_readl(addr + 0x14) & 1))
wmb();
addr += 0x100; /* next channel base */
}
/* disable channel interrupts */
au_writel(0, DDMA_GLOBAL_BASE + 0x0c);
au_sync();
addr = (void __iomem *)KSEG1ADDR(AU1550_DBDMA_CONF_PHYS_ADDR);
__raw_writel(0, addr + 0x0c);
wmb();
return 0;
}
static int alchemy_dbdma_resume(struct sys_device *dev)
static void alchemy_dbdma_resume(void)
{
struct alchemy_dbdma_sysdev *sdev =
container_of(dev, struct alchemy_dbdma_sysdev, sysdev);
int i;
u32 addr;
void __iomem *addr;
addr = DDMA_GLOBAL_BASE;
au_writel(sdev->pm_regs[0][0], addr + 0x00);
au_writel(sdev->pm_regs[0][1], addr + 0x04);
au_writel(sdev->pm_regs[0][2], addr + 0x08);
au_writel(sdev->pm_regs[0][3], addr + 0x0c);
addr = (void __iomem *)KSEG1ADDR(AU1550_DBDMA_CONF_PHYS_ADDR);
__raw_writel(alchemy_dbdma_pm_data[0][0], addr + 0x00);
__raw_writel(alchemy_dbdma_pm_data[0][1], addr + 0x04);
__raw_writel(alchemy_dbdma_pm_data[0][2], addr + 0x08);
__raw_writel(alchemy_dbdma_pm_data[0][3], addr + 0x0c);
/* restore channel configurations */
for (i = 1, addr = DDMA_CHANNEL_BASE; i <= NUM_DBDMA_CHANS; i++) {
au_writel(sdev->pm_regs[i][0], addr + 0x00);
au_writel(sdev->pm_regs[i][1], addr + 0x04);
au_writel(sdev->pm_regs[i][2], addr + 0x08);
au_writel(sdev->pm_regs[i][3], addr + 0x0c);
au_writel(sdev->pm_regs[i][4], addr + 0x10);
au_writel(sdev->pm_regs[i][5], addr + 0x14);
au_sync();
addr = (void __iomem *)KSEG1ADDR(AU1550_DBDMA_PHYS_ADDR);
for (i = 1; i <= NUM_DBDMA_CHANS; i++) {
__raw_writel(alchemy_dbdma_pm_data[i][0], addr + 0x00);
__raw_writel(alchemy_dbdma_pm_data[i][1], addr + 0x04);
__raw_writel(alchemy_dbdma_pm_data[i][2], addr + 0x08);
__raw_writel(alchemy_dbdma_pm_data[i][3], addr + 0x0c);
__raw_writel(alchemy_dbdma_pm_data[i][4], addr + 0x10);
__raw_writel(alchemy_dbdma_pm_data[i][5], addr + 0x14);
wmb();
addr += 0x100; /* next channel base */
}
return 0;
}
static struct sysdev_class alchemy_dbdma_sysdev_class = {
.name = "dbdma",
static struct syscore_ops alchemy_dbdma_syscore_ops = {
.suspend = alchemy_dbdma_suspend,
.resume = alchemy_dbdma_resume,
};
static int __init alchemy_dbdma_sysdev_init(void)
{
struct alchemy_dbdma_sysdev *sdev;
int ret;
ret = sysdev_class_register(&alchemy_dbdma_sysdev_class);
if (ret)
return ret;
sdev = kzalloc(sizeof(struct alchemy_dbdma_sysdev), GFP_KERNEL);
if (!sdev)
return -ENOMEM;
sdev->sysdev.id = -1;
sdev->sysdev.cls = &alchemy_dbdma_sysdev_class;
ret = sysdev_register(&sdev->sysdev);
if (ret)
kfree(sdev);
return ret;
}
static int __init au1xxx_dbdma_init(void)
{
int irq_nr, ret;
@ -1084,11 +1055,7 @@ static int __init au1xxx_dbdma_init(void)
else {
dbdma_initialized = 1;
printk(KERN_INFO "Alchemy DBDMA initialized\n");
ret = alchemy_dbdma_sysdev_init();
if (ret) {
printk(KERN_ERR "DBDMA PM init failed\n");
ret = 0;
}
register_syscore_ops(&alchemy_dbdma_syscore_ops);
}
return ret;

View file

@ -58,6 +58,9 @@
* returned from request_dma.
*/
/* DMA Channel register block spacing */
#define DMA_CHANNEL_LEN 0x00000100
DEFINE_SPINLOCK(au1000_dma_spin_lock);
struct dma_chan au1000_dma_table[NUM_AU1000_DMA_CHANNELS] = {
@ -77,22 +80,23 @@ static const struct dma_dev {
unsigned int fifo_addr;
unsigned int dma_mode;
} dma_dev_table[DMA_NUM_DEV] = {
{UART0_ADDR + UART_TX, 0},
{UART0_ADDR + UART_RX, 0},
{0, 0},
{0, 0},
{AC97C_DATA, DMA_DW16 }, /* coherent */
{AC97C_DATA, DMA_DR | DMA_DW16 }, /* coherent */
{UART3_ADDR + UART_TX, DMA_DW8 | DMA_NC},
{UART3_ADDR + UART_RX, DMA_DR | DMA_DW8 | DMA_NC},
{USBD_EP0RD, DMA_DR | DMA_DW8 | DMA_NC},
{USBD_EP0WR, DMA_DW8 | DMA_NC},
{USBD_EP2WR, DMA_DW8 | DMA_NC},
{USBD_EP3WR, DMA_DW8 | DMA_NC},
{USBD_EP4RD, DMA_DR | DMA_DW8 | DMA_NC},
{USBD_EP5RD, DMA_DR | DMA_DW8 | DMA_NC},
{I2S_DATA, DMA_DW32 | DMA_NC},
{I2S_DATA, DMA_DR | DMA_DW32 | DMA_NC}
{ AU1000_UART0_PHYS_ADDR + 0x04, DMA_DW8 }, /* UART0_TX */
{ AU1000_UART0_PHYS_ADDR + 0x00, DMA_DW8 | DMA_DR }, /* UART0_RX */
{ 0, 0 }, /* DMA_REQ0 */
{ 0, 0 }, /* DMA_REQ1 */
{ AU1000_AC97_PHYS_ADDR + 0x08, DMA_DW16 }, /* AC97 TX c */
{ AU1000_AC97_PHYS_ADDR + 0x08, DMA_DW16 | DMA_DR }, /* AC97 RX c */
{ AU1000_UART3_PHYS_ADDR + 0x04, DMA_DW8 | DMA_NC }, /* UART3_TX */
{ AU1000_UART3_PHYS_ADDR + 0x00, DMA_DW8 | DMA_NC | DMA_DR }, /* UART3_RX */
{ AU1000_USBD_PHYS_ADDR + 0x00, DMA_DW8 | DMA_NC | DMA_DR }, /* EP0RD */
{ AU1000_USBD_PHYS_ADDR + 0x04, DMA_DW8 | DMA_NC }, /* EP0WR */
{ AU1000_USBD_PHYS_ADDR + 0x08, DMA_DW8 | DMA_NC }, /* EP2WR */
{ AU1000_USBD_PHYS_ADDR + 0x0c, DMA_DW8 | DMA_NC }, /* EP3WR */
{ AU1000_USBD_PHYS_ADDR + 0x10, DMA_DW8 | DMA_NC | DMA_DR }, /* EP4RD */
{ AU1000_USBD_PHYS_ADDR + 0x14, DMA_DW8 | DMA_NC | DMA_DR }, /* EP5RD */
/* on Au1500, these 2 are DMA_REQ2/3 (GPIO208/209) instead! */
{ AU1000_I2S_PHYS_ADDR + 0x00, DMA_DW32 | DMA_NC}, /* I2S TX */
{ AU1000_I2S_PHYS_ADDR + 0x00, DMA_DW32 | DMA_NC | DMA_DR}, /* I2S RX */
};
int au1000_dma_read_proc(char *buf, char **start, off_t fpos,
@ -123,10 +127,10 @@ int au1000_dma_read_proc(char *buf, char **start, off_t fpos,
/* Device FIFO addresses and default DMA modes - 2nd bank */
static const struct dma_dev dma_dev_table_bank2[DMA_NUM_DEV_BANK2] = {
{ SD0_XMIT_FIFO, DMA_DS | DMA_DW8 }, /* coherent */
{ SD0_RECV_FIFO, DMA_DS | DMA_DR | DMA_DW8 }, /* coherent */
{ SD1_XMIT_FIFO, DMA_DS | DMA_DW8 }, /* coherent */
{ SD1_RECV_FIFO, DMA_DS | DMA_DR | DMA_DW8 } /* coherent */
{ AU1100_SD0_PHYS_ADDR + 0x00, DMA_DS | DMA_DW8 }, /* coherent */
{ AU1100_SD0_PHYS_ADDR + 0x04, DMA_DS | DMA_DW8 | DMA_DR }, /* coherent */
{ AU1100_SD1_PHYS_ADDR + 0x00, DMA_DS | DMA_DW8 }, /* coherent */
{ AU1100_SD1_PHYS_ADDR + 0x04, DMA_DS | DMA_DW8 | DMA_DR } /* coherent */
};
void dump_au1000_dma_channel(unsigned int dmanr)
@ -202,7 +206,7 @@ int request_au1000_dma(int dev_id, const char *dev_str,
}
/* fill it in */
chan->io = DMA_CHANNEL_BASE + i * DMA_CHANNEL_LEN;
chan->io = KSEG1ADDR(AU1000_DMA_PHYS_ADDR) + i * DMA_CHANNEL_LEN;
chan->dev_id = dev_id;
chan->dev_str = dev_str;
chan->fifo_addr = dev->fifo_addr;

View file

@ -30,7 +30,7 @@
#include <linux/interrupt.h>
#include <linux/irq.h>
#include <linux/slab.h>
#include <linux/sysdev.h>
#include <linux/syscore_ops.h>
#include <asm/irq_cpu.h>
#include <asm/mipsregs.h>
@ -39,6 +39,36 @@
#include <asm/mach-pb1x00/pb1000.h>
#endif
/* Interrupt Controller register offsets */
#define IC_CFG0RD 0x40
#define IC_CFG0SET 0x40
#define IC_CFG0CLR 0x44
#define IC_CFG1RD 0x48
#define IC_CFG1SET 0x48
#define IC_CFG1CLR 0x4C
#define IC_CFG2RD 0x50
#define IC_CFG2SET 0x50
#define IC_CFG2CLR 0x54
#define IC_REQ0INT 0x54
#define IC_SRCRD 0x58
#define IC_SRCSET 0x58
#define IC_SRCCLR 0x5C
#define IC_REQ1INT 0x5C
#define IC_ASSIGNRD 0x60
#define IC_ASSIGNSET 0x60
#define IC_ASSIGNCLR 0x64
#define IC_WAKERD 0x68
#define IC_WAKESET 0x68
#define IC_WAKECLR 0x6C
#define IC_MASKRD 0x70
#define IC_MASKSET 0x70
#define IC_MASKCLR 0x74
#define IC_RISINGRD 0x78
#define IC_RISINGCLR 0x78
#define IC_FALLINGRD 0x7C
#define IC_FALLINGCLR 0x7C
#define IC_TESTBIT 0x80
static int au1x_ic_settype(struct irq_data *d, unsigned int flow_type);
/* NOTE on interrupt priorities: The original writers of this code said:
@ -221,89 +251,101 @@ struct au1xxx_irqmap au1200_irqmap[] __initdata = {
static void au1x_ic0_unmask(struct irq_data *d)
{
unsigned int bit = d->irq - AU1000_INTC0_INT_BASE;
au_writel(1 << bit, IC0_MASKSET);
au_writel(1 << bit, IC0_WAKESET);
au_sync();
void __iomem *base = (void __iomem *)KSEG1ADDR(AU1000_IC0_PHYS_ADDR);
__raw_writel(1 << bit, base + IC_MASKSET);
__raw_writel(1 << bit, base + IC_WAKESET);
wmb();
}
static void au1x_ic1_unmask(struct irq_data *d)
{
unsigned int bit = d->irq - AU1000_INTC1_INT_BASE;
au_writel(1 << bit, IC1_MASKSET);
au_writel(1 << bit, IC1_WAKESET);
void __iomem *base = (void __iomem *)KSEG1ADDR(AU1000_IC1_PHYS_ADDR);
__raw_writel(1 << bit, base + IC_MASKSET);
__raw_writel(1 << bit, base + IC_WAKESET);
/* very hacky. does the pb1000 cpld auto-disable this int?
* nowhere in the current kernel sources is it disabled. --mlau
*/
#if defined(CONFIG_MIPS_PB1000)
if (d->irq == AU1000_GPIO15_INT)
au_writel(0x4000, PB1000_MDR); /* enable int */
__raw_writel(0x4000, (void __iomem *)PB1000_MDR); /* enable int */
#endif
au_sync();
wmb();
}
static void au1x_ic0_mask(struct irq_data *d)
{
unsigned int bit = d->irq - AU1000_INTC0_INT_BASE;
au_writel(1 << bit, IC0_MASKCLR);
au_writel(1 << bit, IC0_WAKECLR);
au_sync();
void __iomem *base = (void __iomem *)KSEG1ADDR(AU1000_IC0_PHYS_ADDR);
__raw_writel(1 << bit, base + IC_MASKCLR);
__raw_writel(1 << bit, base + IC_WAKECLR);
wmb();
}
static void au1x_ic1_mask(struct irq_data *d)
{
unsigned int bit = d->irq - AU1000_INTC1_INT_BASE;
au_writel(1 << bit, IC1_MASKCLR);
au_writel(1 << bit, IC1_WAKECLR);
au_sync();
void __iomem *base = (void __iomem *)KSEG1ADDR(AU1000_IC1_PHYS_ADDR);
__raw_writel(1 << bit, base + IC_MASKCLR);
__raw_writel(1 << bit, base + IC_WAKECLR);
wmb();
}
static void au1x_ic0_ack(struct irq_data *d)
{
unsigned int bit = d->irq - AU1000_INTC0_INT_BASE;
void __iomem *base = (void __iomem *)KSEG1ADDR(AU1000_IC0_PHYS_ADDR);
/*
* This may assume that we don't get interrupts from
* both edges at once, or if we do, that we don't care.
*/
au_writel(1 << bit, IC0_FALLINGCLR);
au_writel(1 << bit, IC0_RISINGCLR);
au_sync();
__raw_writel(1 << bit, base + IC_FALLINGCLR);
__raw_writel(1 << bit, base + IC_RISINGCLR);
wmb();
}
static void au1x_ic1_ack(struct irq_data *d)
{
unsigned int bit = d->irq - AU1000_INTC1_INT_BASE;
void __iomem *base = (void __iomem *)KSEG1ADDR(AU1000_IC1_PHYS_ADDR);
/*
* This may assume that we don't get interrupts from
* both edges at once, or if we do, that we don't care.
*/
au_writel(1 << bit, IC1_FALLINGCLR);
au_writel(1 << bit, IC1_RISINGCLR);
au_sync();
__raw_writel(1 << bit, base + IC_FALLINGCLR);
__raw_writel(1 << bit, base + IC_RISINGCLR);
wmb();
}
static void au1x_ic0_maskack(struct irq_data *d)
{
unsigned int bit = d->irq - AU1000_INTC0_INT_BASE;
void __iomem *base = (void __iomem *)KSEG1ADDR(AU1000_IC0_PHYS_ADDR);
au_writel(1 << bit, IC0_WAKECLR);
au_writel(1 << bit, IC0_MASKCLR);
au_writel(1 << bit, IC0_RISINGCLR);
au_writel(1 << bit, IC0_FALLINGCLR);
au_sync();
__raw_writel(1 << bit, base + IC_WAKECLR);
__raw_writel(1 << bit, base + IC_MASKCLR);
__raw_writel(1 << bit, base + IC_RISINGCLR);
__raw_writel(1 << bit, base + IC_FALLINGCLR);
wmb();
}
static void au1x_ic1_maskack(struct irq_data *d)
{
unsigned int bit = d->irq - AU1000_INTC1_INT_BASE;
void __iomem *base = (void __iomem *)KSEG1ADDR(AU1000_IC1_PHYS_ADDR);
au_writel(1 << bit, IC1_WAKECLR);
au_writel(1 << bit, IC1_MASKCLR);
au_writel(1 << bit, IC1_RISINGCLR);
au_writel(1 << bit, IC1_FALLINGCLR);
au_sync();
__raw_writel(1 << bit, base + IC_WAKECLR);
__raw_writel(1 << bit, base + IC_MASKCLR);
__raw_writel(1 << bit, base + IC_RISINGCLR);
__raw_writel(1 << bit, base + IC_FALLINGCLR);
wmb();
}
static int au1x_ic1_setwake(struct irq_data *d, unsigned int on)
@ -318,13 +360,13 @@ static int au1x_ic1_setwake(struct irq_data *d, unsigned int on)
return -EINVAL;
local_irq_save(flags);
wakemsk = au_readl(SYS_WAKEMSK);
wakemsk = __raw_readl((void __iomem *)SYS_WAKEMSK);
if (on)
wakemsk |= 1 << bit;
else
wakemsk &= ~(1 << bit);
au_writel(wakemsk, SYS_WAKEMSK);
au_sync();
__raw_writel(wakemsk, (void __iomem *)SYS_WAKEMSK);
wmb();
local_irq_restore(flags);
return 0;
@ -356,81 +398,74 @@ static struct irq_chip au1x_ic1_chip = {
static int au1x_ic_settype(struct irq_data *d, unsigned int flow_type)
{
struct irq_chip *chip;
unsigned long icr[6];
unsigned int bit, ic, irq = d->irq;
unsigned int bit, irq = d->irq;
irq_flow_handler_t handler = NULL;
unsigned char *name = NULL;
void __iomem *base;
int ret;
if (irq >= AU1000_INTC1_INT_BASE) {
bit = irq - AU1000_INTC1_INT_BASE;
chip = &au1x_ic1_chip;
ic = 1;
base = (void __iomem *)KSEG1ADDR(AU1000_IC1_PHYS_ADDR);
} else {
bit = irq - AU1000_INTC0_INT_BASE;
chip = &au1x_ic0_chip;
ic = 0;
base = (void __iomem *)KSEG1ADDR(AU1000_IC0_PHYS_ADDR);
}
if (bit > 31)
return -EINVAL;
icr[0] = ic ? IC1_CFG0SET : IC0_CFG0SET;
icr[1] = ic ? IC1_CFG1SET : IC0_CFG1SET;
icr[2] = ic ? IC1_CFG2SET : IC0_CFG2SET;
icr[3] = ic ? IC1_CFG0CLR : IC0_CFG0CLR;
icr[4] = ic ? IC1_CFG1CLR : IC0_CFG1CLR;
icr[5] = ic ? IC1_CFG2CLR : IC0_CFG2CLR;
ret = 0;
switch (flow_type) { /* cfgregs 2:1:0 */
case IRQ_TYPE_EDGE_RISING: /* 0:0:1 */
au_writel(1 << bit, icr[5]);
au_writel(1 << bit, icr[4]);
au_writel(1 << bit, icr[0]);
__raw_writel(1 << bit, base + IC_CFG2CLR);
__raw_writel(1 << bit, base + IC_CFG1CLR);
__raw_writel(1 << bit, base + IC_CFG0SET);
handler = handle_edge_irq;
name = "riseedge";
break;
case IRQ_TYPE_EDGE_FALLING: /* 0:1:0 */
au_writel(1 << bit, icr[5]);
au_writel(1 << bit, icr[1]);
au_writel(1 << bit, icr[3]);
__raw_writel(1 << bit, base + IC_CFG2CLR);
__raw_writel(1 << bit, base + IC_CFG1SET);
__raw_writel(1 << bit, base + IC_CFG0CLR);
handler = handle_edge_irq;
name = "falledge";
break;
case IRQ_TYPE_EDGE_BOTH: /* 0:1:1 */
au_writel(1 << bit, icr[5]);
au_writel(1 << bit, icr[1]);
au_writel(1 << bit, icr[0]);
__raw_writel(1 << bit, base + IC_CFG2CLR);
__raw_writel(1 << bit, base + IC_CFG1SET);
__raw_writel(1 << bit, base + IC_CFG0SET);
handler = handle_edge_irq;
name = "bothedge";
break;
case IRQ_TYPE_LEVEL_HIGH: /* 1:0:1 */
au_writel(1 << bit, icr[2]);
au_writel(1 << bit, icr[4]);
au_writel(1 << bit, icr[0]);
__raw_writel(1 << bit, base + IC_CFG2SET);
__raw_writel(1 << bit, base + IC_CFG1CLR);
__raw_writel(1 << bit, base + IC_CFG0SET);
handler = handle_level_irq;
name = "hilevel";
break;
case IRQ_TYPE_LEVEL_LOW: /* 1:1:0 */
au_writel(1 << bit, icr[2]);
au_writel(1 << bit, icr[1]);
au_writel(1 << bit, icr[3]);
__raw_writel(1 << bit, base + IC_CFG2SET);
__raw_writel(1 << bit, base + IC_CFG1SET);
__raw_writel(1 << bit, base + IC_CFG0CLR);
handler = handle_level_irq;
name = "lowlevel";
break;
case IRQ_TYPE_NONE: /* 0:0:0 */
au_writel(1 << bit, icr[5]);
au_writel(1 << bit, icr[4]);
au_writel(1 << bit, icr[3]);
__raw_writel(1 << bit, base + IC_CFG2CLR);
__raw_writel(1 << bit, base + IC_CFG1CLR);
__raw_writel(1 << bit, base + IC_CFG0CLR);
break;
default:
ret = -EINVAL;
}
__irq_set_chip_handler_name_locked(d->irq, chip, handler, name);
au_sync();
wmb();
return ret;
}
@ -444,21 +479,21 @@ asmlinkage void plat_irq_dispatch(void)
off = MIPS_CPU_IRQ_BASE + 7;
goto handle;
} else if (pending & CAUSEF_IP2) {
s = IC0_REQ0INT;
s = KSEG1ADDR(AU1000_IC0_PHYS_ADDR) + IC_REQ0INT;
off = AU1000_INTC0_INT_BASE;
} else if (pending & CAUSEF_IP3) {
s = IC0_REQ1INT;
s = KSEG1ADDR(AU1000_IC0_PHYS_ADDR) + IC_REQ1INT;
off = AU1000_INTC0_INT_BASE;
} else if (pending & CAUSEF_IP4) {
s = IC1_REQ0INT;
s = KSEG1ADDR(AU1000_IC1_PHYS_ADDR) + IC_REQ0INT;
off = AU1000_INTC1_INT_BASE;
} else if (pending & CAUSEF_IP5) {
s = IC1_REQ1INT;
s = KSEG1ADDR(AU1000_IC1_PHYS_ADDR) + IC_REQ1INT;
off = AU1000_INTC1_INT_BASE;
} else
goto spurious;
s = au_readl(s);
s = __raw_readl((void __iomem *)s);
if (unlikely(!s)) {
spurious:
spurious_interrupt();
@ -469,48 +504,42 @@ asmlinkage void plat_irq_dispatch(void)
do_IRQ(off);
}
static inline void ic_init(void __iomem *base)
{
/* initialize interrupt controller to a safe state */
__raw_writel(0xffffffff, base + IC_CFG0CLR);
__raw_writel(0xffffffff, base + IC_CFG1CLR);
__raw_writel(0xffffffff, base + IC_CFG2CLR);
__raw_writel(0xffffffff, base + IC_MASKCLR);
__raw_writel(0xffffffff, base + IC_ASSIGNCLR);
__raw_writel(0xffffffff, base + IC_WAKECLR);
__raw_writel(0xffffffff, base + IC_SRCSET);
__raw_writel(0xffffffff, base + IC_FALLINGCLR);
__raw_writel(0xffffffff, base + IC_RISINGCLR);
__raw_writel(0x00000000, base + IC_TESTBIT);
wmb();
}
static void __init au1000_init_irq(struct au1xxx_irqmap *map)
{
unsigned int bit, irq_nr;
int i;
/*
* Initialize interrupt controllers to a safe state.
*/
au_writel(0xffffffff, IC0_CFG0CLR);
au_writel(0xffffffff, IC0_CFG1CLR);
au_writel(0xffffffff, IC0_CFG2CLR);
au_writel(0xffffffff, IC0_MASKCLR);
au_writel(0xffffffff, IC0_ASSIGNCLR);
au_writel(0xffffffff, IC0_WAKECLR);
au_writel(0xffffffff, IC0_SRCSET);
au_writel(0xffffffff, IC0_FALLINGCLR);
au_writel(0xffffffff, IC0_RISINGCLR);
au_writel(0x00000000, IC0_TESTBIT);
au_writel(0xffffffff, IC1_CFG0CLR);
au_writel(0xffffffff, IC1_CFG1CLR);
au_writel(0xffffffff, IC1_CFG2CLR);
au_writel(0xffffffff, IC1_MASKCLR);
au_writel(0xffffffff, IC1_ASSIGNCLR);
au_writel(0xffffffff, IC1_WAKECLR);
au_writel(0xffffffff, IC1_SRCSET);
au_writel(0xffffffff, IC1_FALLINGCLR);
au_writel(0xffffffff, IC1_RISINGCLR);
au_writel(0x00000000, IC1_TESTBIT);
void __iomem *base;
ic_init((void __iomem *)KSEG1ADDR(AU1000_IC0_PHYS_ADDR));
ic_init((void __iomem *)KSEG1ADDR(AU1000_IC1_PHYS_ADDR));
mips_cpu_irq_init();
/* register all 64 possible IC0+IC1 irq sources as type "none".
* Use set_irq_type() to set edge/level behaviour at runtime.
*/
for (i = AU1000_INTC0_INT_BASE;
(i < AU1000_INTC0_INT_BASE + 32); i++)
au1x_ic_settype(irq_get_irq_data(i), IRQ_TYPE_NONE);
for (irq_nr = AU1000_INTC0_INT_BASE;
(irq_nr < AU1000_INTC0_INT_BASE + 32); irq_nr++)
au1x_ic_settype(irq_get_irq_data(irq_nr), IRQ_TYPE_NONE);
for (i = AU1000_INTC1_INT_BASE;
(i < AU1000_INTC1_INT_BASE + 32); i++)
au1x_ic_settype(irq_get_irq_data(i), IRQ_TYPE_NONE);
for (irq_nr = AU1000_INTC1_INT_BASE;
(irq_nr < AU1000_INTC1_INT_BASE + 32); irq_nr++)
au1x_ic_settype(irq_get_irq_data(irq_nr), IRQ_TYPE_NONE);
/*
* Initialize IC0, which is fixed per processor.
@ -520,13 +549,13 @@ static void __init au1000_init_irq(struct au1xxx_irqmap *map)
if (irq_nr >= AU1000_INTC1_INT_BASE) {
bit = irq_nr - AU1000_INTC1_INT_BASE;
if (map->im_request)
au_writel(1 << bit, IC1_ASSIGNSET);
base = (void __iomem *)KSEG1ADDR(AU1000_IC1_PHYS_ADDR);
} else {
bit = irq_nr - AU1000_INTC0_INT_BASE;
if (map->im_request)
au_writel(1 << bit, IC0_ASSIGNSET);
base = (void __iomem *)KSEG1ADDR(AU1000_IC0_PHYS_ADDR);
}
if (map->im_request)
__raw_writel(1 << bit, base + IC_ASSIGNSET);
au1x_ic_settype(irq_get_irq_data(irq_nr), map->im_type);
++map;
@ -556,90 +585,62 @@ void __init arch_init_irq(void)
}
}
struct alchemy_ic_sysdev {
struct sys_device sysdev;
void __iomem *base;
unsigned long pmdata[7];
};
static int alchemy_ic_suspend(struct sys_device *dev, pm_message_t state)
static unsigned long alchemy_ic_pmdata[7 * 2];
static inline void alchemy_ic_suspend_one(void __iomem *base, unsigned long *d)
{
struct alchemy_ic_sysdev *icdev =
container_of(dev, struct alchemy_ic_sysdev, sysdev);
d[0] = __raw_readl(base + IC_CFG0RD);
d[1] = __raw_readl(base + IC_CFG1RD);
d[2] = __raw_readl(base + IC_CFG2RD);
d[3] = __raw_readl(base + IC_SRCRD);
d[4] = __raw_readl(base + IC_ASSIGNRD);
d[5] = __raw_readl(base + IC_WAKERD);
d[6] = __raw_readl(base + IC_MASKRD);
ic_init(base); /* shut it up too while at it */
}
icdev->pmdata[0] = __raw_readl(icdev->base + IC_CFG0RD);
icdev->pmdata[1] = __raw_readl(icdev->base + IC_CFG1RD);
icdev->pmdata[2] = __raw_readl(icdev->base + IC_CFG2RD);
icdev->pmdata[3] = __raw_readl(icdev->base + IC_SRCRD);
icdev->pmdata[4] = __raw_readl(icdev->base + IC_ASSIGNRD);
icdev->pmdata[5] = __raw_readl(icdev->base + IC_WAKERD);
icdev->pmdata[6] = __raw_readl(icdev->base + IC_MASKRD);
static inline void alchemy_ic_resume_one(void __iomem *base, unsigned long *d)
{
ic_init(base);
__raw_writel(d[0], base + IC_CFG0SET);
__raw_writel(d[1], base + IC_CFG1SET);
__raw_writel(d[2], base + IC_CFG2SET);
__raw_writel(d[3], base + IC_SRCSET);
__raw_writel(d[4], base + IC_ASSIGNSET);
__raw_writel(d[5], base + IC_WAKESET);
wmb();
__raw_writel(d[6], base + IC_MASKSET);
wmb();
}
static int alchemy_ic_suspend(void)
{
alchemy_ic_suspend_one((void __iomem *)KSEG1ADDR(AU1000_IC0_PHYS_ADDR),
alchemy_ic_pmdata);
alchemy_ic_suspend_one((void __iomem *)KSEG1ADDR(AU1000_IC1_PHYS_ADDR),
&alchemy_ic_pmdata[7]);
return 0;
}
static int alchemy_ic_resume(struct sys_device *dev)
static void alchemy_ic_resume(void)
{
struct alchemy_ic_sysdev *icdev =
container_of(dev, struct alchemy_ic_sysdev, sysdev);
__raw_writel(0xffffffff, icdev->base + IC_MASKCLR);
__raw_writel(0xffffffff, icdev->base + IC_CFG0CLR);
__raw_writel(0xffffffff, icdev->base + IC_CFG1CLR);
__raw_writel(0xffffffff, icdev->base + IC_CFG2CLR);
__raw_writel(0xffffffff, icdev->base + IC_SRCCLR);
__raw_writel(0xffffffff, icdev->base + IC_ASSIGNCLR);
__raw_writel(0xffffffff, icdev->base + IC_WAKECLR);
__raw_writel(0xffffffff, icdev->base + IC_RISINGCLR);
__raw_writel(0xffffffff, icdev->base + IC_FALLINGCLR);
__raw_writel(0x00000000, icdev->base + IC_TESTBIT);
wmb();
__raw_writel(icdev->pmdata[0], icdev->base + IC_CFG0SET);
__raw_writel(icdev->pmdata[1], icdev->base + IC_CFG1SET);
__raw_writel(icdev->pmdata[2], icdev->base + IC_CFG2SET);
__raw_writel(icdev->pmdata[3], icdev->base + IC_SRCSET);
__raw_writel(icdev->pmdata[4], icdev->base + IC_ASSIGNSET);
__raw_writel(icdev->pmdata[5], icdev->base + IC_WAKESET);
wmb();
__raw_writel(icdev->pmdata[6], icdev->base + IC_MASKSET);
wmb();
return 0;
alchemy_ic_resume_one((void __iomem *)KSEG1ADDR(AU1000_IC1_PHYS_ADDR),
&alchemy_ic_pmdata[7]);
alchemy_ic_resume_one((void __iomem *)KSEG1ADDR(AU1000_IC0_PHYS_ADDR),
alchemy_ic_pmdata);
}
static struct sysdev_class alchemy_ic_sysdev_class = {
.name = "ic",
static struct syscore_ops alchemy_ic_syscore_ops = {
.suspend = alchemy_ic_suspend,
.resume = alchemy_ic_resume,
};
static int __init alchemy_ic_sysdev_init(void)
static int __init alchemy_ic_pm_init(void)
{
struct alchemy_ic_sysdev *icdev;
unsigned long icbase[2] = { IC0_PHYS_ADDR, IC1_PHYS_ADDR };
int err, i;
err = sysdev_class_register(&alchemy_ic_sysdev_class);
if (err)
return err;
for (i = 0; i < 2; i++) {
icdev = kzalloc(sizeof(struct alchemy_ic_sysdev), GFP_KERNEL);
if (!icdev)
return -ENOMEM;
icdev->base = ioremap(icbase[i], 0x1000);
icdev->sysdev.id = i;
icdev->sysdev.cls = &alchemy_ic_sysdev_class;
err = sysdev_register(&icdev->sysdev);
if (err) {
kfree(icdev);
return err;
}
}
register_syscore_ops(&alchemy_ic_syscore_ops);
return 0;
}
device_initcall(alchemy_ic_sysdev_init);
device_initcall(alchemy_ic_pm_init);

View file

@ -13,9 +13,10 @@
#include <linux/dma-mapping.h>
#include <linux/etherdevice.h>
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/serial_8250.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <asm/mach-au1x00/au1xxx.h>
#include <asm/mach-au1x00/au1xxx_dbdma.h>
@ -30,21 +31,12 @@ static void alchemy_8250_pm(struct uart_port *port, unsigned int state,
#ifdef CONFIG_SERIAL_8250
switch (state) {
case 0:
if ((__raw_readl(port->membase + UART_MOD_CNTRL) & 3) != 3) {
/* power-on sequence as suggested in the databooks */
__raw_writel(0, port->membase + UART_MOD_CNTRL);
wmb();
__raw_writel(1, port->membase + UART_MOD_CNTRL);
wmb();
}
__raw_writel(3, port->membase + UART_MOD_CNTRL); /* full on */
wmb();
alchemy_uart_enable(CPHYSADDR(port->membase));
serial8250_do_pm(port, state, old_state);
break;
case 3: /* power off */
serial8250_do_pm(port, state, old_state);
__raw_writel(0, port->membase + UART_MOD_CNTRL);
wmb();
alchemy_uart_disable(CPHYSADDR(port->membase));
break;
default:
serial8250_do_pm(port, state, old_state);
@ -65,38 +57,60 @@ static void alchemy_8250_pm(struct uart_port *port, unsigned int state,
.pm = alchemy_8250_pm, \
}
static struct plat_serial8250_port au1x00_uart_data[] = {
#if defined(CONFIG_SOC_AU1000)
PORT(UART0_PHYS_ADDR, AU1000_UART0_INT),
PORT(UART1_PHYS_ADDR, AU1000_UART1_INT),
PORT(UART2_PHYS_ADDR, AU1000_UART2_INT),
PORT(UART3_PHYS_ADDR, AU1000_UART3_INT),
#elif defined(CONFIG_SOC_AU1500)
PORT(UART0_PHYS_ADDR, AU1500_UART0_INT),
PORT(UART3_PHYS_ADDR, AU1500_UART3_INT),
#elif defined(CONFIG_SOC_AU1100)
PORT(UART0_PHYS_ADDR, AU1100_UART0_INT),
PORT(UART1_PHYS_ADDR, AU1100_UART1_INT),
PORT(UART3_PHYS_ADDR, AU1100_UART3_INT),
#elif defined(CONFIG_SOC_AU1550)
PORT(UART0_PHYS_ADDR, AU1550_UART0_INT),
PORT(UART1_PHYS_ADDR, AU1550_UART1_INT),
PORT(UART3_PHYS_ADDR, AU1550_UART3_INT),
#elif defined(CONFIG_SOC_AU1200)
PORT(UART0_PHYS_ADDR, AU1200_UART0_INT),
PORT(UART1_PHYS_ADDR, AU1200_UART1_INT),
#endif
{ },
static struct plat_serial8250_port au1x00_uart_data[][4] __initdata = {
[ALCHEMY_CPU_AU1000] = {
PORT(AU1000_UART0_PHYS_ADDR, AU1000_UART0_INT),
PORT(AU1000_UART1_PHYS_ADDR, AU1000_UART1_INT),
PORT(AU1000_UART2_PHYS_ADDR, AU1000_UART2_INT),
PORT(AU1000_UART3_PHYS_ADDR, AU1000_UART3_INT),
},
[ALCHEMY_CPU_AU1500] = {
PORT(AU1000_UART0_PHYS_ADDR, AU1500_UART0_INT),
PORT(AU1000_UART3_PHYS_ADDR, AU1500_UART3_INT),
},
[ALCHEMY_CPU_AU1100] = {
PORT(AU1000_UART0_PHYS_ADDR, AU1100_UART0_INT),
PORT(AU1000_UART1_PHYS_ADDR, AU1100_UART1_INT),
PORT(AU1000_UART3_PHYS_ADDR, AU1100_UART3_INT),
},
[ALCHEMY_CPU_AU1550] = {
PORT(AU1000_UART0_PHYS_ADDR, AU1550_UART0_INT),
PORT(AU1000_UART1_PHYS_ADDR, AU1550_UART1_INT),
PORT(AU1000_UART3_PHYS_ADDR, AU1550_UART3_INT),
},
[ALCHEMY_CPU_AU1200] = {
PORT(AU1000_UART0_PHYS_ADDR, AU1200_UART0_INT),
PORT(AU1000_UART1_PHYS_ADDR, AU1200_UART1_INT),
},
};
static struct platform_device au1xx0_uart_device = {
.name = "serial8250",
.id = PLAT8250_DEV_AU1X00,
.dev = {
.platform_data = au1x00_uart_data,
},
};
static void __init alchemy_setup_uarts(int ctype)
{
unsigned int uartclk = get_au1x00_uart_baud_base() * 16;
int s = sizeof(struct plat_serial8250_port);
int c = alchemy_get_uarts(ctype);
struct plat_serial8250_port *ports;
ports = kzalloc(s * (c + 1), GFP_KERNEL);
if (!ports) {
printk(KERN_INFO "Alchemy: no memory for UART data\n");
return;
}
memcpy(ports, au1x00_uart_data[ctype], s * c);
au1xx0_uart_device.dev.platform_data = ports;
/* Fill up uartclk. */
for (s = 0; s < c; s++)
ports[s].uartclk = uartclk;
if (platform_device_register(&au1xx0_uart_device))
printk(KERN_INFO "Alchemy: failed to register UARTs\n");
}
/* OHCI (USB full speed host controller) */
static struct resource au1xxx_usb_ohci_resources[] = {
[0] = {
@ -269,8 +283,8 @@ extern struct au1xmmc_platform_data au1xmmc_platdata[2];
static struct resource au1200_mmc0_resources[] = {
[0] = {
.start = SD0_PHYS_ADDR,
.end = SD0_PHYS_ADDR + 0x7ffff,
.start = AU1100_SD0_PHYS_ADDR,
.end = AU1100_SD0_PHYS_ADDR + 0xfff,
.flags = IORESOURCE_MEM,
},
[1] = {
@ -305,8 +319,8 @@ static struct platform_device au1200_mmc0_device = {
#ifndef CONFIG_MIPS_DB1200
static struct resource au1200_mmc1_resources[] = {
[0] = {
.start = SD1_PHYS_ADDR,
.end = SD1_PHYS_ADDR + 0x7ffff,
.start = AU1100_SD1_PHYS_ADDR,
.end = AU1100_SD1_PHYS_ADDR + 0xfff,
.flags = IORESOURCE_MEM,
},
[1] = {
@ -359,15 +373,16 @@ static struct platform_device pbdb_smbus_device = {
#endif
/* Macro to help defining the Ethernet MAC resources */
#define MAC_RES_COUNT 3 /* MAC regs base, MAC enable reg, MAC INT */
#define MAC_RES(_base, _enable, _irq) \
{ \
.start = CPHYSADDR(_base), \
.end = CPHYSADDR(_base + 0xffff), \
.start = _base, \
.end = _base + 0xffff, \
.flags = IORESOURCE_MEM, \
}, \
{ \
.start = CPHYSADDR(_enable), \
.end = CPHYSADDR(_enable + 0x3), \
.start = _enable, \
.end = _enable + 0x3, \
.flags = IORESOURCE_MEM, \
}, \
{ \
@ -376,19 +391,29 @@ static struct platform_device pbdb_smbus_device = {
.flags = IORESOURCE_IRQ \
}
static struct resource au1xxx_eth0_resources[] = {
#if defined(CONFIG_SOC_AU1000)
MAC_RES(AU1000_ETH0_BASE, AU1000_MAC0_ENABLE, AU1000_MAC0_DMA_INT),
#elif defined(CONFIG_SOC_AU1100)
MAC_RES(AU1100_ETH0_BASE, AU1100_MAC0_ENABLE, AU1100_MAC0_DMA_INT),
#elif defined(CONFIG_SOC_AU1550)
MAC_RES(AU1550_ETH0_BASE, AU1550_MAC0_ENABLE, AU1550_MAC0_DMA_INT),
#elif defined(CONFIG_SOC_AU1500)
MAC_RES(AU1500_ETH0_BASE, AU1500_MAC0_ENABLE, AU1500_MAC0_DMA_INT),
#endif
static struct resource au1xxx_eth0_resources[][MAC_RES_COUNT] __initdata = {
[ALCHEMY_CPU_AU1000] = {
MAC_RES(AU1000_MAC0_PHYS_ADDR,
AU1000_MACEN_PHYS_ADDR,
AU1000_MAC0_DMA_INT)
},
[ALCHEMY_CPU_AU1500] = {
MAC_RES(AU1500_MAC0_PHYS_ADDR,
AU1500_MACEN_PHYS_ADDR,
AU1500_MAC0_DMA_INT)
},
[ALCHEMY_CPU_AU1100] = {
MAC_RES(AU1000_MAC0_PHYS_ADDR,
AU1000_MACEN_PHYS_ADDR,
AU1100_MAC0_DMA_INT)
},
[ALCHEMY_CPU_AU1550] = {
MAC_RES(AU1000_MAC0_PHYS_ADDR,
AU1000_MACEN_PHYS_ADDR,
AU1550_MAC0_DMA_INT)
},
};
static struct au1000_eth_platform_data au1xxx_eth0_platform_data = {
.phy1_search_mac0 = 1,
};
@ -396,20 +421,26 @@ static struct au1000_eth_platform_data au1xxx_eth0_platform_data = {
static struct platform_device au1xxx_eth0_device = {
.name = "au1000-eth",
.id = 0,
.num_resources = ARRAY_SIZE(au1xxx_eth0_resources),
.resource = au1xxx_eth0_resources,
.num_resources = MAC_RES_COUNT,
.dev.platform_data = &au1xxx_eth0_platform_data,
};
#ifndef CONFIG_SOC_AU1100
static struct resource au1xxx_eth1_resources[] = {
#if defined(CONFIG_SOC_AU1000)
MAC_RES(AU1000_ETH1_BASE, AU1000_MAC1_ENABLE, AU1000_MAC1_DMA_INT),
#elif defined(CONFIG_SOC_AU1550)
MAC_RES(AU1550_ETH1_BASE, AU1550_MAC1_ENABLE, AU1550_MAC1_DMA_INT),
#elif defined(CONFIG_SOC_AU1500)
MAC_RES(AU1500_ETH1_BASE, AU1500_MAC1_ENABLE, AU1500_MAC1_DMA_INT),
#endif
static struct resource au1xxx_eth1_resources[][MAC_RES_COUNT] __initdata = {
[ALCHEMY_CPU_AU1000] = {
MAC_RES(AU1000_MAC1_PHYS_ADDR,
AU1000_MACEN_PHYS_ADDR + 4,
AU1000_MAC1_DMA_INT)
},
[ALCHEMY_CPU_AU1500] = {
MAC_RES(AU1500_MAC1_PHYS_ADDR,
AU1500_MACEN_PHYS_ADDR + 4,
AU1500_MAC1_DMA_INT)
},
[ALCHEMY_CPU_AU1550] = {
MAC_RES(AU1000_MAC1_PHYS_ADDR,
AU1000_MACEN_PHYS_ADDR + 4,
AU1550_MAC1_DMA_INT)
},
};
static struct au1000_eth_platform_data au1xxx_eth1_platform_data = {
@ -419,11 +450,9 @@ static struct au1000_eth_platform_data au1xxx_eth1_platform_data = {
static struct platform_device au1xxx_eth1_device = {
.name = "au1000-eth",
.id = 1,
.num_resources = ARRAY_SIZE(au1xxx_eth1_resources),
.resource = au1xxx_eth1_resources,
.num_resources = MAC_RES_COUNT,
.dev.platform_data = &au1xxx_eth1_platform_data,
};
#endif
void __init au1xxx_override_eth_cfg(unsigned int port,
struct au1000_eth_platform_data *eth_data)
@ -434,15 +463,65 @@ void __init au1xxx_override_eth_cfg(unsigned int port,
if (port == 0)
memcpy(&au1xxx_eth0_platform_data, eth_data,
sizeof(struct au1000_eth_platform_data));
#ifndef CONFIG_SOC_AU1100
else
memcpy(&au1xxx_eth1_platform_data, eth_data,
sizeof(struct au1000_eth_platform_data));
#endif
}
static void __init alchemy_setup_macs(int ctype)
{
int ret, i;
unsigned char ethaddr[6];
struct resource *macres;
/* Handle 1st MAC */
if (alchemy_get_macs(ctype) < 1)
return;
macres = kmalloc(sizeof(struct resource) * MAC_RES_COUNT, GFP_KERNEL);
if (!macres) {
printk(KERN_INFO "Alchemy: no memory for MAC0 resources\n");
return;
}
memcpy(macres, au1xxx_eth0_resources[ctype],
sizeof(struct resource) * MAC_RES_COUNT);
au1xxx_eth0_device.resource = macres;
i = prom_get_ethernet_addr(ethaddr);
if (!i && !is_valid_ether_addr(au1xxx_eth0_platform_data.mac))
memcpy(au1xxx_eth0_platform_data.mac, ethaddr, 6);
ret = platform_device_register(&au1xxx_eth0_device);
if (!ret)
printk(KERN_INFO "Alchemy: failed to register MAC0\n");
/* Handle 2nd MAC */
if (alchemy_get_macs(ctype) < 2)
return;
macres = kmalloc(sizeof(struct resource) * MAC_RES_COUNT, GFP_KERNEL);
if (!macres) {
printk(KERN_INFO "Alchemy: no memory for MAC1 resources\n");
return;
}
memcpy(macres, au1xxx_eth1_resources[ctype],
sizeof(struct resource) * MAC_RES_COUNT);
au1xxx_eth1_device.resource = macres;
ethaddr[5] += 1; /* next addr for 2nd MAC */
if (!i && !is_valid_ether_addr(au1xxx_eth1_platform_data.mac))
memcpy(au1xxx_eth1_platform_data.mac, ethaddr, 6);
/* Register second MAC if enabled in pinfunc */
if (!(au_readl(SYS_PINFUNC) & (u32)SYS_PF_NI2)) {
ret = platform_device_register(&au1xxx_eth1_device);
if (ret)
printk(KERN_INFO "Alchemy: failed to register MAC1\n");
}
}
static struct platform_device *au1xxx_platform_devices[] __initdata = {
&au1xx0_uart_device,
&au1xxx_usb_ohci_device,
#ifdef CONFIG_FB_AU1100
&au1100_lcd_device,
@ -460,36 +539,17 @@ static struct platform_device *au1xxx_platform_devices[] __initdata = {
#ifdef SMBUS_PSC_BASE
&pbdb_smbus_device,
#endif
&au1xxx_eth0_device,
};
static int __init au1xxx_platform_init(void)
{
unsigned int uartclk = get_au1x00_uart_baud_base() * 16;
int err, i;
unsigned char ethaddr[6];
int err, ctype = alchemy_get_cputype();
/* Fill up uartclk. */
for (i = 0; au1x00_uart_data[i].flags; i++)
au1x00_uart_data[i].uartclk = uartclk;
/* use firmware-provided mac addr if available and necessary */
i = prom_get_ethernet_addr(ethaddr);
if (!i && !is_valid_ether_addr(au1xxx_eth0_platform_data.mac))
memcpy(au1xxx_eth0_platform_data.mac, ethaddr, 6);
alchemy_setup_uarts(ctype);
alchemy_setup_macs(ctype);
err = platform_add_devices(au1xxx_platform_devices,
ARRAY_SIZE(au1xxx_platform_devices));
#ifndef CONFIG_SOC_AU1100
ethaddr[5] += 1; /* next addr for 2nd MAC */
if (!i && !is_valid_ether_addr(au1xxx_eth1_platform_data.mac))
memcpy(au1xxx_eth1_platform_data.mac, ethaddr, 6);
/* Register second MAC if enabled in pinfunc */
if (!err && !(au_readl(SYS_PINFUNC) & (u32)SYS_PF_NI2))
err = platform_device_register(&au1xxx_eth1_device);
#endif
return err;
}

View file

@ -52,8 +52,6 @@ void __init plat_mem_setup(void)
/* this is faster than wasting cycles trying to approximate it */
preset_lpj = (est_freq >> 1) / HZ;
board_setup(); /* board specific setup */
if (au1xxx_cpu_needs_config_od())
/* Various early Au1xx0 errata corrected by this */
set_c0_config(1 << 19); /* Set Config[OD] */
@ -61,6 +59,8 @@ void __init plat_mem_setup(void)
/* Clear to obtain best system bus performance */
clear_c0_config(1 << 19); /* Clear Config[OD] */
board_setup(); /* board specific setup */
/* IO/MEM resources. */
set_io_port_base(0);
ioport_resource.start = IOPORT_RESOURCE_START;

View file

@ -23,6 +23,13 @@ void __init board_setup(void)
unsigned long freq0, clksrc, div, pfc;
unsigned short whoami;
/* Set Config[OD] (disable overlapping bus transaction):
* This gets rid of a _lot_ of spurious interrupts (especially
* wrt. IDE); but incurs ~10% performance hit in some
* cpu-bound applications.
*/
set_c0_config(1 << 19);
bcsr_init(DB1200_BCSR_PHYS_ADDR,
DB1200_BCSR_PHYS_ADDR + DB1200_BCSR_HEXLED_OFS);

View file

@ -65,7 +65,7 @@ void __init board_setup(void)
/* Set AUX clock to 12 MHz * 8 = 96 MHz */
au_writel(8, SYS_AUXPLL);
au_writel(0, SYS_PINSTATERD);
alchemy_gpio1_input_enable();
udelay(100);
#if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE)

View file

@ -56,7 +56,7 @@ void __init board_setup(void)
sys_clksrc = sys_freqctrl = pin_func = 0;
/* Set AUX clock to 12 MHz * 8 = 96 MHz */
au_writel(8, SYS_AUXPLL);
au_writel(0, SYS_PINSTATERD);
alchemy_gpio1_input_enable();
udelay(100);
/* GPIO201 is input for PCMCIA card detect */

View file

@ -62,5 +62,5 @@ void __init prom_init(void)
void prom_putchar(unsigned char c)
{
alchemy_uart_putchar(UART0_PHYS_ADDR, c);
alchemy_uart_putchar(AU1000_UART0_PHYS_ADDR, c);
}

View file

@ -36,9 +36,6 @@
#include <prom.h>
#define UART1_ADDR KSEG1ADDR(UART1_PHYS_ADDR)
#define UART3_ADDR KSEG1ADDR(UART3_PHYS_ADDR)
char irq_tab_alchemy[][5] __initdata = {
[0] = { -1, AU1500_PCI_INTA, AU1500_PCI_INTB, 0xff, 0xff },
};
@ -67,18 +64,15 @@ static void gpr_power_off(void)
void __init board_setup(void)
{
printk(KERN_INFO "Tarpeze ITS GPR board\n");
printk(KERN_INFO "Trapeze ITS GPR board\n");
pm_power_off = gpr_power_off;
_machine_halt = gpr_power_off;
_machine_restart = gpr_reset;
/* Enable UART3 */
au_writel(0x1, UART3_ADDR + UART_MOD_CNTRL);/* clock enable (CE) */
au_writel(0x3, UART3_ADDR + UART_MOD_CNTRL); /* CE and "enable" */
/* Enable UART1 */
au_writel(0x1, UART1_ADDR + UART_MOD_CNTRL); /* clock enable (CE) */
au_writel(0x3, UART1_ADDR + UART_MOD_CNTRL); /* CE and "enable" */
/* Enable UART1/3 */
alchemy_uart_enable(AU1000_UART3_PHYS_ADDR);
alchemy_uart_enable(AU1000_UART1_PHYS_ADDR);
/* Take away Reset of UMTS-card */
alchemy_gpio_direction_output(215, 1);

View file

@ -59,5 +59,5 @@ void __init prom_init(void)
void prom_putchar(unsigned char c)
{
alchemy_uart_putchar(UART0_PHYS_ADDR, c);
alchemy_uart_putchar(AU1000_UART0_PHYS_ADDR, c);
}

View file

@ -87,7 +87,7 @@ void __init board_setup(void)
au_writel(SYS_PF_NI2, SYS_PINFUNC);
/* Initialize GPIO */
au_writel(0xFFFFFFFF, SYS_TRIOUTCLR);
au_writel(~0, KSEG1ADDR(AU1000_SYS_PHYS_ADDR) + SYS_TRIOUTCLR);
alchemy_gpio_direction_output(0, 0); /* Disable M66EN (PCI 66MHz) */
alchemy_gpio_direction_output(3, 1); /* Disable PCI CLKRUN# */
alchemy_gpio_direction_output(1, 1); /* Enable EXT_IO3 */

View file

@ -62,5 +62,5 @@ void __init prom_init(void)
void prom_putchar(unsigned char c)
{
alchemy_uart_putchar(UART0_PHYS_ADDR, c);
alchemy_uart_putchar(AU1000_UART0_PHYS_ADDR, c);
}

View file

@ -53,8 +53,8 @@ static struct platform_device mtx1_button = {
static struct resource mtx1_wdt_res[] = {
[0] = {
.start = 15,
.end = 15,
.start = 215,
.end = 215,
.name = "mtx1-wdt-gpio",
.flags = IORESOURCE_IRQ,
}

View file

@ -66,13 +66,10 @@ void __init board_setup(void)
au_writel(pin_func, SYS_PINFUNC);
/* Enable UART */
au_writel(0x01, UART3_ADDR + UART_MOD_CNTRL); /* clock enable (CE) */
mdelay(10);
au_writel(0x03, UART3_ADDR + UART_MOD_CNTRL); /* CE and "enable" */
mdelay(10);
/* Enable DTR = USB power up */
au_writel(0x01, UART3_ADDR + UART_MCR); /* UART_MCR_DTR is 0x01??? */
alchemy_uart_enable(AU1000_UART3_PHYS_ADDR);
/* Enable DTR (MCR bit 0) = USB power up */
__raw_writel(1, (void __iomem *)KSEG1ADDR(AU1000_UART3_PHYS_ADDR + 0x18));
wmb();
#ifdef CONFIG_PCI
#if defined(__MIPSEB__)

View file

@ -59,5 +59,5 @@ void __init prom_init(void)
void prom_putchar(unsigned char c)
{
alchemy_uart_putchar(UART0_PHYS_ADDR, c);
alchemy_uart_putchar(AU1000_UART0_PHYS_ADDR, c);
}

View file

@ -3,6 +3,7 @@
*
* Copyright (C) 2005 Broadcom Corporation
* Copyright (C) 2006 Felix Fietkau <nbd@openwrt.org>
* Copyright (C) 2010-2011 Hauke Mehrtens <hauke@hauke-m.de>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
@ -23,7 +24,7 @@
static char nvram_buf[NVRAM_SPACE];
/* Probe for NVRAM header */
static void __init early_nvram_init(void)
static void early_nvram_init(void)
{
struct ssb_mipscore *mcore = &ssb_bcm47xx.mipscore;
struct nvram_header *header;

View file

@ -3,6 +3,7 @@
* Copyright (C) 2006 Felix Fietkau <nbd@openwrt.org>
* Copyright (C) 2006 Michael Buesch <mb@bu3sch.de>
* Copyright (C) 2010 Waldemar Brodkorb <wbx@openadk.org>
* Copyright (C) 2010-2011 Hauke Mehrtens <hauke@hauke-m.de>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
@ -57,10 +58,49 @@ static void bcm47xx_machine_halt(void)
}
#define READ_FROM_NVRAM(_outvar, name, buf) \
if (nvram_getenv(name, buf, sizeof(buf)) >= 0)\
if (nvram_getprefix(prefix, name, buf, sizeof(buf)) >= 0)\
sprom->_outvar = simple_strtoul(buf, NULL, 0);
static void bcm47xx_fill_sprom(struct ssb_sprom *sprom)
#define READ_FROM_NVRAM2(_outvar, name1, name2, buf) \
if (nvram_getprefix(prefix, name1, buf, sizeof(buf)) >= 0 || \
nvram_getprefix(prefix, name2, buf, sizeof(buf)) >= 0)\
sprom->_outvar = simple_strtoul(buf, NULL, 0);
static inline int nvram_getprefix(const char *prefix, char *name,
char *buf, int len)
{
if (prefix) {
char key[100];
snprintf(key, sizeof(key), "%s%s", prefix, name);
return nvram_getenv(key, buf, len);
}
return nvram_getenv(name, buf, len);
}
static u32 nvram_getu32(const char *name, char *buf, int len)
{
int rv;
char key[100];
u16 var0, var1;
snprintf(key, sizeof(key), "%s0", name);
rv = nvram_getenv(key, buf, len);
/* return 0 here so this looks like unset */
if (rv < 0)
return 0;
var0 = simple_strtoul(buf, NULL, 0);
snprintf(key, sizeof(key), "%s1", name);
rv = nvram_getenv(key, buf, len);
if (rv < 0)
return 0;
var1 = simple_strtoul(buf, NULL, 0);
return var1 << 16 | var0;
}
static void bcm47xx_fill_sprom(struct ssb_sprom *sprom, const char *prefix)
{
char buf[100];
u32 boardflags;
@ -69,11 +109,12 @@ static void bcm47xx_fill_sprom(struct ssb_sprom *sprom)
sprom->revision = 1; /* Fallback: Old hardware does not define this. */
READ_FROM_NVRAM(revision, "sromrev", buf);
if (nvram_getenv("il0macaddr", buf, sizeof(buf)) >= 0)
if (nvram_getprefix(prefix, "il0macaddr", buf, sizeof(buf)) >= 0 ||
nvram_getprefix(prefix, "macaddr", buf, sizeof(buf)) >= 0)
nvram_parse_macaddr(buf, sprom->il0mac);
if (nvram_getenv("et0macaddr", buf, sizeof(buf)) >= 0)
if (nvram_getprefix(prefix, "et0macaddr", buf, sizeof(buf)) >= 0)
nvram_parse_macaddr(buf, sprom->et0mac);
if (nvram_getenv("et1macaddr", buf, sizeof(buf)) >= 0)
if (nvram_getprefix(prefix, "et1macaddr", buf, sizeof(buf)) >= 0)
nvram_parse_macaddr(buf, sprom->et1mac);
READ_FROM_NVRAM(et0phyaddr, "et0phyaddr", buf);
READ_FROM_NVRAM(et1phyaddr, "et1phyaddr", buf);
@ -95,20 +136,36 @@ static void bcm47xx_fill_sprom(struct ssb_sprom *sprom)
READ_FROM_NVRAM(pa1hib0, "pa1hib0", buf);
READ_FROM_NVRAM(pa1hib2, "pa1hib1", buf);
READ_FROM_NVRAM(pa1hib1, "pa1hib2", buf);
READ_FROM_NVRAM(gpio0, "wl0gpio0", buf);
READ_FROM_NVRAM(gpio1, "wl0gpio1", buf);
READ_FROM_NVRAM(gpio2, "wl0gpio2", buf);
READ_FROM_NVRAM(gpio3, "wl0gpio3", buf);
READ_FROM_NVRAM(maxpwr_bg, "pa0maxpwr", buf);
READ_FROM_NVRAM(maxpwr_al, "pa1lomaxpwr", buf);
READ_FROM_NVRAM(maxpwr_a, "pa1maxpwr", buf);
READ_FROM_NVRAM(maxpwr_ah, "pa1himaxpwr", buf);
READ_FROM_NVRAM(itssi_a, "pa1itssit", buf);
READ_FROM_NVRAM(itssi_bg, "pa0itssit", buf);
READ_FROM_NVRAM2(gpio0, "ledbh0", "wl0gpio0", buf);
READ_FROM_NVRAM2(gpio1, "ledbh1", "wl0gpio1", buf);
READ_FROM_NVRAM2(gpio2, "ledbh2", "wl0gpio2", buf);
READ_FROM_NVRAM2(gpio3, "ledbh3", "wl0gpio3", buf);
READ_FROM_NVRAM2(maxpwr_bg, "maxp2ga0", "pa0maxpwr", buf);
READ_FROM_NVRAM2(maxpwr_al, "maxp5gla0", "pa1lomaxpwr", buf);
READ_FROM_NVRAM2(maxpwr_a, "maxp5ga0", "pa1maxpwr", buf);
READ_FROM_NVRAM2(maxpwr_ah, "maxp5gha0", "pa1himaxpwr", buf);
READ_FROM_NVRAM2(itssi_bg, "itt5ga0", "pa0itssit", buf);
READ_FROM_NVRAM2(itssi_a, "itt2ga0", "pa1itssit", buf);
READ_FROM_NVRAM(tri2g, "tri2g", buf);
READ_FROM_NVRAM(tri5gl, "tri5gl", buf);
READ_FROM_NVRAM(tri5g, "tri5g", buf);
READ_FROM_NVRAM(tri5gh, "tri5gh", buf);
READ_FROM_NVRAM(txpid2g[0], "txpid2ga0", buf);
READ_FROM_NVRAM(txpid2g[1], "txpid2ga1", buf);
READ_FROM_NVRAM(txpid2g[2], "txpid2ga2", buf);
READ_FROM_NVRAM(txpid2g[3], "txpid2ga3", buf);
READ_FROM_NVRAM(txpid5g[0], "txpid5ga0", buf);
READ_FROM_NVRAM(txpid5g[1], "txpid5ga1", buf);
READ_FROM_NVRAM(txpid5g[2], "txpid5ga2", buf);
READ_FROM_NVRAM(txpid5g[3], "txpid5ga3", buf);
READ_FROM_NVRAM(txpid5gl[0], "txpid5gla0", buf);
READ_FROM_NVRAM(txpid5gl[1], "txpid5gla1", buf);
READ_FROM_NVRAM(txpid5gl[2], "txpid5gla2", buf);
READ_FROM_NVRAM(txpid5gl[3], "txpid5gla3", buf);
READ_FROM_NVRAM(txpid5gh[0], "txpid5gha0", buf);
READ_FROM_NVRAM(txpid5gh[1], "txpid5gha1", buf);
READ_FROM_NVRAM(txpid5gh[2], "txpid5gha2", buf);
READ_FROM_NVRAM(txpid5gh[3], "txpid5gha3", buf);
READ_FROM_NVRAM(rxpo2g, "rxpo2g", buf);
READ_FROM_NVRAM(rxpo5g, "rxpo5g", buf);
READ_FROM_NVRAM(rssisav2g, "rssisav2g", buf);
@ -120,19 +177,27 @@ static void bcm47xx_fill_sprom(struct ssb_sprom *sprom)
READ_FROM_NVRAM(rssismf5g, "rssismf5g", buf);
READ_FROM_NVRAM(bxa5g, "bxa5g", buf);
READ_FROM_NVRAM(cck2gpo, "cck2gpo", buf);
READ_FROM_NVRAM(ofdm2gpo, "ofdm2gpo", buf);
READ_FROM_NVRAM(ofdm5glpo, "ofdm5glpo", buf);
READ_FROM_NVRAM(ofdm5gpo, "ofdm5gpo", buf);
READ_FROM_NVRAM(ofdm5ghpo, "ofdm5ghpo", buf);
if (nvram_getenv("boardflags", buf, sizeof(buf)) >= 0) {
sprom->ofdm2gpo = nvram_getu32("ofdm2gpo", buf, sizeof(buf));
sprom->ofdm5glpo = nvram_getu32("ofdm5glpo", buf, sizeof(buf));
sprom->ofdm5gpo = nvram_getu32("ofdm5gpo", buf, sizeof(buf));
sprom->ofdm5ghpo = nvram_getu32("ofdm5ghpo", buf, sizeof(buf));
READ_FROM_NVRAM(antenna_gain.ghz24.a0, "ag0", buf);
READ_FROM_NVRAM(antenna_gain.ghz24.a1, "ag1", buf);
READ_FROM_NVRAM(antenna_gain.ghz24.a2, "ag2", buf);
READ_FROM_NVRAM(antenna_gain.ghz24.a3, "ag3", buf);
memcpy(&sprom->antenna_gain.ghz5, &sprom->antenna_gain.ghz24,
sizeof(sprom->antenna_gain.ghz5));
if (nvram_getprefix(prefix, "boardflags", buf, sizeof(buf)) >= 0) {
boardflags = simple_strtoul(buf, NULL, 0);
if (boardflags) {
sprom->boardflags_lo = (boardflags & 0x0000FFFFU);
sprom->boardflags_hi = (boardflags & 0xFFFF0000U) >> 16;
}
}
if (nvram_getenv("boardflags2", buf, sizeof(buf)) >= 0) {
if (nvram_getprefix(prefix, "boardflags2", buf, sizeof(buf)) >= 0) {
boardflags = simple_strtoul(buf, NULL, 0);
if (boardflags) {
sprom->boardflags2_lo = (boardflags & 0x0000FFFFU);
@ -141,6 +206,22 @@ static void bcm47xx_fill_sprom(struct ssb_sprom *sprom)
}
}
int bcm47xx_get_sprom(struct ssb_bus *bus, struct ssb_sprom *out)
{
char prefix[10];
if (bus->bustype == SSB_BUSTYPE_PCI) {
snprintf(prefix, sizeof(prefix), "pci/%u/%u/",
bus->host_pci->bus->number + 1,
PCI_SLOT(bus->host_pci->devfn));
bcm47xx_fill_sprom(out, prefix);
return 0;
} else {
printk(KERN_WARNING "bcm47xx: unable to fill SPROM for given bustype.\n");
return -EINVAL;
}
}
static int bcm47xx_get_invariants(struct ssb_bus *bus,
struct ssb_init_invariants *iv)
{
@ -158,7 +239,7 @@ static int bcm47xx_get_invariants(struct ssb_bus *bus,
if (nvram_getenv("boardrev", buf, sizeof(buf)) >= 0)
iv->boardinfo.rev = (u16)simple_strtoul(buf, NULL, 0);
bcm47xx_fill_sprom(&iv->sprom);
bcm47xx_fill_sprom(&iv->sprom, NULL);
if (nvram_getenv("cardbus", buf, sizeof(buf)) >= 0)
iv->has_cardbus_slot = !!simple_strtoul(buf, NULL, 10);
@ -172,6 +253,11 @@ void __init plat_mem_setup(void)
char buf[100];
struct ssb_mipscore *mcore;
err = ssb_arch_register_fallback_sprom(&bcm47xx_get_sprom);
if (err)
printk(KERN_WARNING "bcm47xx: someone else already registered"
" a ssb SPROM callback handler (err %d)\n", err);
err = ssb_bus_ssbbus_register(&ssb_bcm47xx, SSB_ENUM_BASE,
bcm47xx_get_invariants);
if (err)

View file

@ -643,6 +643,17 @@ static struct ssb_sprom bcm63xx_sprom = {
.boardflags_lo = 0x2848,
.boardflags_hi = 0x0000,
};
int bcm63xx_get_fallback_sprom(struct ssb_bus *bus, struct ssb_sprom *out)
{
if (bus->bustype == SSB_BUSTYPE_PCI) {
memcpy(out, &bcm63xx_sprom, sizeof(struct ssb_sprom));
return 0;
} else {
printk(KERN_ERR PFX "unable to fill SPROM for given bustype.\n");
return -EINVAL;
}
}
#endif
/*
@ -793,8 +804,9 @@ void __init board_prom_init(void)
if (!board_get_mac_address(bcm63xx_sprom.il0mac)) {
memcpy(bcm63xx_sprom.et0mac, bcm63xx_sprom.il0mac, ETH_ALEN);
memcpy(bcm63xx_sprom.et1mac, bcm63xx_sprom.il0mac, ETH_ALEN);
if (ssb_arch_set_fallback_sprom(&bcm63xx_sprom) < 0)
printk(KERN_ERR "failed to register fallback SPROM\n");
if (ssb_arch_register_fallback_sprom(
&bcm63xx_get_fallback_sprom) < 0)
printk(KERN_ERR PFX "failed to register fallback SPROM\n");
}
#endif
}

View file

@ -3,5 +3,5 @@
void putc(char c)
{
/* all current (Jan. 2010) in-kernel boards */
alchemy_uart_putchar(UART0_PHYS_ADDR, c);
alchemy_uart_putchar(AU1000_UART0_PHYS_ADDR, c);
}

View file

@ -288,7 +288,6 @@ void octeon_user_io_init(void)
union octeon_cvmemctl cvmmemctl;
union cvmx_iob_fau_timeout fau_timeout;
union cvmx_pow_nw_tim nm_tim;
uint64_t cvmctl;
/* Get the current settings for CP0_CVMMEMCTL_REG */
cvmmemctl.u64 = read_c0_cvmmemctl();
@ -392,12 +391,6 @@ void octeon_user_io_init(void)
CONFIG_CAVIUM_OCTEON_CVMSEG_SIZE,
CONFIG_CAVIUM_OCTEON_CVMSEG_SIZE * 128);
/* Move the performance counter interrupts to IRQ 6 */
cvmctl = read_c0_cvmctl();
cvmctl &= ~(7 << 7);
cvmctl |= 6 << 7;
write_c0_cvmctl(cvmctl);
/* Set a default for the hardware timeouts */
fau_timeout.u64 = 0;
fau_timeout.s.tout_val = 0xfff;

View file

@ -37,7 +37,7 @@ static irqreturn_t mailbox_interrupt(int irq, void *dev_id)
uint64_t action;
/* Load the mailbox register to figure out what we're supposed to do */
action = cvmx_read_csr(CVMX_CIU_MBOX_CLRX(coreid));
action = cvmx_read_csr(CVMX_CIU_MBOX_CLRX(coreid)) & 0xffff;
/* Clear the mailbox to clear the interrupt */
cvmx_write_csr(CVMX_CIU_MBOX_CLRX(coreid), action);
@ -200,16 +200,15 @@ void octeon_prepare_cpus(unsigned int max_cpus)
if (labi->labi_signature != LABI_SIGNATURE)
panic("The bootloader version on this board is incorrect.");
#endif
cvmx_write_csr(CVMX_CIU_MBOX_CLRX(cvmx_get_core_num()), 0xffffffff);
/*
* Only the low order mailbox bits are used for IPIs, leave
* the other bits alone.
*/
cvmx_write_csr(CVMX_CIU_MBOX_CLRX(cvmx_get_core_num()), 0xffff);
if (request_irq(OCTEON_IRQ_MBOX0, mailbox_interrupt, IRQF_DISABLED,
"mailbox0", mailbox_interrupt)) {
"SMP-IPI", mailbox_interrupt)) {
panic("Cannot request_irq(OCTEON_IRQ_MBOX0)\n");
}
if (request_irq(OCTEON_IRQ_MBOX1, mailbox_interrupt, IRQF_DISABLED,
"mailbox1", mailbox_interrupt)) {
panic("Cannot request_irq(OCTEON_IRQ_MBOX1)\n");
}
}
/**

View file

@ -86,8 +86,8 @@ CONFIG_NET_SCHED=y
CONFIG_NET_EMATCH=y
CONFIG_NET_CLS_ACT=y
CONFIG_BT=m
CONFIG_BT_L2CAP=m
CONFIG_BT_SCO=m
CONFIG_BT_L2CAP=y
CONFIG_BT_SCO=y
CONFIG_BT_RFCOMM=m
CONFIG_BT_RFCOMM_TTY=y
CONFIG_BT_BNEP=m
@ -329,7 +329,7 @@ CONFIG_USB_LED=m
CONFIG_USB_GADGET=m
CONFIG_USB_GADGET_M66592=y
CONFIG_MMC=m
CONFIG_LEDS_CLASS=m
CONFIG_LEDS_CLASS=y
CONFIG_STAGING=y
# CONFIG_STAGING_EXCLUDE_BUILD is not set
CONFIG_FB_SM7XX=y

View file

@ -374,7 +374,7 @@ CONFIG_FB_CIRRUS=y
# CONFIG_VGA_CONSOLE is not set
CONFIG_FRAMEBUFFER_CONSOLE=y
CONFIG_HID=m
CONFIG_LEDS_CLASS=m
CONFIG_LEDS_CLASS=y
CONFIG_LEDS_TRIGGER_TIMER=m
CONFIG_LEDS_TRIGGER_IDE_DISK=y
CONFIG_LEDS_TRIGGER_HEARTBEAT=m

View file

@ -225,8 +225,8 @@ CONFIG_TOSHIBA_FIR=m
CONFIG_VLSI_FIR=m
CONFIG_MCS_FIR=m
CONFIG_BT=m
CONFIG_BT_L2CAP=m
CONFIG_BT_SCO=m
CONFIG_BT_L2CAP=y
CONFIG_BT_SCO=y
CONFIG_BT_RFCOMM=m
CONFIG_BT_RFCOMM_TTY=y
CONFIG_BT_BNEP=m

View file

@ -0,0 +1,574 @@
CONFIG_NLM_XLR_BOARD=y
CONFIG_HIGHMEM=y
CONFIG_KSM=y
CONFIG_DEFAULT_MMAP_MIN_ADDR=65536
CONFIG_SMP=y
CONFIG_NO_HZ=y
CONFIG_HIGH_RES_TIMERS=y
CONFIG_PREEMPT_VOLUNTARY=y
CONFIG_KEXEC=y
CONFIG_EXPERIMENTAL=y
CONFIG_CROSS_COMPILE="mips64-unknown-linux-gnu-"
# CONFIG_LOCALVERSION_AUTO is not set
CONFIG_SYSVIPC=y
CONFIG_POSIX_MQUEUE=y
CONFIG_BSD_PROCESS_ACCT=y
CONFIG_BSD_PROCESS_ACCT_V3=y
CONFIG_TASKSTATS=y
CONFIG_TASK_DELAY_ACCT=y
CONFIG_TASK_XACCT=y
CONFIG_TASK_IO_ACCOUNTING=y
CONFIG_AUDIT=y
CONFIG_NAMESPACES=y
CONFIG_SCHED_AUTOGROUP=y
CONFIG_BLK_DEV_INITRD=y
CONFIG_INITRAMFS_SOURCE="usr/dev_file_list usr/rootfs"
CONFIG_RD_BZIP2=y
CONFIG_RD_LZMA=y
CONFIG_INITRAMFS_COMPRESSION_GZIP=y
# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
CONFIG_EXPERT=y
CONFIG_KALLSYMS_ALL=y
# CONFIG_ELF_CORE is not set
# CONFIG_PCSPKR_PLATFORM is not set
# CONFIG_PERF_EVENTS is not set
# CONFIG_COMPAT_BRK is not set
CONFIG_PROFILING=y
CONFIG_MODULES=y
CONFIG_MODULE_UNLOAD=y
CONFIG_MODVERSIONS=y
CONFIG_MODULE_SRCVERSION_ALL=y
CONFIG_BLK_DEV_INTEGRITY=y
CONFIG_BINFMT_MISC=m
CONFIG_PM_RUNTIME=y
CONFIG_PM_DEBUG=y
CONFIG_PACKET=y
CONFIG_UNIX=y
CONFIG_XFRM_USER=m
CONFIG_NET_KEY=m
CONFIG_INET=y
CONFIG_IP_MULTICAST=y
CONFIG_IP_ADVANCED_ROUTER=y
CONFIG_IP_MULTIPLE_TABLES=y
CONFIG_IP_ROUTE_MULTIPATH=y
CONFIG_IP_ROUTE_VERBOSE=y
CONFIG_NET_IPIP=m
CONFIG_IP_MROUTE=y
CONFIG_IP_PIMSM_V1=y
CONFIG_IP_PIMSM_V2=y
CONFIG_SYN_COOKIES=y
CONFIG_INET_AH=m
CONFIG_INET_ESP=m
CONFIG_INET_IPCOMP=m
CONFIG_INET_XFRM_MODE_TRANSPORT=m
CONFIG_INET_XFRM_MODE_TUNNEL=m
CONFIG_INET_XFRM_MODE_BEET=m
CONFIG_TCP_CONG_ADVANCED=y
CONFIG_TCP_CONG_HSTCP=m
CONFIG_TCP_CONG_HYBLA=m
CONFIG_TCP_CONG_SCALABLE=m
CONFIG_TCP_CONG_LP=m
CONFIG_TCP_CONG_VENO=m
CONFIG_TCP_CONG_YEAH=m
CONFIG_TCP_CONG_ILLINOIS=m
CONFIG_TCP_MD5SIG=y
CONFIG_IPV6=y
CONFIG_IPV6_PRIVACY=y
CONFIG_INET6_AH=m
CONFIG_INET6_ESP=m
CONFIG_INET6_IPCOMP=m
CONFIG_INET6_XFRM_MODE_TRANSPORT=m
CONFIG_INET6_XFRM_MODE_TUNNEL=m
CONFIG_INET6_XFRM_MODE_BEET=m
CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION=m
CONFIG_IPV6_SIT=m
CONFIG_IPV6_TUNNEL=m
CONFIG_IPV6_MULTIPLE_TABLES=y
CONFIG_NETLABEL=y
CONFIG_NETFILTER=y
CONFIG_NF_CONNTRACK=m
CONFIG_NF_CONNTRACK_SECMARK=y
CONFIG_NF_CONNTRACK_EVENTS=y
CONFIG_NF_CT_PROTO_UDPLITE=m
CONFIG_NF_CONNTRACK_AMANDA=m
CONFIG_NF_CONNTRACK_FTP=m
CONFIG_NF_CONNTRACK_H323=m
CONFIG_NF_CONNTRACK_IRC=m
CONFIG_NF_CONNTRACK_NETBIOS_NS=m
CONFIG_NF_CONNTRACK_PPTP=m
CONFIG_NF_CONNTRACK_SANE=m
CONFIG_NF_CONNTRACK_SIP=m
CONFIG_NF_CONNTRACK_TFTP=m
CONFIG_NF_CT_NETLINK=m
CONFIG_NETFILTER_TPROXY=m
CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m
CONFIG_NETFILTER_XT_TARGET_CONNMARK=m
CONFIG_NETFILTER_XT_TARGET_CONNSECMARK=m
CONFIG_NETFILTER_XT_TARGET_DSCP=m
CONFIG_NETFILTER_XT_TARGET_MARK=m
CONFIG_NETFILTER_XT_TARGET_NFLOG=m
CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m
CONFIG_NETFILTER_XT_TARGET_NOTRACK=m
CONFIG_NETFILTER_XT_TARGET_TPROXY=m
CONFIG_NETFILTER_XT_TARGET_TRACE=m
CONFIG_NETFILTER_XT_TARGET_SECMARK=m
CONFIG_NETFILTER_XT_TARGET_TCPMSS=m
CONFIG_NETFILTER_XT_MATCH_CLUSTER=m
CONFIG_NETFILTER_XT_MATCH_COMMENT=m
CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m
CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=m
CONFIG_NETFILTER_XT_MATCH_CONNMARK=m
CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m
CONFIG_NETFILTER_XT_MATCH_DSCP=m
CONFIG_NETFILTER_XT_MATCH_ESP=m
CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=m
CONFIG_NETFILTER_XT_MATCH_HELPER=m
CONFIG_NETFILTER_XT_MATCH_IPRANGE=m
CONFIG_NETFILTER_XT_MATCH_LENGTH=m
CONFIG_NETFILTER_XT_MATCH_LIMIT=m
CONFIG_NETFILTER_XT_MATCH_MAC=m
CONFIG_NETFILTER_XT_MATCH_MARK=m
CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m
CONFIG_NETFILTER_XT_MATCH_OSF=m
CONFIG_NETFILTER_XT_MATCH_OWNER=m
CONFIG_NETFILTER_XT_MATCH_POLICY=m
CONFIG_NETFILTER_XT_MATCH_PHYSDEV=m
CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m
CONFIG_NETFILTER_XT_MATCH_QUOTA=m
CONFIG_NETFILTER_XT_MATCH_RATEEST=m
CONFIG_NETFILTER_XT_MATCH_REALM=m
CONFIG_NETFILTER_XT_MATCH_RECENT=m
CONFIG_NETFILTER_XT_MATCH_SOCKET=m
CONFIG_NETFILTER_XT_MATCH_STATE=m
CONFIG_NETFILTER_XT_MATCH_STATISTIC=m
CONFIG_NETFILTER_XT_MATCH_STRING=m
CONFIG_NETFILTER_XT_MATCH_TCPMSS=m
CONFIG_NETFILTER_XT_MATCH_TIME=m
CONFIG_NETFILTER_XT_MATCH_U32=m
CONFIG_IP_VS=m
CONFIG_IP_VS_IPV6=y
CONFIG_IP_VS_PROTO_TCP=y
CONFIG_IP_VS_PROTO_UDP=y
CONFIG_IP_VS_PROTO_ESP=y
CONFIG_IP_VS_PROTO_AH=y
CONFIG_IP_VS_RR=m
CONFIG_IP_VS_WRR=m
CONFIG_IP_VS_LC=m
CONFIG_IP_VS_WLC=m
CONFIG_IP_VS_LBLC=m
CONFIG_IP_VS_LBLCR=m
CONFIG_IP_VS_DH=m
CONFIG_IP_VS_SH=m
CONFIG_IP_VS_SED=m
CONFIG_IP_VS_NQ=m
CONFIG_IP_VS_FTP=m
CONFIG_NF_CONNTRACK_IPV4=m
CONFIG_IP_NF_QUEUE=m
CONFIG_IP_NF_IPTABLES=m
CONFIG_IP_NF_MATCH_AH=m
CONFIG_IP_NF_MATCH_ECN=m
CONFIG_IP_NF_MATCH_TTL=m
CONFIG_IP_NF_FILTER=m
CONFIG_IP_NF_TARGET_REJECT=m
CONFIG_IP_NF_TARGET_LOG=m
CONFIG_IP_NF_TARGET_ULOG=m
CONFIG_NF_NAT=m
CONFIG_IP_NF_TARGET_MASQUERADE=m
CONFIG_IP_NF_TARGET_NETMAP=m
CONFIG_IP_NF_TARGET_REDIRECT=m
CONFIG_IP_NF_MANGLE=m
CONFIG_IP_NF_TARGET_CLUSTERIP=m
CONFIG_IP_NF_TARGET_ECN=m
CONFIG_IP_NF_TARGET_TTL=m
CONFIG_IP_NF_RAW=m
CONFIG_IP_NF_SECURITY=m
CONFIG_IP_NF_ARPTABLES=m
CONFIG_IP_NF_ARPFILTER=m
CONFIG_IP_NF_ARP_MANGLE=m
CONFIG_NF_CONNTRACK_IPV6=m
CONFIG_IP6_NF_QUEUE=m
CONFIG_IP6_NF_IPTABLES=m
CONFIG_IP6_NF_MATCH_AH=m
CONFIG_IP6_NF_MATCH_EUI64=m
CONFIG_IP6_NF_MATCH_FRAG=m
CONFIG_IP6_NF_MATCH_OPTS=m
CONFIG_IP6_NF_MATCH_HL=m
CONFIG_IP6_NF_MATCH_IPV6HEADER=m
CONFIG_IP6_NF_MATCH_MH=m
CONFIG_IP6_NF_MATCH_RT=m
CONFIG_IP6_NF_TARGET_HL=m
CONFIG_IP6_NF_TARGET_LOG=m
CONFIG_IP6_NF_FILTER=m
CONFIG_IP6_NF_TARGET_REJECT=m
CONFIG_IP6_NF_MANGLE=m
CONFIG_IP6_NF_RAW=m
CONFIG_IP6_NF_SECURITY=m
CONFIG_DECNET_NF_GRABULATOR=m
CONFIG_BRIDGE_NF_EBTABLES=m
CONFIG_BRIDGE_EBT_BROUTE=m
CONFIG_BRIDGE_EBT_T_FILTER=m
CONFIG_BRIDGE_EBT_T_NAT=m
CONFIG_BRIDGE_EBT_802_3=m
CONFIG_BRIDGE_EBT_AMONG=m
CONFIG_BRIDGE_EBT_ARP=m
CONFIG_BRIDGE_EBT_IP=m
CONFIG_BRIDGE_EBT_IP6=m
CONFIG_BRIDGE_EBT_LIMIT=m
CONFIG_BRIDGE_EBT_MARK=m
CONFIG_BRIDGE_EBT_PKTTYPE=m
CONFIG_BRIDGE_EBT_STP=m
CONFIG_BRIDGE_EBT_VLAN=m
CONFIG_BRIDGE_EBT_ARPREPLY=m
CONFIG_BRIDGE_EBT_DNAT=m
CONFIG_BRIDGE_EBT_MARK_T=m
CONFIG_BRIDGE_EBT_REDIRECT=m
CONFIG_BRIDGE_EBT_SNAT=m
CONFIG_BRIDGE_EBT_LOG=m
CONFIG_BRIDGE_EBT_ULOG=m
CONFIG_BRIDGE_EBT_NFLOG=m
CONFIG_IP_DCCP=m
CONFIG_RDS=m
CONFIG_RDS_TCP=m
CONFIG_TIPC=m
CONFIG_ATM=m
CONFIG_ATM_CLIP=m
CONFIG_ATM_LANE=m
CONFIG_ATM_MPOA=m
CONFIG_ATM_BR2684=m
CONFIG_BRIDGE=m
CONFIG_VLAN_8021Q=m
CONFIG_VLAN_8021Q_GVRP=y
CONFIG_DECNET=m
CONFIG_LLC2=m
CONFIG_IPX=m
CONFIG_ATALK=m
CONFIG_DEV_APPLETALK=m
CONFIG_IPDDP=m
CONFIG_IPDDP_ENCAP=y
CONFIG_IPDDP_DECAP=y
CONFIG_X25=m
CONFIG_LAPB=m
CONFIG_ECONET=m
CONFIG_ECONET_AUNUDP=y
CONFIG_ECONET_NATIVE=y
CONFIG_WAN_ROUTER=m
CONFIG_PHONET=m
CONFIG_IEEE802154=m
CONFIG_NET_SCHED=y
CONFIG_NET_SCH_CBQ=m
CONFIG_NET_SCH_HTB=m
CONFIG_NET_SCH_HFSC=m
CONFIG_NET_SCH_ATM=m
CONFIG_NET_SCH_PRIO=m
CONFIG_NET_SCH_MULTIQ=m
CONFIG_NET_SCH_RED=m
CONFIG_NET_SCH_SFQ=m
CONFIG_NET_SCH_TEQL=m
CONFIG_NET_SCH_TBF=m
CONFIG_NET_SCH_GRED=m
CONFIG_NET_SCH_DSMARK=m
CONFIG_NET_SCH_NETEM=m
CONFIG_NET_SCH_DRR=m
CONFIG_NET_SCH_INGRESS=m
CONFIG_NET_CLS_BASIC=m
CONFIG_NET_CLS_TCINDEX=m
CONFIG_NET_CLS_ROUTE4=m
CONFIG_NET_CLS_FW=m
CONFIG_NET_CLS_U32=m
CONFIG_CLS_U32_MARK=y
CONFIG_NET_CLS_RSVP=m
CONFIG_NET_CLS_RSVP6=m
CONFIG_NET_CLS_FLOW=m
CONFIG_NET_EMATCH=y
CONFIG_NET_EMATCH_CMP=m
CONFIG_NET_EMATCH_NBYTE=m
CONFIG_NET_EMATCH_U32=m
CONFIG_NET_EMATCH_META=m
CONFIG_NET_EMATCH_TEXT=m
CONFIG_NET_CLS_ACT=y
CONFIG_NET_ACT_POLICE=m
CONFIG_NET_ACT_GACT=m
CONFIG_GACT_PROB=y
CONFIG_NET_ACT_MIRRED=m
CONFIG_NET_ACT_IPT=m
CONFIG_NET_ACT_NAT=m
CONFIG_NET_ACT_PEDIT=m
CONFIG_NET_ACT_SIMP=m
CONFIG_NET_ACT_SKBEDIT=m
CONFIG_DCB=y
CONFIG_NET_PKTGEN=m
# CONFIG_WIRELESS is not set
CONFIG_DEVTMPFS=y
CONFIG_DEVTMPFS_MOUNT=y
# CONFIG_STANDALONE is not set
CONFIG_CONNECTOR=y
CONFIG_MTD=m
CONFIG_BLK_DEV_LOOP=y
CONFIG_BLK_DEV_CRYPTOLOOP=m
CONFIG_BLK_DEV_NBD=m
CONFIG_BLK_DEV_OSD=m
CONFIG_BLK_DEV_RAM=y
CONFIG_BLK_DEV_RAM_SIZE=65536
CONFIG_CDROM_PKTCDVD=y
CONFIG_MISC_DEVICES=y
CONFIG_RAID_ATTRS=m
CONFIG_SCSI=y
CONFIG_SCSI_TGT=m
CONFIG_BLK_DEV_SD=y
CONFIG_CHR_DEV_ST=m
CONFIG_CHR_DEV_OSST=m
CONFIG_BLK_DEV_SR=y
CONFIG_CHR_DEV_SG=y
CONFIG_CHR_DEV_SCH=m
CONFIG_SCSI_MULTI_LUN=y
CONFIG_SCSI_CONSTANTS=y
CONFIG_SCSI_LOGGING=y
CONFIG_SCSI_SCAN_ASYNC=y
CONFIG_SCSI_SPI_ATTRS=m
CONFIG_SCSI_FC_TGT_ATTRS=y
CONFIG_SCSI_SAS_LIBSAS=m
CONFIG_SCSI_SRP_ATTRS=m
CONFIG_SCSI_SRP_TGT_ATTRS=y
CONFIG_ISCSI_TCP=m
CONFIG_LIBFCOE=m
CONFIG_SCSI_DEBUG=m
CONFIG_SCSI_DH=y
CONFIG_SCSI_DH_RDAC=m
CONFIG_SCSI_DH_HP_SW=m
CONFIG_SCSI_DH_EMC=m
CONFIG_SCSI_DH_ALUA=m
CONFIG_SCSI_OSD_INITIATOR=m
CONFIG_SCSI_OSD_ULD=m
# CONFIG_INPUT_MOUSEDEV is not set
CONFIG_INPUT_EVDEV=y
CONFIG_INPUT_EVBUG=m
# CONFIG_INPUT_KEYBOARD is not set
# CONFIG_INPUT_MOUSE is not set
# CONFIG_SERIO_I8042 is not set
CONFIG_SERIO_SERPORT=m
CONFIG_SERIO_LIBPS2=y
CONFIG_SERIO_RAW=m
CONFIG_VT_HW_CONSOLE_BINDING=y
CONFIG_DEVPTS_MULTIPLE_INSTANCES=y
CONFIG_LEGACY_PTY_COUNT=0
CONFIG_SERIAL_NONSTANDARD=y
CONFIG_N_HDLC=m
# CONFIG_DEVKMEM is not set
CONFIG_STALDRV=y
CONFIG_SERIAL_8250=y
CONFIG_SERIAL_8250_CONSOLE=y
CONFIG_SERIAL_8250_NR_UARTS=48
CONFIG_SERIAL_8250_EXTENDED=y
CONFIG_SERIAL_8250_MANY_PORTS=y
CONFIG_SERIAL_8250_SHARE_IRQ=y
CONFIG_SERIAL_8250_RSA=y
CONFIG_HW_RANDOM=y
CONFIG_HW_RANDOM_TIMERIOMEM=m
CONFIG_RAW_DRIVER=m
# CONFIG_HWMON is not set
# CONFIG_VGA_CONSOLE is not set
# CONFIG_HID_SUPPORT is not set
# CONFIG_USB_SUPPORT is not set
CONFIG_UIO=y
CONFIG_UIO_PDRV=m
CONFIG_UIO_PDRV_GENIRQ=m
CONFIG_EXT2_FS=y
CONFIG_EXT2_FS_XATTR=y
CONFIG_EXT2_FS_POSIX_ACL=y
CONFIG_EXT2_FS_SECURITY=y
CONFIG_EXT3_FS=y
CONFIG_EXT3_FS_POSIX_ACL=y
CONFIG_EXT3_FS_SECURITY=y
CONFIG_EXT4_FS=y
CONFIG_EXT4_FS_POSIX_ACL=y
CONFIG_EXT4_FS_SECURITY=y
CONFIG_GFS2_FS=m
CONFIG_GFS2_FS_LOCKING_DLM=y
CONFIG_OCFS2_FS=m
CONFIG_BTRFS_FS=m
CONFIG_BTRFS_FS_POSIX_ACL=y
CONFIG_NILFS2_FS=m
CONFIG_QUOTA_NETLINK_INTERFACE=y
# CONFIG_PRINT_QUOTA_WARNING is not set
CONFIG_QFMT_V1=m
CONFIG_QFMT_V2=m
CONFIG_AUTOFS4_FS=m
CONFIG_FUSE_FS=y
CONFIG_CUSE=m
CONFIG_FSCACHE=m
CONFIG_FSCACHE_STATS=y
CONFIG_FSCACHE_HISTOGRAM=y
CONFIG_CACHEFILES=m
CONFIG_ISO9660_FS=m
CONFIG_JOLIET=y
CONFIG_ZISOFS=y
CONFIG_UDF_FS=m
CONFIG_MSDOS_FS=m
CONFIG_VFAT_FS=m
CONFIG_NTFS_FS=m
CONFIG_PROC_KCORE=y
CONFIG_TMPFS=y
CONFIG_TMPFS_POSIX_ACL=y
CONFIG_CONFIGFS_FS=y
CONFIG_ADFS_FS=m
CONFIG_AFFS_FS=m
CONFIG_ECRYPT_FS=y
CONFIG_HFS_FS=m
CONFIG_HFSPLUS_FS=m
CONFIG_BEFS_FS=m
CONFIG_BFS_FS=m
CONFIG_EFS_FS=m
CONFIG_CRAMFS=m
CONFIG_SQUASHFS=m
CONFIG_VXFS_FS=m
CONFIG_MINIX_FS=m
CONFIG_OMFS_FS=m
CONFIG_HPFS_FS=m
CONFIG_QNX4FS_FS=m
CONFIG_ROMFS_FS=m
CONFIG_SYSV_FS=m
CONFIG_UFS_FS=m
CONFIG_EXOFS_FS=m
CONFIG_NFS_FS=m
CONFIG_NFS_V3=y
CONFIG_NFS_V3_ACL=y
CONFIG_NFS_V4=y
CONFIG_NFS_FSCACHE=y
CONFIG_NFSD=m
CONFIG_NFSD_V3_ACL=y
CONFIG_NFSD_V4=y
CONFIG_CIFS=m
CONFIG_CIFS_WEAK_PW_HASH=y
CONFIG_CIFS_UPCALL=y
CONFIG_CIFS_XATTR=y
CONFIG_CIFS_POSIX=y
CONFIG_CIFS_DFS_UPCALL=y
CONFIG_CIFS_EXPERIMENTAL=y
CONFIG_NCP_FS=m
CONFIG_NCPFS_PACKET_SIGNING=y
CONFIG_NCPFS_IOCTL_LOCKING=y
CONFIG_NCPFS_STRONG=y
CONFIG_NCPFS_NFS_NS=y
CONFIG_NCPFS_OS2_NS=y
CONFIG_NCPFS_NLS=y
CONFIG_NCPFS_EXTRAS=y
CONFIG_CODA_FS=m
CONFIG_AFS_FS=m
CONFIG_PARTITION_ADVANCED=y
CONFIG_ACORN_PARTITION=y
CONFIG_ACORN_PARTITION_ICS=y
CONFIG_ACORN_PARTITION_RISCIX=y
CONFIG_OSF_PARTITION=y
CONFIG_AMIGA_PARTITION=y
CONFIG_ATARI_PARTITION=y
CONFIG_MAC_PARTITION=y
CONFIG_BSD_DISKLABEL=y
CONFIG_MINIX_SUBPARTITION=y
CONFIG_SOLARIS_X86_PARTITION=y
CONFIG_UNIXWARE_DISKLABEL=y
CONFIG_LDM_PARTITION=y
CONFIG_SGI_PARTITION=y
CONFIG_ULTRIX_PARTITION=y
CONFIG_SUN_PARTITION=y
CONFIG_KARMA_PARTITION=y
CONFIG_EFI_PARTITION=y
CONFIG_SYSV68_PARTITION=y
CONFIG_NLS=y
CONFIG_NLS_DEFAULT="cp437"
CONFIG_NLS_CODEPAGE_437=m
CONFIG_NLS_CODEPAGE_737=m
CONFIG_NLS_CODEPAGE_775=m
CONFIG_NLS_CODEPAGE_850=m
CONFIG_NLS_CODEPAGE_852=m
CONFIG_NLS_CODEPAGE_855=m
CONFIG_NLS_CODEPAGE_857=m
CONFIG_NLS_CODEPAGE_860=m
CONFIG_NLS_CODEPAGE_861=m
CONFIG_NLS_CODEPAGE_862=m
CONFIG_NLS_CODEPAGE_863=m
CONFIG_NLS_CODEPAGE_864=m
CONFIG_NLS_CODEPAGE_865=m
CONFIG_NLS_CODEPAGE_866=m
CONFIG_NLS_CODEPAGE_869=m
CONFIG_NLS_CODEPAGE_936=m
CONFIG_NLS_CODEPAGE_950=m
CONFIG_NLS_CODEPAGE_932=m
CONFIG_NLS_CODEPAGE_949=m
CONFIG_NLS_CODEPAGE_874=m
CONFIG_NLS_ISO8859_8=m
CONFIG_NLS_CODEPAGE_1250=m
CONFIG_NLS_CODEPAGE_1251=m
CONFIG_NLS_ASCII=m
CONFIG_NLS_ISO8859_1=m
CONFIG_NLS_ISO8859_2=m
CONFIG_NLS_ISO8859_3=m
CONFIG_NLS_ISO8859_4=m
CONFIG_NLS_ISO8859_5=m
CONFIG_NLS_ISO8859_6=m
CONFIG_NLS_ISO8859_7=m
CONFIG_NLS_ISO8859_9=m
CONFIG_NLS_ISO8859_13=m
CONFIG_NLS_ISO8859_14=m
CONFIG_NLS_ISO8859_15=m
CONFIG_NLS_KOI8_R=m
CONFIG_NLS_KOI8_U=m
CONFIG_PRINTK_TIME=y
# CONFIG_ENABLE_WARN_DEPRECATED is not set
# CONFIG_ENABLE_MUST_CHECK is not set
CONFIG_UNUSED_SYMBOLS=y
CONFIG_DEBUG_KERNEL=y
CONFIG_DETECT_HUNG_TASK=y
CONFIG_SCHEDSTATS=y
CONFIG_TIMER_STATS=y
CONFIG_DEBUG_INFO=y
CONFIG_DEBUG_MEMORY_INIT=y
CONFIG_SYSCTL_SYSCALL_CHECK=y
CONFIG_SCHED_TRACER=y
CONFIG_BLK_DEV_IO_TRACE=y
CONFIG_KGDB=y
CONFIG_SECURITY=y
CONFIG_SECURITY_NETWORK=y
CONFIG_LSM_MMAP_MIN_ADDR=0
CONFIG_SECURITY_SELINUX=y
CONFIG_SECURITY_SELINUX_BOOTPARAM=y
CONFIG_SECURITY_SELINUX_BOOTPARAM_VALUE=0
CONFIG_SECURITY_SELINUX_DISABLE=y
CONFIG_SECURITY_SMACK=y
CONFIG_SECURITY_TOMOYO=y
CONFIG_CRYPTO_NULL=m
CONFIG_CRYPTO_CRYPTD=m
CONFIG_CRYPTO_TEST=m
CONFIG_CRYPTO_CCM=m
CONFIG_CRYPTO_GCM=m
CONFIG_CRYPTO_CTS=m
CONFIG_CRYPTO_LRW=m
CONFIG_CRYPTO_PCBC=m
CONFIG_CRYPTO_XTS=m
CONFIG_CRYPTO_HMAC=y
CONFIG_CRYPTO_XCBC=m
CONFIG_CRYPTO_VMAC=m
CONFIG_CRYPTO_MICHAEL_MIC=m
CONFIG_CRYPTO_RMD128=m
CONFIG_CRYPTO_RMD160=m
CONFIG_CRYPTO_RMD256=m
CONFIG_CRYPTO_RMD320=m
CONFIG_CRYPTO_SHA256=m
CONFIG_CRYPTO_SHA512=m
CONFIG_CRYPTO_TGR192=m
CONFIG_CRYPTO_WP512=m
CONFIG_CRYPTO_ANUBIS=m
CONFIG_CRYPTO_BLOWFISH=m
CONFIG_CRYPTO_CAMELLIA=m
CONFIG_CRYPTO_CAST5=m
CONFIG_CRYPTO_CAST6=m
CONFIG_CRYPTO_FCRYPT=m
CONFIG_CRYPTO_KHAZAD=m
CONFIG_CRYPTO_SALSA20=m
CONFIG_CRYPTO_SEED=m
CONFIG_CRYPTO_SERPENT=m
CONFIG_CRYPTO_TEA=m
CONFIG_CRYPTO_TWOFISH=m
CONFIG_CRYPTO_ZLIB=m
CONFIG_CRYPTO_LZO=m
CONFIG_CRC_CCITT=m
CONFIG_CRC7=m

View file

@ -33,6 +33,7 @@
#define PRID_COMP_TOSHIBA 0x070000
#define PRID_COMP_LSI 0x080000
#define PRID_COMP_LEXRA 0x0b0000
#define PRID_COMP_NETLOGIC 0x0c0000
#define PRID_COMP_CAVIUM 0x0d0000
#define PRID_COMP_INGENIC 0xd00000
@ -141,6 +142,31 @@
#define PRID_IMP_JZRISC 0x0200
/*
* These are the PRID's for when 23:16 == PRID_COMP_NETLOGIC
*/
#define PRID_IMP_NETLOGIC_XLR732 0x0000
#define PRID_IMP_NETLOGIC_XLR716 0x0200
#define PRID_IMP_NETLOGIC_XLR532 0x0900
#define PRID_IMP_NETLOGIC_XLR308 0x0600
#define PRID_IMP_NETLOGIC_XLR532C 0x0800
#define PRID_IMP_NETLOGIC_XLR516C 0x0a00
#define PRID_IMP_NETLOGIC_XLR508C 0x0b00
#define PRID_IMP_NETLOGIC_XLR308C 0x0f00
#define PRID_IMP_NETLOGIC_XLS608 0x8000
#define PRID_IMP_NETLOGIC_XLS408 0x8800
#define PRID_IMP_NETLOGIC_XLS404 0x8c00
#define PRID_IMP_NETLOGIC_XLS208 0x8e00
#define PRID_IMP_NETLOGIC_XLS204 0x8f00
#define PRID_IMP_NETLOGIC_XLS108 0xce00
#define PRID_IMP_NETLOGIC_XLS104 0xcf00
#define PRID_IMP_NETLOGIC_XLS616B 0x4000
#define PRID_IMP_NETLOGIC_XLS608B 0x4a00
#define PRID_IMP_NETLOGIC_XLS416B 0x4400
#define PRID_IMP_NETLOGIC_XLS412B 0x4c00
#define PRID_IMP_NETLOGIC_XLS408B 0x4e00
#define PRID_IMP_NETLOGIC_XLS404B 0x4f00
/*
* Definitions for 7:0 on legacy processors
*/
@ -234,6 +260,7 @@ enum cpu_type_enum {
*/
CPU_5KC, CPU_20KC, CPU_25KF, CPU_SB1, CPU_SB1A, CPU_LOONGSON2,
CPU_CAVIUM_OCTEON, CPU_CAVIUM_OCTEON_PLUS, CPU_CAVIUM_OCTEON2,
CPU_XLR,
CPU_LAST
};

View file

@ -161,6 +161,45 @@ static inline int alchemy_get_cputype(void)
return ALCHEMY_CPU_UNKNOWN;
}
/* return number of uarts on a given cputype */
static inline int alchemy_get_uarts(int type)
{
switch (type) {
case ALCHEMY_CPU_AU1000:
return 4;
case ALCHEMY_CPU_AU1500:
case ALCHEMY_CPU_AU1200:
return 2;
case ALCHEMY_CPU_AU1100:
case ALCHEMY_CPU_AU1550:
return 3;
}
return 0;
}
/* enable an UART block if it isn't already */
static inline void alchemy_uart_enable(u32 uart_phys)
{
void __iomem *addr = (void __iomem *)KSEG1ADDR(uart_phys);
/* reset, enable clock, deassert reset */
if ((__raw_readl(addr + 0x100) & 3) != 3) {
__raw_writel(0, addr + 0x100);
wmb();
__raw_writel(1, addr + 0x100);
wmb();
}
__raw_writel(3, addr + 0x100);
wmb();
}
static inline void alchemy_uart_disable(u32 uart_phys)
{
void __iomem *addr = (void __iomem *)KSEG1ADDR(uart_phys);
__raw_writel(0, addr + 0x100); /* UART_MOD_CNTRL */
wmb();
}
static inline void alchemy_uart_putchar(u32 uart_phys, u8 c)
{
void __iomem *base = (void __iomem *)KSEG1ADDR(uart_phys);
@ -180,6 +219,20 @@ static inline void alchemy_uart_putchar(u32 uart_phys, u8 c)
wmb();
}
/* return number of ethernet MACs on a given cputype */
static inline int alchemy_get_macs(int type)
{
switch (type) {
case ALCHEMY_CPU_AU1000:
case ALCHEMY_CPU_AU1500:
case ALCHEMY_CPU_AU1550:
return 2;
case ALCHEMY_CPU_AU1100:
return 1;
}
return 0;
}
/* arch/mips/au1000/common/clocks.c */
extern void set_au1x00_speed(unsigned int new_freq);
extern unsigned int get_au1x00_speed(void);
@ -630,38 +683,42 @@ enum soc_au1200_ints {
/*
* Physical base addresses for integrated peripherals
* 0..au1000 1..au1500 2..au1100 3..au1550 4..au1200
*/
#define AU1000_AC97_PHYS_ADDR 0x10000000 /* 012 */
#define AU1000_USBD_PHYS_ADDR 0x10200000 /* 0123 */
#define AU1000_IC0_PHYS_ADDR 0x10400000 /* 01234 */
#define AU1000_MAC0_PHYS_ADDR 0x10500000 /* 023 */
#define AU1000_MAC1_PHYS_ADDR 0x10510000 /* 023 */
#define AU1000_MACEN_PHYS_ADDR 0x10520000 /* 023 */
#define AU1100_SD0_PHYS_ADDR 0x10600000 /* 24 */
#define AU1100_SD1_PHYS_ADDR 0x10680000 /* 24 */
#define AU1000_I2S_PHYS_ADDR 0x11000000 /* 02 */
#define AU1500_MAC0_PHYS_ADDR 0x11500000 /* 1 */
#define AU1500_MAC1_PHYS_ADDR 0x11510000 /* 1 */
#define AU1500_MACEN_PHYS_ADDR 0x11520000 /* 1 */
#define AU1000_UART0_PHYS_ADDR 0x11100000 /* 01234 */
#define AU1000_UART1_PHYS_ADDR 0x11200000 /* 0234 */
#define AU1000_UART2_PHYS_ADDR 0x11300000 /* 0 */
#define AU1000_UART3_PHYS_ADDR 0x11400000 /* 0123 */
#define AU1500_GPIO2_PHYS_ADDR 0x11700000 /* 1234 */
#define AU1000_IC1_PHYS_ADDR 0x11800000 /* 01234 */
#define AU1000_SYS_PHYS_ADDR 0x11900000 /* 01234 */
#define AU1000_DMA_PHYS_ADDR 0x14002000 /* 012 */
#define AU1550_DBDMA_PHYS_ADDR 0x14002000 /* 34 */
#define AU1550_DBDMA_CONF_PHYS_ADDR 0x14003000 /* 34 */
#define AU1000_MACDMA0_PHYS_ADDR 0x14004000 /* 0123 */
#define AU1000_MACDMA1_PHYS_ADDR 0x14004200 /* 0123 */
#ifdef CONFIG_SOC_AU1000
#define MEM_PHYS_ADDR 0x14000000
#define STATIC_MEM_PHYS_ADDR 0x14001000
#define DMA0_PHYS_ADDR 0x14002000
#define DMA1_PHYS_ADDR 0x14002100
#define DMA2_PHYS_ADDR 0x14002200
#define DMA3_PHYS_ADDR 0x14002300
#define DMA4_PHYS_ADDR 0x14002400
#define DMA5_PHYS_ADDR 0x14002500
#define DMA6_PHYS_ADDR 0x14002600
#define DMA7_PHYS_ADDR 0x14002700
#define IC0_PHYS_ADDR 0x10400000
#define IC1_PHYS_ADDR 0x11800000
#define AC97_PHYS_ADDR 0x10000000
#define USBH_PHYS_ADDR 0x10100000
#define USBD_PHYS_ADDR 0x10200000
#define IRDA_PHYS_ADDR 0x10300000
#define MAC0_PHYS_ADDR 0x10500000
#define MAC1_PHYS_ADDR 0x10510000
#define MACEN_PHYS_ADDR 0x10520000
#define MACDMA0_PHYS_ADDR 0x14004000
#define MACDMA1_PHYS_ADDR 0x14004200
#define I2S_PHYS_ADDR 0x11000000
#define UART0_PHYS_ADDR 0x11100000
#define UART1_PHYS_ADDR 0x11200000
#define UART2_PHYS_ADDR 0x11300000
#define UART3_PHYS_ADDR 0x11400000
#define SSI0_PHYS_ADDR 0x11600000
#define SSI1_PHYS_ADDR 0x11680000
#define SYS_PHYS_ADDR 0x11900000
#define PCMCIA_IO_PHYS_ADDR 0xF00000000ULL
#define PCMCIA_ATTR_PHYS_ADDR 0xF40000000ULL
#define PCMCIA_MEM_PHYS_ADDR 0xF80000000ULL
@ -672,30 +729,8 @@ enum soc_au1200_ints {
#ifdef CONFIG_SOC_AU1500
#define MEM_PHYS_ADDR 0x14000000
#define STATIC_MEM_PHYS_ADDR 0x14001000
#define DMA0_PHYS_ADDR 0x14002000
#define DMA1_PHYS_ADDR 0x14002100
#define DMA2_PHYS_ADDR 0x14002200
#define DMA3_PHYS_ADDR 0x14002300
#define DMA4_PHYS_ADDR 0x14002400
#define DMA5_PHYS_ADDR 0x14002500
#define DMA6_PHYS_ADDR 0x14002600
#define DMA7_PHYS_ADDR 0x14002700
#define IC0_PHYS_ADDR 0x10400000
#define IC1_PHYS_ADDR 0x11800000
#define AC97_PHYS_ADDR 0x10000000
#define USBH_PHYS_ADDR 0x10100000
#define USBD_PHYS_ADDR 0x10200000
#define PCI_PHYS_ADDR 0x14005000
#define MAC0_PHYS_ADDR 0x11500000
#define MAC1_PHYS_ADDR 0x11510000
#define MACEN_PHYS_ADDR 0x11520000
#define MACDMA0_PHYS_ADDR 0x14004000
#define MACDMA1_PHYS_ADDR 0x14004200
#define I2S_PHYS_ADDR 0x11000000
#define UART0_PHYS_ADDR 0x11100000
#define UART3_PHYS_ADDR 0x11400000
#define GPIO2_PHYS_ADDR 0x11700000
#define SYS_PHYS_ADDR 0x11900000
#define PCI_MEM_PHYS_ADDR 0x400000000ULL
#define PCI_IO_PHYS_ADDR 0x500000000ULL
#define PCI_CONFIG0_PHYS_ADDR 0x600000000ULL
@ -710,34 +745,10 @@ enum soc_au1200_ints {
#ifdef CONFIG_SOC_AU1100
#define MEM_PHYS_ADDR 0x14000000
#define STATIC_MEM_PHYS_ADDR 0x14001000
#define DMA0_PHYS_ADDR 0x14002000
#define DMA1_PHYS_ADDR 0x14002100
#define DMA2_PHYS_ADDR 0x14002200
#define DMA3_PHYS_ADDR 0x14002300
#define DMA4_PHYS_ADDR 0x14002400
#define DMA5_PHYS_ADDR 0x14002500
#define DMA6_PHYS_ADDR 0x14002600
#define DMA7_PHYS_ADDR 0x14002700
#define IC0_PHYS_ADDR 0x10400000
#define SD0_PHYS_ADDR 0x10600000
#define SD1_PHYS_ADDR 0x10680000
#define IC1_PHYS_ADDR 0x11800000
#define AC97_PHYS_ADDR 0x10000000
#define USBH_PHYS_ADDR 0x10100000
#define USBD_PHYS_ADDR 0x10200000
#define IRDA_PHYS_ADDR 0x10300000
#define MAC0_PHYS_ADDR 0x10500000
#define MACEN_PHYS_ADDR 0x10520000
#define MACDMA0_PHYS_ADDR 0x14004000
#define MACDMA1_PHYS_ADDR 0x14004200
#define I2S_PHYS_ADDR 0x11000000
#define UART0_PHYS_ADDR 0x11100000
#define UART1_PHYS_ADDR 0x11200000
#define UART3_PHYS_ADDR 0x11400000
#define SSI0_PHYS_ADDR 0x11600000
#define SSI1_PHYS_ADDR 0x11680000
#define GPIO2_PHYS_ADDR 0x11700000
#define SYS_PHYS_ADDR 0x11900000
#define LCD_PHYS_ADDR 0x15000000
#define PCMCIA_IO_PHYS_ADDR 0xF00000000ULL
#define PCMCIA_ATTR_PHYS_ADDR 0xF40000000ULL
@ -749,22 +760,8 @@ enum soc_au1200_ints {
#ifdef CONFIG_SOC_AU1550
#define MEM_PHYS_ADDR 0x14000000
#define STATIC_MEM_PHYS_ADDR 0x14001000
#define IC0_PHYS_ADDR 0x10400000
#define IC1_PHYS_ADDR 0x11800000
#define USBH_PHYS_ADDR 0x14020000
#define USBD_PHYS_ADDR 0x10200000
#define PCI_PHYS_ADDR 0x14005000
#define MAC0_PHYS_ADDR 0x10500000
#define MAC1_PHYS_ADDR 0x10510000
#define MACEN_PHYS_ADDR 0x10520000
#define MACDMA0_PHYS_ADDR 0x14004000
#define MACDMA1_PHYS_ADDR 0x14004200
#define UART0_PHYS_ADDR 0x11100000
#define UART1_PHYS_ADDR 0x11200000
#define UART3_PHYS_ADDR 0x11400000
#define GPIO2_PHYS_ADDR 0x11700000
#define SYS_PHYS_ADDR 0x11900000
#define DDMA_PHYS_ADDR 0x14002000
#define PE_PHYS_ADDR 0x14008000
#define PSC0_PHYS_ADDR 0x11A00000
#define PSC1_PHYS_ADDR 0x11B00000
@ -786,19 +783,10 @@ enum soc_au1200_ints {
#define STATIC_MEM_PHYS_ADDR 0x14001000
#define AES_PHYS_ADDR 0x10300000
#define CIM_PHYS_ADDR 0x14004000
#define IC0_PHYS_ADDR 0x10400000
#define IC1_PHYS_ADDR 0x11800000
#define USBM_PHYS_ADDR 0x14020000
#define USBH_PHYS_ADDR 0x14020100
#define UART0_PHYS_ADDR 0x11100000
#define UART1_PHYS_ADDR 0x11200000
#define GPIO2_PHYS_ADDR 0x11700000
#define SYS_PHYS_ADDR 0x11900000
#define DDMA_PHYS_ADDR 0x14002000
#define PSC0_PHYS_ADDR 0x11A00000
#define PSC1_PHYS_ADDR 0x11B00000
#define SD0_PHYS_ADDR 0x10600000
#define SD1_PHYS_ADDR 0x10680000
#define LCD_PHYS_ADDR 0x15000000
#define SWCNT_PHYS_ADDR 0x1110010C
#define MAEFE_PHYS_ADDR 0x14012000
@ -835,183 +823,43 @@ enum soc_au1200_ints {
#endif
/* Interrupt Controller register offsets */
#define IC_CFG0RD 0x40
#define IC_CFG0SET 0x40
#define IC_CFG0CLR 0x44
#define IC_CFG1RD 0x48
#define IC_CFG1SET 0x48
#define IC_CFG1CLR 0x4C
#define IC_CFG2RD 0x50
#define IC_CFG2SET 0x50
#define IC_CFG2CLR 0x54
#define IC_REQ0INT 0x54
#define IC_SRCRD 0x58
#define IC_SRCSET 0x58
#define IC_SRCCLR 0x5C
#define IC_REQ1INT 0x5C
#define IC_ASSIGNRD 0x60
#define IC_ASSIGNSET 0x60
#define IC_ASSIGNCLR 0x64
#define IC_WAKERD 0x68
#define IC_WAKESET 0x68
#define IC_WAKECLR 0x6C
#define IC_MASKRD 0x70
#define IC_MASKSET 0x70
#define IC_MASKCLR 0x74
#define IC_RISINGRD 0x78
#define IC_RISINGCLR 0x78
#define IC_FALLINGRD 0x7C
#define IC_FALLINGCLR 0x7C
#define IC_TESTBIT 0x80
/* Interrupt Controller 0 */
#define IC0_CFG0RD 0xB0400040
#define IC0_CFG0SET 0xB0400040
#define IC0_CFG0CLR 0xB0400044
#define IC0_CFG1RD 0xB0400048
#define IC0_CFG1SET 0xB0400048
#define IC0_CFG1CLR 0xB040004C
#define IC0_CFG2RD 0xB0400050
#define IC0_CFG2SET 0xB0400050
#define IC0_CFG2CLR 0xB0400054
#define IC0_REQ0INT 0xB0400054
#define IC0_SRCRD 0xB0400058
#define IC0_SRCSET 0xB0400058
#define IC0_SRCCLR 0xB040005C
#define IC0_REQ1INT 0xB040005C
#define IC0_ASSIGNRD 0xB0400060
#define IC0_ASSIGNSET 0xB0400060
#define IC0_ASSIGNCLR 0xB0400064
#define IC0_WAKERD 0xB0400068
#define IC0_WAKESET 0xB0400068
#define IC0_WAKECLR 0xB040006C
#define IC0_MASKRD 0xB0400070
#define IC0_MASKSET 0xB0400070
#define IC0_MASKCLR 0xB0400074
#define IC0_RISINGRD 0xB0400078
#define IC0_RISINGCLR 0xB0400078
#define IC0_FALLINGRD 0xB040007C
#define IC0_FALLINGCLR 0xB040007C
#define IC0_TESTBIT 0xB0400080
/* Interrupt Controller 1 */
#define IC1_CFG0RD 0xB1800040
#define IC1_CFG0SET 0xB1800040
#define IC1_CFG0CLR 0xB1800044
#define IC1_CFG1RD 0xB1800048
#define IC1_CFG1SET 0xB1800048
#define IC1_CFG1CLR 0xB180004C
#define IC1_CFG2RD 0xB1800050
#define IC1_CFG2SET 0xB1800050
#define IC1_CFG2CLR 0xB1800054
#define IC1_REQ0INT 0xB1800054
#define IC1_SRCRD 0xB1800058
#define IC1_SRCSET 0xB1800058
#define IC1_SRCCLR 0xB180005C
#define IC1_REQ1INT 0xB180005C
#define IC1_ASSIGNRD 0xB1800060
#define IC1_ASSIGNSET 0xB1800060
#define IC1_ASSIGNCLR 0xB1800064
#define IC1_WAKERD 0xB1800068
#define IC1_WAKESET 0xB1800068
#define IC1_WAKECLR 0xB180006C
#define IC1_MASKRD 0xB1800070
#define IC1_MASKSET 0xB1800070
#define IC1_MASKCLR 0xB1800074
#define IC1_RISINGRD 0xB1800078
#define IC1_RISINGCLR 0xB1800078
#define IC1_FALLINGRD 0xB180007C
#define IC1_FALLINGCLR 0xB180007C
#define IC1_TESTBIT 0xB1800080
/* Au1000 */
#ifdef CONFIG_SOC_AU1000
#define UART0_ADDR 0xB1100000
#define UART3_ADDR 0xB1400000
#define USB_OHCI_BASE 0x10100000 /* phys addr for ioremap */
#define USB_HOST_CONFIG 0xB017FFFC
#define FOR_PLATFORM_C_USB_HOST_INT AU1000_USB_HOST_INT
#define AU1000_ETH0_BASE 0xB0500000
#define AU1000_ETH1_BASE 0xB0510000
#define AU1000_MAC0_ENABLE 0xB0520000
#define AU1000_MAC1_ENABLE 0xB0520004
#define NUM_ETH_INTERFACES 2
#endif /* CONFIG_SOC_AU1000 */
/* Au1500 */
#ifdef CONFIG_SOC_AU1500
#define UART0_ADDR 0xB1100000
#define UART3_ADDR 0xB1400000
#define USB_OHCI_BASE 0x10100000 /* phys addr for ioremap */
#define USB_HOST_CONFIG 0xB017fffc
#define FOR_PLATFORM_C_USB_HOST_INT AU1500_USB_HOST_INT
#define AU1500_ETH0_BASE 0xB1500000
#define AU1500_ETH1_BASE 0xB1510000
#define AU1500_MAC0_ENABLE 0xB1520000
#define AU1500_MAC1_ENABLE 0xB1520004
#define NUM_ETH_INTERFACES 2
#endif /* CONFIG_SOC_AU1500 */
/* Au1100 */
#ifdef CONFIG_SOC_AU1100
#define UART0_ADDR 0xB1100000
#define UART3_ADDR 0xB1400000
#define USB_OHCI_BASE 0x10100000 /* phys addr for ioremap */
#define USB_HOST_CONFIG 0xB017FFFC
#define FOR_PLATFORM_C_USB_HOST_INT AU1100_USB_HOST_INT
#define AU1100_ETH0_BASE 0xB0500000
#define AU1100_MAC0_ENABLE 0xB0520000
#define NUM_ETH_INTERFACES 1
#endif /* CONFIG_SOC_AU1100 */
#ifdef CONFIG_SOC_AU1550
#define UART0_ADDR 0xB1100000
#define USB_OHCI_BASE 0x14020000 /* phys addr for ioremap */
#define USB_OHCI_LEN 0x00060000
#define USB_HOST_CONFIG 0xB4027ffc
#define FOR_PLATFORM_C_USB_HOST_INT AU1550_USB_HOST_INT
#define AU1550_ETH0_BASE 0xB0500000
#define AU1550_ETH1_BASE 0xB0510000
#define AU1550_MAC0_ENABLE 0xB0520000
#define AU1550_MAC1_ENABLE 0xB0520004
#define NUM_ETH_INTERFACES 2
#endif /* CONFIG_SOC_AU1550 */
#ifdef CONFIG_SOC_AU1200
#define UART0_ADDR 0xB1100000
#define USB_UOC_BASE 0x14020020
#define USB_UOC_LEN 0x20
#define USB_OHCI_BASE 0x14020100
@ -1504,22 +1352,6 @@ enum soc_au1200_ints {
#define SYS_PINFUNC_S1B (1 << 2)
#endif
#define SYS_TRIOUTRD 0xB1900100
#define SYS_TRIOUTCLR 0xB1900100
#define SYS_OUTPUTRD 0xB1900108
#define SYS_OUTPUTSET 0xB1900108
#define SYS_OUTPUTCLR 0xB190010C
#define SYS_PINSTATERD 0xB1900110
#define SYS_PININPUTEN 0xB1900110
/* GPIO2, Au1500, Au1550 only */
#define GPIO2_BASE 0xB1700000
#define GPIO2_DIR (GPIO2_BASE + 0)
#define GPIO2_OUTPUT (GPIO2_BASE + 8)
#define GPIO2_PINSTATE (GPIO2_BASE + 0xC)
#define GPIO2_INTENABLE (GPIO2_BASE + 0x10)
#define GPIO2_ENABLE (GPIO2_BASE + 0x14)
/* Power Management */
#define SYS_SCRATCH0 0xB1900018
#define SYS_SCRATCH1 0xB190001C
@ -1635,12 +1467,6 @@ enum soc_au1200_ints {
# define AC97C_RS (1 << 1)
# define AC97C_CE (1 << 0)
/* Secure Digital (SD) Controller */
#define SD0_XMIT_FIFO 0xB0600000
#define SD0_RECV_FIFO 0xB0600004
#define SD1_XMIT_FIFO 0xB0680000
#define SD1_RECV_FIFO 0xB0680004
#if defined(CONFIG_SOC_AU1500) || defined(CONFIG_SOC_AU1550)
/* Au1500 PCI Controller */
#define Au1500_CFG_BASE 0xB4005000 /* virtual, KSEG1 addr */

View file

@ -37,10 +37,6 @@
#define NUM_AU1000_DMA_CHANNELS 8
/* DMA Channel Base Addresses */
#define DMA_CHANNEL_BASE 0xB4002000
#define DMA_CHANNEL_LEN 0x00000100
/* DMA Channel Register Offsets */
#define DMA_MODE_SET 0x00000000
#define DMA_MODE_READ DMA_MODE_SET

View file

@ -37,14 +37,6 @@
#ifndef _LANGUAGE_ASSEMBLY
/*
* The DMA base addresses.
* The channels are every 256 bytes (0x0100) from the channel 0 base.
* Interrupt status/enable is bits 15:0 for channels 15 to zero.
*/
#define DDMA_GLOBAL_BASE 0xb4003000
#define DDMA_CHANNEL_BASE 0xb4002000
typedef volatile struct dbdma_global {
u32 ddma_config;
u32 ddma_intstat;

View file

@ -24,6 +24,23 @@
#define MAKE_IRQ(intc, off) (AU1000_INTC##intc##_INT_BASE + (off))
/* GPIO1 registers within SYS_ area */
#define SYS_TRIOUTRD 0x100
#define SYS_TRIOUTCLR 0x100
#define SYS_OUTPUTRD 0x108
#define SYS_OUTPUTSET 0x108
#define SYS_OUTPUTCLR 0x10C
#define SYS_PINSTATERD 0x110
#define SYS_PININPUTEN 0x110
/* register offsets within GPIO2 block */
#define GPIO2_DIR 0x00
#define GPIO2_OUTPUT 0x08
#define GPIO2_PINSTATE 0x0C
#define GPIO2_INTENABLE 0x10
#define GPIO2_ENABLE 0x14
struct gpio;
static inline int au1000_gpio1_to_irq(int gpio)
{
@ -200,23 +217,26 @@ static inline int au1200_irq_to_gpio(int irq)
*/
static inline void alchemy_gpio1_set_value(int gpio, int v)
{
void __iomem *base = (void __iomem *)KSEG1ADDR(AU1000_SYS_PHYS_ADDR);
unsigned long mask = 1 << (gpio - ALCHEMY_GPIO1_BASE);
unsigned long r = v ? SYS_OUTPUTSET : SYS_OUTPUTCLR;
au_writel(mask, r);
au_sync();
__raw_writel(mask, base + r);
wmb();
}
static inline int alchemy_gpio1_get_value(int gpio)
{
void __iomem *base = (void __iomem *)KSEG1ADDR(AU1000_SYS_PHYS_ADDR);
unsigned long mask = 1 << (gpio - ALCHEMY_GPIO1_BASE);
return au_readl(SYS_PINSTATERD) & mask;
return __raw_readl(base + SYS_PINSTATERD) & mask;
}
static inline int alchemy_gpio1_direction_input(int gpio)
{
void __iomem *base = (void __iomem *)KSEG1ADDR(AU1000_SYS_PHYS_ADDR);
unsigned long mask = 1 << (gpio - ALCHEMY_GPIO1_BASE);
au_writel(mask, SYS_TRIOUTCLR);
au_sync();
__raw_writel(mask, base + SYS_TRIOUTCLR);
wmb();
return 0;
}
@ -257,27 +277,31 @@ static inline int alchemy_gpio1_to_irq(int gpio)
*/
static inline void __alchemy_gpio2_mod_dir(int gpio, int to_out)
{
void __iomem *base = (void __iomem *)KSEG1ADDR(AU1500_GPIO2_PHYS_ADDR);
unsigned long mask = 1 << (gpio - ALCHEMY_GPIO2_BASE);
unsigned long d = au_readl(GPIO2_DIR);
unsigned long d = __raw_readl(base + GPIO2_DIR);
if (to_out)
d |= mask;
else
d &= ~mask;
au_writel(d, GPIO2_DIR);
au_sync();
__raw_writel(d, base + GPIO2_DIR);
wmb();
}
static inline void alchemy_gpio2_set_value(int gpio, int v)
{
void __iomem *base = (void __iomem *)KSEG1ADDR(AU1500_GPIO2_PHYS_ADDR);
unsigned long mask;
mask = ((v) ? 0x00010001 : 0x00010000) << (gpio - ALCHEMY_GPIO2_BASE);
au_writel(mask, GPIO2_OUTPUT);
au_sync();
__raw_writel(mask, base + GPIO2_OUTPUT);
wmb();
}
static inline int alchemy_gpio2_get_value(int gpio)
{
return au_readl(GPIO2_PINSTATE) & (1 << (gpio - ALCHEMY_GPIO2_BASE));
void __iomem *base = (void __iomem *)KSEG1ADDR(AU1500_GPIO2_PHYS_ADDR);
return __raw_readl(base + GPIO2_PINSTATE) & (1 << (gpio - ALCHEMY_GPIO2_BASE));
}
static inline int alchemy_gpio2_direction_input(int gpio)
@ -329,21 +353,23 @@ static inline int alchemy_gpio2_to_irq(int gpio)
*/
static inline void alchemy_gpio1_input_enable(void)
{
au_writel(0, SYS_PININPUTEN); /* the write op is key */
au_sync();
void __iomem *base = (void __iomem *)KSEG1ADDR(AU1000_SYS_PHYS_ADDR);
__raw_writel(0, base + SYS_PININPUTEN); /* the write op is key */
wmb();
}
/* GPIO2 shared interrupts and control */
static inline void __alchemy_gpio2_mod_int(int gpio2, int en)
{
unsigned long r = au_readl(GPIO2_INTENABLE);
void __iomem *base = (void __iomem *)KSEG1ADDR(AU1500_GPIO2_PHYS_ADDR);
unsigned long r = __raw_readl(base + GPIO2_INTENABLE);
if (en)
r |= 1 << gpio2;
else
r &= ~(1 << gpio2);
au_writel(r, GPIO2_INTENABLE);
au_sync();
__raw_writel(r, base + GPIO2_INTENABLE);
wmb();
}
/**
@ -418,10 +444,11 @@ static inline void alchemy_gpio2_disable_int(int gpio2)
*/
static inline void alchemy_gpio2_enable(void)
{
au_writel(3, GPIO2_ENABLE); /* reset, clock enabled */
au_sync();
au_writel(1, GPIO2_ENABLE); /* clock enabled */
au_sync();
void __iomem *base = (void __iomem *)KSEG1ADDR(AU1500_GPIO2_PHYS_ADDR);
__raw_writel(3, base + GPIO2_ENABLE); /* reset, clock enabled */
wmb();
__raw_writel(1, base + GPIO2_ENABLE); /* clock enabled */
wmb();
}
/**
@ -431,8 +458,9 @@ static inline void alchemy_gpio2_enable(void)
*/
static inline void alchemy_gpio2_disable(void)
{
au_writel(2, GPIO2_ENABLE); /* reset, clock disabled */
au_sync();
void __iomem *base = (void __iomem *)KSEG1ADDR(AU1500_GPIO2_PHYS_ADDR);
__raw_writel(2, base + GPIO2_ENABLE); /* reset, clock disabled */
wmb();
}
/**********************************************************************/
@ -556,6 +584,16 @@ static inline void gpio_set_value(int gpio, int v)
alchemy_gpio_set_value(gpio, v);
}
static inline int gpio_get_value_cansleep(unsigned gpio)
{
return gpio_get_value(gpio);
}
static inline void gpio_set_value_cansleep(unsigned gpio, int value)
{
gpio_set_value(gpio, value);
}
static inline int gpio_is_valid(int gpio)
{
return alchemy_gpio_is_valid(gpio);
@ -581,10 +619,50 @@ static inline int gpio_request(unsigned gpio, const char *label)
return 0;
}
static inline int gpio_request_one(unsigned gpio,
unsigned long flags, const char *label)
{
return 0;
}
static inline int gpio_request_array(struct gpio *array, size_t num)
{
return 0;
}
static inline void gpio_free(unsigned gpio)
{
}
static inline void gpio_free_array(struct gpio *array, size_t num)
{
}
static inline int gpio_set_debounce(unsigned gpio, unsigned debounce)
{
return -ENOSYS;
}
static inline int gpio_export(unsigned gpio, bool direction_may_change)
{
return -ENOSYS;
}
static inline int gpio_export_link(struct device *dev, const char *name,
unsigned gpio)
{
return -ENOSYS;
}
static inline int gpio_sysfs_set_active_low(unsigned gpio, int value)
{
return -ENOSYS;
}
static inline void gpio_unexport(unsigned gpio)
{
}
#endif /* !CONFIG_ALCHEMY_GPIO_INDIRECT */

View file

@ -39,8 +39,16 @@ extern int nvram_getenv(char *name, char *val, size_t val_len);
static inline void nvram_parse_macaddr(char *buf, u8 *macaddr)
{
sscanf(buf, "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx", &macaddr[0], &macaddr[1],
&macaddr[2], &macaddr[3], &macaddr[4], &macaddr[5]);
if (strchr(buf, ':'))
sscanf(buf, "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx", &macaddr[0],
&macaddr[1], &macaddr[2], &macaddr[3], &macaddr[4],
&macaddr[5]);
else if (strchr(buf, '-'))
sscanf(buf, "%hhx-%hhx-%hhx-%hhx-%hhx-%hhx", &macaddr[0],
&macaddr[1], &macaddr[2], &macaddr[3], &macaddr[4],
&macaddr[5]);
else
printk(KERN_WARNING "Can not parse mac address: %s\n", buf);
}
#endif

View file

@ -63,6 +63,11 @@
# CN30XX Disable instruction prefetching
or v0, v0, 0x2000
skip:
# First clear off CvmCtl[IPPCI] bit and move the performance
# counters interrupt to IRQ 6
li v1, ~(7 << 7)
and v0, v0, v1
ori v0, v0, (6 << 7)
# Write the cavium control register
dmtc0 v0, CP0_CVMCTL_REG
sync

View file

@ -0,0 +1,63 @@
/*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 as published
* by the Free Software Foundation.
*
* Copyright (C) 2010 John Crispin <blogic@openwrt.org>
*/
#ifndef _LANTIQ_H__
#define _LANTIQ_H__
#include <linux/irq.h>
/* generic reg access functions */
#define ltq_r32(reg) __raw_readl(reg)
#define ltq_w32(val, reg) __raw_writel(val, reg)
#define ltq_w32_mask(clear, set, reg) \
ltq_w32((ltq_r32(reg) & ~(clear)) | (set), reg)
#define ltq_r8(reg) __raw_readb(reg)
#define ltq_w8(val, reg) __raw_writeb(val, reg)
/* register access macros for EBU and CGU */
#define ltq_ebu_w32(x, y) ltq_w32((x), ltq_ebu_membase + (y))
#define ltq_ebu_r32(x) ltq_r32(ltq_ebu_membase + (x))
#define ltq_cgu_w32(x, y) ltq_w32((x), ltq_cgu_membase + (y))
#define ltq_cgu_r32(x) ltq_r32(ltq_cgu_membase + (x))
extern __iomem void *ltq_ebu_membase;
extern __iomem void *ltq_cgu_membase;
extern unsigned int ltq_get_cpu_ver(void);
extern unsigned int ltq_get_soc_type(void);
/* clock speeds */
#define CLOCK_60M 60000000
#define CLOCK_83M 83333333
#define CLOCK_111M 111111111
#define CLOCK_133M 133333333
#define CLOCK_167M 166666667
#define CLOCK_200M 200000000
#define CLOCK_266M 266666666
#define CLOCK_333M 333333333
#define CLOCK_400M 400000000
/* spinlock all ebu i/o */
extern spinlock_t ebu_lock;
/* some irq helpers */
extern void ltq_disable_irq(struct irq_data *data);
extern void ltq_mask_and_ack_irq(struct irq_data *data);
extern void ltq_enable_irq(struct irq_data *data);
/* find out what caused the last cpu reset */
extern int ltq_reset_cause(void);
#define LTQ_RST_CAUSE_WDTRST 0x20
#define IOPORT_RESOURCE_START 0x10000000
#define IOPORT_RESOURCE_END 0xffffffff
#define IOMEM_RESOURCE_START 0x10000000
#define IOMEM_RESOURCE_END 0xffffffff
#define LTQ_FLASH_START 0x10000000
#define LTQ_FLASH_MAX 0x04000000
#endif

View file

@ -0,0 +1,53 @@
/*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 as published
* by the Free Software Foundation.
*
* Copyright (C) 2010 John Crispin <blogic@openwrt.org>
*/
#ifndef _LANTIQ_PLATFORM_H__
#define _LANTIQ_PLATFORM_H__
#include <linux/mtd/partitions.h>
#include <linux/socket.h>
/* struct used to pass info to the pci core */
enum {
PCI_CLOCK_INT = 0,
PCI_CLOCK_EXT
};
#define PCI_EXIN0 0x0001
#define PCI_EXIN1 0x0002
#define PCI_EXIN2 0x0004
#define PCI_EXIN3 0x0008
#define PCI_EXIN4 0x0010
#define PCI_EXIN5 0x0020
#define PCI_EXIN_MAX 6
#define PCI_GNT1 0x0040
#define PCI_GNT2 0x0080
#define PCI_GNT3 0x0100
#define PCI_GNT4 0x0200
#define PCI_REQ1 0x0400
#define PCI_REQ2 0x0800
#define PCI_REQ3 0x1000
#define PCI_REQ4 0x2000
#define PCI_REQ_SHIFT 10
#define PCI_REQ_MASK 0xf
struct ltq_pci_data {
int clock;
int gpio;
int irq[16];
};
/* struct used to pass info to network drivers */
struct ltq_eth_data {
struct sockaddr mac;
int mii_mode;
};
#endif

View file

@ -0,0 +1,24 @@
/*
* 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.
*
*/
#ifndef __ASM_MIPS_MACH_LANTIQ_WAR_H
#define __ASM_MIPS_MACH_LANTIQ_WAR_H
#define R4600_V1_INDEX_ICACHEOP_WAR 0
#define R4600_V1_HIT_CACHEOP_WAR 0
#define R4600_V2_HIT_CACHEOP_WAR 0
#define R5432_CP0_INTERRUPT_WAR 0
#define BCM1250_M3_WAR 0
#define SIBYTE_1956_WAR 0
#define MIPS4K_ICACHE_REFILL_WAR 0
#define MIPS_CACHE_SYNC_WAR 0
#define TX49XX_ICACHE_INDEX_INV_WAR 0
#define RM9000_CDEX_SMP_WAR 0
#define ICACHE_REFILLS_WORKAROUND_WAR 0
#define R10000_LLSC_WAR 0
#define MIPS34K_MISSED_ITLB_WAR 0
#endif

View file

@ -0,0 +1,18 @@
/*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 as published
* by the Free Software Foundation.
*
* Copyright (C) 2010 John Crispin <blogic@openwrt.org>
*/
#ifndef __LANTIQ_IRQ_H
#define __LANTIQ_IRQ_H
#include <lantiq_irq.h>
#define NR_IRQS 256
#include_next <irq.h>
#endif

View file

@ -0,0 +1,66 @@
/*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 as published
* by the Free Software Foundation.
*
* Copyright (C) 2010 John Crispin <blogic@openwrt.org>
*/
#ifndef _LANTIQ_XWAY_IRQ_H__
#define _LANTIQ_XWAY_IRQ_H__
#define INT_NUM_IRQ0 8
#define INT_NUM_IM0_IRL0 (INT_NUM_IRQ0 + 0)
#define INT_NUM_IM1_IRL0 (INT_NUM_IRQ0 + 32)
#define INT_NUM_IM2_IRL0 (INT_NUM_IRQ0 + 64)
#define INT_NUM_IM3_IRL0 (INT_NUM_IRQ0 + 96)
#define INT_NUM_IM4_IRL0 (INT_NUM_IRQ0 + 128)
#define INT_NUM_IM_OFFSET (INT_NUM_IM1_IRL0 - INT_NUM_IM0_IRL0)
#define LTQ_ASC_TIR(x) (INT_NUM_IM3_IRL0 + (x * 8))
#define LTQ_ASC_RIR(x) (INT_NUM_IM3_IRL0 + (x * 8) + 1)
#define LTQ_ASC_EIR(x) (INT_NUM_IM3_IRL0 + (x * 8) + 2)
#define LTQ_ASC_ASE_TIR INT_NUM_IM2_IRL0
#define LTQ_ASC_ASE_RIR (INT_NUM_IM2_IRL0 + 2)
#define LTQ_ASC_ASE_EIR (INT_NUM_IM2_IRL0 + 3)
#define LTQ_SSC_TIR (INT_NUM_IM0_IRL0 + 15)
#define LTQ_SSC_RIR (INT_NUM_IM0_IRL0 + 14)
#define LTQ_SSC_EIR (INT_NUM_IM0_IRL0 + 16)
#define LTQ_MEI_DYING_GASP_INT (INT_NUM_IM1_IRL0 + 21)
#define LTQ_MEI_INT (INT_NUM_IM1_IRL0 + 23)
#define LTQ_TIMER6_INT (INT_NUM_IM1_IRL0 + 23)
#define LTQ_USB_INT (INT_NUM_IM1_IRL0 + 22)
#define LTQ_USB_OC_INT (INT_NUM_IM4_IRL0 + 23)
#define MIPS_CPU_TIMER_IRQ 7
#define LTQ_DMA_CH0_INT (INT_NUM_IM2_IRL0)
#define LTQ_DMA_CH1_INT (INT_NUM_IM2_IRL0 + 1)
#define LTQ_DMA_CH2_INT (INT_NUM_IM2_IRL0 + 2)
#define LTQ_DMA_CH3_INT (INT_NUM_IM2_IRL0 + 3)
#define LTQ_DMA_CH4_INT (INT_NUM_IM2_IRL0 + 4)
#define LTQ_DMA_CH5_INT (INT_NUM_IM2_IRL0 + 5)
#define LTQ_DMA_CH6_INT (INT_NUM_IM2_IRL0 + 6)
#define LTQ_DMA_CH7_INT (INT_NUM_IM2_IRL0 + 7)
#define LTQ_DMA_CH8_INT (INT_NUM_IM2_IRL0 + 8)
#define LTQ_DMA_CH9_INT (INT_NUM_IM2_IRL0 + 9)
#define LTQ_DMA_CH10_INT (INT_NUM_IM2_IRL0 + 10)
#define LTQ_DMA_CH11_INT (INT_NUM_IM2_IRL0 + 11)
#define LTQ_DMA_CH12_INT (INT_NUM_IM2_IRL0 + 25)
#define LTQ_DMA_CH13_INT (INT_NUM_IM2_IRL0 + 26)
#define LTQ_DMA_CH14_INT (INT_NUM_IM2_IRL0 + 27)
#define LTQ_DMA_CH15_INT (INT_NUM_IM2_IRL0 + 28)
#define LTQ_DMA_CH16_INT (INT_NUM_IM2_IRL0 + 29)
#define LTQ_DMA_CH17_INT (INT_NUM_IM2_IRL0 + 30)
#define LTQ_DMA_CH18_INT (INT_NUM_IM2_IRL0 + 16)
#define LTQ_DMA_CH19_INT (INT_NUM_IM2_IRL0 + 21)
#define LTQ_PPE_MBOX_INT (INT_NUM_IM2_IRL0 + 24)
#define INT_NUM_IM4_IRL14 (INT_NUM_IM4_IRL0 + 14)
#endif

View file

@ -0,0 +1,141 @@
/*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 as published
* by the Free Software Foundation.
*
* Copyright (C) 2010 John Crispin <blogic@openwrt.org>
*/
#ifndef _LTQ_XWAY_H__
#define _LTQ_XWAY_H__
#ifdef CONFIG_SOC_TYPE_XWAY
#include <lantiq.h>
/* Chip IDs */
#define SOC_ID_DANUBE1 0x129
#define SOC_ID_DANUBE2 0x12B
#define SOC_ID_TWINPASS 0x12D
#define SOC_ID_AMAZON_SE 0x152
#define SOC_ID_ARX188 0x16C
#define SOC_ID_ARX168 0x16D
#define SOC_ID_ARX182 0x16F
/* SoC Types */
#define SOC_TYPE_DANUBE 0x01
#define SOC_TYPE_TWINPASS 0x02
#define SOC_TYPE_AR9 0x03
#define SOC_TYPE_VR9 0x04
#define SOC_TYPE_AMAZON_SE 0x05
/* ASC0/1 - serial port */
#define LTQ_ASC0_BASE_ADDR 0x1E100400
#define LTQ_ASC1_BASE_ADDR 0x1E100C00
#define LTQ_ASC_SIZE 0x400
/* RCU - reset control unit */
#define LTQ_RCU_BASE_ADDR 0x1F203000
#define LTQ_RCU_SIZE 0x1000
/* GPTU - general purpose timer unit */
#define LTQ_GPTU_BASE_ADDR 0x18000300
#define LTQ_GPTU_SIZE 0x100
/* EBU - external bus unit */
#define LTQ_EBU_GPIO_START 0x14000000
#define LTQ_EBU_GPIO_SIZE 0x1000
#define LTQ_EBU_BASE_ADDR 0x1E105300
#define LTQ_EBU_SIZE 0x100
#define LTQ_EBU_BUSCON0 0x0060
#define LTQ_EBU_PCC_CON 0x0090
#define LTQ_EBU_PCC_IEN 0x00A4
#define LTQ_EBU_PCC_ISTAT 0x00A0
#define LTQ_EBU_BUSCON1 0x0064
#define LTQ_EBU_ADDRSEL1 0x0024
#define EBU_WRDIS 0x80000000
/* CGU - clock generation unit */
#define LTQ_CGU_BASE_ADDR 0x1F103000
#define LTQ_CGU_SIZE 0x1000
/* ICU - interrupt control unit */
#define LTQ_ICU_BASE_ADDR 0x1F880200
#define LTQ_ICU_SIZE 0x100
/* EIU - external interrupt unit */
#define LTQ_EIU_BASE_ADDR 0x1F101000
#define LTQ_EIU_SIZE 0x1000
/* PMU - power management unit */
#define LTQ_PMU_BASE_ADDR 0x1F102000
#define LTQ_PMU_SIZE 0x1000
#define PMU_DMA 0x0020
#define PMU_USB 0x8041
#define PMU_LED 0x0800
#define PMU_GPT 0x1000
#define PMU_PPE 0x2000
#define PMU_FPI 0x4000
#define PMU_SWITCH 0x10000000
/* ETOP - ethernet */
#define LTQ_ETOP_BASE_ADDR 0x1E180000
#define LTQ_ETOP_SIZE 0x40000
/* DMA */
#define LTQ_DMA_BASE_ADDR 0x1E104100
#define LTQ_DMA_SIZE 0x800
/* PCI */
#define PCI_CR_BASE_ADDR 0x1E105400
#define PCI_CR_SIZE 0x400
/* WDT */
#define LTQ_WDT_BASE_ADDR 0x1F8803F0
#define LTQ_WDT_SIZE 0x10
/* STP - serial to parallel conversion unit */
#define LTQ_STP_BASE_ADDR 0x1E100BB0
#define LTQ_STP_SIZE 0x40
/* GPIO */
#define LTQ_GPIO0_BASE_ADDR 0x1E100B10
#define LTQ_GPIO1_BASE_ADDR 0x1E100B40
#define LTQ_GPIO2_BASE_ADDR 0x1E100B70
#define LTQ_GPIO_SIZE 0x30
/* SSC */
#define LTQ_SSC_BASE_ADDR 0x1e100800
#define LTQ_SSC_SIZE 0x100
/* MEI - dsl core */
#define LTQ_MEI_BASE_ADDR 0x1E116000
/* DEU - data encryption unit */
#define LTQ_DEU_BASE_ADDR 0x1E103100
/* MPS - multi processor unit (voice) */
#define LTQ_MPS_BASE_ADDR (KSEG1 + 0x1F107000)
#define LTQ_MPS_CHIPID ((u32 *)(LTQ_MPS_BASE_ADDR + 0x0344))
/* request a non-gpio and set the PIO config */
extern int ltq_gpio_request(unsigned int pin, unsigned int alt0,
unsigned int alt1, unsigned int dir, const char *name);
extern void ltq_pmu_enable(unsigned int module);
extern void ltq_pmu_disable(unsigned int module);
static inline int ltq_is_ar9(void)
{
return (ltq_get_soc_type() == SOC_TYPE_AR9);
}
static inline int ltq_is_vr9(void)
{
return (ltq_get_soc_type() == SOC_TYPE_VR9);
}
#endif /* CONFIG_SOC_TYPE_XWAY */
#endif /* _LTQ_XWAY_H__ */

View file

@ -0,0 +1,60 @@
/*
* 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.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
*
* Copyright (C) 2011 John Crispin <blogic@openwrt.org>
*/
#ifndef LTQ_DMA_H__
#define LTQ_DMA_H__
#define LTQ_DESC_SIZE 0x08 /* each descriptor is 64bit */
#define LTQ_DESC_NUM 0x40 /* 64 descriptors / channel */
#define LTQ_DMA_OWN BIT(31) /* owner bit */
#define LTQ_DMA_C BIT(30) /* complete bit */
#define LTQ_DMA_SOP BIT(29) /* start of packet */
#define LTQ_DMA_EOP BIT(28) /* end of packet */
#define LTQ_DMA_TX_OFFSET(x) ((x & 0x1f) << 23) /* data bytes offset */
#define LTQ_DMA_RX_OFFSET(x) ((x & 0x7) << 23) /* data bytes offset */
#define LTQ_DMA_SIZE_MASK (0xffff) /* the size field is 16 bit */
struct ltq_dma_desc {
u32 ctl;
u32 addr;
};
struct ltq_dma_channel {
int nr; /* the channel number */
int irq; /* the mapped irq */
int desc; /* the current descriptor */
struct ltq_dma_desc *desc_base; /* the descriptor base */
int phys; /* physical addr */
};
enum {
DMA_PORT_ETOP = 0,
DMA_PORT_DEU,
};
extern void ltq_dma_enable_irq(struct ltq_dma_channel *ch);
extern void ltq_dma_disable_irq(struct ltq_dma_channel *ch);
extern void ltq_dma_ack_irq(struct ltq_dma_channel *ch);
extern void ltq_dma_open(struct ltq_dma_channel *ch);
extern void ltq_dma_close(struct ltq_dma_channel *ch);
extern void ltq_dma_alloc_tx(struct ltq_dma_channel *ch);
extern void ltq_dma_alloc_rx(struct ltq_dma_channel *ch);
extern void ltq_dma_free(struct ltq_dma_channel *ch);
extern void ltq_dma_init_port(int p);
#endif

View file

@ -0,0 +1,47 @@
/*
* 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) 2011 Netlogic Microsystems
* Copyright (C) 2003 Ralf Baechle
*/
#ifndef __ASM_MACH_NETLOGIC_CPU_FEATURE_OVERRIDES_H
#define __ASM_MACH_NETLOGIC_CPU_FEATURE_OVERRIDES_H
#define cpu_has_4kex 1
#define cpu_has_4k_cache 1
#define cpu_has_watch 1
#define cpu_has_mips16 0
#define cpu_has_counter 1
#define cpu_has_divec 1
#define cpu_has_vce 0
#define cpu_has_cache_cdex_p 0
#define cpu_has_cache_cdex_s 0
#define cpu_has_prefetch 1
#define cpu_has_mcheck 1
#define cpu_has_ejtag 1
#define cpu_has_llsc 1
#define cpu_has_vtag_icache 0
#define cpu_has_dc_aliases 0
#define cpu_has_ic_fills_f_dc 0
#define cpu_has_dsp 0
#define cpu_has_mipsmt 0
#define cpu_has_userlocal 0
#define cpu_icache_snoops_remote_store 0
#define cpu_has_nofpuex 0
#define cpu_has_64bits 1
#define cpu_has_mips32r1 1
#define cpu_has_mips32r2 0
#define cpu_has_mips64r1 1
#define cpu_has_mips64r2 0
#define cpu_has_inclusive_pcaches 0
#define cpu_dcache_line_size() 32
#define cpu_icache_line_size() 32
#endif /* __ASM_MACH_NETLOGIC_CPU_FEATURE_OVERRIDES_H */

View file

@ -0,0 +1,14 @@
/*
* 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) 2011 Netlogic Microsystems.
*/
#ifndef __ASM_NETLOGIC_IRQ_H
#define __ASM_NETLOGIC_IRQ_H
#define NR_IRQS 64
#define MIPS_CPU_IRQ_BASE 0
#endif /* __ASM_NETLOGIC_IRQ_H */

View file

@ -0,0 +1,26 @@
/*
* 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) 2011 Netlogic Microsystems.
* Copyright (C) 2002, 2004, 2007 by Ralf Baechle <ralf@linux-mips.org>
*/
#ifndef __ASM_MIPS_MACH_NLM_WAR_H
#define __ASM_MIPS_MACH_NLM_WAR_H
#define R4600_V1_INDEX_ICACHEOP_WAR 0
#define R4600_V1_HIT_CACHEOP_WAR 0
#define R4600_V2_HIT_CACHEOP_WAR 0
#define R5432_CP0_INTERRUPT_WAR 0
#define BCM1250_M3_WAR 0
#define SIBYTE_1956_WAR 0
#define MIPS4K_ICACHE_REFILL_WAR 0
#define MIPS_CACHE_SYNC_WAR 0
#define TX49XX_ICACHE_INDEX_INV_WAR 0
#define RM9000_CDEX_SMP_WAR 0
#define ICACHE_REFILLS_WORKAROUND_WAR 0
#define R10000_LLSC_WAR 0
#define MIPS34K_MISSED_ITLB_WAR 0
#endif /* __ASM_MIPS_MACH_NLM_WAR_H */

View file

@ -118,6 +118,8 @@ search_module_dbetables(unsigned long addr)
#define MODULE_PROC_FAMILY "LOONGSON2 "
#elif defined CONFIG_CPU_CAVIUM_OCTEON
#define MODULE_PROC_FAMILY "OCTEON "
#elif defined CONFIG_CPU_XLR
#define MODULE_PROC_FAMILY "XLR "
#else
#error MODULE_PROC_FAMILY undefined for your processor configuration
#endif

View file

@ -0,0 +1,45 @@
/*
* Copyright 2003-2011 NetLogic Microsystems, Inc. (NetLogic). All rights
* reserved.
*
* This software is available to you under a choice of one of two
* licenses. You may choose to be licensed under the terms of the GNU
* General Public License (GPL) Version 2, available from the file
* COPYING in the main directory of this source tree, or the NetLogic
* license below:
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* THIS SOFTWARE IS PROVIDED BY NETLOGIC ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL NETLOGIC OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _ASM_NLM_INTERRUPT_H
#define _ASM_NLM_INTERRUPT_H
/* Defines for the IRQ numbers */
#define IRQ_IPI_SMP_FUNCTION 3
#define IRQ_IPI_SMP_RESCHEDULE 4
#define IRQ_MSGRING 6
#define IRQ_TIMER 7
#endif

View file

@ -0,0 +1,76 @@
/*
* Copyright 2003-2011 NetLogic Microsystems, Inc. (NetLogic). All rights
* reserved.
*
* This software is available to you under a choice of one of two
* licenses. You may choose to be licensed under the terms of the GNU
* General Public License (GPL) Version 2, available from the file
* COPYING in the main directory of this source tree, or the NetLogic
* license below:
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* THIS SOFTWARE IS PROVIDED BY NETLOGIC ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL NETLOGIC OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _ASM_NLM_MIPS_EXTS_H
#define _ASM_NLM_MIPS_EXTS_H
/*
* XLR and XLP interrupt request and interrupt mask registers
*/
#define read_c0_eirr() __read_64bit_c0_register($9, 6)
#define read_c0_eimr() __read_64bit_c0_register($9, 7)
#define write_c0_eirr(val) __write_64bit_c0_register($9, 6, val)
/*
* Writing EIMR in 32 bit is a special case, the lower 8 bit of the
* EIMR is shadowed in the status register, so we cannot save and
* restore status register for split read.
*/
#define write_c0_eimr(val) \
do { \
if (sizeof(unsigned long) == 4) { \
unsigned long __flags; \
\
local_irq_save(__flags); \
__asm__ __volatile__( \
".set\tmips64\n\t" \
"dsll\t%L0, %L0, 32\n\t" \
"dsrl\t%L0, %L0, 32\n\t" \
"dsll\t%M0, %M0, 32\n\t" \
"or\t%L0, %L0, %M0\n\t" \
"dmtc0\t%L0, $9, 7\n\t" \
".set\tmips0" \
: : "r" (val)); \
__flags = (__flags & 0xffff00ff) | (((val) & 0xff) << 8);\
local_irq_restore(__flags); \
} else \
__write_64bit_c0_register($9, 7, (val)); \
} while (0)
static inline int hard_smp_processor_id(void)
{
return __read_32bit_c0_register($15, 1) & 0x3ff;
}
#endif /*_ASM_NLM_MIPS_EXTS_H */

View file

@ -0,0 +1,109 @@
/*
* Copyright 2003-2011 NetLogic Microsystems, Inc. (NetLogic). All rights
* reserved.
*
* This software is available to you under a choice of one of two
* licenses. You may choose to be licensed under the terms of the GNU
* General Public License (GPL) Version 2, available from the file
* COPYING in the main directory of this source tree, or the NetLogic
* license below:
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* THIS SOFTWARE IS PROVIDED BY NETLOGIC ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL NETLOGIC OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _ASM_NETLOGIC_BOOTINFO_H
#define _ASM_NETLOGIC_BOOTINFO_H
struct psb_info {
uint64_t boot_level;
uint64_t io_base;
uint64_t output_device;
uint64_t uart_print;
uint64_t led_output;
uint64_t init;
uint64_t exit;
uint64_t warm_reset;
uint64_t wakeup;
uint64_t online_cpu_map;
uint64_t master_reentry_sp;
uint64_t master_reentry_gp;
uint64_t master_reentry_fn;
uint64_t slave_reentry_fn;
uint64_t magic_dword;
uint64_t uart_putchar;
uint64_t size;
uint64_t uart_getchar;
uint64_t nmi_handler;
uint64_t psb_version;
uint64_t mac_addr;
uint64_t cpu_frequency;
uint64_t board_version;
uint64_t malloc;
uint64_t free;
uint64_t global_shmem_addr;
uint64_t global_shmem_size;
uint64_t psb_os_cpu_map;
uint64_t userapp_cpu_map;
uint64_t wakeup_os;
uint64_t psb_mem_map;
uint64_t board_major_version;
uint64_t board_minor_version;
uint64_t board_manf_revision;
uint64_t board_serial_number;
uint64_t psb_physaddr_map;
uint64_t xlr_loaderip_config;
uint64_t bldr_envp;
uint64_t avail_mem_map;
};
enum {
NETLOGIC_IO_SPACE = 0x10,
PCIX_IO_SPACE,
PCIX_CFG_SPACE,
PCIX_MEMORY_SPACE,
HT_IO_SPACE,
HT_CFG_SPACE,
HT_MEMORY_SPACE,
SRAM_SPACE,
FLASH_CONTROLLER_SPACE
};
#define NLM_MAX_ARGS 64
#define NLM_MAX_ENVS 32
/* This is what netlboot passes and linux boot_mem_map is subtly different */
#define NLM_BOOT_MEM_MAP_MAX 32
struct nlm_boot_mem_map {
int nr_map;
struct nlm_boot_mem_map_entry {
uint64_t addr; /* start of memory segment */
uint64_t size; /* size of memory segment */
uint32_t type; /* type of memory segment */
} map[NLM_BOOT_MEM_MAP_MAX];
};
/* Pointer to saved boot loader info */
extern struct psb_info nlm_prom_info;
#endif

View file

@ -0,0 +1,73 @@
/*
* Copyright 2003-2011 NetLogic Microsystems, Inc. (NetLogic). All rights
* reserved.
*
* This software is available to you under a choice of one of two
* licenses. You may choose to be licensed under the terms of the GNU
* General Public License (GPL) Version 2, available from the file
* COPYING in the main directory of this source tree, or the NetLogic
* license below:
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* THIS SOFTWARE IS PROVIDED BY NETLOGIC ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL NETLOGIC OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _ASM_NLM_GPIO_H
#define _ASM_NLM_GPIO_H
#define NETLOGIC_GPIO_INT_EN_REG 0
#define NETLOGIC_GPIO_INPUT_INVERSION_REG 1
#define NETLOGIC_GPIO_IO_DIR_REG 2
#define NETLOGIC_GPIO_IO_DATA_WR_REG 3
#define NETLOGIC_GPIO_IO_DATA_RD_REG 4
#define NETLOGIC_GPIO_SWRESET_REG 8
#define NETLOGIC_GPIO_DRAM1_CNTRL_REG 9
#define NETLOGIC_GPIO_DRAM1_RATIO_REG 10
#define NETLOGIC_GPIO_DRAM1_RESET_REG 11
#define NETLOGIC_GPIO_DRAM1_STATUS_REG 12
#define NETLOGIC_GPIO_DRAM2_CNTRL_REG 13
#define NETLOGIC_GPIO_DRAM2_RATIO_REG 14
#define NETLOGIC_GPIO_DRAM2_RESET_REG 15
#define NETLOGIC_GPIO_DRAM2_STATUS_REG 16
#define NETLOGIC_GPIO_PWRON_RESET_CFG_REG 21
#define NETLOGIC_GPIO_BIST_ALL_GO_STATUS_REG 24
#define NETLOGIC_GPIO_BIST_CPU_GO_STATUS_REG 25
#define NETLOGIC_GPIO_BIST_DEV_GO_STATUS_REG 26
#define NETLOGIC_GPIO_FUSE_BANK_REG 35
#define NETLOGIC_GPIO_CPU_RESET_REG 40
#define NETLOGIC_GPIO_RNG_REG 43
#define NETLOGIC_PWRON_RESET_PCMCIA_BOOT 17
#define NETLOGIC_GPIO_LED_BITMAP 0x1700000
#define NETLOGIC_GPIO_LED_0_SHIFT 20
#define NETLOGIC_GPIO_LED_1_SHIFT 24
#define NETLOGIC_GPIO_LED_OUTPUT_CODE_RESET 0x01
#define NETLOGIC_GPIO_LED_OUTPUT_CODE_HARD_RESET 0x02
#define NETLOGIC_GPIO_LED_OUTPUT_CODE_SOFT_RESET 0x03
#define NETLOGIC_GPIO_LED_OUTPUT_CODE_MAIN 0x04
#endif

View file

@ -0,0 +1,131 @@
/*
* Copyright 2003-2011 NetLogic Microsystems, Inc. (NetLogic). All rights
* reserved.
*
* This software is available to you under a choice of one of two
* licenses. You may choose to be licensed under the terms of the GNU
* General Public License (GPL) Version 2, available from the file
* COPYING in the main directory of this source tree, or the NetLogic
* license below:
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* THIS SOFTWARE IS PROVIDED BY NETLOGIC ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL NETLOGIC OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _ASM_NLM_IOMAP_H
#define _ASM_NLM_IOMAP_H
#define DEFAULT_NETLOGIC_IO_BASE CKSEG1ADDR(0x1ef00000)
#define NETLOGIC_IO_DDR2_CHN0_OFFSET 0x01000
#define NETLOGIC_IO_DDR2_CHN1_OFFSET 0x02000
#define NETLOGIC_IO_DDR2_CHN2_OFFSET 0x03000
#define NETLOGIC_IO_DDR2_CHN3_OFFSET 0x04000
#define NETLOGIC_IO_PIC_OFFSET 0x08000
#define NETLOGIC_IO_UART_0_OFFSET 0x14000
#define NETLOGIC_IO_UART_1_OFFSET 0x15100
#define NETLOGIC_IO_SIZE 0x1000
#define NETLOGIC_IO_BRIDGE_OFFSET 0x00000
#define NETLOGIC_IO_RLD2_CHN0_OFFSET 0x05000
#define NETLOGIC_IO_RLD2_CHN1_OFFSET 0x06000
#define NETLOGIC_IO_SRAM_OFFSET 0x07000
#define NETLOGIC_IO_PCIX_OFFSET 0x09000
#define NETLOGIC_IO_HT_OFFSET 0x0A000
#define NETLOGIC_IO_SECURITY_OFFSET 0x0B000
#define NETLOGIC_IO_GMAC_0_OFFSET 0x0C000
#define NETLOGIC_IO_GMAC_1_OFFSET 0x0D000
#define NETLOGIC_IO_GMAC_2_OFFSET 0x0E000
#define NETLOGIC_IO_GMAC_3_OFFSET 0x0F000
/* XLS devices */
#define NETLOGIC_IO_GMAC_4_OFFSET 0x20000
#define NETLOGIC_IO_GMAC_5_OFFSET 0x21000
#define NETLOGIC_IO_GMAC_6_OFFSET 0x22000
#define NETLOGIC_IO_GMAC_7_OFFSET 0x23000
#define NETLOGIC_IO_PCIE_0_OFFSET 0x1E000
#define NETLOGIC_IO_PCIE_1_OFFSET 0x1F000
#define NETLOGIC_IO_SRIO_0_OFFSET 0x1E000
#define NETLOGIC_IO_SRIO_1_OFFSET 0x1F000
#define NETLOGIC_IO_USB_0_OFFSET 0x24000
#define NETLOGIC_IO_USB_1_OFFSET 0x25000
#define NETLOGIC_IO_COMP_OFFSET 0x1D000
/* end XLS devices */
/* XLR devices */
#define NETLOGIC_IO_SPI4_0_OFFSET 0x10000
#define NETLOGIC_IO_XGMAC_0_OFFSET 0x11000
#define NETLOGIC_IO_SPI4_1_OFFSET 0x12000
#define NETLOGIC_IO_XGMAC_1_OFFSET 0x13000
/* end XLR devices */
#define NETLOGIC_IO_I2C_0_OFFSET 0x16000
#define NETLOGIC_IO_I2C_1_OFFSET 0x17000
#define NETLOGIC_IO_GPIO_OFFSET 0x18000
#define NETLOGIC_IO_FLASH_OFFSET 0x19000
#define NETLOGIC_IO_TB_OFFSET 0x1C000
#define NETLOGIC_CPLD_OFFSET KSEG1ADDR(0x1d840000)
/*
* Base Address (Virtual) of the PCI Config address space
* For now, choose 256M phys in kseg1 = 0xA0000000 + (1<<28)
* Config space spans 256 (num of buses) * 256 (num functions) * 256 bytes
* ie 1<<24 = 16M
*/
#define DEFAULT_PCI_CONFIG_BASE 0x18000000
#define DEFAULT_HT_TYPE0_CFG_BASE 0x16000000
#define DEFAULT_HT_TYPE1_CFG_BASE 0x17000000
#ifndef __ASSEMBLY__
#include <linux/types.h>
#include <asm/byteorder.h>
typedef volatile __u32 nlm_reg_t;
extern unsigned long netlogic_io_base;
/* FIXME read once in write_reg */
#ifdef CONFIG_CPU_LITTLE_ENDIAN
#define netlogic_read_reg(base, offset) ((base)[(offset)])
#define netlogic_write_reg(base, offset, value) ((base)[(offset)] = (value))
#else
#define netlogic_read_reg(base, offset) (be32_to_cpu((base)[(offset)]))
#define netlogic_write_reg(base, offset, value) \
((base)[(offset)] = cpu_to_be32((value)))
#endif
#define netlogic_read_reg_le32(base, offset) (le32_to_cpu((base)[(offset)]))
#define netlogic_write_reg_le32(base, offset, value) \
((base)[(offset)] = cpu_to_le32((value)))
#define netlogic_io_mmio(offset) ((nlm_reg_t *)(netlogic_io_base+(offset)))
#endif /* __ASSEMBLY__ */
#endif

View file

@ -0,0 +1,231 @@
/*
* Copyright 2003-2011 NetLogic Microsystems, Inc. (NetLogic). All rights
* reserved.
*
* This software is available to you under a choice of one of two
* licenses. You may choose to be licensed under the terms of the GNU
* General Public License (GPL) Version 2, available from the file
* COPYING in the main directory of this source tree, or the NetLogic
* license below:
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* THIS SOFTWARE IS PROVIDED BY NETLOGIC ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL NETLOGIC OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _ASM_NLM_XLR_PIC_H
#define _ASM_NLM_XLR_PIC_H
#define PIC_CLKS_PER_SEC 66666666ULL
/* PIC hardware interrupt numbers */
#define PIC_IRT_WD_INDEX 0
#define PIC_IRT_TIMER_0_INDEX 1
#define PIC_IRT_TIMER_1_INDEX 2
#define PIC_IRT_TIMER_2_INDEX 3
#define PIC_IRT_TIMER_3_INDEX 4
#define PIC_IRT_TIMER_4_INDEX 5
#define PIC_IRT_TIMER_5_INDEX 6
#define PIC_IRT_TIMER_6_INDEX 7
#define PIC_IRT_TIMER_7_INDEX 8
#define PIC_IRT_CLOCK_INDEX PIC_IRT_TIMER_7_INDEX
#define PIC_IRT_UART_0_INDEX 9
#define PIC_IRT_UART_1_INDEX 10
#define PIC_IRT_I2C_0_INDEX 11
#define PIC_IRT_I2C_1_INDEX 12
#define PIC_IRT_PCMCIA_INDEX 13
#define PIC_IRT_GPIO_INDEX 14
#define PIC_IRT_HYPER_INDEX 15
#define PIC_IRT_PCIX_INDEX 16
/* XLS */
#define PIC_IRT_CDE_INDEX 15
#define PIC_IRT_BRIDGE_TB_XLS_INDEX 16
/* XLS */
#define PIC_IRT_GMAC0_INDEX 17
#define PIC_IRT_GMAC1_INDEX 18
#define PIC_IRT_GMAC2_INDEX 19
#define PIC_IRT_GMAC3_INDEX 20
#define PIC_IRT_XGS0_INDEX 21
#define PIC_IRT_XGS1_INDEX 22
#define PIC_IRT_HYPER_FATAL_INDEX 23
#define PIC_IRT_PCIX_FATAL_INDEX 24
#define PIC_IRT_BRIDGE_AERR_INDEX 25
#define PIC_IRT_BRIDGE_BERR_INDEX 26
#define PIC_IRT_BRIDGE_TB_XLR_INDEX 27
#define PIC_IRT_BRIDGE_AERR_NMI_INDEX 28
/* XLS */
#define PIC_IRT_GMAC4_INDEX 21
#define PIC_IRT_GMAC5_INDEX 22
#define PIC_IRT_GMAC6_INDEX 23
#define PIC_IRT_GMAC7_INDEX 24
#define PIC_IRT_BRIDGE_ERR_INDEX 25
#define PIC_IRT_PCIE_LINK0_INDEX 26
#define PIC_IRT_PCIE_LINK1_INDEX 27
#define PIC_IRT_PCIE_LINK2_INDEX 23
#define PIC_IRT_PCIE_LINK3_INDEX 24
#define PIC_IRT_PCIE_XLSB0_LINK2_INDEX 28
#define PIC_IRT_PCIE_XLSB0_LINK3_INDEX 29
#define PIC_IRT_SRIO_LINK0_INDEX 26
#define PIC_IRT_SRIO_LINK1_INDEX 27
#define PIC_IRT_SRIO_LINK2_INDEX 28
#define PIC_IRT_SRIO_LINK3_INDEX 29
#define PIC_IRT_PCIE_INT_INDEX 28
#define PIC_IRT_PCIE_FATAL_INDEX 29
#define PIC_IRT_GPIO_B_INDEX 30
#define PIC_IRT_USB_INDEX 31
/* XLS */
#define PIC_NUM_IRTS 32
#define PIC_CLOCK_TIMER 7
/* PIC Registers */
#define PIC_CTRL 0x00
#define PIC_IPI 0x04
#define PIC_INT_ACK 0x06
#define WD_MAX_VAL_0 0x08
#define WD_MAX_VAL_1 0x09
#define WD_MASK_0 0x0a
#define WD_MASK_1 0x0b
#define WD_HEARBEAT_0 0x0c
#define WD_HEARBEAT_1 0x0d
#define PIC_IRT_0_BASE 0x40
#define PIC_IRT_1_BASE 0x80
#define PIC_TIMER_MAXVAL_0_BASE 0x100
#define PIC_TIMER_MAXVAL_1_BASE 0x110
#define PIC_TIMER_COUNT_0_BASE 0x120
#define PIC_TIMER_COUNT_1_BASE 0x130
#define PIC_IRT_0(picintr) (PIC_IRT_0_BASE + (picintr))
#define PIC_IRT_1(picintr) (PIC_IRT_1_BASE + (picintr))
#define PIC_TIMER_MAXVAL_0(i) (PIC_TIMER_MAXVAL_0_BASE + (i))
#define PIC_TIMER_MAXVAL_1(i) (PIC_TIMER_MAXVAL_1_BASE + (i))
#define PIC_TIMER_COUNT_0(i) (PIC_TIMER_COUNT_0_BASE + (i))
#define PIC_TIMER_COUNT_1(i) (PIC_TIMER_COUNT_0_BASE + (i))
/*
* Mapping between hardware interrupt numbers and IRQs on CPU
* we use a simple scheme to map PIC interrupts 0-31 to IRQs
* 8-39. This leaves the IRQ 0-7 for cpu interrupts like
* count/compare and FMN
*/
#define PIC_IRQ_BASE 8
#define PIC_INTR_TO_IRQ(i) (PIC_IRQ_BASE + (i))
#define PIC_IRQ_TO_INTR(i) ((i) - PIC_IRQ_BASE)
#define PIC_IRT_FIRST_IRQ PIC_IRQ_BASE
#define PIC_WD_IRQ PIC_INTR_TO_IRQ(PIC_IRT_WD_INDEX)
#define PIC_TIMER_0_IRQ PIC_INTR_TO_IRQ(PIC_IRT_TIMER_0_INDEX)
#define PIC_TIMER_1_IRQ PIC_INTR_TO_IRQ(PIC_IRT_TIMER_1_INDEX)
#define PIC_TIMER_2_IRQ PIC_INTR_TO_IRQ(PIC_IRT_TIMER_2_INDEX)
#define PIC_TIMER_3_IRQ PIC_INTR_TO_IRQ(PIC_IRT_TIMER_3_INDEX)
#define PIC_TIMER_4_IRQ PIC_INTR_TO_IRQ(PIC_IRT_TIMER_4_INDEX)
#define PIC_TIMER_5_IRQ PIC_INTR_TO_IRQ(PIC_IRT_TIMER_5_INDEX)
#define PIC_TIMER_6_IRQ PIC_INTR_TO_IRQ(PIC_IRT_TIMER_6_INDEX)
#define PIC_TIMER_7_IRQ PIC_INTR_TO_IRQ(PIC_IRT_TIMER_7_INDEX)
#define PIC_CLOCK_IRQ (PIC_TIMER_7_IRQ)
#define PIC_UART_0_IRQ PIC_INTR_TO_IRQ(PIC_IRT_UART_0_INDEX)
#define PIC_UART_1_IRQ PIC_INTR_TO_IRQ(PIC_IRT_UART_1_INDEX)
#define PIC_I2C_0_IRQ PIC_INTR_TO_IRQ(PIC_IRT_I2C_0_INDEX)
#define PIC_I2C_1_IRQ PIC_INTR_TO_IRQ(PIC_IRT_I2C_1_INDEX)
#define PIC_PCMCIA_IRQ PIC_INTR_TO_IRQ(PIC_IRT_PCMCIA_INDEX)
#define PIC_GPIO_IRQ PIC_INTR_TO_IRQ(PIC_IRT_GPIO_INDEX)
#define PIC_HYPER_IRQ PIC_INTR_TO_IRQ(PIC_IRT_HYPER_INDEX)
#define PIC_PCIX_IRQ PIC_INTR_TO_IRQ(PIC_IRT_PCIX_INDEX)
/* XLS */
#define PIC_CDE_IRQ PIC_INTR_TO_IRQ(PIC_IRT_CDE_INDEX)
#define PIC_BRIDGE_TB_XLS_IRQ PIC_INTR_TO_IRQ(PIC_IRT_BRIDGE_TB_XLS_INDEX)
/* end XLS */
#define PIC_GMAC_0_IRQ PIC_INTR_TO_IRQ(PIC_IRT_GMAC0_INDEX)
#define PIC_GMAC_1_IRQ PIC_INTR_TO_IRQ(PIC_IRT_GMAC1_INDEX)
#define PIC_GMAC_2_IRQ PIC_INTR_TO_IRQ(PIC_IRT_GMAC2_INDEX)
#define PIC_GMAC_3_IRQ PIC_INTR_TO_IRQ(PIC_IRT_GMAC3_INDEX)
#define PIC_XGS_0_IRQ PIC_INTR_TO_IRQ(PIC_IRT_XGS0_INDEX)
#define PIC_XGS_1_IRQ PIC_INTR_TO_IRQ(PIC_IRT_XGS1_INDEX)
#define PIC_HYPER_FATAL_IRQ PIC_INTR_TO_IRQ(PIC_IRT_HYPER_FATAL_INDEX)
#define PIC_PCIX_FATAL_IRQ PIC_INTR_TO_IRQ(PIC_IRT_PCIX_FATAL_INDEX)
#define PIC_BRIDGE_AERR_IRQ PIC_INTR_TO_IRQ(PIC_IRT_BRIDGE_AERR_INDEX)
#define PIC_BRIDGE_BERR_IRQ PIC_INTR_TO_IRQ(PIC_IRT_BRIDGE_BERR_INDEX)
#define PIC_BRIDGE_TB_XLR_IRQ PIC_INTR_TO_IRQ(PIC_IRT_BRIDGE_TB_XLR_INDEX)
#define PIC_BRIDGE_AERR_NMI_IRQ PIC_INTR_TO_IRQ(PIC_IRT_BRIDGE_AERR_NMI_INDEX)
/* XLS defines */
#define PIC_GMAC_4_IRQ PIC_INTR_TO_IRQ(PIC_IRT_GMAC4_INDEX)
#define PIC_GMAC_5_IRQ PIC_INTR_TO_IRQ(PIC_IRT_GMAC5_INDEX)
#define PIC_GMAC_6_IRQ PIC_INTR_TO_IRQ(PIC_IRT_GMAC6_INDEX)
#define PIC_GMAC_7_IRQ PIC_INTR_TO_IRQ(PIC_IRT_GMAC7_INDEX)
#define PIC_BRIDGE_ERR_IRQ PIC_INTR_TO_IRQ(PIC_IRT_BRIDGE_ERR_INDEX)
#define PIC_PCIE_LINK0_IRQ PIC_INTR_TO_IRQ(PIC_IRT_PCIE_LINK0_INDEX)
#define PIC_PCIE_LINK1_IRQ PIC_INTR_TO_IRQ(PIC_IRT_PCIE_LINK1_INDEX)
#define PIC_PCIE_LINK2_IRQ PIC_INTR_TO_IRQ(PIC_IRT_PCIE_LINK2_INDEX)
#define PIC_PCIE_LINK3_IRQ PIC_INTR_TO_IRQ(PIC_IRT_PCIE_LINK3_INDEX)
#define PIC_PCIE_XLSB0_LINK2_IRQ PIC_INTR_TO_IRQ(PIC_IRT_PCIE_XLSB0_LINK2_INDEX)
#define PIC_PCIE_XLSB0_LINK3_IRQ PIC_INTR_TO_IRQ(PIC_IRT_PCIE_XLSB0_LINK3_INDEX)
#define PIC_SRIO_LINK0_IRQ PIC_INTR_TO_IRQ(PIC_IRT_SRIO_LINK0_INDEX)
#define PIC_SRIO_LINK1_IRQ PIC_INTR_TO_IRQ(PIC_IRT_SRIO_LINK1_INDEX)
#define PIC_SRIO_LINK2_IRQ PIC_INTR_TO_IRQ(PIC_IRT_SRIO_LINK2_INDEX)
#define PIC_SRIO_LINK3_IRQ PIC_INTR_TO_IRQ(PIC_IRT_SRIO_LINK3_INDEX)
#define PIC_PCIE_INT_IRQ PIC_INTR_TO_IRQ(PIC_IRT_PCIE_INT__INDEX)
#define PIC_PCIE_FATAL_IRQ PIC_INTR_TO_IRQ(PIC_IRT_PCIE_FATAL_INDEX)
#define PIC_GPIO_B_IRQ PIC_INTR_TO_IRQ(PIC_IRT_GPIO_B_INDEX)
#define PIC_USB_IRQ PIC_INTR_TO_IRQ(PIC_IRT_USB_INDEX)
#define PIC_IRT_LAST_IRQ PIC_USB_IRQ
/* end XLS */
#ifndef __ASSEMBLY__
static inline void pic_send_ipi(u32 ipi)
{
nlm_reg_t *mmio = netlogic_io_mmio(NETLOGIC_IO_PIC_OFFSET);
netlogic_write_reg(mmio, PIC_IPI, ipi);
}
static inline u32 pic_read_control(void)
{
nlm_reg_t *mmio = netlogic_io_mmio(NETLOGIC_IO_PIC_OFFSET);
return netlogic_read_reg(mmio, PIC_CTRL);
}
static inline void pic_write_control(u32 control)
{
nlm_reg_t *mmio = netlogic_io_mmio(NETLOGIC_IO_PIC_OFFSET);
netlogic_write_reg(mmio, PIC_CTRL, control);
}
static inline void pic_update_control(u32 control)
{
nlm_reg_t *mmio = netlogic_io_mmio(NETLOGIC_IO_PIC_OFFSET);
netlogic_write_reg(mmio, PIC_CTRL,
(control | netlogic_read_reg(mmio, PIC_CTRL)));
}
#define PIC_IRQ_IS_EDGE_TRIGGERED(irq) (((irq) >= PIC_TIMER_0_IRQ) && \
((irq) <= PIC_TIMER_7_IRQ))
#define PIC_IRQ_IS_IRT(irq) (((irq) >= PIC_IRT_FIRST_IRQ) && \
((irq) <= PIC_IRT_LAST_IRQ))
#endif
#endif /* _ASM_NLM_XLR_PIC_H */

View file

@ -0,0 +1,75 @@
/*
* Copyright 2003-2011 NetLogic Microsystems, Inc. (NetLogic). All rights
* reserved.
*
* This software is available to you under a choice of one of two
* licenses. You may choose to be licensed under the terms of the GNU
* General Public License (GPL) Version 2, available from the file
* COPYING in the main directory of this source tree, or the NetLogic
* license below:
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* THIS SOFTWARE IS PROVIDED BY NETLOGIC ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL NETLOGIC OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _ASM_NLM_XLR_H
#define _ASM_NLM_XLR_H
/* Platform UART functions */
struct uart_port;
unsigned int nlm_xlr_uart_in(struct uart_port *, int);
void nlm_xlr_uart_out(struct uart_port *, int, int);
/* SMP support functions */
struct irq_desc;
void nlm_smp_function_ipi_handler(unsigned int irq, struct irq_desc *desc);
void nlm_smp_resched_ipi_handler(unsigned int irq, struct irq_desc *desc);
int nlm_wakeup_secondary_cpus(u32 wakeup_mask);
void nlm_smp_irq_init(void);
void nlm_boot_smp_nmi(void);
void prom_pre_boot_secondary_cpus(void);
extern struct plat_smp_ops nlm_smp_ops;
extern unsigned long nlm_common_ebase;
/* XLS B silicon "Rook" */
static inline unsigned int nlm_chip_is_xls_b(void)
{
uint32_t prid = read_c0_prid();
return ((prid & 0xf000) == 0x4000);
}
/*
* XLR chip types
*/
/* The XLS product line has chip versions 0x[48c]? */
static inline unsigned int nlm_chip_is_xls(void)
{
uint32_t prid = read_c0_prid();
return ((prid & 0xf000) == 0x8000 || (prid & 0xf000) == 0x4000 ||
(prid & 0xf000) == 0xc000);
}
#endif /* _ASM_NLM_XLR_H */

View file

@ -141,7 +141,8 @@ extern int ptrace_set_watch_regs(struct task_struct *child,
#define instruction_pointer(regs) ((regs)->cp0_epc)
#define profile_pc(regs) instruction_pointer(regs)
extern asmlinkage void do_syscall_trace(struct pt_regs *regs, int entryexit);
extern asmlinkage void syscall_trace_enter(struct pt_regs *regs);
extern asmlinkage void syscall_trace_leave(struct pt_regs *regs);
extern NORET_TYPE void die(const char *, struct pt_regs *) ATTRIB_NORET;

View file

@ -149,6 +149,9 @@ register struct thread_info *__current_thread_info __asm__("$28");
#define _TIF_FPUBOUND (1<<TIF_FPUBOUND)
#define _TIF_LOAD_WATCH (1<<TIF_LOAD_WATCH)
/* work to do in syscall_trace_leave() */
#define _TIF_WORK_SYSCALL_EXIT (_TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT)
/* work to do on interrupt/exception return */
#define _TIF_WORK_MASK (0x0000ffef & \
~(_TIF_SECCOMP | _TIF_SYSCALL_AUDIT))

View file

@ -1,5 +1,6 @@
/*
* Copyright (C) 2009-2010, Lars-Peter Clausen <lars@metafoo.de>
* Copyright (C) 2011, Maarten ter Huurne <maarten@treewalker.org>
* JZ4740 setup code
*
* This program is free software; you can redistribute it and/or modify it
@ -14,13 +15,44 @@
*/
#include <linux/init.h>
#include <linux/io.h>
#include <linux/kernel.h>
#include <asm/bootinfo.h>
#include <asm/mach-jz4740/base.h>
#include "reset.h"
#define JZ4740_EMC_SDRAM_CTRL 0x80
static void __init jz4740_detect_mem(void)
{
void __iomem *jz_emc_base;
u32 ctrl, bus, bank, rows, cols;
phys_t size;
jz_emc_base = ioremap(JZ4740_EMC_BASE_ADDR, 0x100);
ctrl = readl(jz_emc_base + JZ4740_EMC_SDRAM_CTRL);
bus = 2 - ((ctrl >> 31) & 1);
bank = 1 + ((ctrl >> 19) & 1);
cols = 8 + ((ctrl >> 26) & 7);
rows = 11 + ((ctrl >> 20) & 3);
printk(KERN_DEBUG
"SDRAM preconfigured: bus:%u bank:%u rows:%u cols:%u\n",
bus, bank, rows, cols);
iounmap(jz_emc_base);
size = 1 << (bus + bank + cols + rows);
add_memory_region(0, size, BOOT_MEM_RAM);
}
void __init plat_mem_setup(void)
{
jz4740_reset_init();
jz4740_detect_mem();
}
const char *get_system_type(void)

View file

@ -52,6 +52,7 @@ obj-$(CONFIG_CPU_TX39XX) += r2300_fpu.o r2300_switch.o
obj-$(CONFIG_CPU_TX49XX) += r4k_fpu.o r4k_switch.o
obj-$(CONFIG_CPU_VR41XX) += r4k_fpu.o r4k_switch.o
obj-$(CONFIG_CPU_CAVIUM_OCTEON) += octeon_switch.o
obj-$(CONFIG_CPU_XLR) += r4k_fpu.o r4k_switch.o
obj-$(CONFIG_SMP) += smp.o
obj-$(CONFIG_SMP_UP) += smp-up.o

View file

@ -291,6 +291,12 @@ static inline int cpu_has_confreg(void)
#endif
}
static inline void set_elf_platform(int cpu, const char *plat)
{
if (cpu == 0)
__elf_platform = plat;
}
/*
* Get the FPU Implementation/Revision.
*/
@ -614,6 +620,16 @@ static inline void cpu_probe_legacy(struct cpuinfo_mips *c, unsigned int cpu)
case PRID_IMP_LOONGSON2:
c->cputype = CPU_LOONGSON2;
__cpu_name[cpu] = "ICT Loongson-2";
switch (c->processor_id & PRID_REV_MASK) {
case PRID_REV_LOONGSON2E:
set_elf_platform(cpu, "loongson2e");
break;
case PRID_REV_LOONGSON2F:
set_elf_platform(cpu, "loongson2f");
break;
}
c->isa_level = MIPS_CPU_ISA_III;
c->options = R4K_OPTS |
MIPS_CPU_FPU | MIPS_CPU_LLSC |
@ -911,12 +927,14 @@ static inline void cpu_probe_broadcom(struct cpuinfo_mips *c, unsigned int cpu)
case PRID_IMP_BMIPS32_REV8:
c->cputype = CPU_BMIPS32;
__cpu_name[cpu] = "Broadcom BMIPS32";
set_elf_platform(cpu, "bmips32");
break;
case PRID_IMP_BMIPS3300:
case PRID_IMP_BMIPS3300_ALT:
case PRID_IMP_BMIPS3300_BUG:
c->cputype = CPU_BMIPS3300;
__cpu_name[cpu] = "Broadcom BMIPS3300";
set_elf_platform(cpu, "bmips3300");
break;
case PRID_IMP_BMIPS43XX: {
int rev = c->processor_id & 0xff;
@ -925,15 +943,18 @@ static inline void cpu_probe_broadcom(struct cpuinfo_mips *c, unsigned int cpu)
rev <= PRID_REV_BMIPS4380_HI) {
c->cputype = CPU_BMIPS4380;
__cpu_name[cpu] = "Broadcom BMIPS4380";
set_elf_platform(cpu, "bmips4380");
} else {
c->cputype = CPU_BMIPS4350;
__cpu_name[cpu] = "Broadcom BMIPS4350";
set_elf_platform(cpu, "bmips4350");
}
break;
}
case PRID_IMP_BMIPS5000:
c->cputype = CPU_BMIPS5000;
__cpu_name[cpu] = "Broadcom BMIPS5000";
set_elf_platform(cpu, "bmips5000");
c->options |= MIPS_CPU_ULRI;
break;
}
@ -956,14 +977,12 @@ static inline void cpu_probe_cavium(struct cpuinfo_mips *c, unsigned int cpu)
c->cputype = CPU_CAVIUM_OCTEON_PLUS;
__cpu_name[cpu] = "Cavium Octeon+";
platform:
if (cpu == 0)
__elf_platform = "octeon";
set_elf_platform(cpu, "octeon");
break;
case PRID_IMP_CAVIUM_CN63XX:
c->cputype = CPU_CAVIUM_OCTEON2;
__cpu_name[cpu] = "Cavium Octeon II";
if (cpu == 0)
__elf_platform = "octeon2";
set_elf_platform(cpu, "octeon2");
break;
default:
printk(KERN_INFO "Unknown Octeon chip!\n");
@ -988,6 +1007,59 @@ static inline void cpu_probe_ingenic(struct cpuinfo_mips *c, unsigned int cpu)
}
}
static inline void cpu_probe_netlogic(struct cpuinfo_mips *c, int cpu)
{
decode_configs(c);
c->options = (MIPS_CPU_TLB |
MIPS_CPU_4KEX |
MIPS_CPU_COUNTER |
MIPS_CPU_DIVEC |
MIPS_CPU_WATCH |
MIPS_CPU_EJTAG |
MIPS_CPU_LLSC);
switch (c->processor_id & 0xff00) {
case PRID_IMP_NETLOGIC_XLR732:
case PRID_IMP_NETLOGIC_XLR716:
case PRID_IMP_NETLOGIC_XLR532:
case PRID_IMP_NETLOGIC_XLR308:
case PRID_IMP_NETLOGIC_XLR532C:
case PRID_IMP_NETLOGIC_XLR516C:
case PRID_IMP_NETLOGIC_XLR508C:
case PRID_IMP_NETLOGIC_XLR308C:
c->cputype = CPU_XLR;
__cpu_name[cpu] = "Netlogic XLR";
break;
case PRID_IMP_NETLOGIC_XLS608:
case PRID_IMP_NETLOGIC_XLS408:
case PRID_IMP_NETLOGIC_XLS404:
case PRID_IMP_NETLOGIC_XLS208:
case PRID_IMP_NETLOGIC_XLS204:
case PRID_IMP_NETLOGIC_XLS108:
case PRID_IMP_NETLOGIC_XLS104:
case PRID_IMP_NETLOGIC_XLS616B:
case PRID_IMP_NETLOGIC_XLS608B:
case PRID_IMP_NETLOGIC_XLS416B:
case PRID_IMP_NETLOGIC_XLS412B:
case PRID_IMP_NETLOGIC_XLS408B:
case PRID_IMP_NETLOGIC_XLS404B:
c->cputype = CPU_XLR;
__cpu_name[cpu] = "Netlogic XLS";
break;
default:
printk(KERN_INFO "Unknown Netlogic chip id [%02x]!\n",
c->processor_id);
c->cputype = CPU_XLR;
break;
}
c->isa_level = MIPS_CPU_ISA_M64R1;
c->tlbsize = ((read_c0_config1() >> 25) & 0x3f) + 1;
}
#ifdef CONFIG_64BIT
/* For use by uaccess.h */
u64 __ua_limit;
@ -1035,6 +1107,9 @@ __cpuinit void cpu_probe(void)
case PRID_COMP_INGENIC:
cpu_probe_ingenic(c, cpu);
break;
case PRID_COMP_NETLOGIC:
cpu_probe_netlogic(c, cpu);
break;
}
BUG_ON(!__cpu_name[cpu]);

View file

@ -167,14 +167,13 @@ work_notifysig: # deal with pending signals and
FEXPORT(syscall_exit_work_partial)
SAVE_STATIC
syscall_exit_work:
li t0, _TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT
li t0, _TIF_WORK_SYSCALL_EXIT
and t0, a2 # a2 is preloaded with TI_FLAGS
beqz t0, work_pending # trace bit set?
local_irq_enable # could let do_syscall_trace()
local_irq_enable # could let syscall_trace_leave()
# call schedule() instead
move a0, sp
li a1, 1
jal do_syscall_trace
jal syscall_trace_leave
b resume_userspace
#if defined(CONFIG_CPU_MIPSR2) || defined(CONFIG_MIPS_MT)

View file

@ -533,15 +533,10 @@ static inline int audit_arch(void)
* Notification of system call entry/exit
* - triggered by current->work.syscall_trace
*/
asmlinkage void do_syscall_trace(struct pt_regs *regs, int entryexit)
asmlinkage void syscall_trace_enter(struct pt_regs *regs)
{
/* do the secure computing check first */
if (!entryexit)
secure_computing(regs->regs[2]);
if (unlikely(current->audit_context) && entryexit)
audit_syscall_exit(AUDITSC_RESULT(regs->regs[7]),
-regs->regs[2]);
secure_computing(regs->regs[2]);
if (!(current->ptrace & PT_PTRACED))
goto out;
@ -565,8 +560,40 @@ asmlinkage void do_syscall_trace(struct pt_regs *regs, int entryexit)
}
out:
if (unlikely(current->audit_context) && !entryexit)
if (unlikely(current->audit_context))
audit_syscall_entry(audit_arch(), regs->regs[2],
regs->regs[4], regs->regs[5],
regs->regs[6], regs->regs[7]);
}
/*
* Notification of system call entry/exit
* - triggered by current->work.syscall_trace
*/
asmlinkage void syscall_trace_leave(struct pt_regs *regs)
{
if (unlikely(current->audit_context))
audit_syscall_exit(AUDITSC_RESULT(regs->regs[7]),
-regs->regs[2]);
if (!(current->ptrace & PT_PTRACED))
return;
if (!test_thread_flag(TIF_SYSCALL_TRACE))
return;
/* The 0x80 provides a way for the tracing parent to distinguish
between a syscall stop and SIGTRAP delivery */
ptrace_notify(SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD) ?
0x80 : 0));
/*
* this isn't the same as continuing with a signal, but it will do
* for normal use. strace only continues with a signal if the
* stopping signal is not SIGTRAP. -brl
*/
if (current->exit_code) {
send_sig(current->exit_code, current, 1);
current->exit_code = 0;
}
}

View file

@ -88,8 +88,7 @@ syscall_trace_entry:
SAVE_STATIC
move s0, t2
move a0, sp
li a1, 0
jal do_syscall_trace
jal syscall_trace_enter
move t0, s0
RESTORE_STATIC

View file

@ -91,8 +91,7 @@ syscall_trace_entry:
SAVE_STATIC
move s0, t2
move a0, sp
li a1, 0
jal do_syscall_trace
jal syscall_trace_enter
move t0, s0
RESTORE_STATIC

View file

@ -89,8 +89,7 @@ n32_syscall_trace_entry:
SAVE_STATIC
move s0, t2
move a0, sp
li a1, 0
jal do_syscall_trace
jal syscall_trace_enter
move t0, s0
RESTORE_STATIC

View file

@ -123,8 +123,7 @@ trace_a_syscall:
move s0, t2 # Save syscall pointer
move a0, sp
li a1, 0
jal do_syscall_trace
jal syscall_trace_enter
move t0, s0
RESTORE_STATIC

View file

@ -10,12 +10,9 @@
#include <linux/capability.h>
#include <linux/errno.h>
#include <linux/linkage.h>
#include <linux/mm.h>
#include <linux/fs.h>
#include <linux/smp.h>
#include <linux/mman.h>
#include <linux/ptrace.h>
#include <linux/sched.h>
#include <linux/string.h>
#include <linux/syscalls.h>
#include <linux/file.h>
@ -25,11 +22,9 @@
#include <linux/msg.h>
#include <linux/shm.h>
#include <linux/compiler.h>
#include <linux/module.h>
#include <linux/ipc.h>
#include <linux/uaccess.h>
#include <linux/slab.h>
#include <linux/random.h>
#include <linux/elf.h>
#include <asm/asm.h>
@ -66,121 +61,6 @@ asmlinkage int sysm_pipe(nabi_no_regargs volatile struct pt_regs regs)
return res;
}
unsigned long shm_align_mask = PAGE_SIZE - 1; /* Sane caches */
EXPORT_SYMBOL(shm_align_mask);
#define COLOUR_ALIGN(addr,pgoff) \
((((addr) + shm_align_mask) & ~shm_align_mask) + \
(((pgoff) << PAGE_SHIFT) & shm_align_mask))
unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr,
unsigned long len, unsigned long pgoff, unsigned long flags)
{
struct vm_area_struct * vmm;
int do_color_align;
unsigned long task_size;
#ifdef CONFIG_32BIT
task_size = TASK_SIZE;
#else /* Must be CONFIG_64BIT*/
task_size = test_thread_flag(TIF_32BIT_ADDR) ? TASK_SIZE32 : TASK_SIZE;
#endif
if (len > task_size)
return -ENOMEM;
if (flags & MAP_FIXED) {
/* Even MAP_FIXED mappings must reside within task_size. */
if (task_size - len < addr)
return -EINVAL;
/*
* We do not accept a shared mapping if it would violate
* cache aliasing constraints.
*/
if ((flags & MAP_SHARED) &&
((addr - (pgoff << PAGE_SHIFT)) & shm_align_mask))
return -EINVAL;
return addr;
}
do_color_align = 0;
if (filp || (flags & MAP_SHARED))
do_color_align = 1;
if (addr) {
if (do_color_align)
addr = COLOUR_ALIGN(addr, pgoff);
else
addr = PAGE_ALIGN(addr);
vmm = find_vma(current->mm, addr);
if (task_size - len >= addr &&
(!vmm || addr + len <= vmm->vm_start))
return addr;
}
addr = current->mm->mmap_base;
if (do_color_align)
addr = COLOUR_ALIGN(addr, pgoff);
else
addr = PAGE_ALIGN(addr);
for (vmm = find_vma(current->mm, addr); ; vmm = vmm->vm_next) {
/* At this point: (!vmm || addr < vmm->vm_end). */
if (task_size - len < addr)
return -ENOMEM;
if (!vmm || addr + len <= vmm->vm_start)
return addr;
addr = vmm->vm_end;
if (do_color_align)
addr = COLOUR_ALIGN(addr, pgoff);
}
}
void arch_pick_mmap_layout(struct mm_struct *mm)
{
unsigned long random_factor = 0UL;
if (current->flags & PF_RANDOMIZE) {
random_factor = get_random_int();
random_factor = random_factor << PAGE_SHIFT;
if (TASK_IS_32BIT_ADDR)
random_factor &= 0xfffffful;
else
random_factor &= 0xffffffful;
}
mm->mmap_base = TASK_UNMAPPED_BASE + random_factor;
mm->get_unmapped_area = arch_get_unmapped_area;
mm->unmap_area = arch_unmap_area;
}
static inline unsigned long brk_rnd(void)
{
unsigned long rnd = get_random_int();
rnd = rnd << PAGE_SHIFT;
/* 8MB for 32bit, 256MB for 64bit */
if (TASK_IS_32BIT_ADDR)
rnd = rnd & 0x7ffffful;
else
rnd = rnd & 0xffffffful;
return rnd;
}
unsigned long arch_randomize_brk(struct mm_struct *mm)
{
unsigned long base = mm->brk;
unsigned long ret;
ret = PAGE_ALIGN(base + brk_rnd());
if (ret < mm->brk)
return mm->brk;
return ret;
}
SYSCALL_DEFINE6(mips_mmap, unsigned long, addr, unsigned long, len,
unsigned long, prot, unsigned long, flags, unsigned long,
fd, off_t, offset)

View file

@ -68,6 +68,7 @@ SECTIONS
RODATA
/* writeable */
_sdata = .; /* Start of data section */
.data : { /* Data */
. = . + DATAOFFSET; /* for CONFIG_MAPPED_KERNEL */

23
arch/mips/lantiq/Kconfig Normal file
View file

@ -0,0 +1,23 @@
if LANTIQ
config SOC_TYPE_XWAY
bool
default n
choice
prompt "SoC Type"
default SOC_XWAY
config SOC_AMAZON_SE
bool "Amazon SE"
select SOC_TYPE_XWAY
config SOC_XWAY
bool "XWAY"
select SOC_TYPE_XWAY
select HW_HAS_PCI
endchoice
source "arch/mips/lantiq/xway/Kconfig"
endif

11
arch/mips/lantiq/Makefile Normal file
View file

@ -0,0 +1,11 @@
# Copyright (C) 2010 John Crispin <blogic@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 := irq.o setup.o clk.o prom.o devices.o
obj-$(CONFIG_EARLY_PRINTK) += early_printk.o
obj-$(CONFIG_SOC_TYPE_XWAY) += xway/

View file

@ -0,0 +1,8 @@
#
# Lantiq
#
platform-$(CONFIG_LANTIQ) += lantiq/
cflags-$(CONFIG_LANTIQ) += -I$(srctree)/arch/mips/include/asm/mach-lantiq
load-$(CONFIG_LANTIQ) = 0xffffffff80002000
cflags-$(CONFIG_SOC_TYPE_XWAY) += -I$(srctree)/arch/mips/include/asm/mach-lantiq/xway

140
arch/mips/lantiq/clk.c Normal file
View file

@ -0,0 +1,140 @@
/*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 as published
* by the Free Software Foundation.
*
* Copyright (C) 2010 Thomas Langer <thomas.langer@lantiq.com>
* Copyright (C) 2010 John Crispin <blogic@openwrt.org>
*/
#include <linux/io.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/clk.h>
#include <linux/err.h>
#include <linux/list.h>
#include <asm/time.h>
#include <asm/irq.h>
#include <asm/div64.h>
#include <lantiq_soc.h>
#include "clk.h"
struct clk {
const char *name;
unsigned long rate;
unsigned long (*get_rate) (void);
};
static struct clk *cpu_clk;
static int cpu_clk_cnt;
/* lantiq socs have 3 static clocks */
static struct clk cpu_clk_generic[] = {
{
.name = "cpu",
.get_rate = ltq_get_cpu_hz,
}, {
.name = "fpi",
.get_rate = ltq_get_fpi_hz,
}, {
.name = "io",
.get_rate = ltq_get_io_region_clock,
},
};
static struct resource ltq_cgu_resource = {
.name = "cgu",
.start = LTQ_CGU_BASE_ADDR,
.end = LTQ_CGU_BASE_ADDR + LTQ_CGU_SIZE - 1,
.flags = IORESOURCE_MEM,
};
/* remapped clock register range */
void __iomem *ltq_cgu_membase;
void clk_init(void)
{
cpu_clk = cpu_clk_generic;
cpu_clk_cnt = ARRAY_SIZE(cpu_clk_generic);
}
static inline int clk_good(struct clk *clk)
{
return clk && !IS_ERR(clk);
}
unsigned long clk_get_rate(struct clk *clk)
{
if (unlikely(!clk_good(clk)))
return 0;
if (clk->rate != 0)
return clk->rate;
if (clk->get_rate != NULL)
return clk->get_rate();
return 0;
}
EXPORT_SYMBOL(clk_get_rate);
struct clk *clk_get(struct device *dev, const char *id)
{
int i;
for (i = 0; i < cpu_clk_cnt; i++)
if (!strcmp(id, cpu_clk[i].name))
return &cpu_clk[i];
BUG();
return ERR_PTR(-ENOENT);
}
EXPORT_SYMBOL(clk_get);
void clk_put(struct clk *clk)
{
/* not used */
}
EXPORT_SYMBOL(clk_put);
static inline u32 ltq_get_counter_resolution(void)
{
u32 res;
__asm__ __volatile__(
".set push\n"
".set mips32r2\n"
"rdhwr %0, $3\n"
".set pop\n"
: "=&r" (res)
: /* no input */
: "memory");
return res;
}
void __init plat_time_init(void)
{
struct clk *clk;
if (insert_resource(&iomem_resource, &ltq_cgu_resource) < 0)
panic("Failed to insert cgu memory\n");
if (request_mem_region(ltq_cgu_resource.start,
resource_size(&ltq_cgu_resource), "cgu") < 0)
panic("Failed to request cgu memory\n");
ltq_cgu_membase = ioremap_nocache(ltq_cgu_resource.start,
resource_size(&ltq_cgu_resource));
if (!ltq_cgu_membase) {
pr_err("Failed to remap cgu memory\n");
unreachable();
}
clk = clk_get(0, "cpu");
mips_hpt_frequency = clk_get_rate(clk) / ltq_get_counter_resolution();
write_c0_compare(read_c0_count());
clk_put(clk);
}

18
arch/mips/lantiq/clk.h Normal file
View file

@ -0,0 +1,18 @@
/*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 as published
* by the Free Software Foundation.
*
* Copyright (C) 2010 John Crispin <blogic@openwrt.org>
*/
#ifndef _LTQ_CLK_H__
#define _LTQ_CLK_H__
extern void clk_init(void);
extern unsigned long ltq_get_cpu_hz(void);
extern unsigned long ltq_get_fpi_hz(void);
extern unsigned long ltq_get_io_region_clock(void);
#endif

122
arch/mips/lantiq/devices.c Normal file
View file

@ -0,0 +1,122 @@
/*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 as published
* by the Free Software Foundation.
*
* Copyright (C) 2010 John Crispin <blogic@openwrt.org>
*/
#include <linux/init.h>
#include <linux/module.h>
#include <linux/types.h>
#include <linux/string.h>
#include <linux/kernel.h>
#include <linux/reboot.h>
#include <linux/platform_device.h>
#include <linux/leds.h>
#include <linux/etherdevice.h>
#include <linux/reboot.h>
#include <linux/time.h>
#include <linux/io.h>
#include <linux/gpio.h>
#include <linux/leds.h>
#include <asm/bootinfo.h>
#include <asm/irq.h>
#include <lantiq_soc.h>
#include "devices.h"
/* nor flash */
static struct resource ltq_nor_resource = {
.name = "nor",
.start = LTQ_FLASH_START,
.end = LTQ_FLASH_START + LTQ_FLASH_MAX - 1,
.flags = IORESOURCE_MEM,
};
static struct platform_device ltq_nor = {
.name = "ltq_nor",
.resource = &ltq_nor_resource,
.num_resources = 1,
};
void __init ltq_register_nor(struct physmap_flash_data *data)
{
ltq_nor.dev.platform_data = data;
platform_device_register(&ltq_nor);
}
/* watchdog */
static struct resource ltq_wdt_resource = {
.name = "watchdog",
.start = LTQ_WDT_BASE_ADDR,
.end = LTQ_WDT_BASE_ADDR + LTQ_WDT_SIZE - 1,
.flags = IORESOURCE_MEM,
};
void __init ltq_register_wdt(void)
{
platform_device_register_simple("ltq_wdt", 0, &ltq_wdt_resource, 1);
}
/* asc ports */
static struct resource ltq_asc0_resources[] = {
{
.name = "asc0",
.start = LTQ_ASC0_BASE_ADDR,
.end = LTQ_ASC0_BASE_ADDR + LTQ_ASC_SIZE - 1,
.flags = IORESOURCE_MEM,
},
IRQ_RES(tx, LTQ_ASC_TIR(0)),
IRQ_RES(rx, LTQ_ASC_RIR(0)),
IRQ_RES(err, LTQ_ASC_EIR(0)),
};
static struct resource ltq_asc1_resources[] = {
{
.name = "asc1",
.start = LTQ_ASC1_BASE_ADDR,
.end = LTQ_ASC1_BASE_ADDR + LTQ_ASC_SIZE - 1,
.flags = IORESOURCE_MEM,
},
IRQ_RES(tx, LTQ_ASC_TIR(1)),
IRQ_RES(rx, LTQ_ASC_RIR(1)),
IRQ_RES(err, LTQ_ASC_EIR(1)),
};
void __init ltq_register_asc(int port)
{
switch (port) {
case 0:
platform_device_register_simple("ltq_asc", 0,
ltq_asc0_resources, ARRAY_SIZE(ltq_asc0_resources));
break;
case 1:
platform_device_register_simple("ltq_asc", 1,
ltq_asc1_resources, ARRAY_SIZE(ltq_asc1_resources));
break;
default:
break;
}
}
#ifdef CONFIG_PCI
/* pci */
static struct platform_device ltq_pci = {
.name = "ltq_pci",
.num_resources = 0,
};
void __init ltq_register_pci(struct ltq_pci_data *data)
{
ltq_pci.dev.platform_data = data;
platform_device_register(&ltq_pci);
}
#else
void __init ltq_register_pci(struct ltq_pci_data *data)
{
pr_err("kernel is compiled without PCI support\n");
}
#endif

View file

@ -0,0 +1,23 @@
/*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 as published
* by the Free Software Foundation.
*
* Copyright (C) 2010 John Crispin <blogic@openwrt.org>
*/
#ifndef _LTQ_DEVICES_H__
#define _LTQ_DEVICES_H__
#include <lantiq_platform.h>
#include <linux/mtd/physmap.h>
#define IRQ_RES(resname, irq) \
{.name = #resname, .start = (irq), .flags = IORESOURCE_IRQ}
extern void ltq_register_nor(struct physmap_flash_data *data);
extern void ltq_register_wdt(void);
extern void ltq_register_asc(int port);
extern void ltq_register_pci(struct ltq_pci_data *data);
#endif

View file

@ -0,0 +1,33 @@
/*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 as published
* by the Free Software Foundation.
*
* Copyright (C) 2010 John Crispin <blogic@openwrt.org>
*/
#include <linux/init.h>
#include <linux/cpu.h>
#include <lantiq.h>
#include <lantiq_soc.h>
/* no ioremap possible at this early stage, lets use KSEG1 instead */
#define LTQ_ASC_BASE KSEG1ADDR(LTQ_ASC1_BASE_ADDR)
#define ASC_BUF 1024
#define LTQ_ASC_FSTAT ((u32 *)(LTQ_ASC_BASE + 0x0048))
#define LTQ_ASC_TBUF ((u32 *)(LTQ_ASC_BASE + 0x0020))
#define TXMASK 0x3F00
#define TXOFFSET 8
void prom_putchar(char c)
{
unsigned long flags;
local_irq_save(flags);
do { } while ((ltq_r32(LTQ_ASC_FSTAT) & TXMASK) >> TXOFFSET);
if (c == '\n')
ltq_w32('\r', LTQ_ASC_TBUF);
ltq_w32(c, LTQ_ASC_TBUF);
local_irq_restore(flags);
}

326
arch/mips/lantiq/irq.c Normal file
View file

@ -0,0 +1,326 @@
/*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 as published
* by the Free Software Foundation.
*
* Copyright (C) 2010 John Crispin <blogic@openwrt.org>
* Copyright (C) 2010 Thomas Langer <thomas.langer@lantiq.com>
*/
#include <linux/interrupt.h>
#include <linux/ioport.h>
#include <asm/bootinfo.h>
#include <asm/irq_cpu.h>
#include <lantiq_soc.h>
#include <irq.h>
/* register definitions */
#define LTQ_ICU_IM0_ISR 0x0000
#define LTQ_ICU_IM0_IER 0x0008
#define LTQ_ICU_IM0_IOSR 0x0010
#define LTQ_ICU_IM0_IRSR 0x0018
#define LTQ_ICU_IM0_IMR 0x0020
#define LTQ_ICU_IM1_ISR 0x0028
#define LTQ_ICU_OFFSET (LTQ_ICU_IM1_ISR - LTQ_ICU_IM0_ISR)
#define LTQ_EIU_EXIN_C 0x0000
#define LTQ_EIU_EXIN_INIC 0x0004
#define LTQ_EIU_EXIN_INEN 0x000C
/* irq numbers used by the external interrupt unit (EIU) */
#define LTQ_EIU_IR0 (INT_NUM_IM4_IRL0 + 30)
#define LTQ_EIU_IR1 (INT_NUM_IM3_IRL0 + 31)
#define LTQ_EIU_IR2 (INT_NUM_IM1_IRL0 + 26)
#define LTQ_EIU_IR3 INT_NUM_IM1_IRL0
#define LTQ_EIU_IR4 (INT_NUM_IM1_IRL0 + 1)
#define LTQ_EIU_IR5 (INT_NUM_IM1_IRL0 + 2)
#define LTQ_EIU_IR6 (INT_NUM_IM2_IRL0 + 30)
#define MAX_EIU 6
/* irqs generated by device attached to the EBU need to be acked in
* a special manner
*/
#define LTQ_ICU_EBU_IRQ 22
#define ltq_icu_w32(x, y) ltq_w32((x), ltq_icu_membase + (y))
#define ltq_icu_r32(x) ltq_r32(ltq_icu_membase + (x))
#define ltq_eiu_w32(x, y) ltq_w32((x), ltq_eiu_membase + (y))
#define ltq_eiu_r32(x) ltq_r32(ltq_eiu_membase + (x))
static unsigned short ltq_eiu_irq[MAX_EIU] = {
LTQ_EIU_IR0,
LTQ_EIU_IR1,
LTQ_EIU_IR2,
LTQ_EIU_IR3,
LTQ_EIU_IR4,
LTQ_EIU_IR5,
};
static struct resource ltq_icu_resource = {
.name = "icu",
.start = LTQ_ICU_BASE_ADDR,
.end = LTQ_ICU_BASE_ADDR + LTQ_ICU_SIZE - 1,
.flags = IORESOURCE_MEM,
};
static struct resource ltq_eiu_resource = {
.name = "eiu",
.start = LTQ_EIU_BASE_ADDR,
.end = LTQ_EIU_BASE_ADDR + LTQ_ICU_SIZE - 1,
.flags = IORESOURCE_MEM,
};
static void __iomem *ltq_icu_membase;
static void __iomem *ltq_eiu_membase;
void ltq_disable_irq(struct irq_data *d)
{
u32 ier = LTQ_ICU_IM0_IER;
int irq_nr = d->irq - INT_NUM_IRQ0;
ier += LTQ_ICU_OFFSET * (irq_nr / INT_NUM_IM_OFFSET);
irq_nr %= INT_NUM_IM_OFFSET;
ltq_icu_w32(ltq_icu_r32(ier) & ~(1 << irq_nr), ier);
}
void ltq_mask_and_ack_irq(struct irq_data *d)
{
u32 ier = LTQ_ICU_IM0_IER;
u32 isr = LTQ_ICU_IM0_ISR;
int irq_nr = d->irq - INT_NUM_IRQ0;
ier += LTQ_ICU_OFFSET * (irq_nr / INT_NUM_IM_OFFSET);
isr += LTQ_ICU_OFFSET * (irq_nr / INT_NUM_IM_OFFSET);
irq_nr %= INT_NUM_IM_OFFSET;
ltq_icu_w32(ltq_icu_r32(ier) & ~(1 << irq_nr), ier);
ltq_icu_w32((1 << irq_nr), isr);
}
static void ltq_ack_irq(struct irq_data *d)
{
u32 isr = LTQ_ICU_IM0_ISR;
int irq_nr = d->irq - INT_NUM_IRQ0;
isr += LTQ_ICU_OFFSET * (irq_nr / INT_NUM_IM_OFFSET);
irq_nr %= INT_NUM_IM_OFFSET;
ltq_icu_w32((1 << irq_nr), isr);
}
void ltq_enable_irq(struct irq_data *d)
{
u32 ier = LTQ_ICU_IM0_IER;
int irq_nr = d->irq - INT_NUM_IRQ0;
ier += LTQ_ICU_OFFSET * (irq_nr / INT_NUM_IM_OFFSET);
irq_nr %= INT_NUM_IM_OFFSET;
ltq_icu_w32(ltq_icu_r32(ier) | (1 << irq_nr), ier);
}
static unsigned int ltq_startup_eiu_irq(struct irq_data *d)
{
int i;
int irq_nr = d->irq - INT_NUM_IRQ0;
ltq_enable_irq(d);
for (i = 0; i < MAX_EIU; i++) {
if (irq_nr == ltq_eiu_irq[i]) {
/* low level - we should really handle set_type */
ltq_eiu_w32(ltq_eiu_r32(LTQ_EIU_EXIN_C) |
(0x6 << (i * 4)), LTQ_EIU_EXIN_C);
/* clear all pending */
ltq_eiu_w32(ltq_eiu_r32(LTQ_EIU_EXIN_INIC) & ~(1 << i),
LTQ_EIU_EXIN_INIC);
/* enable */
ltq_eiu_w32(ltq_eiu_r32(LTQ_EIU_EXIN_INEN) | (1 << i),
LTQ_EIU_EXIN_INEN);
break;
}
}
return 0;
}
static void ltq_shutdown_eiu_irq(struct irq_data *d)
{
int i;
int irq_nr = d->irq - INT_NUM_IRQ0;
ltq_disable_irq(d);
for (i = 0; i < MAX_EIU; i++) {
if (irq_nr == ltq_eiu_irq[i]) {
/* disable */
ltq_eiu_w32(ltq_eiu_r32(LTQ_EIU_EXIN_INEN) & ~(1 << i),
LTQ_EIU_EXIN_INEN);
break;
}
}
}
static struct irq_chip ltq_irq_type = {
"icu",
.irq_enable = ltq_enable_irq,
.irq_disable = ltq_disable_irq,
.irq_unmask = ltq_enable_irq,
.irq_ack = ltq_ack_irq,
.irq_mask = ltq_disable_irq,
.irq_mask_ack = ltq_mask_and_ack_irq,
};
static struct irq_chip ltq_eiu_type = {
"eiu",
.irq_startup = ltq_startup_eiu_irq,
.irq_shutdown = ltq_shutdown_eiu_irq,
.irq_enable = ltq_enable_irq,
.irq_disable = ltq_disable_irq,
.irq_unmask = ltq_enable_irq,
.irq_ack = ltq_ack_irq,
.irq_mask = ltq_disable_irq,
.irq_mask_ack = ltq_mask_and_ack_irq,
};
static void ltq_hw_irqdispatch(int module)
{
u32 irq;
irq = ltq_icu_r32(LTQ_ICU_IM0_IOSR + (module * LTQ_ICU_OFFSET));
if (irq == 0)
return;
/* silicon bug causes only the msb set to 1 to be valid. all
* other bits might be bogus
*/
irq = __fls(irq);
do_IRQ((int)irq + INT_NUM_IM0_IRL0 + (INT_NUM_IM_OFFSET * module));
/* if this is a EBU irq, we need to ack it or get a deadlock */
if ((irq == LTQ_ICU_EBU_IRQ) && (module == 0))
ltq_ebu_w32(ltq_ebu_r32(LTQ_EBU_PCC_ISTAT) | 0x10,
LTQ_EBU_PCC_ISTAT);
}
#define DEFINE_HWx_IRQDISPATCH(x) \
static void ltq_hw ## x ## _irqdispatch(void) \
{ \
ltq_hw_irqdispatch(x); \
}
DEFINE_HWx_IRQDISPATCH(0)
DEFINE_HWx_IRQDISPATCH(1)
DEFINE_HWx_IRQDISPATCH(2)
DEFINE_HWx_IRQDISPATCH(3)
DEFINE_HWx_IRQDISPATCH(4)
static void ltq_hw5_irqdispatch(void)
{
do_IRQ(MIPS_CPU_TIMER_IRQ);
}
asmlinkage void plat_irq_dispatch(void)
{
unsigned int pending = read_c0_status() & read_c0_cause() & ST0_IM;
unsigned int i;
if (pending & CAUSEF_IP7) {
do_IRQ(MIPS_CPU_TIMER_IRQ);
goto out;
} else {
for (i = 0; i < 5; i++) {
if (pending & (CAUSEF_IP2 << i)) {
ltq_hw_irqdispatch(i);
goto out;
}
}
}
pr_alert("Spurious IRQ: CAUSE=0x%08x\n", read_c0_status());
out:
return;
}
static struct irqaction cascade = {
.handler = no_action,
.flags = IRQF_DISABLED,
.name = "cascade",
};
void __init arch_init_irq(void)
{
int i;
if (insert_resource(&iomem_resource, &ltq_icu_resource) < 0)
panic("Failed to insert icu memory\n");
if (request_mem_region(ltq_icu_resource.start,
resource_size(&ltq_icu_resource), "icu") < 0)
panic("Failed to request icu memory\n");
ltq_icu_membase = ioremap_nocache(ltq_icu_resource.start,
resource_size(&ltq_icu_resource));
if (!ltq_icu_membase)
panic("Failed to remap icu memory\n");
if (insert_resource(&iomem_resource, &ltq_eiu_resource) < 0)
panic("Failed to insert eiu memory\n");
if (request_mem_region(ltq_eiu_resource.start,
resource_size(&ltq_eiu_resource), "eiu") < 0)
panic("Failed to request eiu memory\n");
ltq_eiu_membase = ioremap_nocache(ltq_eiu_resource.start,
resource_size(&ltq_eiu_resource));
if (!ltq_eiu_membase)
panic("Failed to remap eiu memory\n");
/* make sure all irqs are turned off by default */
for (i = 0; i < 5; i++)
ltq_icu_w32(0, LTQ_ICU_IM0_IER + (i * LTQ_ICU_OFFSET));
/* clear all possibly pending interrupts */
ltq_icu_w32(~0, LTQ_ICU_IM0_ISR + (i * LTQ_ICU_OFFSET));
mips_cpu_irq_init();
for (i = 2; i <= 6; i++)
setup_irq(i, &cascade);
if (cpu_has_vint) {
pr_info("Setting up vectored interrupts\n");
set_vi_handler(2, ltq_hw0_irqdispatch);
set_vi_handler(3, ltq_hw1_irqdispatch);
set_vi_handler(4, ltq_hw2_irqdispatch);
set_vi_handler(5, ltq_hw3_irqdispatch);
set_vi_handler(6, ltq_hw4_irqdispatch);
set_vi_handler(7, ltq_hw5_irqdispatch);
}
for (i = INT_NUM_IRQ0;
i <= (INT_NUM_IRQ0 + (5 * INT_NUM_IM_OFFSET)); i++)
if ((i == LTQ_EIU_IR0) || (i == LTQ_EIU_IR1) ||
(i == LTQ_EIU_IR2))
irq_set_chip_and_handler(i, &ltq_eiu_type,
handle_level_irq);
/* EIU3-5 only exist on ar9 and vr9 */
else if (((i == LTQ_EIU_IR3) || (i == LTQ_EIU_IR4) ||
(i == LTQ_EIU_IR5)) && (ltq_is_ar9() || ltq_is_vr9()))
irq_set_chip_and_handler(i, &ltq_eiu_type,
handle_level_irq);
else
irq_set_chip_and_handler(i, &ltq_irq_type,
handle_level_irq);
#if !defined(CONFIG_MIPS_MT_SMP) && !defined(CONFIG_MIPS_MT_SMTC)
set_c0_status(IE_IRQ0 | IE_IRQ1 | IE_IRQ2 |
IE_IRQ3 | IE_IRQ4 | IE_IRQ5);
#else
set_c0_status(IE_SW0 | IE_SW1 | IE_IRQ0 | IE_IRQ1 |
IE_IRQ2 | IE_IRQ3 | IE_IRQ4 | IE_IRQ5);
#endif
}
unsigned int __cpuinit get_c0_compare_int(void)
{
return CP0_LEGACY_COMPARE_IRQ;
}

View file

@ -0,0 +1,20 @@
/*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 as published
* by the Free Software Foundation.
*
* Copyright (C) 2010 John Crispin <blogic@openwrt.org>
*/
#ifndef _LANTIQ_MACH_H__
#define _LANTIQ_MACH_H__
#include <asm/mips_machine.h>
enum lantiq_mach_type {
LTQ_MACH_GENERIC = 0,
LTQ_MACH_EASY50712, /* Danube evaluation board */
LTQ_MACH_EASY50601, /* Amazon SE evaluation board */
};
#endif

71
arch/mips/lantiq/prom.c Normal file
View file

@ -0,0 +1,71 @@
/*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 as published
* by the Free Software Foundation.
*
* Copyright (C) 2010 John Crispin <blogic@openwrt.org>
*/
#include <linux/module.h>
#include <linux/clk.h>
#include <asm/bootinfo.h>
#include <asm/time.h>
#include <lantiq.h>
#include "prom.h"
#include "clk.h"
static struct ltq_soc_info soc_info;
unsigned int ltq_get_cpu_ver(void)
{
return soc_info.rev;
}
EXPORT_SYMBOL(ltq_get_cpu_ver);
unsigned int ltq_get_soc_type(void)
{
return soc_info.type;
}
EXPORT_SYMBOL(ltq_get_soc_type);
const char *get_system_type(void)
{
return soc_info.sys_type;
}
void prom_free_prom_memory(void)
{
}
static void __init prom_init_cmdline(void)
{
int argc = fw_arg0;
char **argv = (char **) KSEG1ADDR(fw_arg1);
int i;
for (i = 0; i < argc; i++) {
char *p = (char *) KSEG1ADDR(argv[i]);
if (p && *p) {
strlcat(arcs_cmdline, p, sizeof(arcs_cmdline));
strlcat(arcs_cmdline, " ", sizeof(arcs_cmdline));
}
}
}
void __init prom_init(void)
{
struct clk *clk;
ltq_soc_detect(&soc_info);
clk_init();
clk = clk_get(0, "cpu");
snprintf(soc_info.sys_type, LTQ_SYS_TYPE_LEN - 1, "%s rev1.%d",
soc_info.name, soc_info.rev);
clk_put(clk);
soc_info.sys_type[LTQ_SYS_TYPE_LEN - 1] = '\0';
pr_info("SoC: %s\n", soc_info.sys_type);
prom_init_cmdline();
}

25
arch/mips/lantiq/prom.h Normal file
View file

@ -0,0 +1,25 @@
/*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 as published
* by the Free Software Foundation.
*
* Copyright (C) 2010 John Crispin <blogic@openwrt.org>
*/
#ifndef _LTQ_PROM_H__
#define _LTQ_PROM_H__
#define LTQ_SYS_TYPE_LEN 0x100
struct ltq_soc_info {
unsigned char *name;
unsigned int rev;
unsigned int partnum;
unsigned int type;
unsigned char sys_type[LTQ_SYS_TYPE_LEN];
};
extern void ltq_soc_detect(struct ltq_soc_info *i);
extern void ltq_soc_setup(void);
#endif

66
arch/mips/lantiq/setup.c Normal file
View file

@ -0,0 +1,66 @@
/*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 as published
* by the Free Software Foundation.
*
* Copyright (C) 2010 John Crispin <blogic@openwrt.org>
*/
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/io.h>
#include <linux/ioport.h>
#include <asm/bootinfo.h>
#include <lantiq_soc.h>
#include "machtypes.h"
#include "devices.h"
#include "prom.h"
void __init plat_mem_setup(void)
{
/* assume 16M as default incase uboot fails to pass proper ramsize */
unsigned long memsize = 16;
char **envp = (char **) KSEG1ADDR(fw_arg2);
ioport_resource.start = IOPORT_RESOURCE_START;
ioport_resource.end = IOPORT_RESOURCE_END;
iomem_resource.start = IOMEM_RESOURCE_START;
iomem_resource.end = IOMEM_RESOURCE_END;
set_io_port_base((unsigned long) KSEG1);
while (*envp) {
char *e = (char *)KSEG1ADDR(*envp);
if (!strncmp(e, "memsize=", 8)) {
e += 8;
if (strict_strtoul(e, 0, &memsize))
pr_warn("bad memsize specified\n");
}
envp++;
}
memsize *= 1024 * 1024;
add_memory_region(0x00000000, memsize, BOOT_MEM_RAM);
}
static int __init
lantiq_setup(void)
{
ltq_soc_setup();
mips_machine_setup();
return 0;
}
arch_initcall(lantiq_setup);
static void __init
lantiq_generic_init(void)
{
/* Nothing to do */
}
MIPS_MACHINE(LTQ_MACH_GENERIC,
"Generic",
"Generic Lantiq based board",
lantiq_generic_init);

View file

@ -0,0 +1,23 @@
if SOC_XWAY
menu "MIPS Machine"
config LANTIQ_MACH_EASY50712
bool "Easy50712 - Danube"
default y
endmenu
endif
if SOC_AMAZON_SE
menu "MIPS Machine"
config LANTIQ_MACH_EASY50601
bool "Easy50601 - Amazon SE"
default y
endmenu
endif

View file

@ -0,0 +1,7 @@
obj-y := pmu.o ebu.o reset.o gpio.o gpio_stp.o gpio_ebu.o devices.o dma.o
obj-$(CONFIG_SOC_XWAY) += clk-xway.o prom-xway.o setup-xway.o
obj-$(CONFIG_SOC_AMAZON_SE) += clk-ase.o prom-ase.o setup-ase.o
obj-$(CONFIG_LANTIQ_MACH_EASY50712) += mach-easy50712.o
obj-$(CONFIG_LANTIQ_MACH_EASY50601) += mach-easy50601.o

View file

@ -0,0 +1,48 @@
/*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 as published
* by the Free Software Foundation.
*
* Copyright (C) 2011 John Crispin <blogic@openwrt.org>
*/
#include <linux/io.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/clk.h>
#include <asm/time.h>
#include <asm/irq.h>
#include <asm/div64.h>
#include <lantiq_soc.h>
/* cgu registers */
#define LTQ_CGU_SYS 0x0010
unsigned int ltq_get_io_region_clock(void)
{
return CLOCK_133M;
}
EXPORT_SYMBOL(ltq_get_io_region_clock);
unsigned int ltq_get_fpi_bus_clock(int fpi)
{
return CLOCK_133M;
}
EXPORT_SYMBOL(ltq_get_fpi_bus_clock);
unsigned int ltq_get_cpu_hz(void)
{
if (ltq_cgu_r32(LTQ_CGU_SYS) & (1 << 5))
return CLOCK_266M;
else
return CLOCK_133M;
}
EXPORT_SYMBOL(ltq_get_cpu_hz);
unsigned int ltq_get_fpi_hz(void)
{
return CLOCK_133M;
}
EXPORT_SYMBOL(ltq_get_fpi_hz);

View file

@ -0,0 +1,223 @@
/*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 as published
* by the Free Software Foundation.
*
* Copyright (C) 2010 John Crispin <blogic@openwrt.org>
*/
#include <linux/io.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/clk.h>
#include <asm/time.h>
#include <asm/irq.h>
#include <asm/div64.h>
#include <lantiq_soc.h>
static unsigned int ltq_ram_clocks[] = {
CLOCK_167M, CLOCK_133M, CLOCK_111M, CLOCK_83M };
#define DDR_HZ ltq_ram_clocks[ltq_cgu_r32(LTQ_CGU_SYS) & 0x3]
#define BASIC_FREQUENCY_1 35328000
#define BASIC_FREQUENCY_2 36000000
#define BASIS_REQUENCY_USB 12000000
#define GET_BITS(x, msb, lsb) \
(((x) & ((1 << ((msb) + 1)) - 1)) >> (lsb))
#define LTQ_CGU_PLL0_CFG 0x0004
#define LTQ_CGU_PLL1_CFG 0x0008
#define LTQ_CGU_PLL2_CFG 0x000C
#define LTQ_CGU_SYS 0x0010
#define LTQ_CGU_UPDATE 0x0014
#define LTQ_CGU_IF_CLK 0x0018
#define LTQ_CGU_OSC_CON 0x001C
#define LTQ_CGU_SMD 0x0020
#define LTQ_CGU_CT1SR 0x0028
#define LTQ_CGU_CT2SR 0x002C
#define LTQ_CGU_PCMCR 0x0030
#define LTQ_CGU_PCI_CR 0x0034
#define LTQ_CGU_PD_PC 0x0038
#define LTQ_CGU_FMR 0x003C
#define CGU_PLL0_PHASE_DIVIDER_ENABLE \
(ltq_cgu_r32(LTQ_CGU_PLL0_CFG) & (1 << 31))
#define CGU_PLL0_BYPASS \
(ltq_cgu_r32(LTQ_CGU_PLL0_CFG) & (1 << 30))
#define CGU_PLL0_CFG_DSMSEL \
(ltq_cgu_r32(LTQ_CGU_PLL0_CFG) & (1 << 28))
#define CGU_PLL0_CFG_FRAC_EN \
(ltq_cgu_r32(LTQ_CGU_PLL0_CFG) & (1 << 27))
#define CGU_PLL1_SRC \
(ltq_cgu_r32(LTQ_CGU_PLL1_CFG) & (1 << 31))
#define CGU_PLL2_PHASE_DIVIDER_ENABLE \
(ltq_cgu_r32(LTQ_CGU_PLL2_CFG) & (1 << 20))
#define CGU_SYS_FPI_SEL (1 << 6)
#define CGU_SYS_DDR_SEL 0x3
#define CGU_PLL0_SRC (1 << 29)
#define CGU_PLL0_CFG_PLLK GET_BITS(ltq_cgu_r32(LTQ_CGU_PLL0_CFG), 26, 17)
#define CGU_PLL0_CFG_PLLN GET_BITS(ltq_cgu_r32(LTQ_CGU_PLL0_CFG), 12, 6)
#define CGU_PLL0_CFG_PLLM GET_BITS(ltq_cgu_r32(LTQ_CGU_PLL0_CFG), 5, 2)
#define CGU_PLL2_SRC GET_BITS(ltq_cgu_r32(LTQ_CGU_PLL2_CFG), 18, 17)
#define CGU_PLL2_CFG_INPUT_DIV GET_BITS(ltq_cgu_r32(LTQ_CGU_PLL2_CFG), 16, 13)
static unsigned int ltq_get_pll0_fdiv(void);
static inline unsigned int get_input_clock(int pll)
{
switch (pll) {
case 0:
if (ltq_cgu_r32(LTQ_CGU_PLL0_CFG) & CGU_PLL0_SRC)
return BASIS_REQUENCY_USB;
else if (CGU_PLL0_PHASE_DIVIDER_ENABLE)
return BASIC_FREQUENCY_1;
else
return BASIC_FREQUENCY_2;
case 1:
if (CGU_PLL1_SRC)
return BASIS_REQUENCY_USB;
else if (CGU_PLL0_PHASE_DIVIDER_ENABLE)
return BASIC_FREQUENCY_1;
else
return BASIC_FREQUENCY_2;
case 2:
switch (CGU_PLL2_SRC) {
case 0:
return ltq_get_pll0_fdiv();
case 1:
return CGU_PLL2_PHASE_DIVIDER_ENABLE ?
BASIC_FREQUENCY_1 :
BASIC_FREQUENCY_2;
case 2:
return BASIS_REQUENCY_USB;
}
default:
return 0;
}
}
static inline unsigned int cal_dsm(int pll, unsigned int num, unsigned int den)
{
u64 res, clock = get_input_clock(pll);
res = num * clock;
do_div(res, den);
return res;
}
static inline unsigned int mash_dsm(int pll, unsigned int M, unsigned int N,
unsigned int K)
{
unsigned int num = ((N + 1) << 10) + K;
unsigned int den = (M + 1) << 10;
return cal_dsm(pll, num, den);
}
static inline unsigned int ssff_dsm_1(int pll, unsigned int M, unsigned int N,
unsigned int K)
{
unsigned int num = ((N + 1) << 11) + K + 512;
unsigned int den = (M + 1) << 11;
return cal_dsm(pll, num, den);
}
static inline unsigned int ssff_dsm_2(int pll, unsigned int M, unsigned int N,
unsigned int K)
{
unsigned int num = K >= 512 ?
((N + 1) << 12) + K - 512 : ((N + 1) << 12) + K + 3584;
unsigned int den = (M + 1) << 12;
return cal_dsm(pll, num, den);
}
static inline unsigned int dsm(int pll, unsigned int M, unsigned int N,
unsigned int K, unsigned int dsmsel, unsigned int phase_div_en)
{
if (!dsmsel)
return mash_dsm(pll, M, N, K);
else if (!phase_div_en)
return mash_dsm(pll, M, N, K);
else
return ssff_dsm_2(pll, M, N, K);
}
static inline unsigned int ltq_get_pll0_fosc(void)
{
if (CGU_PLL0_BYPASS)
return get_input_clock(0);
else
return !CGU_PLL0_CFG_FRAC_EN
? dsm(0, CGU_PLL0_CFG_PLLM, CGU_PLL0_CFG_PLLN, 0,
CGU_PLL0_CFG_DSMSEL,
CGU_PLL0_PHASE_DIVIDER_ENABLE)
: dsm(0, CGU_PLL0_CFG_PLLM, CGU_PLL0_CFG_PLLN,
CGU_PLL0_CFG_PLLK, CGU_PLL0_CFG_DSMSEL,
CGU_PLL0_PHASE_DIVIDER_ENABLE);
}
static unsigned int ltq_get_pll0_fdiv(void)
{
unsigned int div = CGU_PLL2_CFG_INPUT_DIV + 1;
return (ltq_get_pll0_fosc() + (div >> 1)) / div;
}
unsigned int ltq_get_io_region_clock(void)
{
unsigned int ret = ltq_get_pll0_fosc();
switch (ltq_cgu_r32(LTQ_CGU_PLL2_CFG) & CGU_SYS_DDR_SEL) {
default:
case 0:
return (ret + 1) / 2;
case 1:
return (ret * 2 + 2) / 5;
case 2:
return (ret + 1) / 3;
case 3:
return (ret + 2) / 4;
}
}
EXPORT_SYMBOL(ltq_get_io_region_clock);
unsigned int ltq_get_fpi_bus_clock(int fpi)
{
unsigned int ret = ltq_get_io_region_clock();
if ((fpi == 2) && (ltq_cgu_r32(LTQ_CGU_SYS) & CGU_SYS_FPI_SEL))
ret >>= 1;
return ret;
}
EXPORT_SYMBOL(ltq_get_fpi_bus_clock);
unsigned int ltq_get_cpu_hz(void)
{
switch (ltq_cgu_r32(LTQ_CGU_SYS) & 0xc) {
case 0:
return CLOCK_333M;
case 4:
return DDR_HZ;
case 8:
return DDR_HZ << 1;
default:
return DDR_HZ >> 1;
}
}
EXPORT_SYMBOL(ltq_get_cpu_hz);
unsigned int ltq_get_fpi_hz(void)
{
unsigned int ddr_clock = DDR_HZ;
if (ltq_cgu_r32(LTQ_CGU_SYS) & 0x40)
return ddr_clock >> 1;
return ddr_clock;
}
EXPORT_SYMBOL(ltq_get_fpi_hz);

View file

@ -0,0 +1,121 @@
/*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 as published
* by the Free Software Foundation.
*
* Copyright (C) 2010 John Crispin <blogic@openwrt.org>
*/
#include <linux/init.h>
#include <linux/module.h>
#include <linux/types.h>
#include <linux/string.h>
#include <linux/mtd/physmap.h>
#include <linux/kernel.h>
#include <linux/reboot.h>
#include <linux/platform_device.h>
#include <linux/leds.h>
#include <linux/etherdevice.h>
#include <linux/reboot.h>
#include <linux/time.h>
#include <linux/io.h>
#include <linux/gpio.h>
#include <linux/leds.h>
#include <asm/bootinfo.h>
#include <asm/irq.h>
#include <lantiq_soc.h>
#include <lantiq_irq.h>
#include <lantiq_platform.h>
#include "devices.h"
/* gpio */
static struct resource ltq_gpio_resource[] = {
{
.name = "gpio0",
.start = LTQ_GPIO0_BASE_ADDR,
.end = LTQ_GPIO0_BASE_ADDR + LTQ_GPIO_SIZE - 1,
.flags = IORESOURCE_MEM,
}, {
.name = "gpio1",
.start = LTQ_GPIO1_BASE_ADDR,
.end = LTQ_GPIO1_BASE_ADDR + LTQ_GPIO_SIZE - 1,
.flags = IORESOURCE_MEM,
}, {
.name = "gpio2",
.start = LTQ_GPIO2_BASE_ADDR,
.end = LTQ_GPIO2_BASE_ADDR + LTQ_GPIO_SIZE - 1,
.flags = IORESOURCE_MEM,
}
};
void __init ltq_register_gpio(void)
{
platform_device_register_simple("ltq_gpio", 0,
&ltq_gpio_resource[0], 1);
platform_device_register_simple("ltq_gpio", 1,
&ltq_gpio_resource[1], 1);
/* AR9 and VR9 have an extra gpio block */
if (ltq_is_ar9() || ltq_is_vr9()) {
platform_device_register_simple("ltq_gpio", 2,
&ltq_gpio_resource[2], 1);
}
}
/* serial to parallel conversion */
static struct resource ltq_stp_resource = {
.name = "stp",
.start = LTQ_STP_BASE_ADDR,
.end = LTQ_STP_BASE_ADDR + LTQ_STP_SIZE - 1,
.flags = IORESOURCE_MEM,
};
void __init ltq_register_gpio_stp(void)
{
platform_device_register_simple("ltq_stp", 0, &ltq_stp_resource, 1);
}
/* asc ports - amazon se has its own serial mapping */
static struct resource ltq_ase_asc_resources[] = {
{
.name = "asc0",
.start = LTQ_ASC1_BASE_ADDR,
.end = LTQ_ASC1_BASE_ADDR + LTQ_ASC_SIZE - 1,
.flags = IORESOURCE_MEM,
},
IRQ_RES(tx, LTQ_ASC_ASE_TIR),
IRQ_RES(rx, LTQ_ASC_ASE_RIR),
IRQ_RES(err, LTQ_ASC_ASE_EIR),
};
void __init ltq_register_ase_asc(void)
{
platform_device_register_simple("ltq_asc", 0,
ltq_ase_asc_resources, ARRAY_SIZE(ltq_ase_asc_resources));
}
/* ethernet */
static struct resource ltq_etop_resources = {
.name = "etop",
.start = LTQ_ETOP_BASE_ADDR,
.end = LTQ_ETOP_BASE_ADDR + LTQ_ETOP_SIZE - 1,
.flags = IORESOURCE_MEM,
};
static struct platform_device ltq_etop = {
.name = "ltq_etop",
.resource = &ltq_etop_resources,
.num_resources = 1,
};
void __init
ltq_register_etop(struct ltq_eth_data *eth)
{
if (eth) {
ltq_etop.dev.platform_data = eth;
platform_device_register(&ltq_etop);
}
}

View file

@ -0,0 +1,20 @@
/*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 as published
* by the Free Software Foundation.
*
* Copyright (C) 2010 John Crispin <blogic@openwrt.org>
*/
#ifndef _LTQ_DEVICES_XWAY_H__
#define _LTQ_DEVICES_XWAY_H__
#include "../devices.h"
#include <linux/phy.h>
extern void ltq_register_gpio(void);
extern void ltq_register_gpio_stp(void);
extern void ltq_register_ase_asc(void);
extern void ltq_register_etop(struct ltq_eth_data *eth);
#endif

253
arch/mips/lantiq/xway/dma.c Normal file
View file

@ -0,0 +1,253 @@
/*
* 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.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
*
* Copyright (C) 2011 John Crispin <blogic@openwrt.org>
*/
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/io.h>
#include <linux/dma-mapping.h>
#include <lantiq_soc.h>
#include <xway_dma.h>
#define LTQ_DMA_CTRL 0x10
#define LTQ_DMA_CPOLL 0x14
#define LTQ_DMA_CS 0x18
#define LTQ_DMA_CCTRL 0x1C
#define LTQ_DMA_CDBA 0x20
#define LTQ_DMA_CDLEN 0x24
#define LTQ_DMA_CIS 0x28
#define LTQ_DMA_CIE 0x2C
#define LTQ_DMA_PS 0x40
#define LTQ_DMA_PCTRL 0x44
#define LTQ_DMA_IRNEN 0xf4
#define DMA_DESCPT BIT(3) /* descriptor complete irq */
#define DMA_TX BIT(8) /* TX channel direction */
#define DMA_CHAN_ON BIT(0) /* channel on / off bit */
#define DMA_PDEN BIT(6) /* enable packet drop */
#define DMA_CHAN_RST BIT(1) /* channel on / off bit */
#define DMA_RESET BIT(0) /* channel on / off bit */
#define DMA_IRQ_ACK 0x7e /* IRQ status register */
#define DMA_POLL BIT(31) /* turn on channel polling */
#define DMA_CLK_DIV4 BIT(6) /* polling clock divider */
#define DMA_2W_BURST BIT(1) /* 2 word burst length */
#define DMA_MAX_CHANNEL 20 /* the soc has 20 channels */
#define DMA_ETOP_ENDIANESS (0xf << 8) /* endianess swap etop channels */
#define DMA_WEIGHT (BIT(17) | BIT(16)) /* default channel wheight */
#define ltq_dma_r32(x) ltq_r32(ltq_dma_membase + (x))
#define ltq_dma_w32(x, y) ltq_w32(x, ltq_dma_membase + (y))
#define ltq_dma_w32_mask(x, y, z) ltq_w32_mask(x, y, \
ltq_dma_membase + (z))
static struct resource ltq_dma_resource = {
.name = "dma",
.start = LTQ_DMA_BASE_ADDR,
.end = LTQ_DMA_BASE_ADDR + LTQ_DMA_SIZE - 1,
.flags = IORESOURCE_MEM,
};
static void __iomem *ltq_dma_membase;
void
ltq_dma_enable_irq(struct ltq_dma_channel *ch)
{
unsigned long flags;
local_irq_save(flags);
ltq_dma_w32(ch->nr, LTQ_DMA_CS);
ltq_dma_w32_mask(0, 1 << ch->nr, LTQ_DMA_IRNEN);
local_irq_restore(flags);
}
EXPORT_SYMBOL_GPL(ltq_dma_enable_irq);
void
ltq_dma_disable_irq(struct ltq_dma_channel *ch)
{
unsigned long flags;
local_irq_save(flags);
ltq_dma_w32(ch->nr, LTQ_DMA_CS);
ltq_dma_w32_mask(1 << ch->nr, 0, LTQ_DMA_IRNEN);
local_irq_restore(flags);
}
EXPORT_SYMBOL_GPL(ltq_dma_disable_irq);
void
ltq_dma_ack_irq(struct ltq_dma_channel *ch)
{
unsigned long flags;
local_irq_save(flags);
ltq_dma_w32(ch->nr, LTQ_DMA_CS);
ltq_dma_w32(DMA_IRQ_ACK, LTQ_DMA_CIS);
local_irq_restore(flags);
}
EXPORT_SYMBOL_GPL(ltq_dma_ack_irq);
void
ltq_dma_open(struct ltq_dma_channel *ch)
{
unsigned long flag;
local_irq_save(flag);
ltq_dma_w32(ch->nr, LTQ_DMA_CS);
ltq_dma_w32_mask(0, DMA_CHAN_ON, LTQ_DMA_CCTRL);
ltq_dma_enable_irq(ch);
local_irq_restore(flag);
}
EXPORT_SYMBOL_GPL(ltq_dma_open);
void
ltq_dma_close(struct ltq_dma_channel *ch)
{
unsigned long flag;
local_irq_save(flag);
ltq_dma_w32(ch->nr, LTQ_DMA_CS);
ltq_dma_w32_mask(DMA_CHAN_ON, 0, LTQ_DMA_CCTRL);
ltq_dma_disable_irq(ch);
local_irq_restore(flag);
}
EXPORT_SYMBOL_GPL(ltq_dma_close);
static void
ltq_dma_alloc(struct ltq_dma_channel *ch)
{
unsigned long flags;
ch->desc = 0;
ch->desc_base = dma_alloc_coherent(NULL,
LTQ_DESC_NUM * LTQ_DESC_SIZE,
&ch->phys, GFP_ATOMIC);
memset(ch->desc_base, 0, LTQ_DESC_NUM * LTQ_DESC_SIZE);
local_irq_save(flags);
ltq_dma_w32(ch->nr, LTQ_DMA_CS);
ltq_dma_w32(ch->phys, LTQ_DMA_CDBA);
ltq_dma_w32(LTQ_DESC_NUM, LTQ_DMA_CDLEN);
ltq_dma_w32_mask(DMA_CHAN_ON, 0, LTQ_DMA_CCTRL);
wmb();
ltq_dma_w32_mask(0, DMA_CHAN_RST, LTQ_DMA_CCTRL);
while (ltq_dma_r32(LTQ_DMA_CCTRL) & DMA_CHAN_RST)
;
local_irq_restore(flags);
}
void
ltq_dma_alloc_tx(struct ltq_dma_channel *ch)
{
unsigned long flags;
ltq_dma_alloc(ch);
local_irq_save(flags);
ltq_dma_w32(DMA_DESCPT, LTQ_DMA_CIE);
ltq_dma_w32_mask(0, 1 << ch->nr, LTQ_DMA_IRNEN);
ltq_dma_w32(DMA_WEIGHT | DMA_TX, LTQ_DMA_CCTRL);
local_irq_restore(flags);
}
EXPORT_SYMBOL_GPL(ltq_dma_alloc_tx);
void
ltq_dma_alloc_rx(struct ltq_dma_channel *ch)
{
unsigned long flags;
ltq_dma_alloc(ch);
local_irq_save(flags);
ltq_dma_w32(DMA_DESCPT, LTQ_DMA_CIE);
ltq_dma_w32_mask(0, 1 << ch->nr, LTQ_DMA_IRNEN);
ltq_dma_w32(DMA_WEIGHT, LTQ_DMA_CCTRL);
local_irq_restore(flags);
}
EXPORT_SYMBOL_GPL(ltq_dma_alloc_rx);
void
ltq_dma_free(struct ltq_dma_channel *ch)
{
if (!ch->desc_base)
return;
ltq_dma_close(ch);
dma_free_coherent(NULL, LTQ_DESC_NUM * LTQ_DESC_SIZE,
ch->desc_base, ch->phys);
}
EXPORT_SYMBOL_GPL(ltq_dma_free);
void
ltq_dma_init_port(int p)
{
ltq_dma_w32(p, LTQ_DMA_PS);
switch (p) {
case DMA_PORT_ETOP:
/*
* Tell the DMA engine to swap the endianess of data frames and
* drop packets if the channel arbitration fails.
*/
ltq_dma_w32_mask(0, DMA_ETOP_ENDIANESS | DMA_PDEN,
LTQ_DMA_PCTRL);
break;
case DMA_PORT_DEU:
ltq_dma_w32((DMA_2W_BURST << 4) | (DMA_2W_BURST << 2),
LTQ_DMA_PCTRL);
break;
default:
break;
}
}
EXPORT_SYMBOL_GPL(ltq_dma_init_port);
int __init
ltq_dma_init(void)
{
int i;
/* insert and request the memory region */
if (insert_resource(&iomem_resource, &ltq_dma_resource) < 0)
panic("Failed to insert dma memory\n");
if (request_mem_region(ltq_dma_resource.start,
resource_size(&ltq_dma_resource), "dma") < 0)
panic("Failed to request dma memory\n");
/* remap dma register range */
ltq_dma_membase = ioremap_nocache(ltq_dma_resource.start,
resource_size(&ltq_dma_resource));
if (!ltq_dma_membase)
panic("Failed to remap dma memory\n");
/* power up and reset the dma engine */
ltq_pmu_enable(PMU_DMA);
ltq_dma_w32_mask(0, DMA_RESET, LTQ_DMA_CTRL);
/* disable all interrupts */
ltq_dma_w32(0, LTQ_DMA_IRNEN);
/* reset/configure each channel */
for (i = 0; i < DMA_MAX_CHANNEL; i++) {
ltq_dma_w32(i, LTQ_DMA_CS);
ltq_dma_w32(DMA_CHAN_RST, LTQ_DMA_CCTRL);
ltq_dma_w32(DMA_POLL | DMA_CLK_DIV4, LTQ_DMA_CPOLL);
ltq_dma_w32_mask(DMA_CHAN_ON, 0, LTQ_DMA_CCTRL);
}
return 0;
}
postcore_initcall(ltq_dma_init);

View file

@ -0,0 +1,53 @@
/*
* 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.
*
* EBU - the external bus unit attaches PCI, NOR and NAND
*
* Copyright (C) 2010 John Crispin <blogic@openwrt.org>
*/
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/version.h>
#include <linux/ioport.h>
#include <lantiq_soc.h>
/* all access to the ebu must be locked */
DEFINE_SPINLOCK(ebu_lock);
EXPORT_SYMBOL_GPL(ebu_lock);
static struct resource ltq_ebu_resource = {
.name = "ebu",
.start = LTQ_EBU_BASE_ADDR,
.end = LTQ_EBU_BASE_ADDR + LTQ_EBU_SIZE - 1,
.flags = IORESOURCE_MEM,
};
/* remapped base addr of the clock unit and external bus unit */
void __iomem *ltq_ebu_membase;
static int __init lantiq_ebu_init(void)
{
/* insert and request the memory region */
if (insert_resource(&iomem_resource, &ltq_ebu_resource) < 0)
panic("Failed to insert ebu memory\n");
if (request_mem_region(ltq_ebu_resource.start,
resource_size(&ltq_ebu_resource), "ebu") < 0)
panic("Failed to request ebu memory\n");
/* remap ebu register range */
ltq_ebu_membase = ioremap_nocache(ltq_ebu_resource.start,
resource_size(&ltq_ebu_resource));
if (!ltq_ebu_membase)
panic("Failed to remap ebu memory\n");
/* make sure to unprotect the memory region where flash is located */
ltq_ebu_w32(ltq_ebu_r32(LTQ_EBU_BUSCON0) & ~EBU_WRDIS, LTQ_EBU_BUSCON0);
return 0;
}
postcore_initcall(lantiq_ebu_init);

View file

@ -0,0 +1,195 @@
/*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 as published
* by the Free Software Foundation.
*
* Copyright (C) 2010 John Crispin <blogic@openwrt.org>
*/
#include <linux/slab.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/gpio.h>
#include <linux/ioport.h>
#include <linux/io.h>
#include <lantiq_soc.h>
#define LTQ_GPIO_OUT 0x00
#define LTQ_GPIO_IN 0x04
#define LTQ_GPIO_DIR 0x08
#define LTQ_GPIO_ALTSEL0 0x0C
#define LTQ_GPIO_ALTSEL1 0x10
#define LTQ_GPIO_OD 0x14
#define PINS_PER_PORT 16
#define MAX_PORTS 3
#define ltq_gpio_getbit(m, r, p) (!!(ltq_r32(m + r) & (1 << p)))
#define ltq_gpio_setbit(m, r, p) ltq_w32_mask(0, (1 << p), m + r)
#define ltq_gpio_clearbit(m, r, p) ltq_w32_mask((1 << p), 0, m + r)
struct ltq_gpio {
void __iomem *membase;
struct gpio_chip chip;
};
static struct ltq_gpio ltq_gpio_port[MAX_PORTS];
int gpio_to_irq(unsigned int gpio)
{
return -EINVAL;
}
EXPORT_SYMBOL(gpio_to_irq);
int irq_to_gpio(unsigned int gpio)
{
return -EINVAL;
}
EXPORT_SYMBOL(irq_to_gpio);
int ltq_gpio_request(unsigned int pin, unsigned int alt0,
unsigned int alt1, unsigned int dir, const char *name)
{
int id = 0;
if (pin >= (MAX_PORTS * PINS_PER_PORT))
return -EINVAL;
if (gpio_request(pin, name)) {
pr_err("failed to setup lantiq gpio: %s\n", name);
return -EBUSY;
}
if (dir)
gpio_direction_output(pin, 1);
else
gpio_direction_input(pin);
while (pin >= PINS_PER_PORT) {
pin -= PINS_PER_PORT;
id++;
}
if (alt0)
ltq_gpio_setbit(ltq_gpio_port[id].membase,
LTQ_GPIO_ALTSEL0, pin);
else
ltq_gpio_clearbit(ltq_gpio_port[id].membase,
LTQ_GPIO_ALTSEL0, pin);
if (alt1)
ltq_gpio_setbit(ltq_gpio_port[id].membase,
LTQ_GPIO_ALTSEL1, pin);
else
ltq_gpio_clearbit(ltq_gpio_port[id].membase,
LTQ_GPIO_ALTSEL1, pin);
return 0;
}
EXPORT_SYMBOL(ltq_gpio_request);
static void ltq_gpio_set(struct gpio_chip *chip, unsigned int offset, int value)
{
struct ltq_gpio *ltq_gpio = container_of(chip, struct ltq_gpio, chip);
if (value)
ltq_gpio_setbit(ltq_gpio->membase, LTQ_GPIO_OUT, offset);
else
ltq_gpio_clearbit(ltq_gpio->membase, LTQ_GPIO_OUT, offset);
}
static int ltq_gpio_get(struct gpio_chip *chip, unsigned int offset)
{
struct ltq_gpio *ltq_gpio = container_of(chip, struct ltq_gpio, chip);
return ltq_gpio_getbit(ltq_gpio->membase, LTQ_GPIO_IN, offset);
}
static int ltq_gpio_direction_input(struct gpio_chip *chip, unsigned int offset)
{
struct ltq_gpio *ltq_gpio = container_of(chip, struct ltq_gpio, chip);
ltq_gpio_clearbit(ltq_gpio->membase, LTQ_GPIO_OD, offset);
ltq_gpio_clearbit(ltq_gpio->membase, LTQ_GPIO_DIR, offset);
return 0;
}
static int ltq_gpio_direction_output(struct gpio_chip *chip,
unsigned int offset, int value)
{
struct ltq_gpio *ltq_gpio = container_of(chip, struct ltq_gpio, chip);
ltq_gpio_setbit(ltq_gpio->membase, LTQ_GPIO_OD, offset);
ltq_gpio_setbit(ltq_gpio->membase, LTQ_GPIO_DIR, offset);
ltq_gpio_set(chip, offset, value);
return 0;
}
static int ltq_gpio_req(struct gpio_chip *chip, unsigned offset)
{
struct ltq_gpio *ltq_gpio = container_of(chip, struct ltq_gpio, chip);
ltq_gpio_clearbit(ltq_gpio->membase, LTQ_GPIO_ALTSEL0, offset);
ltq_gpio_clearbit(ltq_gpio->membase, LTQ_GPIO_ALTSEL1, offset);
return 0;
}
static int ltq_gpio_probe(struct platform_device *pdev)
{
struct resource *res;
if (pdev->id >= MAX_PORTS) {
dev_err(&pdev->dev, "invalid gpio port %d\n",
pdev->id);
return -EINVAL;
}
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!res) {
dev_err(&pdev->dev, "failed to get memory for gpio port %d\n",
pdev->id);
return -ENOENT;
}
res = devm_request_mem_region(&pdev->dev, res->start,
resource_size(res), dev_name(&pdev->dev));
if (!res) {
dev_err(&pdev->dev,
"failed to request memory for gpio port %d\n",
pdev->id);
return -EBUSY;
}
ltq_gpio_port[pdev->id].membase = devm_ioremap_nocache(&pdev->dev,
res->start, resource_size(res));
if (!ltq_gpio_port[pdev->id].membase) {
dev_err(&pdev->dev, "failed to remap memory for gpio port %d\n",
pdev->id);
return -ENOMEM;
}
ltq_gpio_port[pdev->id].chip.label = "ltq_gpio";
ltq_gpio_port[pdev->id].chip.direction_input = ltq_gpio_direction_input;
ltq_gpio_port[pdev->id].chip.direction_output =
ltq_gpio_direction_output;
ltq_gpio_port[pdev->id].chip.get = ltq_gpio_get;
ltq_gpio_port[pdev->id].chip.set = ltq_gpio_set;
ltq_gpio_port[pdev->id].chip.request = ltq_gpio_req;
ltq_gpio_port[pdev->id].chip.base = PINS_PER_PORT * pdev->id;
ltq_gpio_port[pdev->id].chip.ngpio = PINS_PER_PORT;
platform_set_drvdata(pdev, &ltq_gpio_port[pdev->id]);
return gpiochip_add(&ltq_gpio_port[pdev->id].chip);
}
static struct platform_driver
ltq_gpio_driver = {
.probe = ltq_gpio_probe,
.driver = {
.name = "ltq_gpio",
.owner = THIS_MODULE,
},
};
int __init ltq_gpio_init(void)
{
int ret = platform_driver_register(&ltq_gpio_driver);
if (ret)
pr_info("ltq_gpio : Error registering platfom driver!");
return ret;
}
postcore_initcall(ltq_gpio_init);

View file

@ -0,0 +1,126 @@
/*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 as published
* by the Free Software Foundation.
*
* Copyright (C) 2010 John Crispin <blogic@openwrt.org>
*/
#include <linux/init.h>
#include <linux/module.h>
#include <linux/types.h>
#include <linux/platform_device.h>
#include <linux/mutex.h>
#include <linux/gpio.h>
#include <linux/io.h>
#include <lantiq_soc.h>
/*
* By attaching hardware latches to the EBU it is possible to create output
* only gpios. This driver configures a special memory address, which when
* written to outputs 16 bit to the latches.
*/
#define LTQ_EBU_BUSCON 0x1e7ff /* 16 bit access, slowest timing */
#define LTQ_EBU_WP 0x80000000 /* write protect bit */
/* we keep a shadow value of the last value written to the ebu */
static int ltq_ebu_gpio_shadow = 0x0;
static void __iomem *ltq_ebu_gpio_membase;
static void ltq_ebu_apply(void)
{
unsigned long flags;
spin_lock_irqsave(&ebu_lock, flags);
ltq_ebu_w32(LTQ_EBU_BUSCON, LTQ_EBU_BUSCON1);
*((__u16 *)ltq_ebu_gpio_membase) = ltq_ebu_gpio_shadow;
ltq_ebu_w32(LTQ_EBU_BUSCON | LTQ_EBU_WP, LTQ_EBU_BUSCON1);
spin_unlock_irqrestore(&ebu_lock, flags);
}
static void ltq_ebu_set(struct gpio_chip *chip, unsigned offset, int value)
{
if (value)
ltq_ebu_gpio_shadow |= (1 << offset);
else
ltq_ebu_gpio_shadow &= ~(1 << offset);
ltq_ebu_apply();
}
static int ltq_ebu_direction_output(struct gpio_chip *chip, unsigned offset,
int value)
{
ltq_ebu_set(chip, offset, value);
return 0;
}
static struct gpio_chip ltq_ebu_chip = {
.label = "ltq_ebu",
.direction_output = ltq_ebu_direction_output,
.set = ltq_ebu_set,
.base = 72,
.ngpio = 16,
.can_sleep = 1,
.owner = THIS_MODULE,
};
static int ltq_ebu_probe(struct platform_device *pdev)
{
int ret = 0;
struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!res) {
dev_err(&pdev->dev, "failed to get memory resource\n");
return -ENOENT;
}
res = devm_request_mem_region(&pdev->dev, res->start,
resource_size(res), dev_name(&pdev->dev));
if (!res) {
dev_err(&pdev->dev, "failed to request memory resource\n");
return -EBUSY;
}
ltq_ebu_gpio_membase = devm_ioremap_nocache(&pdev->dev, res->start,
resource_size(res));
if (!ltq_ebu_gpio_membase) {
dev_err(&pdev->dev, "Failed to ioremap mem region\n");
return -ENOMEM;
}
/* grab the default shadow value passed form the platform code */
ltq_ebu_gpio_shadow = (unsigned int) pdev->dev.platform_data;
/* tell the ebu controller which memory address we will be using */
ltq_ebu_w32(pdev->resource->start | 0x1, LTQ_EBU_ADDRSEL1);
/* write protect the region */
ltq_ebu_w32(LTQ_EBU_BUSCON | LTQ_EBU_WP, LTQ_EBU_BUSCON1);
ret = gpiochip_add(&ltq_ebu_chip);
if (!ret)
ltq_ebu_apply();
return ret;
}
static struct platform_driver ltq_ebu_driver = {
.probe = ltq_ebu_probe,
.driver = {
.name = "ltq_ebu",
.owner = THIS_MODULE,
},
};
static int __init ltq_ebu_init(void)
{
int ret = platform_driver_register(&ltq_ebu_driver);
if (ret)
pr_info("ltq_ebu : Error registering platfom driver!");
return ret;
}
postcore_initcall(ltq_ebu_init);

View file

@ -0,0 +1,157 @@
/*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 as published
* by the Free Software Foundation.
*
* Copyright (C) 2007 John Crispin <blogic@openwrt.org>
*
*/
#include <linux/slab.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/types.h>
#include <linux/platform_device.h>
#include <linux/mutex.h>
#include <linux/io.h>
#include <linux/gpio.h>
#include <lantiq_soc.h>
#define LTQ_STP_CON0 0x00
#define LTQ_STP_CON1 0x04
#define LTQ_STP_CPU0 0x08
#define LTQ_STP_CPU1 0x0C
#define LTQ_STP_AR 0x10
#define LTQ_STP_CON_SWU (1 << 31)
#define LTQ_STP_2HZ 0
#define LTQ_STP_4HZ (1 << 23)
#define LTQ_STP_8HZ (2 << 23)
#define LTQ_STP_10HZ (3 << 23)
#define LTQ_STP_SPEED_MASK (0xf << 23)
#define LTQ_STP_UPD_FPI (1 << 31)
#define LTQ_STP_UPD_MASK (3 << 30)
#define LTQ_STP_ADSL_SRC (3 << 24)
#define LTQ_STP_GROUP0 (1 << 0)
#define LTQ_STP_RISING 0
#define LTQ_STP_FALLING (1 << 26)
#define LTQ_STP_EDGE_MASK (1 << 26)
#define ltq_stp_r32(reg) __raw_readl(ltq_stp_membase + reg)
#define ltq_stp_w32(val, reg) __raw_writel(val, ltq_stp_membase + reg)
#define ltq_stp_w32_mask(clear, set, reg) \
ltq_w32((ltq_r32(ltq_stp_membase + reg) & ~(clear)) | (set), \
ltq_stp_membase + (reg))
static int ltq_stp_shadow = 0xffff;
static void __iomem *ltq_stp_membase;
static void ltq_stp_set(struct gpio_chip *chip, unsigned offset, int value)
{
if (value)
ltq_stp_shadow |= (1 << offset);
else
ltq_stp_shadow &= ~(1 << offset);
ltq_stp_w32(ltq_stp_shadow, LTQ_STP_CPU0);
}
static int ltq_stp_direction_output(struct gpio_chip *chip, unsigned offset,
int value)
{
ltq_stp_set(chip, offset, value);
return 0;
}
static struct gpio_chip ltq_stp_chip = {
.label = "ltq_stp",
.direction_output = ltq_stp_direction_output,
.set = ltq_stp_set,
.base = 48,
.ngpio = 24,
.can_sleep = 1,
.owner = THIS_MODULE,
};
static int ltq_stp_hw_init(void)
{
/* the 3 pins used to control the external stp */
ltq_gpio_request(4, 1, 0, 1, "stp-st");
ltq_gpio_request(5, 1, 0, 1, "stp-d");
ltq_gpio_request(6, 1, 0, 1, "stp-sh");
/* sane defaults */
ltq_stp_w32(0, LTQ_STP_AR);
ltq_stp_w32(0, LTQ_STP_CPU0);
ltq_stp_w32(0, LTQ_STP_CPU1);
ltq_stp_w32(LTQ_STP_CON_SWU, LTQ_STP_CON0);
ltq_stp_w32(0, LTQ_STP_CON1);
/* rising or falling edge */
ltq_stp_w32_mask(LTQ_STP_EDGE_MASK, LTQ_STP_FALLING, LTQ_STP_CON0);
/* per default stp 15-0 are set */
ltq_stp_w32_mask(0, LTQ_STP_GROUP0, LTQ_STP_CON1);
/* stp are update periodically by the FPI bus */
ltq_stp_w32_mask(LTQ_STP_UPD_MASK, LTQ_STP_UPD_FPI, LTQ_STP_CON1);
/* set stp update speed */
ltq_stp_w32_mask(LTQ_STP_SPEED_MASK, LTQ_STP_8HZ, LTQ_STP_CON1);
/* tell the hardware that pin (led) 0 and 1 are controlled
* by the dsl arc
*/
ltq_stp_w32_mask(0, LTQ_STP_ADSL_SRC, LTQ_STP_CON0);
ltq_pmu_enable(PMU_LED);
return 0;
}
static int __devinit ltq_stp_probe(struct platform_device *pdev)
{
struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
int ret = 0;
if (!res)
return -ENOENT;
res = devm_request_mem_region(&pdev->dev, res->start,
resource_size(res), dev_name(&pdev->dev));
if (!res) {
dev_err(&pdev->dev, "failed to request STP memory\n");
return -EBUSY;
}
ltq_stp_membase = devm_ioremap_nocache(&pdev->dev, res->start,
resource_size(res));
if (!ltq_stp_membase) {
dev_err(&pdev->dev, "failed to remap STP memory\n");
return -ENOMEM;
}
ret = gpiochip_add(&ltq_stp_chip);
if (!ret)
ret = ltq_stp_hw_init();
return ret;
}
static struct platform_driver ltq_stp_driver = {
.probe = ltq_stp_probe,
.driver = {
.name = "ltq_stp",
.owner = THIS_MODULE,
},
};
int __init ltq_stp_init(void)
{
int ret = platform_driver_register(&ltq_stp_driver);
if (ret)
pr_info("ltq_stp: error registering platfom driver");
return ret;
}
postcore_initcall(ltq_stp_init);

View file

@ -0,0 +1,57 @@
/*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 as published
* by the Free Software Foundation.
*
* Copyright (C) 2010 John Crispin <blogic@openwrt.org>
*/
#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 <linux/input.h>
#include <lantiq.h>
#include "../machtypes.h"
#include "devices.h"
static struct mtd_partition easy50601_partitions[] = {
{
.name = "uboot",
.offset = 0x0,
.size = 0x10000,
},
{
.name = "uboot_env",
.offset = 0x10000,
.size = 0x10000,
},
{
.name = "linux",
.offset = 0x20000,
.size = 0xE0000,
},
{
.name = "rootfs",
.offset = 0x100000,
.size = 0x300000,
},
};
static struct physmap_flash_data easy50601_flash_data = {
.nr_parts = ARRAY_SIZE(easy50601_partitions),
.parts = easy50601_partitions,
};
static void __init easy50601_init(void)
{
ltq_register_nor(&easy50601_flash_data);
}
MIPS_MACHINE(LTQ_MACH_EASY50601,
"EASY50601",
"EASY50601 Eval Board",
easy50601_init);

View file

@ -0,0 +1,74 @@
/*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 as published
* by the Free Software Foundation.
*
* Copyright (C) 2010 John Crispin <blogic@openwrt.org>
*/
#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 <linux/input.h>
#include <linux/phy.h>
#include <lantiq_soc.h>
#include <irq.h>
#include "../machtypes.h"
#include "devices.h"
static struct mtd_partition easy50712_partitions[] = {
{
.name = "uboot",
.offset = 0x0,
.size = 0x10000,
},
{
.name = "uboot_env",
.offset = 0x10000,
.size = 0x10000,
},
{
.name = "linux",
.offset = 0x20000,
.size = 0xe0000,
},
{
.name = "rootfs",
.offset = 0x100000,
.size = 0x300000,
},
};
static struct physmap_flash_data easy50712_flash_data = {
.nr_parts = ARRAY_SIZE(easy50712_partitions),
.parts = easy50712_partitions,
};
static struct ltq_pci_data ltq_pci_data = {
.clock = PCI_CLOCK_INT,
.gpio = PCI_GNT1 | PCI_REQ1,
.irq = {
[14] = INT_NUM_IM0_IRL0 + 22,
},
};
static struct ltq_eth_data ltq_eth_data = {
.mii_mode = PHY_INTERFACE_MODE_MII,
};
static void __init easy50712_init(void)
{
ltq_register_gpio_stp();
ltq_register_nor(&easy50712_flash_data);
ltq_register_pci(&ltq_pci_data);
ltq_register_etop(&ltq_eth_data);
}
MIPS_MACHINE(LTQ_MACH_EASY50712,
"EASY50712",
"EASY50712 Eval Board",
easy50712_init);

View file

@ -0,0 +1,70 @@
/*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 as published
* by the Free Software Foundation.
*
* Copyright (C) 2010 John Crispin <blogic@openwrt.org>
*/
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/version.h>
#include <linux/ioport.h>
#include <lantiq_soc.h>
/* PMU - the power management unit allows us to turn part of the core
* on and off
*/
/* the enable / disable registers */
#define LTQ_PMU_PWDCR 0x1C
#define LTQ_PMU_PWDSR 0x20
#define ltq_pmu_w32(x, y) ltq_w32((x), ltq_pmu_membase + (y))
#define ltq_pmu_r32(x) ltq_r32(ltq_pmu_membase + (x))
static struct resource ltq_pmu_resource = {
.name = "pmu",
.start = LTQ_PMU_BASE_ADDR,
.end = LTQ_PMU_BASE_ADDR + LTQ_PMU_SIZE - 1,
.flags = IORESOURCE_MEM,
};
static void __iomem *ltq_pmu_membase;
void ltq_pmu_enable(unsigned int module)
{
int err = 1000000;
ltq_pmu_w32(ltq_pmu_r32(LTQ_PMU_PWDCR) & ~module, LTQ_PMU_PWDCR);
do {} while (--err && (ltq_pmu_r32(LTQ_PMU_PWDSR) & module));
if (!err)
panic("activating PMU module failed!\n");
}
EXPORT_SYMBOL(ltq_pmu_enable);
void ltq_pmu_disable(unsigned int module)
{
ltq_pmu_w32(ltq_pmu_r32(LTQ_PMU_PWDCR) | module, LTQ_PMU_PWDCR);
}
EXPORT_SYMBOL(ltq_pmu_disable);
int __init ltq_pmu_init(void)
{
if (insert_resource(&iomem_resource, &ltq_pmu_resource) < 0)
panic("Failed to insert pmu memory\n");
if (request_mem_region(ltq_pmu_resource.start,
resource_size(&ltq_pmu_resource), "pmu") < 0)
panic("Failed to request pmu memory\n");
ltq_pmu_membase = ioremap_nocache(ltq_pmu_resource.start,
resource_size(&ltq_pmu_resource));
if (!ltq_pmu_membase)
panic("Failed to remap pmu memory\n");
return 0;
}
core_initcall(ltq_pmu_init);

View file

@ -0,0 +1,39 @@
/*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 as published
* by the Free Software Foundation.
*
* Copyright (C) 2010 John Crispin <blogic@openwrt.org>
*/
#include <linux/module.h>
#include <linux/clk.h>
#include <asm/bootinfo.h>
#include <asm/time.h>
#include <lantiq_soc.h>
#include "../prom.h"
#define SOC_AMAZON_SE "Amazon_SE"
#define PART_SHIFT 12
#define PART_MASK 0x0FFFFFFF
#define REV_SHIFT 28
#define REV_MASK 0xF0000000
void __init ltq_soc_detect(struct ltq_soc_info *i)
{
i->partnum = (ltq_r32(LTQ_MPS_CHIPID) & PART_MASK) >> PART_SHIFT;
i->rev = (ltq_r32(LTQ_MPS_CHIPID) & REV_MASK) >> REV_SHIFT;
switch (i->partnum) {
case SOC_ID_AMAZON_SE:
i->name = SOC_AMAZON_SE;
i->type = SOC_TYPE_AMAZON_SE;
break;
default:
unreachable();
break;
}
}

View file

@ -0,0 +1,54 @@
/*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 as published
* by the Free Software Foundation.
*
* Copyright (C) 2010 John Crispin <blogic@openwrt.org>
*/
#include <linux/module.h>
#include <linux/clk.h>
#include <asm/bootinfo.h>
#include <asm/time.h>
#include <lantiq_soc.h>
#include "../prom.h"
#define SOC_DANUBE "Danube"
#define SOC_TWINPASS "Twinpass"
#define SOC_AR9 "AR9"
#define PART_SHIFT 12
#define PART_MASK 0x0FFFFFFF
#define REV_SHIFT 28
#define REV_MASK 0xF0000000
void __init ltq_soc_detect(struct ltq_soc_info *i)
{
i->partnum = (ltq_r32(LTQ_MPS_CHIPID) & PART_MASK) >> PART_SHIFT;
i->rev = (ltq_r32(LTQ_MPS_CHIPID) & REV_MASK) >> REV_SHIFT;
switch (i->partnum) {
case SOC_ID_DANUBE1:
case SOC_ID_DANUBE2:
i->name = SOC_DANUBE;
i->type = SOC_TYPE_DANUBE;
break;
case SOC_ID_TWINPASS:
i->name = SOC_TWINPASS;
i->type = SOC_TYPE_DANUBE;
break;
case SOC_ID_ARX188:
case SOC_ID_ARX168:
case SOC_ID_ARX182:
i->name = SOC_AR9;
i->type = SOC_TYPE_AR9;
break;
default:
unreachable();
break;
}
}

View file

@ -0,0 +1,91 @@
/*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 as published
* by the Free Software Foundation.
*
* Copyright (C) 2010 John Crispin <blogic@openwrt.org>
*/
#include <linux/init.h>
#include <linux/io.h>
#include <linux/ioport.h>
#include <linux/pm.h>
#include <linux/module.h>
#include <asm/reboot.h>
#include <lantiq_soc.h>
#define ltq_rcu_w32(x, y) ltq_w32((x), ltq_rcu_membase + (y))
#define ltq_rcu_r32(x) ltq_r32(ltq_rcu_membase + (x))
/* register definitions */
#define LTQ_RCU_RST 0x0010
#define LTQ_RCU_RST_ALL 0x40000000
#define LTQ_RCU_RST_STAT 0x0014
#define LTQ_RCU_STAT_SHIFT 26
static struct resource ltq_rcu_resource = {
.name = "rcu",
.start = LTQ_RCU_BASE_ADDR,
.end = LTQ_RCU_BASE_ADDR + LTQ_RCU_SIZE - 1,
.flags = IORESOURCE_MEM,
};
/* remapped base addr of the reset control unit */
static void __iomem *ltq_rcu_membase;
/* This function is used by the watchdog driver */
int ltq_reset_cause(void)
{
u32 val = ltq_rcu_r32(LTQ_RCU_RST_STAT);
return val >> LTQ_RCU_STAT_SHIFT;
}
EXPORT_SYMBOL_GPL(ltq_reset_cause);
static void ltq_machine_restart(char *command)
{
pr_notice("System restart\n");
local_irq_disable();
ltq_rcu_w32(ltq_rcu_r32(LTQ_RCU_RST) | LTQ_RCU_RST_ALL, LTQ_RCU_RST);
unreachable();
}
static void ltq_machine_halt(void)
{
pr_notice("System halted.\n");
local_irq_disable();
unreachable();
}
static void ltq_machine_power_off(void)
{
pr_notice("Please turn off the power now.\n");
local_irq_disable();
unreachable();
}
static int __init mips_reboot_setup(void)
{
/* insert and request the memory region */
if (insert_resource(&iomem_resource, &ltq_rcu_resource) < 0)
panic("Failed to insert rcu memory\n");
if (request_mem_region(ltq_rcu_resource.start,
resource_size(&ltq_rcu_resource), "rcu") < 0)
panic("Failed to request rcu memory\n");
/* remap rcu register range */
ltq_rcu_membase = ioremap_nocache(ltq_rcu_resource.start,
resource_size(&ltq_rcu_resource));
if (!ltq_rcu_membase)
panic("Failed to remap rcu memory\n");
_machine_restart = ltq_machine_restart;
_machine_halt = ltq_machine_halt;
pm_power_off = ltq_machine_power_off;
return 0;
}
arch_initcall(mips_reboot_setup);

View file

@ -0,0 +1,19 @@
/*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 as published
* by the Free Software Foundation.
*
* Copyright (C) 2011 John Crispin <blogic@openwrt.org>
*/
#include <lantiq_soc.h>
#include "../prom.h"
#include "devices.h"
void __init ltq_soc_setup(void)
{
ltq_register_ase_asc();
ltq_register_gpio();
ltq_register_wdt();
}

View file

@ -0,0 +1,20 @@
/*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 as published
* by the Free Software Foundation.
*
* Copyright (C) 2011 John Crispin <blogic@openwrt.org>
*/
#include <lantiq_soc.h>
#include "../prom.h"
#include "devices.h"
void __init ltq_soc_setup(void)
{
ltq_register_asc(0);
ltq_register_asc(1);
ltq_register_gpio();
ltq_register_wdt();
}

View file

@ -28,6 +28,7 @@ obj-$(CONFIG_CPU_TX39XX) += r3k_dump_tlb.o
obj-$(CONFIG_CPU_TX49XX) += dump_tlb.o
obj-$(CONFIG_CPU_VR41XX) += dump_tlb.o
obj-$(CONFIG_CPU_CAVIUM_OCTEON) += dump_tlb.o
obj-$(CONFIG_CPU_XLR) += dump_tlb.o
# libgcc-style stuff needed in the kernel
obj-y += ashldi3.o ashrdi3.o cmpdi2.o lshrdi3.o ucmpdi2.o

Some files were not shown because too many files have changed in this diff Show more