soc: Remove copyright notices
[coreboot.git] / src / soc / qualcomm / qcs405 / uart.c
blobc9c1b3906b5b2e7fda830202fa57d3b72138a8dd
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/uart.h>
38 #include <soc/cdp.h>
39 #include <stdint.h>
40 #include <soc/iomap.h>
42 #define FIFO_DATA_SIZE 4
44 typedef struct {
45 void *uart_dm_base;
46 unsigned int blsp_uart;
47 gpio_func_data_t dbg_uart_gpio[NO_OF_DBG_UART_GPIOS];
48 } uart_params_t;
50 void ipq_configure_gpio(const gpio_func_data_t *gpio, unsigned int count)
52 int i;
54 for (i = 0; i < count; i++) {
55 gpio_configure(gpio->gpio, gpio->func,
56 gpio->pull, gpio->drvstr, gpio->enable);
57 gpio++;
61 static const uart_params_t uart_board_param = {
62 .uart_dm_base = UART2_DM_BASE,
63 .blsp_uart = BLSP1_UART2,
64 .dbg_uart_gpio = {
66 .gpio = GPIO(17),
67 .func = 1,
68 .dir = GPIO_OUTPUT,
69 .pull = GPIO_PULL_UP,
70 .enable = GPIO_OUTPUT
73 .gpio = GPIO(18),
74 .func = 1,
75 .dir = GPIO_INPUT,
76 .pull = GPIO_NO_PULL,
77 .enable = GPIO_INPUT
82 /**
83 * @brief msm_boot_uart_dm_init_rx_transfer - Init Rx transfer
84 * @param uart_dm_base: UART controller base address
86 static unsigned int msm_boot_uart_dm_init_rx_transfer(void *uart_dm_base)
88 /* Reset receiver */
89 write32(MSM_BOOT_UART_DM_CR(uart_dm_base),
90 MSM_BOOT_UART_DM_CMD_RESET_RX);
92 /* Enable receiver */
93 write32(MSM_BOOT_UART_DM_CR(uart_dm_base),
94 MSM_BOOT_UART_DM_CR_RX_ENABLE);
95 write32(MSM_BOOT_UART_DM_DMRX(uart_dm_base),
96 MSM_BOOT_UART_DM_DMRX_DEF_VALUE);
98 /* Clear stale event */
99 write32(MSM_BOOT_UART_DM_CR(uart_dm_base),
100 MSM_BOOT_UART_DM_CMD_RES_STALE_INT);
102 /* Enable stale event */
103 write32(MSM_BOOT_UART_DM_CR(uart_dm_base),
104 MSM_BOOT_UART_DM_GCMD_ENA_STALE_EVT);
106 return MSM_BOOT_UART_DM_E_SUCCESS;
109 #if CONFIG(DRIVERS_UART)
110 static unsigned int msm_boot_uart_dm_init(void *uart_dm_base);
112 /* Received data is valid or not */
113 static int valid_data = 0;
115 /* Received data */
116 static unsigned int word = 0;
119 void uart_tx_byte(int idx, unsigned char data)
121 int num_of_chars = 1;
122 void *base = uart_board_param.uart_dm_base;
124 /* Wait until transmit FIFO is empty. */
125 while (!(read32(MSM_BOOT_UART_DM_SR(base)) &
126 MSM_BOOT_UART_DM_SR_TXEMT))
127 udelay(1);
129 * TX FIFO is ready to accept new character(s). First write number of
130 * characters to be transmitted.
132 write32(MSM_BOOT_UART_DM_NO_CHARS_FOR_TX(base), num_of_chars);
134 /* And now write the character(s) */
135 write32(MSM_BOOT_UART_DM_TF(base, 0), data);
137 #endif /* CONFIG_SERIAL_UART */
140 * @brief msm_boot_uart_dm_reset - resets UART controller
141 * @param base: UART controller base address
143 static unsigned int msm_boot_uart_dm_reset(void *base)
145 write32(MSM_BOOT_UART_DM_CR(base), MSM_BOOT_UART_DM_CMD_RESET_RX);
146 write32(MSM_BOOT_UART_DM_CR(base), MSM_BOOT_UART_DM_CMD_RESET_TX);
147 write32(MSM_BOOT_UART_DM_CR(base),
148 MSM_BOOT_UART_DM_CMD_RESET_ERR_STAT);
149 write32(MSM_BOOT_UART_DM_CR(base), MSM_BOOT_UART_DM_CMD_RES_TX_ERR);
150 write32(MSM_BOOT_UART_DM_CR(base), MSM_BOOT_UART_DM_CMD_RES_STALE_INT);
152 return MSM_BOOT_UART_DM_E_SUCCESS;
156 * @brief msm_boot_uart_dm_init - initilaizes UART controller
157 * @param uart_dm_base: UART controller base address
159 unsigned int msm_boot_uart_dm_init(void *uart_dm_base)
161 /* Configure UART mode registers MR1 and MR2 */
162 /* Hardware flow control isn't supported */
163 write32(MSM_BOOT_UART_DM_MR1(uart_dm_base), 0x0);
165 /* 8-N-1 configuration: 8 data bits - No parity - 1 stop bit */
166 write32(MSM_BOOT_UART_DM_MR2(uart_dm_base),
167 MSM_BOOT_UART_DM_8_N_1_MODE);
169 /* Configure Interrupt Mask register IMR */
170 write32(MSM_BOOT_UART_DM_IMR(uart_dm_base),
171 MSM_BOOT_UART_DM_IMR_ENABLED);
174 * Configure Tx and Rx watermarks configuration registers
175 * TX watermark value is set to 0 - interrupt is generated when
176 * FIFO level is less than or equal to 0
178 write32(MSM_BOOT_UART_DM_TFWR(uart_dm_base),
179 MSM_BOOT_UART_DM_TFW_VALUE);
181 /* RX watermark value */
182 write32(MSM_BOOT_UART_DM_RFWR(uart_dm_base),
183 MSM_BOOT_UART_DM_RFW_VALUE);
185 /* Configure Interrupt Programming Register */
186 /* Set initial Stale timeout value */
187 write32(MSM_BOOT_UART_DM_IPR(uart_dm_base),
188 MSM_BOOT_UART_DM_STALE_TIMEOUT_LSB);
190 /* Configure IRDA if required */
191 /* Disabling IRDA mode */
192 write32(MSM_BOOT_UART_DM_IRDA(uart_dm_base), 0x0);
194 /* Configure hunt character value in HCR register */
195 /* Keep it in reset state */
196 write32(MSM_BOOT_UART_DM_HCR(uart_dm_base), 0x0);
199 * Configure Rx FIFO base address
200 * Both TX/RX shares same SRAM and default is half-n-half.
201 * Sticking with default value now.
202 * As such RAM size is (2^RAM_ADDR_WIDTH, 32-bit entries).
203 * We have found RAM_ADDR_WIDTH = 0x7f
206 /* Issue soft reset command */
207 msm_boot_uart_dm_reset(uart_dm_base);
209 /* Enable/Disable Rx/Tx DM interfaces */
210 /* Data Mover not currently utilized. */
211 write32(MSM_BOOT_UART_DM_DMEN(uart_dm_base), 0x0);
213 /* Enable transmitter */
214 write32(MSM_BOOT_UART_DM_CR(uart_dm_base),
215 MSM_BOOT_UART_DM_CR_TX_ENABLE);
217 /* Initialize Receive Path */
218 msm_boot_uart_dm_init_rx_transfer(uart_dm_base);
220 return 0;
224 * @brief qcs405_uart_init - initializes UART
226 * Initializes clocks, GPIO and UART controller.
228 void uart_init(int idx)
230 /* Note int idx isn't used in this driver. */
231 void *dm_base;
233 dm_base = uart_board_param.uart_dm_base;
235 if (read32(MSM_BOOT_UART_DM_CSR(dm_base)) == 0xFF)
236 return; /* UART must have been already initialized. */
238 clock_configure_uart(1843200);
239 clock_enable_uart();
241 ipq_configure_gpio(uart_board_param.dbg_uart_gpio,
242 NO_OF_DBG_UART_GPIOS);
244 write32(MSM_BOOT_UART_DM_CSR(dm_base), 0xFF);
246 /* Initialize UART_DM */
247 msm_boot_uart_dm_init(dm_base);
250 /* for the benefit of non-console uart init */
251 void qcs405_uart_init(void)
253 uart_init(0);
257 * @brief uart_tx_flush - transmits a string of data
258 * @param idx: string to transmit
260 void uart_tx_flush(int idx)
262 void *base = uart_board_param.uart_dm_base;
264 while (!(read32(MSM_BOOT_UART_DM_SR(base)) &
265 MSM_BOOT_UART_DM_SR_TXEMT))
269 #if CONFIG(DRIVERS_UART)
271 * qcs405_serial_getc - reads a character
273 * Returns the character read from serial port.
275 uint8_t uart_rx_byte(int idx)
277 uint8_t byte;
279 byte = (uint8_t)(word & 0xff);
280 word = word >> 8;
281 valid_data--;
283 return byte;
285 #endif
287 void uart_fill_lb(void *data)
289 struct lb_serial serial;
291 serial.type = LB_SERIAL_TYPE_MEMORY_MAPPED;
292 serial.baseaddr = (uint64_t)UART2_DM_BASE;
293 serial.baud = get_uart_baudrate();
294 serial.regwidth = 1;
295 serial.input_hertz = uart_platform_refclk();
296 serial.uart_pci_addr = CONFIG_UART_PCI_ADDR;
297 lb_add_serial(&serial, data);
299 lb_add_console(LB_TAG_CONSOLE_SERIAL8250MEM, data);