1
1
/*
2
2
* Copyright (c) 2018 Linaro Limited
3
+ * Copyright (c) 2022 Arm Limited (or its affiliates). All rights reserved.
3
4
*
4
5
* SPDX-License-Identifier: Apache-2.0
5
6
*/
12
13
#include <zephyr/init.h>
13
14
#include <zephyr/device.h>
14
15
#include <zephyr/drivers/uart.h>
16
+ #include <zephyr/sys/device_mmio.h>
15
17
16
18
#ifdef CONFIG_CPU_CORTEX_M
17
19
#include <cmsis_compiler.h>
@@ -43,7 +45,7 @@ struct pl011_regs {
43
45
};
44
46
45
47
struct pl011_config {
46
- volatile struct pl011_regs * uart ;
48
+ DEVICE_MMIO_ROM ;
47
49
uint32_t sys_clk_freq ;
48
50
#ifdef CONFIG_UART_INTERRUPT_DRIVEN
49
51
uart_irq_config_func_t irq_config_func ;
@@ -52,6 +54,7 @@ struct pl011_config {
52
54
53
55
/* Device data structure */
54
56
struct pl011_data {
57
+ DEVICE_MMIO_RAM ;
55
58
uint32_t baud_rate ; /* Baud rate */
56
59
bool sbsa ; /* SBSA mode */
57
60
#ifdef CONFIG_UART_INTERRUPT_DRIVEN
@@ -153,39 +156,35 @@ struct pl011_data {
153
156
PL011_IMSC_RXIM | PL011_IMSC_TXIM | \
154
157
PL011_IMSC_RTIM)
155
158
156
- static void pl011_enable (const struct device * dev )
159
+ static inline
160
+ volatile struct pl011_regs * const get_uart (const struct device * dev )
157
161
{
158
- const struct pl011_config * config = dev -> config ;
162
+ return (volatile struct pl011_regs * const )DEVICE_MMIO_GET (dev );
163
+ }
159
164
160
- config -> uart -> cr |= PL011_CR_UARTEN ;
165
+ static void pl011_enable (const struct device * dev )
166
+ {
167
+ get_uart (dev )-> cr |= PL011_CR_UARTEN ;
161
168
}
162
169
163
170
static void pl011_disable (const struct device * dev )
164
171
{
165
- const struct pl011_config * config = dev -> config ;
166
-
167
- config -> uart -> cr &= ~PL011_CR_UARTEN ;
172
+ get_uart (dev )-> cr &= ~PL011_CR_UARTEN ;
168
173
}
169
174
170
175
static void pl011_enable_fifo (const struct device * dev )
171
176
{
172
- const struct pl011_config * config = dev -> config ;
173
-
174
- config -> uart -> lcr_h |= PL011_LCRH_FEN ;
177
+ get_uart (dev )-> lcr_h |= PL011_LCRH_FEN ;
175
178
}
176
179
177
180
static void pl011_disable_fifo (const struct device * dev )
178
181
{
179
- const struct pl011_config * config = dev -> config ;
180
-
181
- config -> uart -> lcr_h &= ~PL011_LCRH_FEN ;
182
+ get_uart (dev )-> lcr_h &= ~PL011_LCRH_FEN ;
182
183
}
183
184
184
185
static int pl011_set_baudrate (const struct device * dev ,
185
186
uint32_t clk , uint32_t baudrate )
186
187
{
187
- const struct pl011_config * config = dev -> config ;
188
-
189
188
/* Avoiding float calculations, bauddiv is left shifted by 6 */
190
189
uint64_t bauddiv = (((uint64_t )clk ) << PL011_FBRD_WIDTH )
191
190
/ (baudrate * 16U );
@@ -199,160 +198,137 @@ static int pl011_set_baudrate(const struct device *dev,
199
198
return - EINVAL ;
200
199
}
201
200
202
- config -> uart -> ibrd = bauddiv >> PL011_FBRD_WIDTH ;
203
- config -> uart -> fbrd = bauddiv & ((1u << PL011_FBRD_WIDTH ) - 1u );
201
+ get_uart ( dev ) -> ibrd = bauddiv >> PL011_FBRD_WIDTH ;
202
+ get_uart ( dev ) -> fbrd = bauddiv & ((1u << PL011_FBRD_WIDTH ) - 1u );
204
203
205
204
__DMB ();
206
205
207
206
/* In order to internally update the contents of ibrd or fbrd, a
208
207
* lcr_h write must always be performed at the end
209
208
* ARM DDI 0183F, Pg 3-13
210
209
*/
211
- config -> uart -> lcr_h = config -> uart -> lcr_h ;
210
+ get_uart ( dev ) -> lcr_h = get_uart ( dev ) -> lcr_h ;
212
211
213
212
return 0 ;
214
213
}
215
214
216
215
static bool pl011_is_readable (const struct device * dev )
217
216
{
218
- const struct pl011_config * config = dev -> config ;
219
217
struct pl011_data * data = dev -> data ;
220
218
221
219
if (!data -> sbsa &&
222
- (!(config -> uart -> cr & PL011_CR_UARTEN ) ||
223
- !(config -> uart -> cr & PL011_CR_RXE )))
220
+ (!(get_uart ( dev ) -> cr & PL011_CR_UARTEN ) ||
221
+ !(get_uart ( dev ) -> cr & PL011_CR_RXE )))
224
222
return false;
225
223
226
- return (config -> uart -> fr & PL011_FR_RXFE ) == 0U ;
224
+ return (get_uart ( dev ) -> fr & PL011_FR_RXFE ) == 0U ;
227
225
}
228
226
229
227
static int pl011_poll_in (const struct device * dev , unsigned char * c )
230
228
{
231
- const struct pl011_config * config = dev -> config ;
232
-
233
229
if (!pl011_is_readable (dev )) {
234
230
return -1 ;
235
231
}
236
232
237
233
/* got a character */
238
- * c = (unsigned char )config -> uart -> dr ;
234
+ * c = (unsigned char )get_uart ( dev ) -> dr ;
239
235
240
- return config -> uart -> rsr & PL011_RSR_ERROR_MASK ;
236
+ return get_uart ( dev ) -> rsr & PL011_RSR_ERROR_MASK ;
241
237
}
242
238
243
239
static void pl011_poll_out (const struct device * dev ,
244
240
unsigned char c )
245
241
{
246
- const struct pl011_config * config = dev -> config ;
247
-
248
242
/* Wait for space in FIFO */
249
- while (config -> uart -> fr & PL011_FR_TXFF ) {
243
+ while (get_uart ( dev ) -> fr & PL011_FR_TXFF ) {
250
244
; /* Wait */
251
245
}
252
246
253
247
/* Send a character */
254
- config -> uart -> dr = (uint32_t )c ;
248
+ get_uart ( dev ) -> dr = (uint32_t )c ;
255
249
}
256
250
257
251
#ifdef CONFIG_UART_INTERRUPT_DRIVEN
258
252
static int pl011_fifo_fill (const struct device * dev ,
259
253
const uint8_t * tx_data , int len )
260
254
{
261
- const struct pl011_config * config = dev -> config ;
262
255
uint8_t num_tx = 0U ;
263
256
264
- while (!(config -> uart -> fr & PL011_FR_TXFF ) && (len - num_tx > 0 )) {
265
- config -> uart -> dr = tx_data [num_tx ++ ];
257
+ while (!(get_uart ( dev ) -> fr & PL011_FR_TXFF ) && (len - num_tx > 0 )) {
258
+ get_uart ( dev ) -> dr = tx_data [num_tx ++ ];
266
259
}
267
260
return num_tx ;
268
261
}
269
262
270
263
static int pl011_fifo_read (const struct device * dev ,
271
264
uint8_t * rx_data , const int len )
272
265
{
273
- const struct pl011_config * config = dev -> config ;
274
266
uint8_t num_rx = 0U ;
275
267
276
- while ((len - num_rx > 0 ) && !(config -> uart -> fr & PL011_FR_RXFE )) {
277
- rx_data [num_rx ++ ] = config -> uart -> dr ;
268
+ while ((len - num_rx > 0 ) && !(get_uart ( dev ) -> fr & PL011_FR_RXFE )) {
269
+ rx_data [num_rx ++ ] = get_uart ( dev ) -> dr ;
278
270
}
279
271
280
272
return num_rx ;
281
273
}
282
274
283
275
static void pl011_irq_tx_enable (const struct device * dev )
284
276
{
285
- const struct pl011_config * config = dev -> config ;
286
-
287
- config -> uart -> imsc |= PL011_IMSC_TXIM ;
277
+ get_uart (dev )-> imsc |= PL011_IMSC_TXIM ;
288
278
}
289
279
290
280
static void pl011_irq_tx_disable (const struct device * dev )
291
281
{
292
- const struct pl011_config * config = dev -> config ;
293
-
294
- config -> uart -> imsc &= ~PL011_IMSC_TXIM ;
282
+ get_uart (dev )-> imsc &= ~PL011_IMSC_TXIM ;
295
283
}
296
284
297
285
static int pl011_irq_tx_complete (const struct device * dev )
298
286
{
299
- const struct pl011_config * config = dev -> config ;
300
-
301
287
/* check for TX FIFO empty */
302
- return config -> uart -> fr & PL011_FR_TXFE ;
288
+ return get_uart ( dev ) -> fr & PL011_FR_TXFE ;
303
289
}
304
290
305
291
static int pl011_irq_tx_ready (const struct device * dev )
306
292
{
307
- const struct pl011_config * config = dev -> config ;
308
293
struct pl011_data * data = dev -> data ;
309
294
310
- if (!data -> sbsa && !(config -> uart -> cr & PL011_CR_TXE ))
295
+ if (!data -> sbsa && !(get_uart ( dev ) -> cr & PL011_CR_TXE ))
311
296
return false;
312
297
313
- return ((config -> uart -> imsc & PL011_IMSC_TXIM ) &&
298
+ return ((get_uart ( dev ) -> imsc & PL011_IMSC_TXIM ) &&
314
299
pl011_irq_tx_complete (dev ));
315
300
}
316
301
317
302
static void pl011_irq_rx_enable (const struct device * dev )
318
303
{
319
- const struct pl011_config * config = dev -> config ;
320
-
321
- config -> uart -> imsc |= PL011_IMSC_RXIM | PL011_IMSC_RTIM ;
304
+ get_uart (dev )-> imsc |= PL011_IMSC_RXIM | PL011_IMSC_RTIM ;
322
305
}
323
306
324
307
static void pl011_irq_rx_disable (const struct device * dev )
325
308
{
326
- const struct pl011_config * config = dev -> config ;
327
-
328
- config -> uart -> imsc &= ~(PL011_IMSC_RXIM | PL011_IMSC_RTIM );
309
+ get_uart (dev )-> imsc &= ~(PL011_IMSC_RXIM | PL011_IMSC_RTIM );
329
310
}
330
311
331
312
static int pl011_irq_rx_ready (const struct device * dev )
332
313
{
333
- const struct pl011_config * config = dev -> config ;
334
314
struct pl011_data * data = dev -> data ;
335
315
336
- if (!data -> sbsa && !(config -> uart -> cr & PL011_CR_RXE ))
316
+ if (!data -> sbsa && !(get_uart ( dev ) -> cr & PL011_CR_RXE ))
337
317
return false;
338
318
339
- return ((config -> uart -> imsc & PL011_IMSC_RXIM ) &&
340
- (!(config -> uart -> fr & PL011_FR_RXFE )));
319
+ return ((get_uart ( dev ) -> imsc & PL011_IMSC_RXIM ) &&
320
+ (!(get_uart ( dev ) -> fr & PL011_FR_RXFE )));
341
321
}
342
322
343
323
static void pl011_irq_err_enable (const struct device * dev )
344
324
{
345
- const struct pl011_config * config = dev -> config ;
346
-
347
325
/* enable framing, parity, break, and overrun */
348
- config -> uart -> imsc |= PL011_IMSC_ERROR_MASK ;
326
+ get_uart ( dev ) -> imsc |= PL011_IMSC_ERROR_MASK ;
349
327
}
350
328
351
329
static void pl011_irq_err_disable (const struct device * dev )
352
330
{
353
- const struct pl011_config * config = dev -> config ;
354
-
355
- config -> uart -> imsc &= ~PL011_IMSC_ERROR_MASK ;
331
+ get_uart (dev )-> imsc &= ~PL011_IMSC_ERROR_MASK ;
356
332
}
357
333
358
334
static int pl011_irq_is_pending (const struct device * dev )
@@ -404,6 +380,8 @@ static int pl011_init(const struct device *dev)
404
380
int ret ;
405
381
uint32_t lcrh ;
406
382
383
+ DEVICE_MMIO_MAP (dev , K_MEM_CACHE_NONE );
384
+
407
385
/*
408
386
* If working in SBSA mode, we assume that UART is already configured,
409
387
* or does not require configuration at all (if UART is emulated by
@@ -422,23 +400,23 @@ static int pl011_init(const struct device *dev)
422
400
}
423
401
424
402
/* Setting the default character format */
425
- lcrh = config -> uart -> lcr_h & ~(PL011_LCRH_FORMAT_MASK );
403
+ lcrh = get_uart ( dev ) -> lcr_h & ~(PL011_LCRH_FORMAT_MASK );
426
404
lcrh &= ~(BIT (0 ) | BIT (7 ));
427
405
lcrh |= PL011_LCRH_WLEN_SIZE (8 ) << PL011_LCRH_WLEN_SHIFT ;
428
- config -> uart -> lcr_h = lcrh ;
406
+ get_uart ( dev ) -> lcr_h = lcrh ;
429
407
430
408
/* Enabling the FIFOs */
431
409
pl011_enable_fifo (dev );
432
410
}
433
411
/* initialize all IRQs as masked */
434
- config -> uart -> imsc = 0U ;
435
- config -> uart -> icr = PL011_IMSC_MASK_ALL ;
412
+ get_uart ( dev ) -> imsc = 0U ;
413
+ get_uart ( dev ) -> icr = PL011_IMSC_MASK_ALL ;
436
414
437
415
if (!data -> sbsa ) {
438
- config -> uart -> dmacr = 0U ;
416
+ get_uart ( dev ) -> dmacr = 0U ;
439
417
__ISB ();
440
- config -> uart -> cr &= ~(BIT (14 ) | BIT (15 ) | BIT (1 ));
441
- config -> uart -> cr |= PL011_CR_RXE | PL011_CR_TXE ;
418
+ get_uart ( dev ) -> cr &= ~(BIT (14 ) | BIT (15 ) | BIT (1 ));
419
+ get_uart ( dev ) -> cr |= PL011_CR_RXE | PL011_CR_TXE ;
442
420
__ISB ();
443
421
}
444
422
#ifdef CONFIG_UART_INTERRUPT_DRIVEN
@@ -481,7 +459,7 @@ void pl011_isr(const struct device *dev)
481
459
}; \
482
460
\
483
461
static struct pl011_config pl011_cfg_port_##n = { \
484
- .uart = (volatile struct pl011_regs *)DT_INST_REG_ADDR (n), \
462
+ DEVICE_MMIO_ROM_INIT(DT_DRV_INST (n)), \
485
463
.sys_clk_freq = DT_INST_PROP_BY_PHANDLE(n, clocks, clock_frequency), \
486
464
.irq_config_func = pl011_irq_config_func_##n, \
487
465
};
@@ -521,7 +499,7 @@ static void pl011_irq_config_func_sbsa(const struct device *dev);
521
499
#endif
522
500
523
501
static struct pl011_config pl011_cfg_sbsa = {
524
- . uart = ( volatile struct pl011_regs * ) DT_INST_REG_ADDR ( 0 ),
502
+ DEVICE_MMIO_ROM_INIT ( DT_DRV_INST ( 0 ) ),
525
503
#ifdef CONFIG_UART_INTERRUPT_DRIVEN
526
504
.irq_config_func = pl011_irq_config_func_sbsa ,
527
505
#endif
0 commit comments