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