2 * Synopsys DesignWare 8250 driver.
4 * Copyright 2011 Picochip, Jamie Iles.
5 * Copyright 2013 Intel Corporation
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
12 * The Synopsys DesignWare 8250 has an extra feature whereby it detects if the
13 * LCR is written whilst busy. If it is, then a busy detect interrupt is
14 * raised, the LCR needs to be rewritten and the uart status register read.
16 #include <linux/device.h>
17 #include <linux/init.h>
19 #include <linux/module.h>
20 #include <linux/serial_8250.h>
21 #include <linux/serial_core.h>
22 #include <linux/serial_reg.h>
24 #include <linux/of_irq.h>
25 #include <linux/of_platform.h>
26 #include <linux/platform_device.h>
27 #include <linux/slab.h>
28 #include <linux/acpi.h>
32 /* Offsets for the DesignWare specific registers */
33 #define DW_UART_USR 0x1f /* UART Status Register */
34 #define DW_UART_CPR 0xf4 /* Component Parameter Register */
35 #define DW_UART_UCV 0xf8 /* UART Component Version */
37 /* Intel Low Power Subsystem specific */
38 #define LPSS_PRV_CLOCK_PARAMS 0x800
40 /* Component Parameter Register bits */
41 #define DW_UART_CPR_ABP_DATA_WIDTH (3 << 0)
42 #define DW_UART_CPR_AFCE_MODE (1 << 4)
43 #define DW_UART_CPR_THRE_MODE (1 << 5)
44 #define DW_UART_CPR_SIR_MODE (1 << 6)
45 #define DW_UART_CPR_SIR_LP_MODE (1 << 7)
46 #define DW_UART_CPR_ADDITIONAL_FEATURES (1 << 8)
47 #define DW_UART_CPR_FIFO_ACCESS (1 << 9)
48 #define DW_UART_CPR_FIFO_STAT (1 << 10)
49 #define DW_UART_CPR_SHADOW (1 << 11)
50 #define DW_UART_CPR_ENCODED_PARMS (1 << 12)
51 #define DW_UART_CPR_DMA_EXTRA (1 << 13)
52 #define DW_UART_CPR_FIFO_MODE (0xff << 16)
53 /* Helper for fifo size calculation */
54 #define DW_UART_CPR_FIFO_SIZE(a) (((a >> 16) & 0xff) * 16)
62 static void dw8250_serial_out(struct uart_port
*p
, int offset
, int value
)
64 struct dw8250_data
*d
= p
->private_data
;
66 if (offset
== UART_LCR
)
69 offset
<<= p
->regshift
;
70 writeb(value
, p
->membase
+ offset
);
73 static unsigned int dw8250_serial_in(struct uart_port
*p
, int offset
)
75 offset
<<= p
->regshift
;
77 return readb(p
->membase
+ offset
);
80 static void dw8250_serial_out32(struct uart_port
*p
, int offset
, int value
)
82 struct dw8250_data
*d
= p
->private_data
;
84 if (offset
== UART_LCR
)
87 offset
<<= p
->regshift
;
88 writel(value
, p
->membase
+ offset
);
91 static unsigned int dw8250_serial_in32(struct uart_port
*p
, int offset
)
93 offset
<<= p
->regshift
;
95 return readl(p
->membase
+ offset
);
98 static int dw8250_handle_irq(struct uart_port
*p
)
100 struct dw8250_data
*d
= p
->private_data
;
101 unsigned int iir
= p
->serial_in(p
, UART_IIR
);
103 if (serial8250_handle_irq(p
, iir
)) {
105 } else if ((iir
& UART_IIR_BUSY
) == UART_IIR_BUSY
) {
106 /* Clear the USR and write the LCR again. */
107 (void)p
->serial_in(p
, DW_UART_USR
);
108 p
->serial_out(p
, UART_LCR
, d
->last_lcr
);
116 static int dw8250_probe_of(struct uart_port
*p
)
118 struct device_node
*np
= p
->dev
->of_node
;
121 if (!of_property_read_u32(np
, "reg-io-width", &val
)) {
126 p
->iotype
= UPIO_MEM32
;
127 p
->serial_in
= dw8250_serial_in32
;
128 p
->serial_out
= dw8250_serial_out32
;
131 dev_err(p
->dev
, "unsupported reg-io-width (%u)\n", val
);
136 if (!of_property_read_u32(np
, "reg-shift", &val
))
139 if (of_property_read_u32(np
, "clock-frequency", &val
)) {
140 dev_err(p
->dev
, "no clock-frequency property set\n");
149 static bool dw8250_acpi_dma_filter(struct dma_chan
*chan
, void *parm
)
151 return chan
->chan_id
== *(int *)parm
;
155 dw8250_acpi_walk_resource(struct acpi_resource
*res
, void *data
)
157 struct uart_port
*p
= data
;
158 struct uart_8250_port
*port
;
159 struct uart_8250_dma
*dma
;
160 struct acpi_resource_fixed_dma
*fixed_dma
;
161 struct dma_slave_config
*slave
;
163 port
= container_of(p
, struct uart_8250_port
, port
);
166 case ACPI_RESOURCE_TYPE_FIXED_DMA
:
167 fixed_dma
= &res
->data
.fixed_dma
;
171 dma
= devm_kzalloc(p
->dev
, sizeof(*dma
), GFP_KERNEL
);
176 slave
= &dma
->txconf
;
178 slave
->direction
= DMA_MEM_TO_DEV
;
179 slave
->dst_addr_width
= DMA_SLAVE_BUSWIDTH_1_BYTE
;
180 slave
->slave_id
= fixed_dma
->request_lines
;
181 slave
->dst_maxburst
= port
->tx_loadsz
/ 4;
183 dma
->tx_chan_id
= fixed_dma
->channels
;
184 dma
->tx_param
= &dma
->tx_chan_id
;
185 dma
->fn
= dw8250_acpi_dma_filter
;
188 slave
= &dma
->rxconf
;
190 slave
->direction
= DMA_DEV_TO_MEM
;
191 slave
->src_addr_width
= DMA_SLAVE_BUSWIDTH_1_BYTE
;
192 slave
->slave_id
= fixed_dma
->request_lines
;
193 slave
->src_maxburst
= p
->fifosize
/ 4;
195 dma
->rx_chan_id
= fixed_dma
->channels
;
196 dma
->rx_param
= &dma
->rx_chan_id
;
205 static int dw8250_probe_acpi(struct uart_port
*p
)
207 const struct acpi_device_id
*id
;
211 id
= acpi_match_device(p
->dev
->driver
->acpi_match_table
, p
->dev
);
215 p
->iotype
= UPIO_MEM32
;
216 p
->serial_in
= dw8250_serial_in32
;
217 p
->serial_out
= dw8250_serial_out32
;
219 p
->uartclk
= (unsigned int)id
->driver_data
;
221 status
= acpi_walk_resources(ACPI_HANDLE(p
->dev
), METHOD_NAME__CRS
,
222 dw8250_acpi_walk_resource
, p
);
223 if (ACPI_FAILURE(status
)) {
224 dev_err_ratelimited(p
->dev
, "%s failed \"%s\"\n", __func__
,
225 acpi_format_exception(status
));
229 /* Fix Haswell issue where the clocks do not get enabled */
230 if (!strcmp(id
->id
, "INT33C4") || !strcmp(id
->id
, "INT33C5")) {
231 reg
= readl(p
->membase
+ LPSS_PRV_CLOCK_PARAMS
);
232 writel(reg
| 1, p
->membase
+ LPSS_PRV_CLOCK_PARAMS
);
238 static inline int dw8250_probe_acpi(struct uart_port
*p
)
242 #endif /* CONFIG_ACPI */
244 static void dw8250_setup_port(struct uart_8250_port
*up
)
246 struct uart_port
*p
= &up
->port
;
247 u32 reg
= readl(p
->membase
+ DW_UART_UCV
);
250 * If the Component Version Register returns zero, we know that
251 * ADDITIONAL_FEATURES are not enabled. No need to go any further.
256 dev_dbg_ratelimited(p
->dev
, "Designware UART version %c.%c%c\n",
257 (reg
>> 24) & 0xff, (reg
>> 16) & 0xff, (reg
>> 8) & 0xff);
259 reg
= readl(p
->membase
+ DW_UART_CPR
);
263 /* Select the type based on fifo */
264 if (reg
& DW_UART_CPR_FIFO_MODE
) {
265 p
->type
= PORT_16550A
;
266 p
->flags
|= UPF_FIXED_TYPE
;
267 p
->fifosize
= DW_UART_CPR_FIFO_SIZE(reg
);
268 up
->tx_loadsz
= p
->fifosize
;
272 static int dw8250_probe(struct platform_device
*pdev
)
274 struct uart_8250_port uart
= {};
275 struct resource
*regs
= platform_get_resource(pdev
, IORESOURCE_MEM
, 0);
276 struct resource
*irq
= platform_get_resource(pdev
, IORESOURCE_IRQ
, 0);
277 struct dw8250_data
*data
;
281 dev_err(&pdev
->dev
, "no registers/irq defined\n");
285 spin_lock_init(&uart
.port
.lock
);
286 uart
.port
.mapbase
= regs
->start
;
287 uart
.port
.irq
= irq
->start
;
288 uart
.port
.handle_irq
= dw8250_handle_irq
;
289 uart
.port
.type
= PORT_8250
;
290 uart
.port
.flags
= UPF_SHARE_IRQ
| UPF_BOOT_AUTOCONF
| UPF_FIXED_PORT
;
291 uart
.port
.dev
= &pdev
->dev
;
293 uart
.port
.membase
= ioremap(regs
->start
, resource_size(regs
));
294 if (!uart
.port
.membase
)
297 uart
.port
.iotype
= UPIO_MEM
;
298 uart
.port
.serial_in
= dw8250_serial_in
;
299 uart
.port
.serial_out
= dw8250_serial_out
;
301 dw8250_setup_port(&uart
);
303 if (pdev
->dev
.of_node
) {
304 err
= dw8250_probe_of(&uart
.port
);
307 } else if (ACPI_HANDLE(&pdev
->dev
)) {
308 err
= dw8250_probe_acpi(&uart
.port
);
315 data
= devm_kzalloc(&pdev
->dev
, sizeof(*data
), GFP_KERNEL
);
319 uart
.port
.private_data
= data
;
321 data
->line
= serial8250_register_8250_port(&uart
);
325 platform_set_drvdata(pdev
, data
);
330 static int dw8250_remove(struct platform_device
*pdev
)
332 struct dw8250_data
*data
= platform_get_drvdata(pdev
);
334 serial8250_unregister_port(data
->line
);
340 static int dw8250_suspend(struct platform_device
*pdev
, pm_message_t state
)
342 struct dw8250_data
*data
= platform_get_drvdata(pdev
);
344 serial8250_suspend_port(data
->line
);
349 static int dw8250_resume(struct platform_device
*pdev
)
351 struct dw8250_data
*data
= platform_get_drvdata(pdev
);
353 serial8250_resume_port(data
->line
);
358 #define dw8250_suspend NULL
359 #define dw8250_resume NULL
360 #endif /* CONFIG_PM */
362 static const struct of_device_id dw8250_of_match
[] = {
363 { .compatible
= "snps,dw-apb-uart" },
366 MODULE_DEVICE_TABLE(of
, dw8250_of_match
);
368 static const struct acpi_device_id dw8250_acpi_match
[] = {
369 { "INT33C4", 100000000 },
370 { "INT33C5", 100000000 },
373 MODULE_DEVICE_TABLE(acpi
, dw8250_acpi_match
);
375 static struct platform_driver dw8250_platform_driver
= {
377 .name
= "dw-apb-uart",
378 .owner
= THIS_MODULE
,
379 .of_match_table
= dw8250_of_match
,
380 .acpi_match_table
= ACPI_PTR(dw8250_acpi_match
),
382 .probe
= dw8250_probe
,
383 .remove
= dw8250_remove
,
384 .suspend
= dw8250_suspend
,
385 .resume
= dw8250_resume
,
388 module_platform_driver(dw8250_platform_driver
);
390 MODULE_AUTHOR("Jamie Iles");
391 MODULE_LICENSE("GPL");
392 MODULE_DESCRIPTION("Synopsys DesignWare 8250 serial port driver");