drivers/uart: Use uart_platform_refclk for all UART models

Allow the platform to override the input clock for the UART by
implementing the routine uart_platform_refclk and setting the Kconfig
value UART_OVERRIDE_REFCLK.  Provide a default uart_platform_refclk
routine which is disabled when UART_OVERRIDE_REFCLK is selected.  This
works around ROMCC not supporting weak routines.

Testing on Galileo:
*  Edit the src/mainboard/intel/galileo/Makefile.inc file:
   *  Add "select ADD_FSP_PDAT_FILE"
   *  Add "select ADD_FSP_RAW_BIN"
   *  Add "select ADD_RMU_FILE"
*  Place the FSP.bin file in the location specified by CONFIG_FSP_FILE
*  Place the pdat.bin files in the location specified by
   CONFIG_FSP_PDAT_FILE
*  Place the rmu.bin file in the location specified by CONFIG_RMU_FILE
*  Build EDK2 CorebootPayloadPkg/CorebootPayloadPkgIa32.dsc to generate
   UEFIPAYLOAD.fd
*  Testing is successful when CorebootPayloadPkg is able to properly
   initialize the serial port without using built-in values.

Change-Id: If4afc45a828e5ba935fecb6d95b239625e912d14
Signed-off-by: Lee Leahy <leroy.p.leahy@intel.com>
Reviewed-on: https://review.coreboot.org/14612
Tested-by: build bot (Jenkins)
Reviewed-by: Martin Roth <martinroth@google.com>
This commit is contained in:
Lee Leahy 2016-05-07 09:04:46 -07:00 committed by Leroy P Leahy
parent 148762110c
commit 6ec72c9b4f
17 changed files with 38 additions and 44 deletions

View File

@ -13,5 +13,6 @@ config CPU_SPECIFIC_OPTIONS
select HAVE_MONOTONIC_TIMER select HAVE_MONOTONIC_TIMER
select HAVE_UART_SPECIAL select HAVE_UART_SPECIAL
select BOOTBLOCK_CONSOLE select BOOTBLOCK_CONSOLE
select UART_OVERRIDE_REFCLK
endif # if CPU_ALLWINNER_A10 endif # if CPU_ALLWINNER_A10

View File

@ -7,5 +7,6 @@ config CPU_TI_AM335X
select HAVE_UART_SPECIAL select HAVE_UART_SPECIAL
select BOOTBLOCK_CONSOLE select BOOTBLOCK_CONSOLE
select GENERIC_UDELAY select GENERIC_UDELAY
select UART_OVERRIDE_REFCLK
bool bool
default n default n

View File

@ -20,6 +20,13 @@ config UART_OVERRIDE_INPUT_CLOCK_DIVIDER
Set to "y" when the platform overrides the uart_input_clock_divider Set to "y" when the platform overrides the uart_input_clock_divider
routine. routine.
config UART_OVERRIDE_REFCLK
boolean
default n
help
Set to "y" when the platform overrides the uart_platform_refclk
routine.
config DRIVERS_UART_8250MEM config DRIVERS_UART_8250MEM
bool bool
default n default n
@ -39,6 +46,7 @@ config DRIVERS_UART_OXPCIE
depends on PCI depends on PCI
select DRIVERS_UART_8250MEM select DRIVERS_UART_8250MEM
select EARLY_PCI_BRIDGE select EARLY_PCI_BRIDGE
select UART_OVERRIDE_REFCLK
help help
Support for Oxford OXPCIe952 serial port PCIe cards. Support for Oxford OXPCIe952 serial port PCIe cards.
Currently only devices with the vendor ID 0x1415 and device ID Currently only devices with the vendor ID 0x1415 and device ID

View File

@ -92,10 +92,7 @@ void uart_fill_lb(void *data)
serial.baseaddr = uart_platform_base(CONFIG_UART_FOR_CONSOLE); serial.baseaddr = uart_platform_base(CONFIG_UART_FOR_CONSOLE);
serial.baud = default_baudrate(); serial.baud = default_baudrate();
serial.regwidth = 1; serial.regwidth = 1;
if (IS_ENABLED(CONFIG_UART_USE_REFCLK_AS_INPUT_CLOCK)) serial.input_hertz = uart_platform_refclk();
serial.input_hertz = uart_platform_refclk();
else
serial.input_hertz = 0;
serial.uart_pci_addr = CONFIG_UART_PCI_ADDR; serial.uart_pci_addr = CONFIG_UART_PCI_ADDR;
lb_add_serial(&serial, data); lb_add_serial(&serial, data);

View File

@ -48,10 +48,7 @@ void uart_fill_lb(void *data)
serial.baseaddr = uart_platform_base(CONFIG_UART_FOR_CONSOLE); serial.baseaddr = uart_platform_base(CONFIG_UART_FOR_CONSOLE);
serial.baud = default_baudrate(); serial.baud = default_baudrate();
serial.regwidth = 1; serial.regwidth = 1;
if (IS_ENABLED(CONFIG_UART_USE_REFCLK_AS_INPUT_CLOCK)) serial.input_hertz = uart_platform_refclk();
serial.input_hertz = uart_platform_refclk();
else
serial.input_hertz = 0;
serial.uart_pci_addr = CONFIG_UART_PCI_ADDR; serial.uart_pci_addr = CONFIG_UART_PCI_ADDR;
lb_add_serial(&serial, data); lb_add_serial(&serial, data);

View File

@ -27,16 +27,6 @@
/* Should support 8250, 16450, 16550, 16550A type UARTs */ /* Should support 8250, 16450, 16550, 16550A type UARTs */
/* Nominal values only, good for the range of choices Kconfig offers for
* set of standard baudrates.
*/
/* Multiply the maximim baud-rate by the default oversample rate to compute
* the default input clock to the UART. The uart_baudrate_divisor divides
* by the oversample clock to determine the final baud-rate.
*/
#define BAUDRATE_REFCLK (115200 * 16)
/* Expected character delay at 1200bps is 9ms for a working UART /* Expected character delay at 1200bps is 9ms for a working UART
* and no flow-control. Assume UART as stuck if shift register * and no flow-control. Assume UART as stuck if shift register
* or FIFO takes more than 50ms per character to appear empty. * or FIFO takes more than 50ms per character to appear empty.
@ -115,7 +105,7 @@ uintptr_t uart_platform_base(int idx)
void uart_init(int idx) void uart_init(int idx)
{ {
unsigned int div; unsigned int div;
div = uart_baudrate_divisor(default_baudrate(), BAUDRATE_REFCLK, div = uart_baudrate_divisor(default_baudrate(), uart_platform_refclk(),
uart_input_clock_divider()); uart_input_clock_divider());
uart8250_init(uart_platform_base(idx), div); uart8250_init(uart_platform_base(idx), div);
} }
@ -143,10 +133,7 @@ void uart_fill_lb(void *data)
serial.baseaddr = uart_platform_base(CONFIG_UART_FOR_CONSOLE); serial.baseaddr = uart_platform_base(CONFIG_UART_FOR_CONSOLE);
serial.baud = default_baudrate(); serial.baud = default_baudrate();
serial.regwidth = 1; serial.regwidth = 1;
if (IS_ENABLED(CONFIG_UART_USE_REFCLK_AS_INPUT_CLOCK)) serial.input_hertz = uart_platform_refclk();
serial.input_hertz = uart_platform_refclk();
else
serial.input_hertz = 0;
serial.uart_pci_addr = CONFIG_UART_PCI_ADDR; serial.uart_pci_addr = CONFIG_UART_PCI_ADDR;
lb_add_serial(&serial, data); lb_add_serial(&serial, data);

View File

@ -157,10 +157,7 @@ void uart_fill_lb(void *data)
serial.regwidth = sizeof(uint32_t); serial.regwidth = sizeof(uint32_t);
else else
serial.regwidth = sizeof(uint8_t); serial.regwidth = sizeof(uint8_t);
if (IS_ENABLED(CONFIG_UART_USE_REFCLK_AS_INPUT_CLOCK)) serial.input_hertz = uart_platform_refclk();
serial.input_hertz = uart_platform_refclk();
else
serial.input_hertz = 0;
serial.uart_pci_addr = CONFIG_UART_PCI_ADDR; serial.uart_pci_addr = CONFIG_UART_PCI_ADDR;
lb_add_serial(&serial, data); lb_add_serial(&serial, data);

View File

@ -59,3 +59,19 @@ unsigned int uart_input_clock_divider(void)
return 16; return 16;
} }
#endif #endif
#if !IS_ENABLED(CONFIG_UART_OVERRIDE_REFCLK)
unsigned int uart_platform_refclk(void)
{
/* Specify the default input clock frequency for the UART.
*
* The older UART's used an input clock frequency of 1.8432 MHz which
* with the 16x oversampling provided the maximum baud-rate of 115200.
* Specify this as maximum baud-rate multiplied by oversample so that
* it is obvious that the maximum baud rate is 115200 when divided by
* oversample clock. Also note that crystal on the board does not
* change when software selects another input clock divider.
*/
return 115200 * 16;
}
#endif

View File

@ -25,6 +25,7 @@ config CPU_IMGTEC_PISTACHIO
select SPI_ATOMIC_SEQUENCING select SPI_ATOMIC_SEQUENCING
select GENERIC_GPIO_LIB select GENERIC_GPIO_LIB
select HAVE_HARD_RESET select HAVE_HARD_RESET
select UART_OVERRIDE_REFCLK
bool bool
if CPU_IMGTEC_PISTACHIO if CPU_IMGTEC_PISTACHIO

View File

@ -68,12 +68,6 @@ uintptr_t uart_platform_base(int idx)
return (CONFIG_CONSOLE_UART_BASE_ADDRESS); return (CONFIG_CONSOLE_UART_BASE_ADDRESS);
} }
unsigned int uart_platform_refclk(void)
{
/* That's within 0.5% of the actual value we've set earlier */
return 115200 * 16;
}
static const struct pad_config uart_gpios[] = { static const struct pad_config uart_gpios[] = {
PAD_CFG_NF(GPIO_42, NATIVE, DEEP, NF1), /* UART1 RX */ PAD_CFG_NF(GPIO_42, NATIVE, DEEP, NF1), /* UART1 RX */
PAD_CFG_NF(GPIO_43, NATIVE, DEEP, NF1), /* UART1 TX */ PAD_CFG_NF(GPIO_43, NATIVE, DEEP, NF1), /* UART1 TX */

View File

@ -30,6 +30,7 @@ config CPU_SPECIFIC_OPTIONS
select SOC_INTEL_COMMON select SOC_INTEL_COMMON
select SOC_SETS_MTRRS select SOC_SETS_MTRRS
select TSC_CONSTANT_RATE select TSC_CONSTANT_RATE
select UART_OVERRIDE_REFCLK
select UDELAY_TSC select UDELAY_TSC
select UNCOMPRESSED_RAMSTAGE select UNCOMPRESSED_RAMSTAGE
select USE_MARCH_586 select USE_MARCH_586

View File

@ -18,17 +18,6 @@
#include <soc/iomap.h> #include <soc/iomap.h>
#include <soc/serialio.h> #include <soc/serialio.h>
unsigned int uart_platform_refclk(void)
{
/*
* Set M and N divisor inputs and enable clock.
* Main reference frequency to UART is:
* 120MHz * M / N = 120MHz * 48 / 3125 = 1843200Hz
* The different order below is to handle integer math overflow.
*/
return 120 * MHz / SIO_REG_PPR_CLOCK_N_DIV * SIO_REG_PPR_CLOCK_M_DIV;
}
uintptr_t uart_platform_base(int idx) uintptr_t uart_platform_base(int idx)
{ {
/* Same base address for all debug port usage. In reality UART2 /* Same base address for all debug port usage. In reality UART2

View File

@ -10,6 +10,7 @@ config SOC_MARVELL_ARMADA38X
select RETURN_FROM_VERSTAGE select RETURN_FROM_VERSTAGE
select BOOTBLOCK_CUSTOM select BOOTBLOCK_CUSTOM
select GENERIC_UDELAY select GENERIC_UDELAY
select UART_OVERRIDE_REFCLK
if SOC_MARVELL_ARMADA38X if SOC_MARVELL_ARMADA38X

View File

@ -13,6 +13,7 @@ config SOC_NVIDIA_TEGRA132
select HAVE_HARD_RESET select HAVE_HARD_RESET
select HAVE_UART_SPECIAL select HAVE_UART_SPECIAL
select GENERIC_GPIO_LIB select GENERIC_GPIO_LIB
select UART_OVERRIDE_REFCLK
if SOC_NVIDIA_TEGRA132 if SOC_NVIDIA_TEGRA132

View File

@ -27,6 +27,7 @@ config SOC_ROCKCHIP_RK3288
select UNCOMPRESSED_RAMSTAGE select UNCOMPRESSED_RAMSTAGE
select GENERIC_GPIO_LIB select GENERIC_GPIO_LIB
select RTC select RTC
select UART_OVERRIDE_REFCLK
if SOC_ROCKCHIP_RK3288 if SOC_ROCKCHIP_RK3288

View File

@ -12,6 +12,7 @@ config SOC_ROCKCHIP_RK3399
select GENERIC_UDELAY select GENERIC_UDELAY
select HAVE_MONOTONIC_TIMER select HAVE_MONOTONIC_TIMER
select UNCOMPRESSED_RAMSTAGE select UNCOMPRESSED_RAMSTAGE
select UART_OVERRIDE_REFCLK
if SOC_ROCKCHIP_RK3399 if SOC_ROCKCHIP_RK3399

View File

@ -235,6 +235,7 @@ config HUDSON_UART
select DRIVERS_UART_8250MEM select DRIVERS_UART_8250MEM
select DRIVERS_UART_8250MEM_32 select DRIVERS_UART_8250MEM_32
select NO_UART_ON_SUPERIO select NO_UART_ON_SUPERIO
select UART_OVERRIDE_REFCLK
help help
There are two UART controllers in Kern. There are two UART controllers in Kern.
The UART registers are memory-mapped. UART The UART registers are memory-mapped. UART