blob: 97f9e76520aa8591e3fe75535d2c72a6724e1beb [file] [log] [blame]
Patrick Georgi16849bb2020-05-10 17:52:40 +02001/* Source : APQ8064 LK boot */
Patrick Georgi70517072020-05-10 18:47:05 +02002/* SPDX-License-Identifier: BSD-3-Clause */
Prudhvi Yarlagadda37e957f2019-03-22 15:26:02 +05303
4#include <device/mmio.h>
5#include <boot/coreboot_tables.h>
Prudhvi Yarlagadda37e957f2019-03-22 15:26:02 +05306#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/uart.h>
12#include <soc/cdp.h>
13#include <stdint.h>
Prudhvi Yarlagadda37e957f2019-03-22 15:26:02 +053014#include <soc/iomap.h>
15
16#define FIFO_DATA_SIZE 4
17
18typedef struct {
19 void *uart_dm_base;
20 unsigned int blsp_uart;
21 gpio_func_data_t dbg_uart_gpio[NO_OF_DBG_UART_GPIOS];
22} uart_params_t;
23
24void ipq_configure_gpio(const gpio_func_data_t *gpio, unsigned int count)
25{
26 int i;
27
28 for (i = 0; i < count; i++) {
29 gpio_configure(gpio->gpio, gpio->func,
30 gpio->pull, gpio->drvstr, gpio->enable);
31 gpio++;
32 }
33}
34
35static const uart_params_t uart_board_param = {
36 .uart_dm_base = UART2_DM_BASE,
37 .blsp_uart = BLSP1_UART2,
38 .dbg_uart_gpio = {
39 {
40 .gpio = GPIO(17),
41 .func = 1,
42 .dir = GPIO_OUTPUT,
43 .pull = GPIO_PULL_UP,
44 .enable = GPIO_OUTPUT
45 },
46 {
47 .gpio = GPIO(18),
48 .func = 1,
49 .dir = GPIO_INPUT,
50 .pull = GPIO_NO_PULL,
51 .enable = GPIO_INPUT
52 },
53 },
54};
55
56/**
57 * @brief msm_boot_uart_dm_init_rx_transfer - Init Rx transfer
58 * @param uart_dm_base: UART controller base address
59 */
60static unsigned int msm_boot_uart_dm_init_rx_transfer(void *uart_dm_base)
61{
62 /* Reset receiver */
63 write32(MSM_BOOT_UART_DM_CR(uart_dm_base),
64 MSM_BOOT_UART_DM_CMD_RESET_RX);
65
66 /* Enable receiver */
67 write32(MSM_BOOT_UART_DM_CR(uart_dm_base),
68 MSM_BOOT_UART_DM_CR_RX_ENABLE);
69 write32(MSM_BOOT_UART_DM_DMRX(uart_dm_base),
70 MSM_BOOT_UART_DM_DMRX_DEF_VALUE);
71
72 /* Clear stale event */
73 write32(MSM_BOOT_UART_DM_CR(uart_dm_base),
74 MSM_BOOT_UART_DM_CMD_RES_STALE_INT);
75
76 /* Enable stale event */
77 write32(MSM_BOOT_UART_DM_CR(uart_dm_base),
78 MSM_BOOT_UART_DM_GCMD_ENA_STALE_EVT);
79
80 return MSM_BOOT_UART_DM_E_SUCCESS;
81}
82
83#if CONFIG(DRIVERS_UART)
84static unsigned int msm_boot_uart_dm_init(void *uart_dm_base);
85
86/* Received data is valid or not */
87static int valid_data = 0;
88
89/* Received data */
90static unsigned int word = 0;
91
Felix Helde3a12472020-09-11 15:47:09 +020092void uart_tx_byte(unsigned int idx, unsigned char data)
Prudhvi Yarlagadda37e957f2019-03-22 15:26:02 +053093{
94 int num_of_chars = 1;
95 void *base = uart_board_param.uart_dm_base;
96
97 /* Wait until transmit FIFO is empty. */
98 while (!(read32(MSM_BOOT_UART_DM_SR(base)) &
99 MSM_BOOT_UART_DM_SR_TXEMT))
100 udelay(1);
101 /*
102 * TX FIFO is ready to accept new character(s). First write number of
103 * characters to be transmitted.
104 */
105 write32(MSM_BOOT_UART_DM_NO_CHARS_FOR_TX(base), num_of_chars);
106
107 /* And now write the character(s) */
108 write32(MSM_BOOT_UART_DM_TF(base, 0), data);
109}
110#endif /* CONFIG_SERIAL_UART */
111
112/**
113 * @brief msm_boot_uart_dm_reset - resets UART controller
114 * @param base: UART controller base address
115 */
116static unsigned int msm_boot_uart_dm_reset(void *base)
117{
118 write32(MSM_BOOT_UART_DM_CR(base), MSM_BOOT_UART_DM_CMD_RESET_RX);
119 write32(MSM_BOOT_UART_DM_CR(base), MSM_BOOT_UART_DM_CMD_RESET_TX);
120 write32(MSM_BOOT_UART_DM_CR(base),
121 MSM_BOOT_UART_DM_CMD_RESET_ERR_STAT);
122 write32(MSM_BOOT_UART_DM_CR(base), MSM_BOOT_UART_DM_CMD_RES_TX_ERR);
123 write32(MSM_BOOT_UART_DM_CR(base), MSM_BOOT_UART_DM_CMD_RES_STALE_INT);
124
125 return MSM_BOOT_UART_DM_E_SUCCESS;
126}
127
128/**
129 * @brief msm_boot_uart_dm_init - initilaizes UART controller
130 * @param uart_dm_base: UART controller base address
131 */
132unsigned int msm_boot_uart_dm_init(void *uart_dm_base)
133{
134 /* Configure UART mode registers MR1 and MR2 */
135 /* Hardware flow control isn't supported */
136 write32(MSM_BOOT_UART_DM_MR1(uart_dm_base), 0x0);
137
138 /* 8-N-1 configuration: 8 data bits - No parity - 1 stop bit */
139 write32(MSM_BOOT_UART_DM_MR2(uart_dm_base),
140 MSM_BOOT_UART_DM_8_N_1_MODE);
141
142 /* Configure Interrupt Mask register IMR */
143 write32(MSM_BOOT_UART_DM_IMR(uart_dm_base),
144 MSM_BOOT_UART_DM_IMR_ENABLED);
145
146 /*
147 * Configure Tx and Rx watermarks configuration registers
148 * TX watermark value is set to 0 - interrupt is generated when
149 * FIFO level is less than or equal to 0
150 */
151 write32(MSM_BOOT_UART_DM_TFWR(uart_dm_base),
152 MSM_BOOT_UART_DM_TFW_VALUE);
153
154 /* RX watermark value */
155 write32(MSM_BOOT_UART_DM_RFWR(uart_dm_base),
156 MSM_BOOT_UART_DM_RFW_VALUE);
157
158 /* Configure Interrupt Programming Register */
159 /* Set initial Stale timeout value */
160 write32(MSM_BOOT_UART_DM_IPR(uart_dm_base),
161 MSM_BOOT_UART_DM_STALE_TIMEOUT_LSB);
162
163 /* Configure IRDA if required */
164 /* Disabling IRDA mode */
165 write32(MSM_BOOT_UART_DM_IRDA(uart_dm_base), 0x0);
166
167 /* Configure hunt character value in HCR register */
168 /* Keep it in reset state */
169 write32(MSM_BOOT_UART_DM_HCR(uart_dm_base), 0x0);
170
171 /*
172 * Configure Rx FIFO base address
173 * Both TX/RX shares same SRAM and default is half-n-half.
174 * Sticking with default value now.
175 * As such RAM size is (2^RAM_ADDR_WIDTH, 32-bit entries).
176 * We have found RAM_ADDR_WIDTH = 0x7f
177 */
178
179 /* Issue soft reset command */
180 msm_boot_uart_dm_reset(uart_dm_base);
181
182 /* Enable/Disable Rx/Tx DM interfaces */
183 /* Data Mover not currently utilized. */
184 write32(MSM_BOOT_UART_DM_DMEN(uart_dm_base), 0x0);
185
186 /* Enable transmitter */
187 write32(MSM_BOOT_UART_DM_CR(uart_dm_base),
188 MSM_BOOT_UART_DM_CR_TX_ENABLE);
189
190 /* Initialize Receive Path */
191 msm_boot_uart_dm_init_rx_transfer(uart_dm_base);
192
193 return 0;
194}
195
196/**
197 * @brief qcs405_uart_init - initializes UART
198 *
199 * Initializes clocks, GPIO and UART controller.
200 */
Felix Helde3a12472020-09-11 15:47:09 +0200201void uart_init(unsigned int idx)
Prudhvi Yarlagadda37e957f2019-03-22 15:26:02 +0530202{
203 /* Note int idx isn't used in this driver. */
204 void *dm_base;
205
206 dm_base = uart_board_param.uart_dm_base;
207
208 if (read32(MSM_BOOT_UART_DM_CSR(dm_base)) == 0xFF)
209 return; /* UART must have been already initialized. */
210
211 clock_configure_uart(1843200);
212 clock_enable_uart();
213
214 ipq_configure_gpio(uart_board_param.dbg_uart_gpio,
215 NO_OF_DBG_UART_GPIOS);
216
217 write32(MSM_BOOT_UART_DM_CSR(dm_base), 0xFF);
218
219 /* Initialize UART_DM */
220 msm_boot_uart_dm_init(dm_base);
221}
222
223/* for the benefit of non-console uart init */
224void qcs405_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 */
Felix Helde3a12472020-09-11 15:47:09 +0200233void uart_tx_flush(unsigned int idx)
Prudhvi Yarlagadda37e957f2019-03-22 15:26:02 +0530234{
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#if CONFIG(DRIVERS_UART)
243/**
244 * qcs405_serial_getc - reads a character
245 *
246 * Returns the character read from serial port.
247 */
Felix Helde3a12472020-09-11 15:47:09 +0200248uint8_t uart_rx_byte(unsigned int idx)
Prudhvi Yarlagadda37e957f2019-03-22 15:26:02 +0530249{
250 uint8_t byte;
251
252 byte = (uint8_t)(word & 0xff);
253 word = word >> 8;
254 valid_data--;
255
256 return byte;
257}
258#endif
259
Prudhvi Yarlagadda37e957f2019-03-22 15:26:02 +0530260void uart_fill_lb(void *data)
261{
262 struct lb_serial serial;
263
264 serial.type = LB_SERIAL_TYPE_MEMORY_MAPPED;
265 serial.baseaddr = (uint64_t)UART2_DM_BASE;
266 serial.baud = get_uart_baudrate();
267 serial.regwidth = 1;
Jacob Garber78398272019-07-24 11:12:09 -0600268 serial.input_hertz = uart_platform_refclk();
269 serial.uart_pci_addr = CONFIG_UART_PCI_ADDR;
Prudhvi Yarlagadda37e957f2019-03-22 15:26:02 +0530270 lb_add_serial(&serial, data);
Jacob Garber78398272019-07-24 11:12:09 -0600271
Prudhvi Yarlagadda37e957f2019-03-22 15:26:02 +0530272 lb_add_console(LB_TAG_CONSOLE_SERIAL8250MEM, data);
273}