mb/google/brya/var/uldrenite: Generate RAM ID and SPD file
[coreboot.git] / src / soc / qualcomm / qcs405 / uart.c
blob16c71b4205c7148dd5310f629f689a3fc55e825c
1 /* Source : APQ8064 LK boot */
2 /* SPDX-License-Identifier: BSD-3-Clause */
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/uart.h>
12 #include <soc/cdp.h>
13 #include <stdint.h>
14 #include <soc/iomap.h>
16 #define FIFO_DATA_SIZE 4
18 typedef 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;
24 void ipq_configure_gpio(const gpio_func_data_t *gpio, unsigned int count)
26 int i;
28 for (i = 0; i < count; i++) {
29 gpio_configure(gpio->gpio, gpio->func,
30 gpio->pull, gpio->drvstr, gpio->enable);
31 gpio++;
35 static const uart_params_t uart_board_param = {
36 .uart_dm_base = UART2_DM_BASE,
37 .blsp_uart = BLSP1_UART2,
38 .dbg_uart_gpio = {
40 .gpio = GPIO(17),
41 .func = 1,
42 .dir = GPIO_OUTPUT,
43 .pull = GPIO_PULL_UP,
44 .enable = GPIO_OUTPUT
47 .gpio = GPIO(18),
48 .func = 1,
49 .dir = GPIO_INPUT,
50 .pull = GPIO_NO_PULL,
51 .enable = GPIO_INPUT
56 /**
57 * @brief msm_boot_uart_dm_init_rx_transfer - Init Rx transfer
58 * @param uart_dm_base: UART controller base address
60 static unsigned int msm_boot_uart_dm_init_rx_transfer(void *uart_dm_base)
62 /* Reset receiver */
63 write32(MSM_BOOT_UART_DM_CR(uart_dm_base),
64 MSM_BOOT_UART_DM_CMD_RESET_RX);
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);
72 /* Clear stale event */
73 write32(MSM_BOOT_UART_DM_CR(uart_dm_base),
74 MSM_BOOT_UART_DM_CMD_RES_STALE_INT);
76 /* Enable stale event */
77 write32(MSM_BOOT_UART_DM_CR(uart_dm_base),
78 MSM_BOOT_UART_DM_GCMD_ENA_STALE_EVT);
80 return MSM_BOOT_UART_DM_E_SUCCESS;
83 #if CONFIG(DRIVERS_UART)
84 static unsigned int msm_boot_uart_dm_init(void *uart_dm_base);
86 /* Received data is valid or not */
87 static int valid_data = 0;
89 /* Received data */
90 static unsigned int word = 0;
92 void uart_tx_byte(unsigned int idx, unsigned char data)
94 int num_of_chars = 1;
95 void *base = uart_board_param.uart_dm_base;
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);
102 * TX FIFO is ready to accept new character(s). First write number of
103 * characters to be transmitted.
105 write32(MSM_BOOT_UART_DM_NO_CHARS_FOR_TX(base), num_of_chars);
107 /* And now write the character(s) */
108 write32(MSM_BOOT_UART_DM_TF(base, 0), data);
110 #endif /* CONFIG_SERIAL_UART */
113 * @brief msm_boot_uart_dm_reset - resets UART controller
114 * @param base: UART controller base address
116 static unsigned int msm_boot_uart_dm_reset(void *base)
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);
125 return MSM_BOOT_UART_DM_E_SUCCESS;
129 * @brief msm_boot_uart_dm_init - initilaizes UART controller
130 * @param uart_dm_base: UART controller base address
132 unsigned int msm_boot_uart_dm_init(void *uart_dm_base)
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);
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);
142 /* Configure Interrupt Mask register IMR */
143 write32(MSM_BOOT_UART_DM_IMR(uart_dm_base),
144 MSM_BOOT_UART_DM_IMR_ENABLED);
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
151 write32(MSM_BOOT_UART_DM_TFWR(uart_dm_base),
152 MSM_BOOT_UART_DM_TFW_VALUE);
154 /* RX watermark value */
155 write32(MSM_BOOT_UART_DM_RFWR(uart_dm_base),
156 MSM_BOOT_UART_DM_RFW_VALUE);
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);
163 /* Configure IRDA if required */
164 /* Disabling IRDA mode */
165 write32(MSM_BOOT_UART_DM_IRDA(uart_dm_base), 0x0);
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);
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
179 /* Issue soft reset command */
180 msm_boot_uart_dm_reset(uart_dm_base);
182 /* Enable/Disable Rx/Tx DM interfaces */
183 /* Data Mover not currently utilized. */
184 write32(MSM_BOOT_UART_DM_DMEN(uart_dm_base), 0x0);
186 /* Enable transmitter */
187 write32(MSM_BOOT_UART_DM_CR(uart_dm_base),
188 MSM_BOOT_UART_DM_CR_TX_ENABLE);
190 /* Initialize Receive Path */
191 msm_boot_uart_dm_init_rx_transfer(uart_dm_base);
193 return 0;
197 * @brief qcs405_uart_init - initializes UART
199 * Initializes clocks, GPIO and UART controller.
201 void uart_init(unsigned int idx)
203 /* Note int idx isn't used in this driver. */
204 void *dm_base;
206 dm_base = uart_board_param.uart_dm_base;
208 if (read32(MSM_BOOT_UART_DM_CSR(dm_base)) == 0xFF)
209 return; /* UART must have been already initialized. */
211 clock_configure_uart(1843200);
212 clock_enable_uart();
214 ipq_configure_gpio(uart_board_param.dbg_uart_gpio,
215 NO_OF_DBG_UART_GPIOS);
217 write32(MSM_BOOT_UART_DM_CSR(dm_base), 0xFF);
219 /* Initialize UART_DM */
220 msm_boot_uart_dm_init(dm_base);
223 /* for the benefit of non-console uart init */
224 void qcs405_uart_init(void)
226 uart_init(0);
230 * @brief uart_tx_flush - transmits a string of data
231 * @param idx: string to transmit
233 void uart_tx_flush(unsigned int idx)
235 void *base = uart_board_param.uart_dm_base;
237 while (!(read32(MSM_BOOT_UART_DM_SR(base)) &
238 MSM_BOOT_UART_DM_SR_TXEMT))
242 #if CONFIG(DRIVERS_UART)
244 * qcs405_serial_getc - reads a character
246 * Returns the character read from serial port.
248 uint8_t uart_rx_byte(unsigned int idx)
250 uint8_t byte;
252 byte = (uint8_t)(word & 0xff);
253 word = word >> 8;
254 valid_data--;
256 return byte;
258 #endif
260 enum cb_err fill_lb_serial(struct lb_serial *serial)
262 serial->type = LB_SERIAL_TYPE_MEMORY_MAPPED;
263 serial->baseaddr = (uint64_t)UART2_DM_BASE;
264 serial->baud = get_uart_baudrate();
265 serial->regwidth = 1;
266 serial->input_hertz = uart_platform_refclk();
268 return CB_SUCCESS;