coreboot
coreboot is an Open Source project aimed at replacing the proprietary BIOS found in most computers.
uart.c File Reference
#include <device/mmio.h>
#include <console/uart.h>
#include <delay.h>
#include <endian.h>
#include <stdint.h>
#include <soc/clock.h>
#include <soc/uart.h>
#include <assert.h>
#include <soc/addressmap.h>
#include <drivers/uart/pl011.h>
Include dependency graph for uart.c:

Go to the source code of this file.

Data Structures

union  cn81xx_uart_ctl
 
struct  cn81xx_uart
 

Macros

#define UART_IBRD_BAUD_DIVINT_SHIFT   0
 
#define UART_IBRD_BAUD_DIVINT_MASK   0xffff
 
#define UART_FBRD_BAUD_DIVFRAC_SHIFT   0
 
#define UART_FBRD_BAUD_DIVFRAC_MASK   0x3f
 
#define UART_SCLK_DIV   3
 

Functions

 check_member (cn81xx_uart, uctl_ctl, 0x1000)
 
 check_member (cn81xx_uart, uctl_spare1, 0x10f8)
 
static size_t uart_sclk_divisor (const size_t reg)
 Returns the current UART HCLK divider. More...
 
static size_t uart_hclk (struct cn81xx_uart *uart)
 Returns the current UART HCLK. More...
 
unsigned int uart_platform_refclk (void)
 
uintptr_t uart_platform_base (unsigned int idx)
 
static void uart_wait_hclk (struct cn81xx_uart *uart, const size_t hclks)
 Waits given count if HCLK cycles. More...
 
int uart_is_enabled (const size_t bus)
 Returns the UART state. More...
 
int uart_setup (const size_t bus, int baudrate)
 Setup UART with desired BAUD rate in 8N1, no parity mode. More...
 

Macro Definition Documentation

◆ UART_FBRD_BAUD_DIVFRAC_MASK

#define UART_FBRD_BAUD_DIVFRAC_MASK   0x3f

Definition at line 48 of file uart.c.

◆ UART_FBRD_BAUD_DIVFRAC_SHIFT

#define UART_FBRD_BAUD_DIVFRAC_SHIFT   0

Definition at line 47 of file uart.c.

◆ UART_IBRD_BAUD_DIVINT_MASK

#define UART_IBRD_BAUD_DIVINT_MASK   0xffff

Definition at line 45 of file uart.c.

◆ UART_IBRD_BAUD_DIVINT_SHIFT

#define UART_IBRD_BAUD_DIVINT_SHIFT   0

Definition at line 44 of file uart.c.

◆ UART_SCLK_DIV

#define UART_SCLK_DIV   3

Definition at line 53 of file uart.c.

Function Documentation

◆ check_member() [1/2]

check_member ( cn81xx_uart  ,
uctl_ctl  ,
0x1000   
)

◆ check_member() [2/2]

check_member ( cn81xx_uart  ,
uctl_spare1  ,
0x10f8   
)

◆ uart_hclk()

static size_t uart_hclk ( struct cn81xx_uart uart)
static

Returns the current UART HCLK.

Parameters
uartThe UART to operate on
Returns
The HCLK in Hz

Definition at line 76 of file uart.c.

References cn81xx_uart_ctl::h_clkdiv_sel, read64(), cn81xx_uart_ctl::s, thunderx_get_io_clock(), cn81xx_uart_ctl::u, uart_sclk_divisor(), and cn81xx_uart::uctl_ctl.

Referenced by uart_platform_refclk(), and uart_wait_hclk().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ uart_is_enabled()

int uart_is_enabled ( const size_t  bus)

Returns the UART state.

Parameters
busThe UART to operate on
Returns
Boolean: True if UART is enabled

Definition at line 120 of file uart.c.

References assert, cn81xx_uart_ctl::csclk_en, read64(), cn81xx_uart_ctl::s, cn81xx_uart_ctl::u, UAAx_PF_BAR0, and cn81xx_uart::uctl_ctl.

Referenced by bootblock_mainboard_early_init(), and dt_platform_fixup().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ uart_platform_base()

uintptr_t uart_platform_base ( unsigned int  idx)

Definition at line 96 of file uart.c.

◆ uart_platform_refclk()

unsigned int uart_platform_refclk ( void  )

Definition at line 85 of file uart.c.

References uart_hclk().

Referenced by uart_fill_lb(), and uart_init().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ uart_sclk_divisor()

static size_t uart_sclk_divisor ( const size_t  reg)
static

Returns the current UART HCLK divider.

Parameters
regThe H_CLKDIV_SEL value
Returns
The HCLK divider

Definition at line 61 of file uart.c.

References ARRAY_SIZE, and assert.

Referenced by uart_hclk(), and uart_setup().

Here is the caller graph for this function:

◆ uart_setup()

int uart_setup ( const size_t  bus,
int  baudrate 
)

Setup UART with desired BAUD rate in 8N1, no parity mode.

Parameters
busThe UART to operate on
baudratebaudrate to set up
Returns
Boolean: True on error
  1. Assert all resets: a. UAA reset: UCTL_CTL[UAA_RST] = 1 b. UCTL reset: UCTL_CTL[UCTL_RST] = 1
  2. Configure the HCLK: a. Reset the clock dividers: UCTL_CTL[H_CLKDIV_RST] = 1. b. Select the HCLK frequency i. UCTL_CTL[H_CLKDIV] = desired value, ii. UCTL_CTL[H_CLKDIV_EN] = 1 to enable the HCLK. iii. Readback UCTL_CTL to ensure the values take effect. c. Deassert the HCLK clock divider reset: UCTL_CTL[H_CLKDIV_RST] = 0.
  3. Wait 20 HCLK cycles from step 3 for HCLK to start and async fifo to properly reset.
  4. Deassert UCTL and UAHC resets: a. UCTL_CTL[UCTL_RST] = 0 b. Wait 10 HCLK cycles. c. UCTL_CTL[UAHC_RST] = 0 d. You will have to wait 10 HCLK cycles before accessing any HCLK-only registers.
  5. Enable conditional SCLK of UCTL by writing UCTL_CTL[CSCLK_EN] = 1.

Exit here if the UART is not going to be used in coreboot. The previous initialization steps are sufficient to make the Linux kernel not panic.

  1. Initialize the integer and fractional baud rate divider registers UARTIBRD and UARTFBRD as follows: a. Baud Rate Divisor = UARTCLK/(16xBaud Rate) = BRDI + BRDF b. The fractional register BRDF, m is calculated as integer(BRDF x 64 + 0.5) Example calculation: If the required baud rate is 230400 and hclk = 4MHz then: Baud Rate Divisor = (4x10^6)/(16x230400) = 1.085 This means BRDI = 1 and BRDF = 0.085. Therefore, fractional part, BRDF = integer((0.085x64)+0.5) = 5 Generated baud rate divider = 1+5/64 = 1.078
  2. Program the line control register UAA(0..1)_LCR_H and the control register UAA(0..1)_CR

Definition at line 141 of file uart.c.

References assert, pl011_uart::cr, cn81xx_uart_ctl::csclk_en, pl011_uart::fbrd, cn81xx_uart_ctl::h_clk_byp_sel, cn81xx_uart_ctl::h_clk_en, cn81xx_uart_ctl::h_clkdiv_rst, cn81xx_uart_ctl::h_clkdiv_sel, pl011_uart::ibrd, pl011_uart::lcr_h, cn81xx_uart::pl011, PL011_UARTCR_RXE, PL011_UARTCR_TXE, PL011_UARTCR_UARTEN, PL011_UARTLCR_H_FEN, PL011_UARTLCR_H_WLEN_8, read64(), cn81xx_uart_ctl::s, thunderx_get_io_clock(), cn81xx_uart_ctl::u, cn81xx_uart_ctl::uaa_rst, UAAx_PF_BAR0, UART_FBRD_BAUD_DIVFRAC_MASK, UART_SCLK_DIV, uart_sclk_divisor(), uart_wait_hclk(), cn81xx_uart::uctl_ctl, cn81xx_uart_ctl::uctl_rst, write32(), and write64().

Referenced by bootblock_mainboard_early_init().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ uart_wait_hclk()

static void uart_wait_hclk ( struct cn81xx_uart uart,
const size_t  hclks 
)
static

Waits given count if HCLK cycles.

Parameters
uartThe UART to operate on
hclksThe number of HCLK cycles to wait

Definition at line 107 of file uart.c.

References delay(), MAX, uart_hclk(), and udelay().

Referenced by uart_setup().

Here is the call graph for this function:
Here is the caller graph for this function: