soc: Remove copyright notices
[coreboot.git] / src / soc / qualcomm / ipq40xx / uart.c
blob9e20776bdb294fd26fe4692cdb35e3506dd66a0d
1 /*
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
6 * met:
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>
33 #include <delay.h>
34 #include <gpio.h>
35 #include <soc/clock.h>
36 #include <soc/blsp.h>
37 #include <soc/ipq_uart.h>
38 #include <stdint.h>
40 #define FIFO_DATA_SIZE 4
42 typedef struct {
43 void *uart_dm_base;
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];
47 } uart_params_t;
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,
53 .dbg_uart_gpio = {
55 #if CONFIG(IPQ_QFN_PART)
56 .gpio = 60,
57 .func = 2,
58 #else /* bga */
59 .gpio = 16,
60 .func = 1,
61 #endif
62 .dir = GPIO_INPUT,
63 .pull = GPIO_NO_PULL,
64 .enable = GPIO_ENABLE
67 #if CONFIG(IPQ_QFN_PART)
68 .gpio = 61,
69 .func = 2,
70 #else /* bga */
71 .gpio = 17,
72 .func = 1,
73 #endif
74 .dir = GPIO_OUTPUT,
75 .pull = GPIO_NO_PULL,
76 .enable = GPIO_ENABLE
81 /**
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)
87 /* Reset receiver */
88 write32(MSM_BOOT_UART_DM_CR(uart_dm_base),
89 MSM_BOOT_UART_DM_CMD_RESET_RX);
91 /* Enable receiver */
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;
113 /* Received data */
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))
124 udelay(1);
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);
216 return 0;
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. */
227 void *dm_base;
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)
252 uart_init(0);
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)
275 uint8_t byte;
277 byte = (uint8_t)(word & 0xff);
278 word = word >> 8;
279 valid_data--;
281 return byte;
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();
292 serial.regwidth = 1;
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);