OxPCIe uart: Split PCI bridge control

None of the PCI bridge management here is specific to the PCI UART
device/function. Also the Kconfig variable defaults are not globally
valid, fill samsung/lumpy with working values.

Change-Id: Id22631412379af1d6bf62c996357d36d7ec47ca3
Signed-off-by: Kyösti Mälkki <kyosti.malkki@gmail.com>
Reviewed-on: http://review.coreboot.org/5237
Tested-by: build bot (Jenkins)
Reviewed-by: Alexandru Gagniuc <mr.nuke.me@gmail.com>
This commit is contained in:
Kyösti Mälkki
2014-02-14 12:45:09 +02:00
committed by Patrick Georgi
parent afa7b13b93
commit 4c686f2106
9 changed files with 183 additions and 135 deletions

View File

@@ -1,68 +1,10 @@
config DRIVERS_OXFORD_OXPCIE
bool "Oxford OXPCIe952"
default n
depends on PCI
select DRIVERS_UART_8250MEM
select EARLY_PCI_BRIDGE
help
Support for Oxford OXPCIe952 serial port PCIe cards.
Currently only devices with the vendor ID 0x1415 and device ID
0xc158 will work.
NOTE: Right now you have to set the base address of your OXPCIe952
card to exactly the value that the device allocator would set them
later on, or serial console functionality will stop as soon as the
resource allocator assigns a new base address to the device.
config OXFORD_OXPCIE_BRIDGE_BUS
hex "OXPCIe's PCIe bridge bus number"
default 0x0
depends on DRIVERS_OXFORD_OXPCIE
help
While coreboot is executing code from ROM, the coreboot resource
allocator has not been running yet. Hence PCI devices living behind
a bridge are not yet visible to the system. In order to use an
OXPCIe952 based PCIe card, coreboot has to set up the PCIe bridge
that controls the OXPCIe952 controller first.
config OXFORD_OXPCIE_BRIDGE_DEVICE
hex "OXPCIe's PCIe bridge device number"
default 0x1c
depends on DRIVERS_OXFORD_OXPCIE
help
While coreboot is executing code from ROM, the coreboot resource
allocator has not been running yet. Hence PCI devices living behind
a bridge are not yet visible to the system. In order to use an
OXPCIe952 based PCIe card, coreboot has to set up the PCIe bridge
that controls the OXPCIe952 controller first.
config OXFORD_OXPCIE_BRIDGE_FUNCTION
hex "OXPCIe's PCIe bridge function number"
default 0x2
depends on DRIVERS_OXFORD_OXPCIE
help
While coreboot is executing code from ROM, the coreboot resource
allocator has not been running yet. Hence PCI devices living behind
a bridge are not yet visible to the system. In order to use an
OXPCIe952 based PCIe card, coreboot has to set up the PCIe bridge
that controls the OXPCIe952 controller first.
config OXFORD_OXPCIE_BRIDGE_SUBORDINATE
hex "OXPCIe's PCIe bridge subordinate bus"
default 0x3
depends on DRIVERS_OXFORD_OXPCIE
help
While coreboot is executing code from ROM, the coreboot resource
allocator has not been running yet. Hence PCI devices living behind
a bridge are not yet visible to the system. In order to use an
OXPCIe952 based PCIe card, coreboot has to set up the PCIe bridge
that controls the OXPCIe952 controller first.
config OXFORD_OXPCIE_BASE_ADDRESS
hex "Base address for rom stage console"
default 0xe0400000
depends on DRIVERS_OXFORD_OXPCIE
help
While coreboot is executing code from ROM, the coreboot resource
allocator has not been running yet. Hence PCI devices living behind
a bridge are not yet visible to the system. In order to use an
OXPCIe952 based PCIe card, coreboot has to set up a temporary address
for the OXPCIe952 controller.
0xc158 or 0xc11b will work.

View File

@@ -23,101 +23,53 @@
#include <stddef.h>
#include <arch/io.h>
#include <arch/early_variables.h>
#include <delay.h>
#include <boot/coreboot_tables.h>
#include <console/uart.h>
#include <device/pci.h>
#include <device/pci_def.h>
static unsigned int oxpcie_present CAR_GLOBAL;
static ROMSTAGE_CONST u32 uart0_base = CONFIG_OXFORD_OXPCIE_BASE_ADDRESS + 0x1000;
static ROMSTAGE_CONST u32 uart1_base = CONFIG_OXFORD_OXPCIE_BASE_ADDRESS + 0x2000;
static ROMSTAGE_CONST u32 uart0_base = CONFIG_EARLY_PCI_MMIO_BASE + 0x1000;
static ROMSTAGE_CONST u32 uart1_base = CONFIG_EARLY_PCI_MMIO_BASE + 0x2000;
#define PCIE_BRIDGE \
PCI_DEV(CONFIG_OXFORD_OXPCIE_BRIDGE_BUS, \
CONFIG_OXFORD_OXPCIE_BRIDGE_DEVICE, \
CONFIG_OXFORD_OXPCIE_BRIDGE_FUNCTION)
#define OXPCIE_DEVICE \
PCI_DEV(CONFIG_OXFORD_OXPCIE_BRIDGE_SUBORDINATE, 0, 0)
#define OXPCIE_DEVICE_3 \
PCI_DEV(CONFIG_OXFORD_OXPCIE_BRIDGE_SUBORDINATE, 0, 3)
static void oxpcie_init_bridge(void)
int pci_early_device_probe(u8 bus, u8 dev, u32 mmio_base)
{
u16 reg16;
pci_devfn_t device = PCI_DEV(bus, dev, 0);
/* First we reset the secondary bus */
reg16 = pci_read_config16(PCIE_BRIDGE, PCI_BRIDGE_CONTROL);
reg16 |= (1 << 6); /* SRESET */
pci_write_config16(PCIE_BRIDGE, PCI_BRIDGE_CONTROL, reg16);
/* Assume we don't have to wait here forever */
/* Read back and clear reset bit. */
reg16 = pci_read_config16(PCIE_BRIDGE, PCI_BRIDGE_CONTROL);
reg16 &= ~(1 << 6); /* SRESET */
pci_write_config16(PCIE_BRIDGE, PCI_BRIDGE_CONTROL, reg16);
/* Set up subordinate bus number */
pci_write_config8(PCIE_BRIDGE, PCI_SECONDARY_BUS, 0x00);
pci_write_config8(PCIE_BRIDGE, PCI_SUBORDINATE_BUS, 0x00);
pci_write_config8(PCIE_BRIDGE, PCI_SECONDARY_BUS,
CONFIG_OXFORD_OXPCIE_BRIDGE_SUBORDINATE);
pci_write_config8(PCIE_BRIDGE, PCI_SUBORDINATE_BUS,
CONFIG_OXFORD_OXPCIE_BRIDGE_SUBORDINATE);
/* Memory window for the OXPCIe952 card */
// XXX is the calculation of base and limit correct?
pci_write_config32(PCIE_BRIDGE, PCI_MEMORY_BASE,
((CONFIG_OXFORD_OXPCIE_BASE_ADDRESS & 0xffff0000) |
((CONFIG_OXFORD_OXPCIE_BASE_ADDRESS >> 16) & 0xff00)));
/* Enable memory access through bridge */
reg16 = pci_read_config16(PCIE_BRIDGE, PCI_COMMAND);
reg16 |= PCI_COMMAND_MEMORY;
pci_write_config16(PCIE_BRIDGE, PCI_COMMAND, reg16);
u32 timeout = 20000; // Timeout in 10s of microseconds.
u32 id = 0;
for (;;) {
id = pci_read_config32(OXPCIE_DEVICE, PCI_VENDOR_ID);
if (!timeout-- || (id != 0 && id != 0xffffffff))
break;
udelay(10);
}
u32 device = OXPCIE_DEVICE; /* unknown default */
u32 id = pci_read_config32(device, PCI_VENDOR_ID);
switch (id) {
case 0xc1181415: /* e.g. Startech PEX1S1PMINI */
case 0xc1181415: /* e.g. Startech PEX1S1PMINI function 0 */
/* On this device function 0 is the parallel port, and
* function 3 is the serial port. So let's go look for
* the UART.
*/
id = pci_read_config32(OXPCIE_DEVICE_3, PCI_VENDOR_ID);
device = PCI_DEV(bus, dev, 3);
id = pci_read_config32(device, PCI_VENDOR_ID);
if (id != 0xc11b1415)
return;
device = OXPCIE_DEVICE_3;
return -1;
break;
case 0xc11b1415: /* e.g. Startech PEX1S1PMINI function 3 */
case 0xc1581415: /* e.g. Startech MPEX2S952 */
device = OXPCIE_DEVICE;
break;
default:
/* No UART here. */
return;
return -1;
}
/* Sanity-check, we assume fixed location. */
if (mmio_base != CONFIG_EARLY_PCI_MMIO_BASE)
return -1;
/* Setup base address on device */
pci_write_config32(device, PCI_BASE_ADDRESS_0,
CONFIG_OXFORD_OXPCIE_BASE_ADDRESS);
pci_write_config32(device, PCI_BASE_ADDRESS_0, mmio_base);
/* Enable memory on device */
reg16 = pci_read_config16(device, PCI_COMMAND);
u16 reg16 = pci_read_config16(device, PCI_COMMAND);
reg16 |= PCI_COMMAND_MEMORY;
pci_write_config16(device, PCI_COMMAND, reg16);
car_set_var(oxpcie_present, 1);
return 0;
}
static int oxpcie_uart_active(void)
@@ -157,8 +109,3 @@ unsigned int uart_platform_refclk(void)
{
return 62500000;
}
void oxford_init(void)
{
oxpcie_init_bridge();
}