The NXP i.MX8QXP CPU has one PCI Express (PCIe) hardware module that can either be configured to act as a root complex or a PCI Express endpoint. PCI Express is a third-generation I/O interconnect targeting low-cost, high-volume, multi-platform interconnection.

PCIe includes the following cores:

  • PCIe dual mode (DM) core

  • PCIe root complex (RC) core

  • PCIe endpoint (EP) core

The Linux BSP only supports the PCIe port acting as Root Complex (RC).

On the ConnectCore 8X system-on-module:

  • On wireless variants of the ConnectCore 8X SOM, the PCIe bus is dedicated to the communication with the Qualcomm QCA6574A wireless chipset and it is not available on the LGA pads.

  • On non-wireless variants of the ConnectCore 8X SOM, the PCIe bus is available on the LGA pads.

On the ConnectCore 8X SBC Pro:

  • The PCIe port is available in the PCIe mini card connector at the bottom of the board.

    The PCIe lines can only be used on non-wireless variants of the ConnectCore 8X.

    The ConnectCore 8X SBC Pro does not assemble the PCIe clock generator. You need to assemble additional hardware to use the PCIe bus. See the ConnectCore 8X SBC Pro reference design at the product support web site.

Kernel configuration

You can manage the PCIe driver support through the kernel configuration option:

  • Freescale i.MX6 PCIe controller (CONFIG_PCI_IMX6)

This option is enabled as built-in on the default ConnectCore 8X kernel configuration file.

Kernel driver

The PCIe bus driver for the ConnectCore 8X system-on-module is located at drivers/pci/dwc/pci-imx6.c.

Device tree bindings and customization

The i.MX8QXP PCIe interface device tree binding is documented at Documentation/devicetree/bindings/pci/fsl,imx6q-pcie.txt.

Example: PCIe (Mini card) on the ConnectCore 8X SBC Pro

Definition of the PCIe bus

i.MX8QXP device tree
pcieb: pcie@0x5f010000 {
	 * pcieb phyx1 lane1 in default, adjust it refer to the
	 * exact hw design.
	compatible = "fsl,imx8qxp-pcie","snps,dw-pcie";
	reg = <0x0 0x5f010000 0x0 0x10000>, /* Controller reg*/
		<0x0 0x7ff00000 0x0 0x80000>; /* PCI cfg space */
	reg-names = "dbi", "config";
	reserved-region = <&rpmsg_reserved>;
	#address-cells = <3>;
	#size-cells = <2>;
	device_type = "pci";
	ranges = <0x81000000 0 0x00000000 0x0 0x7ff80000 0 0x00010000 /* downstream I/O */
		0x82000000 0 0x70000000 0x0 0x70000000 0 0x0ff00000>; /* non-prefetchable memory */
	num-lanes = <1>;

	#interrupt-cells = <1>;
	interrupts = <GIC_SPI 102 IRQ_TYPE_LEVEL_HIGH>,
	interrupt-names = "msi";

	 * Set these clocks in default, then clocks should be
	 * refined for exact hw design of imx8 pcie.
	clocks = <&clk IMX8QXP_HSIO_PCIE_MSTR_AXI_CLK>,
	clock-names = "pcie", "pcie_bus", "pcie_phy", "pcie_per", "pcie_inbound_axi";

	interrupt-map-mask = <0 0 0 0x7>;
	interrupt-map =  <0 0 0 1 &gic 0 105 4>,
			<0 0 0 2 &gic 0 106 4>,
			<0 0 0 3 &gic 0 107 4>,
			<0 0 0 4 &gic 0 108 4>;
	power-domains = <&pd_pcie>;
	fsl,max-link-speed = <3>;
	hsio-cfg = <PCIEAX2PCIEBX1>;
	hsio = <&hsio>;
	ctrl-id = <1>; /* pcieb */
	cpu-base-addr = <0x80000000>;
	status = "disabled";

IOMUX configuration

The ConnectCore 8X SBC Pro assembles a PCIe Mini card connector. Three GPIOs of the ConnectCore 8X SOM are routed to the PCIe connector:

  • GPIO0_IO30: PCIe disable line

  • GPIO0_IO29: PCIe wake line

  • GPIO3_IO16: PCIe reset line

ConnectCore 8X SBC Pro device tree
/* PCIE (Mini Card) */
pinctrl_pcieb: pcieagrp {
	fsl,pins = <
		/* PCIE_RESET_N */
		SC_P_QSPI0A_SCLK_LSIO_GPIO3_IO16	0x06000021
		/* PCIE_DIS_N */
		SC_P_SAI1_RXC_LSIO_GPIO0_IO30		0x06000021
		/* PCIE_WAKE_N */
		SC_P_SAI1_RXD_LSIO_GPIO0_IO29		0x06000021

Bus enabling

The PCIe bus is disabled by default on the ConnectCore 8X SBC Pro device tree because of the missing clock generator (see note). To enable it, set the status property to okay.

ConnectCore 8X SBC Pro device tree
/* PCIE (Mini Card) */
&pcieb {
	pinctrl-names = "default";
	pinctrl-0 = <&pinctrl_pcieb>;
	ext_osc = <1>;
	reset-gpio = <&gpio3 16 GPIO_ACTIVE_LOW>; /* PCIE_RESET_N */
	disable-gpio = <&gpio0 30 GPIO_ACTIVE_HIGH>; /* PCIE_DIS_N */
	epdev_on-supply = <&reg_3v3_pcie>;
	status = "okay";