MIPS: Alchemy: Rewrite UART setup and constants.

Detect CPU type at runtime and setup uarts accordingly; also clean up the
uart base address mess in the process as far as possible.

Signed-off-by: Manuel Lauss <manuel.lauss@googlemail.com>
To: Linux-MIPS <linux-mips@linux-mips.org>
Cc: Florian Fainelli <florian@openwrt.org>
Cc: Wolfgang Grandegger <wg@grandegger.com>
Patchwork: https://patchwork.linux-mips.org/patch/2352/
Signed-off-by: Ralf Baechle <ralf@linux-mips.org
This commit is contained in:
Manuel Lauss 2011-05-08 10:42:17 +02:00 committed by Ralf Baechle
parent adcb86279f
commit 80130204b4
9 changed files with 107 additions and 78 deletions

View File

@ -30,21 +30,12 @@ static void alchemy_8250_pm(struct uart_port *port, unsigned int state,
#ifdef CONFIG_SERIAL_8250 #ifdef CONFIG_SERIAL_8250
switch (state) { switch (state) {
case 0: case 0:
if ((__raw_readl(port->membase + UART_MOD_CNTRL) & 3) != 3) { alchemy_uart_enable(CPHYSADDR(port->membase));
/* 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();
serial8250_do_pm(port, state, old_state); serial8250_do_pm(port, state, old_state);
break; break;
case 3: /* power off */ case 3: /* power off */
serial8250_do_pm(port, state, old_state); serial8250_do_pm(port, state, old_state);
__raw_writel(0, port->membase + UART_MOD_CNTRL); alchemy_uart_disable(CPHYSADDR(port->membase));
wmb();
break; break;
default: default:
serial8250_do_pm(port, state, old_state); serial8250_do_pm(port, state, old_state);
@ -65,38 +56,60 @@ static void alchemy_8250_pm(struct uart_port *port, unsigned int state,
.pm = alchemy_8250_pm, \ .pm = alchemy_8250_pm, \
} }
static struct plat_serial8250_port au1x00_uart_data[] = { static struct plat_serial8250_port au1x00_uart_data[][4] __initdata = {
#if defined(CONFIG_SOC_AU1000) [ALCHEMY_CPU_AU1000] = {
PORT(UART0_PHYS_ADDR, AU1000_UART0_INT), PORT(AU1000_UART0_PHYS_ADDR, AU1000_UART0_INT),
PORT(UART1_PHYS_ADDR, AU1000_UART1_INT), PORT(AU1000_UART1_PHYS_ADDR, AU1000_UART1_INT),
PORT(UART2_PHYS_ADDR, AU1000_UART2_INT), PORT(AU1000_UART2_PHYS_ADDR, AU1000_UART2_INT),
PORT(UART3_PHYS_ADDR, AU1000_UART3_INT), PORT(AU1000_UART3_PHYS_ADDR, AU1000_UART3_INT),
#elif defined(CONFIG_SOC_AU1500) },
PORT(UART0_PHYS_ADDR, AU1500_UART0_INT), [ALCHEMY_CPU_AU1500] = {
PORT(UART3_PHYS_ADDR, AU1500_UART3_INT), PORT(AU1000_UART0_PHYS_ADDR, AU1500_UART0_INT),
#elif defined(CONFIG_SOC_AU1100) PORT(AU1000_UART3_PHYS_ADDR, AU1500_UART3_INT),
PORT(UART0_PHYS_ADDR, AU1100_UART0_INT), },
PORT(UART1_PHYS_ADDR, AU1100_UART1_INT), [ALCHEMY_CPU_AU1100] = {
PORT(UART3_PHYS_ADDR, AU1100_UART3_INT), PORT(AU1000_UART0_PHYS_ADDR, AU1100_UART0_INT),
#elif defined(CONFIG_SOC_AU1550) PORT(AU1000_UART1_PHYS_ADDR, AU1100_UART1_INT),
PORT(UART0_PHYS_ADDR, AU1550_UART0_INT), PORT(AU1000_UART3_PHYS_ADDR, AU1100_UART3_INT),
PORT(UART1_PHYS_ADDR, AU1550_UART1_INT), },
PORT(UART3_PHYS_ADDR, AU1550_UART3_INT), [ALCHEMY_CPU_AU1550] = {
#elif defined(CONFIG_SOC_AU1200) PORT(AU1000_UART0_PHYS_ADDR, AU1550_UART0_INT),
PORT(UART0_PHYS_ADDR, AU1200_UART0_INT), PORT(AU1000_UART1_PHYS_ADDR, AU1550_UART1_INT),
PORT(UART1_PHYS_ADDR, AU1200_UART1_INT), PORT(AU1000_UART3_PHYS_ADDR, AU1550_UART3_INT),
#endif },
{ }, [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 = { static struct platform_device au1xx0_uart_device = {
.name = "serial8250", .name = "serial8250",
.id = PLAT8250_DEV_AU1X00, .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) */ /* OHCI (USB full speed host controller) */
static struct resource au1xxx_usb_ohci_resources[] = { static struct resource au1xxx_usb_ohci_resources[] = {
[0] = { [0] = {
@ -442,7 +455,6 @@ void __init au1xxx_override_eth_cfg(unsigned int port,
} }
static struct platform_device *au1xxx_platform_devices[] __initdata = { static struct platform_device *au1xxx_platform_devices[] __initdata = {
&au1xx0_uart_device,
&au1xxx_usb_ohci_device, &au1xxx_usb_ohci_device,
#ifdef CONFIG_FB_AU1100 #ifdef CONFIG_FB_AU1100
&au1100_lcd_device, &au1100_lcd_device,
@ -465,13 +477,10 @@ static struct platform_device *au1xxx_platform_devices[] __initdata = {
static int __init au1xxx_platform_init(void) static int __init au1xxx_platform_init(void)
{ {
unsigned int uartclk = get_au1x00_uart_baud_base() * 16; int err, i, ctype = alchemy_get_cputype();
int err, i;
unsigned char ethaddr[6]; unsigned char ethaddr[6];
/* Fill up uartclk. */ alchemy_setup_uarts(ctype);
for (i = 0; au1x00_uart_data[i].flags; i++)
au1x00_uart_data[i].uartclk = uartclk;
/* use firmware-provided mac addr if available and necessary */ /* use firmware-provided mac addr if available and necessary */
i = prom_get_ethernet_addr(ethaddr); i = prom_get_ethernet_addr(ethaddr);

View File

@ -62,5 +62,5 @@ void __init prom_init(void)
void prom_putchar(unsigned char c) 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> #include <prom.h>
#define UART1_ADDR KSEG1ADDR(UART1_PHYS_ADDR)
#define UART3_ADDR KSEG1ADDR(UART3_PHYS_ADDR)
char irq_tab_alchemy[][5] __initdata = { char irq_tab_alchemy[][5] __initdata = {
[0] = { -1, AU1500_PCI_INTA, AU1500_PCI_INTB, 0xff, 0xff }, [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) 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; pm_power_off = gpr_power_off;
_machine_halt = gpr_power_off; _machine_halt = gpr_power_off;
_machine_restart = gpr_reset; _machine_restart = gpr_reset;
/* Enable UART3 */ /* Enable UART1/3 */
au_writel(0x1, UART3_ADDR + UART_MOD_CNTRL);/* clock enable (CE) */ alchemy_uart_enable(AU1000_UART3_PHYS_ADDR);
au_writel(0x3, UART3_ADDR + UART_MOD_CNTRL); /* CE and "enable" */ alchemy_uart_enable(AU1000_UART1_PHYS_ADDR);
/* Enable UART1 */
au_writel(0x1, UART1_ADDR + UART_MOD_CNTRL); /* clock enable (CE) */
au_writel(0x3, UART1_ADDR + UART_MOD_CNTRL); /* CE and "enable" */
/* Take away Reset of UMTS-card */ /* Take away Reset of UMTS-card */
alchemy_gpio_direction_output(215, 1); alchemy_gpio_direction_output(215, 1);

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -161,6 +161,45 @@ static inline int alchemy_get_cputype(void)
return ALCHEMY_CPU_UNKNOWN; 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) static inline void alchemy_uart_putchar(u32 uart_phys, u8 c)
{ {
void __iomem *base = (void __iomem *)KSEG1ADDR(uart_phys); void __iomem *base = (void __iomem *)KSEG1ADDR(uart_phys);
@ -634,6 +673,10 @@ enum soc_au1200_ints {
*/ */
#define AU1000_IC0_PHYS_ADDR 0x10400000 /* 01234 */ #define AU1000_IC0_PHYS_ADDR 0x10400000 /* 01234 */
#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 AU1000_IC1_PHYS_ADDR 0x11800000 /* 01234 */ #define AU1000_IC1_PHYS_ADDR 0x11800000 /* 01234 */
#define AU1550_DBDMA_PHYS_ADDR 0x14002000 /* 34 */ #define AU1550_DBDMA_PHYS_ADDR 0x14002000 /* 34 */
#define AU1550_DBDMA_CONF_PHYS_ADDR 0x14003000 /* 34 */ #define AU1550_DBDMA_CONF_PHYS_ADDR 0x14003000 /* 34 */
@ -660,10 +703,6 @@ enum soc_au1200_ints {
#define MACDMA0_PHYS_ADDR 0x14004000 #define MACDMA0_PHYS_ADDR 0x14004000
#define MACDMA1_PHYS_ADDR 0x14004200 #define MACDMA1_PHYS_ADDR 0x14004200
#define I2S_PHYS_ADDR 0x11000000 #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 SSI0_PHYS_ADDR 0x11600000
#define SSI1_PHYS_ADDR 0x11680000 #define SSI1_PHYS_ADDR 0x11680000
#define SYS_PHYS_ADDR 0x11900000 #define SYS_PHYS_ADDR 0x11900000
@ -695,8 +734,6 @@ enum soc_au1200_ints {
#define MACDMA0_PHYS_ADDR 0x14004000 #define MACDMA0_PHYS_ADDR 0x14004000
#define MACDMA1_PHYS_ADDR 0x14004200 #define MACDMA1_PHYS_ADDR 0x14004200
#define I2S_PHYS_ADDR 0x11000000 #define I2S_PHYS_ADDR 0x11000000
#define UART0_PHYS_ADDR 0x11100000
#define UART3_PHYS_ADDR 0x11400000
#define GPIO2_PHYS_ADDR 0x11700000 #define GPIO2_PHYS_ADDR 0x11700000
#define SYS_PHYS_ADDR 0x11900000 #define SYS_PHYS_ADDR 0x11900000
#define PCI_MEM_PHYS_ADDR 0x400000000ULL #define PCI_MEM_PHYS_ADDR 0x400000000ULL
@ -732,9 +769,6 @@ enum soc_au1200_ints {
#define MACDMA0_PHYS_ADDR 0x14004000 #define MACDMA0_PHYS_ADDR 0x14004000
#define MACDMA1_PHYS_ADDR 0x14004200 #define MACDMA1_PHYS_ADDR 0x14004200
#define I2S_PHYS_ADDR 0x11000000 #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 SSI0_PHYS_ADDR 0x11600000
#define SSI1_PHYS_ADDR 0x11680000 #define SSI1_PHYS_ADDR 0x11680000
#define GPIO2_PHYS_ADDR 0x11700000 #define GPIO2_PHYS_ADDR 0x11700000
@ -758,9 +792,6 @@ enum soc_au1200_ints {
#define MACEN_PHYS_ADDR 0x10520000 #define MACEN_PHYS_ADDR 0x10520000
#define MACDMA0_PHYS_ADDR 0x14004000 #define MACDMA0_PHYS_ADDR 0x14004000
#define MACDMA1_PHYS_ADDR 0x14004200 #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 GPIO2_PHYS_ADDR 0x11700000
#define SYS_PHYS_ADDR 0x11900000 #define SYS_PHYS_ADDR 0x11900000
#define PE_PHYS_ADDR 0x14008000 #define PE_PHYS_ADDR 0x14008000
@ -786,8 +817,6 @@ enum soc_au1200_ints {
#define CIM_PHYS_ADDR 0x14004000 #define CIM_PHYS_ADDR 0x14004000
#define USBM_PHYS_ADDR 0x14020000 #define USBM_PHYS_ADDR 0x14020000
#define USBH_PHYS_ADDR 0x14020100 #define USBH_PHYS_ADDR 0x14020100
#define UART0_PHYS_ADDR 0x11100000
#define UART1_PHYS_ADDR 0x11200000
#define GPIO2_PHYS_ADDR 0x11700000 #define GPIO2_PHYS_ADDR 0x11700000
#define SYS_PHYS_ADDR 0x11900000 #define SYS_PHYS_ADDR 0x11900000
#define PSC0_PHYS_ADDR 0x11A00000 #define PSC0_PHYS_ADDR 0x11A00000