1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32#include "csio_hw.h"
33#include "csio_init.h"
34
35
36
37
38
39
40
41static uint32_t
42csio_t4_read_pcie_cfg4(struct csio_hw *hw, int reg)
43{
44 u32 val = 0;
45 struct csio_mb *mbp;
46 int rv;
47 struct fw_ldst_cmd *ldst_cmd;
48
49 mbp = mempool_alloc(hw->mb_mempool, GFP_ATOMIC);
50 if (!mbp) {
51 CSIO_INC_STATS(hw, n_err_nomem);
52 pci_read_config_dword(hw->pdev, reg, &val);
53 return val;
54 }
55
56 csio_mb_ldst(hw, mbp, CSIO_MB_DEFAULT_TMO, reg);
57 rv = csio_mb_issue(hw, mbp);
58
59
60
61
62
63 if (rv == 0) {
64 ldst_cmd = (struct fw_ldst_cmd *)(mbp->mb);
65 val = ntohl(ldst_cmd->u.pcie.data[0]);
66 } else
67 pci_read_config_dword(hw->pdev, reg, &val);
68
69 mempool_free(mbp, hw->mb_mempool);
70
71 return val;
72}
73
74static int
75csio_t4_set_mem_win(struct csio_hw *hw, uint32_t win)
76{
77 u32 bar0;
78 u32 mem_win_base;
79
80
81
82
83
84
85
86
87
88
89 bar0 = csio_t4_read_pcie_cfg4(hw, PCI_BASE_ADDRESS_0);
90 bar0 &= PCI_BASE_ADDRESS_MEM_MASK;
91
92 mem_win_base = bar0 + MEMWIN_BASE;
93
94
95
96
97
98
99 csio_wr_reg32(hw, mem_win_base | BIR(0) |
100 WINDOW(ilog2(MEMWIN_APERTURE) - 10),
101 PCIE_MEM_ACCESS_REG(PCIE_MEM_ACCESS_BASE_WIN, win));
102 csio_rd_reg32(hw,
103 PCIE_MEM_ACCESS_REG(PCIE_MEM_ACCESS_BASE_WIN, win));
104 return 0;
105}
106
107
108
109
110static void
111csio_t4_pcie_intr_handler(struct csio_hw *hw)
112{
113 static struct intr_info sysbus_intr_info[] = {
114 { RNPP, "RXNP array parity error", -1, 1 },
115 { RPCP, "RXPC array parity error", -1, 1 },
116 { RCIP, "RXCIF array parity error", -1, 1 },
117 { RCCP, "Rx completions control array parity error", -1, 1 },
118 { RFTP, "RXFT array parity error", -1, 1 },
119 { 0, NULL, 0, 0 }
120 };
121 static struct intr_info pcie_port_intr_info[] = {
122 { TPCP, "TXPC array parity error", -1, 1 },
123 { TNPP, "TXNP array parity error", -1, 1 },
124 { TFTP, "TXFT array parity error", -1, 1 },
125 { TCAP, "TXCA array parity error", -1, 1 },
126 { TCIP, "TXCIF array parity error", -1, 1 },
127 { RCAP, "RXCA array parity error", -1, 1 },
128 { OTDD, "outbound request TLP discarded", -1, 1 },
129 { RDPE, "Rx data parity error", -1, 1 },
130 { TDUE, "Tx uncorrectable data error", -1, 1 },
131 { 0, NULL, 0, 0 }
132 };
133
134 static struct intr_info pcie_intr_info[] = {
135 { MSIADDRLPERR, "MSI AddrL parity error", -1, 1 },
136 { MSIADDRHPERR, "MSI AddrH parity error", -1, 1 },
137 { MSIDATAPERR, "MSI data parity error", -1, 1 },
138 { MSIXADDRLPERR, "MSI-X AddrL parity error", -1, 1 },
139 { MSIXADDRHPERR, "MSI-X AddrH parity error", -1, 1 },
140 { MSIXDATAPERR, "MSI-X data parity error", -1, 1 },
141 { MSIXDIPERR, "MSI-X DI parity error", -1, 1 },
142 { PIOCPLPERR, "PCI PIO completion FIFO parity error", -1, 1 },
143 { PIOREQPERR, "PCI PIO request FIFO parity error", -1, 1 },
144 { TARTAGPERR, "PCI PCI target tag FIFO parity error", -1, 1 },
145 { CCNTPERR, "PCI CMD channel count parity error", -1, 1 },
146 { CREQPERR, "PCI CMD channel request parity error", -1, 1 },
147 { CRSPPERR, "PCI CMD channel response parity error", -1, 1 },
148 { DCNTPERR, "PCI DMA channel count parity error", -1, 1 },
149 { DREQPERR, "PCI DMA channel request parity error", -1, 1 },
150 { DRSPPERR, "PCI DMA channel response parity error", -1, 1 },
151 { HCNTPERR, "PCI HMA channel count parity error", -1, 1 },
152 { HREQPERR, "PCI HMA channel request parity error", -1, 1 },
153 { HRSPPERR, "PCI HMA channel response parity error", -1, 1 },
154 { CFGSNPPERR, "PCI config snoop FIFO parity error", -1, 1 },
155 { FIDPERR, "PCI FID parity error", -1, 1 },
156 { INTXCLRPERR, "PCI INTx clear parity error", -1, 1 },
157 { MATAGPERR, "PCI MA tag parity error", -1, 1 },
158 { PIOTAGPERR, "PCI PIO tag parity error", -1, 1 },
159 { RXCPLPERR, "PCI Rx completion parity error", -1, 1 },
160 { RXWRPERR, "PCI Rx write parity error", -1, 1 },
161 { RPLPERR, "PCI replay buffer parity error", -1, 1 },
162 { PCIESINT, "PCI core secondary fault", -1, 1 },
163 { PCIEPINT, "PCI core primary fault", -1, 1 },
164 { UNXSPLCPLERR, "PCI unexpected split completion error", -1,
165 0 },
166 { 0, NULL, 0, 0 }
167 };
168
169 int fat;
170 fat = csio_handle_intr_status(hw,
171 PCIE_CORE_UTL_SYSTEM_BUS_AGENT_STATUS,
172 sysbus_intr_info) +
173 csio_handle_intr_status(hw,
174 PCIE_CORE_UTL_PCI_EXPRESS_PORT_STATUS,
175 pcie_port_intr_info) +
176 csio_handle_intr_status(hw, PCIE_INT_CAUSE, pcie_intr_info);
177 if (fat)
178 csio_hw_fatal_err(hw);
179}
180
181
182
183
184
185
186
187
188static unsigned int
189csio_t4_flash_cfg_addr(struct csio_hw *hw)
190{
191 return FLASH_CFG_OFFSET;
192}
193
194
195
196
197
198
199
200
201
202
203
204
205
206static int
207csio_t4_mc_read(struct csio_hw *hw, int idx, uint32_t addr, __be32 *data,
208 uint64_t *ecc)
209{
210 int i;
211
212 if (csio_rd_reg32(hw, MC_BIST_CMD) & START_BIST)
213 return -EBUSY;
214 csio_wr_reg32(hw, addr & ~0x3fU, MC_BIST_CMD_ADDR);
215 csio_wr_reg32(hw, 64, MC_BIST_CMD_LEN);
216 csio_wr_reg32(hw, 0xc, MC_BIST_DATA_PATTERN);
217 csio_wr_reg32(hw, BIST_OPCODE(1) | START_BIST | BIST_CMD_GAP(1),
218 MC_BIST_CMD);
219 i = csio_hw_wait_op_done_val(hw, MC_BIST_CMD, START_BIST,
220 0, 10, 1, NULL);
221 if (i)
222 return i;
223
224#define MC_DATA(i) MC_BIST_STATUS_REG(MC_BIST_STATUS_RDATA, i)
225
226 for (i = 15; i >= 0; i--)
227 *data++ = htonl(csio_rd_reg32(hw, MC_DATA(i)));
228 if (ecc)
229 *ecc = csio_rd_reg64(hw, MC_DATA(16));
230#undef MC_DATA
231 return 0;
232}
233
234
235
236
237
238
239
240
241
242
243
244
245
246static int
247csio_t4_edc_read(struct csio_hw *hw, int idx, uint32_t addr, __be32 *data,
248 uint64_t *ecc)
249{
250 int i;
251
252 idx *= EDC_STRIDE;
253 if (csio_rd_reg32(hw, EDC_BIST_CMD + idx) & START_BIST)
254 return -EBUSY;
255 csio_wr_reg32(hw, addr & ~0x3fU, EDC_BIST_CMD_ADDR + idx);
256 csio_wr_reg32(hw, 64, EDC_BIST_CMD_LEN + idx);
257 csio_wr_reg32(hw, 0xc, EDC_BIST_DATA_PATTERN + idx);
258 csio_wr_reg32(hw, BIST_OPCODE(1) | BIST_CMD_GAP(1) | START_BIST,
259 EDC_BIST_CMD + idx);
260 i = csio_hw_wait_op_done_val(hw, EDC_BIST_CMD + idx, START_BIST,
261 0, 10, 1, NULL);
262 if (i)
263 return i;
264
265#define EDC_DATA(i) (EDC_BIST_STATUS_REG(EDC_BIST_STATUS_RDATA, i) + idx)
266
267 for (i = 15; i >= 0; i--)
268 *data++ = htonl(csio_rd_reg32(hw, EDC_DATA(i)));
269 if (ecc)
270 *ecc = csio_rd_reg64(hw, EDC_DATA(16));
271#undef EDC_DATA
272 return 0;
273}
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292static int
293csio_t4_memory_rw(struct csio_hw *hw, u32 win, int mtype, u32 addr,
294 u32 len, uint32_t *buf, int dir)
295{
296 u32 pos, start, offset, memoffset, bar0;
297 u32 edc_size, mc_size, mem_reg, mem_aperture, mem_base;
298
299
300
301
302 if ((addr & 0x3) || (len & 0x3))
303 return -EINVAL;
304
305
306
307
308
309
310 edc_size = EDRAM_SIZE_GET(csio_rd_reg32(hw, MA_EDRAM0_BAR));
311 if (mtype != MEM_MC1)
312 memoffset = (mtype * (edc_size * 1024 * 1024));
313 else {
314 mc_size = EXT_MEM_SIZE_GET(csio_rd_reg32(hw,
315 MA_EXT_MEMORY_BAR));
316 memoffset = (MEM_MC0 * edc_size + mc_size) * 1024 * 1024;
317 }
318
319
320 addr = addr + memoffset;
321
322
323
324
325
326
327
328
329
330
331 mem_reg = csio_rd_reg32(hw,
332 PCIE_MEM_ACCESS_REG(PCIE_MEM_ACCESS_BASE_WIN, win));
333 mem_aperture = 1 << (WINDOW(mem_reg) + 10);
334 mem_base = GET_PCIEOFST(mem_reg) << 10;
335
336 bar0 = csio_t4_read_pcie_cfg4(hw, PCI_BASE_ADDRESS_0);
337 bar0 &= PCI_BASE_ADDRESS_MEM_MASK;
338 mem_base -= bar0;
339
340 start = addr & ~(mem_aperture-1);
341 offset = addr - start;
342
343 csio_dbg(hw, "csio_t4_memory_rw: mem_reg: 0x%x, mem_aperture: 0x%x\n",
344 mem_reg, mem_aperture);
345 csio_dbg(hw, "csio_t4_memory_rw: mem_base: 0x%x, mem_offset: 0x%x\n",
346 mem_base, memoffset);
347 csio_dbg(hw, "csio_t4_memory_rw: bar0: 0x%x, start:0x%x, offset:0x%x\n",
348 bar0, start, offset);
349 csio_dbg(hw, "csio_t4_memory_rw: mtype: %d, addr: 0x%x, len: %d\n",
350 mtype, addr, len);
351
352 for (pos = start; len > 0; pos += mem_aperture, offset = 0) {
353
354
355
356
357
358 csio_wr_reg32(hw, pos,
359 PCIE_MEM_ACCESS_REG(PCIE_MEM_ACCESS_OFFSET, win));
360 csio_rd_reg32(hw,
361 PCIE_MEM_ACCESS_REG(PCIE_MEM_ACCESS_OFFSET, win));
362
363 while (offset < mem_aperture && len > 0) {
364 if (dir)
365 *buf++ = csio_rd_reg32(hw, mem_base + offset);
366 else
367 csio_wr_reg32(hw, *buf++, mem_base + offset);
368
369 offset += sizeof(__be32);
370 len -= sizeof(__be32);
371 }
372 }
373 return 0;
374}
375
376
377
378
379
380
381
382static void
383csio_t4_dfs_create_ext_mem(struct csio_hw *hw)
384{
385 u32 size;
386 int i = csio_rd_reg32(hw, MA_TARGET_MEM_ENABLE);
387 if (i & EXT_MEM_ENABLE) {
388 size = csio_rd_reg32(hw, MA_EXT_MEMORY_BAR);
389 csio_add_debugfs_mem(hw, "mc", MEM_MC,
390 EXT_MEM_SIZE_GET(size));
391 }
392}
393
394
395struct csio_hw_chip_ops t4_ops = {
396 .chip_set_mem_win = csio_t4_set_mem_win,
397 .chip_pcie_intr_handler = csio_t4_pcie_intr_handler,
398 .chip_flash_cfg_addr = csio_t4_flash_cfg_addr,
399 .chip_mc_read = csio_t4_mc_read,
400 .chip_edc_read = csio_t4_edc_read,
401 .chip_memory_rw = csio_t4_memory_rw,
402 .chip_dfs_create_ext_mem = csio_t4_dfs_create_ext_mem,
403};
404