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