ckfwq/linux-3.0.4/arch/mips/loongson/gsc3280/serial.c

301 lines
7.4 KiB
C

/*
* 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) 2007 Ralf Baechle (ralf@linux-mips.org)
*
* Copyright (C) 2009 Lemote, Inc.
* Author: Yan hua (yanhua@lemote.com)
* Author: Wu Zhangjin (wuzhangjin@gmail.com)
*/
#include <linux/io.h>
#include <linux/init.h>
#include <linux/serial_8250.h>
#include <gsc3280/gsc3280_regs.h>
#include <asm/bootinfo.h>
#include <loongson.h>
#include <machine.h>
#include <gsc3280/gsc3280_int.h>
#include <linux/clk.h>
int printf_raw(const char *fmt, ...);
#if 0
#define PORT(int) \
{ \
.irq = int, \
.uartclk = 1843200, \
.iotype = UPIO_PORT, \
.flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST, \
.regshift = 0, \
}
#define UART0_CLK 5560000
#define UART1_CLK 5560000
#define UART2_CLK 5560000
#define UART3_CLK 16670000
#define UART4_CLK 16670000
#define UART5_CLK 16670000
#define UART6_CLK 5560000
#define UART7_CLK 5560000
#define PORT_M(int) \
{ \
.irq = MIPS_CPU_IRQ_BASE + 8 + (int), \
.uartclk = UART_CLK, \
.iotype = UPIO_MEM, \
.flags = UPF_BUGGY_UART | UPF_SKIP_TEST, \
.membase = (void __iomem *)NULL, \
.regshift = 0, \
.private_data = &serial_data, \
}
#endif
//extern struct serial_platform_data serial_data;
int uart0=0;
int uart1=1;
int uart2=2;
int uart3=3;
int uart4=4;
int uart5=5;
int uart6=6;
int uart7=7;
//static const unsigned int U0_CLK=2*clk_get_rate(clk_get(NULL,"uart0"));
//#define CLK0 (2*clk_get_rate(clk_get(NULL,"uart0")))
static struct plat_serial8250_port uart8250_uart0_data[]={
{
.membase= NULL,
.mapbase=GSC3280_UART0_BASEADDR & 0x1fffffff,
.irq =EXT_GSC3280_UART0_IRQ,
//uartclk =2*clk_get_rate(clk_get(NULL,"uart0")),
//.uartclk =11120000,
.regshift = 0,
.iotype = UPIO_MEM,
.flags = UPF_BOOT_AUTOCONF | UPF_BUGGY_UART | UPF_SKIP_TEST|UPF_IOREMAP,
.private_data =&uart0,
},
{}
};
static struct plat_serial8250_port uart8250_uart1_data[]={
{
.membase= NULL,
.mapbase=GSC3280_UART1_BASEADDR & 0x1fffffff,
.irq =EXT_GSC3280_UART1_IRQ,
// .uartclk =5560000,
// .uartclk =11120000,
.regshift = 0,
.iotype = UPIO_MEM,
.flags = UPF_BOOT_AUTOCONF | UPF_BUGGY_UART | UPF_SKIP_TEST|UPF_IOREMAP,
.private_data=&uart1,
// .private_data = &serial_data,
},
{}
};
static struct plat_serial8250_port uart8250_uart2_data[]={
{
.membase= NULL,
.mapbase=GSC3280_UART2_BASEADDR & 0x1fffffff,
.irq =EXT_GSC3280_UART2_IRQ,
//.uartclk =5560000,
// .uartclk =11120000,
.regshift = 0,
.iotype = UPIO_MEM,
.flags = UPF_BOOT_AUTOCONF | UPF_BUGGY_UART | UPF_SKIP_TEST|UPF_IOREMAP,
.private_data=&uart2,
// .private_data = &serial_data,
},
{}
};
static struct plat_serial8250_port uart8250_uart3_data[]={
{
.membase= NULL,
.mapbase=GSC3280_UART3_BASEADDR & 0x1fffffff,
.irq =EXT_GSC3280_UART3_IRQ,
//.uartclk =16670000,
// .uartclk =33340000,
.regshift = 0,
.iotype = UPIO_MEM,
.flags = UPF_BOOT_AUTOCONF | UPF_BUGGY_UART | UPF_SKIP_TEST|UPF_IOREMAP,
.private_data=&uart3,
// .private_data = &serial_data,
},
{}
};
static struct plat_serial8250_port uart8250_uart4_data[]={
{
.membase= NULL,
.mapbase=GSC3280_UART4_BASEADDR & 0x1fffffff,
//.uartclk =16670000,
.irq =EXT_GSC3280_UART4_IRQ,
// .uartclk =33340000,
.regshift = 0,
.iotype = UPIO_MEM,
.flags = UPF_BOOT_AUTOCONF | UPF_BUGGY_UART | UPF_SKIP_TEST|UPF_IOREMAP,
.private_data=&uart4,
// .private_data = &serial_data,
},
{}
};
static struct plat_serial8250_port uart8250_uart5_data[]={
{
.membase= NULL,
.mapbase=GSC3280_UART5_BASEADDR & 0x1fffffff,
.irq =EXT_GSC3280_UART5_IRQ,
//.uartclk =16670000,
// .uartclk =33340000,
.regshift = 0,
.iotype = UPIO_MEM,
.flags = UPF_BOOT_AUTOCONF | UPF_BUGGY_UART | UPF_SKIP_TEST|UPF_IOREMAP,
.private_data=&uart5,
// .private_data = &serial_data,
},
{}
};
static struct plat_serial8250_port uart8250_uart6_data[]={
{
.membase= NULL,
.mapbase=GSC3280_UART6_BASEADDR & 0x1fffffff,
.irq =EXT_GSC3280_UART6_IRQ,
//.uartclk =921600,
//.uartclk =463333,
// .uartclk =5560000,
.regshift = 0,
.iotype = UPIO_MEM,
.flags = UPF_BOOT_AUTOCONF | UPF_BUGGY_UART | UPF_SKIP_TEST|UPF_IOREMAP,
.private_data=&uart6,
// .private_data = &serial_data,
},
{}
};
static struct plat_serial8250_port uart8250_uart7_data[]={
{
.membase= NULL,
.mapbase=GSC3280_UART7_BASEADDR & 0x1fffffff,
.irq =EXT_GSC3280_UART7_IRQ,
// .uartclk =5560000,
.regshift = 0,
.iotype = UPIO_MEM,
.flags = UPF_BOOT_AUTOCONF | UPF_BUGGY_UART | UPF_SKIP_TEST|UPF_IOREMAP,
.private_data=&uart7,
// .private_data = &serial_data,
},
{}
};
static struct platform_device uart8250_uart0_device = {
.name = "serial8250",
.id = PLAT8250_DEV_PLATFORM,
.dev={
.platform_data=(void *)uart8250_uart0_data,
}
};
static struct platform_device uart8250_uart1_device = {
.name = "serial8250",
.id = PLAT8250_DEV_PLATFORM1,
.dev={
.platform_data=(void *)uart8250_uart1_data,
}
};
static struct platform_device uart8250_uart2_device = {
.name = "serial8250",
.id =PLAT8250_DEV_PLATFORM2,
.dev={
.platform_data=(void *)uart8250_uart2_data,
}
};
static struct platform_device uart8250_uart3_device = {
.name = "serial8250",
.id = PLAT8250_DEV_PLATFORM3,
.dev={
.platform_data=(void *)uart8250_uart3_data,
}
};
static struct platform_device uart8250_uart4_device = {
.name = "serial8250",
.id = PLAT8250_DEV_PLATFORM4,
.dev={
.platform_data=(void *)uart8250_uart4_data,
}
};
static struct platform_device uart8250_uart5_device = {
.name = "serial8250",
.id =PLAT8250_DEV_PLATFORM5,
.dev={
.platform_data=(void *)uart8250_uart5_data,
}
};
static struct platform_device uart8250_uart6_device = {
.name = "serial8250",
.id =PLAT8250_DEV_PLATFORM6,
.dev={
.platform_data=(void *)uart8250_uart6_data,
}
};
static struct platform_device uart8250_uart7_device = {
.name = "serial8250",
.id =PLAT8250_DEV_PLATFORM7,
.dev={
.platform_data=(void *)uart8250_uart7_data,
}
};
void serial_get_clk(void)
{
uart8250_uart0_data->uartclk=clk_get_rate(clk_get(NULL,"uart0"))<<1;
uart8250_uart1_data->uartclk=clk_get_rate(clk_get(NULL,"uart1"))<<1;
uart8250_uart2_data->uartclk=clk_get_rate(clk_get(NULL,"uart2"))<<1;
uart8250_uart3_data->uartclk=clk_get_rate(clk_get(NULL,"uart3"))<<1;
uart8250_uart4_data->uartclk=clk_get_rate(clk_get(NULL,"uart4"))<<1;
uart8250_uart5_data->uartclk=clk_get_rate(clk_get(NULL,"uart5"))<<1;
uart8250_uart6_data->uartclk=clk_get_rate(clk_get(NULL,"uart6"));
uart8250_uart7_data->uartclk=clk_get_rate(clk_get(NULL,"uart7"));
}
static int __init serial_init(void)
{
int i;
for(i=0;i<8;i++){
if(9 == readl((volatile void*)(GSC3280_REGADDR_SYSCTL_CLKDIV_UART0 + (i*0x4)))){
writel(0x1,(volatile void*)(GSC3280_REGADDR_SYSCTL_CLKDIV_UART0 + (i*0x4)));
}
printk(KERN_INFO "KERN uart%d clk div: 0X%08x\n",i,readl((volatile void*)(GSC3280_REGADDR_SYSCTL_CLKDIV_UART0 + (i*0x4))));
}
serial_get_clk();
platform_device_register(&uart8250_uart0_device);
platform_device_register(&uart8250_uart1_device);
platform_device_register(&uart8250_uart2_device);
platform_device_register(&uart8250_uart3_device);
platform_device_register(&uart8250_uart4_device);
platform_device_register(&uart8250_uart5_device);
platform_device_register(&uart8250_uart6_device);
platform_device_register(&uart8250_uart7_device);
return 0;
}
device_initcall(serial_init);