diff options
author | Vadim Bendebury <vbendeb@chromium.org> | 2014-05-27 18:03:38 -0700 |
---|---|---|
committer | Marc Jones <marc.jones@se-eng.com> | 2015-01-03 20:02:37 +0100 |
commit | 24a53dddb9b0b545ab9208722ff7b684114b4e91 (patch) | |
tree | bffd2066158aa26568c31578acb784a17feeef3a /src/soc/qualcomm/ipq806x/uart.c | |
parent | 0780d67ffe8ef754ace0912114e2b1e772554990 (diff) | |
download | coreboot-24a53dddb9b0b545ab9208722ff7b684114b4e91.tar.xz |
ipq806x: clean up UART driver tx_byte function
The driver as it was copied from u-boot provided a function to
transmit multiple characters in one invocation. This feature was not
ported to coreboot, there is no need to maintain the complexity when
only one character at a time is transmitted. It is also very desirable
to get rid of a 1024 byte array allocated on the stack.
The array was necessary to allow to convert multiple newline
characters in the transmit data flow into two character sequences
CRLF. Now just a single word is enough to keep one or two characters
to transmit.
[EDIT km: newline translation is now part of printk]
BUG=chrome-os-partner:27784
TEST=verified that coreboot with the new code prints generates console
output.
Original-Change-Id: I73869c5f4ca87210b34811b583386554bafff1e7
Original-Signed-off-by: Vadim Bendebury <vbendeb@chromium.org>
Original-Reviewed-on: https://chromium-review.googlesource.com/201782
Original-Reviewed-by: Stefan Reinauer <reinauer@chromium.org>
Original-Reviewed-by: Trevor Bourget <tbourget@codeaurora.org>
(cherry picked from commit eab3dc9d30c7e8355a2563e18ada78e4070e6151)
Signed-off-by: Marc Jones <marc.jones@se-eng.com>
Change-Id: I4274b8f7188bf9636906b39bcd9ec7adf0e1222e
Signed-off-by: Kyösti Mälkki <kyosti.malkki@gmail.com>
Reviewed-on: http://review.coreboot.org/8011
Tested-by: build bot (Jenkins)
Reviewed-by: Marc Jones <marc.jones@se-eng.com>
Diffstat (limited to 'src/soc/qualcomm/ipq806x/uart.c')
-rw-r--r-- | src/soc/qualcomm/ipq806x/uart.c | 118 |
1 files changed, 12 insertions, 106 deletions
diff --git a/src/soc/qualcomm/ipq806x/uart.c b/src/soc/qualcomm/ipq806x/uart.c index f7b5d0295e..4989247f33 100644 --- a/src/soc/qualcomm/ipq806x/uart.c +++ b/src/soc/qualcomm/ipq806x/uart.c @@ -192,108 +192,23 @@ msm_boot_uart_dm_read(unsigned int *data, int *count, int wait) } #endif -/** - * msm_boot_uart_replace_lr_with_cr - replaces "\n" with "\r\n" - * @data_in: characters to be converted - * @num_of_chars: no. of characters - * @data_out: location where converted chars are stored - * - * Replace linefeed char "\n" with carriage return + linefeed - * "\r\n". Currently keeping it simple than efficient. - */ -static unsigned int -msm_boot_uart_replace_lr_with_cr(unsigned char *data_in, - int num_of_chars, - char *data_out, int *num_of_chars_out) +void uart_tx_byte(int idx, unsigned char data) { - int i = 0, j = 0; - - if ((data_in == NULL) || (data_out == NULL) || (num_of_chars < 0)) - return MSM_BOOT_UART_DM_E_INVAL; - - for (i = 0, j = 0; i < num_of_chars; i++, j++) { - if (data_in[i] == '\n') - data_out[j++] = '\r'; - - data_out[j] = data_in[i]; - } - - *num_of_chars_out = j; - - return MSM_BOOT_UART_DM_E_SUCCESS; -} - -/** - * msm_boot_uart_dm_write - transmit data - * @data: data to transmit - * @num_of_chars: no. of bytes to transmit - * - * Writes the data to the TX FIFO. If no space is available blocks - * till space becomes available. - */ -static unsigned int -msm_boot_uart_dm_write(unsigned char *data, unsigned int num_of_chars) -{ - unsigned int tx_word_count = 0; - unsigned int tx_char_left = 0, tx_char = 0; - unsigned int tx_word = 0; - int i = 0; - char *tx_data = NULL; - char new_data[1024]; unsigned int base = uart_board_param.uart_dm_base; - if ((data == NULL) || (num_of_chars <= 0)) - return MSM_BOOT_UART_DM_E_INVAL; - - /* Replace line-feed (/n) with carriage-return + line-feed (/r/n) */ - msm_boot_uart_replace_lr_with_cr(data, num_of_chars, new_data, &i); + /* Wait until transmit FIFO is empty. */ + while (!(readl_i(MSM_BOOT_UART_DM_SR(base)) & + MSM_BOOT_UART_DM_SR_TXEMT)) + udelay(1); - tx_data = new_data; - num_of_chars = i; - - /* Write to NO_CHARS_FOR_TX register number of characters - * to be transmitted. However, before writing TX_FIFO must - * be empty as indicated by TX_READY interrupt in IMR register - */ - /* Check if transmit FIFO is empty. - * If not we'll wait for TX_READY interrupt. */ - - if (!(readl_i(MSM_BOOT_UART_DM_SR(base)) & MSM_BOOT_UART_DM_SR_TXEMT)) { - while (!(readl_i(MSM_BOOT_UART_DM_ISR(base)) & - MSM_BOOT_UART_DM_TX_READY)) - udelay(1); - } - - /* We are here. FIFO is ready to be written. */ - /* Write number of characters to be written */ - writel_i(num_of_chars, MSM_BOOT_UART_DM_NO_CHARS_FOR_TX(base)); - - /* Clear TX_READY interrupt */ - writel_i(MSM_BOOT_UART_DM_GCMD_RES_TX_RDY_INT, - MSM_BOOT_UART_DM_CR(base)); - - /* We use four-character word FIFO. So we need to divide data into - * four characters and write in UART_DM_TF register */ - tx_word_count = (num_of_chars % 4) ? ((num_of_chars / 4) + 1) : - (num_of_chars / 4); - tx_char_left = num_of_chars; - - for (i = 0; i < (int)tx_word_count; i++) { - tx_char = (tx_char_left < 4) ? tx_char_left : 4; - PACK_CHARS_INTO_WORDS(tx_data, tx_char, tx_word); - - /* Wait till TX FIFO has space */ - while (!(readl_i(MSM_BOOT_UART_DM_SR(base)) & - MSM_BOOT_UART_DM_SR_TXRDY)) - udelay(1); - - /* TX FIFO has space. Write the chars */ - writel_i(tx_word, MSM_BOOT_UART_DM_TF(base, 0)); - tx_char_left = num_of_chars - (i + 1) * 4; - tx_data = tx_data + 4; - } + /* + * TX FIFO is ready to accept new character(s). First write number of + * characters to be transmitted. + */ + writel_i(1, MSM_BOOT_UART_DM_NO_CHARS_FOR_TX(base)); - return MSM_BOOT_UART_DM_E_SUCCESS; + /* And now write the character(s) */ + writel_i(data, MSM_BOOT_UART_DM_TF(base, 0)); } /* @@ -419,15 +334,6 @@ uint32_t uartmem_getbaseaddr(void) #endif /** - * uart_tx_byte - transmits a character - * @c: character to transmit - */ -void uart_tx_byte(int idx, unsigned char c) -{ - msm_boot_uart_dm_write(&c, 1); -} - -/** * uart_tx_flush - transmits a string of data * @s: string to transmit */ |