Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

ice: redesign dpll sma/u.fl pins control

DPLL-enabled E810 NIC driver provides user with list of input and output
pins. Hardware internal design impacts user control over SMA and U.FL
pins. Currently end-user view on those dpll pins doesn't provide any layer
of abstraction. On the hardware level SMA and U.FL pins are tied together
due to existence of direction control logic for each pair:
- SMA1 (bi-directional) and U.FL1 (only output)
- SMA2 (bi-directional) and U.FL2 (only input)
The user activity on each pin of the pair may impact the state of the
other.

Previously all the pins were provided to the user as is, without the
control over SMA pins direction.

Introduce a software controlled layer of abstraction over external board
pins, instead of providing the user with access to raw pins connected to
the dpll:
- new software controlled SMA and U.FL pins,
- callback operations directing user requests to corresponding hardware
pins according to the runtime configuration,
- ability to control SMA pins direction.

Reviewed-by: Przemek Kitszel <przemyslaw.kitszel@intel.com>
Signed-off-by: Arkadiusz Kubalewski <arkadiusz.kubalewski@intel.com>
Tested-by: Rinitha S <sx.rinitha@intel.com> (A Contingent worker at Intel)
Reviewed-by: Simon Horman <horms@kernel.org>
Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>

authored by

Arkadiusz Kubalewski and committed by
Tony Nguyen
2dd5d03c 9acae9e2

+936 -15
+913 -14
drivers/net/ethernet/intel/ice/ice_dpll.c
··· 11 11 #define ICE_DPLL_RCLK_NUM_PER_PF 1 12 12 #define ICE_DPLL_PIN_ESYNC_PULSE_HIGH_PERCENT 25 13 13 #define ICE_DPLL_PIN_GEN_RCLK_FREQ 1953125 14 + #define ICE_DPLL_PIN_PRIO_OUTPUT 0xff 15 + #define ICE_DPLL_SW_PIN_INPUT_BASE_SFP 4 16 + #define ICE_DPLL_SW_PIN_INPUT_BASE_QSFP 6 17 + #define ICE_DPLL_SW_PIN_OUTPUT_BASE 0 18 + 19 + #define ICE_DPLL_PIN_SW_INPUT_ABS(in_idx) \ 20 + (ICE_DPLL_SW_PIN_INPUT_BASE_SFP + (in_idx)) 21 + 22 + #define ICE_DPLL_PIN_SW_1_INPUT_ABS_IDX \ 23 + (ICE_DPLL_PIN_SW_INPUT_ABS(ICE_DPLL_PIN_SW_1_IDX)) 24 + 25 + #define ICE_DPLL_PIN_SW_2_INPUT_ABS_IDX \ 26 + (ICE_DPLL_PIN_SW_INPUT_ABS(ICE_DPLL_PIN_SW_2_IDX)) 27 + 28 + #define ICE_DPLL_PIN_SW_OUTPUT_ABS(out_idx) \ 29 + (ICE_DPLL_SW_PIN_OUTPUT_BASE + (out_idx)) 30 + 31 + #define ICE_DPLL_PIN_SW_1_OUTPUT_ABS_IDX \ 32 + (ICE_DPLL_PIN_SW_OUTPUT_ABS(ICE_DPLL_PIN_SW_1_IDX)) 33 + 34 + #define ICE_DPLL_PIN_SW_2_OUTPUT_ABS_IDX \ 35 + (ICE_DPLL_PIN_SW_OUTPUT_ABS(ICE_DPLL_PIN_SW_2_IDX)) 14 36 15 37 /** 16 38 * enum ice_dpll_pin_type - enumerate ice pin types: ··· 40 18 * @ICE_DPLL_PIN_TYPE_INPUT: input pin 41 19 * @ICE_DPLL_PIN_TYPE_OUTPUT: output pin 42 20 * @ICE_DPLL_PIN_TYPE_RCLK_INPUT: recovery clock input pin 21 + * @ICE_DPLL_PIN_TYPE_SOFTWARE: software controlled SMA/U.FL pins 43 22 */ 44 23 enum ice_dpll_pin_type { 45 24 ICE_DPLL_PIN_INVALID, 46 25 ICE_DPLL_PIN_TYPE_INPUT, 47 26 ICE_DPLL_PIN_TYPE_OUTPUT, 48 27 ICE_DPLL_PIN_TYPE_RCLK_INPUT, 28 + ICE_DPLL_PIN_TYPE_SOFTWARE, 49 29 }; 50 30 51 31 static const char * const pin_type_name[] = { 52 32 [ICE_DPLL_PIN_TYPE_INPUT] = "input", 53 33 [ICE_DPLL_PIN_TYPE_OUTPUT] = "output", 54 34 [ICE_DPLL_PIN_TYPE_RCLK_INPUT] = "rclk-input", 35 + [ICE_DPLL_PIN_TYPE_SOFTWARE] = "software", 55 36 }; 37 + 38 + static const char * const ice_dpll_sw_pin_sma[] = { "SMA1", "SMA2" }; 39 + static const char * const ice_dpll_sw_pin_ufl[] = { "U.FL1", "U.FL2" }; 56 40 57 41 static const struct dpll_pin_frequency ice_esync_range[] = { 58 42 DPLL_PIN_FREQUENCY_RANGE(0, DPLL_PIN_FREQUENCY_1_HZ), 59 43 }; 44 + 45 + /** 46 + * ice_dpll_is_sw_pin - check if given pin shall be controlled by SW 47 + * @pf: private board structure 48 + * @index: index of a pin as understood by FW 49 + * @input: true for input, false for output 50 + * 51 + * Check if the pin shall be controlled by SW - instead of providing raw access 52 + * for pin control. For E810 NIC with dpll there is additional MUX-related logic 53 + * between SMA/U.FL pins/connectors and dpll device, best to give user access 54 + * with series of wrapper functions as from user perspective they convey single 55 + * functionality rather then separated pins. 56 + * 57 + * Return: 58 + * * true - pin controlled by SW 59 + * * false - pin not controlled by SW 60 + */ 61 + static bool ice_dpll_is_sw_pin(struct ice_pf *pf, u8 index, bool input) 62 + { 63 + if (input && pf->hw.device_id == ICE_DEV_ID_E810C_QSFP) 64 + index -= ICE_DPLL_SW_PIN_INPUT_BASE_QSFP - 65 + ICE_DPLL_SW_PIN_INPUT_BASE_SFP; 66 + 67 + if ((input && (index == ICE_DPLL_PIN_SW_1_INPUT_ABS_IDX || 68 + index == ICE_DPLL_PIN_SW_2_INPUT_ABS_IDX)) || 69 + (!input && (index == ICE_DPLL_PIN_SW_1_OUTPUT_ABS_IDX || 70 + index == ICE_DPLL_PIN_SW_2_OUTPUT_ABS_IDX))) 71 + return true; 72 + return false; 73 + } 60 74 61 75 /** 62 76 * ice_dpll_is_reset - check if reset is in progress ··· 338 280 } 339 281 340 282 /** 283 + * ice_dpll_sw_pin_frequency_set - callback to set frequency of SW pin 284 + * @pin: pointer to a pin 285 + * @pin_priv: private data pointer passed on pin registration 286 + * @dpll: pointer to dpll 287 + * @dpll_priv: private data pointer passed on dpll registration 288 + * @frequency: on success holds pin's frequency 289 + * @extack: error reporting 290 + * 291 + * Calls set frequency command for corresponding and active input/output pin. 292 + * 293 + * Context: Calls a function which acquires and releases pf->dplls.lock 294 + * Return: 295 + * * 0 - success 296 + * * negative - error pin not active or couldn't get from hw 297 + */ 298 + static int 299 + ice_dpll_sw_pin_frequency_set(const struct dpll_pin *pin, void *pin_priv, 300 + const struct dpll_device *dpll, void *dpll_priv, 301 + u64 frequency, struct netlink_ext_ack *extack) 302 + { 303 + struct ice_dpll_pin *sma = pin_priv; 304 + int ret; 305 + 306 + if (!sma->active) { 307 + NL_SET_ERR_MSG(extack, "pin is not active"); 308 + return -EINVAL; 309 + } 310 + if (sma->direction == DPLL_PIN_DIRECTION_INPUT) 311 + ret = ice_dpll_input_frequency_set(NULL, sma->input, dpll, 312 + dpll_priv, frequency, 313 + extack); 314 + else 315 + ret = ice_dpll_output_frequency_set(NULL, sma->output, dpll, 316 + dpll_priv, frequency, 317 + extack); 318 + 319 + return ret; 320 + } 321 + 322 + /** 323 + * ice_dpll_sw_pin_frequency_get - callback for get frequency of SW pin 324 + * @pin: pointer to a pin 325 + * @pin_priv: private data pointer passed on pin registration 326 + * @dpll: pointer to dpll 327 + * @dpll_priv: private data pointer passed on dpll registration 328 + * @frequency: on success holds pin's frequency 329 + * @extack: error reporting 330 + * 331 + * Calls get frequency command for corresponding active input/output. 332 + * 333 + * Context: Calls a function which acquires and releases pf->dplls.lock 334 + * Return: 335 + * * 0 - success 336 + * * negative - error pin not active or couldn't get from hw 337 + */ 338 + static int 339 + ice_dpll_sw_pin_frequency_get(const struct dpll_pin *pin, void *pin_priv, 340 + const struct dpll_device *dpll, void *dpll_priv, 341 + u64 *frequency, struct netlink_ext_ack *extack) 342 + { 343 + struct ice_dpll_pin *sma = pin_priv; 344 + int ret; 345 + 346 + if (!sma->active) { 347 + *frequency = 0; 348 + return 0; 349 + } 350 + if (sma->direction == DPLL_PIN_DIRECTION_INPUT) { 351 + ret = ice_dpll_input_frequency_get(NULL, sma->input, dpll, 352 + dpll_priv, frequency, 353 + extack); 354 + } else { 355 + ret = ice_dpll_output_frequency_get(NULL, sma->output, dpll, 356 + dpll_priv, frequency, 357 + extack); 358 + } 359 + 360 + return ret; 361 + } 362 + 363 + /** 341 364 * ice_dpll_pin_enable - enable a pin on dplls 342 365 * @hw: board private hw structure 343 366 * @pin: pointer to a pin ··· 511 372 pin_type_name[pin_type], pin->idx); 512 373 513 374 return ret; 375 + } 376 + 377 + /** 378 + * ice_dpll_sw_pins_update - update status of all SW pins 379 + * @pf: private board struct 380 + * 381 + * Determine and update pin struct fields (direction/active) of their current 382 + * values for all the SW controlled pins. 383 + * 384 + * Context: Call with pf->dplls.lock held 385 + * Return: 386 + * * 0 - OK 387 + * * negative - error 388 + */ 389 + static int 390 + ice_dpll_sw_pins_update(struct ice_pf *pf) 391 + { 392 + struct ice_dplls *d = &pf->dplls; 393 + struct ice_dpll_pin *p; 394 + u8 data = 0; 395 + int ret; 396 + 397 + ret = ice_read_sma_ctrl(&pf->hw, &data); 398 + if (ret) 399 + return ret; 400 + /* no change since last check */ 401 + if (d->sma_data == data) 402 + return 0; 403 + 404 + /* 405 + * SMA1/U.FL1 vs SMA2/U.FL2 are using different bit scheme to decide 406 + * on their direction and if are active 407 + */ 408 + p = &d->sma[ICE_DPLL_PIN_SW_1_IDX]; 409 + p->active = true; 410 + p->direction = DPLL_PIN_DIRECTION_INPUT; 411 + if (data & ICE_SMA1_DIR_EN) { 412 + p->direction = DPLL_PIN_DIRECTION_OUTPUT; 413 + if (data & ICE_SMA1_TX_EN) 414 + p->active = false; 415 + } 416 + 417 + p = &d->sma[ICE_DPLL_PIN_SW_2_IDX]; 418 + p->active = true; 419 + p->direction = DPLL_PIN_DIRECTION_INPUT; 420 + if ((data & ICE_SMA2_INACTIVE_MASK) == ICE_SMA2_INACTIVE_MASK) 421 + p->active = false; 422 + else if (data & ICE_SMA2_DIR_EN) 423 + p->direction = DPLL_PIN_DIRECTION_OUTPUT; 424 + 425 + p = &d->ufl[ICE_DPLL_PIN_SW_1_IDX]; 426 + if (!(data & (ICE_SMA1_DIR_EN | ICE_SMA1_TX_EN))) 427 + p->active = true; 428 + else 429 + p->active = false; 430 + 431 + p = &d->ufl[ICE_DPLL_PIN_SW_2_IDX]; 432 + p->active = (data & ICE_SMA2_DIR_EN) && !(data & ICE_SMA2_UFL2_RX_DIS); 433 + d->sma_data = data; 434 + 435 + return 0; 514 436 } 515 437 516 438 /** ··· 670 470 pin->state[parent] = 671 471 DPLL_PIN_STATE_DISCONNECTED; 672 472 } 473 + break; 474 + case ICE_DPLL_PIN_TYPE_SOFTWARE: 475 + ret = ice_dpll_sw_pins_update(pf); 476 + if (ret) 477 + goto err; 673 478 break; 674 479 default: 675 480 return -EINVAL; ··· 998 793 } 999 794 1000 795 /** 796 + * ice_dpll_sma_direction_set - set direction of SMA pin 797 + * @p: pointer to a pin 798 + * @direction: requested direction of the pin 799 + * @extack: error reporting 800 + * 801 + * Wrapper for dpll subsystem callback. Set direction of a SMA pin. 802 + * 803 + * Context: Call with pf->dplls.lock held 804 + * Return: 805 + * * 0 - success 806 + * * negative - failed to get state 807 + */ 808 + static int ice_dpll_sma_direction_set(struct ice_dpll_pin *p, 809 + enum dpll_pin_direction direction, 810 + struct netlink_ext_ack *extack) 811 + { 812 + u8 data; 813 + int ret; 814 + 815 + if (p->direction == direction && p->active) 816 + return 0; 817 + ret = ice_read_sma_ctrl(&p->pf->hw, &data); 818 + if (ret) 819 + return ret; 820 + 821 + switch (p->idx) { 822 + case ICE_DPLL_PIN_SW_1_IDX: 823 + data &= ~ICE_SMA1_MASK; 824 + if (direction == DPLL_PIN_DIRECTION_OUTPUT) 825 + data |= ICE_SMA1_DIR_EN; 826 + break; 827 + case ICE_DPLL_PIN_SW_2_IDX: 828 + if (direction == DPLL_PIN_DIRECTION_INPUT) { 829 + data &= ~ICE_SMA2_DIR_EN; 830 + } else { 831 + data &= ~ICE_SMA2_TX_EN; 832 + data |= ICE_SMA2_DIR_EN; 833 + } 834 + break; 835 + default: 836 + return -EINVAL; 837 + } 838 + ret = ice_write_sma_ctrl(&p->pf->hw, data); 839 + if (!ret) 840 + ret = ice_dpll_pin_state_update(p->pf, p, 841 + ICE_DPLL_PIN_TYPE_SOFTWARE, 842 + extack); 843 + 844 + return ret; 845 + } 846 + 847 + /** 848 + * ice_dpll_ufl_pin_state_set - set U.FL pin state on dpll device 849 + * @pin: pointer to a pin 850 + * @pin_priv: private data pointer passed on pin registration 851 + * @dpll: registered dpll pointer 852 + * @dpll_priv: private data pointer passed on dpll registration 853 + * @state: requested state of the pin 854 + * @extack: error reporting 855 + * 856 + * Dpll subsystem callback. Set the state of a pin. 857 + * 858 + * Context: Acquires and releases pf->dplls.lock 859 + * Return: 860 + * * 0 - success 861 + * * negative - error 862 + */ 863 + static int 864 + ice_dpll_ufl_pin_state_set(const struct dpll_pin *pin, void *pin_priv, 865 + const struct dpll_device *dpll, void *dpll_priv, 866 + enum dpll_pin_state state, 867 + struct netlink_ext_ack *extack) 868 + { 869 + struct ice_dpll_pin *p = pin_priv, *target; 870 + struct ice_dpll *d = dpll_priv; 871 + enum ice_dpll_pin_type type; 872 + struct ice_pf *pf = p->pf; 873 + struct ice_hw *hw; 874 + bool enable; 875 + u8 data; 876 + int ret; 877 + 878 + if (ice_dpll_is_reset(pf, extack)) 879 + return -EBUSY; 880 + 881 + mutex_lock(&pf->dplls.lock); 882 + hw = &pf->hw; 883 + ret = ice_read_sma_ctrl(hw, &data); 884 + if (ret) 885 + goto unlock; 886 + 887 + ret = -EINVAL; 888 + switch (p->idx) { 889 + case ICE_DPLL_PIN_SW_1_IDX: 890 + if (state == DPLL_PIN_STATE_CONNECTED) { 891 + data &= ~ICE_SMA1_MASK; 892 + enable = true; 893 + } else if (state == DPLL_PIN_STATE_DISCONNECTED) { 894 + data |= ICE_SMA1_TX_EN; 895 + enable = false; 896 + } else { 897 + goto unlock; 898 + } 899 + target = p->output; 900 + type = ICE_DPLL_PIN_TYPE_OUTPUT; 901 + break; 902 + case ICE_DPLL_PIN_SW_2_IDX: 903 + if (state == DPLL_PIN_STATE_SELECTABLE) { 904 + data |= ICE_SMA2_DIR_EN; 905 + data &= ~ICE_SMA2_UFL2_RX_DIS; 906 + enable = true; 907 + } else if (state == DPLL_PIN_STATE_DISCONNECTED) { 908 + data |= ICE_SMA2_UFL2_RX_DIS; 909 + enable = false; 910 + } else { 911 + goto unlock; 912 + } 913 + target = p->input; 914 + type = ICE_DPLL_PIN_TYPE_INPUT; 915 + break; 916 + default: 917 + goto unlock; 918 + } 919 + 920 + ret = ice_write_sma_ctrl(hw, data); 921 + if (ret) 922 + goto unlock; 923 + ret = ice_dpll_pin_state_update(pf, p, ICE_DPLL_PIN_TYPE_SOFTWARE, 924 + extack); 925 + if (ret) 926 + goto unlock; 927 + 928 + if (enable) 929 + ret = ice_dpll_pin_enable(hw, target, d->dpll_idx, type, extack); 930 + else 931 + ret = ice_dpll_pin_disable(hw, target, type, extack); 932 + if (!ret) 933 + ret = ice_dpll_pin_state_update(pf, target, type, extack); 934 + 935 + unlock: 936 + mutex_unlock(&pf->dplls.lock); 937 + 938 + return ret; 939 + } 940 + 941 + /** 942 + * ice_dpll_sw_pin_state_get - get SW pin state 943 + * @pin: pointer to a pin 944 + * @pin_priv: private data pointer passed on pin registration 945 + * @dpll: registered dpll pointer 946 + * @dpll_priv: private data pointer passed on dpll registration 947 + * @state: on success holds state of the pin 948 + * @extack: error reporting 949 + * 950 + * Dpll subsystem callback. Check state of a SW pin. 951 + * 952 + * Context: Acquires and releases pf->dplls.lock 953 + * Return: 954 + * * 0 - success 955 + * * negative - error 956 + */ 957 + static int 958 + ice_dpll_sw_pin_state_get(const struct dpll_pin *pin, void *pin_priv, 959 + const struct dpll_device *dpll, void *dpll_priv, 960 + enum dpll_pin_state *state, 961 + struct netlink_ext_ack *extack) 962 + { 963 + struct ice_dpll_pin *p = pin_priv; 964 + struct ice_dpll *d = dpll_priv; 965 + struct ice_pf *pf = p->pf; 966 + int ret = 0; 967 + 968 + if (ice_dpll_is_reset(pf, extack)) 969 + return -EBUSY; 970 + mutex_lock(&pf->dplls.lock); 971 + if (!p->active) { 972 + *state = DPLL_PIN_STATE_DISCONNECTED; 973 + goto unlock; 974 + } 975 + 976 + if (p->direction == DPLL_PIN_DIRECTION_INPUT) { 977 + ret = ice_dpll_pin_state_update(pf, p->input, 978 + ICE_DPLL_PIN_TYPE_INPUT, 979 + extack); 980 + if (ret) 981 + goto unlock; 982 + *state = p->input->state[d->dpll_idx]; 983 + } else { 984 + ret = ice_dpll_pin_state_update(pf, p->output, 985 + ICE_DPLL_PIN_TYPE_OUTPUT, 986 + extack); 987 + if (ret) 988 + goto unlock; 989 + *state = p->output->state[d->dpll_idx]; 990 + } 991 + unlock: 992 + mutex_unlock(&pf->dplls.lock); 993 + 994 + return ret; 995 + } 996 + 997 + /** 998 + * ice_dpll_sma_pin_state_set - set SMA pin state on dpll device 999 + * @pin: pointer to a pin 1000 + * @pin_priv: private data pointer passed on pin registration 1001 + * @dpll: registered dpll pointer 1002 + * @dpll_priv: private data pointer passed on dpll registration 1003 + * @state: requested state of the pin 1004 + * @extack: error reporting 1005 + * 1006 + * Dpll subsystem callback. Set state of a pin. 1007 + * 1008 + * Context: Acquires and releases pf->dplls.lock 1009 + * Return: 1010 + * * 0 - success 1011 + * * negative - failed to get state 1012 + */ 1013 + static int 1014 + ice_dpll_sma_pin_state_set(const struct dpll_pin *pin, void *pin_priv, 1015 + const struct dpll_device *dpll, void *dpll_priv, 1016 + enum dpll_pin_state state, 1017 + struct netlink_ext_ack *extack) 1018 + { 1019 + struct ice_dpll_pin *sma = pin_priv, *target; 1020 + struct ice_dpll *d = dpll_priv; 1021 + struct ice_pf *pf = sma->pf; 1022 + enum ice_dpll_pin_type type; 1023 + bool enable; 1024 + int ret; 1025 + 1026 + if (ice_dpll_is_reset(pf, extack)) 1027 + return -EBUSY; 1028 + 1029 + mutex_lock(&pf->dplls.lock); 1030 + if (!sma->active) { 1031 + ret = ice_dpll_sma_direction_set(sma, sma->direction, extack); 1032 + if (ret) 1033 + goto unlock; 1034 + } 1035 + if (sma->direction == DPLL_PIN_DIRECTION_INPUT) { 1036 + enable = state == DPLL_PIN_STATE_SELECTABLE; 1037 + target = sma->input; 1038 + type = ICE_DPLL_PIN_TYPE_INPUT; 1039 + } else { 1040 + enable = state == DPLL_PIN_STATE_CONNECTED; 1041 + target = sma->output; 1042 + type = ICE_DPLL_PIN_TYPE_OUTPUT; 1043 + } 1044 + 1045 + if (enable) 1046 + ret = ice_dpll_pin_enable(&pf->hw, target, d->dpll_idx, type, 1047 + extack); 1048 + else 1049 + ret = ice_dpll_pin_disable(&pf->hw, target, type, extack); 1050 + if (!ret) 1051 + ret = ice_dpll_pin_state_update(pf, target, type, extack); 1052 + 1053 + unlock: 1054 + mutex_unlock(&pf->dplls.lock); 1055 + 1056 + return ret; 1057 + } 1058 + 1059 + /** 1001 1060 * ice_dpll_input_prio_get - get dpll's input prio 1002 1061 * @pin: pointer to a pin 1003 1062 * @pin_priv: private data pointer passed on pin registration ··· 1329 860 return ret; 1330 861 } 1331 862 863 + static int 864 + ice_dpll_sw_input_prio_get(const struct dpll_pin *pin, void *pin_priv, 865 + const struct dpll_device *dpll, void *dpll_priv, 866 + u32 *prio, struct netlink_ext_ack *extack) 867 + { 868 + struct ice_dpll_pin *p = pin_priv; 869 + struct ice_dpll *d = dpll_priv; 870 + struct ice_pf *pf = d->pf; 871 + 872 + mutex_lock(&pf->dplls.lock); 873 + if (p->input && p->direction == DPLL_PIN_DIRECTION_INPUT) 874 + *prio = d->input_prio[p->input->idx]; 875 + else 876 + *prio = ICE_DPLL_PIN_PRIO_OUTPUT; 877 + mutex_unlock(&pf->dplls.lock); 878 + 879 + return 0; 880 + } 881 + 882 + static int 883 + ice_dpll_sw_input_prio_set(const struct dpll_pin *pin, void *pin_priv, 884 + const struct dpll_device *dpll, void *dpll_priv, 885 + u32 prio, struct netlink_ext_ack *extack) 886 + { 887 + struct ice_dpll_pin *p = pin_priv; 888 + struct ice_dpll *d = dpll_priv; 889 + struct ice_pf *pf = d->pf; 890 + int ret; 891 + 892 + if (!p->input || p->direction != DPLL_PIN_DIRECTION_INPUT) 893 + return -EINVAL; 894 + if (ice_dpll_is_reset(pf, extack)) 895 + return -EBUSY; 896 + 897 + mutex_lock(&pf->dplls.lock); 898 + ret = ice_dpll_hw_input_prio_set(pf, d, p->input, prio, extack); 899 + mutex_unlock(&pf->dplls.lock); 900 + 901 + return ret; 902 + } 903 + 1332 904 /** 1333 905 * ice_dpll_input_direction - callback for get input pin direction 1334 906 * @pin: pointer to a pin ··· 1416 906 struct netlink_ext_ack *extack) 1417 907 { 1418 908 *direction = DPLL_PIN_DIRECTION_OUTPUT; 909 + 910 + return 0; 911 + } 912 + 913 + /** 914 + * ice_dpll_pin_sma_direction_set - callback for set SMA pin direction 915 + * @pin: pointer to a pin 916 + * @pin_priv: private data pointer passed on pin registration 917 + * @dpll: registered dpll pointer 918 + * @dpll_priv: private data pointer passed on dpll registration 919 + * @direction: requested pin direction 920 + * @extack: error reporting 921 + * 922 + * Dpll subsystem callback. Handler for setting direction of a SMA pin. 923 + * 924 + * Context: Acquires and releases pf->dplls.lock 925 + * Return: 926 + * * 0 - success 927 + * * negative - error 928 + */ 929 + static int 930 + ice_dpll_pin_sma_direction_set(const struct dpll_pin *pin, void *pin_priv, 931 + const struct dpll_device *dpll, void *dpll_priv, 932 + enum dpll_pin_direction direction, 933 + struct netlink_ext_ack *extack) 934 + { 935 + struct ice_dpll_pin *p = pin_priv; 936 + struct ice_pf *pf = p->pf; 937 + int ret; 938 + 939 + if (ice_dpll_is_reset(pf, extack)) 940 + return -EBUSY; 941 + 942 + mutex_lock(&pf->dplls.lock); 943 + ret = ice_dpll_sma_direction_set(p, direction, extack); 944 + mutex_unlock(&pf->dplls.lock); 945 + 946 + return ret; 947 + } 948 + 949 + /** 950 + * ice_dpll_pin_sw_direction_get - callback for get SW pin direction 951 + * @pin: pointer to a pin 952 + * @pin_priv: private data pointer passed on pin registration 953 + * @dpll: registered dpll pointer 954 + * @dpll_priv: private data pointer passed on dpll registration 955 + * @direction: on success holds pin direction 956 + * @extack: error reporting 957 + * 958 + * Dpll subsystem callback. Handler for getting direction of a SMA pin. 959 + * 960 + * Context: Acquires and releases pf->dplls.lock 961 + * Return: 962 + * * 0 - success 963 + * * negative - error 964 + */ 965 + static int 966 + ice_dpll_pin_sw_direction_get(const struct dpll_pin *pin, void *pin_priv, 967 + const struct dpll_device *dpll, void *dpll_priv, 968 + enum dpll_pin_direction *direction, 969 + struct netlink_ext_ack *extack) 970 + { 971 + struct ice_dpll_pin *p = pin_priv; 972 + struct ice_pf *pf = p->pf; 973 + 974 + if (ice_dpll_is_reset(pf, extack)) 975 + return -EBUSY; 976 + mutex_lock(&pf->dplls.lock); 977 + *direction = p->direction; 978 + mutex_unlock(&pf->dplls.lock); 1419 979 1420 980 return 0; 1421 981 } ··· 1604 1024 * Dpll subsystem callback. Wraps a handler for setting phase adjust on input 1605 1025 * pin. 1606 1026 * 1607 - * Context: Calls a function which acquires pf->dplls.lock 1027 + * Context: Calls a function which acquires and releases pf->dplls.lock 1608 1028 * Return: 1609 1029 * * 0 - success 1610 1030 * * negative - error ··· 1648 1068 ICE_DPLL_PIN_TYPE_OUTPUT); 1649 1069 } 1650 1070 1071 + /** 1072 + * ice_dpll_sw_phase_adjust_get - callback for get SW pin phase adjust 1073 + * @pin: pointer to a pin 1074 + * @pin_priv: private data pointer passed on pin registration 1075 + * @dpll: registered dpll pointer 1076 + * @dpll_priv: private data pointer passed on dpll registration 1077 + * @phase_adjust: on success holds phase adjust value 1078 + * @extack: error reporting 1079 + * 1080 + * Dpll subsystem callback. Wraps a handler for getting phase adjust on sw 1081 + * pin. 1082 + * 1083 + * Context: Calls a function which acquires and releases pf->dplls.lock 1084 + * Return: 1085 + * * 0 - success 1086 + * * negative - error 1087 + */ 1088 + static int 1089 + ice_dpll_sw_phase_adjust_get(const struct dpll_pin *pin, void *pin_priv, 1090 + const struct dpll_device *dpll, void *dpll_priv, 1091 + s32 *phase_adjust, 1092 + struct netlink_ext_ack *extack) 1093 + { 1094 + struct ice_dpll_pin *p = pin_priv; 1095 + 1096 + if (p->direction == DPLL_PIN_DIRECTION_INPUT) 1097 + return ice_dpll_pin_phase_adjust_get(p->input->pin, p->input, 1098 + dpll, dpll_priv, 1099 + phase_adjust, extack); 1100 + else 1101 + return ice_dpll_pin_phase_adjust_get(p->output->pin, p->output, 1102 + dpll, dpll_priv, 1103 + phase_adjust, extack); 1104 + } 1105 + 1106 + /** 1107 + * ice_dpll_sw_phase_adjust_set - callback for set SW pin phase adjust value 1108 + * @pin: pointer to a pin 1109 + * @pin_priv: private data pointer passed on pin registration 1110 + * @dpll: registered dpll pointer 1111 + * @dpll_priv: private data pointer passed on dpll registration 1112 + * @phase_adjust: phase_adjust to be set 1113 + * @extack: error reporting 1114 + * 1115 + * Dpll subsystem callback. Wraps a handler for setting phase adjust on output 1116 + * pin. 1117 + * 1118 + * Context: Calls a function which acquires and releases pf->dplls.lock 1119 + * Return: 1120 + * * 0 - success 1121 + * * negative - error 1122 + */ 1123 + static int 1124 + ice_dpll_sw_phase_adjust_set(const struct dpll_pin *pin, void *pin_priv, 1125 + const struct dpll_device *dpll, void *dpll_priv, 1126 + s32 phase_adjust, 1127 + struct netlink_ext_ack *extack) 1128 + { 1129 + struct ice_dpll_pin *p = pin_priv; 1130 + 1131 + if (!p->active) { 1132 + NL_SET_ERR_MSG(extack, "pin is not active"); 1133 + return -EINVAL; 1134 + } 1135 + if (p->direction == DPLL_PIN_DIRECTION_INPUT) 1136 + return ice_dpll_pin_phase_adjust_set(p->input->pin, p->input, 1137 + dpll, dpll_priv, 1138 + phase_adjust, extack, 1139 + ICE_DPLL_PIN_TYPE_INPUT); 1140 + else 1141 + return ice_dpll_pin_phase_adjust_set(p->output->pin, p->output, 1142 + dpll, dpll_priv, 1143 + phase_adjust, extack, 1144 + ICE_DPLL_PIN_TYPE_OUTPUT); 1145 + } 1146 + 1651 1147 #define ICE_DPLL_PHASE_OFFSET_DIVIDER 100 1652 1148 #define ICE_DPLL_PHASE_OFFSET_FACTOR \ 1653 1149 (DPLL_PHASE_OFFSET_DIVIDER / ICE_DPLL_PHASE_OFFSET_DIVIDER) ··· 1749 1093 const struct dpll_device *dpll, void *dpll_priv, 1750 1094 s64 *phase_offset, struct netlink_ext_ack *extack) 1751 1095 { 1096 + struct ice_dpll_pin *p = pin_priv; 1752 1097 struct ice_dpll *d = dpll_priv; 1753 1098 struct ice_pf *pf = d->pf; 1754 1099 1755 1100 mutex_lock(&pf->dplls.lock); 1756 - if (d->active_input == pin) 1101 + if (d->active_input == pin || (p->input && 1102 + d->active_input == p->input->pin)) 1757 1103 *phase_offset = d->phase_offset * ICE_DPLL_PHASE_OFFSET_FACTOR; 1758 1104 else 1759 1105 *phase_offset = 0; ··· 1973 1315 } 1974 1316 1975 1317 /** 1318 + * ice_dpll_sw_esync_set - callback for setting embedded sync on SW pin 1319 + * @pin: pointer to a pin 1320 + * @pin_priv: private data pointer passed on pin registration 1321 + * @dpll: registered dpll pointer 1322 + * @dpll_priv: private data pointer passed on dpll registration 1323 + * @freq: requested embedded sync frequency 1324 + * @extack: error reporting 1325 + * 1326 + * Dpll subsystem callback. Handler for setting embedded sync frequency value 1327 + * on SW pin. 1328 + * 1329 + * Context: Calls a function which acquires and releases pf->dplls.lock 1330 + * Return: 1331 + * * 0 - success 1332 + * * negative - error 1333 + */ 1334 + static int 1335 + ice_dpll_sw_esync_set(const struct dpll_pin *pin, void *pin_priv, 1336 + const struct dpll_device *dpll, void *dpll_priv, 1337 + u64 freq, struct netlink_ext_ack *extack) 1338 + { 1339 + struct ice_dpll_pin *p = pin_priv; 1340 + 1341 + if (!p->active) { 1342 + NL_SET_ERR_MSG(extack, "pin is not active"); 1343 + return -EINVAL; 1344 + } 1345 + if (p->direction == DPLL_PIN_DIRECTION_INPUT) 1346 + return ice_dpll_input_esync_set(p->input->pin, p->input, dpll, 1347 + dpll_priv, freq, extack); 1348 + else 1349 + return ice_dpll_output_esync_set(p->output->pin, p->output, 1350 + dpll, dpll_priv, freq, extack); 1351 + } 1352 + 1353 + /** 1354 + * ice_dpll_sw_esync_get - callback for getting embedded sync on SW pin 1355 + * @pin: pointer to a pin 1356 + * @pin_priv: private data pointer passed on pin registration 1357 + * @dpll: registered dpll pointer 1358 + * @dpll_priv: private data pointer passed on dpll registration 1359 + * @esync: on success holds embedded sync frequency and properties 1360 + * @extack: error reporting 1361 + * 1362 + * Dpll subsystem callback. Handler for getting embedded sync frequency value 1363 + * of SW pin. 1364 + * 1365 + * Context: Calls a function which acquires and releases pf->dplls.lock 1366 + * Return: 1367 + * * 0 - success 1368 + * * negative - error 1369 + */ 1370 + static int 1371 + ice_dpll_sw_esync_get(const struct dpll_pin *pin, void *pin_priv, 1372 + const struct dpll_device *dpll, void *dpll_priv, 1373 + struct dpll_pin_esync *esync, 1374 + struct netlink_ext_ack *extack) 1375 + { 1376 + struct ice_dpll_pin *p = pin_priv; 1377 + 1378 + if (p->direction == DPLL_PIN_DIRECTION_INPUT) 1379 + return ice_dpll_input_esync_get(p->input->pin, p->input, dpll, 1380 + dpll_priv, esync, extack); 1381 + else 1382 + return ice_dpll_output_esync_get(p->output->pin, p->output, 1383 + dpll, dpll_priv, esync, 1384 + extack); 1385 + } 1386 + 1387 + /** 1976 1388 * ice_dpll_rclk_state_on_pin_set - set a state on rclk pin 1977 1389 * @pin: pointer to a pin 1978 1390 * @pin_priv: private data pointer passed on pin registration ··· 2153 1425 .state_on_pin_set = ice_dpll_rclk_state_on_pin_set, 2154 1426 .state_on_pin_get = ice_dpll_rclk_state_on_pin_get, 2155 1427 .direction_get = ice_dpll_input_direction, 1428 + }; 1429 + 1430 + static const struct dpll_pin_ops ice_dpll_pin_sma_ops = { 1431 + .state_on_dpll_set = ice_dpll_sma_pin_state_set, 1432 + .state_on_dpll_get = ice_dpll_sw_pin_state_get, 1433 + .direction_get = ice_dpll_pin_sw_direction_get, 1434 + .direction_set = ice_dpll_pin_sma_direction_set, 1435 + .prio_get = ice_dpll_sw_input_prio_get, 1436 + .prio_set = ice_dpll_sw_input_prio_set, 1437 + .frequency_get = ice_dpll_sw_pin_frequency_get, 1438 + .frequency_set = ice_dpll_sw_pin_frequency_set, 1439 + .phase_adjust_get = ice_dpll_sw_phase_adjust_get, 1440 + .phase_adjust_set = ice_dpll_sw_phase_adjust_set, 1441 + .phase_offset_get = ice_dpll_phase_offset_get, 1442 + .esync_set = ice_dpll_sw_esync_set, 1443 + .esync_get = ice_dpll_sw_esync_get, 1444 + }; 1445 + 1446 + static const struct dpll_pin_ops ice_dpll_pin_ufl_ops = { 1447 + .state_on_dpll_set = ice_dpll_ufl_pin_state_set, 1448 + .state_on_dpll_get = ice_dpll_sw_pin_state_get, 1449 + .direction_get = ice_dpll_pin_sw_direction_get, 1450 + .frequency_get = ice_dpll_sw_pin_frequency_get, 1451 + .frequency_set = ice_dpll_sw_pin_frequency_set, 1452 + .esync_set = ice_dpll_sw_esync_set, 1453 + .esync_get = ice_dpll_sw_esync_get, 1454 + .phase_adjust_get = ice_dpll_sw_phase_adjust_get, 1455 + .phase_adjust_set = ice_dpll_sw_phase_adjust_set, 1456 + .phase_offset_get = ice_dpll_phase_offset_get, 2156 1457 }; 2157 1458 2158 1459 static const struct dpll_pin_ops ice_dpll_input_ops = { ··· 2446 1689 int i; 2447 1690 2448 1691 for (i = 0; i < count; i++) 2449 - dpll_pin_unregister(dpll, pins[i].pin, ops, &pins[i]); 1692 + if (!pins[i].hidden) 1693 + dpll_pin_unregister(dpll, pins[i].pin, ops, &pins[i]); 2450 1694 } 2451 1695 2452 1696 /** ··· 2470 1712 int ret, i; 2471 1713 2472 1714 for (i = 0; i < count; i++) { 2473 - ret = dpll_pin_register(dpll, pins[i].pin, ops, &pins[i]); 2474 - if (ret) 2475 - goto unregister_pins; 1715 + if (!pins[i].hidden) { 1716 + ret = dpll_pin_register(dpll, pins[i].pin, ops, &pins[i]); 1717 + if (ret) 1718 + goto unregister_pins; 1719 + } 2476 1720 } 2477 1721 2478 1722 return 0; 2479 1723 2480 1724 unregister_pins: 2481 1725 while (--i >= 0) 2482 - dpll_pin_unregister(dpll, pins[i].pin, ops, &pins[i]); 1726 + if (!pins[i].hidden) 1727 + dpll_pin_unregister(dpll, pins[i].pin, ops, &pins[i]); 2483 1728 return ret; 2484 1729 } 2485 1730 ··· 2670 1909 ice_dpll_unregister_pins(de->dpll, outputs, 2671 1910 &ice_dpll_output_ops, num_outputs); 2672 1911 ice_dpll_release_pins(outputs, num_outputs); 1912 + if (!pf->dplls.generic) { 1913 + ice_dpll_deinit_direct_pins(cgu, pf->dplls.ufl, 1914 + ICE_DPLL_PIN_SW_NUM, 1915 + &ice_dpll_pin_ufl_ops, 1916 + pf->dplls.pps.dpll, 1917 + pf->dplls.eec.dpll); 1918 + ice_dpll_deinit_direct_pins(cgu, pf->dplls.sma, 1919 + ICE_DPLL_PIN_SW_NUM, 1920 + &ice_dpll_pin_sma_ops, 1921 + pf->dplls.pps.dpll, 1922 + pf->dplls.eec.dpll); 1923 + } 2673 1924 } 2674 1925 } 2675 1926 ··· 2699 1926 */ 2700 1927 static int ice_dpll_init_pins(struct ice_pf *pf, bool cgu) 2701 1928 { 2702 - u32 rclk_idx; 2703 - int ret; 1929 + int ret, count; 2704 1930 2705 1931 ret = ice_dpll_init_direct_pins(pf, cgu, pf->dplls.inputs, 0, 2706 1932 pf->dplls.num_inputs, ··· 2707 1935 pf->dplls.eec.dpll, pf->dplls.pps.dpll); 2708 1936 if (ret) 2709 1937 return ret; 1938 + count = pf->dplls.num_inputs; 2710 1939 if (cgu) { 2711 1940 ret = ice_dpll_init_direct_pins(pf, cgu, pf->dplls.outputs, 2712 - pf->dplls.num_inputs, 1941 + count, 2713 1942 pf->dplls.num_outputs, 2714 1943 &ice_dpll_output_ops, 2715 1944 pf->dplls.eec.dpll, 2716 1945 pf->dplls.pps.dpll); 2717 1946 if (ret) 2718 1947 goto deinit_inputs; 1948 + count += pf->dplls.num_outputs; 1949 + if (!pf->dplls.generic) { 1950 + ret = ice_dpll_init_direct_pins(pf, cgu, pf->dplls.sma, 1951 + count, 1952 + ICE_DPLL_PIN_SW_NUM, 1953 + &ice_dpll_pin_sma_ops, 1954 + pf->dplls.eec.dpll, 1955 + pf->dplls.pps.dpll); 1956 + if (ret) 1957 + goto deinit_outputs; 1958 + count += ICE_DPLL_PIN_SW_NUM; 1959 + ret = ice_dpll_init_direct_pins(pf, cgu, pf->dplls.ufl, 1960 + count, 1961 + ICE_DPLL_PIN_SW_NUM, 1962 + &ice_dpll_pin_ufl_ops, 1963 + pf->dplls.eec.dpll, 1964 + pf->dplls.pps.dpll); 1965 + if (ret) 1966 + goto deinit_sma; 1967 + count += ICE_DPLL_PIN_SW_NUM; 1968 + } 1969 + } else { 1970 + count += pf->dplls.num_outputs + 2 * ICE_DPLL_PIN_SW_NUM; 2719 1971 } 2720 - rclk_idx = pf->dplls.num_inputs + pf->dplls.num_outputs + pf->hw.pf_id; 2721 - ret = ice_dpll_init_rclk_pins(pf, &pf->dplls.rclk, rclk_idx, 1972 + ret = ice_dpll_init_rclk_pins(pf, &pf->dplls.rclk, count + pf->hw.pf_id, 2722 1973 &ice_dpll_rclk_ops); 2723 1974 if (ret) 2724 - goto deinit_outputs; 1975 + goto deinit_ufl; 2725 1976 2726 1977 return 0; 1978 + deinit_ufl: 1979 + ice_dpll_deinit_direct_pins(cgu, pf->dplls.ufl, 1980 + ICE_DPLL_PIN_SW_NUM, 1981 + &ice_dpll_pin_ufl_ops, 1982 + pf->dplls.pps.dpll, pf->dplls.eec.dpll); 1983 + deinit_sma: 1984 + ice_dpll_deinit_direct_pins(cgu, pf->dplls.sma, 1985 + ICE_DPLL_PIN_SW_NUM, 1986 + &ice_dpll_pin_sma_ops, 1987 + pf->dplls.pps.dpll, pf->dplls.eec.dpll); 2727 1988 deinit_outputs: 2728 1989 ice_dpll_deinit_direct_pins(cgu, pf->dplls.outputs, 2729 1990 pf->dplls.num_outputs, ··· 2989 2184 default: 2990 2185 return -EINVAL; 2991 2186 } 2992 - if (num_pins != ice_cgu_get_num_pins(hw, input)) 2187 + if (num_pins != ice_cgu_get_num_pins(hw, input)) { 2188 + pf->dplls.generic = true; 2993 2189 return ice_dpll_init_info_pins_generic(pf, input); 2190 + } 2994 2191 2995 2192 for (i = 0; i < num_pins; i++) { 2996 2193 caps = 0; ··· 3010 2203 return ret; 3011 2204 caps |= (DPLL_PIN_CAPABILITIES_PRIORITY_CAN_CHANGE | 3012 2205 DPLL_PIN_CAPABILITIES_STATE_CAN_CHANGE); 2206 + if (ice_dpll_is_sw_pin(pf, i, true)) 2207 + pins[i].hidden = true; 3013 2208 } else { 3014 2209 ret = ice_cgu_get_output_pin_state_caps(hw, i, &caps); 3015 2210 if (ret) 3016 2211 return ret; 2212 + if (ice_dpll_is_sw_pin(pf, i, false)) 2213 + pins[i].hidden = true; 3017 2214 } 3018 2215 ice_dpll_phase_range_set(&pins[i].prop.phase_range, 3019 2216 phase_adj_max); ··· 3057 2246 } 3058 2247 3059 2248 /** 2249 + * ice_dpll_init_info_sw_pins - initializes software controlled pin information 2250 + * @pf: board private structure 2251 + * 2252 + * Init information for software controlled pins, cache them in 2253 + * pf->dplls.sma and pf->dplls.ufl. 2254 + * 2255 + * Return: 2256 + * * 0 - success 2257 + * * negative - init failure reason 2258 + */ 2259 + static int ice_dpll_init_info_sw_pins(struct ice_pf *pf) 2260 + { 2261 + u8 freq_supp_num, pin_abs_idx, input_idx_offset = 0; 2262 + struct ice_dplls *d = &pf->dplls; 2263 + struct ice_dpll_pin *pin; 2264 + u32 phase_adj_max, caps; 2265 + int i, ret; 2266 + 2267 + if (pf->hw.device_id == ICE_DEV_ID_E810C_QSFP) 2268 + input_idx_offset = ICE_E810_RCLK_PINS_NUM; 2269 + phase_adj_max = max(d->input_phase_adj_max, d->output_phase_adj_max); 2270 + caps = DPLL_PIN_CAPABILITIES_STATE_CAN_CHANGE; 2271 + for (i = 0; i < ICE_DPLL_PIN_SW_NUM; i++) { 2272 + pin = &d->sma[i]; 2273 + pin->idx = i; 2274 + pin->prop.type = DPLL_PIN_TYPE_EXT; 2275 + pin_abs_idx = ICE_DPLL_PIN_SW_INPUT_ABS(i) + input_idx_offset; 2276 + pin->prop.freq_supported = 2277 + ice_cgu_get_pin_freq_supp(&pf->hw, pin_abs_idx, 2278 + true, &freq_supp_num); 2279 + pin->prop.freq_supported_num = freq_supp_num; 2280 + pin->prop.capabilities = 2281 + (DPLL_PIN_CAPABILITIES_DIRECTION_CAN_CHANGE | 2282 + DPLL_PIN_CAPABILITIES_PRIORITY_CAN_CHANGE | 2283 + caps); 2284 + pin->pf = pf; 2285 + pin->prop.board_label = ice_dpll_sw_pin_sma[i]; 2286 + pin->input = &d->inputs[pin_abs_idx]; 2287 + pin->output = &d->outputs[ICE_DPLL_PIN_SW_OUTPUT_ABS(i)]; 2288 + ice_dpll_phase_range_set(&pin->prop.phase_range, phase_adj_max); 2289 + } 2290 + for (i = 0; i < ICE_DPLL_PIN_SW_NUM; i++) { 2291 + pin = &d->ufl[i]; 2292 + pin->idx = i; 2293 + pin->prop.type = DPLL_PIN_TYPE_EXT; 2294 + pin->prop.capabilities = caps; 2295 + pin->pf = pf; 2296 + pin->prop.board_label = ice_dpll_sw_pin_ufl[i]; 2297 + if (i == ICE_DPLL_PIN_SW_1_IDX) { 2298 + pin->direction = DPLL_PIN_DIRECTION_OUTPUT; 2299 + pin_abs_idx = ICE_DPLL_PIN_SW_OUTPUT_ABS(i); 2300 + pin->prop.freq_supported = 2301 + ice_cgu_get_pin_freq_supp(&pf->hw, pin_abs_idx, 2302 + false, 2303 + &freq_supp_num); 2304 + pin->prop.freq_supported_num = freq_supp_num; 2305 + pin->input = NULL; 2306 + pin->output = &d->outputs[pin_abs_idx]; 2307 + } else if (i == ICE_DPLL_PIN_SW_2_IDX) { 2308 + pin->direction = DPLL_PIN_DIRECTION_INPUT; 2309 + pin_abs_idx = ICE_DPLL_PIN_SW_INPUT_ABS(i) + 2310 + input_idx_offset; 2311 + pin->output = NULL; 2312 + pin->input = &d->inputs[pin_abs_idx]; 2313 + pin->prop.freq_supported = 2314 + ice_cgu_get_pin_freq_supp(&pf->hw, pin_abs_idx, 2315 + true, &freq_supp_num); 2316 + pin->prop.freq_supported_num = freq_supp_num; 2317 + pin->prop.capabilities = 2318 + (DPLL_PIN_CAPABILITIES_PRIORITY_CAN_CHANGE | 2319 + caps); 2320 + } 2321 + ice_dpll_phase_range_set(&pin->prop.phase_range, phase_adj_max); 2322 + } 2323 + ret = ice_dpll_pin_state_update(pf, pin, ICE_DPLL_PIN_TYPE_SOFTWARE, 2324 + NULL); 2325 + if (ret) 2326 + return ret; 2327 + 2328 + return 0; 2329 + } 2330 + 2331 + /** 3060 2332 * ice_dpll_init_pins_info - init pins info wrapper 3061 2333 * @pf: board private structure 3062 2334 * @pin_type: type of pins being initialized ··· 3159 2265 return ice_dpll_init_info_direct_pins(pf, pin_type); 3160 2266 case ICE_DPLL_PIN_TYPE_RCLK_INPUT: 3161 2267 return ice_dpll_init_info_rclk_pin(pf); 2268 + case ICE_DPLL_PIN_TYPE_SOFTWARE: 2269 + return ice_dpll_init_info_sw_pins(pf); 3162 2270 default: 3163 2271 return -EINVAL; 3164 2272 } ··· 3245 2349 } 3246 2350 3247 2351 ret = ice_dpll_init_pins_info(pf, ICE_DPLL_PIN_TYPE_OUTPUT); 2352 + if (ret) 2353 + goto deinit_info; 2354 + ret = ice_dpll_init_pins_info(pf, ICE_DPLL_PIN_TYPE_SOFTWARE); 3248 2355 if (ret) 3249 2356 goto deinit_info; 3250 2357 }
+22 -1
drivers/net/ethernet/intel/ice/ice_dpll.h
··· 8 8 9 9 #define ICE_DPLL_RCLK_NUM_MAX 4 10 10 11 + /** 12 + * enum ice_dpll_pin_sw - enumerate ice software pin indices: 13 + * @ICE_DPLL_PIN_SW_1_IDX: index of first SW pin 14 + * @ICE_DPLL_PIN_SW_2_IDX: index of second SW pin 15 + * @ICE_DPLL_PIN_SW_NUM: number of SW pins in pair 16 + */ 17 + enum ice_dpll_pin_sw { 18 + ICE_DPLL_PIN_SW_1_IDX, 19 + ICE_DPLL_PIN_SW_2_IDX, 20 + ICE_DPLL_PIN_SW_NUM 21 + }; 22 + 11 23 /** ice_dpll_pin - store info about pins 12 24 * @pin: dpll pin structure 13 25 * @pf: pointer to pf, which has registered the dpll_pin ··· 43 31 struct dpll_pin_properties prop; 44 32 u32 freq; 45 33 s32 phase_adjust; 34 + struct ice_dpll_pin *input; 35 + struct ice_dpll_pin *output; 36 + enum dpll_pin_direction direction; 46 37 u8 status; 38 + bool active; 39 + bool hidden; 47 40 }; 48 41 49 42 /** ice_dpll - store info required for DPLL control ··· 110 93 struct ice_dpll pps; 111 94 struct ice_dpll_pin *inputs; 112 95 struct ice_dpll_pin *outputs; 96 + struct ice_dpll_pin sma[ICE_DPLL_PIN_SW_NUM]; 97 + struct ice_dpll_pin ufl[ICE_DPLL_PIN_SW_NUM]; 113 98 struct ice_dpll_pin rclk; 114 99 u8 num_inputs; 115 100 u8 num_outputs; 116 - int cgu_state_acq_err_num; 101 + u8 sma_data; 117 102 u8 base_rclk_idx; 103 + int cgu_state_acq_err_num; 118 104 u64 clock_id; 119 105 s32 input_phase_adj_max; 120 106 s32 output_phase_adj_max; 107 + bool generic; 121 108 }; 122 109 123 110 #if IS_ENABLED(CONFIG_PTP_1588_CLOCK)
+1
drivers/net/ethernet/intel/ice/ice_ptp_hw.h
··· 704 704 #define ICE_SMA1_MASK (ICE_SMA1_DIR_EN | ICE_SMA1_TX_EN) 705 705 #define ICE_SMA2_MASK (ICE_SMA2_UFL2_RX_DIS | ICE_SMA2_DIR_EN | \ 706 706 ICE_SMA2_TX_EN) 707 + #define ICE_SMA2_INACTIVE_MASK (ICE_SMA2_DIR_EN | ICE_SMA2_TX_EN) 707 708 #define ICE_ALL_SMA_MASK (ICE_SMA1_MASK | ICE_SMA2_MASK) 708 709 709 710 #define ICE_SMA_MIN_BIT 3