1 // SPDX-License-Identifier: GPL-2.0 2 /* Copyright (C) 2021, Intel Corporation. */ 3 4 #include "ice_common.h" 5 #include "ice_ptp_hw.h" 6 7 /* Low level functions for interacting with and managing the device clock used 8 * for the Precision Time Protocol. 9 * 10 * The ice hardware represents the current time using three registers: 11 * 12 * GLTSYN_TIME_H GLTSYN_TIME_L GLTSYN_TIME_R 13 * +---------------+ +---------------+ +---------------+ 14 * | 32 bits | | 32 bits | | 32 bits | 15 * +---------------+ +---------------+ +---------------+ 16 * 17 * The registers are incremented every clock tick using a 40bit increment 18 * value defined over two registers: 19 * 20 * GLTSYN_INCVAL_H GLTSYN_INCVAL_L 21 * +---------------+ +---------------+ 22 * | 8 bit s | | 32 bits | 23 * +---------------+ +---------------+ 24 * 25 * The increment value is added to the GLSTYN_TIME_R and GLSTYN_TIME_L 26 * registers every clock source tick. Depending on the specific device 27 * configuration, the clock source frequency could be one of a number of 28 * values. 29 * 30 * For E810 devices, the increment frequency is 812.5 MHz 31 * 32 * The hardware captures timestamps in the PHY for incoming packets, and for 33 * outgoing packets on request. To support this, the PHY maintains a timer 34 * that matches the lower 64 bits of the global source timer. 35 * 36 * In order to ensure that the PHY timers and the source timer are equivalent, 37 * shadow registers are used to prepare the desired initial values. A special 38 * sync command is issued to trigger copying from the shadow registers into 39 * the appropriate source and PHY registers simultaneously. 40 */ 41 42 /** 43 * ice_get_ptp_src_clock_index - determine source clock index 44 * @hw: pointer to HW struct 45 * 46 * Determine the source clock index currently in use, based on device 47 * capabilities reported during initialization. 48 */ 49 u8 ice_get_ptp_src_clock_index(struct ice_hw *hw) 50 { 51 return hw->func_caps.ts_func_info.tmr_index_assoc; 52 } 53 54 /* E810 functions 55 * 56 * The following functions operate on the E810 series devices which use 57 * a separate external PHY. 58 */ 59 60 /** 61 * ice_read_phy_reg_e810 - Read register from external PHY on E810 62 * @hw: pointer to the HW struct 63 * @addr: the address to read from 64 * @val: On return, the value read from the PHY 65 * 66 * Read a register from the external PHY on the E810 device. 67 */ 68 static int ice_read_phy_reg_e810(struct ice_hw *hw, u32 addr, u32 *val) 69 { 70 struct ice_sbq_msg_input msg = {0}; 71 int err; 72 73 msg.msg_addr_low = lower_16_bits(addr); 74 msg.msg_addr_high = upper_16_bits(addr); 75 msg.opcode = ice_sbq_msg_rd; 76 msg.dest_dev = rmn_0; 77 78 err = ice_sbq_rw_reg(hw, &msg); 79 if (err) { 80 ice_debug(hw, ICE_DBG_PTP, "Failed to send message to PHY, err %d\n", 81 err); 82 return err; 83 } 84 85 *val = msg.data; 86 87 return 0; 88 } 89 90 /** 91 * ice_write_phy_reg_e810 - Write register on external PHY on E810 92 * @hw: pointer to the HW struct 93 * @addr: the address to writem to 94 * @val: the value to write to the PHY 95 * 96 * Write a value to a register of the external PHY on the E810 device. 97 */ 98 static int ice_write_phy_reg_e810(struct ice_hw *hw, u32 addr, u32 val) 99 { 100 struct ice_sbq_msg_input msg = {0}; 101 int err; 102 103 msg.msg_addr_low = lower_16_bits(addr); 104 msg.msg_addr_high = upper_16_bits(addr); 105 msg.opcode = ice_sbq_msg_wr; 106 msg.dest_dev = rmn_0; 107 msg.data = val; 108 109 err = ice_sbq_rw_reg(hw, &msg); 110 if (err) { 111 ice_debug(hw, ICE_DBG_PTP, "Failed to send message to PHY, err %d\n", 112 err); 113 return err; 114 } 115 116 return 0; 117 } 118 119 /** 120 * ice_read_phy_tstamp_e810 - Read a PHY timestamp out of the external PHY 121 * @hw: pointer to the HW struct 122 * @lport: the lport to read from 123 * @idx: the timestamp index to read 124 * @tstamp: on return, the 40bit timestamp value 125 * 126 * Read a 40bit timestamp value out of the timestamp block of the external PHY 127 * on the E810 device. 128 */ 129 static int 130 ice_read_phy_tstamp_e810(struct ice_hw *hw, u8 lport, u8 idx, u64 *tstamp) 131 { 132 u32 lo_addr, hi_addr, lo, hi; 133 int err; 134 135 lo_addr = TS_EXT(LOW_TX_MEMORY_BANK_START, lport, idx); 136 hi_addr = TS_EXT(HIGH_TX_MEMORY_BANK_START, lport, idx); 137 138 err = ice_read_phy_reg_e810(hw, lo_addr, &lo); 139 if (err) { 140 ice_debug(hw, ICE_DBG_PTP, "Failed to read low PTP timestamp register, err %d\n", 141 err); 142 return err; 143 } 144 145 err = ice_read_phy_reg_e810(hw, hi_addr, &hi); 146 if (err) { 147 ice_debug(hw, ICE_DBG_PTP, "Failed to read high PTP timestamp register, err %d\n", 148 err); 149 return err; 150 } 151 152 /* For E810 devices, the timestamp is reported with the lower 32 bits 153 * in the low register, and the upper 8 bits in the high register. 154 */ 155 *tstamp = ((u64)hi) << TS_HIGH_S | ((u64)lo & TS_LOW_M); 156 157 return 0; 158 } 159 160 /** 161 * ice_clear_phy_tstamp_e810 - Clear a timestamp from the external PHY 162 * @hw: pointer to the HW struct 163 * @lport: the lport to read from 164 * @idx: the timestamp index to reset 165 * 166 * Clear a timestamp, resetting its valid bit, from the timestamp block of the 167 * external PHY on the E810 device. 168 */ 169 static int ice_clear_phy_tstamp_e810(struct ice_hw *hw, u8 lport, u8 idx) 170 { 171 u32 lo_addr, hi_addr; 172 int err; 173 174 lo_addr = TS_EXT(LOW_TX_MEMORY_BANK_START, lport, idx); 175 hi_addr = TS_EXT(HIGH_TX_MEMORY_BANK_START, lport, idx); 176 177 err = ice_write_phy_reg_e810(hw, lo_addr, 0); 178 if (err) { 179 ice_debug(hw, ICE_DBG_PTP, "Failed to clear low PTP timestamp register, err %d\n", 180 err); 181 return err; 182 } 183 184 err = ice_write_phy_reg_e810(hw, hi_addr, 0); 185 if (err) { 186 ice_debug(hw, ICE_DBG_PTP, "Failed to clear high PTP timestamp register, err %d\n", 187 err); 188 return err; 189 } 190 191 return 0; 192 } 193 194 /** 195 * ice_ptp_init_phy_e810 - Enable PTP function on the external PHY 196 * @hw: pointer to HW struct 197 * 198 * Enable the timesync PTP functionality for the external PHY connected to 199 * this function. 200 */ 201 int ice_ptp_init_phy_e810(struct ice_hw *hw) 202 { 203 u8 tmr_idx; 204 int err; 205 206 tmr_idx = hw->func_caps.ts_func_info.tmr_index_owned; 207 err = ice_write_phy_reg_e810(hw, ETH_GLTSYN_ENA(tmr_idx), 208 GLTSYN_ENA_TSYN_ENA_M); 209 if (err) 210 ice_debug(hw, ICE_DBG_PTP, "PTP failed in ena_phy_time_syn %d\n", 211 err); 212 213 return err; 214 } 215 216 /** 217 * ice_ptp_init_phc_e810 - Perform E810 specific PHC initialization 218 * @hw: pointer to HW struct 219 * 220 * Perform E810-specific PTP hardware clock initialization steps. 221 */ 222 static int ice_ptp_init_phc_e810(struct ice_hw *hw) 223 { 224 /* Ensure synchronization delay is zero */ 225 wr32(hw, GLTSYN_SYNC_DLAY, 0); 226 227 /* Initialize the PHY */ 228 return ice_ptp_init_phy_e810(hw); 229 } 230 231 /** 232 * ice_ptp_prep_phy_time_e810 - Prepare PHY port with initial time 233 * @hw: Board private structure 234 * @time: Time to initialize the PHY port clock to 235 * 236 * Program the PHY port ETH_GLTSYN_SHTIME registers in preparation setting the 237 * initial clock time. The time will not actually be programmed until the 238 * driver issues an INIT_TIME command. 239 * 240 * The time value is the upper 32 bits of the PHY timer, usually in units of 241 * nominal nanoseconds. 242 */ 243 static int ice_ptp_prep_phy_time_e810(struct ice_hw *hw, u32 time) 244 { 245 u8 tmr_idx; 246 int err; 247 248 tmr_idx = hw->func_caps.ts_func_info.tmr_index_owned; 249 err = ice_write_phy_reg_e810(hw, ETH_GLTSYN_SHTIME_0(tmr_idx), 0); 250 if (err) { 251 ice_debug(hw, ICE_DBG_PTP, "Failed to write SHTIME_0, err %d\n", 252 err); 253 return err; 254 } 255 256 err = ice_write_phy_reg_e810(hw, ETH_GLTSYN_SHTIME_L(tmr_idx), time); 257 if (err) { 258 ice_debug(hw, ICE_DBG_PTP, "Failed to write SHTIME_L, err %d\n", 259 err); 260 return err; 261 } 262 263 return 0; 264 } 265 266 /** 267 * ice_ptp_prep_phy_adj_e810 - Prep PHY port for a time adjustment 268 * @hw: pointer to HW struct 269 * @adj: adjustment value to program 270 * 271 * Prepare the PHY port for an atomic adjustment by programming the PHY 272 * ETH_GLTSYN_SHADJ_L and ETH_GLTSYN_SHADJ_H registers. The actual adjustment 273 * is completed by issuing an ADJ_TIME sync command. 274 * 275 * The adjustment value only contains the portion used for the upper 32bits of 276 * the PHY timer, usually in units of nominal nanoseconds. Negative 277 * adjustments are supported using 2s complement arithmetic. 278 */ 279 static int ice_ptp_prep_phy_adj_e810(struct ice_hw *hw, s32 adj) 280 { 281 u8 tmr_idx; 282 int err; 283 284 tmr_idx = hw->func_caps.ts_func_info.tmr_index_owned; 285 286 /* Adjustments are represented as signed 2's complement values in 287 * nanoseconds. Sub-nanosecond adjustment is not supported. 288 */ 289 err = ice_write_phy_reg_e810(hw, ETH_GLTSYN_SHADJ_L(tmr_idx), 0); 290 if (err) { 291 ice_debug(hw, ICE_DBG_PTP, "Failed to write adj to PHY SHADJ_L, err %d\n", 292 err); 293 return err; 294 } 295 296 err = ice_write_phy_reg_e810(hw, ETH_GLTSYN_SHADJ_H(tmr_idx), adj); 297 if (err) { 298 ice_debug(hw, ICE_DBG_PTP, "Failed to write adj to PHY SHADJ_H, err %d\n", 299 err); 300 return err; 301 } 302 303 return 0; 304 } 305 306 /** 307 * ice_ptp_prep_phy_incval_e810 - Prep PHY port increment value change 308 * @hw: pointer to HW struct 309 * @incval: The new 40bit increment value to prepare 310 * 311 * Prepare the PHY port for a new increment value by programming the PHY 312 * ETH_GLTSYN_SHADJ_L and ETH_GLTSYN_SHADJ_H registers. The actual change is 313 * completed by issuing an INIT_INCVAL command. 314 */ 315 static int ice_ptp_prep_phy_incval_e810(struct ice_hw *hw, u64 incval) 316 { 317 u32 high, low; 318 u8 tmr_idx; 319 int err; 320 321 tmr_idx = hw->func_caps.ts_func_info.tmr_index_owned; 322 low = lower_32_bits(incval); 323 high = upper_32_bits(incval); 324 325 err = ice_write_phy_reg_e810(hw, ETH_GLTSYN_SHADJ_L(tmr_idx), low); 326 if (err) { 327 ice_debug(hw, ICE_DBG_PTP, "Failed to write incval to PHY SHADJ_L, err %d\n", 328 err); 329 return err; 330 } 331 332 err = ice_write_phy_reg_e810(hw, ETH_GLTSYN_SHADJ_H(tmr_idx), high); 333 if (err) { 334 ice_debug(hw, ICE_DBG_PTP, "Failed to write incval PHY SHADJ_H, err %d\n", 335 err); 336 return err; 337 } 338 339 return 0; 340 } 341 342 /** 343 * ice_ptp_port_cmd_e810 - Prepare all external PHYs for a timer command 344 * @hw: pointer to HW struct 345 * @cmd: Command to be sent to the port 346 * 347 * Prepare the external PHYs connected to this device for a timer sync 348 * command. 349 */ 350 static int ice_ptp_port_cmd_e810(struct ice_hw *hw, enum ice_ptp_tmr_cmd cmd) 351 { 352 u32 cmd_val, val; 353 int err; 354 355 switch (cmd) { 356 case INIT_TIME: 357 cmd_val = GLTSYN_CMD_INIT_TIME; 358 break; 359 case INIT_INCVAL: 360 cmd_val = GLTSYN_CMD_INIT_INCVAL; 361 break; 362 case ADJ_TIME: 363 cmd_val = GLTSYN_CMD_ADJ_TIME; 364 break; 365 case READ_TIME: 366 cmd_val = GLTSYN_CMD_READ_TIME; 367 break; 368 case ADJ_TIME_AT_TIME: 369 cmd_val = GLTSYN_CMD_ADJ_INIT_TIME; 370 break; 371 } 372 373 /* Read, modify, write */ 374 err = ice_read_phy_reg_e810(hw, ETH_GLTSYN_CMD, &val); 375 if (err) { 376 ice_debug(hw, ICE_DBG_PTP, "Failed to read GLTSYN_CMD, err %d\n", err); 377 return err; 378 } 379 380 /* Modify necessary bits only and perform write */ 381 val &= ~TS_CMD_MASK_E810; 382 val |= cmd_val; 383 384 err = ice_write_phy_reg_e810(hw, ETH_GLTSYN_CMD, val); 385 if (err) { 386 ice_debug(hw, ICE_DBG_PTP, "Failed to write back GLTSYN_CMD, err %d\n", err); 387 return err; 388 } 389 390 return 0; 391 } 392 393 /* Device agnostic functions 394 * 395 * The following functions implement useful behavior to hide the differences 396 * between E810 and other devices. They call the device-specific 397 * implementations where necessary. 398 * 399 * Currently, the driver only supports E810, but future work will enable 400 * support for E822-based devices. 401 */ 402 403 /** 404 * ice_ptp_lock - Acquire PTP global semaphore register lock 405 * @hw: pointer to the HW struct 406 * 407 * Acquire the global PTP hardware semaphore lock. Returns true if the lock 408 * was acquired, false otherwise. 409 * 410 * The PFTSYN_SEM register sets the busy bit on read, returning the previous 411 * value. If software sees the busy bit cleared, this means that this function 412 * acquired the lock (and the busy bit is now set). If software sees the busy 413 * bit set, it means that another function acquired the lock. 414 * 415 * Software must clear the busy bit with a write to release the lock for other 416 * functions when done. 417 */ 418 bool ice_ptp_lock(struct ice_hw *hw) 419 { 420 u32 hw_lock; 421 int i; 422 423 #define MAX_TRIES 5 424 425 for (i = 0; i < MAX_TRIES; i++) { 426 hw_lock = rd32(hw, PFTSYN_SEM + (PFTSYN_SEM_BYTES * hw->pf_id)); 427 hw_lock = hw_lock & PFTSYN_SEM_BUSY_M; 428 if (!hw_lock) 429 break; 430 431 /* Somebody is holding the lock */ 432 usleep_range(10000, 20000); 433 } 434 435 return !hw_lock; 436 } 437 438 /** 439 * ice_ptp_unlock - Release PTP global semaphore register lock 440 * @hw: pointer to the HW struct 441 * 442 * Release the global PTP hardware semaphore lock. This is done by writing to 443 * the PFTSYN_SEM register. 444 */ 445 void ice_ptp_unlock(struct ice_hw *hw) 446 { 447 wr32(hw, PFTSYN_SEM + (PFTSYN_SEM_BYTES * hw->pf_id), 0); 448 } 449 450 /** 451 * ice_ptp_src_cmd - Prepare source timer for a timer command 452 * @hw: pointer to HW structure 453 * @cmd: Timer command 454 * 455 * Prepare the source timer for an upcoming timer sync command. 456 */ 457 static void ice_ptp_src_cmd(struct ice_hw *hw, enum ice_ptp_tmr_cmd cmd) 458 { 459 u32 cmd_val; 460 u8 tmr_idx; 461 462 tmr_idx = ice_get_ptp_src_clock_index(hw); 463 cmd_val = tmr_idx << SEL_CPK_SRC; 464 465 switch (cmd) { 466 case INIT_TIME: 467 cmd_val |= GLTSYN_CMD_INIT_TIME; 468 break; 469 case INIT_INCVAL: 470 cmd_val |= GLTSYN_CMD_INIT_INCVAL; 471 break; 472 case ADJ_TIME: 473 cmd_val |= GLTSYN_CMD_ADJ_TIME; 474 break; 475 case ADJ_TIME_AT_TIME: 476 cmd_val |= GLTSYN_CMD_ADJ_INIT_TIME; 477 break; 478 case READ_TIME: 479 cmd_val |= GLTSYN_CMD_READ_TIME; 480 break; 481 } 482 483 wr32(hw, GLTSYN_CMD, cmd_val); 484 } 485 486 /** 487 * ice_ptp_tmr_cmd - Prepare and trigger a timer sync command 488 * @hw: pointer to HW struct 489 * @cmd: the command to issue 490 * 491 * Prepare the source timer and PHY timers and then trigger the requested 492 * command. This causes the shadow registers previously written in preparation 493 * for the command to be synchronously applied to both the source and PHY 494 * timers. 495 */ 496 static int ice_ptp_tmr_cmd(struct ice_hw *hw, enum ice_ptp_tmr_cmd cmd) 497 { 498 int err; 499 500 /* First, prepare the source timer */ 501 ice_ptp_src_cmd(hw, cmd); 502 503 /* Next, prepare the ports */ 504 err = ice_ptp_port_cmd_e810(hw, cmd); 505 if (err) { 506 ice_debug(hw, ICE_DBG_PTP, "Failed to prepare PHY ports for timer command %u, err %d\n", 507 cmd, err); 508 return err; 509 } 510 511 /* Write the sync command register to drive both source and PHY timer commands 512 * synchronously 513 */ 514 wr32(hw, GLTSYN_CMD_SYNC, SYNC_EXEC_CMD); 515 516 return 0; 517 } 518 519 /** 520 * ice_ptp_init_time - Initialize device time to provided value 521 * @hw: pointer to HW struct 522 * @time: 64bits of time (GLTSYN_TIME_L and GLTSYN_TIME_H) 523 * 524 * Initialize the device to the specified time provided. This requires a three 525 * step process: 526 * 527 * 1) write the new init time to the source timer shadow registers 528 * 2) write the new init time to the PHY timer shadow registers 529 * 3) issue an init_time timer command to synchronously switch both the source 530 * and port timers to the new init time value at the next clock cycle. 531 */ 532 int ice_ptp_init_time(struct ice_hw *hw, u64 time) 533 { 534 u8 tmr_idx; 535 int err; 536 537 tmr_idx = hw->func_caps.ts_func_info.tmr_index_owned; 538 539 /* Source timers */ 540 wr32(hw, GLTSYN_SHTIME_L(tmr_idx), lower_32_bits(time)); 541 wr32(hw, GLTSYN_SHTIME_H(tmr_idx), upper_32_bits(time)); 542 wr32(hw, GLTSYN_SHTIME_0(tmr_idx), 0); 543 544 /* PHY timers */ 545 /* Fill Rx and Tx ports and send msg to PHY */ 546 err = ice_ptp_prep_phy_time_e810(hw, time & 0xFFFFFFFF); 547 if (err) 548 return err; 549 550 return ice_ptp_tmr_cmd(hw, INIT_TIME); 551 } 552 553 /** 554 * ice_ptp_write_incval - Program PHC with new increment value 555 * @hw: pointer to HW struct 556 * @incval: Source timer increment value per clock cycle 557 * 558 * Program the PHC with a new increment value. This requires a three-step 559 * process: 560 * 561 * 1) Write the increment value to the source timer shadow registers 562 * 2) Write the increment value to the PHY timer shadow registers 563 * 3) Issue an INIT_INCVAL timer command to synchronously switch both the 564 * source and port timers to the new increment value at the next clock 565 * cycle. 566 */ 567 int ice_ptp_write_incval(struct ice_hw *hw, u64 incval) 568 { 569 u8 tmr_idx; 570 int err; 571 572 tmr_idx = hw->func_caps.ts_func_info.tmr_index_owned; 573 574 /* Shadow Adjust */ 575 wr32(hw, GLTSYN_SHADJ_L(tmr_idx), lower_32_bits(incval)); 576 wr32(hw, GLTSYN_SHADJ_H(tmr_idx), upper_32_bits(incval)); 577 578 err = ice_ptp_prep_phy_incval_e810(hw, incval); 579 if (err) 580 return err; 581 582 return ice_ptp_tmr_cmd(hw, INIT_INCVAL); 583 } 584 585 /** 586 * ice_ptp_write_incval_locked - Program new incval while holding semaphore 587 * @hw: pointer to HW struct 588 * @incval: Source timer increment value per clock cycle 589 * 590 * Program a new PHC incval while holding the PTP semaphore. 591 */ 592 int ice_ptp_write_incval_locked(struct ice_hw *hw, u64 incval) 593 { 594 int err; 595 596 if (!ice_ptp_lock(hw)) 597 return -EBUSY; 598 599 err = ice_ptp_write_incval(hw, incval); 600 601 ice_ptp_unlock(hw); 602 603 return err; 604 } 605 606 /** 607 * ice_ptp_adj_clock - Adjust PHC clock time atomically 608 * @hw: pointer to HW struct 609 * @adj: Adjustment in nanoseconds 610 * 611 * Perform an atomic adjustment of the PHC time by the specified number of 612 * nanoseconds. This requires a three-step process: 613 * 614 * 1) Write the adjustment to the source timer shadow registers 615 * 2) Write the adjustment to the PHY timer shadow registers 616 * 3) Issue an ADJ_TIME timer command to synchronously apply the adjustment to 617 * both the source and port timers at the next clock cycle. 618 */ 619 int ice_ptp_adj_clock(struct ice_hw *hw, s32 adj) 620 { 621 u8 tmr_idx; 622 int err; 623 624 tmr_idx = hw->func_caps.ts_func_info.tmr_index_owned; 625 626 /* Write the desired clock adjustment into the GLTSYN_SHADJ register. 627 * For an ADJ_TIME command, this set of registers represents the value 628 * to add to the clock time. It supports subtraction by interpreting 629 * the value as a 2's complement integer. 630 */ 631 wr32(hw, GLTSYN_SHADJ_L(tmr_idx), 0); 632 wr32(hw, GLTSYN_SHADJ_H(tmr_idx), adj); 633 634 err = ice_ptp_prep_phy_adj_e810(hw, adj); 635 if (err) 636 return err; 637 638 return ice_ptp_tmr_cmd(hw, ADJ_TIME); 639 } 640 641 /** 642 * ice_read_phy_tstamp - Read a PHY timestamp from the timestamo block 643 * @hw: pointer to the HW struct 644 * @block: the block to read from 645 * @idx: the timestamp index to read 646 * @tstamp: on return, the 40bit timestamp value 647 * 648 * Read a 40bit timestamp value out of the timestamp block. 649 */ 650 int ice_read_phy_tstamp(struct ice_hw *hw, u8 block, u8 idx, u64 *tstamp) 651 { 652 return ice_read_phy_tstamp_e810(hw, block, idx, tstamp); 653 } 654 655 /** 656 * ice_clear_phy_tstamp - Clear a timestamp from the timestamp block 657 * @hw: pointer to the HW struct 658 * @block: the block to read from 659 * @idx: the timestamp index to reset 660 * 661 * Clear a timestamp, resetting its valid bit, from the timestamp block. 662 */ 663 int ice_clear_phy_tstamp(struct ice_hw *hw, u8 block, u8 idx) 664 { 665 return ice_clear_phy_tstamp_e810(hw, block, idx); 666 } 667 668 /* E810T SMA functions 669 * 670 * The following functions operate specifically on E810T hardware and are used 671 * to access the extended GPIOs available. 672 */ 673 674 /** 675 * ice_get_pca9575_handle 676 * @hw: pointer to the hw struct 677 * @pca9575_handle: GPIO controller's handle 678 * 679 * Find and return the GPIO controller's handle in the netlist. 680 * When found - the value will be cached in the hw structure and following calls 681 * will return cached value 682 */ 683 static int 684 ice_get_pca9575_handle(struct ice_hw *hw, u16 *pca9575_handle) 685 { 686 struct ice_aqc_get_link_topo *cmd; 687 struct ice_aq_desc desc; 688 int status; 689 u8 idx; 690 691 /* If handle was read previously return cached value */ 692 if (hw->io_expander_handle) { 693 *pca9575_handle = hw->io_expander_handle; 694 return 0; 695 } 696 697 /* If handle was not detected read it from the netlist */ 698 cmd = &desc.params.get_link_topo; 699 ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_get_link_topo); 700 701 /* Set node type to GPIO controller */ 702 cmd->addr.topo_params.node_type_ctx = 703 (ICE_AQC_LINK_TOPO_NODE_TYPE_M & 704 ICE_AQC_LINK_TOPO_NODE_TYPE_GPIO_CTRL); 705 706 #define SW_PCA9575_SFP_TOPO_IDX 2 707 #define SW_PCA9575_QSFP_TOPO_IDX 1 708 709 /* Check if the SW IO expander controlling SMA exists in the netlist. */ 710 if (hw->device_id == ICE_DEV_ID_E810C_SFP) 711 idx = SW_PCA9575_SFP_TOPO_IDX; 712 else if (hw->device_id == ICE_DEV_ID_E810C_QSFP) 713 idx = SW_PCA9575_QSFP_TOPO_IDX; 714 else 715 return -EOPNOTSUPP; 716 717 cmd->addr.topo_params.index = idx; 718 719 status = ice_aq_send_cmd(hw, &desc, NULL, 0, NULL); 720 if (status) 721 return -EOPNOTSUPP; 722 723 /* Verify if we found the right IO expander type */ 724 if (desc.params.get_link_topo.node_part_num != 725 ICE_AQC_GET_LINK_TOPO_NODE_NR_PCA9575) 726 return -EOPNOTSUPP; 727 728 /* If present save the handle and return it */ 729 hw->io_expander_handle = 730 le16_to_cpu(desc.params.get_link_topo.addr.handle); 731 *pca9575_handle = hw->io_expander_handle; 732 733 return 0; 734 } 735 736 /** 737 * ice_read_sma_ctrl_e810t 738 * @hw: pointer to the hw struct 739 * @data: pointer to data to be read from the GPIO controller 740 * 741 * Read the SMA controller state. It is connected to pins 3-7 of Port 1 of the 742 * PCA9575 expander, so only bits 3-7 in data are valid. 743 */ 744 int ice_read_sma_ctrl_e810t(struct ice_hw *hw, u8 *data) 745 { 746 int status; 747 u16 handle; 748 u8 i; 749 750 status = ice_get_pca9575_handle(hw, &handle); 751 if (status) 752 return status; 753 754 *data = 0; 755 756 for (i = ICE_SMA_MIN_BIT_E810T; i <= ICE_SMA_MAX_BIT_E810T; i++) { 757 bool pin; 758 759 status = ice_aq_get_gpio(hw, handle, i + ICE_PCA9575_P1_OFFSET, 760 &pin, NULL); 761 if (status) 762 break; 763 *data |= (u8)(!pin) << i; 764 } 765 766 return status; 767 } 768 769 /** 770 * ice_write_sma_ctrl_e810t 771 * @hw: pointer to the hw struct 772 * @data: data to be written to the GPIO controller 773 * 774 * Write the data to the SMA controller. It is connected to pins 3-7 of Port 1 775 * of the PCA9575 expander, so only bits 3-7 in data are valid. 776 */ 777 int ice_write_sma_ctrl_e810t(struct ice_hw *hw, u8 data) 778 { 779 int status; 780 u16 handle; 781 u8 i; 782 783 status = ice_get_pca9575_handle(hw, &handle); 784 if (status) 785 return status; 786 787 for (i = ICE_SMA_MIN_BIT_E810T; i <= ICE_SMA_MAX_BIT_E810T; i++) { 788 bool pin; 789 790 pin = !(data & (1 << i)); 791 status = ice_aq_set_gpio(hw, handle, i + ICE_PCA9575_P1_OFFSET, 792 pin, NULL); 793 if (status) 794 break; 795 } 796 797 return status; 798 } 799 800 /** 801 * ice_is_pca9575_present 802 * @hw: pointer to the hw struct 803 * 804 * Check if the SW IO expander is present in the netlist 805 */ 806 bool ice_is_pca9575_present(struct ice_hw *hw) 807 { 808 u16 handle = 0; 809 int status; 810 811 if (!ice_is_e810t(hw)) 812 return false; 813 814 status = ice_get_pca9575_handle(hw, &handle); 815 816 return !status && handle; 817 } 818 819 /** 820 * ice_ptp_init_phc - Initialize PTP hardware clock 821 * @hw: pointer to the HW struct 822 * 823 * Perform the steps required to initialize the PTP hardware clock. 824 */ 825 int ice_ptp_init_phc(struct ice_hw *hw) 826 { 827 u8 src_idx = hw->func_caps.ts_func_info.tmr_index_owned; 828 829 /* Enable source clocks */ 830 wr32(hw, GLTSYN_ENA(src_idx), GLTSYN_ENA_TSYN_ENA_M); 831 832 /* Clear event err indications for auxiliary pins */ 833 (void)rd32(hw, GLTSYN_STAT(src_idx)); 834 835 return ice_ptp_init_phc_e810(hw); 836 } 837