0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034 #include "csio_hw.h"
0035 #include "csio_init.h"
0036
0037 static int
0038 csio_t5_set_mem_win(struct csio_hw *hw, uint32_t win)
0039 {
0040 u32 mem_win_base;
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052 mem_win_base = MEMWIN_BASE;
0053
0054
0055
0056
0057
0058
0059 csio_wr_reg32(hw, mem_win_base | BIR_V(0) |
0060 WINDOW_V(ilog2(MEMWIN_APERTURE) - 10),
0061 PCIE_MEM_ACCESS_REG(PCIE_MEM_ACCESS_BASE_WIN_A, win));
0062 csio_rd_reg32(hw,
0063 PCIE_MEM_ACCESS_REG(PCIE_MEM_ACCESS_BASE_WIN_A, win));
0064
0065 return 0;
0066 }
0067
0068
0069
0070
0071 static void
0072 csio_t5_pcie_intr_handler(struct csio_hw *hw)
0073 {
0074 static struct intr_info pcie_intr_info[] = {
0075 { MSTGRPPERR_F, "Master Response Read Queue parity error",
0076 -1, 1 },
0077 { MSTTIMEOUTPERR_F, "Master Timeout FIFO parity error", -1, 1 },
0078 { MSIXSTIPERR_F, "MSI-X STI SRAM parity error", -1, 1 },
0079 { MSIXADDRLPERR_F, "MSI-X AddrL parity error", -1, 1 },
0080 { MSIXADDRHPERR_F, "MSI-X AddrH parity error", -1, 1 },
0081 { MSIXDATAPERR_F, "MSI-X data parity error", -1, 1 },
0082 { MSIXDIPERR_F, "MSI-X DI parity error", -1, 1 },
0083 { PIOCPLGRPPERR_F, "PCI PIO completion Group FIFO parity error",
0084 -1, 1 },
0085 { PIOREQGRPPERR_F, "PCI PIO request Group FIFO parity error",
0086 -1, 1 },
0087 { TARTAGPERR_F, "PCI PCI target tag FIFO parity error", -1, 1 },
0088 { MSTTAGQPERR_F, "PCI master tag queue parity error", -1, 1 },
0089 { CREQPERR_F, "PCI CMD channel request parity error", -1, 1 },
0090 { CRSPPERR_F, "PCI CMD channel response parity error", -1, 1 },
0091 { DREQWRPERR_F, "PCI DMA channel write request parity error",
0092 -1, 1 },
0093 { DREQPERR_F, "PCI DMA channel request parity error", -1, 1 },
0094 { DRSPPERR_F, "PCI DMA channel response parity error", -1, 1 },
0095 { HREQWRPERR_F, "PCI HMA channel count parity error", -1, 1 },
0096 { HREQPERR_F, "PCI HMA channel request parity error", -1, 1 },
0097 { HRSPPERR_F, "PCI HMA channel response parity error", -1, 1 },
0098 { CFGSNPPERR_F, "PCI config snoop FIFO parity error", -1, 1 },
0099 { FIDPERR_F, "PCI FID parity error", -1, 1 },
0100 { VFIDPERR_F, "PCI INTx clear parity error", -1, 1 },
0101 { MAGRPPERR_F, "PCI MA group FIFO parity error", -1, 1 },
0102 { PIOTAGPERR_F, "PCI PIO tag parity error", -1, 1 },
0103 { IPRXHDRGRPPERR_F, "PCI IP Rx header group parity error",
0104 -1, 1 },
0105 { IPRXDATAGRPPERR_F, "PCI IP Rx data group parity error",
0106 -1, 1 },
0107 { RPLPERR_F, "PCI IP replay buffer parity error", -1, 1 },
0108 { IPSOTPERR_F, "PCI IP SOT buffer parity error", -1, 1 },
0109 { TRGT1GRPPERR_F, "PCI TRGT1 group FIFOs parity error", -1, 1 },
0110 { READRSPERR_F, "Outbound read error", -1, 0 },
0111 { 0, NULL, 0, 0 }
0112 };
0113
0114 int fat;
0115 fat = csio_handle_intr_status(hw, PCIE_INT_CAUSE_A, pcie_intr_info);
0116 if (fat)
0117 csio_hw_fatal_err(hw);
0118 }
0119
0120
0121
0122
0123
0124
0125
0126
0127 static unsigned int
0128 csio_t5_flash_cfg_addr(struct csio_hw *hw)
0129 {
0130 return FLASH_CFG_START;
0131 }
0132
0133
0134
0135
0136
0137
0138
0139
0140
0141
0142
0143
0144
0145 static int
0146 csio_t5_mc_read(struct csio_hw *hw, int idx, uint32_t addr, __be32 *data,
0147 uint64_t *ecc)
0148 {
0149 int i;
0150 uint32_t mc_bist_cmd_reg, mc_bist_cmd_addr_reg, mc_bist_cmd_len_reg;
0151 uint32_t mc_bist_data_pattern_reg;
0152
0153 mc_bist_cmd_reg = MC_REG(MC_P_BIST_CMD_A, idx);
0154 mc_bist_cmd_addr_reg = MC_REG(MC_P_BIST_CMD_ADDR_A, idx);
0155 mc_bist_cmd_len_reg = MC_REG(MC_P_BIST_CMD_LEN_A, idx);
0156 mc_bist_data_pattern_reg = MC_REG(MC_P_BIST_DATA_PATTERN_A, idx);
0157
0158 if (csio_rd_reg32(hw, mc_bist_cmd_reg) & START_BIST_F)
0159 return -EBUSY;
0160 csio_wr_reg32(hw, addr & ~0x3fU, mc_bist_cmd_addr_reg);
0161 csio_wr_reg32(hw, 64, mc_bist_cmd_len_reg);
0162 csio_wr_reg32(hw, 0xc, mc_bist_data_pattern_reg);
0163 csio_wr_reg32(hw, BIST_OPCODE_V(1) | START_BIST_F | BIST_CMD_GAP_V(1),
0164 mc_bist_cmd_reg);
0165 i = csio_hw_wait_op_done_val(hw, mc_bist_cmd_reg, START_BIST_F,
0166 0, 10, 1, NULL);
0167 if (i)
0168 return i;
0169
0170 #define MC_DATA(i) MC_BIST_STATUS_REG(MC_BIST_STATUS_RDATA_A, i)
0171
0172 for (i = 15; i >= 0; i--)
0173 *data++ = htonl(csio_rd_reg32(hw, MC_DATA(i)));
0174 if (ecc)
0175 *ecc = csio_rd_reg64(hw, MC_DATA(16));
0176 #undef MC_DATA
0177 return 0;
0178 }
0179
0180
0181
0182
0183
0184
0185
0186
0187
0188
0189
0190
0191
0192 static int
0193 csio_t5_edc_read(struct csio_hw *hw, int idx, uint32_t addr, __be32 *data,
0194 uint64_t *ecc)
0195 {
0196 int i;
0197 uint32_t edc_bist_cmd_reg, edc_bist_cmd_addr_reg, edc_bist_cmd_len_reg;
0198 uint32_t edc_bist_cmd_data_pattern;
0199
0200
0201
0202
0203 #define EDC_STRIDE_T5 (EDC_T51_BASE_ADDR - EDC_T50_BASE_ADDR)
0204 #define EDC_REG_T5(reg, idx) (reg + EDC_STRIDE_T5 * idx)
0205
0206 edc_bist_cmd_reg = EDC_REG_T5(EDC_H_BIST_CMD_A, idx);
0207 edc_bist_cmd_addr_reg = EDC_REG_T5(EDC_H_BIST_CMD_ADDR_A, idx);
0208 edc_bist_cmd_len_reg = EDC_REG_T5(EDC_H_BIST_CMD_LEN_A, idx);
0209 edc_bist_cmd_data_pattern = EDC_REG_T5(EDC_H_BIST_DATA_PATTERN_A, idx);
0210 #undef EDC_REG_T5
0211 #undef EDC_STRIDE_T5
0212
0213 if (csio_rd_reg32(hw, edc_bist_cmd_reg) & START_BIST_F)
0214 return -EBUSY;
0215 csio_wr_reg32(hw, addr & ~0x3fU, edc_bist_cmd_addr_reg);
0216 csio_wr_reg32(hw, 64, edc_bist_cmd_len_reg);
0217 csio_wr_reg32(hw, 0xc, edc_bist_cmd_data_pattern);
0218 csio_wr_reg32(hw, BIST_OPCODE_V(1) | START_BIST_F | BIST_CMD_GAP_V(1),
0219 edc_bist_cmd_reg);
0220 i = csio_hw_wait_op_done_val(hw, edc_bist_cmd_reg, START_BIST_F,
0221 0, 10, 1, NULL);
0222 if (i)
0223 return i;
0224
0225 #define EDC_DATA(i) (EDC_BIST_STATUS_REG(EDC_BIST_STATUS_RDATA_A, i) + idx)
0226
0227 for (i = 15; i >= 0; i--)
0228 *data++ = htonl(csio_rd_reg32(hw, EDC_DATA(i)));
0229 if (ecc)
0230 *ecc = csio_rd_reg64(hw, EDC_DATA(16));
0231 #undef EDC_DATA
0232 return 0;
0233 }
0234
0235
0236
0237
0238
0239
0240
0241
0242
0243
0244
0245
0246
0247
0248
0249
0250
0251
0252 static int
0253 csio_t5_memory_rw(struct csio_hw *hw, u32 win, int mtype, u32 addr,
0254 u32 len, uint32_t *buf, int dir)
0255 {
0256 u32 pos, start, offset, memoffset;
0257 u32 edc_size, mc_size, win_pf, mem_reg, mem_aperture, mem_base;
0258
0259
0260
0261
0262 if ((addr & 0x3) || (len & 0x3))
0263 return -EINVAL;
0264
0265
0266
0267
0268
0269
0270
0271
0272 edc_size = EDRAM0_SIZE_G(csio_rd_reg32(hw, MA_EDRAM0_BAR_A));
0273 if (mtype != MEM_MC1)
0274 memoffset = (mtype * (edc_size * 1024 * 1024));
0275 else {
0276 mc_size = EXT_MEM_SIZE_G(csio_rd_reg32(hw,
0277 MA_EXT_MEMORY_BAR_A));
0278 memoffset = (MEM_MC0 * edc_size + mc_size) * 1024 * 1024;
0279 }
0280
0281
0282 addr = addr + memoffset;
0283
0284
0285
0286
0287
0288
0289
0290
0291
0292
0293 mem_reg = csio_rd_reg32(hw,
0294 PCIE_MEM_ACCESS_REG(PCIE_MEM_ACCESS_BASE_WIN_A, win));
0295 mem_aperture = 1 << (WINDOW_V(mem_reg) + 10);
0296 mem_base = PCIEOFST_G(mem_reg) << 10;
0297
0298 start = addr & ~(mem_aperture-1);
0299 offset = addr - start;
0300 win_pf = PFNUM_V(hw->pfn);
0301
0302 csio_dbg(hw, "csio_t5_memory_rw: mem_reg: 0x%x, mem_aperture: 0x%x\n",
0303 mem_reg, mem_aperture);
0304 csio_dbg(hw, "csio_t5_memory_rw: mem_base: 0x%x, mem_offset: 0x%x\n",
0305 mem_base, memoffset);
0306 csio_dbg(hw, "csio_t5_memory_rw: start:0x%x, offset:0x%x, win_pf:%d\n",
0307 start, offset, win_pf);
0308 csio_dbg(hw, "csio_t5_memory_rw: mtype: %d, addr: 0x%x, len: %d\n",
0309 mtype, addr, len);
0310
0311 for (pos = start; len > 0; pos += mem_aperture, offset = 0) {
0312
0313
0314
0315
0316
0317 csio_wr_reg32(hw, pos | win_pf,
0318 PCIE_MEM_ACCESS_REG(PCIE_MEM_ACCESS_OFFSET_A, win));
0319 csio_rd_reg32(hw,
0320 PCIE_MEM_ACCESS_REG(PCIE_MEM_ACCESS_OFFSET_A, win));
0321
0322 while (offset < mem_aperture && len > 0) {
0323 if (dir)
0324 *buf++ = csio_rd_reg32(hw, mem_base + offset);
0325 else
0326 csio_wr_reg32(hw, *buf++, mem_base + offset);
0327
0328 offset += sizeof(__be32);
0329 len -= sizeof(__be32);
0330 }
0331 }
0332 return 0;
0333 }
0334
0335
0336
0337
0338
0339
0340
0341
0342 static void
0343 csio_t5_dfs_create_ext_mem(struct csio_hw *hw)
0344 {
0345 u32 size;
0346 int i = csio_rd_reg32(hw, MA_TARGET_MEM_ENABLE_A);
0347
0348 if (i & EXT_MEM_ENABLE_F) {
0349 size = csio_rd_reg32(hw, MA_EXT_MEMORY_BAR_A);
0350 csio_add_debugfs_mem(hw, "mc0", MEM_MC0,
0351 EXT_MEM_SIZE_G(size));
0352 }
0353 if (i & EXT_MEM1_ENABLE_F) {
0354 size = csio_rd_reg32(hw, MA_EXT_MEMORY1_BAR_A);
0355 csio_add_debugfs_mem(hw, "mc1", MEM_MC1,
0356 EXT_MEM_SIZE_G(size));
0357 }
0358 }
0359
0360
0361 struct csio_hw_chip_ops t5_ops = {
0362 .chip_set_mem_win = csio_t5_set_mem_win,
0363 .chip_pcie_intr_handler = csio_t5_pcie_intr_handler,
0364 .chip_flash_cfg_addr = csio_t5_flash_cfg_addr,
0365 .chip_mc_read = csio_t5_mc_read,
0366 .chip_edc_read = csio_t5_edc_read,
0367 .chip_memory_rw = csio_t5_memory_rw,
0368 .chip_dfs_create_ext_mem = csio_t5_dfs_create_ext_mem,
0369 };