1 /*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21
22 /*
23 * Copyright (C) 2003-2005 Chelsio Communications. All rights reserved.
24 */
25
26 #pragma ident "%Z%%M% %I% %E% SMI" /* mc3.c */
27
28 #include "common.h"
29 #include "regs.h"
30 #include "mc3.h"
31
32 #ifdef CONFIG_CHELSIO_T1_1G
33 # include "fpga_defs.h"
34 #endif
35
36 struct pemc3 {
37 adapter_t *adapter;
38 unsigned int size;
39 struct pemc3_intr_counts intr_cnt;
40 };
41
42 #define MC3_INTR_MASK (F_MC3_CORR_ERR | F_MC3_UNCORR_ERR | \
43 V_MC3_PARITY_ERR(M_MC3_PARITY_ERR) | F_MC3_ADDR_ERR)
44 #define MC3_INTR_FATAL (F_MC3_UNCORR_ERR | V_MC3_PARITY_ERR(M_MC3_PARITY_ERR) | F_MC3_ADDR_ERR)
45
t1_mc3_intr_enable(struct pemc3 * mc3)46 void t1_mc3_intr_enable(struct pemc3 *mc3)
47 {
48 u32 en = t1_read_reg_4(mc3->adapter, A_PL_ENABLE);
49
50 if (t1_is_asic(mc3->adapter)) {
51 t1_write_reg_4(mc3->adapter, A_MC3_INT_ENABLE, MC3_INTR_MASK);
52 t1_write_reg_4(mc3->adapter, A_PL_ENABLE, en | F_PL_INTR_MC3);
53 #ifdef CONFIG_CHELSIO_T1_1G
54 } else {
55 t1_write_reg_4(mc3->adapter, FPGA_MC3_REG_INTRENABLE,
56 MC3_INTR_MASK);
57 t1_write_reg_4(mc3->adapter, A_PL_ENABLE,
58 en | FPGA_PCIX_INTERRUPT_MC3);
59 #endif
60 }
61 }
62
t1_mc3_intr_disable(struct pemc3 * mc3)63 void t1_mc3_intr_disable(struct pemc3 *mc3)
64 {
65 u32 pl_intr = t1_read_reg_4(mc3->adapter, A_PL_ENABLE);
66
67 if (t1_is_asic(mc3->adapter)) {
68 t1_write_reg_4(mc3->adapter, A_MC3_INT_ENABLE, 0);
69 t1_write_reg_4(mc3->adapter, A_PL_ENABLE,
70 pl_intr & ~F_PL_INTR_MC3);
71 #ifdef CONFIG_CHELSIO_T1_1G
72 } else {
73 t1_write_reg_4(mc3->adapter, FPGA_MC3_REG_INTRENABLE, 0);
74 t1_write_reg_4(mc3->adapter, A_PL_ENABLE,
75 pl_intr & ~FPGA_PCIX_INTERRUPT_MC3);
76 #endif
77 }
78 }
79
t1_mc3_intr_clear(struct pemc3 * mc3)80 void t1_mc3_intr_clear(struct pemc3 *mc3)
81 {
82 if (t1_is_asic(mc3->adapter)) {
83 if (t1_is_T1B(mc3->adapter)) {
84 /*
85 * Workaround for T1B bug: we must write to enable
86 * register to clear interrupts.
87 */
88 u32 old_en;
89
90 old_en = t1_read_reg_4(mc3->adapter, A_MC3_INT_ENABLE);
91 t1_write_reg_4(mc3->adapter, A_MC3_INT_ENABLE,
92 0xffffffff);
93 t1_write_reg_4(mc3->adapter, A_MC3_INT_ENABLE, old_en);
94 } else
95 t1_write_reg_4(mc3->adapter, A_MC3_INT_CAUSE,
96 0xffffffff);
97
98 t1_write_reg_4(mc3->adapter, A_PL_CAUSE, F_PL_INTR_MC3);
99 #ifdef CONFIG_CHELSIO_T1_1G
100 } else {
101 t1_write_reg_4(mc3->adapter, FPGA_MC3_REG_INTRCAUSE,
102 0xffffffff);
103 t1_write_reg_4(mc3->adapter, A_PL_CAUSE,
104 FPGA_PCIX_INTERRUPT_MC3);
105 #endif
106 }
107 }
108
t1_mc3_intr_handler(struct pemc3 * mc3)109 int t1_mc3_intr_handler(struct pemc3 *mc3)
110 {
111 adapter_t *adapter = mc3->adapter;
112 int cause_reg = A_MC3_INT_CAUSE;
113 u32 cause;
114
115 #ifdef CONFIG_CHELSIO_T1_1G
116 if (!t1_is_asic(adapter))
117 cause_reg = FPGA_MC3_REG_INTRCAUSE;
118 #endif
119 cause = t1_read_reg_4(adapter, cause_reg);
120
121 if (cause & F_MC3_CORR_ERR) {
122 mc3->intr_cnt.corr_err++;
123 CH_WARN("%s: MC3 correctable error at addr 0x%x, "
124 "data 0x%x 0x%x 0x%x 0x%x 0x%x\n",
125 adapter_name(adapter),
126 G_MC3_CE_ADDR(t1_read_reg_4(adapter, A_MC3_CE_ADDR)),
127 t1_read_reg_4(adapter, A_MC3_CE_DATA0),
128 t1_read_reg_4(adapter, A_MC3_CE_DATA1),
129 t1_read_reg_4(adapter, A_MC3_CE_DATA2),
130 t1_read_reg_4(adapter, A_MC3_CE_DATA3),
131 t1_read_reg_4(adapter, A_MC3_CE_DATA4));
132 }
133
134 if (cause & F_MC3_UNCORR_ERR) {
135 mc3->intr_cnt.uncorr_err++;
136 CH_ALERT("%s: MC3 uncorrectable error at addr 0x%x, "
137 "data 0x%x 0x%x 0x%x 0x%x 0x%x\n",
138 adapter_name(adapter),
139 G_MC3_UE_ADDR(t1_read_reg_4(adapter, A_MC3_UE_ADDR)),
140 t1_read_reg_4(adapter, A_MC3_UE_DATA0),
141 t1_read_reg_4(adapter, A_MC3_UE_DATA1),
142 t1_read_reg_4(adapter, A_MC3_UE_DATA2),
143 t1_read_reg_4(adapter, A_MC3_UE_DATA3),
144 t1_read_reg_4(adapter, A_MC3_UE_DATA4));
145 }
146
147 if (G_MC3_PARITY_ERR(cause)) {
148 mc3->intr_cnt.parity_err++;
149 CH_ALERT("%s: MC3 parity error 0x%x\n", adapter_name(adapter),
150 G_MC3_PARITY_ERR(cause));
151 }
152
153 if (cause & F_MC3_ADDR_ERR) {
154 mc3->intr_cnt.addr_err++;
155 CH_ALERT("%s: MC3 address error\n", adapter_name(adapter));
156 }
157
158 if (cause & MC3_INTR_FATAL)
159 t1_fatal_err(adapter);
160
161 if (t1_is_T1B(adapter)) {
162 /*
163 * Workaround for T1B bug: we must write to enable register to
164 * clear interrupts.
165 */
166 t1_write_reg_4(adapter, A_MC3_INT_ENABLE, cause);
167 /* restore enable */
168 t1_write_reg_4(adapter, A_MC3_INT_ENABLE, MC3_INTR_MASK);
169 } else
170 t1_write_reg_4(adapter, cause_reg, cause);
171
172 return 0;
173 }
174
175 #define is_MC3A(adapter) (!t1_is_T1B(adapter))
176
177 /*
178 * Write a value to a register and check that the write completed. These
179 * writes normally complete in a cycle or two, so one read should suffice.
180 * The very first read exists to flush the posted write to the device.
181 */
wrreg_wait(adapter_t * adapter,unsigned int addr,u32 val)182 static int wrreg_wait(adapter_t *adapter, unsigned int addr, u32 val)
183 {
184 t1_write_reg_4(adapter, addr, val);
185 val = t1_read_reg_4(adapter, addr); /* flush */
186 if (!(t1_read_reg_4(adapter, addr) & F_BUSY))
187 return 0;
188 CH_ERR("%s: write to MC3 register 0x%x timed out\n",
189 adapter_name(adapter), addr);
190 return -EIO;
191 }
192
193 #define MC3_DLL_DONE (F_MASTER_DLL_LOCKED | F_MASTER_DLL_MAX_TAP_COUNT)
194
t1_mc3_init(struct pemc3 * mc3,unsigned int mc3_clock)195 int t1_mc3_init(struct pemc3 *mc3, unsigned int mc3_clock)
196 {
197 u32 val;
198 unsigned int width, fast_asic, attempts;
199 adapter_t *adapter = mc3->adapter;
200
201 /* Check to see if ASIC is running in slow mode. */
202 val = t1_read_reg_4(adapter, A_MC3_CFG);
203 width = is_MC3A(adapter) ? G_MC3_WIDTH(val) : 0;
204 fast_asic = t1_is_asic(adapter) && !(val & F_MC3_SLOW);
205
206 val &= ~(V_MC3_BANK_CYCLE(M_MC3_BANK_CYCLE) |
207 V_REFRESH_CYCLE(M_REFRESH_CYCLE) |
208 V_PRECHARGE_CYCLE(M_PRECHARGE_CYCLE) |
209 F_ACTIVE_TO_READ_WRITE_DELAY |
210 V_ACTIVE_TO_PRECHARGE_DELAY(M_ACTIVE_TO_PRECHARGE_DELAY) |
211 V_WRITE_RECOVERY_DELAY(M_WRITE_RECOVERY_DELAY));
212
213 if (mc3_clock <= 100000000)
214 val |= V_MC3_BANK_CYCLE(7) | V_REFRESH_CYCLE(4) |
215 V_PRECHARGE_CYCLE(2) | V_ACTIVE_TO_PRECHARGE_DELAY(5) |
216 V_WRITE_RECOVERY_DELAY(2);
217 else if (mc3_clock <= 133000000)
218 val |= V_MC3_BANK_CYCLE(9) | V_REFRESH_CYCLE(5) |
219 V_PRECHARGE_CYCLE(3) | F_ACTIVE_TO_READ_WRITE_DELAY |
220 V_ACTIVE_TO_PRECHARGE_DELAY(6) |
221 V_WRITE_RECOVERY_DELAY(2);
222 else
223 val |= V_MC3_BANK_CYCLE(0xA) | V_REFRESH_CYCLE(6) |
224 V_PRECHARGE_CYCLE(3) | F_ACTIVE_TO_READ_WRITE_DELAY |
225 V_ACTIVE_TO_PRECHARGE_DELAY(7) |
226 V_WRITE_RECOVERY_DELAY(3);
227 t1_write_reg_4(adapter, A_MC3_CFG, val);
228
229 val = t1_read_reg_4(adapter, A_MC3_CFG);
230 t1_write_reg_4(adapter, A_MC3_CFG, val | F_CLK_ENABLE);
231 val = t1_read_reg_4(adapter, A_MC3_CFG); /* flush */
232
233 if (fast_asic) { /* setup DLLs */
234 val = t1_read_reg_4(adapter, A_MC3_STROBE);
235 if (is_MC3A(adapter)) {
236 t1_write_reg_4(adapter, A_MC3_STROBE,
237 val & ~F_SLAVE_DLL_RESET);
238
239 /* Wait for slave DLLs to lock */
240 DELAY_US(2 * 512 / (mc3_clock / 1000000) + 1);
241 } else {
242 /* Initialize the master DLL and slave delay lines. */
243 t1_write_reg_4(adapter, A_MC3_STROBE,
244 val & ~F_MASTER_DLL_RESET);
245
246 /* Wait for the master DLL to lock. */
247 attempts = 100;
248 do {
249 DELAY_US(1);
250 val = t1_read_reg_4(adapter, A_MC3_STROBE);
251 } while (!(val & MC3_DLL_DONE) && --attempts);
252 if (!(val & MC3_DLL_DONE)) {
253 CH_ERR("%s: MC3 DLL lock failed\n",
254 adapter_name(adapter));
255 goto out_fail;
256 }
257 }
258 }
259
260 /* Initiate a precharge and wait for the precharge to complete. */
261 if (wrreg_wait(adapter, A_MC3_PRECHARG, 0))
262 goto out_fail;
263
264 /* Set the SDRAM output drive strength and enable DLLs if needed */
265 if (wrreg_wait(adapter, A_MC3_EXT_MODE, fast_asic ? 0 : 1))
266 goto out_fail;
267
268 /* Specify the SDRAM operating parameters. */
269 if (wrreg_wait(adapter, A_MC3_MODE, fast_asic ? 0x161 : 0x21))
270 goto out_fail;
271
272 /* Initiate a precharge and wait for the precharge to complete. */
273 if (wrreg_wait(adapter, A_MC3_PRECHARG, 0))
274 goto out_fail;
275
276 /* Initiate an immediate refresh and wait for the write to complete. */
277 val = t1_read_reg_4(adapter, A_MC3_REFRESH);
278 if (wrreg_wait(adapter, A_MC3_REFRESH, val & ~F_REFRESH_ENABLE))
279 goto out_fail;
280
281 /* 2nd immediate refresh as before */
282 if (wrreg_wait(adapter, A_MC3_REFRESH, val & ~F_REFRESH_ENABLE))
283 goto out_fail;
284
285 /* Specify the SDRAM operating parameters. */
286 if (wrreg_wait(adapter, A_MC3_MODE, fast_asic ? 0x61 : 0x21))
287 goto out_fail;
288
289 /* Convert to KHz first to avoid 64-bit division. */
290 mc3_clock /= 1000; /* Hz->KHz */
291 mc3_clock = mc3_clock * 7812 + mc3_clock / 2; /* ns */
292 mc3_clock /= 1000000; /* KHz->MHz, ns->us */
293
294 /* Enable periodic refresh. */
295 t1_write_reg_4(adapter, A_MC3_REFRESH,
296 F_REFRESH_ENABLE | V_REFRESH_DIVISOR(mc3_clock));
297 (void) t1_read_reg_4(adapter, A_MC3_REFRESH); /* flush */
298
299 t1_write_reg_4(adapter, A_MC3_ECC_CNTL,
300 F_ECC_GENERATION_ENABLE | F_ECC_CHECK_ENABLE);
301
302 /* Use the BIST engine to clear MC3 memory and initialize ECC. */
303 t1_write_reg_4(adapter, A_MC3_BIST_ADDR_BEG, 0);
304 t1_write_reg_4(adapter, A_MC3_BIST_ADDR_END, (mc3->size << width) - 1);
305 t1_write_reg_4(adapter, A_MC3_BIST_DATA, 0);
306 t1_write_reg_4(adapter, A_MC3_BIST_OP, V_OP(1) | 0x1f0);
307 (void) t1_read_reg_4(adapter, A_MC3_BIST_OP); /* flush */
308
309 attempts = 100;
310 do {
311 DELAY_MS(100);
312 val = t1_read_reg_4(adapter, A_MC3_BIST_OP);
313 } while ((val & F_BUSY) && --attempts);
314 if (val & F_BUSY) {
315 CH_ERR("%s: MC3 BIST timed out\n", adapter_name(adapter));
316 goto out_fail;
317 }
318
319 /* Enable normal memory accesses. */
320 val = t1_read_reg_4(adapter, A_MC3_CFG);
321 t1_write_reg_4(adapter, A_MC3_CFG, val | F_READY);
322 return 0;
323
324 out_fail:
325 return -1;
326 }
327
mc3_calc_size(const adapter_t * adapter,u32 cfg)328 static unsigned int __devinit mc3_calc_size(const adapter_t *adapter, u32 cfg)
329 {
330 unsigned int banks = !!(cfg & F_BANKS) + 1;
331 unsigned int org = !!(cfg & F_ORGANIZATION) + 1;
332 unsigned int density = G_DENSITY(cfg);
333
334 unsigned int capacity_in_MB = is_MC3A(adapter) ?
335 ((256 << density) * banks) / (org << G_MC3_WIDTH(cfg)) :
336 ((128 << density) * (16 / org) * banks) / 8;
337
338 return capacity_in_MB * 1024 * 1024;
339 }
340
t1_mc3_create(adapter_t * adapter)341 struct pemc3 * __devinit t1_mc3_create(adapter_t *adapter)
342 {
343 struct pemc3 *mc3 = t1_os_malloc_wait_zero(sizeof(*mc3));
344
345 if (mc3) {
346 mc3->adapter = adapter;
347 mc3->size = mc3_calc_size(adapter,
348 t1_read_reg_4(adapter, A_MC3_CFG));
349 }
350 return mc3;
351 }
352
t1_mc3_destroy(struct pemc3 * mc3)353 void t1_mc3_destroy(struct pemc3 *mc3)
354 {
355 t1_os_free((void *)mc3, sizeof(*mc3));
356 }
357
t1_mc3_get_size(struct pemc3 * mc3)358 unsigned int t1_mc3_get_size(struct pemc3 *mc3)
359 {
360 return mc3->size;
361 }
362
t1_mc3_get_intr_counts(struct pemc3 * mc3)363 const struct pemc3_intr_counts *t1_mc3_get_intr_counts(struct pemc3 *mc3)
364 {
365 return &mc3->intr_cnt;
366 }
367