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