Hou Zhiqiang | e5d79c4 | 2019-04-08 10:15:46 +0000 | [diff] [blame] | 1 | /* SPDX-License-Identifier: GPL-2.0+ */ |
| 2 | /* |
| 3 | * Copyright 2018-2019 NXP |
| 4 | * |
| 5 | * PCIe Gen4 driver for NXP Layerscape SoCs |
| 6 | * Author: Hou Zhiqiang <Minder.Hou@gmail.com> |
| 7 | */ |
| 8 | |
| 9 | #ifndef _PCIE_LAYERSCAPE_GEN4_H_ |
| 10 | #define _PCIE_LAYERSCAPE_GEN4_H_ |
| 11 | #include <pci.h> |
Simon Glass | 4dcacfc | 2020-05-10 11:40:13 -0600 | [diff] [blame] | 12 | #include <linux/bitops.h> |
Hou Zhiqiang | e5d79c4 | 2019-04-08 10:15:46 +0000 | [diff] [blame] | 13 | |
| 14 | #ifndef CONFIG_SYS_PCI_MEMORY_SIZE |
| 15 | #define CONFIG_SYS_PCI_MEMORY_SIZE (4 * 1024 * 1024 * 1024ULL) |
| 16 | #endif |
| 17 | |
| 18 | #ifndef CONFIG_SYS_PCI_EP_MEMORY_BASE |
| 19 | #define CONFIG_SYS_PCI_EP_MEMORY_BASE CONFIG_SYS_LOAD_ADDR |
| 20 | #endif |
| 21 | |
| 22 | #define PCIE_PF_NUM 2 |
| 23 | #define PCIE_VF_NUM 32 |
| 24 | |
| 25 | #define LS_G4_PF0 0 |
| 26 | #define LS_G4_PF1 1 |
| 27 | #define PF_BAR_NUM 4 |
| 28 | #define VF_BAR_NUM 4 |
| 29 | #define PCIE_BAR_SIZE (8 * 1024) /* 8K */ |
| 30 | #define PCIE_BAR0_SIZE PCIE_BAR_SIZE |
| 31 | #define PCIE_BAR1_SIZE PCIE_BAR_SIZE |
| 32 | #define PCIE_BAR2_SIZE PCIE_BAR_SIZE |
| 33 | #define PCIE_BAR4_SIZE PCIE_BAR_SIZE |
| 34 | #define SIZE_1T (1024 * 1024 * 1024 * 1024ULL) |
| 35 | |
| 36 | /* GPEX CSR */ |
| 37 | #define GPEX_CLASSCODE 0x474 |
| 38 | #define GPEX_CLASSCODE_SHIFT 16 |
| 39 | #define GPEX_CLASSCODE_MASK 0xffff |
| 40 | |
| 41 | #define GPEX_CFG_READY 0x4b0 |
| 42 | #define PCIE_CONFIG_READY BIT(0) |
| 43 | |
| 44 | #define GPEX_BAR_ENABLE 0x4d4 |
| 45 | #define GPEX_BAR_SIZE_LDW 0x4d8 |
| 46 | #define GPEX_BAR_SIZE_UDW 0x4dC |
| 47 | #define GPEX_BAR_SELECT 0x4e0 |
| 48 | |
| 49 | #define BAR_POS(bar, pf, vf_bar) \ |
| 50 | ((bar) + (pf) * PF_BAR_NUM + (vf_bar) * PCIE_PF_NUM * PF_BAR_NUM) |
| 51 | |
| 52 | #define GPEX_SRIOV_INIT_VFS_TOTAL_VF(pf) (0x644 + (pf) * 4) |
| 53 | #define TTL_VF_MASK 0xffff |
| 54 | #define TTL_VF_SHIFT 16 |
| 55 | #define INI_VF_MASK 0xffff |
| 56 | #define INI_VF_SHIFT 0 |
| 57 | #define GPEX_SRIOV_VF_OFFSET_STRIDE(pf) (0x704 + (pf) * 4) |
| 58 | |
| 59 | /* PAB CSR */ |
| 60 | #define PAB_CTRL 0x808 |
| 61 | #define PAB_CTRL_APIO_EN BIT(0) |
| 62 | #define PAB_CTRL_PPIO_EN BIT(1) |
| 63 | #define PAB_CTRL_MAX_BRST_LEN_SHIFT 4 |
| 64 | #define PAB_CTRL_MAX_BRST_LEN_MASK 0x3 |
| 65 | #define PAB_CTRL_PAGE_SEL_SHIFT 13 |
| 66 | #define PAB_CTRL_PAGE_SEL_MASK 0x3f |
| 67 | #define PAB_CTRL_FUNC_SEL_SHIFT 19 |
| 68 | #define PAB_CTRL_FUNC_SEL_MASK 0x1ff |
| 69 | |
| 70 | #define PAB_RST_CTRL 0x820 |
| 71 | #define PAB_BR_STAT 0x80c |
| 72 | |
| 73 | /* AXI PIO Engines */ |
| 74 | #define PAB_AXI_PIO_CTRL(idx) (0x840 + 0x10 * (idx)) |
| 75 | #define APIO_EN BIT(0) |
| 76 | #define MEM_WIN_EN BIT(1) |
| 77 | #define IO_WIN_EN BIT(2) |
| 78 | #define CFG_WIN_EN BIT(3) |
| 79 | #define PAB_AXI_PIO_STAT(idx) (0x844 + 0x10 * (idx)) |
| 80 | #define PAB_AXI_PIO_SL_CMD_STAT(idx) (0x848 + 0x10 * (idx)) |
| 81 | #define PAB_AXI_PIO_SL_ADDR_STAT(idx) (0x84c + 0x10 * (idx)) |
| 82 | #define PAB_AXI_PIO_SL_EXT_ADDR_STAT(idx) (0xb8a0 + 0x4 * (idx)) |
| 83 | |
| 84 | /* PEX PIO Engines */ |
| 85 | #define PAB_PEX_PIO_CTRL(idx) (0x8c0 + 0x10 * (idx)) |
| 86 | #define PPIO_EN BIT(0) |
| 87 | #define PAB_PEX_PIO_STAT(idx) (0x8c4 + 0x10 * (idx)) |
| 88 | #define PAB_PEX_PIO_MT_STAT(idx) (0x8c8 + 0x10 * (idx)) |
| 89 | |
| 90 | #define INDIRECT_ADDR_BNDRY 0xc00 |
| 91 | #define PAGE_IDX_SHIFT 10 |
| 92 | #define PAGE_ADDR_MASK 0x3ff |
| 93 | |
| 94 | #define OFFSET_TO_PAGE_IDX(off) \ |
| 95 | (((off) >> PAGE_IDX_SHIFT) & PAB_CTRL_PAGE_SEL_MASK) |
| 96 | |
| 97 | #define OFFSET_TO_PAGE_ADDR(off) \ |
| 98 | (((off) & PAGE_ADDR_MASK) | INDIRECT_ADDR_BNDRY) |
| 99 | |
| 100 | /* APIO WINs */ |
| 101 | #define PAB_AXI_AMAP_CTRL(idx) (0xba0 + 0x10 * (idx)) |
| 102 | #define PAB_EXT_AXI_AMAP_SIZE(idx) (0xbaf0 + 0x4 * (idx)) |
| 103 | #define PAB_AXI_AMAP_AXI_WIN(idx) (0xba4 + 0x10 * (idx)) |
| 104 | #define PAB_EXT_AXI_AMAP_AXI_WIN(idx) (0x80a0 + 0x4 * (idx)) |
| 105 | #define PAB_AXI_AMAP_PEX_WIN_L(idx) (0xba8 + 0x10 * (idx)) |
| 106 | #define PAB_AXI_AMAP_PEX_WIN_H(idx) (0xbac + 0x10 * (idx)) |
| 107 | #define PAB_AXI_AMAP_PCI_HDR_PARAM(idx) (0x5ba0 + 0x4 * (idx)) |
| 108 | #define FUNC_NUM_PCIE_MASK GENMASK(7, 0) |
| 109 | |
| 110 | #define AXI_AMAP_CTRL_EN BIT(0) |
| 111 | #define AXI_AMAP_CTRL_TYPE_SHIFT 1 |
| 112 | #define AXI_AMAP_CTRL_TYPE_MASK 0x3 |
| 113 | #define AXI_AMAP_CTRL_SIZE_SHIFT 10 |
| 114 | #define AXI_AMAP_CTRL_SIZE_MASK 0x3fffff |
| 115 | |
| 116 | #define PAB_TARGET_BUS(x) (((x) & 0xff) << 24) |
| 117 | #define PAB_TARGET_DEV(x) (((x) & 0x1f) << 19) |
| 118 | #define PAB_TARGET_FUNC(x) (((x) & 0x7) << 16) |
| 119 | |
| 120 | #define PAB_AXI_TYPE_CFG 0x00 |
| 121 | #define PAB_AXI_TYPE_IO 0x01 |
| 122 | #define PAB_AXI_TYPE_MEM 0x02 |
| 123 | #define PAB_AXI_TYPE_ATOM 0x03 |
| 124 | |
| 125 | #define PAB_WINS_NUM 256 |
| 126 | |
| 127 | /* PPIO WINs RC mode */ |
| 128 | #define PAB_PEX_AMAP_CTRL(idx) (0x4ba0 + 0x10 * (idx)) |
| 129 | #define PAB_EXT_PEX_AMAP_SIZE(idx) (0xbef0 + 0x04 * (idx)) |
| 130 | #define PAB_PEX_AMAP_AXI_WIN(idx) (0x4ba4 + 0x10 * (idx)) |
| 131 | #define PAB_EXT_PEX_AMAP_AXI_WIN(idx) (0xb4a0 + 0x04 * (idx)) |
| 132 | #define PAB_PEX_AMAP_PEX_WIN_L(idx) (0x4ba8 + 0x10 * (idx)) |
| 133 | #define PAB_PEX_AMAP_PEX_WIN_H(idx) (0x4bac + 0x10 * (idx)) |
| 134 | |
| 135 | #define IB_TYPE_MEM_F 0x2 |
| 136 | #define IB_TYPE_MEM_NF 0x3 |
| 137 | |
| 138 | #define PEX_AMAP_CTRL_TYPE_SHIFT 0x1 |
| 139 | #define PEX_AMAP_CTRL_EN_SHIFT 0x0 |
| 140 | #define PEX_AMAP_CTRL_TYPE_MASK 0x3 |
| 141 | #define PEX_AMAP_CTRL_EN_MASK 0x1 |
| 142 | |
| 143 | /* PPIO WINs EP mode */ |
| 144 | #define PAB_PEX_BAR_AMAP(pf, bar) \ |
| 145 | (0x1ba0 + 0x20 * (pf) + 4 * (bar)) |
| 146 | #define BAR_AMAP_EN BIT(0) |
| 147 | #define PAB_EXT_PEX_BAR_AMAP(pf, bar) \ |
| 148 | (0x84a0 + 0x20 * (pf) + 4 * (bar)) |
| 149 | |
| 150 | /* CCSR registers */ |
| 151 | #define PCIE_LINK_CTRL_STA 0x5c |
| 152 | #define PCIE_LINK_SPEED_SHIFT 16 |
| 153 | #define PCIE_LINK_SPEED_MASK 0x0f |
| 154 | #define PCIE_LINK_WIDTH_SHIFT 20 |
| 155 | #define PCIE_LINK_WIDTH_MASK 0x3f |
| 156 | #define PCIE_SRIOV_CAPABILITY 0x2a0 |
| 157 | #define PCIE_SRIOV_VF_OFFSET_STRIDE 0x2b4 |
| 158 | |
| 159 | /* LUT registers */ |
| 160 | #define PCIE_LUT_UDR(n) (0x800 + (n) * 8) |
| 161 | #define PCIE_LUT_LDR(n) (0x804 + (n) * 8) |
| 162 | #define PCIE_LUT_ENABLE BIT(31) |
| 163 | #define PCIE_LUT_ENTRY_COUNT 32 |
| 164 | |
| 165 | /* PF control registers */ |
| 166 | #define PCIE_LTSSM_STA 0x7fc |
| 167 | #define LTSSM_STATE_MASK 0x7f |
| 168 | #define LTSSM_PCIE_L0 0x2d /* L0 state */ |
| 169 | |
| 170 | #define PCIE_SRDS_PRTCL(idx) (PCIE1 + (idx)) |
| 171 | #define PCIE_SYS_BASE_ADDR 0x3400000 |
| 172 | #define PCIE_CCSR_SIZE 0x0100000 |
| 173 | |
| 174 | struct ls_pcie_g4 { |
| 175 | int idx; |
| 176 | struct list_head list; |
| 177 | struct udevice *bus; |
| 178 | struct fdt_resource ccsr_res; |
| 179 | struct fdt_resource cfg_res; |
| 180 | struct fdt_resource lut_res; |
| 181 | struct fdt_resource pf_ctrl_res; |
| 182 | void __iomem *ccsr; |
| 183 | void __iomem *cfg; |
| 184 | void __iomem *lut; |
| 185 | void __iomem *pf_ctrl; |
| 186 | bool big_endian; |
| 187 | bool enabled; |
| 188 | int next_lut_index; |
| 189 | struct pci_controller hose; |
| 190 | int stream_id_cur; |
| 191 | int mode; |
| 192 | int sriov_support; |
| 193 | }; |
| 194 | |
| 195 | extern struct list_head ls_pcie_g4_list; |
| 196 | |
| 197 | static inline void lut_writel(struct ls_pcie_g4 *pcie, unsigned int value, |
| 198 | unsigned int offset) |
| 199 | { |
| 200 | if (pcie->big_endian) |
| 201 | out_be32(pcie->lut + offset, value); |
| 202 | else |
| 203 | out_le32(pcie->lut + offset, value); |
| 204 | } |
| 205 | |
| 206 | static inline u32 lut_readl(struct ls_pcie_g4 *pcie, unsigned int offset) |
| 207 | { |
| 208 | if (pcie->big_endian) |
| 209 | return in_be32(pcie->lut + offset); |
| 210 | else |
| 211 | return in_le32(pcie->lut + offset); |
| 212 | } |
| 213 | |
| 214 | static inline void ccsr_set_page(struct ls_pcie_g4 *pcie, u8 pg_idx) |
| 215 | { |
| 216 | u32 val; |
| 217 | |
| 218 | val = in_le32(pcie->ccsr + PAB_CTRL); |
| 219 | val &= ~(PAB_CTRL_PAGE_SEL_MASK << PAB_CTRL_PAGE_SEL_SHIFT); |
| 220 | val |= (pg_idx & PAB_CTRL_PAGE_SEL_MASK) << PAB_CTRL_PAGE_SEL_SHIFT; |
| 221 | |
| 222 | out_le32(pcie->ccsr + PAB_CTRL, val); |
| 223 | } |
| 224 | |
| 225 | static inline unsigned int ccsr_readl(struct ls_pcie_g4 *pcie, u32 offset) |
| 226 | { |
| 227 | if (offset < INDIRECT_ADDR_BNDRY) { |
| 228 | ccsr_set_page(pcie, 0); |
| 229 | return in_le32(pcie->ccsr + offset); |
| 230 | } |
| 231 | |
| 232 | ccsr_set_page(pcie, OFFSET_TO_PAGE_IDX(offset)); |
| 233 | return in_le32(pcie->ccsr + OFFSET_TO_PAGE_ADDR(offset)); |
| 234 | } |
| 235 | |
| 236 | static inline void ccsr_writel(struct ls_pcie_g4 *pcie, u32 offset, u32 value) |
| 237 | { |
| 238 | if (offset < INDIRECT_ADDR_BNDRY) { |
| 239 | ccsr_set_page(pcie, 0); |
| 240 | out_le32(pcie->ccsr + offset, value); |
| 241 | } else { |
| 242 | ccsr_set_page(pcie, OFFSET_TO_PAGE_IDX(offset)); |
| 243 | out_le32(pcie->ccsr + OFFSET_TO_PAGE_ADDR(offset), value); |
| 244 | } |
| 245 | } |
| 246 | |
| 247 | static inline unsigned int pf_ctrl_readl(struct ls_pcie_g4 *pcie, u32 offset) |
| 248 | { |
| 249 | if (pcie->big_endian) |
| 250 | return in_be32(pcie->pf_ctrl + offset); |
| 251 | else |
| 252 | return in_le32(pcie->pf_ctrl + offset); |
| 253 | } |
| 254 | |
| 255 | static inline void pf_ctrl_writel(struct ls_pcie_g4 *pcie, u32 offset, |
| 256 | u32 value) |
| 257 | { |
| 258 | if (pcie->big_endian) |
| 259 | out_be32(pcie->pf_ctrl + offset, value); |
| 260 | else |
| 261 | out_le32(pcie->pf_ctrl + offset, value); |
| 262 | } |
| 263 | |
| 264 | #endif /* _PCIE_LAYERSCAPE_GEN4_H_ */ |