• 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/gsbi.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 	void *uart_gsbi_base;
19 	unsigned int uart_gsbi;
20 	uart_clk_mnd_t mnd_value;
21 	gpio_func_data_t dbg_uart_gpio[NO_OF_DBG_UART_GPIOS];
22 } uart_params_t;
23 
24 /*
25  * All constants lifted from u-boot's
26  * board/qcom/ipq806x_cdp/ipq806x_board_param.h
27  */
28 static const uart_params_t uart_board_param = {
29 	.uart_dm_base = (void *)UART4_DM_BASE,
30 	.uart_gsbi_base = (void *)UART_GSBI4_BASE,
31 	.uart_gsbi = GSBI_4,
32 	.mnd_value = { 12, 625, 313 },
33 		.dbg_uart_gpio = {
34 			{
35 				.gpio = 10,
36 				.func = 1,
37 				.dir = GPIO_OUTPUT,
38 				.pull = GPIO_NO_PULL,
39 				.drvstr = GPIO_12MA,
40 				.enable = GPIO_DISABLE
41 			},
42 			{
43 				.gpio = 11,
44 				.func = 1,
45 				.dir = GPIO_INPUT,
46 				.pull = GPIO_NO_PULL,
47 				.drvstr = GPIO_12MA,
48 				.enable = GPIO_DISABLE
49 			},
50 		}
51 };
52 
53 /**
54  * msm_boot_uart_dm_init_rx_transfer - Init Rx transfer
55  * @param uart_dm_base: UART controller base address
56  */
msm_boot_uart_dm_init_rx_transfer(void * uart_dm_base)57 static unsigned int msm_boot_uart_dm_init_rx_transfer(void *uart_dm_base)
58 {
59 	/* Reset receiver */
60 	write32(MSM_BOOT_UART_DM_CR(uart_dm_base),
61 		MSM_BOOT_UART_DM_CMD_RESET_RX);
62 
63 	/* Enable receiver */
64 	write32(MSM_BOOT_UART_DM_CR(uart_dm_base),
65 		MSM_BOOT_UART_DM_CR_RX_ENABLE);
66 	write32(MSM_BOOT_UART_DM_DMRX(uart_dm_base),
67 		MSM_BOOT_UART_DM_DMRX_DEF_VALUE);
68 
69 	/* Clear stale event */
70 	write32(MSM_BOOT_UART_DM_CR(uart_dm_base),
71 		MSM_BOOT_UART_DM_CMD_RES_STALE_INT);
72 
73 	/* Enable stale event */
74 	write32(MSM_BOOT_UART_DM_CR(uart_dm_base),
75 		MSM_BOOT_UART_DM_GCMD_ENA_STALE_EVT);
76 
77 	return MSM_BOOT_UART_DM_E_SUCCESS;
78 }
79 
80 static unsigned int msm_boot_uart_dm_init(void  *uart_dm_base);
81 
82 /* Received data is valid or not */
83 static int valid_data = 0;
84 
85 /* Received data */
86 static unsigned int word = 0;
87 
88 /**
89  * msm_boot_uart_dm_read - reads a word from the RX FIFO.
90  * @data: location where the read data is stored
91  * @count: no of valid data in the FIFO
92  * @wait: indicates blocking call or not blocking call
93  *
94  * Reads a word from the RX FIFO. If no data is available blocks if
95  * @wait is true, else returns %MSM_BOOT_UART_DM_E_RX_NOT_READY.
96  */
97  #if 0 /* Not used yet */
98 static unsigned int
99 msm_boot_uart_dm_read(unsigned int *data, int *count, int wait)
100 {
101 	static int total_rx_data = 0;
102 	static int rx_data_read = 0;
103 	void *base;
104 	uint32_t status_reg;
105 
106 	base = uart_board_param.uart_dm_base;
107 
108 	if (data == NULL)
109 		return MSM_BOOT_UART_DM_E_INVAL;
110 
111 	status_reg = readl(MSM_BOOT_UART_DM_MISR(base));
112 
113 	/* Check for DM_RXSTALE for RX transfer to finish */
114 	while (!(status_reg & MSM_BOOT_UART_DM_RXSTALE)) {
115 		status_reg = readl(MSM_BOOT_UART_DM_MISR(base));
116 		if (!wait)
117 			return MSM_BOOT_UART_DM_E_RX_NOT_READY;
118 	}
119 
120 	/* Check for Overrun error. We'll just reset Error Status */
121 	if (readl(MSM_BOOT_UART_DM_SR(base)) &
122 			MSM_BOOT_UART_DM_SR_UART_OVERRUN) {
123 		writel(MSM_BOOT_UART_DM_CMD_RESET_ERR_STAT,
124 			MSM_BOOT_UART_DM_CR(base));
125 		total_rx_data = rx_data_read = 0;
126 		msm_boot_uart_dm_init(base);
127 		return MSM_BOOT_UART_DM_E_RX_NOT_READY;
128 	}
129 
130 	/* Read UART_DM_RX_TOTAL_SNAP for actual number of bytes received */
131 	if (total_rx_data == 0)
132 		total_rx_data =  readl(MSM_BOOT_UART_DM_RX_TOTAL_SNAP(base));
133 
134 	/* Data available in FIFO; read a word. */
135 	*data = readl(MSM_BOOT_UART_DM_RF(base, 0));
136 
137 	/* WAR for http://prism/CR/548280 */
138 	if (*data == 0) {
139 		return MSM_BOOT_UART_DM_E_RX_NOT_READY;
140 	}
141 
142 	/* increment the total count of chars we've read so far */
143 	rx_data_read += FIFO_DATA_SIZE;
144 
145 	/* actual count of valid data in word */
146 	*count = ((total_rx_data < rx_data_read) ?
147 			(FIFO_DATA_SIZE - (rx_data_read - total_rx_data)) :
148 			FIFO_DATA_SIZE);
149 
150 	/* If there are still data left in FIFO we'll read them before
151 	 * initializing RX Transfer again
152 	 */
153 	if (rx_data_read < total_rx_data)
154 		return MSM_BOOT_UART_DM_E_SUCCESS;
155 
156 	msm_boot_uart_dm_init_rx_transfer(base);
157 	total_rx_data = rx_data_read = 0;
158 
159 	return MSM_BOOT_UART_DM_E_SUCCESS;
160 }
161 #endif
162 
uart_tx_byte(unsigned int idx,unsigned char data)163 void uart_tx_byte(unsigned int idx, unsigned char data)
164 {
165 	int num_of_chars = 1;
166 	unsigned int tx_data = 0;
167 	void *base = uart_board_param.uart_dm_base;
168 
169 	/* Wait until transmit FIFO is empty. */
170 	while (!(read32(MSM_BOOT_UART_DM_SR(base)) &
171 		 MSM_BOOT_UART_DM_SR_TXEMT))
172 		udelay(1);
173 	/*
174 	 * TX FIFO is ready to accept new character(s). First write number of
175 	 * characters to be transmitted.
176 	 */
177 	write32(MSM_BOOT_UART_DM_NO_CHARS_FOR_TX(base), num_of_chars);
178 
179 	/* And now write the character(s) */
180 	write32(MSM_BOOT_UART_DM_TF(base, 0), tx_data);
181 }
182 
183 /*
184  * msm_boot_uart_dm_reset - resets UART controller
185  * @base: UART controller base address
186  */
msm_boot_uart_dm_reset(void * base)187 static unsigned int msm_boot_uart_dm_reset(void *base)
188 {
189 	write32(MSM_BOOT_UART_DM_CR(base), MSM_BOOT_UART_DM_CMD_RESET_RX);
190 	write32(MSM_BOOT_UART_DM_CR(base), MSM_BOOT_UART_DM_CMD_RESET_TX);
191 	write32(MSM_BOOT_UART_DM_CR(base),
192 		MSM_BOOT_UART_DM_CMD_RESET_ERR_STAT);
193 	write32(MSM_BOOT_UART_DM_CR(base), MSM_BOOT_UART_DM_CMD_RES_TX_ERR);
194 	write32(MSM_BOOT_UART_DM_CR(base), MSM_BOOT_UART_DM_CMD_RES_STALE_INT);
195 
196 	return MSM_BOOT_UART_DM_E_SUCCESS;
197 }
198 
199 /*
200  * msm_boot_uart_dm_init - initilaizes UART controller
201  * @uart_dm_base: UART controller base address
202  */
msm_boot_uart_dm_init(void * uart_dm_base)203 static unsigned int msm_boot_uart_dm_init(void  *uart_dm_base)
204 {
205 	/* Configure UART mode registers MR1 and MR2 */
206 	/* Hardware flow control isn't supported */
207 	write32(MSM_BOOT_UART_DM_MR1(uart_dm_base), 0x0);
208 
209 	/* 8-N-1 configuration: 8 data bits - No parity - 1 stop bit */
210 	write32(MSM_BOOT_UART_DM_MR2(uart_dm_base),
211 		MSM_BOOT_UART_DM_8_N_1_MODE);
212 
213 	/* Configure Interrupt Mask register IMR */
214 	write32(MSM_BOOT_UART_DM_IMR(uart_dm_base),
215 		MSM_BOOT_UART_DM_IMR_ENABLED);
216 
217 	/*
218 	 * Configure Tx and Rx watermarks configuration registers
219 	 * TX watermark value is set to 0 - interrupt is generated when
220 	 * FIFO level is less than or equal to 0
221 	 */
222 	write32(MSM_BOOT_UART_DM_TFWR(uart_dm_base),
223 		MSM_BOOT_UART_DM_TFW_VALUE);
224 
225 	/* RX watermark value */
226 	write32(MSM_BOOT_UART_DM_RFWR(uart_dm_base),
227 		MSM_BOOT_UART_DM_RFW_VALUE);
228 
229 	/* Configure Interrupt Programming Register */
230 	/* Set initial Stale timeout value */
231 	write32(MSM_BOOT_UART_DM_IPR(uart_dm_base),
232 		MSM_BOOT_UART_DM_STALE_TIMEOUT_LSB);
233 
234 	/* Configure IRDA if required */
235 	/* Disabling IRDA mode */
236 	write32(MSM_BOOT_UART_DM_IRDA(uart_dm_base), 0x0);
237 
238 	/* Configure hunt character value in HCR register */
239 	/* Keep it in reset state */
240 	write32(MSM_BOOT_UART_DM_HCR(uart_dm_base), 0x0);
241 
242 	/*
243 	 * Configure Rx FIFO base address
244 	 * Both TX/RX shares same SRAM and default is half-n-half.
245 	 * Sticking with default value now.
246 	 * As such RAM size is (2^RAM_ADDR_WIDTH, 32-bit entries).
247 	 * We have found RAM_ADDR_WIDTH = 0x7f
248 	 */
249 
250 	/* Issue soft reset command */
251 	msm_boot_uart_dm_reset(uart_dm_base);
252 
253 	/* Enable/Disable Rx/Tx DM interfaces */
254 	/* Data Mover not currently utilized. */
255 	write32(MSM_BOOT_UART_DM_DMEN(uart_dm_base), 0x0);
256 
257 	/* Enable transmitter */
258 	write32(MSM_BOOT_UART_DM_CR(uart_dm_base),
259 		MSM_BOOT_UART_DM_CR_TX_ENABLE);
260 
261 	/* Initialize Receive Path */
262 	msm_boot_uart_dm_init_rx_transfer(uart_dm_base);
263 
264 	return 0;
265 }
266 
267 /**
268  * ipq806x_uart_init - initializes UART
269  *
270  * Initializes clocks, GPIO and UART controller.
271  */
uart_init(unsigned int idx)272 void uart_init(unsigned int idx)
273 {
274 	/* Note int idx isn't used in this driver. */
275 	void *dm_base;
276 	void *gsbi_base;
277 
278 	dm_base = uart_board_param.uart_dm_base;
279 
280 	if (read32(MSM_BOOT_UART_DM_CSR(dm_base)) == UART_DM_CLK_RX_TX_BIT_RATE)
281 		return; /* UART must have been already initialized. */
282 
283 	gsbi_base = uart_board_param.uart_gsbi_base;
284 	ipq_configure_gpio(uart_board_param.dbg_uart_gpio,
285 			   NO_OF_DBG_UART_GPIOS);
286 
287 	/* Configure the uart clock */
288 	uart_clock_config(uart_board_param.uart_gsbi,
289 		uart_board_param.mnd_value.m_value,
290 		uart_board_param.mnd_value.n_value,
291 		uart_board_param.mnd_value.d_value,
292 		0);
293 
294 	write32(GSBI_CTRL_REG(gsbi_base),
295 		GSBI_PROTOCOL_CODE_I2C_UART << GSBI_CTRL_REG_PROTOCOL_CODE_S);
296 	write32(MSM_BOOT_UART_DM_CSR(dm_base), UART_DM_CLK_RX_TX_BIT_RATE);
297 
298 	/* Initialize UART_DM */
299 	msm_boot_uart_dm_init(dm_base);
300 }
301 
302 /* for the benefit of non-console uart init */
ipq806x_uart_init(void)303 void ipq806x_uart_init(void)
304 {
305 	uart_init(0);
306 }
307 
308 #if 0 /* Not used yet */
309 uint32_t uartmem_getbaseaddr(void)
310 {
311 	return (uint32_t)uart_board_param.uart_dm_base;
312 }
313 #endif
314 
315 /**
316  * uart_tx_flush - transmits a string of data
317  * @s: string to transmit
318  */
uart_tx_flush(unsigned int idx)319 void uart_tx_flush(unsigned int idx)
320 {
321 	void *base = uart_board_param.uart_dm_base;
322 
323 	while (!(read32(MSM_BOOT_UART_DM_SR(base)) &
324 		 MSM_BOOT_UART_DM_SR_TXEMT))
325 		;
326 }
327 
328 /**
329  * uart_can_rx_byte - checks if data available for reading
330  *
331  * Returns 1 if data available, 0 otherwise
332  */
333  #if 0 /* Not used yet */
334 int uart_can_rx_byte(void)
335 {
336 	/* Return if data is already read */
337 	if (valid_data)
338 		return 1;
339 
340 	/* Read data from the FIFO */
341 	if (msm_boot_uart_dm_read(&word, &valid_data, 0) !=
342 	    MSM_BOOT_UART_DM_E_SUCCESS)
343 		return 0;
344 
345 	return 1;
346 }
347 #endif
348 
349 /**
350  * ipq806x_serial_getc - reads a character
351  *
352  * Returns the character read from serial port.
353  */
uart_rx_byte(unsigned int idx)354 uint8_t uart_rx_byte(unsigned int idx)
355 {
356 	uint8_t byte;
357 
358 #if 0 /* Not used yet */
359 	while (!uart_can_rx_byte()) {
360 		/* wait for incoming data */
361 	}
362 #endif
363 	byte = (uint8_t)(word & 0xff);
364 	word = word >> 8;
365 	valid_data--;
366 
367 	return byte;
368 }
369 
370 /* TODO: Implement function */
fill_lb_serial(struct lb_serial * serial)371 enum cb_err fill_lb_serial(struct lb_serial *serial)
372 {
373 	return CB_ERR;
374 }
375