5
5
*/
6
6
7
7
#define DT_DRV_COMPAT arm_pl011
8
+ #define SBSA_COMPAT arm_sbsa_uart
8
9
9
10
#include <kernel.h>
10
11
#include <arch/cpu.h>
@@ -41,6 +42,7 @@ struct pl011_regs {
41
42
/* Device data structure */
42
43
struct pl011_data {
43
44
uint32_t baud_rate ; /* Baud rate */
45
+ bool sbsa ; /* SBSA mode */
44
46
#ifdef CONFIG_UART_INTERRUPT_DRIVEN
45
47
uart_irq_callback_user_data_t irq_cb ;
46
48
void * irq_cb_data ;
@@ -199,13 +201,12 @@ static int pl011_set_baudrate(const struct device *dev,
199
201
200
202
static bool pl011_is_readable (const struct device * dev )
201
203
{
202
- if ((PL011_REGS (dev )-> cr & PL011_CR_UARTEN ) &&
203
- (PL011_REGS (dev )-> cr & PL011_CR_RXE ) &&
204
- ((PL011_REGS (dev )-> fr & PL011_FR_RXFE ) == 0U )) {
205
- return true;
206
- }
204
+ if (!DEV_DATA (dev )-> sbsa &&
205
+ (!(PL011_REGS (dev )-> cr & PL011_CR_UARTEN ) ||
206
+ !(PL011_REGS (dev )-> cr & PL011_CR_RXE )))
207
+ return false;
207
208
208
- return false ;
209
+ return ( PL011_REGS ( dev ) -> fr & PL011_FR_RXFE ) == 0U ;
209
210
}
210
211
211
212
static int pl011_poll_in (const struct device * dev , unsigned char * c )
@@ -276,8 +277,10 @@ static int pl011_irq_tx_complete(const struct device *dev)
276
277
277
278
static int pl011_irq_tx_ready (const struct device * dev )
278
279
{
279
- return ((PL011_REGS (dev )-> cr & PL011_CR_TXE ) &&
280
- (PL011_REGS (dev )-> imsc & PL011_IMSC_TXIM ) &&
280
+ if (!DEV_DATA (dev )-> sbsa && !(PL011_REGS (dev )-> cr & PL011_CR_TXE ))
281
+ return false;
282
+
283
+ return ((PL011_REGS (dev )-> imsc & PL011_IMSC_TXIM ) &&
281
284
pl011_irq_tx_complete (dev ));
282
285
}
283
286
@@ -295,8 +298,10 @@ static void pl011_irq_rx_disable(const struct device *dev)
295
298
296
299
static int pl011_irq_rx_ready (const struct device * dev )
297
300
{
298
- return ((PL011_REGS (dev )-> cr & PL011_CR_RXE ) &&
299
- (PL011_REGS (dev )-> imsc & PL011_IMSC_RXIM ) &&
301
+ if (!DEV_DATA (dev )-> sbsa && !(PL011_REGS (dev )-> cr & PL011_CR_RXE ))
302
+ return false;
303
+
304
+ return ((PL011_REGS (dev )-> imsc & PL011_IMSC_RXIM ) &&
300
305
(!(PL011_REGS (dev )-> fr & PL011_FR_RXFE )));
301
306
}
302
307
@@ -356,40 +361,48 @@ static int pl011_init(const struct device *dev)
356
361
int ret ;
357
362
uint32_t lcrh ;
358
363
359
- /* disable the uart */
360
- pl011_disable (dev );
361
- pl011_disable_fifo (dev );
362
-
363
- /* Set baud rate */
364
- ret = pl011_set_baudrate (dev , DEV_CFG (dev )-> sys_clk_freq ,
365
- DEV_DATA (dev )-> baud_rate );
366
- if (ret != 0 ) {
367
- return ret ;
364
+ /*
365
+ * If working in SBSA mode, we assume that UART is already configured,
366
+ * or does not require configuration at all (if UART is emulated by
367
+ * virtualization software).
368
+ */
369
+ if (!DEV_DATA (dev )-> sbsa ) {
370
+ /* disable the uart */
371
+ pl011_disable (dev );
372
+ pl011_disable_fifo (dev );
373
+
374
+ /* Set baud rate */
375
+ ret = pl011_set_baudrate (dev , DEV_CFG (dev )-> sys_clk_freq ,
376
+ DEV_DATA (dev )-> baud_rate );
377
+ if (ret != 0 ) {
378
+ return ret ;
379
+ }
380
+
381
+ /* Setting the default character format */
382
+ lcrh = PL011_REGS (dev )-> lcr_h & ~(PL011_LCRH_FORMAT_MASK );
383
+ lcrh &= ~(BIT (0 ) | BIT (7 ));
384
+ lcrh |= PL011_LCRH_WLEN_SIZE (8 ) << PL011_LCRH_WLEN_SHIFT ;
385
+ PL011_REGS (dev )-> lcr_h = lcrh ;
386
+
387
+ /* Enabling the FIFOs */
388
+ pl011_enable_fifo (dev );
368
389
}
369
-
370
- /* Setting the default character format */
371
- lcrh = PL011_REGS (dev )-> lcr_h & ~(PL011_LCRH_FORMAT_MASK );
372
- lcrh &= ~(BIT (0 ) | BIT (7 ));
373
- lcrh |= PL011_LCRH_WLEN_SIZE (8 ) << PL011_LCRH_WLEN_SHIFT ;
374
- PL011_REGS (dev )-> lcr_h = lcrh ;
375
-
376
- /* Enabling the FIFOs */
377
- pl011_enable_fifo (dev );
378
-
379
390
/* initialize all IRQs as masked */
380
391
PL011_REGS (dev )-> imsc = 0U ;
381
392
PL011_REGS (dev )-> icr = PL011_IMSC_MASK_ALL ;
382
393
383
- PL011_REGS (dev )-> dmacr = 0U ;
384
- __ISB ();
385
- PL011_REGS (dev )-> cr &= ~(BIT (14 ) | BIT (15 ) | BIT (1 ));
386
- PL011_REGS (dev )-> cr |= PL011_CR_RXE | PL011_CR_TXE ;
387
- __ISB ();
388
-
394
+ if (!DEV_DATA (dev )-> sbsa ) {
395
+ PL011_REGS (dev )-> dmacr = 0U ;
396
+ __ISB ();
397
+ PL011_REGS (dev )-> cr &= ~(BIT (14 ) | BIT (15 ) | BIT (1 ));
398
+ PL011_REGS (dev )-> cr |= PL011_CR_RXE | PL011_CR_TXE ;
399
+ __ISB ();
400
+ }
389
401
#ifdef CONFIG_UART_INTERRUPT_DRIVEN
390
402
DEV_CFG (dev )-> irq_config_func (dev );
391
403
#endif
392
- pl011_enable (dev );
404
+ if (!DEV_DATA (dev )-> sbsa )
405
+ pl011_enable (dev );
393
406
394
407
return 0 ;
395
408
}
@@ -532,3 +545,45 @@ static void pl011_irq_config_func_1(const struct device *dev)
532
545
#endif
533
546
534
547
#endif /* CONFIG_UART_PL011_PORT1 */
548
+
549
+ #ifdef CONFIG_UART_PL011_SBSA
550
+
551
+ #undef DT_DRV_COMPAT
552
+ #define DT_DRV_COMPAT SBSA_COMPAT
553
+
554
+ #ifdef CONFIG_UART_INTERRUPT_DRIVEN
555
+ static void pl011_irq_config_func_sbsa (const struct device * dev );
556
+ #endif
557
+
558
+ static struct uart_device_config pl011_cfg_sbsa = {
559
+ .base = (uint8_t * )DT_INST_REG_ADDR (0 ),
560
+ #ifdef CONFIG_UART_INTERRUPT_DRIVEN
561
+ .irq_config_func = pl011_irq_config_func_sbsa ,
562
+ #endif
563
+ };
564
+
565
+ static struct pl011_data pl011_data_sbsa = {
566
+ .sbsa = true,
567
+ };
568
+
569
+ DEVICE_DT_INST_DEFINE (0 ,
570
+ & pl011_init ,
571
+ device_pm_control_nop ,
572
+ & pl011_data_sbsa ,
573
+ & pl011_cfg_sbsa , PRE_KERNEL_1 ,
574
+ CONFIG_KERNEL_INIT_PRIORITY_DEVICE ,
575
+ & pl011_driver_api );
576
+
577
+ #ifdef CONFIG_UART_INTERRUPT_DRIVEN
578
+ static void pl011_irq_config_func_sbsa (const struct device * dev )
579
+ {
580
+ IRQ_CONNECT (DT_INST_IRQN (0 ),
581
+ DT_INST_IRQ (0 , priority ),
582
+ pl011_isr ,
583
+ DEVICE_GET (pl011_sbsa ),
584
+ 0 );
585
+ irq_enable (DT_INST_IRQN (0 ));
586
+ }
587
+ #endif
588
+
589
+ #endif /* CONFIG_UART_PL011_SBSA */
0 commit comments