^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Copyright (C) 2014 Hauke Mehrtens <hauke@hauke-m.de>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * Copyright (C) 2015 Broadcom Corporation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include <linux/pci.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <linux/msi.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/clk.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/mbus.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/interrupt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/irqchip/arm-gic-v3.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/platform_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/of_address.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <linux/of_pci.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <linux/of_irq.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <linux/of_platform.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include <linux/phy/phy.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #include "pcie-iproc.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #define EP_PERST_SOURCE_SELECT_SHIFT 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #define EP_PERST_SOURCE_SELECT BIT(EP_PERST_SOURCE_SELECT_SHIFT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #define EP_MODE_SURVIVE_PERST_SHIFT 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #define EP_MODE_SURVIVE_PERST BIT(EP_MODE_SURVIVE_PERST_SHIFT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #define RC_PCIE_RST_OUTPUT_SHIFT 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #define RC_PCIE_RST_OUTPUT BIT(RC_PCIE_RST_OUTPUT_SHIFT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #define PAXC_RESET_MASK 0x7f
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) #define GIC_V3_CFG_SHIFT 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) #define GIC_V3_CFG BIT(GIC_V3_CFG_SHIFT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) #define MSI_ENABLE_CFG_SHIFT 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) #define MSI_ENABLE_CFG BIT(MSI_ENABLE_CFG_SHIFT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) #define CFG_IND_ADDR_MASK 0x00001ffc
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) #define CFG_ADDR_BUS_NUM_SHIFT 20
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) #define CFG_ADDR_BUS_NUM_MASK 0x0ff00000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) #define CFG_ADDR_DEV_NUM_SHIFT 15
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) #define CFG_ADDR_DEV_NUM_MASK 0x000f8000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) #define CFG_ADDR_FUNC_NUM_SHIFT 12
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) #define CFG_ADDR_FUNC_NUM_MASK 0x00007000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) #define CFG_ADDR_REG_NUM_SHIFT 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) #define CFG_ADDR_REG_NUM_MASK 0x00000ffc
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) #define CFG_ADDR_CFG_TYPE_SHIFT 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) #define CFG_ADDR_CFG_TYPE_MASK 0x00000003
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) #define SYS_RC_INTX_MASK 0xf
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) #define PCIE_PHYLINKUP_SHIFT 3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) #define PCIE_PHYLINKUP BIT(PCIE_PHYLINKUP_SHIFT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) #define PCIE_DL_ACTIVE_SHIFT 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) #define PCIE_DL_ACTIVE BIT(PCIE_DL_ACTIVE_SHIFT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) #define APB_ERR_EN_SHIFT 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) #define APB_ERR_EN BIT(APB_ERR_EN_SHIFT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) #define CFG_RD_SUCCESS 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) #define CFG_RD_UR 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) #define CFG_RD_CRS 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) #define CFG_RD_CA 3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) #define CFG_RETRY_STATUS 0xffff0001
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) #define CFG_RETRY_STATUS_TIMEOUT_US 500000 /* 500 milliseconds */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) /* derive the enum index of the outbound/inbound mapping registers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) #define MAP_REG(base_reg, index) ((base_reg) + (index) * 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) * Maximum number of outbound mapping window sizes that can be supported by any
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) * OARR/OMAP mapping pair
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) #define MAX_NUM_OB_WINDOW_SIZES 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) #define OARR_VALID_SHIFT 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) #define OARR_VALID BIT(OARR_VALID_SHIFT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) #define OARR_SIZE_CFG_SHIFT 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) * Maximum number of inbound mapping region sizes that can be supported by an
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) * IARR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) #define MAX_NUM_IB_REGION_SIZES 9
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) #define IMAP_VALID_SHIFT 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) #define IMAP_VALID BIT(IMAP_VALID_SHIFT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) #define IPROC_PCI_PM_CAP 0x48
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) #define IPROC_PCI_PM_CAP_MASK 0xffff
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) #define IPROC_PCI_EXP_CAP 0xac
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) #define IPROC_PCIE_REG_INVALID 0xffff
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) * iProc PCIe outbound mapping controller specific parameters
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) * @window_sizes: list of supported outbound mapping window sizes in MB
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) * @nr_sizes: number of supported outbound mapping window sizes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) struct iproc_pcie_ob_map {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) resource_size_t window_sizes[MAX_NUM_OB_WINDOW_SIZES];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) unsigned int nr_sizes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) static const struct iproc_pcie_ob_map paxb_ob_map[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) /* OARR0/OMAP0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) .window_sizes = { 128, 256 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) .nr_sizes = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) /* OARR1/OMAP1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) .window_sizes = { 128, 256 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) .nr_sizes = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) static const struct iproc_pcie_ob_map paxb_v2_ob_map[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) /* OARR0/OMAP0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) .window_sizes = { 128, 256 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) .nr_sizes = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) /* OARR1/OMAP1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) .window_sizes = { 128, 256 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) .nr_sizes = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) /* OARR2/OMAP2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) .window_sizes = { 128, 256, 512, 1024 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) .nr_sizes = 4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) /* OARR3/OMAP3 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) .window_sizes = { 128, 256, 512, 1024 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) .nr_sizes = 4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) * iProc PCIe inbound mapping type
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) enum iproc_pcie_ib_map_type {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) /* for DDR memory */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) IPROC_PCIE_IB_MAP_MEM = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) /* for device I/O memory */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) IPROC_PCIE_IB_MAP_IO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) /* invalid or unused */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) IPROC_PCIE_IB_MAP_INVALID
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) * iProc PCIe inbound mapping controller specific parameters
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) * @type: inbound mapping region type
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) * @size_unit: inbound mapping region size unit, could be SZ_1K, SZ_1M, or
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) * SZ_1G
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) * @region_sizes: list of supported inbound mapping region sizes in KB, MB, or
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) * GB, depending on the size unit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) * @nr_sizes: number of supported inbound mapping region sizes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) * @nr_windows: number of supported inbound mapping windows for the region
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) * @imap_addr_offset: register offset between the upper and lower 32-bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) * IMAP address registers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) * @imap_window_offset: register offset between each IMAP window
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) struct iproc_pcie_ib_map {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) enum iproc_pcie_ib_map_type type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) unsigned int size_unit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) resource_size_t region_sizes[MAX_NUM_IB_REGION_SIZES];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) unsigned int nr_sizes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) unsigned int nr_windows;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) u16 imap_addr_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) u16 imap_window_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) static const struct iproc_pcie_ib_map paxb_v2_ib_map[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) /* IARR0/IMAP0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) .type = IPROC_PCIE_IB_MAP_IO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) .size_unit = SZ_1K,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) .region_sizes = { 32 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) .nr_sizes = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) .nr_windows = 8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) .imap_addr_offset = 0x40,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) .imap_window_offset = 0x4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) /* IARR1/IMAP1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) .type = IPROC_PCIE_IB_MAP_MEM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) .size_unit = SZ_1M,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) .region_sizes = { 8 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) .nr_sizes = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) .nr_windows = 8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) .imap_addr_offset = 0x4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) .imap_window_offset = 0x8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) /* IARR2/IMAP2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) .type = IPROC_PCIE_IB_MAP_MEM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) .size_unit = SZ_1M,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) .region_sizes = { 64, 128, 256, 512, 1024, 2048, 4096, 8192,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) 16384 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) .nr_sizes = 9,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) .nr_windows = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) .imap_addr_offset = 0x4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) .imap_window_offset = 0x8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) /* IARR3/IMAP3 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) .type = IPROC_PCIE_IB_MAP_MEM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) .size_unit = SZ_1G,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) .region_sizes = { 1, 2, 4, 8, 16, 32 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) .nr_sizes = 6,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) .nr_windows = 8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) .imap_addr_offset = 0x4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) .imap_window_offset = 0x8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) /* IARR4/IMAP4 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) .type = IPROC_PCIE_IB_MAP_MEM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) .size_unit = SZ_1G,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) .region_sizes = { 32, 64, 128, 256, 512 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) .nr_sizes = 5,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) .nr_windows = 8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) .imap_addr_offset = 0x4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) .imap_window_offset = 0x8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) * iProc PCIe host registers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) enum iproc_pcie_reg {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) /* clock/reset signal control */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) IPROC_PCIE_CLK_CTRL = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) * To allow MSI to be steered to an external MSI controller (e.g., ARM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) * GICv3 ITS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) IPROC_PCIE_MSI_GIC_MODE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) * IPROC_PCIE_MSI_BASE_ADDR and IPROC_PCIE_MSI_WINDOW_SIZE define the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) * window where the MSI posted writes are written, for the writes to be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) * interpreted as MSI writes.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) IPROC_PCIE_MSI_BASE_ADDR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) IPROC_PCIE_MSI_WINDOW_SIZE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) * To hold the address of the register where the MSI writes are
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) * programed. When ARM GICv3 ITS is used, this should be programmed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) * with the address of the GITS_TRANSLATER register.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) IPROC_PCIE_MSI_ADDR_LO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) IPROC_PCIE_MSI_ADDR_HI,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) /* enable MSI */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) IPROC_PCIE_MSI_EN_CFG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) /* allow access to root complex configuration space */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) IPROC_PCIE_CFG_IND_ADDR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) IPROC_PCIE_CFG_IND_DATA,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) /* allow access to device configuration space */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) IPROC_PCIE_CFG_ADDR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) IPROC_PCIE_CFG_DATA,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) /* enable INTx */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) IPROC_PCIE_INTX_EN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) /* outbound address mapping */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) IPROC_PCIE_OARR0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) IPROC_PCIE_OMAP0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) IPROC_PCIE_OARR1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) IPROC_PCIE_OMAP1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) IPROC_PCIE_OARR2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) IPROC_PCIE_OMAP2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) IPROC_PCIE_OARR3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) IPROC_PCIE_OMAP3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) /* inbound address mapping */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) IPROC_PCIE_IARR0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) IPROC_PCIE_IMAP0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) IPROC_PCIE_IARR1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) IPROC_PCIE_IMAP1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) IPROC_PCIE_IARR2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) IPROC_PCIE_IMAP2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) IPROC_PCIE_IARR3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) IPROC_PCIE_IMAP3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) IPROC_PCIE_IARR4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) IPROC_PCIE_IMAP4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) /* config read status */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) IPROC_PCIE_CFG_RD_STATUS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) /* link status */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) IPROC_PCIE_LINK_STATUS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) /* enable APB error for unsupported requests */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) IPROC_PCIE_APB_ERR_EN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) /* total number of core registers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) IPROC_PCIE_MAX_NUM_REG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) /* iProc PCIe PAXB BCMA registers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) static const u16 iproc_pcie_reg_paxb_bcma[IPROC_PCIE_MAX_NUM_REG] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) [IPROC_PCIE_CLK_CTRL] = 0x000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) [IPROC_PCIE_CFG_IND_ADDR] = 0x120,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) [IPROC_PCIE_CFG_IND_DATA] = 0x124,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) [IPROC_PCIE_CFG_ADDR] = 0x1f8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) [IPROC_PCIE_CFG_DATA] = 0x1fc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) [IPROC_PCIE_INTX_EN] = 0x330,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) [IPROC_PCIE_LINK_STATUS] = 0xf0c,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) /* iProc PCIe PAXB registers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) static const u16 iproc_pcie_reg_paxb[IPROC_PCIE_MAX_NUM_REG] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) [IPROC_PCIE_CLK_CTRL] = 0x000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) [IPROC_PCIE_CFG_IND_ADDR] = 0x120,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) [IPROC_PCIE_CFG_IND_DATA] = 0x124,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) [IPROC_PCIE_CFG_ADDR] = 0x1f8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) [IPROC_PCIE_CFG_DATA] = 0x1fc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) [IPROC_PCIE_INTX_EN] = 0x330,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) [IPROC_PCIE_OARR0] = 0xd20,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) [IPROC_PCIE_OMAP0] = 0xd40,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) [IPROC_PCIE_OARR1] = 0xd28,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) [IPROC_PCIE_OMAP1] = 0xd48,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) [IPROC_PCIE_LINK_STATUS] = 0xf0c,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) [IPROC_PCIE_APB_ERR_EN] = 0xf40,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) /* iProc PCIe PAXB v2 registers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) static const u16 iproc_pcie_reg_paxb_v2[IPROC_PCIE_MAX_NUM_REG] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) [IPROC_PCIE_CLK_CTRL] = 0x000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) [IPROC_PCIE_CFG_IND_ADDR] = 0x120,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) [IPROC_PCIE_CFG_IND_DATA] = 0x124,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) [IPROC_PCIE_CFG_ADDR] = 0x1f8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) [IPROC_PCIE_CFG_DATA] = 0x1fc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) [IPROC_PCIE_INTX_EN] = 0x330,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) [IPROC_PCIE_OARR0] = 0xd20,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) [IPROC_PCIE_OMAP0] = 0xd40,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) [IPROC_PCIE_OARR1] = 0xd28,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) [IPROC_PCIE_OMAP1] = 0xd48,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) [IPROC_PCIE_OARR2] = 0xd60,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) [IPROC_PCIE_OMAP2] = 0xd68,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) [IPROC_PCIE_OARR3] = 0xdf0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) [IPROC_PCIE_OMAP3] = 0xdf8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) [IPROC_PCIE_IARR0] = 0xd00,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) [IPROC_PCIE_IMAP0] = 0xc00,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) [IPROC_PCIE_IARR1] = 0xd08,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) [IPROC_PCIE_IMAP1] = 0xd70,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) [IPROC_PCIE_IARR2] = 0xd10,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) [IPROC_PCIE_IMAP2] = 0xcc0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) [IPROC_PCIE_IARR3] = 0xe00,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) [IPROC_PCIE_IMAP3] = 0xe08,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) [IPROC_PCIE_IARR4] = 0xe68,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) [IPROC_PCIE_IMAP4] = 0xe70,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) [IPROC_PCIE_CFG_RD_STATUS] = 0xee0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) [IPROC_PCIE_LINK_STATUS] = 0xf0c,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) [IPROC_PCIE_APB_ERR_EN] = 0xf40,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) /* iProc PCIe PAXC v1 registers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) static const u16 iproc_pcie_reg_paxc[IPROC_PCIE_MAX_NUM_REG] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) [IPROC_PCIE_CLK_CTRL] = 0x000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) [IPROC_PCIE_CFG_IND_ADDR] = 0x1f0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) [IPROC_PCIE_CFG_IND_DATA] = 0x1f4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) [IPROC_PCIE_CFG_ADDR] = 0x1f8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) [IPROC_PCIE_CFG_DATA] = 0x1fc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) /* iProc PCIe PAXC v2 registers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) static const u16 iproc_pcie_reg_paxc_v2[IPROC_PCIE_MAX_NUM_REG] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) [IPROC_PCIE_MSI_GIC_MODE] = 0x050,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) [IPROC_PCIE_MSI_BASE_ADDR] = 0x074,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) [IPROC_PCIE_MSI_WINDOW_SIZE] = 0x078,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) [IPROC_PCIE_MSI_ADDR_LO] = 0x07c,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) [IPROC_PCIE_MSI_ADDR_HI] = 0x080,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) [IPROC_PCIE_MSI_EN_CFG] = 0x09c,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) [IPROC_PCIE_CFG_IND_ADDR] = 0x1f0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) [IPROC_PCIE_CFG_IND_DATA] = 0x1f4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) [IPROC_PCIE_CFG_ADDR] = 0x1f8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) [IPROC_PCIE_CFG_DATA] = 0x1fc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) * List of device IDs of controllers that have corrupted capability list that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) * require SW fixup
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) static const u16 iproc_pcie_corrupt_cap_did[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) 0x16cd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) 0x16f0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) 0xd802,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) 0xd804
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) static inline struct iproc_pcie *iproc_data(struct pci_bus *bus)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) struct iproc_pcie *pcie = bus->sysdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) return pcie;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) static inline bool iproc_pcie_reg_is_invalid(u16 reg_offset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) return !!(reg_offset == IPROC_PCIE_REG_INVALID);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) static inline u16 iproc_pcie_reg_offset(struct iproc_pcie *pcie,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) enum iproc_pcie_reg reg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) return pcie->reg_offsets[reg];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) static inline u32 iproc_pcie_read_reg(struct iproc_pcie *pcie,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) enum iproc_pcie_reg reg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) u16 offset = iproc_pcie_reg_offset(pcie, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) if (iproc_pcie_reg_is_invalid(offset))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) return readl(pcie->base + offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) static inline void iproc_pcie_write_reg(struct iproc_pcie *pcie,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) enum iproc_pcie_reg reg, u32 val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) u16 offset = iproc_pcie_reg_offset(pcie, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) if (iproc_pcie_reg_is_invalid(offset))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) writel(val, pcie->base + offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) * APB error forwarding can be disabled during access of configuration
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) * registers of the endpoint device, to prevent unsupported requests
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) * (typically seen during enumeration with multi-function devices) from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) * triggering a system exception.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) static inline void iproc_pcie_apb_err_disable(struct pci_bus *bus,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) bool disable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) struct iproc_pcie *pcie = iproc_data(bus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) u32 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) if (bus->number && pcie->has_apb_err_disable) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) val = iproc_pcie_read_reg(pcie, IPROC_PCIE_APB_ERR_EN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) if (disable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) val &= ~APB_ERR_EN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) val |= APB_ERR_EN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) iproc_pcie_write_reg(pcie, IPROC_PCIE_APB_ERR_EN, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) static void __iomem *iproc_pcie_map_ep_cfg_reg(struct iproc_pcie *pcie,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) unsigned int busno,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) unsigned int slot,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) unsigned int fn,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) int where)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) u16 offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) u32 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) /* EP device access */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) val = (busno << CFG_ADDR_BUS_NUM_SHIFT) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) (slot << CFG_ADDR_DEV_NUM_SHIFT) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) (fn << CFG_ADDR_FUNC_NUM_SHIFT) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) (where & CFG_ADDR_REG_NUM_MASK) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) (1 & CFG_ADDR_CFG_TYPE_MASK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) iproc_pcie_write_reg(pcie, IPROC_PCIE_CFG_ADDR, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) offset = iproc_pcie_reg_offset(pcie, IPROC_PCIE_CFG_DATA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) if (iproc_pcie_reg_is_invalid(offset))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) return (pcie->base + offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) static unsigned int iproc_pcie_cfg_retry(struct iproc_pcie *pcie,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) void __iomem *cfg_data_p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) int timeout = CFG_RETRY_STATUS_TIMEOUT_US;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) unsigned int data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) u32 status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) * As per PCIe spec r3.1, sec 2.3.2, CRS Software Visibility only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) * affects config reads of the Vendor ID. For config writes or any
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) * other config reads, the Root may automatically reissue the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) * configuration request again as a new request.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) * For config reads, this hardware returns CFG_RETRY_STATUS data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) * when it receives a CRS completion, regardless of the address of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) * the read or the CRS Software Visibility Enable bit. As a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) * partial workaround for this, we retry in software any read that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) * returns CFG_RETRY_STATUS.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) * Note that a non-Vendor ID config register may have a value of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) * CFG_RETRY_STATUS. If we read that, we can't distinguish it from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) * a CRS completion, so we will incorrectly retry the read and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) * eventually return the wrong data (0xffffffff).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) data = readl(cfg_data_p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) while (data == CFG_RETRY_STATUS && timeout--) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) * CRS state is set in CFG_RD status register
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) * This will handle the case where CFG_RETRY_STATUS is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) * valid config data.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) status = iproc_pcie_read_reg(pcie, IPROC_PCIE_CFG_RD_STATUS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) if (status != CFG_RD_CRS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) return data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) udelay(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) data = readl(cfg_data_p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) if (data == CFG_RETRY_STATUS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) data = 0xffffffff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) return data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) static void iproc_pcie_fix_cap(struct iproc_pcie *pcie, int where, u32 *val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) u32 i, dev_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) switch (where & ~0x3) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) case PCI_VENDOR_ID:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) dev_id = *val >> 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) * Activate fixup for those controllers that have corrupted
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) * capability list registers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) for (i = 0; i < ARRAY_SIZE(iproc_pcie_corrupt_cap_did); i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) if (dev_id == iproc_pcie_corrupt_cap_did[i])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) pcie->fix_paxc_cap = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) case IPROC_PCI_PM_CAP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) if (pcie->fix_paxc_cap) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) /* advertise PM, force next capability to PCIe */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) *val &= ~IPROC_PCI_PM_CAP_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) *val |= IPROC_PCI_EXP_CAP << 8 | PCI_CAP_ID_PM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) case IPROC_PCI_EXP_CAP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) if (pcie->fix_paxc_cap) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) /* advertise root port, version 2, terminate here */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) *val = (PCI_EXP_TYPE_ROOT_PORT << 4 | 2) << 16 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) PCI_CAP_ID_EXP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) case IPROC_PCI_EXP_CAP + PCI_EXP_RTCTL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) /* Don't advertise CRS SV support */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) *val &= ~(PCI_EXP_RTCAP_CRSVIS << 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) static int iproc_pcie_config_read(struct pci_bus *bus, unsigned int devfn,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) int where, int size, u32 *val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) struct iproc_pcie *pcie = iproc_data(bus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) unsigned int slot = PCI_SLOT(devfn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) unsigned int fn = PCI_FUNC(devfn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) unsigned int busno = bus->number;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) void __iomem *cfg_data_p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) unsigned int data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) /* root complex access */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) if (busno == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) ret = pci_generic_config_read32(bus, devfn, where, size, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) if (ret == PCIBIOS_SUCCESSFUL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) iproc_pcie_fix_cap(pcie, where, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) cfg_data_p = iproc_pcie_map_ep_cfg_reg(pcie, busno, slot, fn, where);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) if (!cfg_data_p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) return PCIBIOS_DEVICE_NOT_FOUND;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) data = iproc_pcie_cfg_retry(pcie, cfg_data_p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) *val = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) if (size <= 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) *val = (data >> (8 * (where & 3))) & ((1 << (size * 8)) - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) * For PAXC and PAXCv2, the total number of PFs that one can enumerate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) * depends on the firmware configuration. Unfortunately, due to an ASIC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) * bug, unconfigured PFs cannot be properly hidden from the root
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) * complex. As a result, write access to these PFs will cause bus lock
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) * up on the embedded processor
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) * Since all unconfigured PFs are left with an incorrect, staled device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) * ID of 0x168e (PCI_DEVICE_ID_NX2_57810), we try to catch those access
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) * early here and reject them all
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) #define DEVICE_ID_MASK 0xffff0000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) #define DEVICE_ID_SHIFT 16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) if (pcie->rej_unconfig_pf &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) (where & CFG_ADDR_REG_NUM_MASK) == PCI_VENDOR_ID)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) if ((*val & DEVICE_ID_MASK) ==
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) (PCI_DEVICE_ID_NX2_57810 << DEVICE_ID_SHIFT))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) return PCIBIOS_FUNC_NOT_SUPPORTED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) return PCIBIOS_SUCCESSFUL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) * Note access to the configuration registers are protected at the higher layer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) * by 'pci_lock' in drivers/pci/access.c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) static void __iomem *iproc_pcie_map_cfg_bus(struct iproc_pcie *pcie,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) int busno, unsigned int devfn,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) int where)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) unsigned slot = PCI_SLOT(devfn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) unsigned fn = PCI_FUNC(devfn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) u16 offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) /* root complex access */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) if (busno == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) if (slot > 0 || fn > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) iproc_pcie_write_reg(pcie, IPROC_PCIE_CFG_IND_ADDR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) where & CFG_IND_ADDR_MASK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) offset = iproc_pcie_reg_offset(pcie, IPROC_PCIE_CFG_IND_DATA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) if (iproc_pcie_reg_is_invalid(offset))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) return (pcie->base + offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) return iproc_pcie_map_ep_cfg_reg(pcie, busno, slot, fn, where);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) static void __iomem *iproc_pcie_bus_map_cfg_bus(struct pci_bus *bus,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) unsigned int devfn,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) int where)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) return iproc_pcie_map_cfg_bus(iproc_data(bus), bus->number, devfn,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) where);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) static int iproc_pci_raw_config_read32(struct iproc_pcie *pcie,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) unsigned int devfn, int where,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) int size, u32 *val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) void __iomem *addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) addr = iproc_pcie_map_cfg_bus(pcie, 0, devfn, where & ~0x3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) if (!addr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) *val = ~0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) return PCIBIOS_DEVICE_NOT_FOUND;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) *val = readl(addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) if (size <= 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) *val = (*val >> (8 * (where & 3))) & ((1 << (size * 8)) - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) return PCIBIOS_SUCCESSFUL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) static int iproc_pci_raw_config_write32(struct iproc_pcie *pcie,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) unsigned int devfn, int where,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) int size, u32 val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) void __iomem *addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) u32 mask, tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) addr = iproc_pcie_map_cfg_bus(pcie, 0, devfn, where & ~0x3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) if (!addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) return PCIBIOS_DEVICE_NOT_FOUND;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) if (size == 4) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) writel(val, addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) return PCIBIOS_SUCCESSFUL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) mask = ~(((1 << (size * 8)) - 1) << ((where & 0x3) * 8));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) tmp = readl(addr) & mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) tmp |= val << ((where & 0x3) * 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) writel(tmp, addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) return PCIBIOS_SUCCESSFUL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) static int iproc_pcie_config_read32(struct pci_bus *bus, unsigned int devfn,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) int where, int size, u32 *val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) struct iproc_pcie *pcie = iproc_data(bus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) iproc_pcie_apb_err_disable(bus, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) if (pcie->iproc_cfg_read)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) ret = iproc_pcie_config_read(bus, devfn, where, size, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) ret = pci_generic_config_read32(bus, devfn, where, size, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) iproc_pcie_apb_err_disable(bus, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) static int iproc_pcie_config_write32(struct pci_bus *bus, unsigned int devfn,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) int where, int size, u32 val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) iproc_pcie_apb_err_disable(bus, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) ret = pci_generic_config_write32(bus, devfn, where, size, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) iproc_pcie_apb_err_disable(bus, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) static struct pci_ops iproc_pcie_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) .map_bus = iproc_pcie_bus_map_cfg_bus,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) .read = iproc_pcie_config_read32,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) .write = iproc_pcie_config_write32,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) static void iproc_pcie_perst_ctrl(struct iproc_pcie *pcie, bool assert)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) u32 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) * PAXC and the internal emulated endpoint device downstream should not
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) * be reset. If firmware has been loaded on the endpoint device at an
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) * earlier boot stage, reset here causes issues.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) if (pcie->ep_is_internal)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) if (assert) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) val = iproc_pcie_read_reg(pcie, IPROC_PCIE_CLK_CTRL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) val &= ~EP_PERST_SOURCE_SELECT & ~EP_MODE_SURVIVE_PERST &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) ~RC_PCIE_RST_OUTPUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) iproc_pcie_write_reg(pcie, IPROC_PCIE_CLK_CTRL, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) udelay(250);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) val = iproc_pcie_read_reg(pcie, IPROC_PCIE_CLK_CTRL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) val |= RC_PCIE_RST_OUTPUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) iproc_pcie_write_reg(pcie, IPROC_PCIE_CLK_CTRL, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) msleep(100);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) int iproc_pcie_shutdown(struct iproc_pcie *pcie)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) iproc_pcie_perst_ctrl(pcie, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) msleep(500);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) EXPORT_SYMBOL_GPL(iproc_pcie_shutdown);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) static int iproc_pcie_check_link(struct iproc_pcie *pcie)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) struct device *dev = pcie->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) u32 hdr_type, link_ctrl, link_status, class, val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) bool link_is_active = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) * PAXC connects to emulated endpoint devices directly and does not
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) * have a Serdes. Therefore skip the link detection logic here.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) if (pcie->ep_is_internal)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) val = iproc_pcie_read_reg(pcie, IPROC_PCIE_LINK_STATUS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) if (!(val & PCIE_PHYLINKUP) || !(val & PCIE_DL_ACTIVE)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) dev_err(dev, "PHY or data link is INACTIVE!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) /* make sure we are not in EP mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) iproc_pci_raw_config_read32(pcie, 0, PCI_HEADER_TYPE, 1, &hdr_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) if ((hdr_type & 0x7f) != PCI_HEADER_TYPE_BRIDGE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) dev_err(dev, "in EP mode, hdr=%#02x\n", hdr_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) /* force class to PCI_CLASS_BRIDGE_PCI (0x0604) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) #define PCI_BRIDGE_CTRL_REG_OFFSET 0x43c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) #define PCI_CLASS_BRIDGE_MASK 0xffff00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) #define PCI_CLASS_BRIDGE_SHIFT 8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) iproc_pci_raw_config_read32(pcie, 0, PCI_BRIDGE_CTRL_REG_OFFSET,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) 4, &class);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) class &= ~PCI_CLASS_BRIDGE_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) class |= (PCI_CLASS_BRIDGE_PCI << PCI_CLASS_BRIDGE_SHIFT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) iproc_pci_raw_config_write32(pcie, 0, PCI_BRIDGE_CTRL_REG_OFFSET,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) 4, class);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) /* check link status to see if link is active */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) iproc_pci_raw_config_read32(pcie, 0, IPROC_PCI_EXP_CAP + PCI_EXP_LNKSTA,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) 2, &link_status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) if (link_status & PCI_EXP_LNKSTA_NLW)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) link_is_active = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) if (!link_is_active) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) /* try GEN 1 link speed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) #define PCI_TARGET_LINK_SPEED_MASK 0xf
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) #define PCI_TARGET_LINK_SPEED_GEN2 0x2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) #define PCI_TARGET_LINK_SPEED_GEN1 0x1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) iproc_pci_raw_config_read32(pcie, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) IPROC_PCI_EXP_CAP + PCI_EXP_LNKCTL2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) 4, &link_ctrl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) if ((link_ctrl & PCI_TARGET_LINK_SPEED_MASK) ==
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) PCI_TARGET_LINK_SPEED_GEN2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) link_ctrl &= ~PCI_TARGET_LINK_SPEED_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) link_ctrl |= PCI_TARGET_LINK_SPEED_GEN1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) iproc_pci_raw_config_write32(pcie, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) IPROC_PCI_EXP_CAP + PCI_EXP_LNKCTL2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) 4, link_ctrl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) msleep(100);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) iproc_pci_raw_config_read32(pcie, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) IPROC_PCI_EXP_CAP + PCI_EXP_LNKSTA,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) 2, &link_status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) if (link_status & PCI_EXP_LNKSTA_NLW)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) link_is_active = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) dev_info(dev, "link: %s\n", link_is_active ? "UP" : "DOWN");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) return link_is_active ? 0 : -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) static void iproc_pcie_enable(struct iproc_pcie *pcie)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) iproc_pcie_write_reg(pcie, IPROC_PCIE_INTX_EN, SYS_RC_INTX_MASK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) static inline bool iproc_pcie_ob_is_valid(struct iproc_pcie *pcie,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) int window_idx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) u32 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) val = iproc_pcie_read_reg(pcie, MAP_REG(IPROC_PCIE_OARR0, window_idx));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) return !!(val & OARR_VALID);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) static inline int iproc_pcie_ob_write(struct iproc_pcie *pcie, int window_idx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) int size_idx, u64 axi_addr, u64 pci_addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) struct device *dev = pcie->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) u16 oarr_offset, omap_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) * Derive the OARR/OMAP offset from the first pair (OARR0/OMAP0) based
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) * on window index.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) oarr_offset = iproc_pcie_reg_offset(pcie, MAP_REG(IPROC_PCIE_OARR0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) window_idx));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) omap_offset = iproc_pcie_reg_offset(pcie, MAP_REG(IPROC_PCIE_OMAP0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) window_idx));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) if (iproc_pcie_reg_is_invalid(oarr_offset) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) iproc_pcie_reg_is_invalid(omap_offset))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) * Program the OARR registers. The upper 32-bit OARR register is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) * always right after the lower 32-bit OARR register.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) writel(lower_32_bits(axi_addr) | (size_idx << OARR_SIZE_CFG_SHIFT) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) OARR_VALID, pcie->base + oarr_offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) writel(upper_32_bits(axi_addr), pcie->base + oarr_offset + 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) /* now program the OMAP registers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) writel(lower_32_bits(pci_addr), pcie->base + omap_offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) writel(upper_32_bits(pci_addr), pcie->base + omap_offset + 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) dev_dbg(dev, "ob window [%d]: offset 0x%x axi %pap pci %pap\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) window_idx, oarr_offset, &axi_addr, &pci_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) dev_dbg(dev, "oarr lo 0x%x oarr hi 0x%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) readl(pcie->base + oarr_offset),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) readl(pcie->base + oarr_offset + 4));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) dev_dbg(dev, "omap lo 0x%x omap hi 0x%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) readl(pcie->base + omap_offset),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) readl(pcie->base + omap_offset + 4));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) * Some iProc SoCs require the SW to configure the outbound address mapping
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) * Outbound address translation:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) * iproc_pcie_address = axi_address - axi_offset
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) * OARR = iproc_pcie_address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) * OMAP = pci_addr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) * axi_addr -> iproc_pcie_address -> OARR -> OMAP -> pci_address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) static int iproc_pcie_setup_ob(struct iproc_pcie *pcie, u64 axi_addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) u64 pci_addr, resource_size_t size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) struct iproc_pcie_ob *ob = &pcie->ob;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) struct device *dev = pcie->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) int ret = -EINVAL, window_idx, size_idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) if (axi_addr < ob->axi_offset) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) dev_err(dev, "axi address %pap less than offset %pap\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) &axi_addr, &ob->axi_offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) * Translate the AXI address to the internal address used by the iProc
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) * PCIe core before programming the OARR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) axi_addr -= ob->axi_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) /* iterate through all OARR/OMAP mapping windows */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) for (window_idx = ob->nr_windows - 1; window_idx >= 0; window_idx--) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) const struct iproc_pcie_ob_map *ob_map =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) &pcie->ob_map[window_idx];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) * If current outbound window is already in use, move on to the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) * next one.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) if (iproc_pcie_ob_is_valid(pcie, window_idx))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) * Iterate through all supported window sizes within the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) * OARR/OMAP pair to find a match. Go through the window sizes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) * in a descending order.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962) for (size_idx = ob_map->nr_sizes - 1; size_idx >= 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) size_idx--) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) resource_size_t window_size =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) ob_map->window_sizes[size_idx] * SZ_1M;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) * Keep iterating until we reach the last window and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) * with the minimal window size at index zero. In this
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) * case, we take a compromise by mapping it using the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971) * minimum window size that can be supported
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) if (size < window_size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974) if (size_idx > 0 || window_idx > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978) * For the corner case of reaching the minimal
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979) * window size that can be supported on the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) * last window
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982) axi_addr = ALIGN_DOWN(axi_addr, window_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) pci_addr = ALIGN_DOWN(pci_addr, window_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) size = window_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987) if (!IS_ALIGNED(axi_addr, window_size) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) !IS_ALIGNED(pci_addr, window_size)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989) dev_err(dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990) "axi %pap or pci %pap not aligned\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) &axi_addr, &pci_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) * Match found! Program both OARR and OMAP and mark
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997) * them as a valid entry.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999) ret = iproc_pcie_ob_write(pcie, window_idx, size_idx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) axi_addr, pci_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) goto err_ob;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) size -= window_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) if (size == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) * If we are here, we are done with the current window,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) * but not yet finished all mappings. Need to move on
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) * to the next window.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) axi_addr += window_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) pci_addr += window_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) err_ob:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) dev_err(dev, "unable to configure outbound mapping\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) dev_err(dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) "axi %pap, axi offset %pap, pci %pap, res size %pap\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) &axi_addr, &ob->axi_offset, &pci_addr, &size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) static int iproc_pcie_map_ranges(struct iproc_pcie *pcie,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) struct list_head *resources)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) struct device *dev = pcie->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) struct resource_entry *window;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) resource_list_for_each_entry(window, resources) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) struct resource *res = window->res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) u64 res_type = resource_type(res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) switch (res_type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) case IORESOURCE_IO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) case IORESOURCE_BUS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) case IORESOURCE_MEM:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) ret = iproc_pcie_setup_ob(pcie, res->start,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) res->start - window->offset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) resource_size(res));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) dev_err(dev, "invalid resource %pR\n", res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) static inline bool iproc_pcie_ib_is_in_use(struct iproc_pcie *pcie,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) int region_idx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) const struct iproc_pcie_ib_map *ib_map = &pcie->ib_map[region_idx];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) u32 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) val = iproc_pcie_read_reg(pcie, MAP_REG(IPROC_PCIE_IARR0, region_idx));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) return !!(val & (BIT(ib_map->nr_sizes) - 1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) static inline bool iproc_pcie_ib_check_type(const struct iproc_pcie_ib_map *ib_map,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) enum iproc_pcie_ib_map_type type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) return !!(ib_map->type == type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) static int iproc_pcie_ib_write(struct iproc_pcie *pcie, int region_idx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) int size_idx, int nr_windows, u64 axi_addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) u64 pci_addr, resource_size_t size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) struct device *dev = pcie->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) const struct iproc_pcie_ib_map *ib_map = &pcie->ib_map[region_idx];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) u16 iarr_offset, imap_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) u32 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) int window_idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) iarr_offset = iproc_pcie_reg_offset(pcie,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) MAP_REG(IPROC_PCIE_IARR0, region_idx));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) imap_offset = iproc_pcie_reg_offset(pcie,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) MAP_REG(IPROC_PCIE_IMAP0, region_idx));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) if (iproc_pcie_reg_is_invalid(iarr_offset) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) iproc_pcie_reg_is_invalid(imap_offset))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) dev_dbg(dev, "ib region [%d]: offset 0x%x axi %pap pci %pap\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) region_idx, iarr_offset, &axi_addr, &pci_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) * Program the IARR registers. The upper 32-bit IARR register is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) * always right after the lower 32-bit IARR register.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) writel(lower_32_bits(pci_addr) | BIT(size_idx),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) pcie->base + iarr_offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) writel(upper_32_bits(pci_addr), pcie->base + iarr_offset + 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) dev_dbg(dev, "iarr lo 0x%x iarr hi 0x%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) readl(pcie->base + iarr_offset),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) readl(pcie->base + iarr_offset + 4));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) * Now program the IMAP registers. Each IARR region may have one or
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) * more IMAP windows.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) size >>= ilog2(nr_windows);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) for (window_idx = 0; window_idx < nr_windows; window_idx++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) val = readl(pcie->base + imap_offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) val |= lower_32_bits(axi_addr) | IMAP_VALID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) writel(val, pcie->base + imap_offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) writel(upper_32_bits(axi_addr),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) pcie->base + imap_offset + ib_map->imap_addr_offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) dev_dbg(dev, "imap window [%d] lo 0x%x hi 0x%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) window_idx, readl(pcie->base + imap_offset),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) readl(pcie->base + imap_offset +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) ib_map->imap_addr_offset));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) imap_offset += ib_map->imap_window_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) axi_addr += size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) static int iproc_pcie_setup_ib(struct iproc_pcie *pcie,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) struct resource_entry *entry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) enum iproc_pcie_ib_map_type type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) struct device *dev = pcie->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) struct iproc_pcie_ib *ib = &pcie->ib;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) unsigned int region_idx, size_idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) u64 axi_addr = entry->res->start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) u64 pci_addr = entry->res->start - entry->offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) resource_size_t size = resource_size(entry->res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) /* iterate through all IARR mapping regions */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) for (region_idx = 0; region_idx < ib->nr_regions; region_idx++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) const struct iproc_pcie_ib_map *ib_map =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) &pcie->ib_map[region_idx];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) * If current inbound region is already in use or not a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) * compatible type, move on to the next.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) if (iproc_pcie_ib_is_in_use(pcie, region_idx) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) !iproc_pcie_ib_check_type(ib_map, type))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) /* iterate through all supported region sizes to find a match */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) for (size_idx = 0; size_idx < ib_map->nr_sizes; size_idx++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) resource_size_t region_size =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) ib_map->region_sizes[size_idx] * ib_map->size_unit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) if (size != region_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) if (!IS_ALIGNED(axi_addr, region_size) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) !IS_ALIGNED(pci_addr, region_size)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) dev_err(dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) "axi %pap or pci %pap not aligned\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) &axi_addr, &pci_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) /* Match found! Program IARR and all IMAP windows. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) ret = iproc_pcie_ib_write(pcie, region_idx, size_idx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) ib_map->nr_windows, axi_addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) pci_addr, size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) goto err_ib;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187) err_ib:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188) dev_err(dev, "unable to configure inbound mapping\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) dev_err(dev, "axi %pap, pci %pap, res size %pap\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) &axi_addr, &pci_addr, &size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) static int iproc_pcie_map_dma_ranges(struct iproc_pcie *pcie)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) struct pci_host_bridge *host = pci_host_bridge_from_priv(pcie);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) struct resource_entry *entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) resource_list_for_each_entry(entry, &host->dma_ranges) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) /* Each range entry corresponds to an inbound mapping region */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) ret = iproc_pcie_setup_ib(pcie, entry, IPROC_PCIE_IB_MAP_MEM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) static void iproc_pcie_invalidate_mapping(struct iproc_pcie *pcie)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) struct iproc_pcie_ib *ib = &pcie->ib;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) struct iproc_pcie_ob *ob = &pcie->ob;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) int idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) if (pcie->ep_is_internal)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220) if (pcie->need_ob_cfg) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) /* iterate through all OARR mapping regions */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) for (idx = ob->nr_windows - 1; idx >= 0; idx--) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) iproc_pcie_write_reg(pcie,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) MAP_REG(IPROC_PCIE_OARR0, idx), 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) if (pcie->need_ib_cfg) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229) /* iterate through all IARR mapping regions */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230) for (idx = 0; idx < ib->nr_regions; idx++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231) iproc_pcie_write_reg(pcie,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232) MAP_REG(IPROC_PCIE_IARR0, idx), 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237) static int iproce_pcie_get_msi(struct iproc_pcie *pcie,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) struct device_node *msi_node,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239) u64 *msi_addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241) struct device *dev = pcie->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) struct resource res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246) * Check if 'msi-map' points to ARM GICv3 ITS, which is the only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247) * supported external MSI controller that requires steering.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249) if (!of_device_is_compatible(msi_node, "arm,gic-v3-its")) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250) dev_err(dev, "unable to find compatible MSI controller\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254) /* derive GITS_TRANSLATER address from GICv3 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255) ret = of_address_to_resource(msi_node, 0, &res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257) dev_err(dev, "unable to obtain MSI controller resources\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261) *msi_addr = res.start + GITS_TRANSLATER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265) static int iproc_pcie_paxb_v2_msi_steer(struct iproc_pcie *pcie, u64 msi_addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268) struct resource_entry entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270) memset(&entry, 0, sizeof(entry));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271) entry.res = &entry.__res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273) msi_addr &= ~(SZ_32K - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274) entry.res->start = msi_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275) entry.res->end = msi_addr + SZ_32K - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277) ret = iproc_pcie_setup_ib(pcie, &entry, IPROC_PCIE_IB_MAP_IO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281) static void iproc_pcie_paxc_v2_msi_steer(struct iproc_pcie *pcie, u64 msi_addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282) bool enable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284) u32 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286) if (!enable) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288) * Disable PAXC MSI steering. All write transfers will be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289) * treated as non-MSI transfers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291) val = iproc_pcie_read_reg(pcie, IPROC_PCIE_MSI_EN_CFG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292) val &= ~MSI_ENABLE_CFG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293) iproc_pcie_write_reg(pcie, IPROC_PCIE_MSI_EN_CFG, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298) * Program bits [43:13] of address of GITS_TRANSLATER register into
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299) * bits [30:0] of the MSI base address register. In fact, in all iProc
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300) * based SoCs, all I/O register bases are well below the 32-bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301) * boundary, so we can safely assume bits [43:32] are always zeros.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303) iproc_pcie_write_reg(pcie, IPROC_PCIE_MSI_BASE_ADDR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304) (u32)(msi_addr >> 13));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306) /* use a default 8K window size */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307) iproc_pcie_write_reg(pcie, IPROC_PCIE_MSI_WINDOW_SIZE, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309) /* steering MSI to GICv3 ITS */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310) val = iproc_pcie_read_reg(pcie, IPROC_PCIE_MSI_GIC_MODE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311) val |= GIC_V3_CFG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312) iproc_pcie_write_reg(pcie, IPROC_PCIE_MSI_GIC_MODE, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1315) * Program bits [43:2] of address of GITS_TRANSLATER register into the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1316) * iProc MSI address registers.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1317) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1318) msi_addr >>= 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1319) iproc_pcie_write_reg(pcie, IPROC_PCIE_MSI_ADDR_HI,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1320) upper_32_bits(msi_addr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1321) iproc_pcie_write_reg(pcie, IPROC_PCIE_MSI_ADDR_LO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1322) lower_32_bits(msi_addr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1323)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1324) /* enable MSI */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1325) val = iproc_pcie_read_reg(pcie, IPROC_PCIE_MSI_EN_CFG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1326) val |= MSI_ENABLE_CFG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1327) iproc_pcie_write_reg(pcie, IPROC_PCIE_MSI_EN_CFG, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1328) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1329)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1330) static int iproc_pcie_msi_steer(struct iproc_pcie *pcie,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1331) struct device_node *msi_node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1332) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1333) struct device *dev = pcie->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1334) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1335) u64 msi_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1336)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1337) ret = iproce_pcie_get_msi(pcie, msi_node, &msi_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1338) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1339) dev_err(dev, "msi steering failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1340) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1341) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1342)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1343) switch (pcie->type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1344) case IPROC_PCIE_PAXB_V2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1345) ret = iproc_pcie_paxb_v2_msi_steer(pcie, msi_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1346) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1347) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1348) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1349) case IPROC_PCIE_PAXC_V2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1350) iproc_pcie_paxc_v2_msi_steer(pcie, msi_addr, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1351) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1352) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1353) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1354) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1355)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1356) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1357) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1358)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1359) static int iproc_pcie_msi_enable(struct iproc_pcie *pcie)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1360) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1361) struct device_node *msi_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1362) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1363)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1364) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1365) * Either the "msi-parent" or the "msi-map" phandle needs to exist
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1366) * for us to obtain the MSI node.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1367) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1368)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1369) msi_node = of_parse_phandle(pcie->dev->of_node, "msi-parent", 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1370) if (!msi_node) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1371) const __be32 *msi_map = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1372) int len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1373) u32 phandle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1374)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1375) msi_map = of_get_property(pcie->dev->of_node, "msi-map", &len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1376) if (!msi_map)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1377) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1378)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1379) phandle = be32_to_cpup(msi_map + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1380) msi_node = of_find_node_by_phandle(phandle);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1381) if (!msi_node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1382) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1383) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1384)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1385) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1386) * Certain revisions of the iProc PCIe controller require additional
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1387) * configurations to steer the MSI writes towards an external MSI
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1388) * controller.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1389) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1390) if (pcie->need_msi_steer) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1391) ret = iproc_pcie_msi_steer(pcie, msi_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1392) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1393) goto out_put_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1394) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1395)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1396) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1397) * If another MSI controller is being used, the call below should fail
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1398) * but that is okay
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1399) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1400) ret = iproc_msi_init(pcie, msi_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1401)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1402) out_put_node:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1403) of_node_put(msi_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1404) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1405) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1406)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1407) static void iproc_pcie_msi_disable(struct iproc_pcie *pcie)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1408) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1409) iproc_msi_exit(pcie);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1410) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1411)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1412) static int iproc_pcie_rev_init(struct iproc_pcie *pcie)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1413) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1414) struct device *dev = pcie->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1415) unsigned int reg_idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1416) const u16 *regs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1417)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1418) switch (pcie->type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1419) case IPROC_PCIE_PAXB_BCMA:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1420) regs = iproc_pcie_reg_paxb_bcma;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1421) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1422) case IPROC_PCIE_PAXB:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1423) regs = iproc_pcie_reg_paxb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1424) pcie->has_apb_err_disable = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1425) if (pcie->need_ob_cfg) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1426) pcie->ob_map = paxb_ob_map;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1427) pcie->ob.nr_windows = ARRAY_SIZE(paxb_ob_map);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1428) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1429) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1430) case IPROC_PCIE_PAXB_V2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1431) regs = iproc_pcie_reg_paxb_v2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1432) pcie->iproc_cfg_read = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1433) pcie->has_apb_err_disable = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1434) if (pcie->need_ob_cfg) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1435) pcie->ob_map = paxb_v2_ob_map;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1436) pcie->ob.nr_windows = ARRAY_SIZE(paxb_v2_ob_map);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1437) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1438) pcie->ib.nr_regions = ARRAY_SIZE(paxb_v2_ib_map);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1439) pcie->ib_map = paxb_v2_ib_map;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1440) pcie->need_msi_steer = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1441) dev_warn(dev, "reads of config registers that contain %#x return incorrect data\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1442) CFG_RETRY_STATUS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1443) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1444) case IPROC_PCIE_PAXC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1445) regs = iproc_pcie_reg_paxc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1446) pcie->ep_is_internal = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1447) pcie->iproc_cfg_read = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1448) pcie->rej_unconfig_pf = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1449) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1450) case IPROC_PCIE_PAXC_V2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1451) regs = iproc_pcie_reg_paxc_v2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1452) pcie->ep_is_internal = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1453) pcie->iproc_cfg_read = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1454) pcie->rej_unconfig_pf = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1455) pcie->need_msi_steer = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1456) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1457) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1458) dev_err(dev, "incompatible iProc PCIe interface\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1459) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1460) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1461)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1462) pcie->reg_offsets = devm_kcalloc(dev, IPROC_PCIE_MAX_NUM_REG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1463) sizeof(*pcie->reg_offsets),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1464) GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1465) if (!pcie->reg_offsets)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1466) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1467)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1468) /* go through the register table and populate all valid registers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1469) pcie->reg_offsets[0] = (pcie->type == IPROC_PCIE_PAXC_V2) ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1470) IPROC_PCIE_REG_INVALID : regs[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1471) for (reg_idx = 1; reg_idx < IPROC_PCIE_MAX_NUM_REG; reg_idx++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1472) pcie->reg_offsets[reg_idx] = regs[reg_idx] ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1473) regs[reg_idx] : IPROC_PCIE_REG_INVALID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1474)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1475) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1476) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1477)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1478) int iproc_pcie_setup(struct iproc_pcie *pcie, struct list_head *res)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1479) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1480) struct device *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1481) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1482) struct pci_host_bridge *host = pci_host_bridge_from_priv(pcie);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1483)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1484) dev = pcie->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1485)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1486) ret = iproc_pcie_rev_init(pcie);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1487) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1488) dev_err(dev, "unable to initialize controller parameters\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1489) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1490) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1491)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1492) ret = phy_init(pcie->phy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1493) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1494) dev_err(dev, "unable to initialize PCIe PHY\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1495) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1496) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1497)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1498) ret = phy_power_on(pcie->phy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1499) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1500) dev_err(dev, "unable to power on PCIe PHY\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1501) goto err_exit_phy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1502) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1503)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1504) iproc_pcie_perst_ctrl(pcie, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1505) iproc_pcie_perst_ctrl(pcie, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1506)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1507) iproc_pcie_invalidate_mapping(pcie);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1508)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1509) if (pcie->need_ob_cfg) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1510) ret = iproc_pcie_map_ranges(pcie, res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1511) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1512) dev_err(dev, "map failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1513) goto err_power_off_phy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1514) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1515) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1516)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1517) if (pcie->need_ib_cfg) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1518) ret = iproc_pcie_map_dma_ranges(pcie);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1519) if (ret && ret != -ENOENT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1520) goto err_power_off_phy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1521) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1522)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1523) ret = iproc_pcie_check_link(pcie);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1524) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1525) dev_err(dev, "no PCIe EP device detected\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1526) goto err_power_off_phy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1527) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1528)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1529) iproc_pcie_enable(pcie);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1530)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1531) if (IS_ENABLED(CONFIG_PCI_MSI))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1532) if (iproc_pcie_msi_enable(pcie))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1533) dev_info(dev, "not using iProc MSI\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1534)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1535) host->ops = &iproc_pcie_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1536) host->sysdata = pcie;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1537) host->map_irq = pcie->map_irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1538)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1539) ret = pci_host_probe(host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1540) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1541) dev_err(dev, "failed to scan host: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1542) goto err_power_off_phy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1543) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1544)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1545) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1546)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1547) err_power_off_phy:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1548) phy_power_off(pcie->phy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1549) err_exit_phy:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1550) phy_exit(pcie->phy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1551) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1552) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1553) EXPORT_SYMBOL(iproc_pcie_setup);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1554)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1555) int iproc_pcie_remove(struct iproc_pcie *pcie)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1556) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1557) struct pci_host_bridge *host = pci_host_bridge_from_priv(pcie);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1558)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1559) pci_stop_root_bus(host->bus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1560) pci_remove_root_bus(host->bus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1561)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1562) iproc_pcie_msi_disable(pcie);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1563)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1564) phy_power_off(pcie->phy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1565) phy_exit(pcie->phy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1566)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1567) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1568) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1569) EXPORT_SYMBOL(iproc_pcie_remove);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1570)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1571) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1572) * The MSI parsing logic in certain revisions of Broadcom PAXC based root
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1573) * complex does not work and needs to be disabled
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1574) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1575) static void quirk_paxc_disable_msi_parsing(struct pci_dev *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1576) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1577) struct iproc_pcie *pcie = iproc_data(pdev->bus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1578)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1579) if (pdev->hdr_type == PCI_HEADER_TYPE_BRIDGE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1580) iproc_pcie_paxc_v2_msi_steer(pcie, 0, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1581) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1582) DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_BROADCOM, 0x16f0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1583) quirk_paxc_disable_msi_parsing);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1584) DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_BROADCOM, 0xd802,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1585) quirk_paxc_disable_msi_parsing);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1586) DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_BROADCOM, 0xd804,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1587) quirk_paxc_disable_msi_parsing);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1588)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1589) static void quirk_paxc_bridge(struct pci_dev *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1590) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1591) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1592) * The PCI config space is shared with the PAXC root port and the first
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1593) * Ethernet device. So, we need to workaround this by telling the PCI
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1594) * code that the bridge is not an Ethernet device.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1595) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1596) if (pdev->hdr_type == PCI_HEADER_TYPE_BRIDGE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1597) pdev->class = PCI_CLASS_BRIDGE_PCI << 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1598)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1599) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1600) * MPSS is not being set properly (as it is currently 0). This is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1601) * because that area of the PCI config space is hard coded to zero, and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1602) * is not modifiable by firmware. Set this to 2 (e.g., 512 byte MPS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1603) * so that the MPS can be set to the real max value.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1604) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1605) pdev->pcie_mpss = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1606) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1607) DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_BROADCOM, 0x16cd, quirk_paxc_bridge);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1608) DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_BROADCOM, 0x16f0, quirk_paxc_bridge);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1609) DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_BROADCOM, 0xd750, quirk_paxc_bridge);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1610) DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_BROADCOM, 0xd802, quirk_paxc_bridge);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1611) DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_BROADCOM, 0xd804, quirk_paxc_bridge);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1612)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1613) MODULE_AUTHOR("Ray Jui <rjui@broadcom.com>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1614) MODULE_DESCRIPTION("Broadcom iPROC PCIe common driver");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1615) MODULE_LICENSE("GPL v2");