blackhawk_sim.c (22632B)
1 /* 2 * 3 * This license is set out in https://raw.githubusercontent.com/Broadcom-Network-Switching-Software/OpenBCM/master/Legal/LICENSE file. 4 * 5 * Copyright 2007-2019 Broadcom Inc. All rights reserved. 6 * 7 * 8 * This software simulator can emulate basic register access for the 9 * TSC/Eagle SerDes PHY. 10 * 11 * The simulator suppor both IEEE clause 22/45 access and Broadcom 12 * proprietary SBUS access. 13 * 14 * Clause 22 address format: 15 * Bits [4:0] : Clause 22 register address 16 * Bits [31:5] : Unused 17 * 18 * Clause 45 address format: 19 * Bits [15:0] : Clause 45 register address 20 * Bits [20:16] : Clause 45 DEVAD 21 * Bits [23:21] : Clause 45 indicator (001b) 22 * Bits [31:24] : Unused 23 * 24 * SBUS address format: 25 * Bits [15:0] : Clause 45 register address 26 * Bits [18:16] : Lane control 27 * Bits [26:19] : Lane multicast (old format) 28 * Bits [31:27] : Clause 45 DEVAD 29 * 30 * The upper 16 bits if the SBUS address format is identical to the 31 * Broadcom Address Extension Register (AER) format. 32 * 33 * The clause 45 indicator serves two purposes which is to ensure that 34 * the upper 16 bits are never zero for a clause 45 address, but it 35 * also makes it possible for the PHY bus driver to distinguish 36 * between a clause 45 DEVAD and the old AER multicast format. 37 */ 38 39 #include <phymod/phymod_system.h> 40 #include <phymod/phymod_sim.h> 41 42 /* Convenience macro */ 43 #define DBG_VERB PHYMOD_DEBUG_VERBOSE 44 45 /* Bit field get/set macros */ 46 #define BLACKHAWK_BF_SET(_val, _mask, _shift) _val |= ((_mask) << (_shift)) 47 #define BLACKHAWK_BF_GET(_val, _mask, _shift) (((_val) >> (_shift)) & (_mask)) 48 49 /* 50 * Raw 32-bit address consists of AER value in upper 16 bits and 51 * clause 45 address in lower 16 bits. 52 */ 53 #define BLACKHAWK_DEVAD_SHIFT 27 54 #define BLACKHAWK_DEVAD_MASK 0x1f 55 #define BLACKHAWK_DEVAD_GET(_addr) \ 56 BLACKHAWK_BF_GET(_addr, BLACKHAWK_DEVAD_MASK, BLACKHAWK_DEVAD_SHIFT) 57 #define BLACKHAWK_LANE_SHIFT 16 58 #define BLACKHAWK_LANE_MASK 0xff 59 #define BLACKHAWK_LANE_GET(_addr) \ 60 BLACKHAWK_BF_GET(_addr, BLACKHAWK_LANE_MASK, BLACKHAWK_LANE_SHIFT) 61 #define BLACKHAWK_PLL_ID_SHIFT 24 62 #define BLACKHAWK_PLL_ID_MASK 0x3 63 #define BLACKHAWK_PLL_ID_GET(_addr) \ 64 BLACKHAWK_BF_GET(_addr, BLACKHAWK_PLL_ID_MASK, BLACKHAWK_PLL_ID_SHIFT) 65 #define BLACKHAWK_REG_SHIFT 0 66 #define BLACKHAWK_REG_MASK 0xffff 67 #define BLACKHAWK_REG_GET(_addr) \ 68 BLACKHAWK_BF_GET(_addr, BLACKHAWK_REG_MASK, BLACKHAWK_REG_SHIFT) 69 70 #define BLACKHAWK_ADDR(_devad, _pll_id, _lane, _reg) \ 71 (((_devad) << BLACKHAWK_DEVAD_SHIFT) + \ 72 ((_pll_id) << BLACKHAWK_PLL_ID_SHIFT) + \ 73 ((_lane) << BLACKHAWK_LANE_SHIFT) + \ 74 ((_reg) << BLACKHAWK_REG_SHIFT)) 75 76 #define BLACKHAWK_AER BLACKHAWK_ADDR(0, 0, 0, 0xffde) 77 #define BLACKHAWK_BLK BLACKHAWK_ADDR(0, 0, 0, 0x001f) 78 79 /* 80 * The CL45 indicator is used to determine whether the upper 16 bits 81 * of the address is an AER value or a clause 45 DEVAD. 82 */ 83 #define BLACKHAWK_CL45 (0x20 << 16) 84 #define BLACKHAWK_CL45_MASK (0xe0 << 16) 85 86 #define BLACKHAWK_ID0 0x600d 87 #define BLACKHAWK_ID1 0x8770 88 #define BLACKHAWK_MODEL 0x26 89 90 #define BLACKHAWK_SIM_FW_LOAD_DONE_REG_ADDR (0x800d203) 91 92 /*RAM sim*/ 93 #define BLACKHAWK_RAM_AHB_CTRL (0xd202) 94 #define BLACKHAWK_RAM_WR_ADDR_REG_MS (0xd205) 95 #define BLACKHAWK_RAM_WR_ADDR_REG_LS (0xd204) 96 #define BLACKHAWK_RAM_WR_DATA_REG_MS (0xd207) 97 #define BLACKHAWK_RAM_WR_DATA_REG_LS (0xd206) 98 #define BLACKHAWK_RAM_RD_ADDR_REG_MS (0xd209) 99 #define BLACKHAWK_RAM_RD_ADDR_REG_LS (0xd208) 100 #define BLACKHAWK_RAM_RD_DATA_REG_MS (0xd20b) 101 #define BLACKHAWK_RAM_RD_DATA_REG_LS (0xd20a) 102 #define BLACKHAWK_IS_RAM_ADDR_REG(reg) (reg == BLACKHAWK_RAM_WR_ADDR_REG_MS || reg == BLACKHAWK_RAM_WR_ADDR_REG_LS || reg == BLACKHAWK_RAM_RD_ADDR_REG_MS || reg == BLACKHAWK_RAM_RD_ADDR_REG_LS) 103 #define BLACKHAWK_IS_RAM_DATA_REG(reg) (reg == BLACKHAWK_RAM_WR_DATA_REG_MS || reg == BLACKHAWK_RAM_WR_DATA_REG_LS || reg == BLACKHAWK_RAM_RD_DATA_REG_MS || reg == BLACKHAWK_RAM_RD_DATA_REG_LS) 104 105 #define BLACKHAWK_SIM_ENTRY_F_RAM_LS_DATA_ENTRY (0x1) 106 #define BLACKHAWK_SIM_ENTRY_F_RAM_MS_DATA_ENTRY (0x2) 107 #define BLACKHAWK_SIM_ENTRY_F_RAM_LS_ADDR_ENTRY (0x4) 108 #define BLACKHAWK_SIM_ENTRY_F_RAM_MS_ADDR_ENTRY (0x8) 109 110 #define BLACKHAWK_UC_TABLE_RAM_BASE (0x100) 111 #define BLACKHAWK_UC_TABLE_RAM_SIZE (56) 112 static uint16_t blackhawk_uc_mem_table[BLACKHAWK_UC_TABLE_RAM_SIZE] = 113 { 114 0x6e49, 0x3666, 0x0208, 0x00d0, 0x0200, 0x3400, 0x4002, 0x0100, 0x0100, 0x2000, 0x0080, 0x2000, 115 0x0, 0x0, 0x0800, 0x2000, 0x0008, 0x0, 0x0104, 0x0100, 0x0310, 0x2000, 0x1c80, 0x2000, 116 0x1480, 0x2000, 0x0, 0x0, 0x0, 0x0, 0x0330, 0x2000, 0x0080, 0x0, 0x1380, 0x2000, 117 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 118 0x0104, 0x0000, 0x0300, 0x2000, 0x1fd0, 0x0, 0x0, 0x0 119 120 }; 121 static int blackhawk_ram_addr; 122 123 124 /* Forward declarations */ 125 STATIC int 126 blackhawk_sim_write(phymod_sim_data_t *pms_data, uint32_t addr, uint32_t data); 127 STATIC int 128 blackhawk_sim_read(phymod_sim_data_t *pms_data, uint32_t addr, uint32_t *data); 129 130 131 STATIC uint32_t 132 blackhawk_sim_default_data_get(uint32_t addr) 133 { 134 uint32_t reg; 135 136 reg = BLACKHAWK_REG_GET(addr); 137 138 /*force FW load success */ 139 if(addr == BLACKHAWK_SIM_FW_LOAD_DONE_REG_ADDR) { 140 return 1; 141 } 142 switch (reg) { 143 case 0x0002: 144 return 0; 145 case 0x0003: 146 return 0; 147 case 0xd03d: 148 /* 149 * This is DSC_A_DSC_UC_CTRL for Falcon. Make sure 150 * The 'ready' bit is set. 151 */ 152 return 0x0080; 153 case 0xd0b9: 154 return 0x7; 155 case 0xd0d9: 156 return 0x47c0; 157 case 0xd100: 158 return BLACKHAWK_MODEL; 159 case 0xd10a: 160 return 0x803c; 161 case 0xd188: 162 /* 163 * Reset check 164 */ 165 return 0x7; 166 case 0xd170: 167 return 0xb000; 168 case 0xd1c9: 169 return 0x0007; 170 default: 171 break; 172 } 173 174 return 0; 175 } 176 177 STATIC int 178 _blackhawk_sim_write(phymod_sim_data_t *pms_data, uint32_t addr, uint32_t data) 179 { 180 int idx; 181 uint32_t mask; 182 183 phymod_sim_entry_t *pse; 184 185 if (pms_data == NULL || pms_data->entries == NULL) { 186 return PHYMOD_E_INIT; 187 } 188 189 /* Support optional write mask in upper 16 bits */ 190 mask = (data >> 16); 191 if (mask == 0) { 192 mask = 0xffff; 193 } 194 data &= mask; 195 196 /* Check if this register has been written already */ 197 for (idx = 0; idx < pms_data->entries_used; idx++) { 198 pse = &pms_data->entries[idx]; 199 if (pse->addr == addr) { 200 pse->data &= ~mask; 201 pse->data |= data; 202 DBG_VERB(("_blackhawk_sim_write 0x%08"PRIx32" = 0x%04"PRIx32"\n", 203 addr, pse->data)); 204 return PHYMOD_E_NONE; 205 } 206 } 207 208 /* Check if database is full */ 209 if (pms_data->entries_used >= pms_data->num_entries) { 210 return PHYMOD_E_RESOURCE; 211 } 212 213 /* Check if new data matches default value */ 214 if (data == blackhawk_sim_default_data_get(addr)) { 215 return PHYMOD_E_NONE; 216 } 217 218 /* Add new register value */ 219 pse = &pms_data->entries[pms_data->entries_used++]; 220 pse->addr = addr; 221 pse->data = data; 222 223 DBG_VERB(("_blackhawk_sim_write 0x%08"PRIx32" = 0x%04"PRIx32" (new)\n", 224 addr, pse->data)); 225 226 return PHYMOD_E_NONE; 227 } 228 229 230 231 STATIC uint32_t 232 blackhawk_sim_reg_copies_get(uint32_t addr) 233 { 234 uint32_t devad, reg; 235 236 devad = BLACKHAWK_DEVAD_GET(addr); 237 reg = BLACKHAWK_REG_GET(addr); 238 239 if (reg == BLACKHAWK_AER || reg == BLACKHAWK_BLK) { 240 return 1; 241 } 242 243 if (devad == 0) { 244 if ((reg & 0xf000) == 0x9000) { 245 return 2; 246 } 247 if ((reg & 0xf000) == 0xc000) { 248 return 4; 249 } 250 } 251 else if (devad == 1) { 252 if ((reg & 0xfff0) == 0xd100) { 253 return 1; 254 } 255 if ((reg & 0xfff0) == 0xd190) { 256 return 1; 257 } 258 if ((reg & 0xfff0) == 0xd180) { 259 return 2; 260 } 261 if ((reg & 0xfff0) == 0xd140) { 262 return 2; 263 } 264 if ((reg & 0xfff0) == 0xd110) { 265 return 2; 266 } 267 return 8; 268 } 269 return 0; 270 } 271 272 STATIC int 273 blackhawk_sim_init(phymod_sim_data_t *pms_data, 274 int num_entries, phymod_sim_entry_t *entries) 275 { 276 if (pms_data != NULL) { 277 PHYMOD_MEMSET(pms_data, 0, sizeof(*pms_data)); 278 pms_data->num_entries = num_entries; 279 pms_data->entries = entries; 280 } 281 return PHYMOD_E_NONE; 282 } 283 284 STATIC int 285 blackhawk_sim_reset(phymod_sim_data_t *pms_data) 286 { 287 uint32_t sim_size; 288 289 if (pms_data == NULL || pms_data->entries == NULL) { 290 return PHYMOD_E_INIT; 291 } 292 293 pms_data->entries_used = 0; 294 sim_size = pms_data->num_entries * sizeof(phymod_sim_entry_t); 295 PHYMOD_MEMSET(pms_data->entries, 0, sim_size); 296 297 return PHYMOD_E_NONE; 298 } 299 300 STATIC int 301 blackhawk_sim_read(phymod_sim_data_t *pms_data, uint32_t addr, uint32_t *data) 302 { 303 int idx; 304 uint32_t aer, blk, devad, reg, copies, pll_id=0; 305 uint32_t lane = 0; 306 phymod_sim_entry_t *pse; 307 uint32_t pse_flag = 0; 308 uint32_t addr_ms = 0, addr_ls = 0, abh_ctrl = 0; 309 int increase_addr_auto = 0; 310 311 if (pms_data == NULL || pms_data->entries == NULL) { 312 return PHYMOD_E_INIT; 313 } 314 315 devad = 0; 316 317 318 if (addr < BLACKHAWK_BLK) { 319 /* Assume clause 22 access */ 320 (void)blackhawk_sim_read(pms_data, BLACKHAWK_BLK, &blk); 321 if (addr & 0x10) { 322 /* IEEE bit */ 323 blk |= 0x8000; 324 } 325 addr = (addr & 0xf) | (blk & 0xfff0); 326 if (addr != BLACKHAWK_AER && addr != BLACKHAWK_BLK) { 327 (void)blackhawk_sim_read(pms_data, BLACKHAWK_AER, &aer); 328 addr |= (aer << 16); 329 } 330 } else { 331 /* Extract devad if clause 45 address format */ 332 if ((addr & BLACKHAWK_CL45_MASK) == BLACKHAWK_CL45) { 333 devad = (addr >> 16) & 0x1f; 334 addr &= 0xffff; 335 } 336 } 337 338 if (addr != BLACKHAWK_AER && addr != BLACKHAWK_BLK) { 339 /* Assume AER is in upper 16 bits */ 340 aer = (addr >> 16); 341 if (aer == 0) { 342 /* Try reading real AER instead */ 343 (void)blackhawk_sim_read(pms_data, BLACKHAWK_AER, &aer); 344 } 345 /* Add clause 45 devad (if used) */ 346 aer |= (devad << 11); 347 addr = (addr & 0xffff) | (aer << 16); 348 349 lane = (aer & 0x7); 350 } 351 352 /* Adjust lane according to number of copies */ 353 devad = BLACKHAWK_DEVAD_GET(addr); 354 reg = BLACKHAWK_REG_GET(addr); 355 copies = blackhawk_sim_reg_copies_get(addr); 356 if (copies == 1) { 357 lane = 0; 358 } else if (copies == 2) { 359 pll_id = BLACKHAWK_PLL_ID_GET(addr); 360 lane = (pll_id == 0) ? 0 : 1; 361 } 362 363 /*handle ram read/write*/ 364 if (BLACKHAWK_IS_RAM_DATA_REG(reg) || BLACKHAWK_IS_RAM_ADDR_REG(reg)) { 365 366 if (BLACKHAWK_IS_RAM_DATA_REG(reg)) { 367 (void)blackhawk_sim_read(pms_data, BLACKHAWK_ADDR(devad, pll_id, lane, BLACKHAWK_RAM_AHB_CTRL), &abh_ctrl); 368 increase_addr_auto = ((abh_ctrl >> 13) & 0x1); 369 370 (void)blackhawk_sim_read(pms_data, BLACKHAWK_ADDR(devad, pll_id, lane, BLACKHAWK_RAM_RD_ADDR_REG_LS), &addr_ls); 371 (void)blackhawk_sim_read(pms_data, BLACKHAWK_ADDR(devad, pll_id, lane, BLACKHAWK_RAM_RD_ADDR_REG_MS), &addr_ms); 372 addr = addr_ls | (addr_ms << 16); 373 if (blackhawk_ram_addr == 0 ) { 374 blackhawk_ram_addr = addr; 375 } else { 376 if (increase_addr_auto) { 377 blackhawk_ram_addr += 1; 378 } else { 379 blackhawk_ram_addr = 0; 380 } 381 } 382 383 if (reg == BLACKHAWK_RAM_RD_DATA_REG_LS || reg == BLACKHAWK_RAM_WR_DATA_REG_LS) { 384 pse_flag |= BLACKHAWK_SIM_ENTRY_F_RAM_LS_DATA_ENTRY; 385 } else { 386 pse_flag |= BLACKHAWK_SIM_ENTRY_F_RAM_MS_DATA_ENTRY; 387 } 388 } else { /*BLACKHAWK_IS_RAM_ADDR_REG*/ 389 addr = BLACKHAWK_ADDR(devad, 0, lane, 0 /*dummy*/); 390 if (reg == BLACKHAWK_RAM_RD_ADDR_REG_LS || reg == BLACKHAWK_RAM_WR_ADDR_REG_LS) { 391 pse_flag |= BLACKHAWK_SIM_ENTRY_F_RAM_LS_ADDR_ENTRY; 392 } else { 393 pse_flag |= BLACKHAWK_SIM_ENTRY_F_RAM_MS_ADDR_ENTRY; 394 } 395 } 396 397 /* Check if this register has been written already */ 398 for (idx = 0; idx < pms_data->entries_used; idx++) { 399 pse = &pms_data->entries[idx]; 400 if ((pse->addr == addr) && (pse->flags == pse_flag)) { 401 *data = pse->data; 402 DBG_VERB(("blackhawk_sim_read 0x%08"PRIx32" = 0x%04"PRIx32"\n", 403 addr, *data)); 404 return PHYMOD_E_NONE; 405 } 406 } 407 408 if((blackhawk_ram_addr >= BLACKHAWK_UC_TABLE_RAM_BASE) && (blackhawk_ram_addr < (BLACKHAWK_UC_TABLE_RAM_BASE + BLACKHAWK_UC_TABLE_RAM_SIZE))) { 409 *data = blackhawk_uc_mem_table[blackhawk_ram_addr - BLACKHAWK_UC_TABLE_RAM_BASE]; 410 }else { 411 *data = 0; 412 } 413 414 return PHYMOD_E_NONE; 415 } 416 417 418 419 addr = BLACKHAWK_ADDR(devad, pll_id, lane, reg); 420 421 /* Check if this register has been written already */ 422 for (idx = 0; idx < pms_data->entries_used; idx++) { 423 pse = &pms_data->entries[idx]; 424 if ((pse->addr == addr) && (pse->flags == pse_flag)) { 425 *data = pse->data; 426 DBG_VERB(("blackhawk_sim_read 0x%08"PRIx32" = 0x%04"PRIx32"\n", 427 addr, *data)); 428 return PHYMOD_E_NONE; 429 } 430 } 431 432 /* Return default value if register was never written */ 433 *data = blackhawk_sim_default_data_get(addr); 434 435 DBG_VERB(("blackhawk_sim_read 0x%08"PRIx32" = [0x%04"PRIx32"]\n", 436 addr, *data)); 437 438 return PHYMOD_E_NONE; 439 } 440 441 STATIC int 442 blackhawk_sim_write(phymod_sim_data_t *pms_data, uint32_t addr, uint32_t data) 443 { 444 int idx; 445 uint32_t aer, blk, devad, reg, copies, pll_id=0; 446 uint32_t lane = 0; 447 phymod_sim_entry_t *pse; 448 uint32_t pse_flag = 0; 449 uint32_t addr_ms = 0, addr_ls = 0; 450 451 if (pms_data == NULL || pms_data->entries == NULL) { 452 return PHYMOD_E_INIT; 453 } 454 455 devad = 0; 456 457 if (addr < BLACKHAWK_BLK) { 458 /* Assume clause 22 access */ 459 (void)blackhawk_sim_read(pms_data, BLACKHAWK_BLK, &blk); 460 /* IEEE bit */ 461 if (addr & 0x10) { 462 blk |= 0x8000; 463 } else { 464 blk &= ~0x8000; 465 } 466 addr = (addr & 0xf) | (blk & 0xfff0); 467 if (addr != BLACKHAWK_AER && addr != BLACKHAWK_BLK) { 468 (void)blackhawk_sim_read(pms_data, BLACKHAWK_AER, &aer); 469 addr |= (aer << 16); 470 } 471 } else { 472 /* Extract devad if clause 45 address format */ 473 if ((addr & BLACKHAWK_CL45_MASK) == BLACKHAWK_CL45) { 474 devad = (addr >> 16) & 0x1f; 475 addr &= 0xffff; 476 } 477 } 478 479 if (addr != BLACKHAWK_AER && addr != BLACKHAWK_BLK) { 480 /* Assume AER is in upper 16 bits */ 481 aer = (addr >> 16); 482 if (aer == 0) { 483 /* Try reading real AER instead */ 484 (void)blackhawk_sim_read(pms_data, BLACKHAWK_AER, &aer); 485 } 486 487 /* Add clause 45 devad (if used) */ 488 aer |= (devad << 11); 489 addr = (addr & 0xffff) | (aer << 16); 490 491 lane = (aer & 0xff); 492 if (lane > 7) { 493 /* 494 * Handle lane broadcast 495 * 496 * Note that we use lane 8 instead of lane 0 to prevent a 497 * broadcast loop. The value 8 will become 0 when masked 498 * with 0x7, but it prevents the AER in the upper 16 bits 499 * from being zero, which will cause the code above to 500 * obtain the AER value from register 0xffde. 501 */ 502 reg = BLACKHAWK_REG_GET(addr); 503 devad = BLACKHAWK_DEVAD_GET(addr); 504 pll_id = BLACKHAWK_PLL_ID_GET(addr); 505 if (lane == 0x20) { 506 /* Write lanes 0 and 1 */ 507 addr = BLACKHAWK_ADDR(devad, pll_id, 0, reg); 508 (void)blackhawk_sim_write(pms_data, addr, data); 509 addr = BLACKHAWK_ADDR(devad, pll_id, 1, reg); 510 (void)blackhawk_sim_write(pms_data, addr, data); 511 } 512 if (lane == 0x21) { 513 /* Write lanes 2 and 3 */ 514 addr = BLACKHAWK_ADDR(devad, pll_id, 2, reg); 515 (void)blackhawk_sim_write(pms_data, addr, data); 516 addr = BLACKHAWK_ADDR(devad, pll_id, 3, reg); 517 (void)blackhawk_sim_write(pms_data, addr, data); 518 } 519 if (lane == 0x22) { 520 /* Write lanes 4 and 5 */ 521 addr = BLACKHAWK_ADDR(devad, pll_id, 4, reg); 522 (void)blackhawk_sim_write(pms_data, addr, data); 523 addr = BLACKHAWK_ADDR(devad, pll_id, 5, reg); 524 (void)blackhawk_sim_write(pms_data, addr, data); 525 } 526 if (lane == 0x23) { 527 /* Write lanes 6 and 7 */ 528 addr = BLACKHAWK_ADDR(devad, pll_id, 6, reg); 529 (void)blackhawk_sim_write(pms_data, addr, data); 530 addr = BLACKHAWK_ADDR(devad, pll_id, 7, reg); 531 (void)blackhawk_sim_write(pms_data, addr, data); 532 } 533 if (lane == 0x40) { 534 /* Write lanes 0,1,2,and 3 */ 535 addr = BLACKHAWK_ADDR(devad, pll_id, 0, reg); 536 (void)blackhawk_sim_write(pms_data, addr, data); 537 addr = BLACKHAWK_ADDR(devad, pll_id, 1, reg); 538 (void)blackhawk_sim_write(pms_data, addr, data); 539 addr = BLACKHAWK_ADDR(devad, pll_id, 2, reg); 540 (void)blackhawk_sim_write(pms_data, addr, data); 541 addr = BLACKHAWK_ADDR(devad, pll_id, 3, reg); 542 (void)blackhawk_sim_write(pms_data, addr, data); 543 } 544 if (lane == 0x41) { 545 /* Write lanes 4,5,6 and 7 */ 546 addr = BLACKHAWK_ADDR(devad, pll_id, 4, reg); 547 (void)blackhawk_sim_write(pms_data, addr, data); 548 addr = BLACKHAWK_ADDR(devad, pll_id, 5, reg); 549 (void)blackhawk_sim_write(pms_data, addr, data); 550 addr = BLACKHAWK_ADDR(devad, pll_id, 6, reg); 551 (void)blackhawk_sim_write(pms_data, addr, data); 552 addr = BLACKHAWK_ADDR(devad, pll_id, 7, reg); 553 (void)blackhawk_sim_write(pms_data, addr, data); 554 } 555 if (lane == 0xff) { 556 /* Write lanes 2 and 3 */ 557 addr = BLACKHAWK_ADDR(devad, pll_id, 0, reg); 558 (void)blackhawk_sim_write(pms_data, addr, data); 559 addr = BLACKHAWK_ADDR(devad, pll_id, 1, reg); 560 (void)blackhawk_sim_write(pms_data, addr, data); 561 addr = BLACKHAWK_ADDR(devad, pll_id, 2, reg); 562 (void)blackhawk_sim_write(pms_data, addr, data); 563 addr = BLACKHAWK_ADDR(devad, pll_id, 3, reg); 564 (void)blackhawk_sim_write(pms_data, addr, data); 565 addr = BLACKHAWK_ADDR(devad, pll_id, 4, reg); 566 (void)blackhawk_sim_write(pms_data, addr, data); 567 addr = BLACKHAWK_ADDR(devad, pll_id, 5, reg); 568 (void)blackhawk_sim_write(pms_data, addr, data); 569 addr = BLACKHAWK_ADDR(devad, pll_id, 6, reg); 570 (void)blackhawk_sim_write(pms_data, addr, data); 571 addr = BLACKHAWK_ADDR(devad, pll_id, 7, reg); 572 (void)blackhawk_sim_write(pms_data, addr, data); 573 } 574 return PHYMOD_E_NONE; 575 } 576 } 577 578 /* Adjust lane according to number of copies */ 579 devad = BLACKHAWK_DEVAD_GET(addr); 580 reg = BLACKHAWK_REG_GET(addr); 581 copies = blackhawk_sim_reg_copies_get(addr); 582 if (copies == 1) { 583 lane = 0; 584 } else if (copies == 2) { 585 pll_id = BLACKHAWK_PLL_ID_GET(addr); 586 lane = (pll_id == 0) ? 0 : 1; 587 } 588 589 /*handle ram read/write*/ 590 if (BLACKHAWK_IS_RAM_DATA_REG(reg) || BLACKHAWK_IS_RAM_ADDR_REG(reg)) { 591 592 if (BLACKHAWK_IS_RAM_DATA_REG(reg)) { 593 594 (void)blackhawk_sim_read(pms_data, BLACKHAWK_ADDR(devad, pll_id, lane, BLACKHAWK_RAM_RD_ADDR_REG_LS), &addr_ls); 595 (void)blackhawk_sim_read(pms_data, BLACKHAWK_ADDR(devad, pll_id, lane, BLACKHAWK_RAM_RD_ADDR_REG_MS), &addr_ms); 596 addr = addr_ls | (addr_ms << 16); 597 if (reg == BLACKHAWK_RAM_RD_DATA_REG_LS || reg == BLACKHAWK_RAM_WR_DATA_REG_LS) { 598 pse_flag |= BLACKHAWK_SIM_ENTRY_F_RAM_LS_DATA_ENTRY; 599 } else { 600 pse_flag |= BLACKHAWK_SIM_ENTRY_F_RAM_MS_DATA_ENTRY; 601 } 602 } else { /*BLACKHAWK_IS_RAM_ADDR_REG*/ 603 addr = BLACKHAWK_ADDR(devad, 0, lane, 0 /*dummy*/); 604 if (reg == BLACKHAWK_RAM_RD_ADDR_REG_LS || reg == BLACKHAWK_RAM_WR_ADDR_REG_LS) { 605 pse_flag |= BLACKHAWK_SIM_ENTRY_F_RAM_LS_ADDR_ENTRY; 606 } else { 607 pse_flag |= BLACKHAWK_SIM_ENTRY_F_RAM_MS_ADDR_ENTRY; 608 } 609 } 610 611 /* Check if this register has been written already */ 612 for (idx = 0; idx < pms_data->entries_used; idx++) { 613 pse = &pms_data->entries[idx]; 614 if ((pse->addr == addr) && (pse->flags == pse_flag)) { 615 pse->data = data; 616 DBG_VERB(("blackhawk_sim_write 0x%08"PRIx32" = 0x%04"PRIx32" - flag = %u \n", 617 addr, pse->data, pse_flag)); 618 return PHYMOD_E_NONE; 619 } 620 } 621 pse = &pms_data->entries[pms_data->entries_used++]; 622 pse->addr = addr; 623 pse->data = data; 624 pse->flags = pse_flag; 625 626 DBG_VERB(("blackhawk_sim_write 0x%08"PRIx32" = 0x%04"PRIx32" - flag = %u (new)\n", 627 addr, pse->data, pse->flags)); 628 629 return PHYMOD_E_NONE; 630 } 631 632 addr = BLACKHAWK_ADDR(devad, pll_id, lane, reg); 633 634 return _blackhawk_sim_write(pms_data, addr, data); 635 } 636 637 STATIC int 638 blackhawk_sim_event(phymod_sim_data_t *pms_data, phymod_sim_event_t event) 639 { 640 if (pms_data == NULL || pms_data->entries == NULL) { 641 return PHYMOD_E_INIT; 642 } 643 644 return PHYMOD_E_NONE; 645 } 646 647 phymod_sim_drv_t blackhawk_sim_drv = { 648 blackhawk_sim_init, 649 blackhawk_sim_reset, 650 blackhawk_sim_read, 651 blackhawk_sim_write, 652 blackhawk_sim_event 653 }; 654