55 */
66
77#define DT_DRV_COMPAT arm_pl011
8+ #define SBSA_COMPAT arm_sbsa_uart
89
910#include <kernel.h>
1011#include <arch/cpu.h>
@@ -41,6 +42,7 @@ struct pl011_regs {
4142/* Device data structure */
4243struct pl011_data {
4344 uint32_t baud_rate ; /* Baud rate */
45+ bool sbsa ; /* SBSA mode */
4446#ifdef CONFIG_UART_INTERRUPT_DRIVEN
4547 uart_irq_callback_user_data_t irq_cb ;
4648 void * irq_cb_data ;
@@ -199,13 +201,12 @@ static int pl011_set_baudrate(const struct device *dev,
199201
200202static bool pl011_is_readable (const struct device * dev )
201203{
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;
207208
208- return false ;
209+ return ( PL011_REGS ( dev ) -> fr & PL011_FR_RXFE ) == 0U ;
209210}
210211
211212static 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)
276277
277278static int pl011_irq_tx_ready (const struct device * dev )
278279{
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 ) &&
281284 pl011_irq_tx_complete (dev ));
282285}
283286
@@ -295,8 +298,10 @@ static void pl011_irq_rx_disable(const struct device *dev)
295298
296299static int pl011_irq_rx_ready (const struct device * dev )
297300{
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 ) &&
300305 (!(PL011_REGS (dev )-> fr & PL011_FR_RXFE )));
301306}
302307
@@ -356,40 +361,48 @@ static int pl011_init(const struct device *dev)
356361 int ret ;
357362 uint32_t lcrh ;
358363
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 );
368389 }
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-
379390 /* initialize all IRQs as masked */
380391 PL011_REGS (dev )-> imsc = 0U ;
381392 PL011_REGS (dev )-> icr = PL011_IMSC_MASK_ALL ;
382393
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+ }
389401#ifdef CONFIG_UART_INTERRUPT_DRIVEN
390402 DEV_CFG (dev )-> irq_config_func (dev );
391403#endif
392- pl011_enable (dev );
404+ if (!DEV_DATA (dev )-> sbsa )
405+ pl011_enable (dev );
393406
394407 return 0 ;
395408}
@@ -532,3 +545,45 @@ static void pl011_irq_config_func_1(const struct device *dev)
532545#endif
533546
534547#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