3b088b3b23a50af902e50397dbb8ce304e859e65
[platform/kernel/u-boot.git] / drivers / serial / serial_msm.c
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Qualcomm UART driver
4  *
5  * (C) Copyright 2015 Mateusz Kulikowski <mateusz.kulikowski@gmail.com>
6  *
7  * UART will work in Data Mover mode.
8  * Based on Linux driver.
9  */
10
11 #include <common.h>
12 #include <clk.h>
13 #include <dm.h>
14 #include <errno.h>
15 #include <malloc.h>
16 #include <serial.h>
17 #include <watchdog.h>
18 #include <asm/io.h>
19 #include <linux/compiler.h>
20 #include <dm/pinctrl.h>
21
22 /* Serial registers - this driver works in uartdm mode*/
23
24 #define UARTDM_DMRX             0x34 /* Max RX transfer length */
25 #define UARTDM_NCF_TX           0x40 /* Number of chars to TX */
26
27 #define UARTDM_RXFS             0x50 /* RX channel status register */
28 #define UARTDM_RXFS_BUF_SHIFT   0x7  /* Number of bytes in the packing buffer */
29 #define UARTDM_RXFS_BUF_MASK    0x7
30 #define UARTDM_MR1                               0x00
31 #define UARTDM_MR2                               0x04
32 #define UARTDM_CSR                               0xA0
33
34 #define UARTDM_SR                0xA4 /* Status register */
35 #define UARTDM_SR_RX_READY       (1 << 0) /* Word is the receiver FIFO */
36 #define UARTDM_SR_TX_EMPTY       (1 << 3) /* Transmitter underrun */
37 #define UARTDM_SR_UART_OVERRUN   (1 << 4) /* Receive overrun */
38
39 #define UARTDM_CR                         0xA8 /* Command register */
40 #define UARTDM_CR_CMD_RESET_ERR           (3 << 4) /* Clear overrun error */
41 #define UARTDM_CR_CMD_RESET_STALE_INT     (8 << 4) /* Clears stale irq */
42 #define UARTDM_CR_CMD_RESET_TX_READY      (3 << 8) /* Clears TX Ready irq*/
43 #define UARTDM_CR_CMD_FORCE_STALE         (4 << 8) /* Causes stale event */
44 #define UARTDM_CR_CMD_STALE_EVENT_DISABLE (6 << 8) /* Disable stale event */
45
46 #define UARTDM_IMR                0xB0 /* Interrupt mask register */
47 #define UARTDM_ISR                0xB4 /* Interrupt status register */
48 #define UARTDM_ISR_TX_READY       0x80 /* TX FIFO empty */
49
50 #define UARTDM_TF               0x100 /* UART Transmit FIFO register */
51 #define UARTDM_RF               0x140 /* UART Receive FIFO register */
52
53 #define UART_DM_CLK_RX_TX_BIT_RATE 0xCC
54 #define MSM_BOOT_UART_DM_8_N_1_MODE 0x34
55 #define MSM_BOOT_UART_DM_CMD_RESET_RX 0x10
56 #define MSM_BOOT_UART_DM_CMD_RESET_TX 0x20
57
58 DECLARE_GLOBAL_DATA_PTR;
59
60 struct msm_serial_data {
61         phys_addr_t base;
62         unsigned chars_cnt; /* number of buffered chars */
63         uint32_t chars_buf; /* buffered chars */
64         uint32_t clk_bit_rate; /* data mover mode bit rate register value */
65 };
66
67 static int msm_serial_fetch(struct udevice *dev)
68 {
69         struct msm_serial_data *priv = dev_get_priv(dev);
70         unsigned sr;
71
72         if (priv->chars_cnt)
73                 return priv->chars_cnt;
74
75         /* Clear error in case of buffer overrun */
76         if (readl(priv->base + UARTDM_SR) & UARTDM_SR_UART_OVERRUN)
77                 writel(UARTDM_CR_CMD_RESET_ERR, priv->base + UARTDM_CR);
78
79         /* We need to fetch new character */
80         sr = readl(priv->base + UARTDM_SR);
81
82         if (sr & UARTDM_SR_RX_READY) {
83                 /* There are at least 4 bytes in fifo */
84                 priv->chars_buf = readl(priv->base + UARTDM_RF);
85                 priv->chars_cnt = 4;
86         } else {
87                 /* Check if there is anything in fifo */
88                 priv->chars_cnt = readl(priv->base + UARTDM_RXFS);
89                 /* Extract number of characters in UART packing buffer*/
90                 priv->chars_cnt = (priv->chars_cnt >>
91                                    UARTDM_RXFS_BUF_SHIFT) &
92                                   UARTDM_RXFS_BUF_MASK;
93                 if (!priv->chars_cnt)
94                         return 0;
95
96                 /* There is at least one charcter, move it to fifo */
97                 writel(UARTDM_CR_CMD_FORCE_STALE,
98                        priv->base + UARTDM_CR);
99
100                 priv->chars_buf = readl(priv->base + UARTDM_RF);
101                 writel(UARTDM_CR_CMD_RESET_STALE_INT,
102                        priv->base + UARTDM_CR);
103                 writel(0x7, priv->base + UARTDM_DMRX);
104         }
105
106         return priv->chars_cnt;
107 }
108
109 static int msm_serial_getc(struct udevice *dev)
110 {
111         struct msm_serial_data *priv = dev_get_priv(dev);
112         char c;
113
114         if (!msm_serial_fetch(dev))
115                 return -EAGAIN;
116
117         c = priv->chars_buf & 0xFF;
118         priv->chars_buf >>= 8;
119         priv->chars_cnt--;
120
121         return c;
122 }
123
124 static int msm_serial_putc(struct udevice *dev, const char ch)
125 {
126         struct msm_serial_data *priv = dev_get_priv(dev);
127
128         if (!(readl(priv->base + UARTDM_SR) & UARTDM_SR_TX_EMPTY) &&
129             !(readl(priv->base + UARTDM_ISR) & UARTDM_ISR_TX_READY))
130                 return -EAGAIN;
131
132         writel(UARTDM_CR_CMD_RESET_TX_READY, priv->base + UARTDM_CR);
133
134         writel(1, priv->base + UARTDM_NCF_TX);
135         writel(ch, priv->base + UARTDM_TF);
136
137         return 0;
138 }
139
140 static int msm_serial_pending(struct udevice *dev, bool input)
141 {
142         if (input) {
143                 if (msm_serial_fetch(dev))
144                         return 1;
145         }
146
147         return 0;
148 }
149
150 static const struct dm_serial_ops msm_serial_ops = {
151         .putc = msm_serial_putc,
152         .pending = msm_serial_pending,
153         .getc = msm_serial_getc,
154 };
155
156 static int msm_uart_clk_init(struct udevice *dev)
157 {
158         uint clk_rate = fdtdec_get_uint(gd->fdt_blob, dev_of_offset(dev),
159                                         "clock-frequency", 115200);
160         uint clkd[2]; /* clk_id and clk_no */
161         int clk_offset;
162         struct udevice *clk_dev;
163         struct clk clk;
164         int ret;
165
166         ret = fdtdec_get_int_array(gd->fdt_blob, dev_of_offset(dev), "clock",
167                                    clkd, 2);
168         if (ret)
169                 return ret;
170
171         clk_offset = fdt_node_offset_by_phandle(gd->fdt_blob, clkd[0]);
172         if (clk_offset < 0)
173                 return clk_offset;
174
175         ret = uclass_get_device_by_of_offset(UCLASS_CLK, clk_offset, &clk_dev);
176         if (ret)
177                 return ret;
178
179         clk.id = clkd[1];
180         ret = clk_request(clk_dev, &clk);
181         if (ret < 0)
182                 return ret;
183
184         ret = clk_set_rate(&clk, clk_rate);
185         clk_free(&clk);
186         if (ret < 0)
187                 return ret;
188
189         return 0;
190 }
191
192 static void uart_dm_init(struct msm_serial_data *priv)
193 {
194         writel(priv->clk_bit_rate, priv->base + UARTDM_CSR);
195         writel(0x0, priv->base + UARTDM_MR1);
196         writel(MSM_BOOT_UART_DM_8_N_1_MODE, priv->base + UARTDM_MR2);
197         writel(MSM_BOOT_UART_DM_CMD_RESET_RX, priv->base + UARTDM_CR);
198         writel(MSM_BOOT_UART_DM_CMD_RESET_TX, priv->base + UARTDM_CR);
199 }
200 static int msm_serial_probe(struct udevice *dev)
201 {
202         int ret;
203         struct msm_serial_data *priv = dev_get_priv(dev);
204
205         /* No need to reinitialize the UART after relocation */
206         if (gd->flags & GD_FLG_RELOC)
207                 return 0;
208
209         ret = msm_uart_clk_init(dev);
210         if (ret)
211                 return ret;
212
213         pinctrl_select_state(dev, "uart");
214         uart_dm_init(priv);
215
216         return 0;
217 }
218
219 static int msm_serial_ofdata_to_platdata(struct udevice *dev)
220 {
221         struct msm_serial_data *priv = dev_get_priv(dev);
222
223         priv->base = dev_read_addr(dev);
224         if (priv->base == FDT_ADDR_T_NONE)
225                 return -EINVAL;
226
227         priv->clk_bit_rate = fdtdec_get_int(gd->fdt_blob, dev_of_offset(dev), 
228                                                         "bit-rate", UART_DM_CLK_RX_TX_BIT_RATE);
229
230         return 0;
231 }
232
233 static const struct udevice_id msm_serial_ids[] = {
234         { .compatible = "qcom,msm-uartdm-v1.4" },
235         { }
236 };
237
238 U_BOOT_DRIVER(serial_msm) = {
239         .name   = "serial_msm",
240         .id     = UCLASS_SERIAL,
241         .of_match = msm_serial_ids,
242         .ofdata_to_platdata = msm_serial_ofdata_to_platdata,
243         .priv_auto      = sizeof(struct msm_serial_data),
244         .probe = msm_serial_probe,
245         .ops    = &msm_serial_ops,
246 };