1 /* This file is part of the coreboot project. */
2 /* SPDX-License-Identifier: GPL-2.0-only */
5 #include <boot/coreboot_tables.h>
6 #include <console/uart.h>
8 #include <soc/qcom_qup_se.h>
9 #include <soc/qupv3_config.h>
12 /* COMMON STATUS/CONFIGURATION REGISTERS AND MASKS */
14 #define GENI_STATUS_M_GENI_CMD_ACTIVE_MASK 0x1
15 #define GENI_STATUS_S_GENI_CMD_ACTIVE_MASK 0x1000
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
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
38 void uart_tx_flush(int idx
)
40 struct qup_regs
*regs
= qup
[idx
].regs
;
42 while (read32(®s
->geni_status
) &
43 GENI_STATUS_M_GENI_CMD_ACTIVE_MASK
)
47 void uart_init(int idx
)
49 struct qup_regs
*regs
= qup
[idx
].regs
;
50 unsigned int reg_value
;
51 unsigned int div
, baud_rate
, uart_freq
;
54 * If the RX (secondary) sequencer is already active, it means the core
55 * has been already initialized in the previous stage. Skip
58 if (read32(®s
->geni_status
) & GENI_STATUS_S_GENI_CMD_ACTIVE_MASK
)
61 qupv3_se_fw_load_and_init(idx
, SE_PROTOCOL_UART
, FIFO
);
62 clock_enable_qup(idx
);
64 reg_value
= read32(®s
->geni_fw_revision_ro
);
65 reg_value
&= GENI_FW_REVISION_RO_PROTOCOL_MASK
;
66 reg_value
>>= GENI_FW_REVISION_RO_PROTOCOL_SHIFT
;
68 assert(reg_value
== SE_PROTOCOL_UART
);
70 baud_rate
= get_uart_baudrate();
72 /* sc7180 requires 16 clock pulses to sample 1 bit of data */
73 uart_freq
= baud_rate
* 16;
75 div
= DIV_ROUND_CLOSEST(QUPV3_UART_SRC_HZ
, uart_freq
);
76 write32(®s
->geni_ser_m_clk_cfg
, (div
<< 4) | 1);
77 write32(®s
->geni_ser_s_clk_cfg
, (div
<< 4) | 1);
79 /* GPIO Configuration */
80 gpio_configure(qup
[idx
].pin
[2], qup
[idx
].func
[2], GPIO_PULL_UP
,
81 GPIO_2MA
, GPIO_OUTPUT
);
82 gpio_configure(qup
[idx
].pin
[3], qup
[idx
].func
[3], GPIO_PULL_UP
,
83 GPIO_2MA
, GPIO_INPUT
);
85 write32(®s
->geni_tx_watermark_reg
, UART_TX_WATERMARK_MARGIN
);
86 write32(®s
->geni_rx_watermark_reg
, FIFO_DEPTH
87 - UART_RX_WATERMARK_MARGIN
);
88 write32(®s
->geni_rx_rfr_watermark_reg
,
89 FIFO_DEPTH
- UART_RX_RFR_WATERMARK_MARGIN
);
91 write32(®s
->uart_tx_word_len
, UART_TX_BITS_PER_WORD
);
92 write32(®s
->uart_rx_word_len
, UART_RX_BITS_PER_WORD
);
94 /* Disable TX parity calculation */
95 write32(®s
->uart_tx_parity_cfg
, 0x0);
96 /* Ignore CTS line status for TX communication */
97 write32(®s
->uart_tx_trans_cfg_reg
, 0x2);
98 /* Disable RX parity calculation */
99 write32(®s
->uart_rx_parity_cfg
, 0x0);
100 /* Disable parity, framing and break check on received word */
101 write32(®s
->uart_rx_trans_cfg
, 0x0);
102 /* Set UART TX stop bit len to one UART bit length */
103 write32(®s
->uart_tx_stop_bit_len
, 0x0);
104 write32(®s
->uart_rx_stale_cnt
, 0x16 * 10);
106 write32(®s
->geni_tx_packing_cfg0
, UART_TX_PACK_VECTOR0
|
107 (UART_TX_PACK_VECTOR1
<< 10));
108 write32(®s
->geni_tx_packing_cfg1
, UART_TX_PACK_VECTOR2
|
109 (UART_TX_PACK_VECTOR3
<< 10));
110 write32(®s
->geni_rx_packing_cfg0
, UART_RX_PACK_VECTOR0
);
111 write32(®s
->geni_rx_packing_cfg1
, UART_RX_PACK_VECTOR2
);
114 write32(®s
->geni_s_cmd0
, START_UART_RX
);
117 unsigned char uart_rx_byte(int idx
)
119 struct qup_regs
*regs
= qup
[idx
].regs
;
121 if (read32(®s
->geni_rx_fifo_status
) & RX_FIFO_WC_MSK
)
122 return read32(®s
->geni_rx_fifon
) & 0xFF;
126 void uart_tx_byte(int idx
, unsigned char data
)
128 struct qup_regs
*regs
= qup
[idx
].regs
;
132 write32(®s
->uart_tx_trans_len
, 1);
134 write32(®s
->geni_m_cmd0
, START_UART_TX
);
135 write32(®s
->geni_tx_fifon
, data
);
138 uintptr_t uart_platform_base(int idx
)
140 return (uintptr_t)qup
[idx
].regs
;
143 void uart_fill_lb(void *data
)
145 struct lb_serial serial
= {0};
147 serial
.type
= LB_SERIAL_TYPE_MEMORY_MAPPED
;
148 serial
.baseaddr
= (uint32_t)uart_platform_base(CONFIG_UART_FOR_CONSOLE
);
149 serial
.baud
= get_uart_baudrate();
151 serial
.input_hertz
= QUPV3_UART_SRC_HZ
;
153 lb_add_serial(&serial
, data
);