amd/stoneyridge: Create new wide IO functions
Create new generic wide IO functions in southbridge.c. These new functions must be usable by kahlee/ec.c and amd/stoneyridge/lpc.c. BUG=b:64033893 TEST=Just build at this stage, full boot to OS and verify serial output at related change 14fdd03a83. Some extra outputs for testing removed when code was committed. Change-Id: Icd0841a1959f3e109b3c35fa35bb4b3c44099dc3 Signed-off-by: Richard Spiegel <richard.spiegel@silverbackltd.com> Reviewed-on: https://review.coreboot.org/22590 Tested-by: build bot (Jenkins) <no-reply@coreboot.org> Reviewed-by: Martin Roth <martinroth@google.com>
This commit is contained in:
parent
903472c3c8
commit
ebf3aa8c63
|
@ -290,6 +290,9 @@
|
|||
#define OC_PORT2_SHIFT 8
|
||||
#define OC_PORT3_SHIFT 12
|
||||
|
||||
#define WIDEIO_RANGE_ERROR -1
|
||||
#define TOTAL_WIDEIO_PORTS 3
|
||||
|
||||
static inline int sb_sata_enable(void)
|
||||
{
|
||||
/* True if IDE or AHCI. */
|
||||
|
@ -343,6 +346,32 @@ uint32_t xhci_pm_read32(uint8_t reg);
|
|||
int s3_load_nvram_early(int size, u32 *old_dword, int nvram_pos);
|
||||
int s3_save_nvram_early(u32 dword, int size, int nvram_pos);
|
||||
void bootblock_fch_early_init(void);
|
||||
/**
|
||||
* @brief Find the size of a particular wide IO
|
||||
*
|
||||
* @param index = index of desired wide IO
|
||||
*
|
||||
* @return size of desired wide IO
|
||||
*/
|
||||
uint16_t sb_wideio_size(int index);
|
||||
/**
|
||||
* @brief Identify if any LPC wide IO is covering the IO range
|
||||
*
|
||||
* @param start = start of IO range
|
||||
* @param size = size of IO range
|
||||
*
|
||||
* @return Index of wide IO covering the range or error
|
||||
*/
|
||||
int sb_find_wideio_range(uint16_t start, uint16_t size);
|
||||
/**
|
||||
* @brief Program a LPC wide IO to support an IO range
|
||||
*
|
||||
* @param start = start of range to be routed through wide IO
|
||||
* @param size = size of range to be routed through wide IO
|
||||
*
|
||||
* @return Index of wide IO register used or error
|
||||
*/
|
||||
int sb_set_wideio_range(uint16_t start, uint16_t size);
|
||||
|
||||
/*
|
||||
* Call the mainboard to get the USB Over Current Map. The mainboard
|
||||
|
|
|
@ -82,12 +82,133 @@ const static struct irq_idx_name irq_association[] = {
|
|||
{ PIRQ_UART1, "UART1\t" },
|
||||
};
|
||||
|
||||
/*
|
||||
* Structure to simplify code obtaining the total of used wide IO
|
||||
* registers and the size assigned to each.
|
||||
*/
|
||||
static struct wide_io_ioport_and_bits {
|
||||
uint32_t enable;
|
||||
uint16_t port;
|
||||
uint8_t alt;
|
||||
} wio_io_en[TOTAL_WIDEIO_PORTS] = {
|
||||
{
|
||||
LPC_WIDEIO0_ENABLE,
|
||||
LPC_WIDEIO_GENERIC_PORT,
|
||||
LPC_ALT_WIDEIO0_ENABLE
|
||||
},
|
||||
{
|
||||
LPC_WIDEIO1_ENABLE,
|
||||
LPC_WIDEIO1_GENERIC_PORT,
|
||||
LPC_ALT_WIDEIO1_ENABLE
|
||||
},
|
||||
{
|
||||
LPC_WIDEIO2_ENABLE,
|
||||
LPC_WIDEIO2_GENERIC_PORT,
|
||||
LPC_ALT_WIDEIO2_ENABLE
|
||||
}
|
||||
};
|
||||
|
||||
const struct irq_idx_name *sb_get_apic_reg_association(size_t *size)
|
||||
{
|
||||
*size = ARRAY_SIZE(irq_association);
|
||||
return irq_association;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Find the size of a particular wide IO
|
||||
*
|
||||
* @param index = index of desired wide IO
|
||||
*
|
||||
* @return size of desired wide IO
|
||||
*/
|
||||
uint16_t sb_wideio_size(int index)
|
||||
{
|
||||
uint32_t enable_register;
|
||||
uint16_t size = 0;
|
||||
uint8_t alternate_register;
|
||||
|
||||
if (index >= TOTAL_WIDEIO_PORTS)
|
||||
return size;
|
||||
enable_register = pci_read_config32(SOC_LPC_DEV,
|
||||
LPC_IO_OR_MEM_DECODE_ENABLE);
|
||||
alternate_register = pci_read_config8(SOC_LPC_DEV,
|
||||
LPC_ALT_WIDEIO_RANGE_ENABLE);
|
||||
if (enable_register & wio_io_en[index].enable)
|
||||
size = (alternate_register & wio_io_en[index].alt) ?
|
||||
16 : 512;
|
||||
return size;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Identify if any LPC wide IO is covering the IO range
|
||||
*
|
||||
* @param start = start of IO range
|
||||
* @param size = size of IO range
|
||||
*
|
||||
* @return Index of wide IO covering the range or error
|
||||
*/
|
||||
int sb_find_wideio_range(uint16_t start, uint16_t size)
|
||||
{
|
||||
uint32_t enable_register;
|
||||
int i, index = WIDEIO_RANGE_ERROR;
|
||||
uint16_t end, current_size, start_wideio, end_wideio;
|
||||
|
||||
end = start + size;
|
||||
enable_register = pci_read_config32(SOC_LPC_DEV,
|
||||
LPC_IO_OR_MEM_DECODE_ENABLE);
|
||||
for (i = 0; i < TOTAL_WIDEIO_PORTS; i++) {
|
||||
current_size = sb_wideio_size(i);
|
||||
if (current_size == 0)
|
||||
continue;
|
||||
start_wideio = pci_read_config16(SOC_LPC_DEV,
|
||||
wio_io_en[i].port);
|
||||
end_wideio = start_wideio + current_size;
|
||||
if ((start >= start_wideio) && (end <= end_wideio)) {
|
||||
index = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return index;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Program a LPC wide IO to support an IO range
|
||||
*
|
||||
* @param start = start of range to be routed through wide IO
|
||||
* @param size = size of range to be routed through wide IO
|
||||
*
|
||||
* @return Index of wide IO register used or error
|
||||
*/
|
||||
int sb_set_wideio_range(uint16_t start, uint16_t size)
|
||||
{
|
||||
int i, index = WIDEIO_RANGE_ERROR;
|
||||
uint32_t enable_register;
|
||||
uint8_t alternate_register;
|
||||
|
||||
enable_register = pci_read_config32(SOC_LPC_DEV,
|
||||
LPC_IO_OR_MEM_DECODE_ENABLE);
|
||||
alternate_register = pci_read_config8(SOC_LPC_DEV,
|
||||
LPC_ALT_WIDEIO_RANGE_ENABLE);
|
||||
for (i = 0; i < TOTAL_WIDEIO_PORTS; i++) {
|
||||
if (enable_register & wio_io_en[i].enable)
|
||||
continue;
|
||||
index = i;
|
||||
pci_write_config16(SOC_LPC_DEV, wio_io_en[i].port, start);
|
||||
enable_register |= wio_io_en[i].enable;
|
||||
pci_write_config32(SOC_LPC_DEV, LPC_IO_OR_MEM_DECODE_ENABLE,
|
||||
enable_register);
|
||||
if (size <= 16)
|
||||
alternate_register |= wio_io_en[i].alt;
|
||||
else
|
||||
alternate_register &= ~wio_io_en[i].alt;
|
||||
pci_write_config8(SOC_LPC_DEV,
|
||||
LPC_ALT_WIDEIO_RANGE_ENABLE,
|
||||
alternate_register);
|
||||
break;
|
||||
}
|
||||
return index;
|
||||
}
|
||||
|
||||
void configure_stoneyridge_uart(void)
|
||||
{
|
||||
u8 byte, byte2;
|
||||
|
|
Loading…
Reference in New Issue