diff options
Diffstat (limited to 'arch')
-rw-r--r-- | arch/sandbox/dts/test.dts | 7 | ||||
-rw-r--r-- | arch/x86/cpu/coreboot/coreboot.c | 6 | ||||
-rw-r--r-- | arch/x86/cpu/quark/Makefile | 1 | ||||
-rw-r--r-- | arch/x86/cpu/quark/msg_port.c | 44 | ||||
-rw-r--r-- | arch/x86/cpu/quark/pci.c | 70 | ||||
-rw-r--r-- | arch/x86/cpu/quark/quark.c | 139 | ||||
-rw-r--r-- | arch/x86/dts/chromebox_panther.dts | 10 | ||||
-rw-r--r-- | arch/x86/dts/galileo.dts | 8 | ||||
-rw-r--r-- | arch/x86/include/asm/arch-quark/quark.h | 85 |
9 files changed, 249 insertions, 121 deletions
diff --git a/arch/sandbox/dts/test.dts b/arch/sandbox/dts/test.dts index c948df8c86..f5217fb877 100644 --- a/arch/sandbox/dts/test.dts +++ b/arch/sandbox/dts/test.dts @@ -9,6 +9,7 @@ aliases { console = &uart0; eth0 = "/eth@10002000"; + eth3 = ð_3; eth5 = ð_5; i2c0 = "/i2c@0"; pci0 = &pci; @@ -121,6 +122,12 @@ fake-host-hwaddr = <0x00 0x00 0x66 0x44 0x22 0x11>; }; + eth_3: sbe5 { + compatible = "sandbox,eth"; + reg = <0x10005000 0x1000>; + fake-host-hwaddr = <0x00 0x00 0x66 0x44 0x22 0x33>; + }; + eth@10004000 { compatible = "sandbox,eth"; reg = <0x10004000 0x1000>; diff --git a/arch/x86/cpu/coreboot/coreboot.c b/arch/x86/cpu/coreboot/coreboot.c index 0e9f15fef6..845f86a176 100644 --- a/arch/x86/cpu/coreboot/coreboot.c +++ b/arch/x86/cpu/coreboot/coreboot.c @@ -8,7 +8,6 @@ #include <common.h> #include <fdtdec.h> -#include <netdev.h> #include <asm/io.h> #include <asm/msr.h> #include <asm/mtrr.h> @@ -48,11 +47,6 @@ int last_stage_init(void) return 0; } -int board_eth_init(bd_t *bis) -{ - return pci_eth_init(bis); -} - void board_final_cleanup(void) { /* diff --git a/arch/x86/cpu/quark/Makefile b/arch/x86/cpu/quark/Makefile index e87b4248e6..8f1d018fb6 100644 --- a/arch/x86/cpu/quark/Makefile +++ b/arch/x86/cpu/quark/Makefile @@ -6,4 +6,3 @@ obj-y += car.o dram.o msg_port.o quark.o obj-y += mrc.o mrc_util.o hte.o smc.o -obj-$(CONFIG_PCI) += pci.o diff --git a/arch/x86/cpu/quark/msg_port.c b/arch/x86/cpu/quark/msg_port.c index 31713e321f..cf828f21c0 100644 --- a/arch/x86/cpu/quark/msg_port.c +++ b/arch/x86/cpu/quark/msg_port.c @@ -5,34 +5,34 @@ */ #include <common.h> -#include <pci.h> #include <asm/arch/device.h> #include <asm/arch/msg_port.h> +#include <asm/arch/quark.h> void msg_port_setup(int op, int port, int reg) { - pci_write_config_dword(QUARK_HOST_BRIDGE, MSG_CTRL_REG, - (((op) << 24) | ((port) << 16) | - (((reg) << 8) & 0xff00) | MSG_BYTE_ENABLE)); + qrk_pci_write_config_dword(QUARK_HOST_BRIDGE, MSG_CTRL_REG, + (((op) << 24) | ((port) << 16) | + (((reg) << 8) & 0xff00) | MSG_BYTE_ENABLE)); } u32 msg_port_read(u8 port, u32 reg) { u32 value; - pci_write_config_dword(QUARK_HOST_BRIDGE, MSG_CTRL_EXT_REG, - reg & 0xffffff00); + qrk_pci_write_config_dword(QUARK_HOST_BRIDGE, MSG_CTRL_EXT_REG, + reg & 0xffffff00); msg_port_setup(MSG_OP_READ, port, reg); - pci_read_config_dword(QUARK_HOST_BRIDGE, MSG_DATA_REG, &value); + qrk_pci_read_config_dword(QUARK_HOST_BRIDGE, MSG_DATA_REG, &value); return value; } void msg_port_write(u8 port, u32 reg, u32 value) { - pci_write_config_dword(QUARK_HOST_BRIDGE, MSG_DATA_REG, value); - pci_write_config_dword(QUARK_HOST_BRIDGE, MSG_CTRL_EXT_REG, - reg & 0xffffff00); + qrk_pci_write_config_dword(QUARK_HOST_BRIDGE, MSG_DATA_REG, value); + qrk_pci_write_config_dword(QUARK_HOST_BRIDGE, MSG_CTRL_EXT_REG, + reg & 0xffffff00); msg_port_setup(MSG_OP_WRITE, port, reg); } @@ -40,19 +40,19 @@ u32 msg_port_alt_read(u8 port, u32 reg) { u32 value; - pci_write_config_dword(QUARK_HOST_BRIDGE, MSG_CTRL_EXT_REG, - reg & 0xffffff00); + qrk_pci_write_config_dword(QUARK_HOST_BRIDGE, MSG_CTRL_EXT_REG, + reg & 0xffffff00); msg_port_setup(MSG_OP_ALT_READ, port, reg); - pci_read_config_dword(QUARK_HOST_BRIDGE, MSG_DATA_REG, &value); + qrk_pci_read_config_dword(QUARK_HOST_BRIDGE, MSG_DATA_REG, &value); return value; } void msg_port_alt_write(u8 port, u32 reg, u32 value) { - pci_write_config_dword(QUARK_HOST_BRIDGE, MSG_DATA_REG, value); - pci_write_config_dword(QUARK_HOST_BRIDGE, MSG_CTRL_EXT_REG, - reg & 0xffffff00); + qrk_pci_write_config_dword(QUARK_HOST_BRIDGE, MSG_DATA_REG, value); + qrk_pci_write_config_dword(QUARK_HOST_BRIDGE, MSG_CTRL_EXT_REG, + reg & 0xffffff00); msg_port_setup(MSG_OP_ALT_WRITE, port, reg); } @@ -60,18 +60,18 @@ u32 msg_port_io_read(u8 port, u32 reg) { u32 value; - pci_write_config_dword(QUARK_HOST_BRIDGE, MSG_CTRL_EXT_REG, - reg & 0xffffff00); + qrk_pci_write_config_dword(QUARK_HOST_BRIDGE, MSG_CTRL_EXT_REG, + reg & 0xffffff00); msg_port_setup(MSG_OP_IO_READ, port, reg); - pci_read_config_dword(QUARK_HOST_BRIDGE, MSG_DATA_REG, &value); + qrk_pci_read_config_dword(QUARK_HOST_BRIDGE, MSG_DATA_REG, &value); return value; } void msg_port_io_write(u8 port, u32 reg, u32 value) { - pci_write_config_dword(QUARK_HOST_BRIDGE, MSG_DATA_REG, value); - pci_write_config_dword(QUARK_HOST_BRIDGE, MSG_CTRL_EXT_REG, - reg & 0xffffff00); + qrk_pci_write_config_dword(QUARK_HOST_BRIDGE, MSG_DATA_REG, value); + qrk_pci_write_config_dword(QUARK_HOST_BRIDGE, MSG_CTRL_EXT_REG, + reg & 0xffffff00); msg_port_setup(MSG_OP_IO_WRITE, port, reg); } diff --git a/arch/x86/cpu/quark/pci.c b/arch/x86/cpu/quark/pci.c deleted file mode 100644 index 354e15a990..0000000000 --- a/arch/x86/cpu/quark/pci.c +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright (C) 2015, Bin Meng <bmeng.cn@gmail.com> - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include <common.h> -#include <pci.h> -#include <asm/pci.h> -#include <asm/arch/device.h> - -DECLARE_GLOBAL_DATA_PTR; - -void board_pci_setup_hose(struct pci_controller *hose) -{ - hose->first_busno = 0; - hose->last_busno = 0; - - /* PCI memory space */ - pci_set_region(hose->regions + 0, - CONFIG_PCI_MEM_BUS, - CONFIG_PCI_MEM_PHYS, - CONFIG_PCI_MEM_SIZE, - PCI_REGION_MEM); - - /* PCI IO space */ - pci_set_region(hose->regions + 1, - CONFIG_PCI_IO_BUS, - CONFIG_PCI_IO_PHYS, - CONFIG_PCI_IO_SIZE, - PCI_REGION_IO); - - pci_set_region(hose->regions + 2, - CONFIG_PCI_PREF_BUS, - CONFIG_PCI_PREF_PHYS, - CONFIG_PCI_PREF_SIZE, - PCI_REGION_PREFETCH); - - pci_set_region(hose->regions + 3, - 0, - 0, - gd->ram_size, - PCI_REGION_MEM | PCI_REGION_SYS_MEMORY); - - hose->region_count = 4; -} - -int board_pci_post_scan(struct pci_controller *hose) -{ - return 0; -} - -int pci_skip_dev(struct pci_controller *hose, pci_dev_t dev) -{ - /* - * TODO: - * - * For some unknown reason, the PCI enumeration process hangs - * when it scans to the PCIe root port 0 (D23:F0) & 1 (D23:F1). - * - * For now we just skip these two devices, and this needs to - * be revisited later. - */ - if (dev == QUARK_HOST_BRIDGE || - dev == QUARK_PCIE0 || dev == QUARK_PCIE1) { - return 1; - } - - return 0; -} diff --git a/arch/x86/cpu/quark/quark.c b/arch/x86/cpu/quark/quark.c index 12ac3761d2..637c370e81 100644 --- a/arch/x86/cpu/quark/quark.c +++ b/arch/x86/cpu/quark/quark.c @@ -31,32 +31,32 @@ static void unprotect_spi_flash(void) { u32 bc; - bc = x86_pci_read_config32(QUARK_LEGACY_BRIDGE, 0xd8); + qrk_pci_read_config_dword(QUARK_LEGACY_BRIDGE, 0xd8, &bc); bc |= 0x1; /* unprotect the flash */ - x86_pci_write_config32(QUARK_LEGACY_BRIDGE, 0xd8, bc); + qrk_pci_write_config_dword(QUARK_LEGACY_BRIDGE, 0xd8, bc); } static void quark_setup_bars(void) { /* GPIO - D31:F0:R44h */ - pci_write_config_dword(QUARK_LEGACY_BRIDGE, LB_GBA, - CONFIG_GPIO_BASE | IO_BAR_EN); + qrk_pci_write_config_dword(QUARK_LEGACY_BRIDGE, LB_GBA, + CONFIG_GPIO_BASE | IO_BAR_EN); /* ACPI PM1 Block - D31:F0:R48h */ - pci_write_config_dword(QUARK_LEGACY_BRIDGE, LB_PM1BLK, - CONFIG_ACPI_PM1_BASE | IO_BAR_EN); + qrk_pci_write_config_dword(QUARK_LEGACY_BRIDGE, LB_PM1BLK, + CONFIG_ACPI_PM1_BASE | IO_BAR_EN); /* GPE0 - D31:F0:R4Ch */ - pci_write_config_dword(QUARK_LEGACY_BRIDGE, LB_GPE0BLK, - CONFIG_ACPI_GPE0_BASE | IO_BAR_EN); + qrk_pci_write_config_dword(QUARK_LEGACY_BRIDGE, LB_GPE0BLK, + CONFIG_ACPI_GPE0_BASE | IO_BAR_EN); /* WDT - D31:F0:R84h */ - pci_write_config_dword(QUARK_LEGACY_BRIDGE, LB_WDTBA, - CONFIG_WDT_BASE | IO_BAR_EN); + qrk_pci_write_config_dword(QUARK_LEGACY_BRIDGE, LB_WDTBA, + CONFIG_WDT_BASE | IO_BAR_EN); /* RCBA - D31:F0:RF0h */ - pci_write_config_dword(QUARK_LEGACY_BRIDGE, LB_RCBA, - CONFIG_RCBA_BASE | MEM_BAR_EN); + qrk_pci_write_config_dword(QUARK_LEGACY_BRIDGE, LB_RCBA, + CONFIG_RCBA_BASE | MEM_BAR_EN); /* ACPI P Block - Msg Port 04:R70h */ msg_port_write(MSG_PORT_RMU, PBLK_BA, @@ -73,6 +73,96 @@ 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_usb_early_init(void) +{ + u32 usb; + + /* The sequence below comes from Quark firmware writer guide */ + + usb = msg_port_alt_read(MSG_PORT_USB_AFE, USB2_GLOBAL_PORT); + usb &= ~(1 << 1); + usb |= ((1 << 6) | (1 << 7)); + msg_port_alt_write(MSG_PORT_USB_AFE, USB2_GLOBAL_PORT, usb); + + usb = msg_port_alt_read(MSG_PORT_USB_AFE, USB2_COMPBG); + usb &= ~((1 << 8) | (1 << 9)); + usb |= ((1 << 7) | (1 << 10)); + msg_port_alt_write(MSG_PORT_USB_AFE, USB2_COMPBG, usb); + + usb = msg_port_alt_read(MSG_PORT_USB_AFE, USB2_PLL2); + usb |= (1 << 29); + msg_port_alt_write(MSG_PORT_USB_AFE, USB2_PLL2, usb); + + usb = msg_port_alt_read(MSG_PORT_USB_AFE, USB2_PLL1); + usb |= (1 << 1); + msg_port_alt_write(MSG_PORT_USB_AFE, USB2_PLL1, usb); + + usb = msg_port_alt_read(MSG_PORT_USB_AFE, USB2_PLL1); + usb &= ~((1 << 3) | (1 << 4) | (1 << 5)); + usb |= (1 << 6); + msg_port_alt_write(MSG_PORT_USB_AFE, USB2_PLL1, usb); + + usb = msg_port_alt_read(MSG_PORT_USB_AFE, USB2_PLL2); + usb &= ~(1 << 29); + msg_port_alt_write(MSG_PORT_USB_AFE, USB2_PLL2, usb); + + usb = msg_port_alt_read(MSG_PORT_USB_AFE, USB2_PLL2); + usb |= (1 << 24); + msg_port_alt_write(MSG_PORT_USB_AFE, USB2_PLL2, usb); +} + static void quark_enable_legacy_seg(void) { u32 hmisc2; @@ -84,7 +174,6 @@ static void quark_enable_legacy_seg(void) int arch_cpu_init(void) { - struct pci_controller *hose; int ret; post_code(POST_CPU_INIT); @@ -96,16 +185,26 @@ int arch_cpu_init(void) if (ret) return ret; - ret = pci_early_init_hose(&hose); - if (ret) - return ret; - /* * Quark SoC has some non-standard BARs (excluding PCI standard BARs) * which need be initialized with suggested values */ 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(); + + /* Initialize USB2 PHY */ + quark_usb_early_init(); + /* Turn on legacy segments (A/B/E/F) decode to system RAM */ quark_enable_legacy_seg(); @@ -137,10 +236,10 @@ int cpu_eth_init(bd_t *bis) u32 base; int ret0, ret1; - pci_read_config_dword(QUARK_EMAC0, PCI_BASE_ADDRESS_0, &base); + qrk_pci_read_config_dword(QUARK_EMAC0, PCI_BASE_ADDRESS_0, &base); ret0 = designware_initialize(base, PHY_INTERFACE_MODE_RMII); - pci_read_config_dword(QUARK_EMAC1, PCI_BASE_ADDRESS_0, &base); + qrk_pci_read_config_dword(QUARK_EMAC1, PCI_BASE_ADDRESS_0, &base); ret1 = designware_initialize(base, PHY_INTERFACE_MODE_RMII); if (ret0 < 0 && ret1 < 0) @@ -154,7 +253,7 @@ void cpu_irq_init(void) struct quark_rcba *rcba; u32 base; - base = x86_pci_read_config32(QUARK_LEGACY_BRIDGE, LB_RCBA); + qrk_pci_read_config_dword(QUARK_LEGACY_BRIDGE, LB_RCBA, &base); base &= ~MEM_BAR_EN; rcba = (struct quark_rcba *)base; diff --git a/arch/x86/dts/chromebox_panther.dts b/arch/x86/dts/chromebox_panther.dts index 36feb96a94..c60ab710d2 100644 --- a/arch/x86/dts/chromebox_panther.dts +++ b/arch/x86/dts/chromebox_panther.dts @@ -42,6 +42,16 @@ stdout-path = "/serial"; }; + pci { + compatible = "pci-x86"; + #address-cells = <3>; + #size-cells = <2>; + u-boot,dm-pre-reloc; + ranges = <0x02000000 0x0 0xe0000000 0xe0000000 0 0x10000000 + 0x42000000 0x0 0xd0000000 0xd0000000 0 0x10000000 + 0x01000000 0x0 0x1000 0x1000 0 0xf000>; + }; + spi { #address-cells = <1>; #size-cells = <0>; diff --git a/arch/x86/dts/galileo.dts b/arch/x86/dts/galileo.dts index d77ff8ad55..f119bf7f42 100644 --- a/arch/x86/dts/galileo.dts +++ b/arch/x86/dts/galileo.dts @@ -54,8 +54,11 @@ pci { #address-cells = <3>; #size-cells = <2>; - compatible = "intel,pci"; - device_type = "pci"; + compatible = "pci-x86"; + u-boot,dm-pre-reloc; + ranges = <0x02000000 0x0 0x90000000 0x90000000 0 0x20000000 + 0x42000000 0x0 0xb0000000 0xb0000000 0 0x20000000 + 0x01000000 0x0 0x2000 0x2000 0 0xe000>; pciuart0: uart@14,5 { compatible = "pci8086,0936.00", @@ -63,6 +66,7 @@ "pciclass,070002", "pciclass,0700", "x86-uart"; + u-boot,dm-pre-reloc; reg = <0x0000a500 0x0 0x0 0x0 0x0 0x0200a510 0x0 0x0 0x0 0x0>; reg-shift = <2>; diff --git a/arch/x86/include/asm/arch-quark/quark.h b/arch/x86/include/asm/arch-quark/quark.h index c9979280b6..5d81976998 100644 --- a/arch/x86/include/asm/arch-quark/quark.h +++ b/arch/x86/include/asm/arch-quark/quark.h @@ -12,6 +12,8 @@ #define MSG_PORT_HOST_BRIDGE 0x03 #define MSG_PORT_RMU 0x04 #define MSG_PORT_MEM_MGR 0x05 +#define MSG_PORT_USB_AFE 0x14 +#define MSG_PORT_PCIE_AFE 0x16 #define MSG_PORT_SOC_UNIT 0x31 /* Port 0x00: Memory Arbiter Message Port Registers */ @@ -48,6 +50,28 @@ #define ESRAM_BLK_CTRL 0x82 #define ESRAM_BLOCK_MODE 0x10000000 +/* Port 0x14: USB2 AFE Unit Port Registers */ + +#define USB2_GLOBAL_PORT 0x4001 +#define USB2_PLL1 0x7f02 +#define USB2_PLL2 0x7f03 +#define USB2_COMPBG 0x7f04 + +/* Port 0x16: PCIe AFE Unit Port Registers */ + +#define PCIE_RXPICTRL0_L0 0x2080 +#define PCIE_RXPICTRL0_L1 0x2180 + +/* Port 0x31: SoC Unit Port Registers */ + +/* PCIe Controller Config */ +#define PCIE_CFG 0x36 +#define PCIE_CTLR_PRI_RST 0x00010000 +#define PCIE_PHY_SB_RST 0x00020000 +#define PCIE_CTLR_SB_RST 0x00040000 +#define PCIE_PHY_LANE_RST 0x00090000 +#define PCIE_CTLR_MAIN_RST 0x00100000 + /* DRAM */ #define DRAM_BASE 0x00000000 #define DRAM_MAX_SIZE 0x80000000 @@ -89,6 +113,67 @@ struct quark_rcba { u16 d20d21_ir; }; +#include <asm/io.h> +#include <asm/pci.h> + +/** + * qrk_pci_read_config_dword() - Read a configuration value + * + * @dev: PCI device address: bus, device and function + * @offset: Dword offset within the device's configuration space + * @valuep: Place to put the returned value + * + * Note: This routine is inlined to provide better performance on Quark + */ +static inline void qrk_pci_read_config_dword(pci_dev_t dev, int offset, + u32 *valuep) +{ + outl(dev | offset | PCI_CFG_EN, PCI_REG_ADDR); + *valuep = inl(PCI_REG_DATA); +} + +/** + * qrk_pci_write_config_dword() - Write a PCI configuration value + * + * @dev: PCI device address: bus, device and function + * @offset: Dword offset within the device's configuration space + * @value: Value to write + * + * Note: This routine is inlined to provide better performance on Quark + */ +static inline void qrk_pci_write_config_dword(pci_dev_t dev, int offset, + u32 value) +{ + outl(dev | offset | PCI_CFG_EN, PCI_REG_ADDR); + outl(value, PCI_REG_DATA); +} + +/** + * board_assert_perst() - Assert the PERST# pin + * + * The CPU interface to the PERST# signal on Quark is platform dependent. + * Board-specific codes need supply this routine to assert PCIe slot reset. + * + * The tricky part in this routine is that any APIs that may trigger PCI + * enumeration process are strictly forbidden, as any access to PCIe root + * port's configuration registers will cause system hang while it is held + * in reset. + */ +void board_assert_perst(void); + +/** + * board_deassert_perst() - De-assert the PERST# pin + * + * The CPU interface to the PERST# signal on Quark is platform dependent. + * Board-specific codes need supply this routine to de-assert PCIe slot reset. + * + * The tricky part in this routine is that any APIs that may trigger PCI + * enumeration process are strictly forbidden, as any access to PCIe root + * port's configuration registers will cause system hang while it is held + * in reset. + */ +void board_deassert_perst(void); + #endif /* __ASSEMBLY__ */ #endif /* _QUARK_H_ */ |