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>
11 #include <soc/ipq_uart.h>
14 #define FIFO_DATA_SIZE 4
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
];
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
,
29 #if CONFIG(IPQ_QFN_PART)
41 #if CONFIG(IPQ_QFN_PART)
56 * @brief msm_boot_uart_dm_init_rx_transfer - Init Rx transfer
57 * @param uart_dm_base: UART controller base address
59 static unsigned int msm_boot_uart_dm_init_rx_transfer(void *uart_dm_base
)
62 write32(MSM_BOOT_UART_DM_CR(uart_dm_base
),
63 MSM_BOOT_UART_DM_CMD_RESET_RX
);
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
);
71 /* Clear stale event */
72 write32(MSM_BOOT_UART_DM_CR(uart_dm_base
),
73 MSM_BOOT_UART_DM_CMD_RES_STALE_INT
);
75 /* Enable stale event */
76 write32(MSM_BOOT_UART_DM_CR(uart_dm_base
),
77 MSM_BOOT_UART_DM_GCMD_ENA_STALE_EVT
);
79 return MSM_BOOT_UART_DM_E_SUCCESS
;
82 static unsigned int msm_boot_uart_dm_init(void *uart_dm_base
);
84 /* Received data is valid or not */
85 static int valid_data
= 0;
88 static unsigned int word
= 0;
90 void uart_tx_byte(unsigned int idx
, unsigned char data
)
93 void *base
= uart_board_param
.uart_dm_base
;
95 /* Wait until transmit FIFO is empty. */
96 while (!(read32(MSM_BOOT_UART_DM_SR(base
)) &
97 MSM_BOOT_UART_DM_SR_TXEMT
))
100 * TX FIFO is ready to accept new character(s). First write number of
101 * characters to be transmitted.
103 write32(MSM_BOOT_UART_DM_NO_CHARS_FOR_TX(base
), num_of_chars
);
105 /* And now write the character(s) */
106 write32(MSM_BOOT_UART_DM_TF(base
, 0), data
);
110 * @brief msm_boot_uart_dm_reset - resets UART controller
111 * @param base: UART controller base address
113 static unsigned int msm_boot_uart_dm_reset(void *base
)
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
);
122 return MSM_BOOT_UART_DM_E_SUCCESS
;
126 * @brief msm_boot_uart_dm_init - initilaizes UART controller
127 * @param uart_dm_base: UART controller base address
129 unsigned int msm_boot_uart_dm_init(void *uart_dm_base
)
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);
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
);
139 /* Configure Interrupt Mask register IMR */
140 write32(MSM_BOOT_UART_DM_IMR(uart_dm_base
),
141 MSM_BOOT_UART_DM_IMR_ENABLED
);
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
148 write32(MSM_BOOT_UART_DM_TFWR(uart_dm_base
),
149 MSM_BOOT_UART_DM_TFW_VALUE
);
151 /* RX watermark value */
152 write32(MSM_BOOT_UART_DM_RFWR(uart_dm_base
),
153 MSM_BOOT_UART_DM_RFW_VALUE
);
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
);
160 /* Configure IRDA if required */
161 /* Disabling IRDA mode */
162 write32(MSM_BOOT_UART_DM_IRDA(uart_dm_base
), 0x0);
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);
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
176 /* Issue soft reset command */
177 msm_boot_uart_dm_reset(uart_dm_base
);
179 /* Enable/Disable Rx/Tx DM interfaces */
180 /* Data Mover not currently utilized. */
181 write32(MSM_BOOT_UART_DM_DMEN(uart_dm_base
), 0x0);
183 /* Enable transmitter */
184 write32(MSM_BOOT_UART_DM_CR(uart_dm_base
),
185 MSM_BOOT_UART_DM_CR_TX_ENABLE
);
187 /* Initialize Receive Path */
188 msm_boot_uart_dm_init_rx_transfer(uart_dm_base
);
194 * @brief ipq40xx_uart_init - initializes UART
196 * Initializes clocks, GPIO and UART controller.
198 void uart_init(unsigned int idx
)
200 /* Note int idx isn't used in this driver. */
203 dm_base
= uart_board_param
.uart_dm_base
;
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. */
208 ipq_configure_gpio(uart_board_param
.dbg_uart_gpio
,
209 NO_OF_DBG_UART_GPIOS
);
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
);
217 write32(MSM_BOOT_UART_DM_CSR(dm_base
), UART_DM_CLK_RX_TX_BIT_RATE
);
219 /* Initialize UART_DM */
220 msm_boot_uart_dm_init(dm_base
);
223 /* for the benefit of non-console uart init */
224 void ipq40xx_uart_init(void)
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
))
243 * ipq40xx_serial_getc - reads a character
245 * Returns the character read from serial port.
247 uint8_t uart_rx_byte(unsigned int idx
)
251 byte
= (uint8_t)(word
& 0xff);
258 /* TODO: Implement function */
259 enum cb_err
fill_lb_serial(struct lb_serial
*serial
)
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();