coreboot
coreboot is an Open Source project aimed at replacing the proprietary BIOS found in most computers.
uart.c
Go to the documentation of this file.
1 /* Source : APQ8064 LK boot */
2 /* SPDX-License-Identifier: BSD-3-Clause */
3 
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/gsbi.h>
11 #include <soc/ipq_uart.h>
12 #include <stdint.h>
13 
14 #define FIFO_DATA_SIZE 4
15 
16 typedef struct {
17  void *uart_dm_base;
19  unsigned int uart_gsbi;
20  uart_clk_mnd_t mnd_value;
23 
24 /*
25  * All constants lifted from u-boot's
26  * board/qcom/ipq806x_cdp/ipq806x_board_param.h
27  */
29  .uart_dm_base = (void *)UART4_DM_BASE,
30  .uart_gsbi_base = (void *)UART_GSBI4_BASE,
31  .uart_gsbi = GSBI_4,
32  .mnd_value = { 12, 625, 313 },
33  .dbg_uart_gpio = {
34  {
35  .gpio = 10,
36  .func = 1,
37  .dir = GPIO_OUTPUT,
38  .pull = GPIO_NO_PULL,
39  .drvstr = GPIO_12MA,
40  .enable = GPIO_DISABLE
41  },
42  {
43  .gpio = 11,
44  .func = 1,
45  .dir = GPIO_INPUT,
46  .pull = GPIO_NO_PULL,
47  .drvstr = GPIO_12MA,
48  .enable = GPIO_DISABLE
49  },
50  }
51 };
52 
53 /**
54  * msm_boot_uart_dm_init_rx_transfer - Init Rx transfer
55  * @param uart_dm_base: UART controller base address
56  */
57 static unsigned int msm_boot_uart_dm_init_rx_transfer(void *uart_dm_base)
58 {
59  /* Reset receiver */
60  write32(MSM_BOOT_UART_DM_CR(uart_dm_base),
62 
63  /* Enable receiver */
64  write32(MSM_BOOT_UART_DM_CR(uart_dm_base),
66  write32(MSM_BOOT_UART_DM_DMRX(uart_dm_base),
68 
69  /* Clear stale event */
70  write32(MSM_BOOT_UART_DM_CR(uart_dm_base),
72 
73  /* Enable stale event */
74  write32(MSM_BOOT_UART_DM_CR(uart_dm_base),
76 
78 }
79 
80 static unsigned int msm_boot_uart_dm_init(void *uart_dm_base);
81 
82 /* Received data is valid or not */
83 static int valid_data = 0;
84 
85 /* Received data */
86 static unsigned int word = 0;
87 
88 /**
89  * msm_boot_uart_dm_read - reads a word from the RX FIFO.
90  * @data: location where the read data is stored
91  * @count: no of valid data in the FIFO
92  * @wait: indicates blocking call or not blocking call
93  *
94  * Reads a word from the RX FIFO. If no data is available blocks if
95  * @wait is true, else returns %MSM_BOOT_UART_DM_E_RX_NOT_READY.
96  */
97  #if 0 /* Not used yet */
98 static unsigned int
99 msm_boot_uart_dm_read(unsigned int *data, int *count, int wait)
100 {
101  static int total_rx_data = 0;
102  static int rx_data_read = 0;
103  void *base;
104  uint32_t status_reg;
105 
107 
108  if (data == NULL)
110 
111  status_reg = readl(MSM_BOOT_UART_DM_MISR(base));
112 
113  /* Check for DM_RXSTALE for RX transfer to finish */
114  while (!(status_reg & MSM_BOOT_UART_DM_RXSTALE)) {
115  status_reg = readl(MSM_BOOT_UART_DM_MISR(base));
116  if (!wait)
118  }
119 
120  /* Check for Overrun error. We'll just reset Error Status */
121  if (readl(MSM_BOOT_UART_DM_SR(base)) &
125  total_rx_data = rx_data_read = 0;
128  }
129 
130  /* Read UART_DM_RX_TOTAL_SNAP for actual number of bytes received */
131  if (total_rx_data == 0)
132  total_rx_data = readl(MSM_BOOT_UART_DM_RX_TOTAL_SNAP(base));
133 
134  /* Data available in FIFO; read a word. */
135  *data = readl(MSM_BOOT_UART_DM_RF(base, 0));
136 
137  /* WAR for http://prism/CR/548280 */
138  if (*data == 0) {
140  }
141 
142  /* increment the total count of chars we've read so far */
143  rx_data_read += FIFO_DATA_SIZE;
144 
145  /* actual count of valid data in word */
146  *count = ((total_rx_data < rx_data_read) ?
147  (FIFO_DATA_SIZE - (rx_data_read - total_rx_data)) :
149 
150  /* If there are still data left in FIFO we'll read them before
151  * initializing RX Transfer again
152  */
153  if (rx_data_read < total_rx_data)
155 
157  total_rx_data = rx_data_read = 0;
158 
160 }
161 #endif
162 
163 void uart_tx_byte(unsigned int idx, unsigned char data)
164 {
165  int num_of_chars = 1;
166  unsigned int tx_data = 0;
168 
169  /* Wait until transmit FIFO is empty. */
170  while (!(read32(MSM_BOOT_UART_DM_SR(base)) &
172  udelay(1);
173  /*
174  * TX FIFO is ready to accept new character(s). First write number of
175  * characters to be transmitted.
176  */
178 
179  /* And now write the character(s) */
180  write32(MSM_BOOT_UART_DM_TF(base, 0), tx_data);
181 }
182 
183 /*
184  * msm_boot_uart_dm_reset - resets UART controller
185  * @base: UART controller base address
186  */
187 static unsigned int msm_boot_uart_dm_reset(void *base)
188 {
195 
197 }
198 
199 /*
200  * msm_boot_uart_dm_init - initilaizes UART controller
201  * @uart_dm_base: UART controller base address
202  */
203 static unsigned int msm_boot_uart_dm_init(void *uart_dm_base)
204 {
205  /* Configure UART mode registers MR1 and MR2 */
206  /* Hardware flow control isn't supported */
207  write32(MSM_BOOT_UART_DM_MR1(uart_dm_base), 0x0);
208 
209  /* 8-N-1 configuration: 8 data bits - No parity - 1 stop bit */
210  write32(MSM_BOOT_UART_DM_MR2(uart_dm_base),
212 
213  /* Configure Interrupt Mask register IMR */
214  write32(MSM_BOOT_UART_DM_IMR(uart_dm_base),
216 
217  /*
218  * Configure Tx and Rx watermarks configuration registers
219  * TX watermark value is set to 0 - interrupt is generated when
220  * FIFO level is less than or equal to 0
221  */
222  write32(MSM_BOOT_UART_DM_TFWR(uart_dm_base),
224 
225  /* RX watermark value */
226  write32(MSM_BOOT_UART_DM_RFWR(uart_dm_base),
228 
229  /* Configure Interrupt Programming Register */
230  /* Set initial Stale timeout value */
231  write32(MSM_BOOT_UART_DM_IPR(uart_dm_base),
233 
234  /* Configure IRDA if required */
235  /* Disabling IRDA mode */
236  write32(MSM_BOOT_UART_DM_IRDA(uart_dm_base), 0x0);
237 
238  /* Configure hunt character value in HCR register */
239  /* Keep it in reset state */
240  write32(MSM_BOOT_UART_DM_HCR(uart_dm_base), 0x0);
241 
242  /*
243  * Configure Rx FIFO base address
244  * Both TX/RX shares same SRAM and default is half-n-half.
245  * Sticking with default value now.
246  * As such RAM size is (2^RAM_ADDR_WIDTH, 32-bit entries).
247  * We have found RAM_ADDR_WIDTH = 0x7f
248  */
249 
250  /* Issue soft reset command */
251  msm_boot_uart_dm_reset(uart_dm_base);
252 
253  /* Enable/Disable Rx/Tx DM interfaces */
254  /* Data Mover not currently utilized. */
255  write32(MSM_BOOT_UART_DM_DMEN(uart_dm_base), 0x0);
256 
257  /* Enable transmitter */
258  write32(MSM_BOOT_UART_DM_CR(uart_dm_base),
260 
261  /* Initialize Receive Path */
262  msm_boot_uart_dm_init_rx_transfer(uart_dm_base);
263 
264  return 0;
265 }
266 
267 /**
268  * ipq806x_uart_init - initializes UART
269  *
270  * Initializes clocks, GPIO and UART controller.
271  */
272 void uart_init(unsigned int idx)
273 {
274  /* Note int idx isn't used in this driver. */
275  void *dm_base;
276  void *gsbi_base;
277 
278  dm_base = uart_board_param.uart_dm_base;
279 
281  return; /* UART must have been already initialized. */
282 
283  gsbi_base = uart_board_param.uart_gsbi_base;
286 
287  /* Configure the uart clock */
292  0);
293 
294  write32(GSBI_CTRL_REG(gsbi_base),
297 
298  /* Initialize UART_DM */
299  msm_boot_uart_dm_init(dm_base);
300 }
301 
302 /* for the benefit of non-console uart init */
304 {
305  uart_init(0);
306 }
307 
308 #if 0 /* Not used yet */
309 uint32_t uartmem_getbaseaddr(void)
310 {
312 }
313 #endif
314 
315 /**
316  * uart_tx_flush - transmits a string of data
317  * @s: string to transmit
318  */
319 void uart_tx_flush(unsigned int idx)
320 {
322 
323  while (!(read32(MSM_BOOT_UART_DM_SR(base)) &
325  ;
326 }
327 
328 /**
329  * uart_can_rx_byte - checks if data available for reading
330  *
331  * Returns 1 if data available, 0 otherwise
332  */
333  #if 0 /* Not used yet */
334 int uart_can_rx_byte(void)
335 {
336  /* Return if data is already read */
337  if (valid_data)
338  return 1;
339 
340  /* Read data from the FIFO */
341  if (msm_boot_uart_dm_read(&word, &valid_data, 0) !=
343  return 0;
344 
345  return 1;
346 }
347 #endif
348 
349 /**
350  * ipq806x_serial_getc - reads a character
351  *
352  * Returns the character read from serial port.
353  */
354 uint8_t uart_rx_byte(unsigned int idx)
355 {
356  uint8_t byte;
357 
358 #if 0 /* Not used yet */
359  while (!uart_can_rx_byte()) {
360  /* wait for incoming data */
361  }
362 #endif
363  byte = (uint8_t)(word & 0xff);
364  word = word >> 8;
365  valid_data--;
366 
367  return byte;
368 }
369 
370 /* TODO: Implement function */
371 void uart_fill_lb(void *data)
372 {
373 }
#define GPIO_OUTPUT
Definition: gpio_ftns.h:23
#define GPIO_INPUT
Definition: gpio_ftns.h:24
static void write32(void *addr, uint32_t val)
Definition: mmio.h:40
static uint32_t read32(const void *addr)
Definition: mmio.h:22
static void wait(unsigned int bus)
Definition: software_i2c.c:55
#define GSBI_CTRL_REG(base)
Definition: gsbi.h:7
#define GSBI_CTRL_REG_PROTOCOL_CODE_S
Definition: gsbi.h:9
#define GSBI_PROTOCOL_CODE_I2C_UART
Definition: gsbi.h:13
#define NO_OF_DBG_UART_GPIOS
Definition: cdp.h:76
#define MSM_BOOT_UART_DM_TF(base, x)
Definition: ipq_uart.h:58
#define MSM_BOOT_UART_DM_DMRX(base)
Definition: ipq_uart.h:152
#define MSM_BOOT_UART_DM_MISR(base)
Definition: ipq_uart.h:198
#define MSM_BOOT_UART_DM_IMR(base)
Definition: ipq_uart.h:111
#define MSM_BOOT_UART_DM_E_INVAL
Definition: ipq_uart.h:239
#define MSM_BOOT_UART_DM_MR1(base)
Definition: ipq_uart.h:44
#define MSM_BOOT_UART_DM_CSR(base)
Definition: ipq_uart.h:51
#define MSM_BOOT_UART_DM_GCMD_ENA_STALE_EVT
Definition: ipq_uart.h:106
#define MSM_BOOT_UART_DM_HCR(base)
Definition: ipq_uart.h:149
#define MSM_BOOT_UART_DM_SR_TXEMT
Definition: ipq_uart.h:182
#define MSM_BOOT_UART_DM_CMD_RES_TX_ERR
Definition: ipq_uart.h:92
#define MSM_BOOT_UART_DM_TFWR(base)
Definition: ipq_uart.h:140
#define MSM_BOOT_UART_DM_MR2(base)
Definition: ipq_uart.h:45
#define MSM_BOOT_UART_DM_E_RX_NOT_READY
Definition: ipq_uart.h:241
#define MSM_BOOT_UART_DM_SR(base)
Definition: ipq_uart.h:175
#define MSM_BOOT_UART_DM_IMR_ENABLED
Definition: ipq_uart.h:130
#define MSM_BOOT_UART_DM_SR_UART_OVERRUN
Definition: ipq_uart.h:183
#define MSM_BOOT_UART_DM_RXSTALE
Definition: ipq_uart.h:119
#define MSM_BOOT_UART_DM_RX_TOTAL_SNAP(base)
Definition: ipq_uart.h:212
#define MSM_BOOT_UART_DM_TFW_VALUE
Definition: ipq_uart.h:142
#define MSM_BOOT_UART_DM_IPR(base)
Definition: ipq_uart.h:135
#define MSM_BOOT_UART_DM_DMEN(base)
Definition: ipq_uart.h:165
#define MSM_BOOT_UART_DM_STALE_TIMEOUT_LSB
Definition: ipq_uart.h:136
#define MSM_BOOT_UART_DM_CR_TX_ENABLE
Definition: ipq_uart.h:71
#define MSM_BOOT_UART_DM_RFWR(base)
Definition: ipq_uart.h:144
#define MSM_BOOT_UART_DM_DMRX_DEF_VALUE
Definition: ipq_uart.h:155
#define MSM_BOOT_UART_DM_NO_CHARS_FOR_TX(base)
Definition: ipq_uart.h:168
#define MSM_BOOT_UART_DM_CMD_RESET_TX
Definition: ipq_uart.h:81
#define MSM_BOOT_UART_DM_IRDA(base)
Definition: ipq_uart.h:159
#define MSM_BOOT_UART_DM_CR(base)
Definition: ipq_uart.h:65
#define MSM_BOOT_UART_DM_8_N_1_MODE
Definition: ipq_uart.h:37
#define MSM_BOOT_UART_DM_CMD_RES_STALE_INT
Definition: ipq_uart.h:87
#define MSM_BOOT_UART_DM_E_SUCCESS
Definition: ipq_uart.h:236
#define MSM_BOOT_UART_DM_CMD_RESET_RX
Definition: ipq_uart.h:80
#define MSM_BOOT_UART_DM_RFW_VALUE
Definition: ipq_uart.h:146
#define MSM_BOOT_UART_DM_CMD_RESET_ERR_STAT
Definition: ipq_uart.h:82
#define MSM_BOOT_UART_DM_RF(base, x)
Definition: ipq_uart.h:191
#define MSM_BOOT_UART_DM_CR_RX_ENABLE
Definition: ipq_uart.h:69
void uart_init(unsigned int idx)
Definition: uart.c:13
void uart_tx_flush(unsigned int idx)
Definition: uart.c:27
unsigned char uart_rx_byte(unsigned int idx)
Definition: uart.c:17
void uart_fill_lb(void *data)
Definition: uart.c:31
void uart_tx_byte(unsigned int idx, unsigned char data)
Definition: uart.c:22
@ GPIO_12MA
Definition: gpio_common.h:75
@ GPIO_NO_PULL
Definition: gpio_common.h:62
#define UART_GSBI4_BASE
Definition: iomap.h:76
#define UART4_DM_BASE
Definition: iomap.h:75
#define GSBI_4
Definition: iomap.h:70
uintptr_t base
Definition: uart.c:17
void uart_clock_config(unsigned int blsp_uart, unsigned int m, unsigned int n, unsigned int d)
uart_clock_config - configures UART clocks
Definition: clock.c:17
#define UART_DM_CLK_RX_TX_BIT_RATE
Definition: clock.h:11
#define GPIO_DISABLE
Definition: gpio.h:37
void ipq806x_uart_init(void)
Definition: uart.c:303
static unsigned int msm_boot_uart_dm_reset(void *base)
Definition: uart.c:187
static const uart_params_t uart_board_param
Definition: uart.c:28
static int valid_data
Definition: uart.c:83
static unsigned int msm_boot_uart_dm_init(void *uart_dm_base)
Definition: uart.c:203
#define FIFO_DATA_SIZE
Definition: uart.c:14
static unsigned int word
Definition: uart.c:86
static unsigned int msm_boot_uart_dm_init_rx_transfer(void *uart_dm_base)
msm_boot_uart_dm_init_rx_transfer - Init Rx transfer
Definition: uart.c:57
void ipq_configure_gpio(const gpio_func_data_t *gpio, unsigned int count)
Definition: uart.c:24
#define NULL
Definition: stddef.h:19
unsigned int uint32_t
Definition: stdint.h:14
unsigned char uint8_t
Definition: stdint.h:8
unsigned int d_value
Definition: cdp.h:38
unsigned int m_value
Definition: cdp.h:36
unsigned int n_value
Definition: cdp.h:37
void * uart_dm_base
Definition: uart.c:17
unsigned int uart_gsbi
Definition: uart.c:19
gpio_func_data_t dbg_uart_gpio[NO_OF_DBG_UART_GPIOS]
Definition: uart.c:20
void * uart_gsbi_base
Definition: uart.c:18
uart_clk_mnd_t mnd_value
Definition: uart.c:18
void udelay(uint32_t us)
Definition: udelay.c:15
#define count