Commit ea2df11f authored by Srinath Mannam's avatar Srinath Mannam Committed by Lorenzo Pieralisi
Browse files

PCI: iproc: Allow outbound configuration for 32-bit I/O region

The IProc host controller has I/O memory windows allocated in
the AXI memory map that can be used to address PCI I/O memory
space.

Mapping from AXI memory windows to PCI outbound memory windows is
carried out in the host controller through OARR/OMAP registers pairs
that permit to define power of two region size AXI<->PCI mappings, the
smallest of which is 128MB.

Current code enables AXI memory window to PCI outbound memory window
mapping only for AXI windows matching one of the OARR/OMAP window sizes,
that are SoC dependent and the smallest of which is 128MB.

Some SoCs implementing the IProc host controller have a 32-bit AXI
memory window into PCI I/O memory space, eg:

    Base address | Size
-----------------------------
(1) 0x42000000   | 0x2000000
(2) 0x400000000  | 0x80000000

but its size (32MB - (1) above) is smaller than the smallest AXI<->PCI
region size provided by OARR (128MB), so the current driver rejects
mappings for the 32-bit region making the IProc host controller driver
unusable on 32-bit systems.

However, there is no reason why the 32-bit I/O memory window cannot be
enabled by mapping it through an OARR/OMAP region bigger in size (ie
32-bit AXI window size is 32MB but can be mapped using a 128MB OARR/OMAP
region).

Allow outbound window configuration of I/O memory windows that
are smaller in size than the host controller OARR/OMAP region, so
that the 32-bit AXI memory window can actually be enabled,
making the IProc host controller operational on 32-bit systems.

Link: https://lore.kernel.org/linux-pci/1551415936-30174-3-git-send-email-srinath.mannam@broadcom.com/


Signed-off-by: default avatarSrinath Mannam <srinath.mannam@broadcom.com>
Signed-off-by: default avatarAbhishek Shah <abhishek.shah@broadcom.com>
Signed-off-by: default avatarRay Jui <ray.jui@broadcom.com>
[lorenzo.pieralisi@arm.com: rewrote the commit log]
Signed-off-by: default avatarLorenzo Pieralisi <lorenzo.pieralisi@arm.com>
Acked-by: default avatarScott Branden <scott.branden@broadcom.com>
parent 73b9e4d3
Loading
Loading
Loading
Loading
+19 −2
Original line number Diff line number Diff line
@@ -955,9 +955,26 @@ static int iproc_pcie_setup_ob(struct iproc_pcie *pcie, u64 axi_addr,
			resource_size_t window_size =
				ob_map->window_sizes[size_idx] * SZ_1M;

			if (size < window_size)
			/*
			 * Keep iterating until we reach the last window and
			 * with the minimal window size at index zero. In this
			 * case, we take a compromise by mapping it using the
			 * minimum window size that can be supported
			 */
			if (size < window_size) {
				if (size_idx > 0 || window_idx > 0)
					continue;

				/*
				 * For the corner case of reaching the minimal
				 * window size that can be supported on the
				 * last window
				 */
				axi_addr = ALIGN_DOWN(axi_addr, window_size);
				pci_addr = ALIGN_DOWN(pci_addr, window_size);
				size = window_size;
			}

			if (!IS_ALIGNED(axi_addr, window_size) ||
			    !IS_ALIGNED(pci_addr, window_size)) {
				dev_err(dev,