2 * Source : APQ8064 LK boot
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above
10 * copyright notice, this list of conditions and the following
11 * disclaimer in the documentation and/or other materials provided
12 * with the distribution.
13 * * Neither the name of The Linux Foundation nor the names of its
14 * contributors may be used to endorse or promote products derived
15 * from this software without specific prior written permission.
17 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
18 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
19 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
21 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
24 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
25 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
26 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
27 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 #include <device/mmio.h>
31 #include <boot/coreboot_tables.h>
32 #include <console/uart.h>
35 #include <soc/clock.h>
37 #include <soc/ipq_uart.h>
40 #define FIFO_DATA_SIZE 4
44 uart_clk_mnd_t mnd_value
;
45 unsigned int blsp_uart
;
46 gpio_func_data_t dbg_uart_gpio
[NO_OF_DBG_UART_GPIOS
];
49 static const uart_params_t uart_board_param
= {
50 .uart_dm_base
= UART1_DM_BASE
,
51 .mnd_value
= { 24, 625, 313 },
52 .blsp_uart
= BLSP1_UART1
,
55 #if CONFIG(IPQ_QFN_PART)
67 #if CONFIG(IPQ_QFN_PART)
82 * @brief msm_boot_uart_dm_init_rx_transfer - Init Rx transfer
83 * @param uart_dm_base: UART controller base address
85 static unsigned int msm_boot_uart_dm_init_rx_transfer(void *uart_dm_base
)
88 write32(MSM_BOOT_UART_DM_CR(uart_dm_base
),
89 MSM_BOOT_UART_DM_CMD_RESET_RX
);
92 write32(MSM_BOOT_UART_DM_CR(uart_dm_base
),
93 MSM_BOOT_UART_DM_CR_RX_ENABLE
);
94 write32(MSM_BOOT_UART_DM_DMRX(uart_dm_base
),
95 MSM_BOOT_UART_DM_DMRX_DEF_VALUE
);
97 /* Clear stale event */
98 write32(MSM_BOOT_UART_DM_CR(uart_dm_base
),
99 MSM_BOOT_UART_DM_CMD_RES_STALE_INT
);
101 /* Enable stale event */
102 write32(MSM_BOOT_UART_DM_CR(uart_dm_base
),
103 MSM_BOOT_UART_DM_GCMD_ENA_STALE_EVT
);
105 return MSM_BOOT_UART_DM_E_SUCCESS
;
108 static unsigned int msm_boot_uart_dm_init(void *uart_dm_base
);
110 /* Received data is valid or not */
111 static int valid_data
= 0;
114 static unsigned int word
= 0;
116 void uart_tx_byte(int idx
, unsigned char data
)
118 int num_of_chars
= 1;
119 void *base
= uart_board_param
.uart_dm_base
;
121 /* Wait until transmit FIFO is empty. */
122 while (!(read32(MSM_BOOT_UART_DM_SR(base
)) &
123 MSM_BOOT_UART_DM_SR_TXEMT
))
126 * TX FIFO is ready to accept new character(s). First write number of
127 * characters to be transmitted.
129 write32(MSM_BOOT_UART_DM_NO_CHARS_FOR_TX(base
), num_of_chars
);
131 /* And now write the character(s) */
132 write32(MSM_BOOT_UART_DM_TF(base
, 0), data
);
136 * @brief msm_boot_uart_dm_reset - resets UART controller
137 * @param base: UART controller base address
139 static unsigned int msm_boot_uart_dm_reset(void *base
)
141 write32(MSM_BOOT_UART_DM_CR(base
), MSM_BOOT_UART_DM_CMD_RESET_RX
);
142 write32(MSM_BOOT_UART_DM_CR(base
), MSM_BOOT_UART_DM_CMD_RESET_TX
);
143 write32(MSM_BOOT_UART_DM_CR(base
),
144 MSM_BOOT_UART_DM_CMD_RESET_ERR_STAT
);
145 write32(MSM_BOOT_UART_DM_CR(base
), MSM_BOOT_UART_DM_CMD_RES_TX_ERR
);
146 write32(MSM_BOOT_UART_DM_CR(base
), MSM_BOOT_UART_DM_CMD_RES_STALE_INT
);
148 return MSM_BOOT_UART_DM_E_SUCCESS
;
152 * @brief msm_boot_uart_dm_init - initilaizes UART controller
153 * @param uart_dm_base: UART controller base address
155 unsigned int msm_boot_uart_dm_init(void *uart_dm_base
)
157 /* Configure UART mode registers MR1 and MR2 */
158 /* Hardware flow control isn't supported */
159 write32(MSM_BOOT_UART_DM_MR1(uart_dm_base
), 0x0);
161 /* 8-N-1 configuration: 8 data bits - No parity - 1 stop bit */
162 write32(MSM_BOOT_UART_DM_MR2(uart_dm_base
),
163 MSM_BOOT_UART_DM_8_N_1_MODE
);
165 /* Configure Interrupt Mask register IMR */
166 write32(MSM_BOOT_UART_DM_IMR(uart_dm_base
),
167 MSM_BOOT_UART_DM_IMR_ENABLED
);
170 * Configure Tx and Rx watermarks configuration registers
171 * TX watermark value is set to 0 - interrupt is generated when
172 * FIFO level is less than or equal to 0
174 write32(MSM_BOOT_UART_DM_TFWR(uart_dm_base
),
175 MSM_BOOT_UART_DM_TFW_VALUE
);
177 /* RX watermark value */
178 write32(MSM_BOOT_UART_DM_RFWR(uart_dm_base
),
179 MSM_BOOT_UART_DM_RFW_VALUE
);
181 /* Configure Interrupt Programming Register */
182 /* Set initial Stale timeout value */
183 write32(MSM_BOOT_UART_DM_IPR(uart_dm_base
),
184 MSM_BOOT_UART_DM_STALE_TIMEOUT_LSB
);
186 /* Configure IRDA if required */
187 /* Disabling IRDA mode */
188 write32(MSM_BOOT_UART_DM_IRDA(uart_dm_base
), 0x0);
190 /* Configure hunt character value in HCR register */
191 /* Keep it in reset state */
192 write32(MSM_BOOT_UART_DM_HCR(uart_dm_base
), 0x0);
195 * Configure Rx FIFO base address
196 * Both TX/RX shares same SRAM and default is half-n-half.
197 * Sticking with default value now.
198 * As such RAM size is (2^RAM_ADDR_WIDTH, 32-bit entries).
199 * We have found RAM_ADDR_WIDTH = 0x7f
202 /* Issue soft reset command */
203 msm_boot_uart_dm_reset(uart_dm_base
);
205 /* Enable/Disable Rx/Tx DM interfaces */
206 /* Data Mover not currently utilized. */
207 write32(MSM_BOOT_UART_DM_DMEN(uart_dm_base
), 0x0);
209 /* Enable transmitter */
210 write32(MSM_BOOT_UART_DM_CR(uart_dm_base
),
211 MSM_BOOT_UART_DM_CR_TX_ENABLE
);
213 /* Initialize Receive Path */
214 msm_boot_uart_dm_init_rx_transfer(uart_dm_base
);
220 * @brief ipq40xx_uart_init - initializes UART
222 * Initializes clocks, GPIO and UART controller.
224 void uart_init(int idx
)
226 /* Note int idx isn't used in this driver. */
229 dm_base
= uart_board_param
.uart_dm_base
;
231 if (read32(MSM_BOOT_UART_DM_CSR(dm_base
)) == UART_DM_CLK_RX_TX_BIT_RATE
)
232 return; /* UART must have been already initialized. */
234 ipq_configure_gpio(uart_board_param
.dbg_uart_gpio
,
235 NO_OF_DBG_UART_GPIOS
);
237 /* Configure the uart clock */
238 uart_clock_config(uart_board_param
.blsp_uart
,
239 uart_board_param
.mnd_value
.m_value
,
240 uart_board_param
.mnd_value
.n_value
,
241 uart_board_param
.mnd_value
.d_value
);
243 write32(MSM_BOOT_UART_DM_CSR(dm_base
), UART_DM_CLK_RX_TX_BIT_RATE
);
245 /* Initialize UART_DM */
246 msm_boot_uart_dm_init(dm_base
);
249 /* for the benefit of non-console uart init */
250 void ipq40xx_uart_init(void)
256 * @brief uart_tx_flush - transmits a string of data
257 * @param idx: string to transmit
259 void uart_tx_flush(int idx
)
261 void *base
= uart_board_param
.uart_dm_base
;
263 while (!(read32(MSM_BOOT_UART_DM_SR(base
)) &
264 MSM_BOOT_UART_DM_SR_TXEMT
))
269 * ipq40xx_serial_getc - reads a character
271 * Returns the character read from serial port.
273 uint8_t uart_rx_byte(int idx
)
277 byte
= (uint8_t)(word
& 0xff);
284 /* TODO: Implement function */
285 void uart_fill_lb(void *data
)
287 struct lb_serial serial
;
289 serial
.type
= LB_SERIAL_TYPE_MEMORY_MAPPED
;
290 serial
.baseaddr
= (uint32_t)UART1_DM_BASE
;
291 serial
.baud
= get_uart_baudrate();
293 serial
.input_hertz
= uart_platform_refclk();
294 serial
.uart_pci_addr
= CONFIG_UART_PCI_ADDR
;
295 lb_add_serial(&serial
, data
);
297 lb_add_console(LB_TAG_CONSOLE_SERIAL8250MEM
, data
);