• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2011, Netlogic Microsystems.
3  * Copyright 2004, Matt Porter <mporter@kernel.crashing.org>
4  *
5  * This file is licensed under the terms of the GNU General Public
6  * License version 2.  This program is licensed "as is" without any
7  * warranty of any kind, whether express or implied.
8  */
9 
10 #include <linux/device.h>
11 #include <linux/platform_device.h>
12 #include <linux/kernel.h>
13 #include <linux/init.h>
14 #include <linux/resource.h>
15 #include <linux/serial_8250.h>
16 #include <linux/serial_reg.h>
17 
18 #include <asm/netlogic/haldefs.h>
19 #include <asm/netlogic/xlr/iomap.h>
20 #include <asm/netlogic/xlr/pic.h>
21 #include <asm/netlogic/xlr/xlr.h>
22 
nlm_xlr_uart_in(struct uart_port * p,int offset)23 unsigned int nlm_xlr_uart_in(struct uart_port *p, int offset)
24 {
25 	uint64_t uartbase;
26 	unsigned int value;
27 
28 	/* sign extend to 64 bits, if needed */
29 	uartbase = (uint64_t)(long)p->membase;
30 	value = nlm_read_reg(uartbase, offset);
31 
32 	/* See XLR/XLS errata */
33 	if (offset == UART_MSR)
34 		value ^= 0xF0;
35 	else if (offset == UART_MCR)
36 		value ^= 0x3;
37 
38 	return value;
39 }
40 
nlm_xlr_uart_out(struct uart_port * p,int offset,int value)41 void nlm_xlr_uart_out(struct uart_port *p, int offset, int value)
42 {
43 	uint64_t uartbase;
44 
45 	/* sign extend to 64 bits, if needed */
46 	uartbase = (uint64_t)(long)p->membase;
47 
48 	/* See XLR/XLS errata */
49 	if (offset == UART_MSR)
50 		value ^= 0xF0;
51 	else if (offset == UART_MCR)
52 		value ^= 0x3;
53 
54 	nlm_write_reg(uartbase, offset, value);
55 }
56 
57 #define PORT(_irq)					\
58 	{						\
59 		.irq		= _irq,			\
60 		.regshift	= 2,			\
61 		.iotype		= UPIO_MEM32,		\
62 		.flags		= (UPF_SKIP_TEST |	\
63 			 UPF_FIXED_TYPE | UPF_BOOT_AUTOCONF),\
64 		.uartclk	= PIC_CLKS_PER_SEC,	\
65 		.type		= PORT_16550A,		\
66 		.serial_in	= nlm_xlr_uart_in,	\
67 		.serial_out	= nlm_xlr_uart_out,	\
68 	}
69 
70 static struct plat_serial8250_port xlr_uart_data[] = {
71 	PORT(PIC_UART_0_IRQ),
72 	PORT(PIC_UART_1_IRQ),
73 	{},
74 };
75 
76 static struct platform_device uart_device = {
77 	.name		= "serial8250",
78 	.id		= PLAT8250_DEV_PLATFORM,
79 	.dev = {
80 		.platform_data = xlr_uart_data,
81 	},
82 };
83 
nlm_uart_init(void)84 static int __init nlm_uart_init(void)
85 {
86 	unsigned long uartbase;
87 
88 	uartbase = (unsigned long)nlm_mmio_base(NETLOGIC_IO_UART_0_OFFSET);
89 	xlr_uart_data[0].membase = (void __iomem *)uartbase;
90 	xlr_uart_data[0].mapbase = CPHYSADDR(uartbase);
91 
92 	uartbase = (unsigned long)nlm_mmio_base(NETLOGIC_IO_UART_1_OFFSET);
93 	xlr_uart_data[1].membase = (void __iomem *)uartbase;
94 	xlr_uart_data[1].mapbase = CPHYSADDR(uartbase);
95 
96 	return platform_device_register(&uart_device);
97 }
98 
99 arch_initcall(nlm_uart_init);
100