• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* Source : APQ8064 LK boot */
2 /* SPDX-License-Identifier: BSD-3-Clause */
3 
4 #include <device/mmio.h>
5 #include <boot/coreboot_tables.h>
6 #include <console/uart.h>
7 #include <delay.h>
8 #include <gpio.h>
9 #include <soc/clock.h>
10 #include <soc/blsp.h>
11 #include <soc/ipq_uart.h>
12 #include <stdint.h>
13 
14 #define FIFO_DATA_SIZE	4
15 
16 typedef struct {
17 	void *uart_dm_base;
18 	uart_clk_mnd_t mnd_value;
19 	unsigned int blsp_uart;
20 	gpio_func_data_t dbg_uart_gpio[NO_OF_DBG_UART_GPIOS];
21 } uart_params_t;
22 
23 static const uart_params_t uart_board_param = {
24 	.uart_dm_base = UART1_DM_BASE,
25 	.mnd_value = { 24, 625, 313 },
26 	.blsp_uart = BLSP1_UART1,
27 	.dbg_uart_gpio = {
28 		{
29 #if CONFIG(IPQ_QFN_PART)
30 			.gpio = 60,
31 			.func = 2,
32 #else	/* bga */
33 			.gpio = 16,
34 			.func = 1,
35 #endif
36 			.dir = GPIO_INPUT,
37 			.pull = GPIO_NO_PULL,
38 			.enable = GPIO_ENABLE
39 		},
40 		{
41 #if CONFIG(IPQ_QFN_PART)
42 			.gpio = 61,
43 			.func = 2,
44 #else	/* bga */
45 			.gpio = 17,
46 			.func = 1,
47 #endif
48 			.dir = GPIO_OUTPUT,
49 			.pull = GPIO_NO_PULL,
50 			.enable = GPIO_ENABLE
51 		},
52 	},
53 };
54 
55 /**
56  * @brief msm_boot_uart_dm_init_rx_transfer - Init Rx transfer
57  * @param uart_dm_base: UART controller base address
58  */
msm_boot_uart_dm_init_rx_transfer(void * uart_dm_base)59 static unsigned int msm_boot_uart_dm_init_rx_transfer(void *uart_dm_base)
60 {
61 	/* Reset receiver */
62 	write32(MSM_BOOT_UART_DM_CR(uart_dm_base),
63 		MSM_BOOT_UART_DM_CMD_RESET_RX);
64 
65 	/* Enable receiver */
66 	write32(MSM_BOOT_UART_DM_CR(uart_dm_base),
67 		MSM_BOOT_UART_DM_CR_RX_ENABLE);
68 	write32(MSM_BOOT_UART_DM_DMRX(uart_dm_base),
69 		MSM_BOOT_UART_DM_DMRX_DEF_VALUE);
70 
71 	/* Clear stale event */
72 	write32(MSM_BOOT_UART_DM_CR(uart_dm_base),
73 		MSM_BOOT_UART_DM_CMD_RES_STALE_INT);
74 
75 	/* Enable stale event */
76 	write32(MSM_BOOT_UART_DM_CR(uart_dm_base),
77 		MSM_BOOT_UART_DM_GCMD_ENA_STALE_EVT);
78 
79 	return MSM_BOOT_UART_DM_E_SUCCESS;
80 }
81 
82 static unsigned int msm_boot_uart_dm_init(void  *uart_dm_base);
83 
84 /* Received data is valid or not */
85 static int valid_data = 0;
86 
87 /* Received data */
88 static unsigned int word = 0;
89 
uart_tx_byte(unsigned int idx,unsigned char data)90 void uart_tx_byte(unsigned int idx, unsigned char data)
91 {
92 	int num_of_chars = 1;
93 	void *base = uart_board_param.uart_dm_base;
94 
95 	/* Wait until transmit FIFO is empty. */
96 	while (!(read32(MSM_BOOT_UART_DM_SR(base)) &
97 		 MSM_BOOT_UART_DM_SR_TXEMT))
98 		udelay(1);
99 	/*
100 	 * TX FIFO is ready to accept new character(s). First write number of
101 	 * characters to be transmitted.
102 	 */
103 	write32(MSM_BOOT_UART_DM_NO_CHARS_FOR_TX(base), num_of_chars);
104 
105 	/* And now write the character(s) */
106 	write32(MSM_BOOT_UART_DM_TF(base, 0), data);
107 }
108 
109 /**
110  * @brief msm_boot_uart_dm_reset - resets UART controller
111  * @param base: UART controller base address
112  */
msm_boot_uart_dm_reset(void * base)113 static unsigned int msm_boot_uart_dm_reset(void *base)
114 {
115 	write32(MSM_BOOT_UART_DM_CR(base), MSM_BOOT_UART_DM_CMD_RESET_RX);
116 	write32(MSM_BOOT_UART_DM_CR(base), MSM_BOOT_UART_DM_CMD_RESET_TX);
117 	write32(MSM_BOOT_UART_DM_CR(base),
118 		MSM_BOOT_UART_DM_CMD_RESET_ERR_STAT);
119 	write32(MSM_BOOT_UART_DM_CR(base), MSM_BOOT_UART_DM_CMD_RES_TX_ERR);
120 	write32(MSM_BOOT_UART_DM_CR(base), MSM_BOOT_UART_DM_CMD_RES_STALE_INT);
121 
122 	return MSM_BOOT_UART_DM_E_SUCCESS;
123 }
124 
125 /**
126  * @brief msm_boot_uart_dm_init - initilaizes UART controller
127  * @param uart_dm_base: UART controller base address
128  */
msm_boot_uart_dm_init(void * uart_dm_base)129 unsigned int msm_boot_uart_dm_init(void  *uart_dm_base)
130 {
131 	/* Configure UART mode registers MR1 and MR2 */
132 	/* Hardware flow control isn't supported */
133 	write32(MSM_BOOT_UART_DM_MR1(uart_dm_base), 0x0);
134 
135 	/* 8-N-1 configuration: 8 data bits - No parity - 1 stop bit */
136 	write32(MSM_BOOT_UART_DM_MR2(uart_dm_base),
137 		MSM_BOOT_UART_DM_8_N_1_MODE);
138 
139 	/* Configure Interrupt Mask register IMR */
140 	write32(MSM_BOOT_UART_DM_IMR(uart_dm_base),
141 		MSM_BOOT_UART_DM_IMR_ENABLED);
142 
143 	/*
144 	 * Configure Tx and Rx watermarks configuration registers
145 	 * TX watermark value is set to 0 - interrupt is generated when
146 	 * FIFO level is less than or equal to 0
147 	 */
148 	write32(MSM_BOOT_UART_DM_TFWR(uart_dm_base),
149 		MSM_BOOT_UART_DM_TFW_VALUE);
150 
151 	/* RX watermark value */
152 	write32(MSM_BOOT_UART_DM_RFWR(uart_dm_base),
153 		MSM_BOOT_UART_DM_RFW_VALUE);
154 
155 	/* Configure Interrupt Programming Register */
156 	/* Set initial Stale timeout value */
157 	write32(MSM_BOOT_UART_DM_IPR(uart_dm_base),
158 		MSM_BOOT_UART_DM_STALE_TIMEOUT_LSB);
159 
160 	/* Configure IRDA if required */
161 	/* Disabling IRDA mode */
162 	write32(MSM_BOOT_UART_DM_IRDA(uart_dm_base), 0x0);
163 
164 	/* Configure hunt character value in HCR register */
165 	/* Keep it in reset state */
166 	write32(MSM_BOOT_UART_DM_HCR(uart_dm_base), 0x0);
167 
168 	/*
169 	 * Configure Rx FIFO base address
170 	 * Both TX/RX shares same SRAM and default is half-n-half.
171 	 * Sticking with default value now.
172 	 * As such RAM size is (2^RAM_ADDR_WIDTH, 32-bit entries).
173 	 * We have found RAM_ADDR_WIDTH = 0x7f
174 	 */
175 
176 	/* Issue soft reset command */
177 	msm_boot_uart_dm_reset(uart_dm_base);
178 
179 	/* Enable/Disable Rx/Tx DM interfaces */
180 	/* Data Mover not currently utilized. */
181 	write32(MSM_BOOT_UART_DM_DMEN(uart_dm_base), 0x0);
182 
183 	/* Enable transmitter */
184 	write32(MSM_BOOT_UART_DM_CR(uart_dm_base),
185 		MSM_BOOT_UART_DM_CR_TX_ENABLE);
186 
187 	/* Initialize Receive Path */
188 	msm_boot_uart_dm_init_rx_transfer(uart_dm_base);
189 
190 	return 0;
191 }
192 
193 /**
194  * @brief ipq40xx_uart_init - initializes UART
195  *
196  * Initializes clocks, GPIO and UART controller.
197  */
uart_init(unsigned int idx)198 void uart_init(unsigned int idx)
199 {
200 	/* Note int idx isn't used in this driver. */
201 	void *dm_base;
202 
203 	dm_base = uart_board_param.uart_dm_base;
204 
205 	if (read32(MSM_BOOT_UART_DM_CSR(dm_base)) == UART_DM_CLK_RX_TX_BIT_RATE)
206 		return; /* UART must have been already initialized. */
207 
208 	ipq_configure_gpio(uart_board_param.dbg_uart_gpio,
209 			   NO_OF_DBG_UART_GPIOS);
210 
211 	/* Configure the uart clock */
212 	uart_clock_config(uart_board_param.blsp_uart,
213 		uart_board_param.mnd_value.m_value,
214 		uart_board_param.mnd_value.n_value,
215 		uart_board_param.mnd_value.d_value);
216 
217 	write32(MSM_BOOT_UART_DM_CSR(dm_base), UART_DM_CLK_RX_TX_BIT_RATE);
218 
219 	/* Initialize UART_DM */
220 	msm_boot_uart_dm_init(dm_base);
221 }
222 
223 /* for the benefit of non-console uart init */
ipq40xx_uart_init(void)224 void ipq40xx_uart_init(void)
225 {
226 	uart_init(0);
227 }
228 
229 /**
230  * @brief uart_tx_flush - transmits a string of data
231  * @param idx: string to transmit
232  */
uart_tx_flush(unsigned int idx)233 void uart_tx_flush(unsigned int idx)
234 {
235 	void *base = uart_board_param.uart_dm_base;
236 
237 	while (!(read32(MSM_BOOT_UART_DM_SR(base)) &
238 		 MSM_BOOT_UART_DM_SR_TXEMT))
239 		;
240 }
241 
242 /**
243  * ipq40xx_serial_getc - reads a character
244  *
245  * Returns the character read from serial port.
246  */
uart_rx_byte(unsigned int idx)247 uint8_t uart_rx_byte(unsigned int idx)
248 {
249 	uint8_t byte;
250 
251 	byte = (uint8_t)(word & 0xff);
252 	word = word >> 8;
253 	valid_data--;
254 
255 	return byte;
256 }
257 
258 /* TODO: Implement function */
fill_lb_serial(struct lb_serial * serial)259 enum cb_err fill_lb_serial(struct lb_serial *serial)
260 {
261 	serial->type = LB_SERIAL_TYPE_MEMORY_MAPPED;
262 	serial->baseaddr = (uint32_t)UART1_DM_BASE;
263 	serial->baud = get_uart_baudrate();
264 	serial->regwidth = 1;
265 	serial->input_hertz = uart_platform_refclk();
266 
267 	return CB_SUCCESS;
268 }
269