Commit d0c47b3ef7c582ec984edeba08984b0acc2ffcba
serial: UniPhier: use 32 bit register access
For PH1-Pro4, the 8 bit write access to LCR register (offset = 0x11) is not working correctly. As a side effect, it also modifies MCR register (offset = 0x10) and results in unexpected behavior. Signed-off-by: Masahiro Yamada <yamada.m@jp.panasonic.com>
Showing 1 changed file with 26 additions and 28 deletions Side-by-side Diff
1 | 1 | /* |
2 | - * Copyright (C) 2012-2014 Panasonic Corporation | |
2 | + * Copyright (C) 2012-2015 Panasonic Corporation | |
3 | 3 | * Author: Masahiro Yamada <yamada.m@jp.panasonic.com> |
4 | 4 | * |
5 | 5 | * SPDX-License-Identifier: GPL-2.0+ |
6 | 6 | |
7 | 7 | |
... | ... | @@ -13,31 +13,25 @@ |
13 | 13 | #include <serial.h> |
14 | 14 | #include <fdtdec.h> |
15 | 15 | |
16 | -#define UART_REG(x) \ | |
17 | - u8 x; \ | |
18 | - u8 postpad_##x[3]; | |
19 | - | |
20 | 16 | /* |
21 | 17 | * Note: Register map is slightly different from that of 16550. |
22 | 18 | */ |
23 | 19 | struct uniphier_serial { |
24 | - UART_REG(rbr); /* 0x00 */ | |
25 | - UART_REG(ier); /* 0x04 */ | |
26 | - UART_REG(iir); /* 0x08 */ | |
27 | - UART_REG(fcr); /* 0x0c */ | |
28 | - u8 mcr; /* 0x10 */ | |
29 | - u8 lcr; | |
30 | - u16 __postpad; | |
31 | - UART_REG(lsr); /* 0x14 */ | |
32 | - UART_REG(msr); /* 0x18 */ | |
33 | - u32 __none1; | |
34 | - u32 __none2; | |
35 | - u16 dlr; | |
36 | - u16 __postpad2; | |
20 | + u32 rx; /* In: Receive buffer */ | |
21 | +#define tx rx /* Out: Transmit buffer */ | |
22 | + u32 ier; /* Interrupt Enable Register */ | |
23 | + u32 iir; /* In: Interrupt ID Register */ | |
24 | + u32 char_fcr; /* Charactor / FIFO Control Register */ | |
25 | + u32 lcr_mcr; /* Line/Modem Control Register */ | |
26 | +#define LCR_SHIFT 8 | |
27 | +#define LCR_MASK (0xff << (LCR_SHIFT)) | |
28 | + u32 lsr; /* In: Line Status Register */ | |
29 | + u32 msr; /* In: Modem Status Register */ | |
30 | + u32 __rsv0; | |
31 | + u32 __rsv1; | |
32 | + u32 dlr; /* Divisor Latch Register */ | |
37 | 33 | }; |
38 | 34 | |
39 | -#define thr rbr | |
40 | - | |
41 | 35 | struct uniphier_serial_private_data { |
42 | 36 | struct uniphier_serial __iomem *membase; |
43 | 37 | }; |
44 | 38 | |
45 | 39 | |
... | ... | @@ -51,12 +45,16 @@ |
51 | 45 | struct uniphier_serial __iomem *port = uniphier_serial_port(dev); |
52 | 46 | const unsigned int mode_x_div = 16; |
53 | 47 | unsigned int divisor; |
48 | + u32 tmp; | |
54 | 49 | |
55 | - writeb(UART_LCR_WLEN8, &port->lcr); | |
50 | + tmp = readl(&port->lcr_mcr); | |
51 | + tmp &= ~LCR_MASK; | |
52 | + tmp |= UART_LCR_WLEN8 << LCR_SHIFT; | |
53 | + writel(tmp, &port->lcr_mcr); | |
56 | 54 | |
57 | 55 | divisor = DIV_ROUND_CLOSEST(plat->uartclk, mode_x_div * baudrate); |
58 | 56 | |
59 | - writew(divisor, &port->dlr); | |
57 | + writel(divisor, &port->dlr); | |
60 | 58 | |
61 | 59 | return 0; |
62 | 60 | } |
63 | 61 | |
64 | 62 | |
65 | 63 | |
... | ... | @@ -65,20 +63,20 @@ |
65 | 63 | { |
66 | 64 | struct uniphier_serial __iomem *port = uniphier_serial_port(dev); |
67 | 65 | |
68 | - if (!(readb(&port->lsr) & UART_LSR_DR)) | |
66 | + if (!(readl(&port->lsr) & UART_LSR_DR)) | |
69 | 67 | return -EAGAIN; |
70 | 68 | |
71 | - return readb(&port->rbr); | |
69 | + return readl(&port->rx); | |
72 | 70 | } |
73 | 71 | |
74 | 72 | static int uniphier_serial_putc(struct udevice *dev, const char c) |
75 | 73 | { |
76 | 74 | struct uniphier_serial __iomem *port = uniphier_serial_port(dev); |
77 | 75 | |
78 | - if (!(readb(&port->lsr) & UART_LSR_THRE)) | |
76 | + if (!(readl(&port->lsr) & UART_LSR_THRE)) | |
79 | 77 | return -EAGAIN; |
80 | 78 | |
81 | - writeb(c, &port->thr); | |
79 | + writel(c, &port->tx); | |
82 | 80 | |
83 | 81 | return 0; |
84 | 82 | } |
85 | 83 | |
... | ... | @@ -88,9 +86,9 @@ |
88 | 86 | struct uniphier_serial __iomem *port = uniphier_serial_port(dev); |
89 | 87 | |
90 | 88 | if (input) |
91 | - return readb(&port->lsr) & UART_LSR_DR; | |
89 | + return readl(&port->lsr) & UART_LSR_DR; | |
92 | 90 | else |
93 | - return !(readb(&port->lsr) & UART_LSR_THRE); | |
91 | + return !(readl(&port->lsr) & UART_LSR_THRE); | |
94 | 92 | } |
95 | 93 | |
96 | 94 | static int uniphier_serial_probe(struct udevice *dev) |
-
mentioned in commit 12a70e
-
mentioned in commit 12a70e
-
mentioned in commit 12a70e
-
mentioned in commit 12a70e
-
mentioned in commit 12a70e
-
mentioned in commit 12a70e
-
mentioned in commit 12a70e
-
mentioned in commit 12a70e
-
mentioned in commit 12a70e
-
mentioned in commit 12a70e
-
mentioned in commit 12a70e
-
mentioned in commit 12a70e
-
mentioned in commit 12a70e
-
mentioned in commit 12a70e
-
mentioned in commit 12a70e
-
mentioned in commit 12a70e
-
mentioned in commit 12a70e
-
mentioned in commit 12a70e
-
mentioned in commit 12a70e
-
mentioned in commit 12a70e
-
mentioned in commit 12a70e
-
mentioned in commit 12a70e
-
mentioned in commit 12a70e
-
mentioned in commit 12a70e
-
mentioned in commit 12a70e
-
mentioned in commit 12a70e
-
mentioned in commit 12a70e
-
mentioned in commit 12a70e
-
mentioned in commit 12a70e
-
mentioned in commit 12a70e
-
mentioned in commit 12a70e
-
mentioned in commit 12a70e
-
mentioned in commit 12a70e
-
mentioned in commit 12a70e
-
mentioned in commit 12a70e
-
mentioned in commit 12a70e
-
mentioned in commit 12a70e
-
mentioned in commit 12a70e