xref: /OK3568_Linux_fs/kernel/arch/mips/netlogic/xlr/platform.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun /*
2*4882a593Smuzhiyun  * Copyright 2011, Netlogic Microsystems.
3*4882a593Smuzhiyun  * Copyright 2004, Matt Porter <mporter@kernel.crashing.org>
4*4882a593Smuzhiyun  *
5*4882a593Smuzhiyun  * This file is licensed under the terms of the GNU General Public
6*4882a593Smuzhiyun  * License version 2.  This program is licensed "as is" without any
7*4882a593Smuzhiyun  * warranty of any kind, whether express or implied.
8*4882a593Smuzhiyun  */
9*4882a593Smuzhiyun 
10*4882a593Smuzhiyun #include <linux/device.h>
11*4882a593Smuzhiyun #include <linux/platform_device.h>
12*4882a593Smuzhiyun #include <linux/kernel.h>
13*4882a593Smuzhiyun #include <linux/init.h>
14*4882a593Smuzhiyun #include <linux/resource.h>
15*4882a593Smuzhiyun #include <linux/serial_8250.h>
16*4882a593Smuzhiyun #include <linux/serial_reg.h>
17*4882a593Smuzhiyun #include <linux/i2c.h>
18*4882a593Smuzhiyun #include <linux/usb/ehci_pdriver.h>
19*4882a593Smuzhiyun #include <linux/usb/ohci_pdriver.h>
20*4882a593Smuzhiyun 
21*4882a593Smuzhiyun #include <asm/netlogic/haldefs.h>
22*4882a593Smuzhiyun #include <asm/netlogic/xlr/iomap.h>
23*4882a593Smuzhiyun #include <asm/netlogic/xlr/pic.h>
24*4882a593Smuzhiyun #include <asm/netlogic/xlr/xlr.h>
25*4882a593Smuzhiyun 
nlm_xlr_uart_in(struct uart_port * p,int offset)26*4882a593Smuzhiyun static unsigned int nlm_xlr_uart_in(struct uart_port *p, int offset)
27*4882a593Smuzhiyun {
28*4882a593Smuzhiyun 	uint64_t uartbase;
29*4882a593Smuzhiyun 	unsigned int value;
30*4882a593Smuzhiyun 
31*4882a593Smuzhiyun 	/* sign extend to 64 bits, if needed */
32*4882a593Smuzhiyun 	uartbase = (uint64_t)(long)p->membase;
33*4882a593Smuzhiyun 	value = nlm_read_reg(uartbase, offset);
34*4882a593Smuzhiyun 
35*4882a593Smuzhiyun 	/* See XLR/XLS errata */
36*4882a593Smuzhiyun 	if (offset == UART_MSR)
37*4882a593Smuzhiyun 		value ^= 0xF0;
38*4882a593Smuzhiyun 	else if (offset == UART_MCR)
39*4882a593Smuzhiyun 		value ^= 0x3;
40*4882a593Smuzhiyun 
41*4882a593Smuzhiyun 	return value;
42*4882a593Smuzhiyun }
43*4882a593Smuzhiyun 
nlm_xlr_uart_out(struct uart_port * p,int offset,int value)44*4882a593Smuzhiyun static void nlm_xlr_uart_out(struct uart_port *p, int offset, int value)
45*4882a593Smuzhiyun {
46*4882a593Smuzhiyun 	uint64_t uartbase;
47*4882a593Smuzhiyun 
48*4882a593Smuzhiyun 	/* sign extend to 64 bits, if needed */
49*4882a593Smuzhiyun 	uartbase = (uint64_t)(long)p->membase;
50*4882a593Smuzhiyun 
51*4882a593Smuzhiyun 	/* See XLR/XLS errata */
52*4882a593Smuzhiyun 	if (offset == UART_MSR)
53*4882a593Smuzhiyun 		value ^= 0xF0;
54*4882a593Smuzhiyun 	else if (offset == UART_MCR)
55*4882a593Smuzhiyun 		value ^= 0x3;
56*4882a593Smuzhiyun 
57*4882a593Smuzhiyun 	nlm_write_reg(uartbase, offset, value);
58*4882a593Smuzhiyun }
59*4882a593Smuzhiyun 
60*4882a593Smuzhiyun #define PORT(_irq)					\
61*4882a593Smuzhiyun 	{						\
62*4882a593Smuzhiyun 		.irq		= _irq,			\
63*4882a593Smuzhiyun 		.regshift	= 2,			\
64*4882a593Smuzhiyun 		.iotype		= UPIO_MEM32,		\
65*4882a593Smuzhiyun 		.flags		= (UPF_SKIP_TEST |	\
66*4882a593Smuzhiyun 			 UPF_FIXED_TYPE | UPF_BOOT_AUTOCONF),\
67*4882a593Smuzhiyun 		.uartclk	= PIC_CLK_HZ,		\
68*4882a593Smuzhiyun 		.type		= PORT_16550A,		\
69*4882a593Smuzhiyun 		.serial_in	= nlm_xlr_uart_in,	\
70*4882a593Smuzhiyun 		.serial_out	= nlm_xlr_uart_out,	\
71*4882a593Smuzhiyun 	}
72*4882a593Smuzhiyun 
73*4882a593Smuzhiyun static struct plat_serial8250_port xlr_uart_data[] = {
74*4882a593Smuzhiyun 	PORT(PIC_UART_0_IRQ),
75*4882a593Smuzhiyun 	PORT(PIC_UART_1_IRQ),
76*4882a593Smuzhiyun 	{},
77*4882a593Smuzhiyun };
78*4882a593Smuzhiyun 
79*4882a593Smuzhiyun static struct platform_device uart_device = {
80*4882a593Smuzhiyun 	.name		= "serial8250",
81*4882a593Smuzhiyun 	.id		= PLAT8250_DEV_PLATFORM,
82*4882a593Smuzhiyun 	.dev = {
83*4882a593Smuzhiyun 		.platform_data = xlr_uart_data,
84*4882a593Smuzhiyun 	},
85*4882a593Smuzhiyun };
86*4882a593Smuzhiyun 
nlm_uart_init(void)87*4882a593Smuzhiyun static int __init nlm_uart_init(void)
88*4882a593Smuzhiyun {
89*4882a593Smuzhiyun 	unsigned long uartbase;
90*4882a593Smuzhiyun 
91*4882a593Smuzhiyun 	uartbase = (unsigned long)nlm_mmio_base(NETLOGIC_IO_UART_0_OFFSET);
92*4882a593Smuzhiyun 	xlr_uart_data[0].membase = (void __iomem *)uartbase;
93*4882a593Smuzhiyun 	xlr_uart_data[0].mapbase = CPHYSADDR(uartbase);
94*4882a593Smuzhiyun 
95*4882a593Smuzhiyun 	uartbase = (unsigned long)nlm_mmio_base(NETLOGIC_IO_UART_1_OFFSET);
96*4882a593Smuzhiyun 	xlr_uart_data[1].membase = (void __iomem *)uartbase;
97*4882a593Smuzhiyun 	xlr_uart_data[1].mapbase = CPHYSADDR(uartbase);
98*4882a593Smuzhiyun 
99*4882a593Smuzhiyun 	return platform_device_register(&uart_device);
100*4882a593Smuzhiyun }
101*4882a593Smuzhiyun 
102*4882a593Smuzhiyun arch_initcall(nlm_uart_init);
103*4882a593Smuzhiyun 
104*4882a593Smuzhiyun #ifdef CONFIG_USB
105*4882a593Smuzhiyun /* Platform USB devices, only on XLS chips */
106*4882a593Smuzhiyun static u64 xls_usb_dmamask = ~(u32)0;
107*4882a593Smuzhiyun #define USB_PLATFORM_DEV(n, i, irq)					\
108*4882a593Smuzhiyun 	{								\
109*4882a593Smuzhiyun 		.name		= n,					\
110*4882a593Smuzhiyun 		.id		= i,					\
111*4882a593Smuzhiyun 		.num_resources	= 2,					\
112*4882a593Smuzhiyun 		.dev		= {					\
113*4882a593Smuzhiyun 			.dma_mask	= &xls_usb_dmamask,		\
114*4882a593Smuzhiyun 			.coherent_dma_mask = 0xffffffff,		\
115*4882a593Smuzhiyun 		},							\
116*4882a593Smuzhiyun 		.resource	= (struct resource[]) {			\
117*4882a593Smuzhiyun 			{						\
118*4882a593Smuzhiyun 				.flags = IORESOURCE_MEM,		\
119*4882a593Smuzhiyun 			},						\
120*4882a593Smuzhiyun 			{						\
121*4882a593Smuzhiyun 				.start	= irq,				\
122*4882a593Smuzhiyun 				.end	= irq,				\
123*4882a593Smuzhiyun 				.flags = IORESOURCE_IRQ,		\
124*4882a593Smuzhiyun 			},						\
125*4882a593Smuzhiyun 		},							\
126*4882a593Smuzhiyun 	}
127*4882a593Smuzhiyun 
128*4882a593Smuzhiyun static struct usb_ehci_pdata xls_usb_ehci_pdata = {
129*4882a593Smuzhiyun 	.caps_offset	= 0,
130*4882a593Smuzhiyun };
131*4882a593Smuzhiyun 
132*4882a593Smuzhiyun static struct usb_ohci_pdata xls_usb_ohci_pdata;
133*4882a593Smuzhiyun 
134*4882a593Smuzhiyun static struct platform_device xls_usb_ehci_device =
135*4882a593Smuzhiyun 			 USB_PLATFORM_DEV("ehci-platform", 0, PIC_USB_IRQ);
136*4882a593Smuzhiyun static struct platform_device xls_usb_ohci_device_0 =
137*4882a593Smuzhiyun 			 USB_PLATFORM_DEV("ohci-platform", 1, PIC_USB_IRQ);
138*4882a593Smuzhiyun static struct platform_device xls_usb_ohci_device_1 =
139*4882a593Smuzhiyun 			 USB_PLATFORM_DEV("ohci-platform", 2, PIC_USB_IRQ);
140*4882a593Smuzhiyun 
141*4882a593Smuzhiyun static struct platform_device *xls_platform_devices[] = {
142*4882a593Smuzhiyun 	&xls_usb_ehci_device,
143*4882a593Smuzhiyun 	&xls_usb_ohci_device_0,
144*4882a593Smuzhiyun 	&xls_usb_ohci_device_1,
145*4882a593Smuzhiyun };
146*4882a593Smuzhiyun 
xls_platform_usb_init(void)147*4882a593Smuzhiyun int xls_platform_usb_init(void)
148*4882a593Smuzhiyun {
149*4882a593Smuzhiyun 	uint64_t usb_mmio, gpio_mmio;
150*4882a593Smuzhiyun 	unsigned long memres;
151*4882a593Smuzhiyun 	uint32_t val;
152*4882a593Smuzhiyun 
153*4882a593Smuzhiyun 	if (!nlm_chip_is_xls())
154*4882a593Smuzhiyun 		return 0;
155*4882a593Smuzhiyun 
156*4882a593Smuzhiyun 	gpio_mmio = nlm_mmio_base(NETLOGIC_IO_GPIO_OFFSET);
157*4882a593Smuzhiyun 	usb_mmio  = nlm_mmio_base(NETLOGIC_IO_USB_1_OFFSET);
158*4882a593Smuzhiyun 
159*4882a593Smuzhiyun 	/* Clear Rogue Phy INTs */
160*4882a593Smuzhiyun 	nlm_write_reg(usb_mmio, 49, 0x10000000);
161*4882a593Smuzhiyun 	/* Enable all interrupts */
162*4882a593Smuzhiyun 	nlm_write_reg(usb_mmio, 50, 0x1f000000);
163*4882a593Smuzhiyun 
164*4882a593Smuzhiyun 	/* Enable ports */
165*4882a593Smuzhiyun 	nlm_write_reg(usb_mmio,	 1, 0x07000500);
166*4882a593Smuzhiyun 
167*4882a593Smuzhiyun 	val = nlm_read_reg(gpio_mmio, 21);
168*4882a593Smuzhiyun 	if (((val >> 22) & 0x01) == 0) {
169*4882a593Smuzhiyun 		pr_info("Detected USB Device mode - Not supported!\n");
170*4882a593Smuzhiyun 		nlm_write_reg(usb_mmio,	 0, 0x01000000);
171*4882a593Smuzhiyun 		return 0;
172*4882a593Smuzhiyun 	}
173*4882a593Smuzhiyun 
174*4882a593Smuzhiyun 	pr_info("Detected USB Host mode - Adding XLS USB devices.\n");
175*4882a593Smuzhiyun 	/* Clear reset, host mode */
176*4882a593Smuzhiyun 	nlm_write_reg(usb_mmio,	 0, 0x02000000);
177*4882a593Smuzhiyun 
178*4882a593Smuzhiyun 	/* Memory resource for various XLS usb ports */
179*4882a593Smuzhiyun 	usb_mmio = nlm_mmio_base(NETLOGIC_IO_USB_0_OFFSET);
180*4882a593Smuzhiyun 	memres = CPHYSADDR((unsigned long)usb_mmio);
181*4882a593Smuzhiyun 	xls_usb_ehci_device.resource[0].start = memres;
182*4882a593Smuzhiyun 	xls_usb_ehci_device.resource[0].end = memres + 0x400 - 1;
183*4882a593Smuzhiyun 	xls_usb_ehci_device.dev.platform_data = &xls_usb_ehci_pdata;
184*4882a593Smuzhiyun 
185*4882a593Smuzhiyun 	memres += 0x400;
186*4882a593Smuzhiyun 	xls_usb_ohci_device_0.resource[0].start = memres;
187*4882a593Smuzhiyun 	xls_usb_ohci_device_0.resource[0].end = memres + 0x400 - 1;
188*4882a593Smuzhiyun 	xls_usb_ohci_device_0.dev.platform_data = &xls_usb_ohci_pdata;
189*4882a593Smuzhiyun 
190*4882a593Smuzhiyun 	memres += 0x400;
191*4882a593Smuzhiyun 	xls_usb_ohci_device_1.resource[0].start = memres;
192*4882a593Smuzhiyun 	xls_usb_ohci_device_1.resource[0].end = memres + 0x400 - 1;
193*4882a593Smuzhiyun 	xls_usb_ohci_device_1.dev.platform_data = &xls_usb_ohci_pdata;
194*4882a593Smuzhiyun 
195*4882a593Smuzhiyun 	return platform_add_devices(xls_platform_devices,
196*4882a593Smuzhiyun 				ARRAY_SIZE(xls_platform_devices));
197*4882a593Smuzhiyun }
198*4882a593Smuzhiyun 
199*4882a593Smuzhiyun arch_initcall(xls_platform_usb_init);
200*4882a593Smuzhiyun #endif
201*4882a593Smuzhiyun 
202*4882a593Smuzhiyun #ifdef CONFIG_I2C
203*4882a593Smuzhiyun static struct i2c_board_info nlm_i2c_board_info1[] __initdata = {
204*4882a593Smuzhiyun 	/* All XLR boards have this RTC and Max6657 Temp Chip */
205*4882a593Smuzhiyun 	[0] = {
206*4882a593Smuzhiyun 		.type	= "ds1374",
207*4882a593Smuzhiyun 		.addr	= 0x68
208*4882a593Smuzhiyun 	},
209*4882a593Smuzhiyun 	[1] = {
210*4882a593Smuzhiyun 		.type	= "lm90",
211*4882a593Smuzhiyun 		.addr	= 0x4c
212*4882a593Smuzhiyun 	},
213*4882a593Smuzhiyun };
214*4882a593Smuzhiyun 
215*4882a593Smuzhiyun static struct resource i2c_resources[] = {
216*4882a593Smuzhiyun 	[0] = {
217*4882a593Smuzhiyun 		.start	= 0,	/* filled at init */
218*4882a593Smuzhiyun 		.end	= 0,
219*4882a593Smuzhiyun 		.flags	= IORESOURCE_MEM,
220*4882a593Smuzhiyun 	},
221*4882a593Smuzhiyun };
222*4882a593Smuzhiyun 
223*4882a593Smuzhiyun static struct platform_device nlm_xlr_i2c_1 = {
224*4882a593Smuzhiyun 	.name		= "xlr-i2cbus",
225*4882a593Smuzhiyun 	.id		= 1,
226*4882a593Smuzhiyun 	.num_resources	= 1,
227*4882a593Smuzhiyun 	.resource	= i2c_resources,
228*4882a593Smuzhiyun };
229*4882a593Smuzhiyun 
nlm_i2c_init(void)230*4882a593Smuzhiyun static int __init nlm_i2c_init(void)
231*4882a593Smuzhiyun {
232*4882a593Smuzhiyun 	int err = 0;
233*4882a593Smuzhiyun 	unsigned int offset;
234*4882a593Smuzhiyun 
235*4882a593Smuzhiyun 	/* I2C bus 0 does not have any useful devices, configure only bus 1 */
236*4882a593Smuzhiyun 	offset = NETLOGIC_IO_I2C_1_OFFSET;
237*4882a593Smuzhiyun 	nlm_xlr_i2c_1.resource[0].start = CPHYSADDR(nlm_mmio_base(offset));
238*4882a593Smuzhiyun 	nlm_xlr_i2c_1.resource[0].end = nlm_xlr_i2c_1.resource[0].start + 0xfff;
239*4882a593Smuzhiyun 
240*4882a593Smuzhiyun 	platform_device_register(&nlm_xlr_i2c_1);
241*4882a593Smuzhiyun 
242*4882a593Smuzhiyun 	err = i2c_register_board_info(1, nlm_i2c_board_info1,
243*4882a593Smuzhiyun 				ARRAY_SIZE(nlm_i2c_board_info1));
244*4882a593Smuzhiyun 	if (err < 0)
245*4882a593Smuzhiyun 		pr_err("nlm-i2c: cannot register board I2C devices\n");
246*4882a593Smuzhiyun 	return err;
247*4882a593Smuzhiyun }
248*4882a593Smuzhiyun 
249*4882a593Smuzhiyun arch_initcall(nlm_i2c_init);
250*4882a593Smuzhiyun #endif
251