25
25
#include <linux/platform_device.h>
26
26
#include <linux/slab.h>
27
27
28
+ /* Offsets for the DesignWare specific registers */
29
+ #define DW_UART_USR 0x1f /* UART Status Register */
30
+ #define DW_UART_CPR 0xf4 /* Component Parameter Register */
31
+ #define DW_UART_UCV 0xf8 /* UART Component Version */
32
+
33
+ /* Component Parameter Register bits */
34
+ #define DW_UART_CPR_ABP_DATA_WIDTH (3 << 0)
35
+ #define DW_UART_CPR_AFCE_MODE (1 << 4)
36
+ #define DW_UART_CPR_THRE_MODE (1 << 5)
37
+ #define DW_UART_CPR_SIR_MODE (1 << 6)
38
+ #define DW_UART_CPR_SIR_LP_MODE (1 << 7)
39
+ #define DW_UART_CPR_ADDITIONAL_FEATURES (1 << 8)
40
+ #define DW_UART_CPR_FIFO_ACCESS (1 << 9)
41
+ #define DW_UART_CPR_FIFO_STAT (1 << 10)
42
+ #define DW_UART_CPR_SHADOW (1 << 11)
43
+ #define DW_UART_CPR_ENCODED_PARMS (1 << 12)
44
+ #define DW_UART_CPR_DMA_EXTRA (1 << 13)
45
+ #define DW_UART_CPR_FIFO_MODE (0xff << 16)
46
+ /* Helper for fifo size calculation */
47
+ #define DW_UART_CPR_FIFO_SIZE (a ) (((a >> 16) & 0xff) * 16)
48
+
49
+
28
50
struct dw8250_data {
29
51
int last_lcr ;
30
52
int line ;
@@ -66,9 +88,6 @@ static unsigned int dw8250_serial_in32(struct uart_port *p, int offset)
66
88
return readl (p -> membase + offset );
67
89
}
68
90
69
- /* Offset for the DesignWare's UART Status Register. */
70
- #define UART_USR 0x1f
71
-
72
91
static int dw8250_handle_irq (struct uart_port * p )
73
92
{
74
93
struct dw8250_data * d = p -> private_data ;
@@ -78,7 +97,7 @@ static int dw8250_handle_irq(struct uart_port *p)
78
97
return 1 ;
79
98
} else if ((iir & UART_IIR_BUSY ) == UART_IIR_BUSY ) {
80
99
/* Clear the USR and write the LCR again. */
81
- (void )p -> serial_in (p , UART_USR );
100
+ (void )p -> serial_in (p , DW_UART_USR );
82
101
p -> serial_out (p , d -> last_lcr , UART_LCR );
83
102
84
103
return 1 ;
@@ -119,6 +138,34 @@ static int dw8250_probe_of(struct uart_port *p)
119
138
return 0 ;
120
139
}
121
140
141
+ static void dw8250_setup_port (struct uart_8250_port * up )
142
+ {
143
+ struct uart_port * p = & up -> port ;
144
+ u32 reg = readl (p -> membase + DW_UART_UCV );
145
+
146
+ /*
147
+ * If the Component Version Register returns zero, we know that
148
+ * ADDITIONAL_FEATURES are not enabled. No need to go any further.
149
+ */
150
+ if (!reg )
151
+ return ;
152
+
153
+ dev_dbg_ratelimited (p -> dev , "Designware UART version %c.%c%c\n" ,
154
+ (reg >> 24 ) & 0xff , (reg >> 16 ) & 0xff , (reg >> 8 ) & 0xff );
155
+
156
+ reg = readl (p -> membase + DW_UART_CPR );
157
+ if (!reg )
158
+ return ;
159
+
160
+ /* Select the type based on fifo */
161
+ if (reg & DW_UART_CPR_FIFO_MODE ) {
162
+ p -> type = PORT_16550A ;
163
+ p -> flags |= UPF_FIXED_TYPE ;
164
+ p -> fifosize = DW_UART_CPR_FIFO_SIZE (reg );
165
+ up -> tx_loadsz = p -> fifosize ;
166
+ }
167
+ }
168
+
122
169
static int dw8250_probe (struct platform_device * pdev )
123
170
{
124
171
struct uart_8250_port uart = {};
@@ -156,6 +203,8 @@ static int dw8250_probe(struct platform_device *pdev)
156
203
return - ENODEV ;
157
204
}
158
205
206
+ dw8250_setup_port (& uart );
207
+
159
208
data = devm_kzalloc (& pdev -> dev , sizeof (* data ), GFP_KERNEL );
160
209
if (!data )
161
210
return - ENOMEM ;
0 commit comments