Skip to content

Commit d626452

Browse files
luca-fancellucarlescufi
authored andcommitted
driver: pl011: use new device model to map MMIO
Use the new device model introduced by device_mmio.h to map pl011 MMIO space. Signed-off-by: Luca Fancellu <[email protected]>
1 parent 0cc9ad4 commit d626452

File tree

1 file changed

+51
-73
lines changed

1 file changed

+51
-73
lines changed

drivers/serial/uart_pl011.c

Lines changed: 51 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
/*
22
* Copyright (c) 2018 Linaro Limited
3+
* Copyright (c) 2022 Arm Limited (or its affiliates). All rights reserved.
34
*
45
* SPDX-License-Identifier: Apache-2.0
56
*/
@@ -12,6 +13,7 @@
1213
#include <zephyr/init.h>
1314
#include <zephyr/device.h>
1415
#include <zephyr/drivers/uart.h>
16+
#include <zephyr/sys/device_mmio.h>
1517

1618
#ifdef CONFIG_CPU_CORTEX_M
1719
#include <cmsis_compiler.h>
@@ -43,7 +45,7 @@ struct pl011_regs {
4345
};
4446

4547
struct pl011_config {
46-
volatile struct pl011_regs *uart;
48+
DEVICE_MMIO_ROM;
4749
uint32_t sys_clk_freq;
4850
#ifdef CONFIG_UART_INTERRUPT_DRIVEN
4951
uart_irq_config_func_t irq_config_func;
@@ -52,6 +54,7 @@ struct pl011_config {
5254

5355
/* Device data structure */
5456
struct pl011_data {
57+
DEVICE_MMIO_RAM;
5558
uint32_t baud_rate; /* Baud rate */
5659
bool sbsa; /* SBSA mode */
5760
#ifdef CONFIG_UART_INTERRUPT_DRIVEN
@@ -153,39 +156,35 @@ struct pl011_data {
153156
PL011_IMSC_RXIM | PL011_IMSC_TXIM | \
154157
PL011_IMSC_RTIM)
155158

156-
static void pl011_enable(const struct device *dev)
159+
static inline
160+
volatile struct pl011_regs *const get_uart(const struct device *dev)
157161
{
158-
const struct pl011_config *config = dev->config;
162+
return (volatile struct pl011_regs *const)DEVICE_MMIO_GET(dev);
163+
}
159164

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;
161168
}
162169

163170
static void pl011_disable(const struct device *dev)
164171
{
165-
const struct pl011_config *config = dev->config;
166-
167-
config->uart->cr &= ~PL011_CR_UARTEN;
172+
get_uart(dev)->cr &= ~PL011_CR_UARTEN;
168173
}
169174

170175
static void pl011_enable_fifo(const struct device *dev)
171176
{
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;
175178
}
176179

177180
static void pl011_disable_fifo(const struct device *dev)
178181
{
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;
182183
}
183184

184185
static int pl011_set_baudrate(const struct device *dev,
185186
uint32_t clk, uint32_t baudrate)
186187
{
187-
const struct pl011_config *config = dev->config;
188-
189188
/* Avoiding float calculations, bauddiv is left shifted by 6 */
190189
uint64_t bauddiv = (((uint64_t)clk) << PL011_FBRD_WIDTH)
191190
/ (baudrate * 16U);
@@ -199,160 +198,137 @@ static int pl011_set_baudrate(const struct device *dev,
199198
return -EINVAL;
200199
}
201200

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);
204203

205204
__DMB();
206205

207206
/* In order to internally update the contents of ibrd or fbrd, a
208207
* lcr_h write must always be performed at the end
209208
* ARM DDI 0183F, Pg 3-13
210209
*/
211-
config->uart->lcr_h = config->uart->lcr_h;
210+
get_uart(dev)->lcr_h = get_uart(dev)->lcr_h;
212211

213212
return 0;
214213
}
215214

216215
static bool pl011_is_readable(const struct device *dev)
217216
{
218-
const struct pl011_config *config = dev->config;
219217
struct pl011_data *data = dev->data;
220218

221219
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)))
224222
return false;
225223

226-
return (config->uart->fr & PL011_FR_RXFE) == 0U;
224+
return (get_uart(dev)->fr & PL011_FR_RXFE) == 0U;
227225
}
228226

229227
static int pl011_poll_in(const struct device *dev, unsigned char *c)
230228
{
231-
const struct pl011_config *config = dev->config;
232-
233229
if (!pl011_is_readable(dev)) {
234230
return -1;
235231
}
236232

237233
/* got a character */
238-
*c = (unsigned char)config->uart->dr;
234+
*c = (unsigned char)get_uart(dev)->dr;
239235

240-
return config->uart->rsr & PL011_RSR_ERROR_MASK;
236+
return get_uart(dev)->rsr & PL011_RSR_ERROR_MASK;
241237
}
242238

243239
static void pl011_poll_out(const struct device *dev,
244240
unsigned char c)
245241
{
246-
const struct pl011_config *config = dev->config;
247-
248242
/* Wait for space in FIFO */
249-
while (config->uart->fr & PL011_FR_TXFF) {
243+
while (get_uart(dev)->fr & PL011_FR_TXFF) {
250244
; /* Wait */
251245
}
252246

253247
/* Send a character */
254-
config->uart->dr = (uint32_t)c;
248+
get_uart(dev)->dr = (uint32_t)c;
255249
}
256250

257251
#ifdef CONFIG_UART_INTERRUPT_DRIVEN
258252
static int pl011_fifo_fill(const struct device *dev,
259253
const uint8_t *tx_data, int len)
260254
{
261-
const struct pl011_config *config = dev->config;
262255
uint8_t num_tx = 0U;
263256

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++];
266259
}
267260
return num_tx;
268261
}
269262

270263
static int pl011_fifo_read(const struct device *dev,
271264
uint8_t *rx_data, const int len)
272265
{
273-
const struct pl011_config *config = dev->config;
274266
uint8_t num_rx = 0U;
275267

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;
278270
}
279271

280272
return num_rx;
281273
}
282274

283275
static void pl011_irq_tx_enable(const struct device *dev)
284276
{
285-
const struct pl011_config *config = dev->config;
286-
287-
config->uart->imsc |= PL011_IMSC_TXIM;
277+
get_uart(dev)->imsc |= PL011_IMSC_TXIM;
288278
}
289279

290280
static void pl011_irq_tx_disable(const struct device *dev)
291281
{
292-
const struct pl011_config *config = dev->config;
293-
294-
config->uart->imsc &= ~PL011_IMSC_TXIM;
282+
get_uart(dev)->imsc &= ~PL011_IMSC_TXIM;
295283
}
296284

297285
static int pl011_irq_tx_complete(const struct device *dev)
298286
{
299-
const struct pl011_config *config = dev->config;
300-
301287
/* check for TX FIFO empty */
302-
return config->uart->fr & PL011_FR_TXFE;
288+
return get_uart(dev)->fr & PL011_FR_TXFE;
303289
}
304290

305291
static int pl011_irq_tx_ready(const struct device *dev)
306292
{
307-
const struct pl011_config *config = dev->config;
308293
struct pl011_data *data = dev->data;
309294

310-
if (!data->sbsa && !(config->uart->cr & PL011_CR_TXE))
295+
if (!data->sbsa && !(get_uart(dev)->cr & PL011_CR_TXE))
311296
return false;
312297

313-
return ((config->uart->imsc & PL011_IMSC_TXIM) &&
298+
return ((get_uart(dev)->imsc & PL011_IMSC_TXIM) &&
314299
pl011_irq_tx_complete(dev));
315300
}
316301

317302
static void pl011_irq_rx_enable(const struct device *dev)
318303
{
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;
322305
}
323306

324307
static void pl011_irq_rx_disable(const struct device *dev)
325308
{
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);
329310
}
330311

331312
static int pl011_irq_rx_ready(const struct device *dev)
332313
{
333-
const struct pl011_config *config = dev->config;
334314
struct pl011_data *data = dev->data;
335315

336-
if (!data->sbsa && !(config->uart->cr & PL011_CR_RXE))
316+
if (!data->sbsa && !(get_uart(dev)->cr & PL011_CR_RXE))
337317
return false;
338318

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)));
341321
}
342322

343323
static void pl011_irq_err_enable(const struct device *dev)
344324
{
345-
const struct pl011_config *config = dev->config;
346-
347325
/* enable framing, parity, break, and overrun */
348-
config->uart->imsc |= PL011_IMSC_ERROR_MASK;
326+
get_uart(dev)->imsc |= PL011_IMSC_ERROR_MASK;
349327
}
350328

351329
static void pl011_irq_err_disable(const struct device *dev)
352330
{
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;
356332
}
357333

358334
static int pl011_irq_is_pending(const struct device *dev)
@@ -404,6 +380,8 @@ static int pl011_init(const struct device *dev)
404380
int ret;
405381
uint32_t lcrh;
406382

383+
DEVICE_MMIO_MAP(dev, K_MEM_CACHE_NONE);
384+
407385
/*
408386
* If working in SBSA mode, we assume that UART is already configured,
409387
* or does not require configuration at all (if UART is emulated by
@@ -422,23 +400,23 @@ static int pl011_init(const struct device *dev)
422400
}
423401

424402
/* 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);
426404
lcrh &= ~(BIT(0) | BIT(7));
427405
lcrh |= PL011_LCRH_WLEN_SIZE(8) << PL011_LCRH_WLEN_SHIFT;
428-
config->uart->lcr_h = lcrh;
406+
get_uart(dev)->lcr_h = lcrh;
429407

430408
/* Enabling the FIFOs */
431409
pl011_enable_fifo(dev);
432410
}
433411
/* 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;
436414

437415
if (!data->sbsa) {
438-
config->uart->dmacr = 0U;
416+
get_uart(dev)->dmacr = 0U;
439417
__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;
442420
__ISB();
443421
}
444422
#ifdef CONFIG_UART_INTERRUPT_DRIVEN
@@ -481,7 +459,7 @@ void pl011_isr(const struct device *dev)
481459
}; \
482460
\
483461
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)), \
485463
.sys_clk_freq = DT_INST_PROP_BY_PHANDLE(n, clocks, clock_frequency), \
486464
.irq_config_func = pl011_irq_config_func_##n, \
487465
};
@@ -521,7 +499,7 @@ static void pl011_irq_config_func_sbsa(const struct device *dev);
521499
#endif
522500

523501
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)),
525503
#ifdef CONFIG_UART_INTERRUPT_DRIVEN
526504
.irq_config_func = pl011_irq_config_func_sbsa,
527505
#endif

0 commit comments

Comments
 (0)