Marc Jones (marc.jones@se-eng.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/8011
-gerrit
commit 427c4ceb05389384d311af6a5add84c9eac75fb8 Author: Vadim Bendebury vbendeb@chromium.org Date: Tue May 27 18:03:38 2014 -0700
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.
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 --- src/soc/qualcomm/ipq806x/include/ipq_uart.h | 9 --- src/soc/qualcomm/ipq806x/uart.c | 121 +++++----------------------- 2 files changed, 18 insertions(+), 112 deletions(-)
diff --git a/src/soc/qualcomm/ipq806x/include/ipq_uart.h b/src/soc/qualcomm/ipq806x/include/ipq_uart.h index da943b9..90ca704 100644 --- a/src/soc/qualcomm/ipq806x/include/ipq_uart.h +++ b/src/soc/qualcomm/ipq806x/include/ipq_uart.h @@ -38,15 +38,6 @@ ((value << (32 - end_pos))\ >> (32 - (end_pos - start_pos)))
- -#define PACK_CHARS_INTO_WORDS(a, cnt, word) { \ - word = 0; \ - int j; \ - for(j=0; j < (int)cnt; j++) { \ - word |= (a[j] & 0xff)<< (j * 8);\ - } \ - } - extern void __udelay(unsigned long usec);
diff --git a/src/soc/qualcomm/ipq806x/uart.c b/src/soc/qualcomm/ipq806x/uart.c index f7b5d02..e09bd0f 100644 --- a/src/soc/qualcomm/ipq806x/uart.c +++ b/src/soc/qualcomm/ipq806x/uart.c @@ -192,108 +192,32 @@ 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]; + int num_of_chars = 1; + unsigned tx_data = 0; 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); - - 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); + /* Add CR to every LF. */ + if (data == '\n') { + num_of_chars++; + tx_data = '\r' | ('\n' << 8); + } else { + tx_data = data; }
- /* 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 */ + /* Wait until transmit FIFO is empty. */ while (!(readl_i(MSM_BOOT_UART_DM_SR(base)) & - MSM_BOOT_UART_DM_SR_TXRDY)) + MSM_BOOT_UART_DM_SR_TXEMT)) udelay(1); + /* + * TX FIFO is ready to accept new character(s). First write number of + * characters to be transmitted. + */ + writel_i(num_of_chars, MSM_BOOT_UART_DM_NO_CHARS_FOR_TX(base));
- /* 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; - } - - return MSM_BOOT_UART_DM_E_SUCCESS; + /* And now write the character(s) */ + writel_i(tx_data, MSM_BOOT_UART_DM_TF(base, 0)); }
/* @@ -419,15 +343,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 */