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:
parent
0780d67ffe
commit
24a53dddb9
|
@ -38,15 +38,6 @@
|
||||||
((value << (32 - end_pos))\
|
((value << (32 - end_pos))\
|
||||||
>> (32 - (end_pos - start_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);
|
extern void __udelay(unsigned long usec);
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -192,108 +192,23 @@ msm_boot_uart_dm_read(unsigned int *data, int *count, int wait)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
void uart_tx_byte(int idx, unsigned char data)
|
||||||
* 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)
|
|
||||||
{
|
{
|
||||||
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;
|
unsigned int base = uart_board_param.uart_dm_base;
|
||||||
|
|
||||||
if ((data == NULL) || (num_of_chars <= 0))
|
/* Wait until transmit FIFO is empty. */
|
||||||
return MSM_BOOT_UART_DM_E_INVAL;
|
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;
|
/* And now write the character(s) */
|
||||||
num_of_chars = i;
|
writel_i(data, MSM_BOOT_UART_DM_TF(base, 0));
|
||||||
|
|
||||||
/* 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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -418,15 +333,6 @@ uint32_t uartmem_getbaseaddr(void)
|
||||||
}
|
}
|
||||||
#endif
|
#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
|
* uart_tx_flush - transmits a string of data
|
||||||
* @s: string to transmit
|
* @s: string to transmit
|
||||||
|
|
Loading…
Reference in New Issue