xref: /aosp_15_r20/external/coreboot/src/soc/qualcomm/common/qupv3_uart.c (revision b9411a12aaaa7e1e6a6fb7c5e057f44ee179a49c)
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>
8 #include <soc/qup_se_handlers_common.h>
9 #include <soc/qupv3_config_common.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 
uart_tx_flush(unsigned int idx)38 void uart_tx_flush(unsigned int idx)
39 {
40 	struct qup_regs *regs = qup[idx].regs;
41 
42 	while (read32(&regs->geni_status) &
43 	       GENI_STATUS_M_GENI_CMD_ACTIVE_MASK)
44 		;
45 }
46 
uart_init(unsigned int idx)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 
61 	qupv3_se_fw_load_and_init(idx, SE_PROTOCOL_UART, FIFO);
62 	clock_enable_qup(idx);
63 
64 	reg_value = read32(&regs->geni_fw_revision_ro);
65 	reg_value &= GENI_FW_REVISION_RO_PROTOCOL_MASK;
66 	reg_value >>= GENI_FW_REVISION_RO_PROTOCOL_SHIFT;
67 
68 	assert(reg_value == SE_PROTOCOL_UART);
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,
81 				GPIO_2MA, GPIO_OUTPUT);
82 	gpio_configure(qup[idx].pin[3], qup[idx].func[3], GPIO_PULL_UP,
83 				GPIO_2MA, GPIO_INPUT);
84 
85 	write32(&regs->geni_tx_watermark_reg, UART_TX_WATERMARK_MARGIN);
86 	write32(&regs->geni_rx_watermark_reg, FIFO_DEPTH
87 					- UART_RX_WATERMARK_MARGIN);
88 	write32(&regs->geni_rx_rfr_watermark_reg,
89 			FIFO_DEPTH - UART_RX_RFR_WATERMARK_MARGIN);
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 
uart_rx_byte(unsigned int idx)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 
uart_tx_byte(unsigned int idx,unsigned char data)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 
uart_platform_base(unsigned int idx)138 uintptr_t uart_platform_base(unsigned int idx)
139 {
140 	return (uintptr_t)qup[idx].regs;
141 }
142 
fill_lb_serial(struct lb_serial * serial)143 enum cb_err fill_lb_serial(struct lb_serial *serial)
144 {
145 	serial->type = LB_SERIAL_TYPE_MEMORY_MAPPED;
146 	serial->baseaddr = (uint32_t)uart_platform_base(CONFIG_UART_FOR_CONSOLE);
147 	serial->baud = get_uart_baudrate();
148 	serial->regwidth = 4;
149 	serial->input_hertz = SRC_XO_HZ;
150 
151 	return CB_SUCCESS;
152 }
153