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>
This commit is contained in:
Vadim Bendebury 2014-05-27 18:03:38 -07:00 committed by Marc Jones
parent 0780d67ffe
commit 24a53dddb9
2 changed files with 12 additions and 115 deletions

View File

@ -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);

View File

@ -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;
/* Wait until transmit FIFO is empty. */
while (!(readl_i(MSM_BOOT_UART_DM_SR(base)) &
MSM_BOOT_UART_DM_SR_TXEMT))
udelay(1);
/* 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 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));
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;
}
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