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:
committed by
Patrick Georgi
parent
afa7b13b93
commit
4c686f2106
@@ -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.
|
||||
|
@@ -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();
|
||||
}
|
||||
|
Reference in New Issue
Block a user