diff options
Diffstat (limited to 'arch/x86/cpu/quark')
-rw-r--r-- | arch/x86/cpu/quark/quark.c | 63 |
1 files changed, 63 insertions, 0 deletions
diff --git a/arch/x86/cpu/quark/quark.c b/arch/x86/cpu/quark/quark.c index 2688a707a7..7c55d9e5cd 100644 --- a/arch/x86/cpu/quark/quark.c +++ b/arch/x86/cpu/quark/quark.c @@ -73,6 +73,58 @@ static void quark_setup_bars(void) CONFIG_PCIE_ECAM_BASE | MEM_BAR_EN); } +static void quark_pcie_early_init(void) +{ + u32 pcie_cfg; + + /* + * Step1: Assert PCIe signal PERST# + * + * The CPU interface to the PERST# signal is platform dependent. + * Call the board-specific codes to perform this task. + */ + board_assert_perst(); + + /* Step2: PHY common lane reset */ + pcie_cfg = msg_port_alt_read(MSG_PORT_SOC_UNIT, PCIE_CFG); + pcie_cfg |= PCIE_PHY_LANE_RST; + msg_port_alt_write(MSG_PORT_SOC_UNIT, PCIE_CFG, pcie_cfg); + /* wait 1 ms for PHY common lane reset */ + mdelay(1); + + /* Step3: PHY sideband interface reset and controller main reset */ + pcie_cfg = msg_port_alt_read(MSG_PORT_SOC_UNIT, PCIE_CFG); + pcie_cfg |= (PCIE_PHY_SB_RST | PCIE_CTLR_MAIN_RST); + msg_port_alt_write(MSG_PORT_SOC_UNIT, PCIE_CFG, pcie_cfg); + /* wait 80ms for PLL to lock */ + mdelay(80); + + /* Step4: Controller sideband interface reset */ + pcie_cfg = msg_port_alt_read(MSG_PORT_SOC_UNIT, PCIE_CFG); + pcie_cfg |= PCIE_CTLR_SB_RST; + msg_port_alt_write(MSG_PORT_SOC_UNIT, PCIE_CFG, pcie_cfg); + /* wait 20ms for controller sideband interface reset */ + mdelay(20); + + /* Step5: De-assert PERST# */ + board_deassert_perst(); + + /* Step6: Controller primary interface reset */ + pcie_cfg = msg_port_alt_read(MSG_PORT_SOC_UNIT, PCIE_CFG); + pcie_cfg |= PCIE_CTLR_PRI_RST; + msg_port_alt_write(MSG_PORT_SOC_UNIT, PCIE_CFG, pcie_cfg); + + /* Mixer Load Lane 0 */ + pcie_cfg = msg_port_io_read(MSG_PORT_PCIE_AFE, PCIE_RXPICTRL0_L0); + pcie_cfg &= ~((1 << 6) | (1 << 7)); + msg_port_io_write(MSG_PORT_PCIE_AFE, PCIE_RXPICTRL0_L0, pcie_cfg); + + /* Mixer Load Lane 1 */ + pcie_cfg = msg_port_io_read(MSG_PORT_PCIE_AFE, PCIE_RXPICTRL0_L1); + pcie_cfg &= ~((1 << 6) | (1 << 7)); + msg_port_io_write(MSG_PORT_PCIE_AFE, PCIE_RXPICTRL0_L1, pcie_cfg); +} + static void quark_enable_legacy_seg(void) { u32 hmisc2; @@ -106,6 +158,17 @@ int arch_cpu_init(void) */ quark_setup_bars(); + /* + * Initialize PCIe controller + * + * Quark SoC holds the PCIe controller in reset following a power on. + * U-Boot needs to release the PCIe controller from reset. The PCIe + * controller (D23:F0/F1) will not be visible in PCI configuration + * space and any access to its PCI configuration registers will cause + * system hang while it is held in reset. + */ + quark_pcie_early_init(); + /* Turn on legacy segments (A/B/E/F) decode to system RAM */ quark_enable_legacy_seg(); |