coreboot
coreboot is an Open Source project aimed at replacing the proprietary BIOS found in most computers.
qupv3_uart.c
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 
3 #include <assert.h>
4 #include <boot/coreboot_tables.h>
5 #include <console/uart.h>
6 #include <soc/clock.h>
7 #include <soc/qcom_qup_se.h>
10 #include <types.h>
11 
12 /* COMMON STATUS/CONFIGURATION REGISTERS AND MASKS */
13 
14 #define GENI_STATUS_M_GENI_CMD_ACTIVE_MASK 0x1
15 #define GENI_STATUS_S_GENI_CMD_ACTIVE_MASK 0x1000
16 
17 #define UART_TX_WATERMARK_MARGIN 4 /* Represented in words */
18 #define UART_RX_WATERMARK_MARGIN 8 /* Represented in words */
19 #define UART_RX_RFR_WATERMARK_MARGIN 4 /* Represented in words */
20 #define UART_TX_BITS_PER_WORD 8
21 #define UART_RX_BITS_PER_WORD 8
22 #define START_UART_TX 0x8000000
23 #define START_UART_RX 0x8000000
24 
25 /* UART FIFO Packing Configuration. */
26 /* Start_idx:0, direction:0, len:7, stop:0 */
27 #define UART_TX_PACK_VECTOR0 0x0E
28 /* Start_idx:8, direction:0, len:7, stop:0 */
29 #define UART_TX_PACK_VECTOR1 0x10E
30 /* Start_idx:16, direction:0, len:7, stop:0 */
31 #define UART_TX_PACK_VECTOR2 0x20E
32 /* Start_idx:24, direction:0, len:7, stop:1 */
33 #define UART_TX_PACK_VECTOR3 0x30F
34 /* Start_idx:0, direction:0, len:7, stop:1 */
35 #define UART_RX_PACK_VECTOR0 0xF
36 #define UART_RX_PACK_VECTOR2 0x00
37 
38 void uart_tx_flush(unsigned int idx)
39 {
40  struct qup_regs *regs = qup[idx].regs;
41 
42  while (read32(&regs->geni_status) &
44  ;
45 }
46 
47 void uart_init(unsigned int idx)
48 {
49  struct qup_regs *regs = qup[idx].regs;
50  unsigned int reg_value;
51  unsigned int div, baud_rate, uart_freq;
52 
53  /*
54  * If the RX (secondary) sequencer is already active, it means the core
55  * has been already initialized in the previous stage. Skip
56  * configuration
57  */
58  if (read32(&regs->geni_status) & GENI_STATUS_S_GENI_CMD_ACTIVE_MASK)
59  return;
60 
62  clock_enable_qup(idx);
63 
64  reg_value = read32(&regs->geni_fw_revision_ro);
67 
69 
70  baud_rate = get_uart_baudrate();
71 
72  /*requires 16 clock pulses to sample 1 bit of data */
73  uart_freq = baud_rate * 16;
74 
75  div = DIV_ROUND_CLOSEST(SRC_XO_HZ, uart_freq);
76  write32(&regs->geni_ser_m_clk_cfg, (div << 4) | 1);
77  write32(&regs->geni_ser_s_clk_cfg, (div << 4) | 1);
78 
79  /* GPIO Configuration */
80  gpio_configure(qup[idx].pin[2], qup[idx].func[2], GPIO_PULL_UP,
82  gpio_configure(qup[idx].pin[3], qup[idx].func[3], GPIO_PULL_UP,
84 
85  write32(&regs->geni_tx_watermark_reg, UART_TX_WATERMARK_MARGIN);
86  write32(&regs->geni_rx_watermark_reg, FIFO_DEPTH
88  write32(&regs->geni_rx_rfr_watermark_reg,
90 
91  write32(&regs->uart_tx_word_len, UART_TX_BITS_PER_WORD);
92  write32(&regs->uart_rx_word_len, UART_RX_BITS_PER_WORD);
93 
94  /* Disable TX parity calculation */
95  write32(&regs->uart_tx_parity_cfg, 0x0);
96  /* Ignore CTS line status for TX communication */
97  write32(&regs->uart_tx_trans_cfg_reg, 0x2);
98  /* Disable RX parity calculation */
99  write32(&regs->uart_rx_parity_cfg, 0x0);
100  /* Disable parity, framing and break check on received word */
101  write32(&regs->uart_rx_trans_cfg, 0x0);
102  /* Set UART TX stop bit len to one UART bit length */
103  write32(&regs->uart_tx_stop_bit_len, 0x0);
104  write32(&regs->uart_rx_stale_cnt, 0x16 * 10);
105 
106  write32(&regs->geni_tx_packing_cfg0, UART_TX_PACK_VECTOR0 |
107  (UART_TX_PACK_VECTOR1 << 10));
108  write32(&regs->geni_tx_packing_cfg1, UART_TX_PACK_VECTOR2 |
109  (UART_TX_PACK_VECTOR3 << 10));
110  write32(&regs->geni_rx_packing_cfg0, UART_RX_PACK_VECTOR0);
111  write32(&regs->geni_rx_packing_cfg1, UART_RX_PACK_VECTOR2);
112 
113  /* Start RX */
114  write32(&regs->geni_s_cmd0, START_UART_RX);
115 }
116 
117 unsigned char uart_rx_byte(unsigned int idx)
118 {
119  struct qup_regs *regs = qup[idx].regs;
120 
121  if (read32(&regs->geni_rx_fifo_status) & RX_FIFO_WC_MSK)
122  return read32(&regs->geni_rx_fifon) & 0xFF;
123  return 0;
124 }
125 
126 void uart_tx_byte(unsigned int idx, unsigned char data)
127 {
128  struct qup_regs *regs = qup[idx].regs;
129 
130  uart_tx_flush(idx);
131 
132  write32(&regs->uart_tx_trans_len, 1);
133  /* Start TX */
134  write32(&regs->geni_m_cmd0, START_UART_TX);
135  write32(&regs->geni_tx_fifon, data);
136 }
137 
138 uintptr_t uart_platform_base(unsigned int idx)
139 {
140  return (uintptr_t)qup[idx].regs;
141 }
142 
143 void uart_fill_lb(void *data)
144 {
145  struct lb_serial serial = {0};
146 
148  serial.baseaddr = (uint32_t)uart_platform_base(CONFIG_UART_FOR_CONSOLE);
149  serial.baud = get_uart_baudrate();
150  serial.regwidth = 4;
151  serial.input_hertz = SRC_XO_HZ;
152 
153  lb_add_serial(&serial, data);
154 }
#define GPIO_OUTPUT
Definition: gpio_ftns.h:23
#define GPIO_INPUT
Definition: gpio_ftns.h:24
static void write32(void *addr, uint32_t val)
Definition: mmio.h:40
static uint32_t read32(const void *addr)
Definition: mmio.h:22
#define assert(statement)
Definition: assert.h:74
unsigned int get_uart_baudrate(void)
Definition: bmcinfo.c:167
#define LB_SERIAL_TYPE_MEMORY_MAPPED
void lb_add_serial(struct lb_serial *serial, void *data)
#define DIV_ROUND_CLOSEST(x, divisor)
Definition: helpers.h:17
unsigned int serial
Definition: edid.c:52
@ GPIO_2MA
Definition: gpio_common.h:70
#define GENI_FW_REVISION_RO_PROTOCOL_MASK
#define RX_FIFO_WC_MSK
#define GENI_FW_REVISION_RO_PROTOCOL_SHIFT
#define FIFO_DEPTH
@ SE_PROTOCOL_UART
void qupv3_se_fw_load_and_init(unsigned int bus, unsigned int protocol, unsigned int mode)
Definition: qupv3_config.c:13
#define UART_RX_RFR_WATERMARK_MARGIN
Definition: qupv3_uart.c:19
#define GENI_STATUS_S_GENI_CMD_ACTIVE_MASK
Definition: qupv3_uart.c:15
#define UART_TX_PACK_VECTOR3
Definition: qupv3_uart.c:33
#define UART_RX_PACK_VECTOR0
Definition: qupv3_uart.c:35
void uart_init(unsigned int idx)
Definition: qupv3_uart.c:47
#define START_UART_RX
Definition: qupv3_uart.c:23
#define GENI_STATUS_M_GENI_CMD_ACTIVE_MASK
Definition: qupv3_uart.c:14
#define UART_TX_BITS_PER_WORD
Definition: qupv3_uart.c:20
void uart_tx_flush(unsigned int idx)
Definition: qupv3_uart.c:38
#define UART_TX_PACK_VECTOR2
Definition: qupv3_uart.c:31
#define UART_RX_BITS_PER_WORD
Definition: qupv3_uart.c:21
uintptr_t uart_platform_base(unsigned int idx)
Definition: qupv3_uart.c:138
#define UART_TX_PACK_VECTOR1
Definition: qupv3_uart.c:29
#define UART_RX_WATERMARK_MARGIN
Definition: qupv3_uart.c:18
unsigned char uart_rx_byte(unsigned int idx)
Definition: qupv3_uart.c:117
#define START_UART_TX
Definition: qupv3_uart.c:22
#define UART_TX_WATERMARK_MARGIN
Definition: qupv3_uart.c:17
void uart_fill_lb(void *data)
Definition: qupv3_uart.c:143
#define UART_RX_PACK_VECTOR2
Definition: qupv3_uart.c:36
void uart_tx_byte(unsigned int idx, unsigned char data)
Definition: qupv3_uart.c:126
#define UART_TX_PACK_VECTOR0
Definition: qupv3_uart.c:27
void gpio_configure(gpio_t gpio, uint32_t func, uint32_t pull, uint32_t drive_str, uint32_t enable)
Definition: gpio.c:7
#define GPIO_PULL_UP
Definition: gpio.h:24
void clock_enable_qup(int qup)
Definition: clock.c:132
#define SRC_XO_HZ
Definition: clock.h:10
unsigned int uint32_t
Definition: stdint.h:14
unsigned long uintptr_t
Definition: stdint.h:21
struct qup_regs * regs
Definition: qcom_qup_se.h:29