xref: /illumos-gate/usr/src/uts/common/io/chxge/com/mc3.c (revision 4f364e7c95ee7fd9d5bbeddc1940e92405bb0e72)
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 
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 
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 
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 
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  */
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 
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 
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 
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 
353 void t1_mc3_destroy(struct pemc3 *mc3)
354 {
355 	t1_os_free((void *)mc3, sizeof(*mc3));
356 }
357 
358 unsigned int t1_mc3_get_size(struct pemc3 *mc3)
359 {
360 	return mc3->size;
361 }
362 
363 const struct pemc3_intr_counts *t1_mc3_get_intr_counts(struct pemc3 *mc3)
364 {
365 	return &mc3->intr_cnt;
366 }
367