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 status; 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 status = ice_sbq_rw_reg(hw, &msg); 79 if (status) { 80 ice_debug(hw, ICE_DBG_PTP, "Failed to send message to PHY, status %d\n", 81 status); 82 return status; 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 status; 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 status = ice_sbq_rw_reg(hw, &msg); 110 if (status) { 111 ice_debug(hw, ICE_DBG_PTP, "Failed to send message to PHY, status %d\n", 112 status); 113 return status; 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 status; 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 status = ice_read_phy_reg_e810(hw, lo_addr, &lo); 139 if (status) { 140 ice_debug(hw, ICE_DBG_PTP, "Failed to read low PTP timestamp register, status %d\n", 141 status); 142 return status; 143 } 144 145 status = ice_read_phy_reg_e810(hw, hi_addr, &hi); 146 if (status) { 147 ice_debug(hw, ICE_DBG_PTP, "Failed to read high PTP timestamp register, status %d\n", 148 status); 149 return status; 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 status; 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 status = ice_write_phy_reg_e810(hw, lo_addr, 0); 178 if (status) { 179 ice_debug(hw, ICE_DBG_PTP, "Failed to clear low PTP timestamp register, status %d\n", 180 status); 181 return status; 182 } 183 184 status = ice_write_phy_reg_e810(hw, hi_addr, 0); 185 if (status) { 186 ice_debug(hw, ICE_DBG_PTP, "Failed to clear high PTP timestamp register, status %d\n", 187 status); 188 return status; 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 int status; 204 u8 tmr_idx; 205 206 tmr_idx = hw->func_caps.ts_func_info.tmr_index_owned; 207 status = ice_write_phy_reg_e810(hw, ETH_GLTSYN_ENA(tmr_idx), 208 GLTSYN_ENA_TSYN_ENA_M); 209 if (status) 210 ice_debug(hw, ICE_DBG_PTP, "PTP failed in ena_phy_time_syn %d\n", 211 status); 212 213 return status; 214 } 215 216 /** 217 * ice_ptp_prep_phy_time_e810 - Prepare PHY port with initial time 218 * @hw: Board private structure 219 * @time: Time to initialize the PHY port clock to 220 * 221 * Program the PHY port ETH_GLTSYN_SHTIME registers in preparation setting the 222 * initial clock time. The time will not actually be programmed until the 223 * driver issues an INIT_TIME command. 224 * 225 * The time value is the upper 32 bits of the PHY timer, usually in units of 226 * nominal nanoseconds. 227 */ 228 static int ice_ptp_prep_phy_time_e810(struct ice_hw *hw, u32 time) 229 { 230 int status; 231 u8 tmr_idx; 232 233 tmr_idx = hw->func_caps.ts_func_info.tmr_index_owned; 234 status = ice_write_phy_reg_e810(hw, ETH_GLTSYN_SHTIME_0(tmr_idx), 0); 235 if (status) { 236 ice_debug(hw, ICE_DBG_PTP, "Failed to write SHTIME_0, status %d\n", 237 status); 238 return status; 239 } 240 241 status = ice_write_phy_reg_e810(hw, ETH_GLTSYN_SHTIME_L(tmr_idx), time); 242 if (status) { 243 ice_debug(hw, ICE_DBG_PTP, "Failed to write SHTIME_L, status %d\n", 244 status); 245 return status; 246 } 247 248 return 0; 249 } 250 251 /** 252 * ice_ptp_prep_phy_adj_e810 - Prep PHY port for a time adjustment 253 * @hw: pointer to HW struct 254 * @adj: adjustment value to program 255 * 256 * Prepare the PHY port for an atomic adjustment by programming the PHY 257 * ETH_GLTSYN_SHADJ_L and ETH_GLTSYN_SHADJ_H registers. The actual adjustment 258 * is completed by issuing an ADJ_TIME sync command. 259 * 260 * The adjustment value only contains the portion used for the upper 32bits of 261 * the PHY timer, usually in units of nominal nanoseconds. Negative 262 * adjustments are supported using 2s complement arithmetic. 263 */ 264 static int ice_ptp_prep_phy_adj_e810(struct ice_hw *hw, s32 adj) 265 { 266 int status; 267 u8 tmr_idx; 268 269 tmr_idx = hw->func_caps.ts_func_info.tmr_index_owned; 270 271 /* Adjustments are represented as signed 2's complement values in 272 * nanoseconds. Sub-nanosecond adjustment is not supported. 273 */ 274 status = ice_write_phy_reg_e810(hw, ETH_GLTSYN_SHADJ_L(tmr_idx), 0); 275 if (status) { 276 ice_debug(hw, ICE_DBG_PTP, "Failed to write adj to PHY SHADJ_L, status %d\n", 277 status); 278 return status; 279 } 280 281 status = ice_write_phy_reg_e810(hw, ETH_GLTSYN_SHADJ_H(tmr_idx), adj); 282 if (status) { 283 ice_debug(hw, ICE_DBG_PTP, "Failed to write adj to PHY SHADJ_H, status %d\n", 284 status); 285 return status; 286 } 287 288 return 0; 289 } 290 291 /** 292 * ice_ptp_prep_phy_incval_e810 - Prep PHY port increment value change 293 * @hw: pointer to HW struct 294 * @incval: The new 40bit increment value to prepare 295 * 296 * Prepare the PHY port for a new increment value by programming the PHY 297 * ETH_GLTSYN_SHADJ_L and ETH_GLTSYN_SHADJ_H registers. The actual change is 298 * completed by issuing an INIT_INCVAL command. 299 */ 300 static int ice_ptp_prep_phy_incval_e810(struct ice_hw *hw, u64 incval) 301 { 302 u32 high, low; 303 int status; 304 u8 tmr_idx; 305 306 tmr_idx = hw->func_caps.ts_func_info.tmr_index_owned; 307 low = lower_32_bits(incval); 308 high = upper_32_bits(incval); 309 310 status = ice_write_phy_reg_e810(hw, ETH_GLTSYN_SHADJ_L(tmr_idx), low); 311 if (status) { 312 ice_debug(hw, ICE_DBG_PTP, "Failed to write incval to PHY SHADJ_L, status %d\n", 313 status); 314 return status; 315 } 316 317 status = ice_write_phy_reg_e810(hw, ETH_GLTSYN_SHADJ_H(tmr_idx), high); 318 if (status) { 319 ice_debug(hw, ICE_DBG_PTP, "Failed to write incval PHY SHADJ_H, status %d\n", 320 status); 321 return status; 322 } 323 324 return 0; 325 } 326 327 /** 328 * ice_ptp_port_cmd_e810 - Prepare all external PHYs for a timer command 329 * @hw: pointer to HW struct 330 * @cmd: Command to be sent to the port 331 * 332 * Prepare the external PHYs connected to this device for a timer sync 333 * command. 334 */ 335 static int ice_ptp_port_cmd_e810(struct ice_hw *hw, enum ice_ptp_tmr_cmd cmd) 336 { 337 u32 cmd_val, val; 338 int status; 339 340 switch (cmd) { 341 case INIT_TIME: 342 cmd_val = GLTSYN_CMD_INIT_TIME; 343 break; 344 case INIT_INCVAL: 345 cmd_val = GLTSYN_CMD_INIT_INCVAL; 346 break; 347 case ADJ_TIME: 348 cmd_val = GLTSYN_CMD_ADJ_TIME; 349 break; 350 case READ_TIME: 351 cmd_val = GLTSYN_CMD_READ_TIME; 352 break; 353 case ADJ_TIME_AT_TIME: 354 cmd_val = GLTSYN_CMD_ADJ_INIT_TIME; 355 break; 356 } 357 358 /* Read, modify, write */ 359 status = ice_read_phy_reg_e810(hw, ETH_GLTSYN_CMD, &val); 360 if (status) { 361 ice_debug(hw, ICE_DBG_PTP, "Failed to read GLTSYN_CMD, status %d\n", status); 362 return status; 363 } 364 365 /* Modify necessary bits only and perform write */ 366 val &= ~TS_CMD_MASK_E810; 367 val |= cmd_val; 368 369 status = ice_write_phy_reg_e810(hw, ETH_GLTSYN_CMD, val); 370 if (status) { 371 ice_debug(hw, ICE_DBG_PTP, "Failed to write back GLTSYN_CMD, status %d\n", status); 372 return status; 373 } 374 375 return 0; 376 } 377 378 /* Device agnostic functions 379 * 380 * The following functions implement useful behavior to hide the differences 381 * between E810 and other devices. They call the device-specific 382 * implementations where necessary. 383 * 384 * Currently, the driver only supports E810, but future work will enable 385 * support for E822-based devices. 386 */ 387 388 /** 389 * ice_ptp_lock - Acquire PTP global semaphore register lock 390 * @hw: pointer to the HW struct 391 * 392 * Acquire the global PTP hardware semaphore lock. Returns true if the lock 393 * was acquired, false otherwise. 394 * 395 * The PFTSYN_SEM register sets the busy bit on read, returning the previous 396 * value. If software sees the busy bit cleared, this means that this function 397 * acquired the lock (and the busy bit is now set). If software sees the busy 398 * bit set, it means that another function acquired the lock. 399 * 400 * Software must clear the busy bit with a write to release the lock for other 401 * functions when done. 402 */ 403 bool ice_ptp_lock(struct ice_hw *hw) 404 { 405 u32 hw_lock; 406 int i; 407 408 #define MAX_TRIES 5 409 410 for (i = 0; i < MAX_TRIES; i++) { 411 hw_lock = rd32(hw, PFTSYN_SEM + (PFTSYN_SEM_BYTES * hw->pf_id)); 412 hw_lock = hw_lock & PFTSYN_SEM_BUSY_M; 413 if (!hw_lock) 414 break; 415 416 /* Somebody is holding the lock */ 417 usleep_range(10000, 20000); 418 } 419 420 return !hw_lock; 421 } 422 423 /** 424 * ice_ptp_unlock - Release PTP global semaphore register lock 425 * @hw: pointer to the HW struct 426 * 427 * Release the global PTP hardware semaphore lock. This is done by writing to 428 * the PFTSYN_SEM register. 429 */ 430 void ice_ptp_unlock(struct ice_hw *hw) 431 { 432 wr32(hw, PFTSYN_SEM + (PFTSYN_SEM_BYTES * hw->pf_id), 0); 433 } 434 435 /** 436 * ice_ptp_src_cmd - Prepare source timer for a timer command 437 * @hw: pointer to HW structure 438 * @cmd: Timer command 439 * 440 * Prepare the source timer for an upcoming timer sync command. 441 */ 442 static void ice_ptp_src_cmd(struct ice_hw *hw, enum ice_ptp_tmr_cmd cmd) 443 { 444 u32 cmd_val; 445 u8 tmr_idx; 446 447 tmr_idx = ice_get_ptp_src_clock_index(hw); 448 cmd_val = tmr_idx << SEL_CPK_SRC; 449 450 switch (cmd) { 451 case INIT_TIME: 452 cmd_val |= GLTSYN_CMD_INIT_TIME; 453 break; 454 case INIT_INCVAL: 455 cmd_val |= GLTSYN_CMD_INIT_INCVAL; 456 break; 457 case ADJ_TIME: 458 cmd_val |= GLTSYN_CMD_ADJ_TIME; 459 break; 460 case ADJ_TIME_AT_TIME: 461 cmd_val |= GLTSYN_CMD_ADJ_INIT_TIME; 462 break; 463 case READ_TIME: 464 cmd_val |= GLTSYN_CMD_READ_TIME; 465 break; 466 } 467 468 wr32(hw, GLTSYN_CMD, cmd_val); 469 } 470 471 /** 472 * ice_ptp_tmr_cmd - Prepare and trigger a timer sync command 473 * @hw: pointer to HW struct 474 * @cmd: the command to issue 475 * 476 * Prepare the source timer and PHY timers and then trigger the requested 477 * command. This causes the shadow registers previously written in preparation 478 * for the command to be synchronously applied to both the source and PHY 479 * timers. 480 */ 481 static int ice_ptp_tmr_cmd(struct ice_hw *hw, enum ice_ptp_tmr_cmd cmd) 482 { 483 int status; 484 485 /* First, prepare the source timer */ 486 ice_ptp_src_cmd(hw, cmd); 487 488 /* Next, prepare the ports */ 489 status = ice_ptp_port_cmd_e810(hw, cmd); 490 if (status) { 491 ice_debug(hw, ICE_DBG_PTP, "Failed to prepare PHY ports for timer command %u, status %d\n", 492 cmd, status); 493 return status; 494 } 495 496 /* Write the sync command register to drive both source and PHY timer commands 497 * synchronously 498 */ 499 wr32(hw, GLTSYN_CMD_SYNC, SYNC_EXEC_CMD); 500 501 return 0; 502 } 503 504 /** 505 * ice_ptp_init_time - Initialize device time to provided value 506 * @hw: pointer to HW struct 507 * @time: 64bits of time (GLTSYN_TIME_L and GLTSYN_TIME_H) 508 * 509 * Initialize the device to the specified time provided. This requires a three 510 * step process: 511 * 512 * 1) write the new init time to the source timer shadow registers 513 * 2) write the new init time to the PHY timer shadow registers 514 * 3) issue an init_time timer command to synchronously switch both the source 515 * and port timers to the new init time value at the next clock cycle. 516 */ 517 int ice_ptp_init_time(struct ice_hw *hw, u64 time) 518 { 519 int status; 520 u8 tmr_idx; 521 522 tmr_idx = hw->func_caps.ts_func_info.tmr_index_owned; 523 524 /* Source timers */ 525 wr32(hw, GLTSYN_SHTIME_L(tmr_idx), lower_32_bits(time)); 526 wr32(hw, GLTSYN_SHTIME_H(tmr_idx), upper_32_bits(time)); 527 wr32(hw, GLTSYN_SHTIME_0(tmr_idx), 0); 528 529 /* PHY timers */ 530 /* Fill Rx and Tx ports and send msg to PHY */ 531 status = ice_ptp_prep_phy_time_e810(hw, time & 0xFFFFFFFF); 532 if (status) 533 return status; 534 535 return ice_ptp_tmr_cmd(hw, INIT_TIME); 536 } 537 538 /** 539 * ice_ptp_write_incval - Program PHC with new increment value 540 * @hw: pointer to HW struct 541 * @incval: Source timer increment value per clock cycle 542 * 543 * Program the PHC with a new increment value. This requires a three-step 544 * process: 545 * 546 * 1) Write the increment value to the source timer shadow registers 547 * 2) Write the increment value to the PHY timer shadow registers 548 * 3) Issue an INIT_INCVAL timer command to synchronously switch both the 549 * source and port timers to the new increment value at the next clock 550 * cycle. 551 */ 552 int ice_ptp_write_incval(struct ice_hw *hw, u64 incval) 553 { 554 int status; 555 u8 tmr_idx; 556 557 tmr_idx = hw->func_caps.ts_func_info.tmr_index_owned; 558 559 /* Shadow Adjust */ 560 wr32(hw, GLTSYN_SHADJ_L(tmr_idx), lower_32_bits(incval)); 561 wr32(hw, GLTSYN_SHADJ_H(tmr_idx), upper_32_bits(incval)); 562 563 status = ice_ptp_prep_phy_incval_e810(hw, incval); 564 if (status) 565 return status; 566 567 return ice_ptp_tmr_cmd(hw, INIT_INCVAL); 568 } 569 570 /** 571 * ice_ptp_write_incval_locked - Program new incval while holding semaphore 572 * @hw: pointer to HW struct 573 * @incval: Source timer increment value per clock cycle 574 * 575 * Program a new PHC incval while holding the PTP semaphore. 576 */ 577 int ice_ptp_write_incval_locked(struct ice_hw *hw, u64 incval) 578 { 579 int status; 580 581 if (!ice_ptp_lock(hw)) 582 return -EBUSY; 583 584 status = ice_ptp_write_incval(hw, incval); 585 586 ice_ptp_unlock(hw); 587 588 return status; 589 } 590 591 /** 592 * ice_ptp_adj_clock - Adjust PHC clock time atomically 593 * @hw: pointer to HW struct 594 * @adj: Adjustment in nanoseconds 595 * 596 * Perform an atomic adjustment of the PHC time by the specified number of 597 * nanoseconds. This requires a three-step process: 598 * 599 * 1) Write the adjustment to the source timer shadow registers 600 * 2) Write the adjustment to the PHY timer shadow registers 601 * 3) Issue an ADJ_TIME timer command to synchronously apply the adjustment to 602 * both the source and port timers at the next clock cycle. 603 */ 604 int ice_ptp_adj_clock(struct ice_hw *hw, s32 adj) 605 { 606 int status; 607 u8 tmr_idx; 608 609 tmr_idx = hw->func_caps.ts_func_info.tmr_index_owned; 610 611 /* Write the desired clock adjustment into the GLTSYN_SHADJ register. 612 * For an ADJ_TIME command, this set of registers represents the value 613 * to add to the clock time. It supports subtraction by interpreting 614 * the value as a 2's complement integer. 615 */ 616 wr32(hw, GLTSYN_SHADJ_L(tmr_idx), 0); 617 wr32(hw, GLTSYN_SHADJ_H(tmr_idx), adj); 618 619 status = ice_ptp_prep_phy_adj_e810(hw, adj); 620 if (status) 621 return status; 622 623 return ice_ptp_tmr_cmd(hw, ADJ_TIME); 624 } 625 626 /** 627 * ice_read_phy_tstamp - Read a PHY timestamp from the timestamo block 628 * @hw: pointer to the HW struct 629 * @block: the block to read from 630 * @idx: the timestamp index to read 631 * @tstamp: on return, the 40bit timestamp value 632 * 633 * Read a 40bit timestamp value out of the timestamp block. 634 */ 635 int ice_read_phy_tstamp(struct ice_hw *hw, u8 block, u8 idx, u64 *tstamp) 636 { 637 return ice_read_phy_tstamp_e810(hw, block, idx, tstamp); 638 } 639 640 /** 641 * ice_clear_phy_tstamp - Clear a timestamp from the timestamp block 642 * @hw: pointer to the HW struct 643 * @block: the block to read from 644 * @idx: the timestamp index to reset 645 * 646 * Clear a timestamp, resetting its valid bit, from the timestamp block. 647 */ 648 int ice_clear_phy_tstamp(struct ice_hw *hw, u8 block, u8 idx) 649 { 650 return ice_clear_phy_tstamp_e810(hw, block, idx); 651 } 652