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

Commit 9bdcf336 authored by Manuel Lauss's avatar Manuel Lauss Committed by Ralf Baechle
Browse files

MIPS: Alchemy: devboard register abstraction



All Alchemy development boards have external CPLDs with a few registers
in them.  They all share an identical register layout with only a few
minor differences (except the PB1000) in bit functions and base
addresses.

This patch
- adds a primitive facility to initialize and use these external
  registers,
- replaces all occurrences of bcsr->xxx accesses with calls to the new
  functions (the pb1200 cascade irq handling code is special).
- collects BCSR register information scattered throughout the board
  headers in a central place.

Signed-off-by: default avatarManuel Lauss <manuel.lauss@gmail.com>
Signed-off-by: default avatarRalf Baechle <ralf@linux-mips.org>
parent ebc89718
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -2,7 +2,7 @@
# Alchemy Develboards
#

obj-y += prom.o
obj-y += prom.o bcsr.o
obj-$(CONFIG_PM)		+= pm.o
obj-$(CONFIG_MIPS_PB1000)	+= pb1000/
obj-$(CONFIG_MIPS_PB1100)	+= pb1100/
+76 −0
Original line number Diff line number Diff line
/*
 * bcsr.h -- Db1xxx/Pb1xxx Devboard CPLD registers ("BCSR") abstraction.
 *
 * All Alchemy development boards (except, of course, the weird PB1000)
 * have a few registers in a CPLD with standardised layout; they mostly
 * only differ in base address.
 * All registers are 16bits wide with 32bit spacing.
 */

#include <linux/module.h>
#include <linux/spinlock.h>
#include <asm/addrspace.h>
#include <asm/io.h>
#include <asm/mach-db1x00/bcsr.h>

static struct bcsr_reg {
	void __iomem *raddr;
	spinlock_t lock;
} bcsr_regs[BCSR_CNT];

void __init bcsr_init(unsigned long bcsr1_phys, unsigned long bcsr2_phys)
{
	int i;

	bcsr1_phys = KSEG1ADDR(CPHYSADDR(bcsr1_phys));
	bcsr2_phys = KSEG1ADDR(CPHYSADDR(bcsr2_phys));

	for (i = 0; i < BCSR_CNT; i++) {
		if (i >= BCSR_HEXLEDS)
			bcsr_regs[i].raddr = (void __iomem *)bcsr2_phys +
					(0x04 * (i - BCSR_HEXLEDS));
		else
			bcsr_regs[i].raddr = (void __iomem *)bcsr1_phys +
					(0x04 * i);

		spin_lock_init(&bcsr_regs[i].lock);
	}
}

unsigned short bcsr_read(enum bcsr_id reg)
{
	unsigned short r;
	unsigned long flags;

	spin_lock_irqsave(&bcsr_regs[reg].lock, flags);
	r = __raw_readw(bcsr_regs[reg].raddr);
	spin_unlock_irqrestore(&bcsr_regs[reg].lock, flags);
	return r;
}
EXPORT_SYMBOL_GPL(bcsr_read);

void bcsr_write(enum bcsr_id reg, unsigned short val)
{
	unsigned long flags;

	spin_lock_irqsave(&bcsr_regs[reg].lock, flags);
	__raw_writew(val, bcsr_regs[reg].raddr);
	wmb();
	spin_unlock_irqrestore(&bcsr_regs[reg].lock, flags);
}
EXPORT_SYMBOL_GPL(bcsr_write);

void bcsr_mod(enum bcsr_id reg, unsigned short clr, unsigned short set)
{
	unsigned short r;
	unsigned long flags;

	spin_lock_irqsave(&bcsr_regs[reg].lock, flags);
	r = __raw_readw(bcsr_regs[reg].raddr);
	r &= ~clr;
	r |= set;
	__raw_writew(r, bcsr_regs[reg].raddr);
	wmb();
	spin_unlock_irqrestore(&bcsr_regs[reg].lock, flags);
}
EXPORT_SYMBOL_GPL(bcsr_mod);
+34 −28
Original line number Diff line number Diff line
@@ -32,12 +32,10 @@

#include <asm/mach-au1x00/au1000.h>
#include <asm/mach-db1x00/db1x00.h>
#include <asm/mach-db1x00/bcsr.h>

#include <prom.h>


static BCSR * const bcsr = (BCSR *)BCSR_KSEG1_ADDR;

const char *get_system_type(void)
{
#ifdef CONFIG_MIPS_BOSPORUS
@@ -49,15 +47,43 @@ const char *get_system_type(void)

void board_reset(void)
{
	/* Hit BCSR.SW_RESET[RESET] */
	bcsr->swreset = 0x0000;
	bcsr_write(BCSR_SYSTEM, 0);
}

void __init board_setup(void)
{
	unsigned long bcsr1, bcsr2;
	u32 pin_func = 0;
	char *argptr;

	bcsr1 = DB1000_BCSR_PHYS_ADDR;
	bcsr2 = DB1000_BCSR_PHYS_ADDR + DB1000_BCSR_HEXLED_OFS;

#ifdef CONFIG_MIPS_DB1000
	printk(KERN_INFO "AMD Alchemy Au1000/Db1000 Board\n");
#endif
#ifdef CONFIG_MIPS_DB1500
	printk(KERN_INFO "AMD Alchemy Au1500/Db1500 Board\n");
#endif
#ifdef CONFIG_MIPS_DB1100
	printk(KERN_INFO "AMD Alchemy Au1100/Db1100 Board\n");
#endif
#ifdef CONFIG_MIPS_BOSPORUS
	printk(KERN_INFO "AMD Alchemy Bosporus Board\n");
#endif
#ifdef CONFIG_MIPS_MIRAGE
	printk(KERN_INFO "AMD Alchemy Mirage Board\n");
#endif
#ifdef CONFIG_MIPS_DB1550
	printk(KERN_INFO "AMD Alchemy Au1550/Db1550 Board\n");

	bcsr1 = DB1550_BCSR_PHYS_ADDR;
	bcsr2 = DB1550_BCSR_PHYS_ADDR + DB1550_BCSR_HEXLED_OFS;
#endif

	/* initialize board register space */
	bcsr_init(bcsr1, bcsr2);

	argptr = prom_getcmdline();
#ifdef CONFIG_SERIAL_8250_CONSOLE
	argptr = strstr(argptr, "console=");
@@ -89,11 +115,10 @@ void __init board_setup(void)
	pin_func = au_readl(SYS_PINFUNC) | SYS_PF_IRF;
	au_writel(pin_func, SYS_PINFUNC);
	/* Power off until the driver is in use */
	bcsr->resets &= ~BCSR_RESETS_IRDA_MODE_MASK;
	bcsr->resets |=  BCSR_RESETS_IRDA_MODE_OFF;
	au_sync();
	bcsr_mod(BCSR_RESETS, BCSR_RESETS_IRDA_MODE_MASK,
				BCSR_RESETS_IRDA_MODE_OFF);
#endif
	bcsr->pcmcia = 0x0000; /* turn off PCMCIA power */
	bcsr_write(BCSR_PCMCIA, 0);	/* turn off PCMCIA power */

	/* Enable GPIO[31:0] inputs */
	alchemy_gpio1_input_enable();
@@ -123,23 +148,4 @@ void __init board_setup(void)
#endif

	au_sync();

#ifdef CONFIG_MIPS_DB1000
	printk(KERN_INFO "AMD Alchemy Au1000/Db1000 Board\n");
#endif
#ifdef CONFIG_MIPS_DB1500
	printk(KERN_INFO "AMD Alchemy Au1500/Db1500 Board\n");
#endif
#ifdef CONFIG_MIPS_DB1100
	printk(KERN_INFO "AMD Alchemy Au1100/Db1100 Board\n");
#endif
#ifdef CONFIG_MIPS_BOSPORUS
	printk(KERN_INFO "AMD Alchemy Bosporus Board\n");
#endif
#ifdef CONFIG_MIPS_MIRAGE
	printk(KERN_INFO "AMD Alchemy Mirage Board\n");
#endif
#ifdef CONFIG_MIPS_DB1550
	printk(KERN_INFO "AMD Alchemy Au1550/Db1550 Board\n");
#endif
}
+5 −2
Original line number Diff line number Diff line
@@ -30,6 +30,7 @@

#include <asm/mach-au1x00/au1000.h>
#include <asm/mach-pb1x00/pb1100.h>
#include <asm/mach-db1x00/bcsr.h>

#include <prom.h>

@@ -49,8 +50,7 @@ const char *get_system_type(void)

void board_reset(void)
{
	/* Hit BCSR.RST_VDDI[SOFT_RESET] */
	au_writel(0x00000000, PB1100_RST_VDDI);
	bcsr_write(BCSR_SYSTEM, 0);
}

void __init board_init_irq(void)
@@ -63,6 +63,9 @@ void __init board_setup(void)
	volatile void __iomem *base = (volatile void __iomem *)0xac000000UL;
	char *argptr;

	bcsr_init(DB1000_BCSR_PHYS_ADDR,
		  DB1000_BCSR_PHYS_ADDR + DB1000_BCSR_HEXLED_OFS);

	argptr = prom_getcmdline();
#ifdef CONFIG_SERIAL_8250_CONSOLE
	argptr = strstr(argptr, "console=");
+23 −26
Original line number Diff line number Diff line
@@ -27,6 +27,8 @@
#include <linux/init.h>
#include <linux/sched.h>

#include <asm/mach-db1x00/bcsr.h>

#include <prom.h>
#include <au1xxx.h>

@@ -38,14 +40,25 @@ const char *get_system_type(void)

void board_reset(void)
{
	bcsr->resets = 0;
	bcsr->system = 0;
	bcsr_write(BCSR_RESETS, 0);
	bcsr_write(BCSR_SYSTEM, 0);
}

void __init board_setup(void)
{
	char *argptr;

#ifdef CONFIG_MIPS_PB1200
	printk(KERN_INFO "AMD Alchemy Pb1200 Board\n");
	bcsr_init(PB1200_BCSR_PHYS_ADDR,
		  PB1200_BCSR_PHYS_ADDR + PB1200_BCSR_HEXLED_OFS);
#endif
#ifdef CONFIG_MIPS_DB1200
	printk(KERN_INFO "AMD Alchemy Db1200 Board\n");
	bcsr_init(DB1200_BCSR_PHYS_ADDR,
		  DB1200_BCSR_PHYS_ADDR + DB1200_BCSR_HEXLED_OFS);
#endif

	argptr = prom_getcmdline();
#ifdef CONFIG_SERIAL_8250_CONSOLE
	argptr = strstr(argptr, "console=");
@@ -82,7 +95,7 @@ void __init board_setup(void)
		u32 pin_func;

		/* Select SMBus in CPLD */
		bcsr->resets &= ~BCSR_RESETS_PCS0MUX;
		bcsr_mod(BCSR_RESETS, BCSR_RESETS_PSC0MUX, 0);

		pin_func = au_readl(SYS_PINFUNC);
		au_sync();
@@ -116,38 +129,24 @@ void __init board_setup(void)

	/*
	 * The Pb1200 development board uses external MUX for PSC0 to
	 * support SMB/SPI. bcsr->resets bit 12: 0=SMB 1=SPI
	 * support SMB/SPI. bcsr_resets bit 12: 0=SMB 1=SPI
	 */
#ifdef CONFIG_I2C_AU1550
	bcsr->resets &= ~BCSR_RESETS_PCS0MUX;
	bcsr_mod(BCSR_RESETS, BCSR_RESETS_PSC0MUX, 0);
#endif
	au_sync();

#ifdef CONFIG_MIPS_PB1200
	printk(KERN_INFO "AMD Alchemy Pb1200 Board\n");
#endif
#ifdef CONFIG_MIPS_DB1200
	printk(KERN_INFO "AMD Alchemy Db1200 Board\n");
#endif
}

int board_au1200fb_panel(void)
{
	BCSR *bcsr = (BCSR *)BCSR_KSEG1_ADDR;
	int p;

	p = bcsr->switches;
	p >>= 8;
	p &= 0x0F;
	return p;
	return (bcsr_read(BCSR_SWITCHES) >> 8) & 0x0f;
}

int board_au1200fb_panel_init(void)
{
	/* Apply power */
	BCSR *bcsr = (BCSR *)BCSR_KSEG1_ADDR;

	bcsr->board |= BCSR_BOARD_LCDVEE | BCSR_BOARD_LCDVDD | BCSR_BOARD_LCDBL;
	bcsr_mod(BCSR_BOARD, 0, BCSR_BOARD_LCDVEE | BCSR_BOARD_LCDVDD |
				BCSR_BOARD_LCDBL);
	/* printk(KERN_DEBUG "board_au1200fb_panel_init()\n"); */
	return 0;
}
@@ -155,10 +154,8 @@ int board_au1200fb_panel_init(void)
int board_au1200fb_panel_shutdown(void)
{
	/* Remove power */
	BCSR *bcsr = (BCSR *)BCSR_KSEG1_ADDR;

	bcsr->board &= ~(BCSR_BOARD_LCDVEE | BCSR_BOARD_LCDVDD |
			 BCSR_BOARD_LCDBL);
	bcsr_mod(BCSR_BOARD, BCSR_BOARD_LCDVEE | BCSR_BOARD_LCDVDD |
			     BCSR_BOARD_LCDBL, 0);
	/* printk(KERN_DEBUG "board_au1200fb_panel_shutdown()\n"); */
	return 0;
}
Loading