summaryrefslogtreecommitdiffstats
path: root/arch/x86/cpu/quark/quark.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/x86/cpu/quark/quark.c')
-rw-r--r--arch/x86/cpu/quark/quark.c63
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();
OpenPOWER on IntegriCloud