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 */
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
4547struct 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 */
5456struct 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
163170static 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
170175static 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
177180static 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
184185static 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
216215static 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
229227static 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
243239static 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
258252static 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
270263static 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
283275static 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
290280static 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
297285static 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
305291static 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
317302static 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
324307static 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
331312static 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
343323static 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
351329static 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
358334static 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
523501static 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