^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * PCIe SERDES driver for AM654x SoC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright (C) 2018 - 2019 Texas Instruments Incorporated - http://www.ti.com/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * Author: Kishon Vijay Abraham I <kishon@ti.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <dt-bindings/phy/phy.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/clk.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/clk-provider.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/mfd/syscon.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/mux/consumer.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/of_address.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/phy/phy.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/platform_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <linux/pm_runtime.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <linux/regmap.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #define CMU_R004 0x4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #define CMU_R060 0x60
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #define CMU_R07C 0x7c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #define CMU_R088 0x88
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #define CMU_R0D0 0xd0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #define CMU_R0E8 0xe8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #define LANE_R048 0x248
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #define LANE_R058 0x258
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #define LANE_R06c 0x26c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #define LANE_R070 0x270
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #define LANE_R070 0x270
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) #define LANE_R19C 0x39c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) #define COMLANE_R004 0xa04
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) #define COMLANE_R138 0xb38
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) #define VERSION_VAL 0x70
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) #define COMLANE_R190 0xb90
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) #define COMLANE_R194 0xb94
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) #define COMRXEQ_R004 0x1404
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) #define COMRXEQ_R008 0x1408
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) #define COMRXEQ_R00C 0x140c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) #define COMRXEQ_R014 0x1414
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) #define COMRXEQ_R018 0x1418
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) #define COMRXEQ_R01C 0x141c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) #define COMRXEQ_R04C 0x144c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) #define COMRXEQ_R088 0x1488
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) #define COMRXEQ_R094 0x1494
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) #define COMRXEQ_R098 0x1498
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) #define SERDES_CTRL 0x1fd0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) #define WIZ_LANEXCTL_STS 0x1fe0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) #define TX0_DISABLE_STATE 0x4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) #define TX0_SLEEP_STATE 0x5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) #define TX0_SNOOZE_STATE 0x6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) #define TX0_ENABLE_STATE 0x7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) #define RX0_DISABLE_STATE 0x4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) #define RX0_SLEEP_STATE 0x5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) #define RX0_SNOOZE_STATE 0x6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) #define RX0_ENABLE_STATE 0x7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) #define WIZ_PLL_CTRL 0x1ff4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) #define PLL_DISABLE_STATE 0x4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) #define PLL_SLEEP_STATE 0x5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) #define PLL_SNOOZE_STATE 0x6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) #define PLL_ENABLE_STATE 0x7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) #define PLL_LOCK_TIME 100000 /* in microseconds */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) #define SLEEP_TIME 100 /* in microseconds */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) #define LANE_USB3 0x0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) #define LANE_PCIE0_LANE0 0x1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) #define LANE_PCIE1_LANE0 0x0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) #define LANE_PCIE0_LANE1 0x1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) #define SERDES_NUM_CLOCKS 3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) #define AM654_SERDES_CTRL_CLKSEL_MASK GENMASK(7, 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) #define AM654_SERDES_CTRL_CLKSEL_SHIFT 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) struct serdes_am654_clk_mux {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) struct clk_hw hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) struct regmap *regmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) unsigned int reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) int clk_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) struct clk_init_data clk_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) #define to_serdes_am654_clk_mux(_hw) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) container_of(_hw, struct serdes_am654_clk_mux, hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) static const struct regmap_config serdes_am654_regmap_config = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) .reg_bits = 32,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) .val_bits = 32,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) .reg_stride = 4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) .fast_io = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) .max_register = 0x1ffc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) enum serdes_am654_fields {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) /* CMU PLL Control */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) CMU_PLL_CTRL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) LANE_PLL_CTRL_RXEQ_RXIDLE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) /* CMU VCO bias current and VREG setting */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) AHB_PMA_CM_VCO_VBIAS_VREG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) AHB_PMA_CM_VCO_BIAS_VREG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) AHB_PMA_CM_SR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) AHB_SSC_GEN_Z_O_20_13,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) /* AHB PMA Lane Configuration */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) AHB_PMA_LN_AGC_THSEL_VREGH,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) /* AGC and Signal detect threshold for Gen3 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) AHB_PMA_LN_GEN3_AGC_SD_THSEL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) AHB_PMA_LN_RX_SELR_GEN3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) AHB_PMA_LN_TX_DRV,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) /* CMU Master Reset */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) CMU_MASTER_CDN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) /* P2S ring buffer initial startup pointer difference */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) P2S_RBUF_PTR_DIFF,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) CONFIG_VERSION,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) /* Lane 1 Master Reset */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) L1_MASTER_CDN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) /* CMU OK Status */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) CMU_OK_I_0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) /* Mid-speed initial calibration control */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) COMRXEQ_MS_INIT_CTRL_7_0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) /* High-speed initial calibration control */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) COMRXEQ_HS_INIT_CAL_7_0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) /* Mid-speed recalibration control */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) COMRXEQ_MS_RECAL_CTRL_7_0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) /* High-speed recalibration control */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) COMRXEQ_HS_RECAL_CTRL_7_0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) /* ATT configuration */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) COMRXEQ_CSR_ATT_CONFIG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) /* Edge based boost adaptation window length */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) COMRXEQ_CSR_EBSTADAPT_WIN_LEN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) /* COMRXEQ control 3 & 4 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) COMRXEQ_CTRL_3_4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) /* COMRXEQ control 14, 15 and 16*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) COMRXEQ_CTRL_14_15_16,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) /* Threshold for errors in pattern data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) COMRXEQ_CSR_DLEV_ERR_THRESH,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) /* COMRXEQ control 25 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) COMRXEQ_CTRL_25,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) /* Mid-speed rate change calibration control */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) CSR_RXEQ_RATE_CHANGE_CAL_RUN_RATE2_O,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) /* High-speed rate change calibration control */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) COMRXEQ_HS_RCHANGE_CTRL_7_0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) /* Serdes reset */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) POR_EN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) /* Tx Enable Value */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) TX0_ENABLE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) /* Rx Enable Value */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) RX0_ENABLE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) /* PLL Enable Value */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) PLL_ENABLE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) /* PLL ready for use */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) PLL_OK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) /* sentinel */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) MAX_FIELDS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) static const struct reg_field serdes_am654_reg_fields[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) [CMU_PLL_CTRL] = REG_FIELD(CMU_R004, 8, 15),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) [AHB_PMA_CM_VCO_VBIAS_VREG] = REG_FIELD(CMU_R060, 8, 15),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) [CMU_MASTER_CDN] = REG_FIELD(CMU_R07C, 24, 31),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) [AHB_PMA_CM_VCO_BIAS_VREG] = REG_FIELD(CMU_R088, 24, 31),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) [AHB_PMA_CM_SR] = REG_FIELD(CMU_R0D0, 24, 31),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) [AHB_SSC_GEN_Z_O_20_13] = REG_FIELD(CMU_R0E8, 8, 15),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) [LANE_PLL_CTRL_RXEQ_RXIDLE] = REG_FIELD(LANE_R048, 8, 15),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) [AHB_PMA_LN_AGC_THSEL_VREGH] = REG_FIELD(LANE_R058, 16, 23),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) [AHB_PMA_LN_GEN3_AGC_SD_THSEL] = REG_FIELD(LANE_R06c, 0, 7),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) [AHB_PMA_LN_RX_SELR_GEN3] = REG_FIELD(LANE_R070, 16, 23),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) [AHB_PMA_LN_TX_DRV] = REG_FIELD(LANE_R19C, 16, 23),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) [P2S_RBUF_PTR_DIFF] = REG_FIELD(COMLANE_R004, 0, 7),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) [CONFIG_VERSION] = REG_FIELD(COMLANE_R138, 16, 23),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) [L1_MASTER_CDN] = REG_FIELD(COMLANE_R190, 8, 15),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) [CMU_OK_I_0] = REG_FIELD(COMLANE_R194, 19, 19),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) [COMRXEQ_MS_INIT_CTRL_7_0] = REG_FIELD(COMRXEQ_R004, 24, 31),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) [COMRXEQ_HS_INIT_CAL_7_0] = REG_FIELD(COMRXEQ_R008, 0, 7),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) [COMRXEQ_MS_RECAL_CTRL_7_0] = REG_FIELD(COMRXEQ_R00C, 8, 15),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) [COMRXEQ_HS_RECAL_CTRL_7_0] = REG_FIELD(COMRXEQ_R00C, 16, 23),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) [COMRXEQ_CSR_ATT_CONFIG] = REG_FIELD(COMRXEQ_R014, 16, 23),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) [COMRXEQ_CSR_EBSTADAPT_WIN_LEN] = REG_FIELD(COMRXEQ_R018, 16, 23),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) [COMRXEQ_CTRL_3_4] = REG_FIELD(COMRXEQ_R01C, 8, 15),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) [COMRXEQ_CTRL_14_15_16] = REG_FIELD(COMRXEQ_R04C, 0, 7),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) [COMRXEQ_CSR_DLEV_ERR_THRESH] = REG_FIELD(COMRXEQ_R088, 16, 23),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) [COMRXEQ_CTRL_25] = REG_FIELD(COMRXEQ_R094, 24, 31),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) [CSR_RXEQ_RATE_CHANGE_CAL_RUN_RATE2_O] = REG_FIELD(COMRXEQ_R098, 8, 15),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) [COMRXEQ_HS_RCHANGE_CTRL_7_0] = REG_FIELD(COMRXEQ_R098, 16, 23),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) [POR_EN] = REG_FIELD(SERDES_CTRL, 29, 29),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) [TX0_ENABLE] = REG_FIELD(WIZ_LANEXCTL_STS, 29, 31),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) [RX0_ENABLE] = REG_FIELD(WIZ_LANEXCTL_STS, 13, 15),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) [PLL_ENABLE] = REG_FIELD(WIZ_PLL_CTRL, 29, 31),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) [PLL_OK] = REG_FIELD(WIZ_PLL_CTRL, 28, 28),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) struct serdes_am654 {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) struct regmap *regmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) struct regmap_field *fields[MAX_FIELDS];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) struct device *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) struct mux_control *control;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) bool busy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) u32 type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) struct device_node *of_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) struct clk_onecell_data clk_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) struct clk *clks[SERDES_NUM_CLOCKS];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) static int serdes_am654_enable_pll(struct serdes_am654 *phy)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) u32 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) ret = regmap_field_write(phy->fields[PLL_ENABLE], PLL_ENABLE_STATE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) return regmap_field_read_poll_timeout(phy->fields[PLL_OK], val, val,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) 1000, PLL_LOCK_TIME);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) static void serdes_am654_disable_pll(struct serdes_am654 *phy)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) struct device *dev = phy->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) ret = regmap_field_write(phy->fields[PLL_ENABLE], PLL_DISABLE_STATE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) dev_err(dev, "Failed to disable PLL\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) static int serdes_am654_enable_txrx(struct serdes_am654 *phy)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) /* Enable TX */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) ret |= regmap_field_write(phy->fields[TX0_ENABLE], TX0_ENABLE_STATE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) /* Enable RX */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) ret |= regmap_field_write(phy->fields[RX0_ENABLE], RX0_ENABLE_STATE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) static int serdes_am654_disable_txrx(struct serdes_am654 *phy)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) /* Disable TX */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) ret |= regmap_field_write(phy->fields[TX0_ENABLE], TX0_DISABLE_STATE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) /* Disable RX */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) ret |= regmap_field_write(phy->fields[RX0_ENABLE], RX0_DISABLE_STATE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) static int serdes_am654_power_on(struct phy *x)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) struct serdes_am654 *phy = phy_get_drvdata(x);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) struct device *dev = phy->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) u32 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) ret = serdes_am654_enable_pll(phy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) dev_err(dev, "Failed to enable PLL\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) ret = serdes_am654_enable_txrx(phy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) dev_err(dev, "Failed to enable TX RX\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) return regmap_field_read_poll_timeout(phy->fields[CMU_OK_I_0], val,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) val, SLEEP_TIME, PLL_LOCK_TIME);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) static int serdes_am654_power_off(struct phy *x)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) struct serdes_am654 *phy = phy_get_drvdata(x);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) serdes_am654_disable_txrx(phy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) serdes_am654_disable_pll(phy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) #define SERDES_AM654_CFG(offset, a, b, val) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) regmap_update_bits(phy->regmap, (offset),\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) GENMASK((a), (b)), (val) << (b))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) static int serdes_am654_usb3_init(struct serdes_am654 *phy)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) SERDES_AM654_CFG(0x0000, 31, 24, 0x17);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) SERDES_AM654_CFG(0x0004, 15, 8, 0x02);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) SERDES_AM654_CFG(0x0004, 7, 0, 0x0e);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) SERDES_AM654_CFG(0x0008, 23, 16, 0x2e);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) SERDES_AM654_CFG(0x0008, 31, 24, 0x2e);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) SERDES_AM654_CFG(0x0060, 7, 0, 0x4b);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) SERDES_AM654_CFG(0x0060, 15, 8, 0x98);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) SERDES_AM654_CFG(0x0060, 23, 16, 0x60);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) SERDES_AM654_CFG(0x00d0, 31, 24, 0x45);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) SERDES_AM654_CFG(0x00e8, 15, 8, 0x0e);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) SERDES_AM654_CFG(0x0220, 7, 0, 0x34);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) SERDES_AM654_CFG(0x0220, 15, 8, 0x34);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) SERDES_AM654_CFG(0x0220, 31, 24, 0x37);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) SERDES_AM654_CFG(0x0224, 7, 0, 0x37);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) SERDES_AM654_CFG(0x0224, 15, 8, 0x37);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) SERDES_AM654_CFG(0x0228, 23, 16, 0x37);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) SERDES_AM654_CFG(0x0228, 31, 24, 0x37);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) SERDES_AM654_CFG(0x022c, 7, 0, 0x37);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) SERDES_AM654_CFG(0x022c, 15, 8, 0x37);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) SERDES_AM654_CFG(0x0230, 15, 8, 0x2a);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) SERDES_AM654_CFG(0x0230, 23, 16, 0x2a);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) SERDES_AM654_CFG(0x0240, 23, 16, 0x10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) SERDES_AM654_CFG(0x0240, 31, 24, 0x34);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) SERDES_AM654_CFG(0x0244, 7, 0, 0x40);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) SERDES_AM654_CFG(0x0244, 23, 16, 0x34);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) SERDES_AM654_CFG(0x0248, 15, 8, 0x0d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) SERDES_AM654_CFG(0x0258, 15, 8, 0x16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) SERDES_AM654_CFG(0x0258, 23, 16, 0x84);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) SERDES_AM654_CFG(0x0258, 31, 24, 0xf2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) SERDES_AM654_CFG(0x025c, 7, 0, 0x21);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) SERDES_AM654_CFG(0x0260, 7, 0, 0x27);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) SERDES_AM654_CFG(0x0260, 15, 8, 0x04);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) SERDES_AM654_CFG(0x0268, 15, 8, 0x04);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) SERDES_AM654_CFG(0x0288, 15, 8, 0x2c);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) SERDES_AM654_CFG(0x0330, 31, 24, 0xa0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) SERDES_AM654_CFG(0x0338, 23, 16, 0x03);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) SERDES_AM654_CFG(0x0338, 31, 24, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) SERDES_AM654_CFG(0x033c, 7, 0, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) SERDES_AM654_CFG(0x0344, 31, 24, 0x18);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) SERDES_AM654_CFG(0x034c, 7, 0, 0x18);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) SERDES_AM654_CFG(0x039c, 23, 16, 0x3b);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) SERDES_AM654_CFG(0x0a04, 7, 0, 0x03);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) SERDES_AM654_CFG(0x0a14, 31, 24, 0x3c);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) SERDES_AM654_CFG(0x0a18, 15, 8, 0x3c);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) SERDES_AM654_CFG(0x0a38, 7, 0, 0x3e);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) SERDES_AM654_CFG(0x0a38, 15, 8, 0x3e);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) SERDES_AM654_CFG(0x0ae0, 7, 0, 0x07);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) SERDES_AM654_CFG(0x0b6c, 23, 16, 0xcd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) SERDES_AM654_CFG(0x0b6c, 31, 24, 0x04);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) SERDES_AM654_CFG(0x0b98, 23, 16, 0x03);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) SERDES_AM654_CFG(0x1400, 7, 0, 0x3f);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) SERDES_AM654_CFG(0x1404, 23, 16, 0x6f);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) SERDES_AM654_CFG(0x1404, 31, 24, 0x6f);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) SERDES_AM654_CFG(0x140c, 7, 0, 0x6f);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) SERDES_AM654_CFG(0x140c, 15, 8, 0x6f);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) SERDES_AM654_CFG(0x1410, 15, 8, 0x27);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) SERDES_AM654_CFG(0x1414, 7, 0, 0x0c);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) SERDES_AM654_CFG(0x1414, 23, 16, 0x07);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) SERDES_AM654_CFG(0x1418, 23, 16, 0x40);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) SERDES_AM654_CFG(0x141c, 7, 0, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) SERDES_AM654_CFG(0x141c, 15, 8, 0x1f);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) SERDES_AM654_CFG(0x1428, 31, 24, 0x08);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) SERDES_AM654_CFG(0x1434, 31, 24, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) SERDES_AM654_CFG(0x1444, 7, 0, 0x94);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) SERDES_AM654_CFG(0x1460, 31, 24, 0x7f);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) SERDES_AM654_CFG(0x1464, 7, 0, 0x43);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) SERDES_AM654_CFG(0x1464, 23, 16, 0x6f);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) SERDES_AM654_CFG(0x1464, 31, 24, 0x43);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) SERDES_AM654_CFG(0x1484, 23, 16, 0x8f);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) SERDES_AM654_CFG(0x1498, 7, 0, 0x4f);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) SERDES_AM654_CFG(0x1498, 23, 16, 0x4f);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) SERDES_AM654_CFG(0x007c, 31, 24, 0x0d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) SERDES_AM654_CFG(0x0b90, 15, 8, 0x0f);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) static int serdes_am654_pcie_init(struct serdes_am654 *phy)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) ret |= regmap_field_write(phy->fields[CMU_PLL_CTRL], 0x2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) ret |= regmap_field_write(phy->fields[AHB_PMA_CM_VCO_VBIAS_VREG], 0x98);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) ret |= regmap_field_write(phy->fields[AHB_PMA_CM_VCO_BIAS_VREG], 0x98);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) ret |= regmap_field_write(phy->fields[AHB_PMA_CM_SR], 0x45);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) ret |= regmap_field_write(phy->fields[AHB_SSC_GEN_Z_O_20_13], 0xe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) ret |= regmap_field_write(phy->fields[LANE_PLL_CTRL_RXEQ_RXIDLE], 0x5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) ret |= regmap_field_write(phy->fields[AHB_PMA_LN_AGC_THSEL_VREGH], 0x83);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) ret |= regmap_field_write(phy->fields[AHB_PMA_LN_GEN3_AGC_SD_THSEL], 0x83);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) ret |= regmap_field_write(phy->fields[AHB_PMA_LN_RX_SELR_GEN3], 0x81);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) ret |= regmap_field_write(phy->fields[AHB_PMA_LN_TX_DRV], 0x3b);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) ret |= regmap_field_write(phy->fields[P2S_RBUF_PTR_DIFF], 0x3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) ret |= regmap_field_write(phy->fields[CONFIG_VERSION], VERSION_VAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) ret |= regmap_field_write(phy->fields[COMRXEQ_MS_INIT_CTRL_7_0], 0xf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) ret |= regmap_field_write(phy->fields[COMRXEQ_HS_INIT_CAL_7_0], 0x4f);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) ret |= regmap_field_write(phy->fields[COMRXEQ_MS_RECAL_CTRL_7_0], 0xf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) ret |= regmap_field_write(phy->fields[COMRXEQ_HS_RECAL_CTRL_7_0], 0x4f);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) ret |= regmap_field_write(phy->fields[COMRXEQ_CSR_ATT_CONFIG], 0x7);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) ret |= regmap_field_write(phy->fields[COMRXEQ_CSR_EBSTADAPT_WIN_LEN], 0x7f);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) ret |= regmap_field_write(phy->fields[COMRXEQ_CTRL_3_4], 0xf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) ret |= regmap_field_write(phy->fields[COMRXEQ_CTRL_14_15_16], 0x9a);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) ret |= regmap_field_write(phy->fields[COMRXEQ_CSR_DLEV_ERR_THRESH], 0x32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) ret |= regmap_field_write(phy->fields[COMRXEQ_CTRL_25], 0x80);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) ret |= regmap_field_write(phy->fields[CSR_RXEQ_RATE_CHANGE_CAL_RUN_RATE2_O], 0xf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) ret |= regmap_field_write(phy->fields[COMRXEQ_HS_RCHANGE_CTRL_7_0], 0x4f);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) ret |= regmap_field_write(phy->fields[CMU_MASTER_CDN], 0x1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) ret |= regmap_field_write(phy->fields[L1_MASTER_CDN], 0x2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) static int serdes_am654_init(struct phy *x)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) struct serdes_am654 *phy = phy_get_drvdata(x);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) switch (phy->type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) case PHY_TYPE_PCIE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) return serdes_am654_pcie_init(phy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) case PHY_TYPE_USB3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) return serdes_am654_usb3_init(phy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) static int serdes_am654_reset(struct phy *x)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) struct serdes_am654 *phy = phy_get_drvdata(x);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) serdes_am654_disable_pll(phy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) serdes_am654_disable_txrx(phy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) ret |= regmap_field_write(phy->fields[POR_EN], 0x1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) mdelay(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) ret |= regmap_field_write(phy->fields[POR_EN], 0x0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) static void serdes_am654_release(struct phy *x)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) struct serdes_am654 *phy = phy_get_drvdata(x);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) phy->type = PHY_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) phy->busy = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) mux_control_deselect(phy->control);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) static struct phy *serdes_am654_xlate(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) struct of_phandle_args *args)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) struct serdes_am654 *am654_phy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) struct phy *phy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) phy = of_phy_simple_xlate(dev, args);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) if (IS_ERR(phy))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) return phy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) am654_phy = phy_get_drvdata(phy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) if (am654_phy->busy)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) return ERR_PTR(-EBUSY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) ret = mux_control_select(am654_phy->control, args->args[1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) dev_err(dev, "Failed to select SERDES Lane Function\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) return ERR_PTR(ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) am654_phy->busy = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) am654_phy->type = args->args[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) return phy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) static const struct phy_ops ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) .reset = serdes_am654_reset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) .init = serdes_am654_init,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) .power_on = serdes_am654_power_on,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) .power_off = serdes_am654_power_off,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) .release = serdes_am654_release,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) .owner = THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) #define SERDES_NUM_MUX_COMBINATIONS 16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) #define LICLK 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) #define EXT_REFCLK 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) #define RICLK 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) static const int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) serdes_am654_mux_table[SERDES_NUM_MUX_COMBINATIONS][SERDES_NUM_CLOCKS] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) * Each combination maps to one of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) * "Figure 12-1986. SerDes Reference Clock Distribution"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) * in TRM.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) /* Parent of CMU refclk, Left output, Right output
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) * either of EXT_REFCLK, LICLK, RICLK
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) { EXT_REFCLK, EXT_REFCLK, EXT_REFCLK }, /* 0000 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) { RICLK, EXT_REFCLK, EXT_REFCLK }, /* 0001 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) { EXT_REFCLK, RICLK, LICLK }, /* 0010 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) { RICLK, RICLK, EXT_REFCLK }, /* 0011 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) { LICLK, EXT_REFCLK, EXT_REFCLK }, /* 0100 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) { EXT_REFCLK, EXT_REFCLK, EXT_REFCLK }, /* 0101 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) { LICLK, RICLK, LICLK }, /* 0110 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) { EXT_REFCLK, RICLK, LICLK }, /* 0111 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) { EXT_REFCLK, EXT_REFCLK, LICLK }, /* 1000 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) { RICLK, EXT_REFCLK, LICLK }, /* 1001 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) { EXT_REFCLK, RICLK, EXT_REFCLK }, /* 1010 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) { RICLK, RICLK, EXT_REFCLK }, /* 1011 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) { LICLK, EXT_REFCLK, LICLK }, /* 1100 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) { EXT_REFCLK, EXT_REFCLK, LICLK }, /* 1101 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) { LICLK, RICLK, EXT_REFCLK }, /* 1110 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) { EXT_REFCLK, RICLK, EXT_REFCLK }, /* 1111 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) static u8 serdes_am654_clk_mux_get_parent(struct clk_hw *hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) struct serdes_am654_clk_mux *mux = to_serdes_am654_clk_mux(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) struct regmap *regmap = mux->regmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) unsigned int reg = mux->reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) unsigned int val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) regmap_read(regmap, reg, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) val &= AM654_SERDES_CTRL_CLKSEL_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) val >>= AM654_SERDES_CTRL_CLKSEL_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) return serdes_am654_mux_table[val][mux->clk_id];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) static int serdes_am654_clk_mux_set_parent(struct clk_hw *hw, u8 index)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) struct serdes_am654_clk_mux *mux = to_serdes_am654_clk_mux(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) struct regmap *regmap = mux->regmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) const char *name = clk_hw_get_name(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) unsigned int reg = mux->reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) int clk_id = mux->clk_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) int parents[SERDES_NUM_CLOCKS];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) const int *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) u32 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) int found, i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) /* get existing setting */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) regmap_read(regmap, reg, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) val &= AM654_SERDES_CTRL_CLKSEL_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) val >>= AM654_SERDES_CTRL_CLKSEL_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) for (i = 0; i < SERDES_NUM_CLOCKS; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) parents[i] = serdes_am654_mux_table[val][i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) /* change parent of this clock. others left intact */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) parents[clk_id] = index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) /* Find the match */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) for (val = 0; val < SERDES_NUM_MUX_COMBINATIONS; val++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) p = serdes_am654_mux_table[val];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) found = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) for (i = 0; i < SERDES_NUM_CLOCKS; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) if (parents[i] != p[i]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) found = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) if (found)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) if (!found) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) * This can never happen, unless we missed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) * a valid combination in serdes_am654_mux_table.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) WARN(1, "Failed to find the parent of %s clock\n", name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) val <<= AM654_SERDES_CTRL_CLKSEL_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) ret = regmap_update_bits(regmap, reg, AM654_SERDES_CTRL_CLKSEL_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) static const struct clk_ops serdes_am654_clk_mux_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) .set_parent = serdes_am654_clk_mux_set_parent,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) .get_parent = serdes_am654_clk_mux_get_parent,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) static int serdes_am654_clk_register(struct serdes_am654 *am654_phy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) const char *clock_name, int clock_num)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) struct device_node *node = am654_phy->of_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) struct device *dev = am654_phy->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) struct serdes_am654_clk_mux *mux;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) struct device_node *regmap_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) const char **parent_names;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) struct clk_init_data *init;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) unsigned int num_parents;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) struct regmap *regmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) const __be32 *addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) unsigned int reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) struct clk *clk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) mux = devm_kzalloc(dev, sizeof(*mux), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) if (!mux)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) init = &mux->clk_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) regmap_node = of_parse_phandle(node, "ti,serdes-clk", 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) if (!regmap_node) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) dev_err(dev, "Fail to get serdes-clk node\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) ret = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) goto out_put_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) regmap = syscon_node_to_regmap(regmap_node->parent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) if (IS_ERR(regmap)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) dev_err(dev, "Fail to get Syscon regmap\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) ret = PTR_ERR(regmap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) goto out_put_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) num_parents = of_clk_get_parent_count(node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) if (num_parents < 2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) dev_err(dev, "SERDES clock must have parents\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) goto out_put_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) parent_names = devm_kzalloc(dev, (sizeof(char *) * num_parents),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) if (!parent_names) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) goto out_put_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) of_clk_parent_fill(node, parent_names, num_parents);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) addr = of_get_address(regmap_node, 0, NULL, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) if (!addr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) goto out_put_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) reg = be32_to_cpu(*addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) init->ops = &serdes_am654_clk_mux_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) init->flags = CLK_SET_RATE_NO_REPARENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) init->parent_names = parent_names;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) init->num_parents = num_parents;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) init->name = clock_name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) mux->regmap = regmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) mux->reg = reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) mux->clk_id = clock_num;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) mux->hw.init = init;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) clk = devm_clk_register(dev, &mux->hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) if (IS_ERR(clk)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) ret = PTR_ERR(clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) goto out_put_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) am654_phy->clks[clock_num] = clk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) out_put_node:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) of_node_put(regmap_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) static const struct of_device_id serdes_am654_id_table[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) .compatible = "ti,phy-am654-serdes",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) {}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) MODULE_DEVICE_TABLE(of, serdes_am654_id_table);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) static int serdes_am654_regfield_init(struct serdes_am654 *am654_phy)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) struct regmap *regmap = am654_phy->regmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) struct device *dev = am654_phy->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) for (i = 0; i < MAX_FIELDS; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) am654_phy->fields[i] = devm_regmap_field_alloc(dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) regmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) serdes_am654_reg_fields[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) if (IS_ERR(am654_phy->fields[i])) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) dev_err(dev, "Unable to allocate regmap field %d\n", i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) return PTR_ERR(am654_phy->fields[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) static int serdes_am654_probe(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) struct phy_provider *phy_provider;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) struct device *dev = &pdev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) struct device_node *node = dev->of_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) struct clk_onecell_data *clk_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) struct serdes_am654 *am654_phy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) struct mux_control *control;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) const char *clock_name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) struct regmap *regmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) void __iomem *base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) struct phy *phy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) am654_phy = devm_kzalloc(dev, sizeof(*am654_phy), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) if (!am654_phy)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) base = devm_platform_ioremap_resource(pdev, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) if (IS_ERR(base))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) return PTR_ERR(base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) regmap = devm_regmap_init_mmio(dev, base, &serdes_am654_regmap_config);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) if (IS_ERR(regmap)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) dev_err(dev, "Failed to initialize regmap\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) return PTR_ERR(regmap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) control = devm_mux_control_get(dev, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) if (IS_ERR(control))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) return PTR_ERR(control);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) am654_phy->dev = dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) am654_phy->of_node = node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) am654_phy->regmap = regmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) am654_phy->control = control;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) am654_phy->type = PHY_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) ret = serdes_am654_regfield_init(am654_phy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) dev_err(dev, "Failed to initialize regfields\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) platform_set_drvdata(pdev, am654_phy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) for (i = 0; i < SERDES_NUM_CLOCKS; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) ret = of_property_read_string_index(node, "clock-output-names",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) i, &clock_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) dev_err(dev, "Failed to get clock name\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) ret = serdes_am654_clk_register(am654_phy, clock_name, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) dev_err(dev, "Failed to initialize clock %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) clock_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) clk_data = &am654_phy->clk_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) clk_data->clks = am654_phy->clks;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) clk_data->clk_num = SERDES_NUM_CLOCKS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) ret = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) pm_runtime_enable(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) phy = devm_phy_create(dev, NULL, &ops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) if (IS_ERR(phy)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) ret = PTR_ERR(phy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) goto clk_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) phy_set_drvdata(phy, am654_phy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) phy_provider = devm_of_phy_provider_register(dev, serdes_am654_xlate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) if (IS_ERR(phy_provider)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) ret = PTR_ERR(phy_provider);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) goto clk_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) clk_err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) of_clk_del_provider(node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) static int serdes_am654_remove(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) struct serdes_am654 *am654_phy = platform_get_drvdata(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) struct device_node *node = am654_phy->of_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) pm_runtime_disable(&pdev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) of_clk_del_provider(node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) static struct platform_driver serdes_am654_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) .probe = serdes_am654_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) .remove = serdes_am654_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) .driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) .name = "phy-am654",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) .of_match_table = serdes_am654_id_table,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) module_platform_driver(serdes_am654_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) MODULE_AUTHOR("Texas Instruments Inc.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) MODULE_DESCRIPTION("TI AM654x SERDES driver");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) MODULE_LICENSE("GPL v2");