GNU Linux-libre 6.8.9-gnu
[releases.git] / drivers / tty / serial / 8250 / 8250_men_mcb.c
1 // SPDX-License-Identifier: GPL-2.0
2 #include <linux/device.h>
3 #include <linux/kernel.h>
4 #include <linux/module.h>
5 #include <linux/io.h>
6 #include <linux/mcb.h>
7 #include <linux/serial.h>
8 #include <linux/serial_core.h>
9 #include <linux/serial_8250.h>
10
11 #define MEN_UART_ID_Z025 0x19
12 #define MEN_UART_ID_Z057 0x39
13 #define MEN_UART_ID_Z125 0x7d
14
15 /*
16  * IP Cores Z025 and Z057 can have up to 4 UART
17  * The UARTs available are stored in a global
18  * register saved in physical address + 0x40
19  * Is saved as follows:
20  *
21  * 7                                                              0
22  * +------+-------+-------+-------+-------+-------+-------+-------+
23  * |UART4 | UART3 | UART2 | UART1 | U4irq | U3irq | U2irq | U1irq |
24  * +------+-------+-------+-------+-------+-------+-------+-------+
25  */
26 #define MEN_UART1_MASK  0x01
27 #define MEN_UART2_MASK  0x02
28 #define MEN_UART3_MASK  0x04
29 #define MEN_UART4_MASK  0x08
30
31 #define MEN_Z125_UARTS_AVAILABLE        0x01
32
33 #define MEN_Z025_MAX_UARTS              4
34 #define MEN_UART_MEM_SIZE               0x10
35 #define MEM_UART_REGISTER_SIZE          0x01
36 #define MEN_Z025_REGISTER_OFFSET        0x40
37
38 #define MEN_UART1_OFFSET        0
39 #define MEN_UART2_OFFSET        (MEN_UART1_OFFSET + MEN_UART_MEM_SIZE)
40 #define MEN_UART3_OFFSET        (MEN_UART2_OFFSET + MEN_UART_MEM_SIZE)
41 #define MEN_UART4_OFFSET        (MEN_UART3_OFFSET + MEN_UART_MEM_SIZE)
42
43 #define MEN_READ_REGISTER(addr) readb(addr)
44
45 #define MAX_PORTS       4
46
47 struct serial_8250_men_mcb_data {
48         int num_ports;
49         int line[MAX_PORTS];
50         unsigned int offset[MAX_PORTS];
51 };
52
53 /*
54  * The Z125 16550-compatible UART has no fixed base clock assigned
55  * So, depending on the board we're on, we need to adjust the
56  * parameter in order to really set the correct baudrate, and
57  * do so if possible without user interaction
58  */
59 static u32 men_lookup_uartclk(struct mcb_device *mdev)
60 {
61         /* use default value if board is not available below */
62         u32 clkval = 1041666;
63
64         dev_info(&mdev->dev, "%s on board %s\n",
65                 dev_name(&mdev->dev),
66                 mdev->bus->name);
67         if  (strncmp(mdev->bus->name, "F075", 4) == 0)
68                 clkval = 1041666;
69         else if (strncmp(mdev->bus->name, "F216", 4) == 0)
70                 clkval = 1843200;
71         else if (strncmp(mdev->bus->name, "F210", 4) == 0)
72                 clkval = 115200;
73         else if (strstr(mdev->bus->name, "215"))
74                 clkval = 1843200;
75         else
76                 dev_info(&mdev->dev,
77                          "board not detected, using default uartclk\n");
78
79         clkval = clkval  << 4;
80
81         return clkval;
82 }
83
84 static int read_uarts_available_from_register(struct resource *mem_res,
85                                               u8 *uarts_available)
86 {
87         void __iomem *mem;
88         int reg_value;
89
90         if (!request_mem_region(mem_res->start + MEN_Z025_REGISTER_OFFSET,
91                                 MEM_UART_REGISTER_SIZE,  KBUILD_MODNAME)) {
92                 return -EBUSY;
93         }
94
95         mem = ioremap(mem_res->start + MEN_Z025_REGISTER_OFFSET,
96                       MEM_UART_REGISTER_SIZE);
97         if (!mem) {
98                 release_mem_region(mem_res->start + MEN_Z025_REGISTER_OFFSET,
99                                    MEM_UART_REGISTER_SIZE);
100                 return -ENOMEM;
101         }
102
103         reg_value = MEN_READ_REGISTER(mem);
104
105         iounmap(mem);
106
107         release_mem_region(mem_res->start + MEN_Z025_REGISTER_OFFSET,
108                            MEM_UART_REGISTER_SIZE);
109
110         *uarts_available = reg_value >> 4;
111
112         return 0;
113 }
114
115 static int read_serial_data(struct mcb_device *mdev,
116                             struct resource *mem_res,
117                             struct serial_8250_men_mcb_data *serial_data)
118 {
119         u8 uarts_available;
120         int count = 0;
121         int mask;
122         int res;
123         int i;
124
125         res = read_uarts_available_from_register(mem_res, &uarts_available);
126         if (res < 0)
127                 return res;
128
129         for (i = 0; i < MAX_PORTS; i++) {
130                 mask = 0x1 << i;
131                 switch (uarts_available & mask) {
132                 case MEN_UART1_MASK:
133                         serial_data->offset[count] = MEN_UART1_OFFSET;
134                         count++;
135                         break;
136                 case MEN_UART2_MASK:
137                         serial_data->offset[count] = MEN_UART2_OFFSET;
138                         count++;
139                         break;
140                 case MEN_UART3_MASK:
141                         serial_data->offset[count] = MEN_UART3_OFFSET;
142                         count++;
143                         break;
144                 case MEN_UART4_MASK:
145                         serial_data->offset[count] = MEN_UART4_OFFSET;
146                         count++;
147                         break;
148                 default:
149                         return -EINVAL;
150                 }
151         }
152
153         if (count <= 0 || count > MAX_PORTS) {
154                 dev_err(&mdev->dev, "unexpected number of ports: %u\n",
155                         count);
156                 return -ENODEV;
157         }
158
159         serial_data->num_ports = count;
160
161         return 0;
162 }
163
164 static int init_serial_data(struct mcb_device *mdev,
165                             struct resource *mem_res,
166                             struct serial_8250_men_mcb_data *serial_data)
167 {
168         switch (mdev->id) {
169         case MEN_UART_ID_Z125:
170                 serial_data->num_ports = 1;
171                 serial_data->offset[0] = 0;
172                 return 0;
173         case MEN_UART_ID_Z025:
174         case MEN_UART_ID_Z057:
175                 return read_serial_data(mdev, mem_res, serial_data);
176         default:
177                 dev_err(&mdev->dev, "no supported device!\n");
178                 return -ENODEV;
179         }
180 }
181
182 static int serial_8250_men_mcb_probe(struct mcb_device *mdev,
183                                      const struct mcb_device_id *id)
184 {
185         struct uart_8250_port uart;
186         struct serial_8250_men_mcb_data *data;
187         struct resource *mem;
188         int i;
189         int res;
190
191         mem = mcb_get_resource(mdev, IORESOURCE_MEM);
192         if (mem == NULL)
193                 return -ENXIO;
194
195         data = devm_kzalloc(&mdev->dev,
196                             sizeof(struct serial_8250_men_mcb_data),
197                             GFP_KERNEL);
198         if (!data)
199                 return -ENOMEM;
200
201         res = init_serial_data(mdev, mem, data);
202         if (res < 0)
203                 return res;
204
205         dev_dbg(&mdev->dev, "found a 16z%03u with %u ports\n",
206                 mdev->id, data->num_ports);
207
208         mcb_set_drvdata(mdev, data);
209
210         for (i = 0; i < data->num_ports; i++) {
211                 memset(&uart, 0, sizeof(struct uart_8250_port));
212                 spin_lock_init(&uart.port.lock);
213
214                 uart.port.flags = UPF_SKIP_TEST |
215                                   UPF_SHARE_IRQ |
216                                   UPF_BOOT_AUTOCONF |
217                                   UPF_IOREMAP;
218                 uart.port.iotype = UPIO_MEM;
219                 uart.port.uartclk = men_lookup_uartclk(mdev);
220                 uart.port.irq = mcb_get_irq(mdev);
221                 uart.port.mapbase = (unsigned long) mem->start
222                                             + data->offset[i];
223
224                 /* ok, register the port */
225                 res = serial8250_register_8250_port(&uart);
226                 if (res < 0) {
227                         dev_err(&mdev->dev, "unable to register UART port\n");
228                         return res;
229                 }
230
231                 data->line[i] = res;
232                 dev_info(&mdev->dev, "found MCB UART: ttyS%d\n", data->line[i]);
233         }
234
235         return 0;
236 }
237
238 static void serial_8250_men_mcb_remove(struct mcb_device *mdev)
239 {
240         int i;
241         struct serial_8250_men_mcb_data *data = mcb_get_drvdata(mdev);
242
243         if (!data)
244                 return;
245
246         for (i = 0; i < data->num_ports; i++)
247                 serial8250_unregister_port(data->line[i]);
248 }
249
250 static const struct mcb_device_id serial_8250_men_mcb_ids[] = {
251         { .device = MEN_UART_ID_Z025 },
252         { .device = MEN_UART_ID_Z057 },
253         { .device = MEN_UART_ID_Z125 },
254         { }
255 };
256 MODULE_DEVICE_TABLE(mcb, serial_8250_men_mcb_ids);
257
258 static struct mcb_driver mcb_driver = {
259         .driver = {
260                 .name = "8250_men_mcb",
261         },
262         .probe = serial_8250_men_mcb_probe,
263         .remove = serial_8250_men_mcb_remove,
264         .id_table = serial_8250_men_mcb_ids,
265 };
266 module_mcb_driver(mcb_driver);
267
268 MODULE_LICENSE("GPL v2");
269 MODULE_DESCRIPTION("MEN 8250 UART driver");
270 MODULE_AUTHOR("Michael Moese <michael.moese@men.de");
271 MODULE_ALIAS("mcb:16z125");
272 MODULE_ALIAS("mcb:16z025");
273 MODULE_ALIAS("mcb:16z057");
274 MODULE_IMPORT_NS(MCB);