Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit fce4a1dd authored by Linus Torvalds's avatar Linus Torvalds
Browse files
* '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
  ...
parents e1f2084e 6f6c3c33
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -11,6 +11,7 @@ platforms += dec
platforms += emma
platforms += jazz
platforms += jz4740
platforms += lantiq
platforms += lasat
platforms += loongson
platforms += mipssim
+61 −0
Original line number Diff line number Diff line
@@ -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
+12 −0
Original line number Diff line number Diff line
@@ -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/

+45 −78
Original line number Diff line number Diff line
@@ -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;
+25 −21
Original line number Diff line number Diff line
@@ -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;
Loading