From 24a53dddb9b0b545ab9208722ff7b684114b4e91 Mon Sep 17 00:00:00 2001 From: Vadim Bendebury Date: Tue, 27 May 2014 18:03:38 -0700 Subject: ipq806x: clean up UART driver tx_byte function MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 Original-Reviewed-on: https://chromium-review.googlesource.com/201782 Original-Reviewed-by: Stefan Reinauer Original-Reviewed-by: Trevor Bourget (cherry picked from commit eab3dc9d30c7e8355a2563e18ada78e4070e6151) Signed-off-by: Marc Jones Change-Id: I4274b8f7188bf9636906b39bcd9ec7adf0e1222e Signed-off-by: Kyösti Mälkki Reviewed-on: http://review.coreboot.org/8011 Tested-by: build bot (Jenkins) Reviewed-by: Marc Jones --- src/soc/qualcomm/ipq806x/uart.c | 118 ++++------------------------------------ 1 file changed, 12 insertions(+), 106 deletions(-) (limited to 'src/soc/qualcomm/ipq806x/uart.c') 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)); } /* @@ -418,15 +333,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 -- cgit v1.2.3