1c589e701SYuti Amonkar // SPDX-License-Identifier: GPL-2.0-only 2c589e701SYuti Amonkar /* 392e9ccc6SSwapnil Jakhade * Cadence Torrent SD0801 PHY driver. 4c589e701SYuti Amonkar * 5c589e701SYuti Amonkar * Copyright 2018 Cadence Design Systems, Inc. 6c589e701SYuti Amonkar * 7c589e701SYuti Amonkar */ 8c589e701SYuti Amonkar 9afa4ba05SSwapnil Jakhade #include <dt-bindings/phy/phy.h> 10e4b496a3SSwapnil Jakhade #include <linux/clk.h> 11c589e701SYuti Amonkar #include <linux/delay.h> 12c589e701SYuti Amonkar #include <linux/err.h> 13c589e701SYuti Amonkar #include <linux/io.h> 14c589e701SYuti Amonkar #include <linux/iopoll.h> 15c589e701SYuti Amonkar #include <linux/kernel.h> 16c589e701SYuti Amonkar #include <linux/module.h> 17c589e701SYuti Amonkar #include <linux/of.h> 18c589e701SYuti Amonkar #include <linux/of_address.h> 19c589e701SYuti Amonkar #include <linux/of_device.h> 20c589e701SYuti Amonkar #include <linux/phy/phy.h> 21c589e701SYuti Amonkar #include <linux/platform_device.h> 22afa4ba05SSwapnil Jakhade #include <linux/reset.h> 2369d114acSSwapnil Jakhade #include <linux/regmap.h> 24c589e701SYuti Amonkar 25e4b496a3SSwapnil Jakhade #define REF_CLK_19_2MHz 19200000 26e4b496a3SSwapnil Jakhade #define REF_CLK_25MHz 25000000 27e4b496a3SSwapnil Jakhade 28e4b496a3SSwapnil Jakhade #define DEFAULT_NUM_LANES 4 29c589e701SYuti Amonkar #define MAX_NUM_LANES 4 30c589e701SYuti Amonkar #define DEFAULT_MAX_BIT_RATE 8100 /* in Mbps */ 31c589e701SYuti Amonkar 3221c79146SSwapnil Jakhade #define POLL_TIMEOUT_US 5000 3369d114acSSwapnil Jakhade 3469d114acSSwapnil Jakhade #define TORRENT_COMMON_CDB_OFFSET 0x0 3569d114acSSwapnil Jakhade 3669d114acSSwapnil Jakhade #define TORRENT_TX_LANE_CDB_OFFSET(ln, block_offset, reg_offset) \ 3769d114acSSwapnil Jakhade ((0x4000 << (block_offset)) + \ 3869d114acSSwapnil Jakhade (((ln) << 9) << (reg_offset))) 3969d114acSSwapnil Jakhade 4069d114acSSwapnil Jakhade #define TORRENT_RX_LANE_CDB_OFFSET(ln, block_offset, reg_offset) \ 4169d114acSSwapnil Jakhade ((0x8000 << (block_offset)) + \ 4269d114acSSwapnil Jakhade (((ln) << 9) << (reg_offset))) 4369d114acSSwapnil Jakhade 4469d114acSSwapnil Jakhade #define TORRENT_PHY_PCS_COMMON_OFFSET(block_offset) \ 4569d114acSSwapnil Jakhade (0xC000 << (block_offset)) 4669d114acSSwapnil Jakhade 4769d114acSSwapnil Jakhade #define TORRENT_PHY_PMA_COMMON_OFFSET(block_offset) \ 4869d114acSSwapnil Jakhade (0xE000 << (block_offset)) 49c589e701SYuti Amonkar 50cba472ecSSwapnil Jakhade #define TORRENT_DPTX_PHY_OFFSET 0x0 51cba472ecSSwapnil Jakhade 52c589e701SYuti Amonkar /* 53c589e701SYuti Amonkar * register offsets from DPTX PHY register block base (i.e MHDP 54c589e701SYuti Amonkar * register base + 0x30a00) 55c589e701SYuti Amonkar */ 56c589e701SYuti Amonkar #define PHY_AUX_CTRL 0x04 57c589e701SYuti Amonkar #define PHY_RESET 0x20 58572d6592SSwapnil Jakhade #define PMA_TX_ELEC_IDLE_MASK 0xF0U 59572d6592SSwapnil Jakhade #define PMA_TX_ELEC_IDLE_SHIFT 4 60572d6592SSwapnil Jakhade #define PHY_L00_RESET_N_MASK 0x01U 61c589e701SYuti Amonkar #define PHY_PMA_XCVR_PLLCLK_EN 0x24 62c589e701SYuti Amonkar #define PHY_PMA_XCVR_PLLCLK_EN_ACK 0x28 63c589e701SYuti Amonkar #define PHY_PMA_XCVR_POWER_STATE_REQ 0x2c 64c589e701SYuti Amonkar #define PHY_POWER_STATE_LN_0 0x0000 65c589e701SYuti Amonkar #define PHY_POWER_STATE_LN_1 0x0008 66c589e701SYuti Amonkar #define PHY_POWER_STATE_LN_2 0x0010 67c589e701SYuti Amonkar #define PHY_POWER_STATE_LN_3 0x0018 6821c79146SSwapnil Jakhade #define PMA_XCVR_POWER_STATE_REQ_LN_MASK 0x3FU 69c589e701SYuti Amonkar #define PHY_PMA_XCVR_POWER_STATE_ACK 0x30 70c589e701SYuti Amonkar #define PHY_PMA_CMN_READY 0x34 71c589e701SYuti Amonkar 72c589e701SYuti Amonkar /* 73c589e701SYuti Amonkar * register offsets from SD0801 PHY register block base (i.e MHDP 74c589e701SYuti Amonkar * register base + 0x500000) 75c589e701SYuti Amonkar */ 7669d114acSSwapnil Jakhade #define CMN_SSM_BANDGAP_TMR 0x0021U 7769d114acSSwapnil Jakhade #define CMN_SSM_BIAS_TMR 0x0022U 7869d114acSSwapnil Jakhade #define CMN_PLLSM0_PLLPRE_TMR 0x002AU 7969d114acSSwapnil Jakhade #define CMN_PLLSM0_PLLLOCK_TMR 0x002CU 8069d114acSSwapnil Jakhade #define CMN_PLLSM1_PLLPRE_TMR 0x0032U 8169d114acSSwapnil Jakhade #define CMN_PLLSM1_PLLLOCK_TMR 0x0034U 8269d114acSSwapnil Jakhade #define CMN_BGCAL_INIT_TMR 0x0064U 8369d114acSSwapnil Jakhade #define CMN_BGCAL_ITER_TMR 0x0065U 8469d114acSSwapnil Jakhade #define CMN_IBCAL_INIT_TMR 0x0074U 8569d114acSSwapnil Jakhade #define CMN_PLL0_VCOCAL_TCTRL 0x0082U 8669d114acSSwapnil Jakhade #define CMN_PLL0_VCOCAL_INIT_TMR 0x0084U 8769d114acSSwapnil Jakhade #define CMN_PLL0_VCOCAL_ITER_TMR 0x0085U 8869d114acSSwapnil Jakhade #define CMN_PLL0_VCOCAL_REFTIM_START 0x0086U 8969d114acSSwapnil Jakhade #define CMN_PLL0_VCOCAL_PLLCNT_START 0x0088U 9069d114acSSwapnil Jakhade #define CMN_PLL0_INTDIV_M0 0x0090U 9169d114acSSwapnil Jakhade #define CMN_PLL0_FRACDIVL_M0 0x0091U 9269d114acSSwapnil Jakhade #define CMN_PLL0_FRACDIVH_M0 0x0092U 9369d114acSSwapnil Jakhade #define CMN_PLL0_HIGH_THR_M0 0x0093U 9469d114acSSwapnil Jakhade #define CMN_PLL0_DSM_DIAG_M0 0x0094U 9569d114acSSwapnil Jakhade #define CMN_PLL0_SS_CTRL1_M0 0x0098U 9669d114acSSwapnil Jakhade #define CMN_PLL0_SS_CTRL2_M0 0x0099U 9769d114acSSwapnil Jakhade #define CMN_PLL0_SS_CTRL3_M0 0x009AU 9869d114acSSwapnil Jakhade #define CMN_PLL0_SS_CTRL4_M0 0x009BU 9969d114acSSwapnil Jakhade #define CMN_PLL0_LOCK_REFCNT_START 0x009CU 10069d114acSSwapnil Jakhade #define CMN_PLL0_LOCK_PLLCNT_START 0x009EU 10169d114acSSwapnil Jakhade #define CMN_PLL0_LOCK_PLLCNT_THR 0x009FU 10269d114acSSwapnil Jakhade #define CMN_PLL1_VCOCAL_TCTRL 0x00C2U 10369d114acSSwapnil Jakhade #define CMN_PLL1_VCOCAL_INIT_TMR 0x00C4U 10469d114acSSwapnil Jakhade #define CMN_PLL1_VCOCAL_ITER_TMR 0x00C5U 10569d114acSSwapnil Jakhade #define CMN_PLL1_VCOCAL_REFTIM_START 0x00C6U 10669d114acSSwapnil Jakhade #define CMN_PLL1_VCOCAL_PLLCNT_START 0x00C8U 10769d114acSSwapnil Jakhade #define CMN_PLL1_INTDIV_M0 0x00D0U 10869d114acSSwapnil Jakhade #define CMN_PLL1_FRACDIVL_M0 0x00D1U 10969d114acSSwapnil Jakhade #define CMN_PLL1_FRACDIVH_M0 0x00D2U 11069d114acSSwapnil Jakhade #define CMN_PLL1_HIGH_THR_M0 0x00D3U 11169d114acSSwapnil Jakhade #define CMN_PLL1_DSM_DIAG_M0 0x00D4U 11269d114acSSwapnil Jakhade #define CMN_PLL1_SS_CTRL1_M0 0x00D8U 11369d114acSSwapnil Jakhade #define CMN_PLL1_SS_CTRL2_M0 0x00D9U 11469d114acSSwapnil Jakhade #define CMN_PLL1_SS_CTRL3_M0 0x00DAU 11569d114acSSwapnil Jakhade #define CMN_PLL1_SS_CTRL4_M0 0x00DBU 11669d114acSSwapnil Jakhade #define CMN_PLL1_LOCK_REFCNT_START 0x00DCU 11769d114acSSwapnil Jakhade #define CMN_PLL1_LOCK_PLLCNT_START 0x00DEU 11869d114acSSwapnil Jakhade #define CMN_PLL1_LOCK_PLLCNT_THR 0x00DFU 11969d114acSSwapnil Jakhade #define CMN_TXPUCAL_INIT_TMR 0x0104U 12069d114acSSwapnil Jakhade #define CMN_TXPUCAL_ITER_TMR 0x0105U 12169d114acSSwapnil Jakhade #define CMN_TXPDCAL_INIT_TMR 0x010CU 12269d114acSSwapnil Jakhade #define CMN_TXPDCAL_ITER_TMR 0x010DU 12369d114acSSwapnil Jakhade #define CMN_RXCAL_INIT_TMR 0x0114U 12469d114acSSwapnil Jakhade #define CMN_RXCAL_ITER_TMR 0x0115U 12569d114acSSwapnil Jakhade #define CMN_SD_CAL_INIT_TMR 0x0124U 12669d114acSSwapnil Jakhade #define CMN_SD_CAL_ITER_TMR 0x0125U 12769d114acSSwapnil Jakhade #define CMN_SD_CAL_REFTIM_START 0x0126U 12869d114acSSwapnil Jakhade #define CMN_SD_CAL_PLLCNT_START 0x0128U 12969d114acSSwapnil Jakhade #define CMN_PDIAG_PLL0_CTRL_M0 0x01A0U 13069d114acSSwapnil Jakhade #define CMN_PDIAG_PLL0_CLK_SEL_M0 0x01A1U 13169d114acSSwapnil Jakhade #define CMN_PDIAG_PLL0_CP_PADJ_M0 0x01A4U 13269d114acSSwapnil Jakhade #define CMN_PDIAG_PLL0_CP_IADJ_M0 0x01A5U 13369d114acSSwapnil Jakhade #define CMN_PDIAG_PLL0_FILT_PADJ_M0 0x01A6U 13469d114acSSwapnil Jakhade #define CMN_PDIAG_PLL0_CP_PADJ_M1 0x01B4U 13569d114acSSwapnil Jakhade #define CMN_PDIAG_PLL0_CP_IADJ_M1 0x01B5U 13669d114acSSwapnil Jakhade #define CMN_PDIAG_PLL1_CTRL_M0 0x01C0U 13769d114acSSwapnil Jakhade #define CMN_PDIAG_PLL1_CLK_SEL_M0 0x01C1U 13869d114acSSwapnil Jakhade #define CMN_PDIAG_PLL1_CP_PADJ_M0 0x01C4U 13969d114acSSwapnil Jakhade #define CMN_PDIAG_PLL1_CP_IADJ_M0 0x01C5U 14069d114acSSwapnil Jakhade #define CMN_PDIAG_PLL1_FILT_PADJ_M0 0x01C6U 141e4b496a3SSwapnil Jakhade 14269d114acSSwapnil Jakhade /* PMA TX Lane registers */ 14369d114acSSwapnil Jakhade #define TX_TXCC_CTRL 0x0040U 14469d114acSSwapnil Jakhade #define TX_TXCC_CPOST_MULT_00 0x004CU 14569d114acSSwapnil Jakhade #define TX_TXCC_MGNFS_MULT_000 0x0050U 14669d114acSSwapnil Jakhade #define DRV_DIAG_TX_DRV 0x00C6U 14769d114acSSwapnil Jakhade #define XCVR_DIAG_PLLDRC_CTRL 0x00E5U 14869d114acSSwapnil Jakhade #define XCVR_DIAG_HSCLK_SEL 0x00E6U 14969d114acSSwapnil Jakhade #define XCVR_DIAG_HSCLK_DIV 0x00E7U 15069d114acSSwapnil Jakhade #define XCVR_DIAG_BIDI_CTRL 0x00EAU 15169d114acSSwapnil Jakhade #define TX_PSC_A0 0x0100U 15269d114acSSwapnil Jakhade #define TX_PSC_A2 0x0102U 15369d114acSSwapnil Jakhade #define TX_PSC_A3 0x0103U 15469d114acSSwapnil Jakhade #define TX_RCVDET_ST_TMR 0x0123U 15569d114acSSwapnil Jakhade #define TX_DIAG_ACYA 0x01E7U 156572d6592SSwapnil Jakhade #define TX_DIAG_ACYA_HBDC_MASK 0x0001U 157e4b496a3SSwapnil Jakhade 15869d114acSSwapnil Jakhade /* PMA RX Lane registers */ 15969d114acSSwapnil Jakhade #define RX_PSC_A0 0x0000U 16069d114acSSwapnil Jakhade #define RX_PSC_A2 0x0002U 16169d114acSSwapnil Jakhade #define RX_PSC_A3 0x0003U 16269d114acSSwapnil Jakhade #define RX_PSC_CAL 0x0006U 16369d114acSSwapnil Jakhade #define RX_REE_GCSM1_CTRL 0x0108U 16469d114acSSwapnil Jakhade #define RX_REE_GCSM2_CTRL 0x0110U 16569d114acSSwapnil Jakhade #define RX_REE_PERGCSM_CTRL 0x0118U 166c589e701SYuti Amonkar 16769d114acSSwapnil Jakhade /* PHY PCS common registers */ 16869d114acSSwapnil Jakhade #define PHY_PLL_CFG 0x000EU 16969d114acSSwapnil Jakhade 17069d114acSSwapnil Jakhade /* PHY PMA common registers */ 17169d114acSSwapnil Jakhade #define PHY_PMA_CMN_CTRL2 0x0001U 17269d114acSSwapnil Jakhade #define PHY_PMA_PLL_RAW_CTRL 0x0003U 17369d114acSSwapnil Jakhade 17469d114acSSwapnil Jakhade static const struct reg_field phy_pll_cfg = 17569d114acSSwapnil Jakhade REG_FIELD(PHY_PLL_CFG, 0, 1); 17669d114acSSwapnil Jakhade 17769d114acSSwapnil Jakhade static const struct reg_field phy_pma_cmn_ctrl_2 = 17869d114acSSwapnil Jakhade REG_FIELD(PHY_PMA_CMN_CTRL2, 0, 7); 17969d114acSSwapnil Jakhade 18069d114acSSwapnil Jakhade static const struct reg_field phy_pma_pll_raw_ctrl = 18169d114acSSwapnil Jakhade REG_FIELD(PHY_PMA_PLL_RAW_CTRL, 0, 1); 18269d114acSSwapnil Jakhade 183cba472ecSSwapnil Jakhade static const struct reg_field phy_reset_ctrl = 184cba472ecSSwapnil Jakhade REG_FIELD(PHY_RESET, 8, 8); 185cba472ecSSwapnil Jakhade 186afa4ba05SSwapnil Jakhade struct cdns_torrent_inst { 187afa4ba05SSwapnil Jakhade struct phy *phy; 188afa4ba05SSwapnil Jakhade u32 mlane; 189afa4ba05SSwapnil Jakhade u32 phy_type; 190afa4ba05SSwapnil Jakhade u32 num_lanes; 191afa4ba05SSwapnil Jakhade struct reset_control *lnk_rst; 192afa4ba05SSwapnil Jakhade }; 193afa4ba05SSwapnil Jakhade 19492e9ccc6SSwapnil Jakhade struct cdns_torrent_phy { 195c589e701SYuti Amonkar void __iomem *base; /* DPTX registers base */ 196c589e701SYuti Amonkar void __iomem *sd_base; /* SD0801 registers base */ 197c589e701SYuti Amonkar u32 max_bit_rate; /* Maximum link bit rate to use (in Mbps) */ 198afa4ba05SSwapnil Jakhade struct reset_control *phy_rst; 199c589e701SYuti Amonkar struct device *dev; 200e4b496a3SSwapnil Jakhade struct clk *clk; 201e4b496a3SSwapnil Jakhade unsigned long ref_clk_rate; 202afa4ba05SSwapnil Jakhade struct cdns_torrent_inst phys[MAX_NUM_LANES]; 203afa4ba05SSwapnil Jakhade int nsubnodes; 204*29d1fd2fSSwapnil Jakhade const struct cdns_torrent_data *init_data; 20569d114acSSwapnil Jakhade struct regmap *regmap; 20669d114acSSwapnil Jakhade struct regmap *regmap_common_cdb; 20769d114acSSwapnil Jakhade struct regmap *regmap_phy_pcs_common_cdb; 20869d114acSSwapnil Jakhade struct regmap *regmap_phy_pma_common_cdb; 20969d114acSSwapnil Jakhade struct regmap *regmap_tx_lane_cdb[MAX_NUM_LANES]; 21069d114acSSwapnil Jakhade struct regmap *regmap_rx_lane_cdb[MAX_NUM_LANES]; 211cba472ecSSwapnil Jakhade struct regmap *regmap_dptx_phy_reg; 21269d114acSSwapnil Jakhade struct regmap_field *phy_pll_cfg; 21369d114acSSwapnil Jakhade struct regmap_field *phy_pma_cmn_ctrl_2; 21469d114acSSwapnil Jakhade struct regmap_field *phy_pma_pll_raw_ctrl; 215cba472ecSSwapnil Jakhade struct regmap_field *phy_reset_ctrl; 216c589e701SYuti Amonkar }; 217c589e701SYuti Amonkar 21821c79146SSwapnil Jakhade enum phy_powerstate { 21921c79146SSwapnil Jakhade POWERSTATE_A0 = 0, 22021c79146SSwapnil Jakhade /* Powerstate A1 is unused */ 22121c79146SSwapnil Jakhade POWERSTATE_A2 = 2, 22221c79146SSwapnil Jakhade POWERSTATE_A3 = 3, 22321c79146SSwapnil Jakhade }; 22421c79146SSwapnil Jakhade 22592e9ccc6SSwapnil Jakhade static int cdns_torrent_dp_init(struct phy *phy); 226e4b496a3SSwapnil Jakhade static int cdns_torrent_dp_exit(struct phy *phy); 227572d6592SSwapnil Jakhade static int cdns_torrent_dp_run(struct cdns_torrent_phy *cdns_phy, 228572d6592SSwapnil Jakhade u32 num_lanes); 22992e9ccc6SSwapnil Jakhade static 23021c79146SSwapnil Jakhade int cdns_torrent_dp_wait_pma_cmn_ready(struct cdns_torrent_phy *cdns_phy); 231afa4ba05SSwapnil Jakhade static void cdns_torrent_dp_pma_cfg(struct cdns_torrent_phy *cdns_phy, 232afa4ba05SSwapnil Jakhade struct cdns_torrent_inst *inst); 23392e9ccc6SSwapnil Jakhade static 234e4b496a3SSwapnil Jakhade void cdns_torrent_dp_pma_cmn_cfg_19_2mhz(struct cdns_torrent_phy *cdns_phy); 235e4b496a3SSwapnil Jakhade static 236e4b496a3SSwapnil Jakhade void cdns_torrent_dp_pma_cmn_vco_cfg_19_2mhz(struct cdns_torrent_phy *cdns_phy, 237e4b496a3SSwapnil Jakhade u32 rate, bool ssc); 238e4b496a3SSwapnil Jakhade static 23992e9ccc6SSwapnil Jakhade void cdns_torrent_dp_pma_cmn_cfg_25mhz(struct cdns_torrent_phy *cdns_phy); 240e4b496a3SSwapnil Jakhade static 241e4b496a3SSwapnil Jakhade void cdns_torrent_dp_pma_cmn_vco_cfg_25mhz(struct cdns_torrent_phy *cdns_phy, 242e4b496a3SSwapnil Jakhade u32 rate, bool ssc); 24392e9ccc6SSwapnil Jakhade static void cdns_torrent_dp_pma_lane_cfg(struct cdns_torrent_phy *cdns_phy, 244c589e701SYuti Amonkar unsigned int lane); 245e4b496a3SSwapnil Jakhade static void cdns_torrent_dp_pma_cmn_rate(struct cdns_torrent_phy *cdns_phy, 246e4b496a3SSwapnil Jakhade u32 rate, u32 num_lanes); 247572d6592SSwapnil Jakhade static int cdns_torrent_dp_configure(struct phy *phy, 248572d6592SSwapnil Jakhade union phy_configure_opts *opts); 249572d6592SSwapnil Jakhade static int cdns_torrent_dp_set_power_state(struct cdns_torrent_phy *cdns_phy, 250572d6592SSwapnil Jakhade u32 num_lanes, 251572d6592SSwapnil Jakhade enum phy_powerstate powerstate); 252afa4ba05SSwapnil Jakhade static int cdns_torrent_phy_on(struct phy *phy); 253afa4ba05SSwapnil Jakhade static int cdns_torrent_phy_off(struct phy *phy); 254572d6592SSwapnil Jakhade 25592e9ccc6SSwapnil Jakhade static const struct phy_ops cdns_torrent_phy_ops = { 25692e9ccc6SSwapnil Jakhade .init = cdns_torrent_dp_init, 257e4b496a3SSwapnil Jakhade .exit = cdns_torrent_dp_exit, 258572d6592SSwapnil Jakhade .configure = cdns_torrent_dp_configure, 259afa4ba05SSwapnil Jakhade .power_on = cdns_torrent_phy_on, 260afa4ba05SSwapnil Jakhade .power_off = cdns_torrent_phy_off, 261c589e701SYuti Amonkar .owner = THIS_MODULE, 262c589e701SYuti Amonkar }; 263c589e701SYuti Amonkar 26469d114acSSwapnil Jakhade struct cdns_torrent_data { 26569d114acSSwapnil Jakhade u8 block_offset_shift; 26669d114acSSwapnil Jakhade u8 reg_offset_shift; 26769d114acSSwapnil Jakhade }; 26869d114acSSwapnil Jakhade 26969d114acSSwapnil Jakhade struct cdns_regmap_cdb_context { 27069d114acSSwapnil Jakhade struct device *dev; 27169d114acSSwapnil Jakhade void __iomem *base; 27269d114acSSwapnil Jakhade u8 reg_offset_shift; 27369d114acSSwapnil Jakhade }; 27469d114acSSwapnil Jakhade 27569d114acSSwapnil Jakhade static int cdns_regmap_write(void *context, unsigned int reg, unsigned int val) 27669d114acSSwapnil Jakhade { 27769d114acSSwapnil Jakhade struct cdns_regmap_cdb_context *ctx = context; 27869d114acSSwapnil Jakhade u32 offset = reg << ctx->reg_offset_shift; 27969d114acSSwapnil Jakhade 28069d114acSSwapnil Jakhade writew(val, ctx->base + offset); 28169d114acSSwapnil Jakhade 28269d114acSSwapnil Jakhade return 0; 28369d114acSSwapnil Jakhade } 28469d114acSSwapnil Jakhade 28569d114acSSwapnil Jakhade static int cdns_regmap_read(void *context, unsigned int reg, unsigned int *val) 28669d114acSSwapnil Jakhade { 28769d114acSSwapnil Jakhade struct cdns_regmap_cdb_context *ctx = context; 28869d114acSSwapnil Jakhade u32 offset = reg << ctx->reg_offset_shift; 28969d114acSSwapnil Jakhade 29069d114acSSwapnil Jakhade *val = readw(ctx->base + offset); 29169d114acSSwapnil Jakhade return 0; 29269d114acSSwapnil Jakhade } 29369d114acSSwapnil Jakhade 294cba472ecSSwapnil Jakhade static int cdns_regmap_dptx_write(void *context, unsigned int reg, 295cba472ecSSwapnil Jakhade unsigned int val) 296cba472ecSSwapnil Jakhade { 297cba472ecSSwapnil Jakhade struct cdns_regmap_cdb_context *ctx = context; 298cba472ecSSwapnil Jakhade u32 offset = reg; 299cba472ecSSwapnil Jakhade 300cba472ecSSwapnil Jakhade writel(val, ctx->base + offset); 301cba472ecSSwapnil Jakhade 302cba472ecSSwapnil Jakhade return 0; 303cba472ecSSwapnil Jakhade } 304cba472ecSSwapnil Jakhade 305cba472ecSSwapnil Jakhade static int cdns_regmap_dptx_read(void *context, unsigned int reg, 306cba472ecSSwapnil Jakhade unsigned int *val) 307cba472ecSSwapnil Jakhade { 308cba472ecSSwapnil Jakhade struct cdns_regmap_cdb_context *ctx = context; 309cba472ecSSwapnil Jakhade u32 offset = reg; 310cba472ecSSwapnil Jakhade 311cba472ecSSwapnil Jakhade *val = readl(ctx->base + offset); 312cba472ecSSwapnil Jakhade return 0; 313cba472ecSSwapnil Jakhade } 314cba472ecSSwapnil Jakhade 31569d114acSSwapnil Jakhade #define TORRENT_TX_LANE_CDB_REGMAP_CONF(n) \ 31669d114acSSwapnil Jakhade { \ 31769d114acSSwapnil Jakhade .name = "torrent_tx_lane" n "_cdb", \ 31869d114acSSwapnil Jakhade .reg_stride = 1, \ 31969d114acSSwapnil Jakhade .fast_io = true, \ 32069d114acSSwapnil Jakhade .reg_write = cdns_regmap_write, \ 32169d114acSSwapnil Jakhade .reg_read = cdns_regmap_read, \ 32269d114acSSwapnil Jakhade } 32369d114acSSwapnil Jakhade 32469d114acSSwapnil Jakhade #define TORRENT_RX_LANE_CDB_REGMAP_CONF(n) \ 32569d114acSSwapnil Jakhade { \ 32669d114acSSwapnil Jakhade .name = "torrent_rx_lane" n "_cdb", \ 32769d114acSSwapnil Jakhade .reg_stride = 1, \ 32869d114acSSwapnil Jakhade .fast_io = true, \ 32969d114acSSwapnil Jakhade .reg_write = cdns_regmap_write, \ 33069d114acSSwapnil Jakhade .reg_read = cdns_regmap_read, \ 33169d114acSSwapnil Jakhade } 33269d114acSSwapnil Jakhade 33357d39c76SRikard Falkeborn static const struct regmap_config cdns_torrent_tx_lane_cdb_config[] = { 33469d114acSSwapnil Jakhade TORRENT_TX_LANE_CDB_REGMAP_CONF("0"), 33569d114acSSwapnil Jakhade TORRENT_TX_LANE_CDB_REGMAP_CONF("1"), 33669d114acSSwapnil Jakhade TORRENT_TX_LANE_CDB_REGMAP_CONF("2"), 33769d114acSSwapnil Jakhade TORRENT_TX_LANE_CDB_REGMAP_CONF("3"), 33869d114acSSwapnil Jakhade }; 33969d114acSSwapnil Jakhade 34057d39c76SRikard Falkeborn static const struct regmap_config cdns_torrent_rx_lane_cdb_config[] = { 34169d114acSSwapnil Jakhade TORRENT_RX_LANE_CDB_REGMAP_CONF("0"), 34269d114acSSwapnil Jakhade TORRENT_RX_LANE_CDB_REGMAP_CONF("1"), 34369d114acSSwapnil Jakhade TORRENT_RX_LANE_CDB_REGMAP_CONF("2"), 34469d114acSSwapnil Jakhade TORRENT_RX_LANE_CDB_REGMAP_CONF("3"), 34569d114acSSwapnil Jakhade }; 34669d114acSSwapnil Jakhade 34757d39c76SRikard Falkeborn static const struct regmap_config cdns_torrent_common_cdb_config = { 34869d114acSSwapnil Jakhade .name = "torrent_common_cdb", 34969d114acSSwapnil Jakhade .reg_stride = 1, 35069d114acSSwapnil Jakhade .fast_io = true, 35169d114acSSwapnil Jakhade .reg_write = cdns_regmap_write, 35269d114acSSwapnil Jakhade .reg_read = cdns_regmap_read, 35369d114acSSwapnil Jakhade }; 35469d114acSSwapnil Jakhade 35557d39c76SRikard Falkeborn static const struct regmap_config cdns_torrent_phy_pcs_cmn_cdb_config = { 35669d114acSSwapnil Jakhade .name = "torrent_phy_pcs_cmn_cdb", 35769d114acSSwapnil Jakhade .reg_stride = 1, 35869d114acSSwapnil Jakhade .fast_io = true, 35969d114acSSwapnil Jakhade .reg_write = cdns_regmap_write, 36069d114acSSwapnil Jakhade .reg_read = cdns_regmap_read, 36169d114acSSwapnil Jakhade }; 36269d114acSSwapnil Jakhade 36357d39c76SRikard Falkeborn static const struct regmap_config cdns_torrent_phy_pma_cmn_cdb_config = { 36469d114acSSwapnil Jakhade .name = "torrent_phy_pma_cmn_cdb", 36569d114acSSwapnil Jakhade .reg_stride = 1, 36669d114acSSwapnil Jakhade .fast_io = true, 36769d114acSSwapnil Jakhade .reg_write = cdns_regmap_write, 36869d114acSSwapnil Jakhade .reg_read = cdns_regmap_read, 36969d114acSSwapnil Jakhade }; 37069d114acSSwapnil Jakhade 37157d39c76SRikard Falkeborn static const struct regmap_config cdns_torrent_dptx_phy_config = { 372cba472ecSSwapnil Jakhade .name = "torrent_dptx_phy", 373cba472ecSSwapnil Jakhade .reg_stride = 1, 374cba472ecSSwapnil Jakhade .fast_io = true, 375cba472ecSSwapnil Jakhade .reg_write = cdns_regmap_dptx_write, 376cba472ecSSwapnil Jakhade .reg_read = cdns_regmap_dptx_read, 377cba472ecSSwapnil Jakhade }; 378cba472ecSSwapnil Jakhade 379ccb1b89dSSwapnil Jakhade /* PHY mmr access functions */ 380ccb1b89dSSwapnil Jakhade 38169d114acSSwapnil Jakhade static void cdns_torrent_phy_write(struct regmap *regmap, u32 offset, u32 val) 382ccb1b89dSSwapnil Jakhade { 38369d114acSSwapnil Jakhade regmap_write(regmap, offset, val); 384ccb1b89dSSwapnil Jakhade } 385ccb1b89dSSwapnil Jakhade 38669d114acSSwapnil Jakhade static u32 cdns_torrent_phy_read(struct regmap *regmap, u32 offset) 387572d6592SSwapnil Jakhade { 38869d114acSSwapnil Jakhade unsigned int val; 389572d6592SSwapnil Jakhade 39069d114acSSwapnil Jakhade regmap_read(regmap, offset, &val); 39169d114acSSwapnil Jakhade return val; 39269d114acSSwapnil Jakhade } 393572d6592SSwapnil Jakhade 394f61b3aedSSwapnil Jakhade /* DPTX mmr access functions */ 395f61b3aedSSwapnil Jakhade 396cba472ecSSwapnil Jakhade static void cdns_torrent_dp_write(struct regmap *regmap, u32 offset, u32 val) 397f61b3aedSSwapnil Jakhade { 398cba472ecSSwapnil Jakhade regmap_write(regmap, offset, val); 399f61b3aedSSwapnil Jakhade } 400f61b3aedSSwapnil Jakhade 401cba472ecSSwapnil Jakhade static u32 cdns_torrent_dp_read(struct regmap *regmap, u32 offset) 402f61b3aedSSwapnil Jakhade { 403cba472ecSSwapnil Jakhade u32 val; 404f61b3aedSSwapnil Jakhade 405cba472ecSSwapnil Jakhade regmap_read(regmap, offset, &val); 406cba472ecSSwapnil Jakhade return val; 407cba472ecSSwapnil Jakhade } 408f61b3aedSSwapnil Jakhade 409572d6592SSwapnil Jakhade /* 410572d6592SSwapnil Jakhade * Structure used to store values of PHY registers for voltage-related 411572d6592SSwapnil Jakhade * coefficients, for particular voltage swing and pre-emphasis level. Values 412572d6592SSwapnil Jakhade * are shared across all physical lanes. 413572d6592SSwapnil Jakhade */ 414572d6592SSwapnil Jakhade struct coefficients { 415572d6592SSwapnil Jakhade /* Value of DRV_DIAG_TX_DRV register to use */ 416572d6592SSwapnil Jakhade u16 diag_tx_drv; 417572d6592SSwapnil Jakhade /* Value of TX_TXCC_MGNFS_MULT_000 register to use */ 418572d6592SSwapnil Jakhade u16 mgnfs_mult; 419572d6592SSwapnil Jakhade /* Value of TX_TXCC_CPOST_MULT_00 register to use */ 420572d6592SSwapnil Jakhade u16 cpost_mult; 421572d6592SSwapnil Jakhade }; 422572d6592SSwapnil Jakhade 423572d6592SSwapnil Jakhade /* 424572d6592SSwapnil Jakhade * Array consists of values of voltage-related registers for sd0801 PHY. A value 425572d6592SSwapnil Jakhade * of 0xFFFF is a placeholder for invalid combination, and will never be used. 426572d6592SSwapnil Jakhade */ 427572d6592SSwapnil Jakhade static const struct coefficients vltg_coeff[4][4] = { 428572d6592SSwapnil Jakhade /* voltage swing 0, pre-emphasis 0->3 */ 429572d6592SSwapnil Jakhade { {.diag_tx_drv = 0x0003, .mgnfs_mult = 0x002A, 430572d6592SSwapnil Jakhade .cpost_mult = 0x0000}, 431572d6592SSwapnil Jakhade {.diag_tx_drv = 0x0003, .mgnfs_mult = 0x001F, 432572d6592SSwapnil Jakhade .cpost_mult = 0x0014}, 433572d6592SSwapnil Jakhade {.diag_tx_drv = 0x0003, .mgnfs_mult = 0x0012, 434572d6592SSwapnil Jakhade .cpost_mult = 0x0020}, 435572d6592SSwapnil Jakhade {.diag_tx_drv = 0x0003, .mgnfs_mult = 0x0000, 436572d6592SSwapnil Jakhade .cpost_mult = 0x002A} 437572d6592SSwapnil Jakhade }, 438572d6592SSwapnil Jakhade 439572d6592SSwapnil Jakhade /* voltage swing 1, pre-emphasis 0->3 */ 440572d6592SSwapnil Jakhade { {.diag_tx_drv = 0x0003, .mgnfs_mult = 0x001F, 441572d6592SSwapnil Jakhade .cpost_mult = 0x0000}, 442572d6592SSwapnil Jakhade {.diag_tx_drv = 0x0003, .mgnfs_mult = 0x0013, 443572d6592SSwapnil Jakhade .cpost_mult = 0x0012}, 444572d6592SSwapnil Jakhade {.diag_tx_drv = 0x0003, .mgnfs_mult = 0x0000, 445572d6592SSwapnil Jakhade .cpost_mult = 0x001F}, 446572d6592SSwapnil Jakhade {.diag_tx_drv = 0xFFFF, .mgnfs_mult = 0xFFFF, 447572d6592SSwapnil Jakhade .cpost_mult = 0xFFFF} 448572d6592SSwapnil Jakhade }, 449572d6592SSwapnil Jakhade 450572d6592SSwapnil Jakhade /* voltage swing 2, pre-emphasis 0->3 */ 451572d6592SSwapnil Jakhade { {.diag_tx_drv = 0x0003, .mgnfs_mult = 0x0013, 452572d6592SSwapnil Jakhade .cpost_mult = 0x0000}, 453572d6592SSwapnil Jakhade {.diag_tx_drv = 0x0003, .mgnfs_mult = 0x0000, 454572d6592SSwapnil Jakhade .cpost_mult = 0x0013}, 455572d6592SSwapnil Jakhade {.diag_tx_drv = 0xFFFF, .mgnfs_mult = 0xFFFF, 456572d6592SSwapnil Jakhade .cpost_mult = 0xFFFF}, 457572d6592SSwapnil Jakhade {.diag_tx_drv = 0xFFFF, .mgnfs_mult = 0xFFFF, 458572d6592SSwapnil Jakhade .cpost_mult = 0xFFFF} 459572d6592SSwapnil Jakhade }, 460572d6592SSwapnil Jakhade 461572d6592SSwapnil Jakhade /* voltage swing 3, pre-emphasis 0->3 */ 462572d6592SSwapnil Jakhade { {.diag_tx_drv = 0x0003, .mgnfs_mult = 0x0000, 463572d6592SSwapnil Jakhade .cpost_mult = 0x0000}, 464572d6592SSwapnil Jakhade {.diag_tx_drv = 0xFFFF, .mgnfs_mult = 0xFFFF, 465572d6592SSwapnil Jakhade .cpost_mult = 0xFFFF}, 466572d6592SSwapnil Jakhade {.diag_tx_drv = 0xFFFF, .mgnfs_mult = 0xFFFF, 467572d6592SSwapnil Jakhade .cpost_mult = 0xFFFF}, 468572d6592SSwapnil Jakhade {.diag_tx_drv = 0xFFFF, .mgnfs_mult = 0xFFFF, 469572d6592SSwapnil Jakhade .cpost_mult = 0xFFFF} 470572d6592SSwapnil Jakhade } 471572d6592SSwapnil Jakhade }; 472572d6592SSwapnil Jakhade 473572d6592SSwapnil Jakhade /* 474572d6592SSwapnil Jakhade * Enable or disable PLL for selected lanes. 475572d6592SSwapnil Jakhade */ 476572d6592SSwapnil Jakhade static int cdns_torrent_dp_set_pll_en(struct cdns_torrent_phy *cdns_phy, 477572d6592SSwapnil Jakhade struct phy_configure_opts_dp *dp, 478572d6592SSwapnil Jakhade bool enable) 479572d6592SSwapnil Jakhade { 480572d6592SSwapnil Jakhade u32 rd_val; 481572d6592SSwapnil Jakhade u32 ret; 482cba472ecSSwapnil Jakhade struct regmap *regmap = cdns_phy->regmap_dptx_phy_reg; 483cba472ecSSwapnil Jakhade 484572d6592SSwapnil Jakhade /* 485572d6592SSwapnil Jakhade * Used to determine, which bits to check for or enable in 486572d6592SSwapnil Jakhade * PHY_PMA_XCVR_PLLCLK_EN register. 487572d6592SSwapnil Jakhade */ 488572d6592SSwapnil Jakhade u32 pll_bits; 489572d6592SSwapnil Jakhade /* Used to enable or disable lanes. */ 490572d6592SSwapnil Jakhade u32 pll_val; 491572d6592SSwapnil Jakhade 492572d6592SSwapnil Jakhade /* Select values of registers and mask, depending on enabled lane 493572d6592SSwapnil Jakhade * count. 494572d6592SSwapnil Jakhade */ 495572d6592SSwapnil Jakhade switch (dp->lanes) { 496572d6592SSwapnil Jakhade /* lane 0 */ 497572d6592SSwapnil Jakhade case (1): 498572d6592SSwapnil Jakhade pll_bits = 0x00000001; 499572d6592SSwapnil Jakhade break; 500572d6592SSwapnil Jakhade /* lanes 0-1 */ 501572d6592SSwapnil Jakhade case (2): 502572d6592SSwapnil Jakhade pll_bits = 0x00000003; 503572d6592SSwapnil Jakhade break; 504572d6592SSwapnil Jakhade /* lanes 0-3, all */ 505572d6592SSwapnil Jakhade default: 506572d6592SSwapnil Jakhade pll_bits = 0x0000000F; 507572d6592SSwapnil Jakhade break; 508572d6592SSwapnil Jakhade } 509572d6592SSwapnil Jakhade 510572d6592SSwapnil Jakhade if (enable) 511572d6592SSwapnil Jakhade pll_val = pll_bits; 512572d6592SSwapnil Jakhade else 513572d6592SSwapnil Jakhade pll_val = 0x00000000; 514572d6592SSwapnil Jakhade 515cba472ecSSwapnil Jakhade cdns_torrent_dp_write(regmap, PHY_PMA_XCVR_PLLCLK_EN, pll_val); 516572d6592SSwapnil Jakhade 517572d6592SSwapnil Jakhade /* Wait for acknowledgment from PHY. */ 518cba472ecSSwapnil Jakhade ret = regmap_read_poll_timeout(regmap, 519572d6592SSwapnil Jakhade PHY_PMA_XCVR_PLLCLK_EN_ACK, 520572d6592SSwapnil Jakhade rd_val, 521572d6592SSwapnil Jakhade (rd_val & pll_bits) == pll_val, 522572d6592SSwapnil Jakhade 0, POLL_TIMEOUT_US); 523572d6592SSwapnil Jakhade ndelay(100); 524572d6592SSwapnil Jakhade return ret; 525572d6592SSwapnil Jakhade } 526572d6592SSwapnil Jakhade 527572d6592SSwapnil Jakhade /* 528572d6592SSwapnil Jakhade * Perform register operations related to setting link rate, once powerstate is 529572d6592SSwapnil Jakhade * set and PLL disable request was processed. 530572d6592SSwapnil Jakhade */ 531572d6592SSwapnil Jakhade static int cdns_torrent_dp_configure_rate(struct cdns_torrent_phy *cdns_phy, 532572d6592SSwapnil Jakhade struct phy_configure_opts_dp *dp) 533572d6592SSwapnil Jakhade { 534572d6592SSwapnil Jakhade u32 ret; 535572d6592SSwapnil Jakhade u32 read_val; 536572d6592SSwapnil Jakhade 537572d6592SSwapnil Jakhade /* Disable the cmn_pll0_en before re-programming the new data rate. */ 53869d114acSSwapnil Jakhade regmap_field_write(cdns_phy->phy_pma_pll_raw_ctrl, 0x0); 539572d6592SSwapnil Jakhade 540572d6592SSwapnil Jakhade /* 541572d6592SSwapnil Jakhade * Wait for PLL ready de-assertion. 542572d6592SSwapnil Jakhade * For PLL0 - PHY_PMA_CMN_CTRL2[2] == 1 543572d6592SSwapnil Jakhade */ 54469d114acSSwapnil Jakhade ret = regmap_field_read_poll_timeout(cdns_phy->phy_pma_cmn_ctrl_2, 545572d6592SSwapnil Jakhade read_val, 546572d6592SSwapnil Jakhade ((read_val >> 2) & 0x01) != 0, 547572d6592SSwapnil Jakhade 0, POLL_TIMEOUT_US); 548572d6592SSwapnil Jakhade if (ret) 549572d6592SSwapnil Jakhade return ret; 550572d6592SSwapnil Jakhade ndelay(200); 551572d6592SSwapnil Jakhade 552572d6592SSwapnil Jakhade /* DP Rate Change - VCO Output settings. */ 553572d6592SSwapnil Jakhade if (cdns_phy->ref_clk_rate == REF_CLK_19_2MHz) { 554572d6592SSwapnil Jakhade /* PMA common configuration 19.2MHz */ 555572d6592SSwapnil Jakhade cdns_torrent_dp_pma_cmn_vco_cfg_19_2mhz(cdns_phy, dp->link_rate, 556572d6592SSwapnil Jakhade dp->ssc); 557572d6592SSwapnil Jakhade cdns_torrent_dp_pma_cmn_cfg_19_2mhz(cdns_phy); 558572d6592SSwapnil Jakhade } else if (cdns_phy->ref_clk_rate == REF_CLK_25MHz) { 559572d6592SSwapnil Jakhade /* PMA common configuration 25MHz */ 560572d6592SSwapnil Jakhade cdns_torrent_dp_pma_cmn_vco_cfg_25mhz(cdns_phy, dp->link_rate, 561572d6592SSwapnil Jakhade dp->ssc); 562572d6592SSwapnil Jakhade cdns_torrent_dp_pma_cmn_cfg_25mhz(cdns_phy); 563572d6592SSwapnil Jakhade } 564572d6592SSwapnil Jakhade cdns_torrent_dp_pma_cmn_rate(cdns_phy, dp->link_rate, dp->lanes); 565572d6592SSwapnil Jakhade 566572d6592SSwapnil Jakhade /* Enable the cmn_pll0_en. */ 56769d114acSSwapnil Jakhade regmap_field_write(cdns_phy->phy_pma_pll_raw_ctrl, 0x3); 568572d6592SSwapnil Jakhade 569572d6592SSwapnil Jakhade /* 570572d6592SSwapnil Jakhade * Wait for PLL ready assertion. 571572d6592SSwapnil Jakhade * For PLL0 - PHY_PMA_CMN_CTRL2[0] == 1 572572d6592SSwapnil Jakhade */ 57369d114acSSwapnil Jakhade ret = regmap_field_read_poll_timeout(cdns_phy->phy_pma_cmn_ctrl_2, 574572d6592SSwapnil Jakhade read_val, 575572d6592SSwapnil Jakhade (read_val & 0x01) != 0, 576572d6592SSwapnil Jakhade 0, POLL_TIMEOUT_US); 577572d6592SSwapnil Jakhade return ret; 578572d6592SSwapnil Jakhade } 579572d6592SSwapnil Jakhade 580572d6592SSwapnil Jakhade /* 581572d6592SSwapnil Jakhade * Verify, that parameters to configure PHY with are correct. 582572d6592SSwapnil Jakhade */ 583afa4ba05SSwapnil Jakhade static int cdns_torrent_dp_verify_config(struct cdns_torrent_inst *inst, 584572d6592SSwapnil Jakhade struct phy_configure_opts_dp *dp) 585572d6592SSwapnil Jakhade { 586572d6592SSwapnil Jakhade u8 i; 587572d6592SSwapnil Jakhade 588572d6592SSwapnil Jakhade /* If changing link rate was required, verify it's supported. */ 589572d6592SSwapnil Jakhade if (dp->set_rate) { 590572d6592SSwapnil Jakhade switch (dp->link_rate) { 591572d6592SSwapnil Jakhade case 1620: 592572d6592SSwapnil Jakhade case 2160: 593572d6592SSwapnil Jakhade case 2430: 594572d6592SSwapnil Jakhade case 2700: 595572d6592SSwapnil Jakhade case 3240: 596572d6592SSwapnil Jakhade case 4320: 597572d6592SSwapnil Jakhade case 5400: 598572d6592SSwapnil Jakhade case 8100: 599572d6592SSwapnil Jakhade /* valid bit rate */ 600572d6592SSwapnil Jakhade break; 601572d6592SSwapnil Jakhade default: 602572d6592SSwapnil Jakhade return -EINVAL; 603572d6592SSwapnil Jakhade } 604572d6592SSwapnil Jakhade } 605572d6592SSwapnil Jakhade 606572d6592SSwapnil Jakhade /* Verify lane count. */ 607572d6592SSwapnil Jakhade switch (dp->lanes) { 608572d6592SSwapnil Jakhade case 1: 609572d6592SSwapnil Jakhade case 2: 610572d6592SSwapnil Jakhade case 4: 611572d6592SSwapnil Jakhade /* valid lane count. */ 612572d6592SSwapnil Jakhade break; 613572d6592SSwapnil Jakhade default: 614572d6592SSwapnil Jakhade return -EINVAL; 615572d6592SSwapnil Jakhade } 616572d6592SSwapnil Jakhade 617572d6592SSwapnil Jakhade /* Check against actual number of PHY's lanes. */ 618afa4ba05SSwapnil Jakhade if (dp->lanes > inst->num_lanes) 619572d6592SSwapnil Jakhade return -EINVAL; 620572d6592SSwapnil Jakhade 621572d6592SSwapnil Jakhade /* 622572d6592SSwapnil Jakhade * If changing voltages is required, check swing and pre-emphasis 623572d6592SSwapnil Jakhade * levels, per-lane. 624572d6592SSwapnil Jakhade */ 625572d6592SSwapnil Jakhade if (dp->set_voltages) { 626572d6592SSwapnil Jakhade /* Lane count verified previously. */ 627572d6592SSwapnil Jakhade for (i = 0; i < dp->lanes; i++) { 628572d6592SSwapnil Jakhade if (dp->voltage[i] > 3 || dp->pre[i] > 3) 629572d6592SSwapnil Jakhade return -EINVAL; 630572d6592SSwapnil Jakhade 631572d6592SSwapnil Jakhade /* Sum of voltage swing and pre-emphasis levels cannot 632572d6592SSwapnil Jakhade * exceed 3. 633572d6592SSwapnil Jakhade */ 634572d6592SSwapnil Jakhade if (dp->voltage[i] + dp->pre[i] > 3) 635572d6592SSwapnil Jakhade return -EINVAL; 636572d6592SSwapnil Jakhade } 637572d6592SSwapnil Jakhade } 638572d6592SSwapnil Jakhade 639572d6592SSwapnil Jakhade return 0; 640572d6592SSwapnil Jakhade } 641572d6592SSwapnil Jakhade 64221c79146SSwapnil Jakhade /* Set power state A0 and PLL clock enable to 0 on enabled lanes. */ 64321c79146SSwapnil Jakhade static void cdns_torrent_dp_set_a0_pll(struct cdns_torrent_phy *cdns_phy, 64421c79146SSwapnil Jakhade u32 num_lanes) 64521c79146SSwapnil Jakhade { 646cba472ecSSwapnil Jakhade struct regmap *regmap = cdns_phy->regmap_dptx_phy_reg; 647cba472ecSSwapnil Jakhade u32 pwr_state = cdns_torrent_dp_read(regmap, 64821c79146SSwapnil Jakhade PHY_PMA_XCVR_POWER_STATE_REQ); 649cba472ecSSwapnil Jakhade u32 pll_clk_en = cdns_torrent_dp_read(regmap, 65021c79146SSwapnil Jakhade PHY_PMA_XCVR_PLLCLK_EN); 65121c79146SSwapnil Jakhade 65221c79146SSwapnil Jakhade /* Lane 0 is always enabled. */ 65321c79146SSwapnil Jakhade pwr_state &= ~(PMA_XCVR_POWER_STATE_REQ_LN_MASK << 65421c79146SSwapnil Jakhade PHY_POWER_STATE_LN_0); 65521c79146SSwapnil Jakhade pll_clk_en &= ~0x01U; 65621c79146SSwapnil Jakhade 65721c79146SSwapnil Jakhade if (num_lanes > 1) { 65821c79146SSwapnil Jakhade /* lane 1 */ 65921c79146SSwapnil Jakhade pwr_state &= ~(PMA_XCVR_POWER_STATE_REQ_LN_MASK << 66021c79146SSwapnil Jakhade PHY_POWER_STATE_LN_1); 66121c79146SSwapnil Jakhade pll_clk_en &= ~(0x01U << 1); 66221c79146SSwapnil Jakhade } 66321c79146SSwapnil Jakhade 66421c79146SSwapnil Jakhade if (num_lanes > 2) { 66521c79146SSwapnil Jakhade /* lanes 2 and 3 */ 66621c79146SSwapnil Jakhade pwr_state &= ~(PMA_XCVR_POWER_STATE_REQ_LN_MASK << 66721c79146SSwapnil Jakhade PHY_POWER_STATE_LN_2); 66821c79146SSwapnil Jakhade pwr_state &= ~(PMA_XCVR_POWER_STATE_REQ_LN_MASK << 66921c79146SSwapnil Jakhade PHY_POWER_STATE_LN_3); 67021c79146SSwapnil Jakhade pll_clk_en &= ~(0x01U << 2); 67121c79146SSwapnil Jakhade pll_clk_en &= ~(0x01U << 3); 67221c79146SSwapnil Jakhade } 67321c79146SSwapnil Jakhade 674cba472ecSSwapnil Jakhade cdns_torrent_dp_write(regmap, PHY_PMA_XCVR_POWER_STATE_REQ, pwr_state); 675cba472ecSSwapnil Jakhade cdns_torrent_dp_write(regmap, PHY_PMA_XCVR_PLLCLK_EN, pll_clk_en); 67621c79146SSwapnil Jakhade } 67721c79146SSwapnil Jakhade 678572d6592SSwapnil Jakhade /* Configure lane count as required. */ 679572d6592SSwapnil Jakhade static int cdns_torrent_dp_set_lanes(struct cdns_torrent_phy *cdns_phy, 680572d6592SSwapnil Jakhade struct phy_configure_opts_dp *dp) 681572d6592SSwapnil Jakhade { 682572d6592SSwapnil Jakhade u32 value; 683572d6592SSwapnil Jakhade u32 ret; 684cba472ecSSwapnil Jakhade struct regmap *regmap = cdns_phy->regmap_dptx_phy_reg; 685572d6592SSwapnil Jakhade u8 lane_mask = (1 << dp->lanes) - 1; 686572d6592SSwapnil Jakhade 687cba472ecSSwapnil Jakhade value = cdns_torrent_dp_read(regmap, PHY_RESET); 688572d6592SSwapnil Jakhade /* clear pma_tx_elec_idle_ln_* bits. */ 689572d6592SSwapnil Jakhade value &= ~PMA_TX_ELEC_IDLE_MASK; 690572d6592SSwapnil Jakhade /* Assert pma_tx_elec_idle_ln_* for disabled lanes. */ 691572d6592SSwapnil Jakhade value |= ((~lane_mask) << PMA_TX_ELEC_IDLE_SHIFT) & 692572d6592SSwapnil Jakhade PMA_TX_ELEC_IDLE_MASK; 693cba472ecSSwapnil Jakhade cdns_torrent_dp_write(regmap, PHY_RESET, value); 694572d6592SSwapnil Jakhade 695572d6592SSwapnil Jakhade /* reset the link by asserting phy_l00_reset_n low */ 696cba472ecSSwapnil Jakhade cdns_torrent_dp_write(regmap, PHY_RESET, 697572d6592SSwapnil Jakhade value & (~PHY_L00_RESET_N_MASK)); 698572d6592SSwapnil Jakhade 699572d6592SSwapnil Jakhade /* 700572d6592SSwapnil Jakhade * Assert lane reset on unused lanes and lane 0 so they remain in reset 701572d6592SSwapnil Jakhade * and powered down when re-enabling the link 702572d6592SSwapnil Jakhade */ 703572d6592SSwapnil Jakhade value = (value & 0x0000FFF0) | (0x0000000E & lane_mask); 704cba472ecSSwapnil Jakhade cdns_torrent_dp_write(regmap, PHY_RESET, value); 705572d6592SSwapnil Jakhade 706572d6592SSwapnil Jakhade cdns_torrent_dp_set_a0_pll(cdns_phy, dp->lanes); 707572d6592SSwapnil Jakhade 708572d6592SSwapnil Jakhade /* release phy_l0*_reset_n based on used laneCount */ 709572d6592SSwapnil Jakhade value = (value & 0x0000FFF0) | (0x0000000F & lane_mask); 710cba472ecSSwapnil Jakhade cdns_torrent_dp_write(regmap, PHY_RESET, value); 711572d6592SSwapnil Jakhade 712572d6592SSwapnil Jakhade /* Wait, until PHY gets ready after releasing PHY reset signal. */ 713572d6592SSwapnil Jakhade ret = cdns_torrent_dp_wait_pma_cmn_ready(cdns_phy); 714572d6592SSwapnil Jakhade if (ret) 715572d6592SSwapnil Jakhade return ret; 716572d6592SSwapnil Jakhade 717572d6592SSwapnil Jakhade ndelay(100); 718572d6592SSwapnil Jakhade 719572d6592SSwapnil Jakhade /* release pma_xcvr_pllclk_en_ln_*, only for the master lane */ 720cba472ecSSwapnil Jakhade cdns_torrent_dp_write(regmap, PHY_PMA_XCVR_PLLCLK_EN, 0x0001); 721572d6592SSwapnil Jakhade 722572d6592SSwapnil Jakhade ret = cdns_torrent_dp_run(cdns_phy, dp->lanes); 723572d6592SSwapnil Jakhade 724572d6592SSwapnil Jakhade return ret; 725572d6592SSwapnil Jakhade } 726572d6592SSwapnil Jakhade 727572d6592SSwapnil Jakhade /* Configure link rate as required. */ 728572d6592SSwapnil Jakhade static int cdns_torrent_dp_set_rate(struct cdns_torrent_phy *cdns_phy, 729572d6592SSwapnil Jakhade struct phy_configure_opts_dp *dp) 730572d6592SSwapnil Jakhade { 731572d6592SSwapnil Jakhade u32 ret; 732572d6592SSwapnil Jakhade 733572d6592SSwapnil Jakhade ret = cdns_torrent_dp_set_power_state(cdns_phy, dp->lanes, 734572d6592SSwapnil Jakhade POWERSTATE_A3); 735572d6592SSwapnil Jakhade if (ret) 736572d6592SSwapnil Jakhade return ret; 737572d6592SSwapnil Jakhade ret = cdns_torrent_dp_set_pll_en(cdns_phy, dp, false); 738572d6592SSwapnil Jakhade if (ret) 739572d6592SSwapnil Jakhade return ret; 740572d6592SSwapnil Jakhade ndelay(200); 741572d6592SSwapnil Jakhade 742572d6592SSwapnil Jakhade ret = cdns_torrent_dp_configure_rate(cdns_phy, dp); 743572d6592SSwapnil Jakhade if (ret) 744572d6592SSwapnil Jakhade return ret; 745572d6592SSwapnil Jakhade ndelay(200); 746572d6592SSwapnil Jakhade 747572d6592SSwapnil Jakhade ret = cdns_torrent_dp_set_pll_en(cdns_phy, dp, true); 748572d6592SSwapnil Jakhade if (ret) 749572d6592SSwapnil Jakhade return ret; 750572d6592SSwapnil Jakhade ret = cdns_torrent_dp_set_power_state(cdns_phy, dp->lanes, 751572d6592SSwapnil Jakhade POWERSTATE_A2); 752572d6592SSwapnil Jakhade if (ret) 753572d6592SSwapnil Jakhade return ret; 754572d6592SSwapnil Jakhade ret = cdns_torrent_dp_set_power_state(cdns_phy, dp->lanes, 755572d6592SSwapnil Jakhade POWERSTATE_A0); 756572d6592SSwapnil Jakhade if (ret) 757572d6592SSwapnil Jakhade return ret; 758572d6592SSwapnil Jakhade ndelay(900); 759572d6592SSwapnil Jakhade 760572d6592SSwapnil Jakhade return ret; 761572d6592SSwapnil Jakhade } 762572d6592SSwapnil Jakhade 763572d6592SSwapnil Jakhade /* Configure voltage swing and pre-emphasis for all enabled lanes. */ 764572d6592SSwapnil Jakhade static void cdns_torrent_dp_set_voltages(struct cdns_torrent_phy *cdns_phy, 765572d6592SSwapnil Jakhade struct phy_configure_opts_dp *dp) 766572d6592SSwapnil Jakhade { 767572d6592SSwapnil Jakhade u8 lane; 768572d6592SSwapnil Jakhade u16 val; 769572d6592SSwapnil Jakhade 770572d6592SSwapnil Jakhade for (lane = 0; lane < dp->lanes; lane++) { 77169d114acSSwapnil Jakhade val = cdns_torrent_phy_read(cdns_phy->regmap_tx_lane_cdb[lane], 77269d114acSSwapnil Jakhade TX_DIAG_ACYA); 773572d6592SSwapnil Jakhade /* 774572d6592SSwapnil Jakhade * Write 1 to register bit TX_DIAG_ACYA[0] to freeze the 775572d6592SSwapnil Jakhade * current state of the analog TX driver. 776572d6592SSwapnil Jakhade */ 777572d6592SSwapnil Jakhade val |= TX_DIAG_ACYA_HBDC_MASK; 77869d114acSSwapnil Jakhade cdns_torrent_phy_write(cdns_phy->regmap_tx_lane_cdb[lane], 77969d114acSSwapnil Jakhade TX_DIAG_ACYA, val); 780572d6592SSwapnil Jakhade 78169d114acSSwapnil Jakhade cdns_torrent_phy_write(cdns_phy->regmap_tx_lane_cdb[lane], 78269d114acSSwapnil Jakhade TX_TXCC_CTRL, 0x08A4); 783572d6592SSwapnil Jakhade val = vltg_coeff[dp->voltage[lane]][dp->pre[lane]].diag_tx_drv; 78469d114acSSwapnil Jakhade cdns_torrent_phy_write(cdns_phy->regmap_tx_lane_cdb[lane], 78569d114acSSwapnil Jakhade DRV_DIAG_TX_DRV, val); 786572d6592SSwapnil Jakhade val = vltg_coeff[dp->voltage[lane]][dp->pre[lane]].mgnfs_mult; 78769d114acSSwapnil Jakhade cdns_torrent_phy_write(cdns_phy->regmap_tx_lane_cdb[lane], 78869d114acSSwapnil Jakhade TX_TXCC_MGNFS_MULT_000, 789572d6592SSwapnil Jakhade val); 790572d6592SSwapnil Jakhade val = vltg_coeff[dp->voltage[lane]][dp->pre[lane]].cpost_mult; 79169d114acSSwapnil Jakhade cdns_torrent_phy_write(cdns_phy->regmap_tx_lane_cdb[lane], 79269d114acSSwapnil Jakhade TX_TXCC_CPOST_MULT_00, 793572d6592SSwapnil Jakhade val); 794572d6592SSwapnil Jakhade 79569d114acSSwapnil Jakhade val = cdns_torrent_phy_read(cdns_phy->regmap_tx_lane_cdb[lane], 79669d114acSSwapnil Jakhade TX_DIAG_ACYA); 797572d6592SSwapnil Jakhade /* 798572d6592SSwapnil Jakhade * Write 0 to register bit TX_DIAG_ACYA[0] to allow the state of 799572d6592SSwapnil Jakhade * analog TX driver to reflect the new programmed one. 800572d6592SSwapnil Jakhade */ 801572d6592SSwapnil Jakhade val &= ~TX_DIAG_ACYA_HBDC_MASK; 80269d114acSSwapnil Jakhade cdns_torrent_phy_write(cdns_phy->regmap_tx_lane_cdb[lane], 80369d114acSSwapnil Jakhade TX_DIAG_ACYA, val); 804572d6592SSwapnil Jakhade } 805572d6592SSwapnil Jakhade }; 806572d6592SSwapnil Jakhade 807572d6592SSwapnil Jakhade static int cdns_torrent_dp_configure(struct phy *phy, 808572d6592SSwapnil Jakhade union phy_configure_opts *opts) 809572d6592SSwapnil Jakhade { 810afa4ba05SSwapnil Jakhade struct cdns_torrent_inst *inst = phy_get_drvdata(phy); 811afa4ba05SSwapnil Jakhade struct cdns_torrent_phy *cdns_phy = dev_get_drvdata(phy->dev.parent); 812572d6592SSwapnil Jakhade int ret; 813572d6592SSwapnil Jakhade 814afa4ba05SSwapnil Jakhade ret = cdns_torrent_dp_verify_config(inst, &opts->dp); 815572d6592SSwapnil Jakhade if (ret) { 816572d6592SSwapnil Jakhade dev_err(&phy->dev, "invalid params for phy configure\n"); 817572d6592SSwapnil Jakhade return ret; 818572d6592SSwapnil Jakhade } 819572d6592SSwapnil Jakhade 820572d6592SSwapnil Jakhade if (opts->dp.set_lanes) { 821572d6592SSwapnil Jakhade ret = cdns_torrent_dp_set_lanes(cdns_phy, &opts->dp); 822572d6592SSwapnil Jakhade if (ret) { 823572d6592SSwapnil Jakhade dev_err(&phy->dev, "cdns_torrent_dp_set_lanes failed\n"); 824572d6592SSwapnil Jakhade return ret; 825572d6592SSwapnil Jakhade } 826572d6592SSwapnil Jakhade } 827572d6592SSwapnil Jakhade 828572d6592SSwapnil Jakhade if (opts->dp.set_rate) { 829572d6592SSwapnil Jakhade ret = cdns_torrent_dp_set_rate(cdns_phy, &opts->dp); 830572d6592SSwapnil Jakhade if (ret) { 831572d6592SSwapnil Jakhade dev_err(&phy->dev, "cdns_torrent_dp_set_rate failed\n"); 832572d6592SSwapnil Jakhade return ret; 833572d6592SSwapnil Jakhade } 834572d6592SSwapnil Jakhade } 835572d6592SSwapnil Jakhade 836572d6592SSwapnil Jakhade if (opts->dp.set_voltages) 837572d6592SSwapnil Jakhade cdns_torrent_dp_set_voltages(cdns_phy, &opts->dp); 838572d6592SSwapnil Jakhade 839572d6592SSwapnil Jakhade return ret; 840572d6592SSwapnil Jakhade } 841572d6592SSwapnil Jakhade 84292e9ccc6SSwapnil Jakhade static int cdns_torrent_dp_init(struct phy *phy) 843c589e701SYuti Amonkar { 844c589e701SYuti Amonkar unsigned char lane_bits; 84521c79146SSwapnil Jakhade int ret; 846afa4ba05SSwapnil Jakhade struct cdns_torrent_inst *inst = phy_get_drvdata(phy); 847afa4ba05SSwapnil Jakhade struct cdns_torrent_phy *cdns_phy = dev_get_drvdata(phy->dev.parent); 848cba472ecSSwapnil Jakhade struct regmap *regmap = cdns_phy->regmap_dptx_phy_reg; 849c589e701SYuti Amonkar 850e4b496a3SSwapnil Jakhade ret = clk_prepare_enable(cdns_phy->clk); 851e4b496a3SSwapnil Jakhade if (ret) { 852e4b496a3SSwapnil Jakhade dev_err(cdns_phy->dev, "Failed to prepare ref clock\n"); 853e4b496a3SSwapnil Jakhade return ret; 854e4b496a3SSwapnil Jakhade } 855e4b496a3SSwapnil Jakhade 856e4b496a3SSwapnil Jakhade cdns_phy->ref_clk_rate = clk_get_rate(cdns_phy->clk); 857e4b496a3SSwapnil Jakhade if (!(cdns_phy->ref_clk_rate)) { 858e4b496a3SSwapnil Jakhade dev_err(cdns_phy->dev, "Failed to get ref clock rate\n"); 859e4b496a3SSwapnil Jakhade clk_disable_unprepare(cdns_phy->clk); 860e4b496a3SSwapnil Jakhade return -EINVAL; 861e4b496a3SSwapnil Jakhade } 862e4b496a3SSwapnil Jakhade 863e4b496a3SSwapnil Jakhade switch (cdns_phy->ref_clk_rate) { 864e4b496a3SSwapnil Jakhade case REF_CLK_19_2MHz: 865e4b496a3SSwapnil Jakhade case REF_CLK_25MHz: 866e4b496a3SSwapnil Jakhade /* Valid Ref Clock Rate */ 867e4b496a3SSwapnil Jakhade break; 868e4b496a3SSwapnil Jakhade default: 869e4b496a3SSwapnil Jakhade dev_err(cdns_phy->dev, "Unsupported Ref Clock Rate\n"); 870e4b496a3SSwapnil Jakhade return -EINVAL; 871e4b496a3SSwapnil Jakhade } 872e4b496a3SSwapnil Jakhade 873cba472ecSSwapnil Jakhade cdns_torrent_dp_write(regmap, PHY_AUX_CTRL, 0x0003); /* enable AUX */ 874c589e701SYuti Amonkar 875c589e701SYuti Amonkar /* PHY PMA registers configuration function */ 876afa4ba05SSwapnil Jakhade cdns_torrent_dp_pma_cfg(cdns_phy, inst); 877c589e701SYuti Amonkar 878c589e701SYuti Amonkar /* 879c589e701SYuti Amonkar * Set lines power state to A0 880c589e701SYuti Amonkar * Set lines pll clk enable to 0 881c589e701SYuti Amonkar */ 882afa4ba05SSwapnil Jakhade cdns_torrent_dp_set_a0_pll(cdns_phy, inst->num_lanes); 883c589e701SYuti Amonkar 884c589e701SYuti Amonkar /* 885c589e701SYuti Amonkar * release phy_l0*_reset_n and pma_tx_elec_idle_ln_* based on 886c589e701SYuti Amonkar * used lanes 887c589e701SYuti Amonkar */ 888afa4ba05SSwapnil Jakhade lane_bits = (1 << inst->num_lanes) - 1; 889cba472ecSSwapnil Jakhade cdns_torrent_dp_write(regmap, PHY_RESET, 890f61b3aedSSwapnil Jakhade ((0xF & ~lane_bits) << 4) | (0xF & lane_bits)); 891c589e701SYuti Amonkar 892c589e701SYuti Amonkar /* release pma_xcvr_pllclk_en_ln_*, only for the master lane */ 893cba472ecSSwapnil Jakhade cdns_torrent_dp_write(regmap, PHY_PMA_XCVR_PLLCLK_EN, 0x0001); 894c589e701SYuti Amonkar 895c589e701SYuti Amonkar /* PHY PMA registers configuration functions */ 896e4b496a3SSwapnil Jakhade /* Initialize PHY with max supported link rate, without SSC. */ 897e4b496a3SSwapnil Jakhade if (cdns_phy->ref_clk_rate == REF_CLK_19_2MHz) 898e4b496a3SSwapnil Jakhade cdns_torrent_dp_pma_cmn_vco_cfg_19_2mhz(cdns_phy, 899e4b496a3SSwapnil Jakhade cdns_phy->max_bit_rate, 900e4b496a3SSwapnil Jakhade false); 901e4b496a3SSwapnil Jakhade else if (cdns_phy->ref_clk_rate == REF_CLK_25MHz) 902e4b496a3SSwapnil Jakhade cdns_torrent_dp_pma_cmn_vco_cfg_25mhz(cdns_phy, 903e4b496a3SSwapnil Jakhade cdns_phy->max_bit_rate, 904e4b496a3SSwapnil Jakhade false); 905e4b496a3SSwapnil Jakhade cdns_torrent_dp_pma_cmn_rate(cdns_phy, cdns_phy->max_bit_rate, 906afa4ba05SSwapnil Jakhade inst->num_lanes); 907c589e701SYuti Amonkar 908c589e701SYuti Amonkar /* take out of reset */ 909cba472ecSSwapnil Jakhade regmap_field_write(cdns_phy->phy_reset_ctrl, 0x1); 910cba472ecSSwapnil Jakhade 911afa4ba05SSwapnil Jakhade cdns_torrent_phy_on(phy); 912afa4ba05SSwapnil Jakhade 91321c79146SSwapnil Jakhade ret = cdns_torrent_dp_wait_pma_cmn_ready(cdns_phy); 91421c79146SSwapnil Jakhade if (ret) 91521c79146SSwapnil Jakhade return ret; 916c589e701SYuti Amonkar 917afa4ba05SSwapnil Jakhade ret = cdns_torrent_dp_run(cdns_phy, inst->num_lanes); 91821c79146SSwapnil Jakhade 91921c79146SSwapnil Jakhade return ret; 920c589e701SYuti Amonkar } 921c589e701SYuti Amonkar 922e4b496a3SSwapnil Jakhade static int cdns_torrent_dp_exit(struct phy *phy) 923e4b496a3SSwapnil Jakhade { 924afa4ba05SSwapnil Jakhade struct cdns_torrent_phy *cdns_phy = dev_get_drvdata(phy->dev.parent); 925e4b496a3SSwapnil Jakhade 926e4b496a3SSwapnil Jakhade clk_disable_unprepare(cdns_phy->clk); 927e4b496a3SSwapnil Jakhade return 0; 928e4b496a3SSwapnil Jakhade } 929e4b496a3SSwapnil Jakhade 93092e9ccc6SSwapnil Jakhade static 93121c79146SSwapnil Jakhade int cdns_torrent_dp_wait_pma_cmn_ready(struct cdns_torrent_phy *cdns_phy) 932c589e701SYuti Amonkar { 933c589e701SYuti Amonkar unsigned int reg; 934c589e701SYuti Amonkar int ret; 935cba472ecSSwapnil Jakhade struct regmap *regmap = cdns_phy->regmap_dptx_phy_reg; 936c589e701SYuti Amonkar 937cba472ecSSwapnil Jakhade ret = regmap_read_poll_timeout(regmap, PHY_PMA_CMN_READY, reg, 938cba472ecSSwapnil Jakhade reg & 1, 0, POLL_TIMEOUT_US); 93921c79146SSwapnil Jakhade if (ret == -ETIMEDOUT) { 940c589e701SYuti Amonkar dev_err(cdns_phy->dev, 941c589e701SYuti Amonkar "timeout waiting for PMA common ready\n"); 94221c79146SSwapnil Jakhade return -ETIMEDOUT; 94321c79146SSwapnil Jakhade } 94421c79146SSwapnil Jakhade 94521c79146SSwapnil Jakhade return 0; 946c589e701SYuti Amonkar } 947c589e701SYuti Amonkar 948afa4ba05SSwapnil Jakhade static void cdns_torrent_dp_pma_cfg(struct cdns_torrent_phy *cdns_phy, 949afa4ba05SSwapnil Jakhade struct cdns_torrent_inst *inst) 950c589e701SYuti Amonkar { 951c589e701SYuti Amonkar unsigned int i; 952c589e701SYuti Amonkar 953e4b496a3SSwapnil Jakhade if (cdns_phy->ref_clk_rate == REF_CLK_19_2MHz) 954e4b496a3SSwapnil Jakhade /* PMA common configuration 19.2MHz */ 955e4b496a3SSwapnil Jakhade cdns_torrent_dp_pma_cmn_cfg_19_2mhz(cdns_phy); 956e4b496a3SSwapnil Jakhade else if (cdns_phy->ref_clk_rate == REF_CLK_25MHz) 957e4b496a3SSwapnil Jakhade /* PMA common configuration 25MHz */ 95892e9ccc6SSwapnil Jakhade cdns_torrent_dp_pma_cmn_cfg_25mhz(cdns_phy); 959c589e701SYuti Amonkar 960c589e701SYuti Amonkar /* PMA lane configuration to deal with multi-link operation */ 961afa4ba05SSwapnil Jakhade for (i = 0; i < inst->num_lanes; i++) 96292e9ccc6SSwapnil Jakhade cdns_torrent_dp_pma_lane_cfg(cdns_phy, i); 963c589e701SYuti Amonkar } 964c589e701SYuti Amonkar 96592e9ccc6SSwapnil Jakhade static 966e4b496a3SSwapnil Jakhade void cdns_torrent_dp_pma_cmn_cfg_19_2mhz(struct cdns_torrent_phy *cdns_phy) 967e4b496a3SSwapnil Jakhade { 96869d114acSSwapnil Jakhade struct regmap *regmap = cdns_phy->regmap_common_cdb; 96969d114acSSwapnil Jakhade 970e4b496a3SSwapnil Jakhade /* refclock registers - assumes 19.2 MHz refclock */ 97169d114acSSwapnil Jakhade cdns_torrent_phy_write(regmap, CMN_SSM_BIAS_TMR, 0x0014); 97269d114acSSwapnil Jakhade cdns_torrent_phy_write(regmap, CMN_PLLSM0_PLLPRE_TMR, 0x0027); 97369d114acSSwapnil Jakhade cdns_torrent_phy_write(regmap, CMN_PLLSM0_PLLLOCK_TMR, 0x00A1); 97469d114acSSwapnil Jakhade cdns_torrent_phy_write(regmap, CMN_PLLSM1_PLLPRE_TMR, 0x0027); 97569d114acSSwapnil Jakhade cdns_torrent_phy_write(regmap, CMN_PLLSM1_PLLLOCK_TMR, 0x00A1); 97669d114acSSwapnil Jakhade cdns_torrent_phy_write(regmap, CMN_BGCAL_INIT_TMR, 0x0060); 97769d114acSSwapnil Jakhade cdns_torrent_phy_write(regmap, CMN_BGCAL_ITER_TMR, 0x0060); 97869d114acSSwapnil Jakhade cdns_torrent_phy_write(regmap, CMN_IBCAL_INIT_TMR, 0x0014); 97969d114acSSwapnil Jakhade cdns_torrent_phy_write(regmap, CMN_TXPUCAL_INIT_TMR, 0x0018); 98069d114acSSwapnil Jakhade cdns_torrent_phy_write(regmap, CMN_TXPUCAL_ITER_TMR, 0x0005); 98169d114acSSwapnil Jakhade cdns_torrent_phy_write(regmap, CMN_TXPDCAL_INIT_TMR, 0x0018); 98269d114acSSwapnil Jakhade cdns_torrent_phy_write(regmap, CMN_TXPDCAL_ITER_TMR, 0x0005); 98369d114acSSwapnil Jakhade cdns_torrent_phy_write(regmap, CMN_RXCAL_INIT_TMR, 0x0240); 98469d114acSSwapnil Jakhade cdns_torrent_phy_write(regmap, CMN_RXCAL_ITER_TMR, 0x0005); 98569d114acSSwapnil Jakhade cdns_torrent_phy_write(regmap, CMN_SD_CAL_INIT_TMR, 0x0002); 98669d114acSSwapnil Jakhade cdns_torrent_phy_write(regmap, CMN_SD_CAL_ITER_TMR, 0x0002); 98769d114acSSwapnil Jakhade cdns_torrent_phy_write(regmap, CMN_SD_CAL_REFTIM_START, 0x000B); 98869d114acSSwapnil Jakhade cdns_torrent_phy_write(regmap, CMN_SD_CAL_PLLCNT_START, 0x0137); 989e4b496a3SSwapnil Jakhade 990e4b496a3SSwapnil Jakhade /* PLL registers */ 99169d114acSSwapnil Jakhade cdns_torrent_phy_write(regmap, CMN_PDIAG_PLL0_CP_PADJ_M0, 0x0509); 99269d114acSSwapnil Jakhade cdns_torrent_phy_write(regmap, CMN_PDIAG_PLL0_CP_IADJ_M0, 0x0F00); 99369d114acSSwapnil Jakhade cdns_torrent_phy_write(regmap, CMN_PDIAG_PLL0_FILT_PADJ_M0, 0x0F08); 99469d114acSSwapnil Jakhade cdns_torrent_phy_write(regmap, CMN_PLL0_DSM_DIAG_M0, 0x0004); 99569d114acSSwapnil Jakhade cdns_torrent_phy_write(regmap, CMN_PDIAG_PLL1_CP_PADJ_M0, 0x0509); 99669d114acSSwapnil Jakhade cdns_torrent_phy_write(regmap, CMN_PDIAG_PLL1_CP_IADJ_M0, 0x0F00); 99769d114acSSwapnil Jakhade cdns_torrent_phy_write(regmap, CMN_PDIAG_PLL1_FILT_PADJ_M0, 0x0F08); 99869d114acSSwapnil Jakhade cdns_torrent_phy_write(regmap, CMN_PLL1_DSM_DIAG_M0, 0x0004); 99969d114acSSwapnil Jakhade cdns_torrent_phy_write(regmap, CMN_PLL0_VCOCAL_INIT_TMR, 0x00C0); 100069d114acSSwapnil Jakhade cdns_torrent_phy_write(regmap, CMN_PLL0_VCOCAL_ITER_TMR, 0x0004); 100169d114acSSwapnil Jakhade cdns_torrent_phy_write(regmap, CMN_PLL1_VCOCAL_INIT_TMR, 0x00C0); 100269d114acSSwapnil Jakhade cdns_torrent_phy_write(regmap, CMN_PLL1_VCOCAL_ITER_TMR, 0x0004); 100369d114acSSwapnil Jakhade cdns_torrent_phy_write(regmap, CMN_PLL0_VCOCAL_REFTIM_START, 0x0260); 100469d114acSSwapnil Jakhade cdns_torrent_phy_write(regmap, CMN_PLL0_VCOCAL_TCTRL, 0x0003); 100569d114acSSwapnil Jakhade cdns_torrent_phy_write(regmap, CMN_PLL1_VCOCAL_REFTIM_START, 0x0260); 100669d114acSSwapnil Jakhade cdns_torrent_phy_write(regmap, CMN_PLL1_VCOCAL_TCTRL, 0x0003); 1007e4b496a3SSwapnil Jakhade } 1008e4b496a3SSwapnil Jakhade 1009e4b496a3SSwapnil Jakhade /* 1010e4b496a3SSwapnil Jakhade * Set registers responsible for enabling and configuring SSC, with second and 1011e4b496a3SSwapnil Jakhade * third register values provided by parameters. 1012e4b496a3SSwapnil Jakhade */ 1013e4b496a3SSwapnil Jakhade static 1014e4b496a3SSwapnil Jakhade void cdns_torrent_dp_enable_ssc_19_2mhz(struct cdns_torrent_phy *cdns_phy, 1015e4b496a3SSwapnil Jakhade u32 ctrl2_val, u32 ctrl3_val) 1016e4b496a3SSwapnil Jakhade { 101769d114acSSwapnil Jakhade struct regmap *regmap = cdns_phy->regmap_common_cdb; 101869d114acSSwapnil Jakhade 101969d114acSSwapnil Jakhade cdns_torrent_phy_write(regmap, CMN_PLL0_SS_CTRL1_M0, 0x0001); 102069d114acSSwapnil Jakhade cdns_torrent_phy_write(regmap, CMN_PLL0_SS_CTRL1_M0, ctrl2_val); 102169d114acSSwapnil Jakhade cdns_torrent_phy_write(regmap, CMN_PLL0_SS_CTRL1_M0, ctrl3_val); 102269d114acSSwapnil Jakhade cdns_torrent_phy_write(regmap, CMN_PLL0_SS_CTRL4_M0, 0x0003); 102369d114acSSwapnil Jakhade cdns_torrent_phy_write(regmap, CMN_PLL1_SS_CTRL1_M0, 0x0001); 102469d114acSSwapnil Jakhade cdns_torrent_phy_write(regmap, CMN_PLL1_SS_CTRL1_M0, ctrl2_val); 102569d114acSSwapnil Jakhade cdns_torrent_phy_write(regmap, CMN_PLL1_SS_CTRL1_M0, ctrl3_val); 102669d114acSSwapnil Jakhade cdns_torrent_phy_write(regmap, CMN_PLL1_SS_CTRL4_M0, 0x0003); 1027e4b496a3SSwapnil Jakhade } 1028e4b496a3SSwapnil Jakhade 1029e4b496a3SSwapnil Jakhade static 1030e4b496a3SSwapnil Jakhade void cdns_torrent_dp_pma_cmn_vco_cfg_19_2mhz(struct cdns_torrent_phy *cdns_phy, 1031e4b496a3SSwapnil Jakhade u32 rate, bool ssc) 1032e4b496a3SSwapnil Jakhade { 103369d114acSSwapnil Jakhade struct regmap *regmap = cdns_phy->regmap_common_cdb; 103469d114acSSwapnil Jakhade 1035e4b496a3SSwapnil Jakhade /* Assumes 19.2 MHz refclock */ 1036e4b496a3SSwapnil Jakhade switch (rate) { 1037e4b496a3SSwapnil Jakhade /* Setting VCO for 10.8GHz */ 1038e4b496a3SSwapnil Jakhade case 2700: 1039e4b496a3SSwapnil Jakhade case 5400: 104069d114acSSwapnil Jakhade cdns_torrent_phy_write(regmap, 1041e4b496a3SSwapnil Jakhade CMN_PLL0_INTDIV_M0, 0x0119); 104269d114acSSwapnil Jakhade cdns_torrent_phy_write(regmap, 1043e4b496a3SSwapnil Jakhade CMN_PLL0_FRACDIVL_M0, 0x4000); 104469d114acSSwapnil Jakhade cdns_torrent_phy_write(regmap, 1045e4b496a3SSwapnil Jakhade CMN_PLL0_FRACDIVH_M0, 0x0002); 104669d114acSSwapnil Jakhade cdns_torrent_phy_write(regmap, 1047e4b496a3SSwapnil Jakhade CMN_PLL0_HIGH_THR_M0, 0x00BC); 104869d114acSSwapnil Jakhade cdns_torrent_phy_write(regmap, 1049e4b496a3SSwapnil Jakhade CMN_PDIAG_PLL0_CTRL_M0, 0x0012); 105069d114acSSwapnil Jakhade cdns_torrent_phy_write(regmap, 1051e4b496a3SSwapnil Jakhade CMN_PLL1_INTDIV_M0, 0x0119); 105269d114acSSwapnil Jakhade cdns_torrent_phy_write(regmap, 1053e4b496a3SSwapnil Jakhade CMN_PLL1_FRACDIVL_M0, 0x4000); 105469d114acSSwapnil Jakhade cdns_torrent_phy_write(regmap, 1055e4b496a3SSwapnil Jakhade CMN_PLL1_FRACDIVH_M0, 0x0002); 105669d114acSSwapnil Jakhade cdns_torrent_phy_write(regmap, 1057e4b496a3SSwapnil Jakhade CMN_PLL1_HIGH_THR_M0, 0x00BC); 105869d114acSSwapnil Jakhade cdns_torrent_phy_write(regmap, 1059e4b496a3SSwapnil Jakhade CMN_PDIAG_PLL1_CTRL_M0, 0x0012); 1060e4b496a3SSwapnil Jakhade if (ssc) 1061e4b496a3SSwapnil Jakhade cdns_torrent_dp_enable_ssc_19_2mhz(cdns_phy, 0x033A, 1062e4b496a3SSwapnil Jakhade 0x006A); 1063e4b496a3SSwapnil Jakhade break; 1064e4b496a3SSwapnil Jakhade /* Setting VCO for 9.72GHz */ 1065e4b496a3SSwapnil Jakhade case 1620: 1066e4b496a3SSwapnil Jakhade case 2430: 1067e4b496a3SSwapnil Jakhade case 3240: 106869d114acSSwapnil Jakhade cdns_torrent_phy_write(regmap, 1069e4b496a3SSwapnil Jakhade CMN_PLL0_INTDIV_M0, 0x01FA); 107069d114acSSwapnil Jakhade cdns_torrent_phy_write(regmap, 1071e4b496a3SSwapnil Jakhade CMN_PLL0_FRACDIVL_M0, 0x4000); 107269d114acSSwapnil Jakhade cdns_torrent_phy_write(regmap, 1073e4b496a3SSwapnil Jakhade CMN_PLL0_FRACDIVH_M0, 0x0002); 107469d114acSSwapnil Jakhade cdns_torrent_phy_write(regmap, 1075e4b496a3SSwapnil Jakhade CMN_PLL0_HIGH_THR_M0, 0x0152); 107669d114acSSwapnil Jakhade cdns_torrent_phy_write(regmap, 1077e4b496a3SSwapnil Jakhade CMN_PDIAG_PLL0_CTRL_M0, 0x0002); 107869d114acSSwapnil Jakhade cdns_torrent_phy_write(regmap, 1079e4b496a3SSwapnil Jakhade CMN_PLL1_INTDIV_M0, 0x01FA); 108069d114acSSwapnil Jakhade cdns_torrent_phy_write(regmap, 1081e4b496a3SSwapnil Jakhade CMN_PLL1_FRACDIVL_M0, 0x4000); 108269d114acSSwapnil Jakhade cdns_torrent_phy_write(regmap, 1083e4b496a3SSwapnil Jakhade CMN_PLL1_FRACDIVH_M0, 0x0002); 108469d114acSSwapnil Jakhade cdns_torrent_phy_write(regmap, 1085e4b496a3SSwapnil Jakhade CMN_PLL1_HIGH_THR_M0, 0x0152); 108669d114acSSwapnil Jakhade cdns_torrent_phy_write(regmap, 1087e4b496a3SSwapnil Jakhade CMN_PDIAG_PLL1_CTRL_M0, 0x0002); 1088e4b496a3SSwapnil Jakhade if (ssc) 1089e4b496a3SSwapnil Jakhade cdns_torrent_dp_enable_ssc_19_2mhz(cdns_phy, 0x05DD, 1090e4b496a3SSwapnil Jakhade 0x0069); 1091e4b496a3SSwapnil Jakhade break; 1092e4b496a3SSwapnil Jakhade /* Setting VCO for 8.64GHz */ 1093e4b496a3SSwapnil Jakhade case 2160: 1094e4b496a3SSwapnil Jakhade case 4320: 109569d114acSSwapnil Jakhade cdns_torrent_phy_write(regmap, 1096e4b496a3SSwapnil Jakhade CMN_PLL0_INTDIV_M0, 0x01C2); 109769d114acSSwapnil Jakhade cdns_torrent_phy_write(regmap, 1098e4b496a3SSwapnil Jakhade CMN_PLL0_FRACDIVL_M0, 0x0000); 109969d114acSSwapnil Jakhade cdns_torrent_phy_write(regmap, 1100e4b496a3SSwapnil Jakhade CMN_PLL0_FRACDIVH_M0, 0x0002); 110169d114acSSwapnil Jakhade cdns_torrent_phy_write(regmap, 1102e4b496a3SSwapnil Jakhade CMN_PLL0_HIGH_THR_M0, 0x012C); 110369d114acSSwapnil Jakhade cdns_torrent_phy_write(regmap, 1104e4b496a3SSwapnil Jakhade CMN_PDIAG_PLL0_CTRL_M0, 0x0002); 110569d114acSSwapnil Jakhade cdns_torrent_phy_write(regmap, 1106e4b496a3SSwapnil Jakhade CMN_PLL1_INTDIV_M0, 0x01C2); 110769d114acSSwapnil Jakhade cdns_torrent_phy_write(regmap, 1108e4b496a3SSwapnil Jakhade CMN_PLL1_FRACDIVL_M0, 0x0000); 110969d114acSSwapnil Jakhade cdns_torrent_phy_write(regmap, 1110e4b496a3SSwapnil Jakhade CMN_PLL1_FRACDIVH_M0, 0x0002); 111169d114acSSwapnil Jakhade cdns_torrent_phy_write(regmap, 1112e4b496a3SSwapnil Jakhade CMN_PLL1_HIGH_THR_M0, 0x012C); 111369d114acSSwapnil Jakhade cdns_torrent_phy_write(regmap, 1114e4b496a3SSwapnil Jakhade CMN_PDIAG_PLL1_CTRL_M0, 0x0002); 1115e4b496a3SSwapnil Jakhade if (ssc) 1116e4b496a3SSwapnil Jakhade cdns_torrent_dp_enable_ssc_19_2mhz(cdns_phy, 0x0536, 1117e4b496a3SSwapnil Jakhade 0x0069); 1118e4b496a3SSwapnil Jakhade break; 1119e4b496a3SSwapnil Jakhade /* Setting VCO for 8.1GHz */ 1120e4b496a3SSwapnil Jakhade case 8100: 112169d114acSSwapnil Jakhade cdns_torrent_phy_write(regmap, 1122e4b496a3SSwapnil Jakhade CMN_PLL0_INTDIV_M0, 0x01A5); 112369d114acSSwapnil Jakhade cdns_torrent_phy_write(regmap, 1124e4b496a3SSwapnil Jakhade CMN_PLL0_FRACDIVL_M0, 0xE000); 112569d114acSSwapnil Jakhade cdns_torrent_phy_write(regmap, 1126e4b496a3SSwapnil Jakhade CMN_PLL0_FRACDIVH_M0, 0x0002); 112769d114acSSwapnil Jakhade cdns_torrent_phy_write(regmap, 1128e4b496a3SSwapnil Jakhade CMN_PLL0_HIGH_THR_M0, 0x011A); 112969d114acSSwapnil Jakhade cdns_torrent_phy_write(regmap, 1130e4b496a3SSwapnil Jakhade CMN_PDIAG_PLL0_CTRL_M0, 0x0002); 113169d114acSSwapnil Jakhade cdns_torrent_phy_write(regmap, 1132e4b496a3SSwapnil Jakhade CMN_PLL1_INTDIV_M0, 0x01A5); 113369d114acSSwapnil Jakhade cdns_torrent_phy_write(regmap, 1134e4b496a3SSwapnil Jakhade CMN_PLL1_FRACDIVL_M0, 0xE000); 113569d114acSSwapnil Jakhade cdns_torrent_phy_write(regmap, 1136e4b496a3SSwapnil Jakhade CMN_PLL1_FRACDIVH_M0, 0x0002); 113769d114acSSwapnil Jakhade cdns_torrent_phy_write(regmap, 1138e4b496a3SSwapnil Jakhade CMN_PLL1_HIGH_THR_M0, 0x011A); 113969d114acSSwapnil Jakhade cdns_torrent_phy_write(regmap, 1140e4b496a3SSwapnil Jakhade CMN_PDIAG_PLL1_CTRL_M0, 0x0002); 1141e4b496a3SSwapnil Jakhade if (ssc) 1142e4b496a3SSwapnil Jakhade cdns_torrent_dp_enable_ssc_19_2mhz(cdns_phy, 0x04D7, 1143e4b496a3SSwapnil Jakhade 0x006A); 1144e4b496a3SSwapnil Jakhade break; 1145e4b496a3SSwapnil Jakhade } 1146e4b496a3SSwapnil Jakhade 1147e4b496a3SSwapnil Jakhade if (ssc) { 114869d114acSSwapnil Jakhade cdns_torrent_phy_write(regmap, 1149e4b496a3SSwapnil Jakhade CMN_PLL0_VCOCAL_PLLCNT_START, 0x025E); 115069d114acSSwapnil Jakhade cdns_torrent_phy_write(regmap, 1151e4b496a3SSwapnil Jakhade CMN_PLL0_LOCK_PLLCNT_THR, 0x0005); 115269d114acSSwapnil Jakhade cdns_torrent_phy_write(regmap, 1153e4b496a3SSwapnil Jakhade CMN_PLL1_VCOCAL_PLLCNT_START, 0x025E); 115469d114acSSwapnil Jakhade cdns_torrent_phy_write(regmap, 1155e4b496a3SSwapnil Jakhade CMN_PLL1_LOCK_PLLCNT_THR, 0x0005); 1156e4b496a3SSwapnil Jakhade } else { 115769d114acSSwapnil Jakhade cdns_torrent_phy_write(regmap, 1158e4b496a3SSwapnil Jakhade CMN_PLL0_VCOCAL_PLLCNT_START, 0x0260); 115969d114acSSwapnil Jakhade cdns_torrent_phy_write(regmap, 1160e4b496a3SSwapnil Jakhade CMN_PLL1_VCOCAL_PLLCNT_START, 0x0260); 1161e4b496a3SSwapnil Jakhade /* Set reset register values to disable SSC */ 116269d114acSSwapnil Jakhade cdns_torrent_phy_write(regmap, 1163e4b496a3SSwapnil Jakhade CMN_PLL0_SS_CTRL1_M0, 0x0002); 116469d114acSSwapnil Jakhade cdns_torrent_phy_write(regmap, 1165e4b496a3SSwapnil Jakhade CMN_PLL0_SS_CTRL2_M0, 0x0000); 116669d114acSSwapnil Jakhade cdns_torrent_phy_write(regmap, 1167e4b496a3SSwapnil Jakhade CMN_PLL0_SS_CTRL3_M0, 0x0000); 116869d114acSSwapnil Jakhade cdns_torrent_phy_write(regmap, 1169e4b496a3SSwapnil Jakhade CMN_PLL0_SS_CTRL4_M0, 0x0000); 117069d114acSSwapnil Jakhade cdns_torrent_phy_write(regmap, 1171e4b496a3SSwapnil Jakhade CMN_PLL0_LOCK_PLLCNT_THR, 0x0003); 117269d114acSSwapnil Jakhade cdns_torrent_phy_write(regmap, 1173e4b496a3SSwapnil Jakhade CMN_PLL1_SS_CTRL1_M0, 0x0002); 117469d114acSSwapnil Jakhade cdns_torrent_phy_write(regmap, 1175e4b496a3SSwapnil Jakhade CMN_PLL1_SS_CTRL2_M0, 0x0000); 117669d114acSSwapnil Jakhade cdns_torrent_phy_write(regmap, 1177e4b496a3SSwapnil Jakhade CMN_PLL1_SS_CTRL3_M0, 0x0000); 117869d114acSSwapnil Jakhade cdns_torrent_phy_write(regmap, 1179e4b496a3SSwapnil Jakhade CMN_PLL1_SS_CTRL4_M0, 0x0000); 118069d114acSSwapnil Jakhade cdns_torrent_phy_write(regmap, 1181e4b496a3SSwapnil Jakhade CMN_PLL1_LOCK_PLLCNT_THR, 0x0003); 1182e4b496a3SSwapnil Jakhade } 1183e4b496a3SSwapnil Jakhade 118469d114acSSwapnil Jakhade cdns_torrent_phy_write(regmap, CMN_PLL0_LOCK_REFCNT_START, 0x0099); 118569d114acSSwapnil Jakhade cdns_torrent_phy_write(regmap, CMN_PLL0_LOCK_PLLCNT_START, 0x0099); 118669d114acSSwapnil Jakhade cdns_torrent_phy_write(regmap, CMN_PLL1_LOCK_REFCNT_START, 0x0099); 118769d114acSSwapnil Jakhade cdns_torrent_phy_write(regmap, CMN_PLL1_LOCK_PLLCNT_START, 0x0099); 1188e4b496a3SSwapnil Jakhade } 1189e4b496a3SSwapnil Jakhade 1190e4b496a3SSwapnil Jakhade static 119192e9ccc6SSwapnil Jakhade void cdns_torrent_dp_pma_cmn_cfg_25mhz(struct cdns_torrent_phy *cdns_phy) 1192c589e701SYuti Amonkar { 119369d114acSSwapnil Jakhade struct regmap *regmap = cdns_phy->regmap_common_cdb; 119469d114acSSwapnil Jakhade 1195c589e701SYuti Amonkar /* refclock registers - assumes 25 MHz refclock */ 119669d114acSSwapnil Jakhade cdns_torrent_phy_write(regmap, CMN_SSM_BIAS_TMR, 0x0019); 119769d114acSSwapnil Jakhade cdns_torrent_phy_write(regmap, CMN_PLLSM0_PLLPRE_TMR, 0x0032); 119869d114acSSwapnil Jakhade cdns_torrent_phy_write(regmap, CMN_PLLSM0_PLLLOCK_TMR, 0x00D1); 119969d114acSSwapnil Jakhade cdns_torrent_phy_write(regmap, CMN_PLLSM1_PLLPRE_TMR, 0x0032); 120069d114acSSwapnil Jakhade cdns_torrent_phy_write(regmap, CMN_PLLSM1_PLLLOCK_TMR, 0x00D1); 120169d114acSSwapnil Jakhade cdns_torrent_phy_write(regmap, CMN_BGCAL_INIT_TMR, 0x007D); 120269d114acSSwapnil Jakhade cdns_torrent_phy_write(regmap, CMN_BGCAL_ITER_TMR, 0x007D); 120369d114acSSwapnil Jakhade cdns_torrent_phy_write(regmap, CMN_IBCAL_INIT_TMR, 0x0019); 120469d114acSSwapnil Jakhade cdns_torrent_phy_write(regmap, CMN_TXPUCAL_INIT_TMR, 0x001E); 120569d114acSSwapnil Jakhade cdns_torrent_phy_write(regmap, CMN_TXPUCAL_ITER_TMR, 0x0006); 120669d114acSSwapnil Jakhade cdns_torrent_phy_write(regmap, CMN_TXPDCAL_INIT_TMR, 0x001E); 120769d114acSSwapnil Jakhade cdns_torrent_phy_write(regmap, CMN_TXPDCAL_ITER_TMR, 0x0006); 120869d114acSSwapnil Jakhade cdns_torrent_phy_write(regmap, CMN_RXCAL_INIT_TMR, 0x02EE); 120969d114acSSwapnil Jakhade cdns_torrent_phy_write(regmap, CMN_RXCAL_ITER_TMR, 0x0006); 121069d114acSSwapnil Jakhade cdns_torrent_phy_write(regmap, CMN_SD_CAL_INIT_TMR, 0x0002); 121169d114acSSwapnil Jakhade cdns_torrent_phy_write(regmap, CMN_SD_CAL_ITER_TMR, 0x0002); 121269d114acSSwapnil Jakhade cdns_torrent_phy_write(regmap, CMN_SD_CAL_REFTIM_START, 0x000E); 121369d114acSSwapnil Jakhade cdns_torrent_phy_write(regmap, CMN_SD_CAL_PLLCNT_START, 0x012B); 1214ccb1b89dSSwapnil Jakhade 1215c589e701SYuti Amonkar /* PLL registers */ 121669d114acSSwapnil Jakhade cdns_torrent_phy_write(regmap, CMN_PDIAG_PLL0_CP_PADJ_M0, 0x0509); 121769d114acSSwapnil Jakhade cdns_torrent_phy_write(regmap, CMN_PDIAG_PLL0_CP_IADJ_M0, 0x0F00); 121869d114acSSwapnil Jakhade cdns_torrent_phy_write(regmap, CMN_PDIAG_PLL0_FILT_PADJ_M0, 0x0F08); 121969d114acSSwapnil Jakhade cdns_torrent_phy_write(regmap, CMN_PLL0_DSM_DIAG_M0, 0x0004); 122069d114acSSwapnil Jakhade cdns_torrent_phy_write(regmap, CMN_PDIAG_PLL1_CP_PADJ_M0, 0x0509); 122169d114acSSwapnil Jakhade cdns_torrent_phy_write(regmap, CMN_PDIAG_PLL1_CP_IADJ_M0, 0x0F00); 122269d114acSSwapnil Jakhade cdns_torrent_phy_write(regmap, CMN_PDIAG_PLL1_FILT_PADJ_M0, 0x0F08); 122369d114acSSwapnil Jakhade cdns_torrent_phy_write(regmap, CMN_PLL1_DSM_DIAG_M0, 0x0004); 122469d114acSSwapnil Jakhade cdns_torrent_phy_write(regmap, CMN_PLL0_VCOCAL_INIT_TMR, 0x00FA); 122569d114acSSwapnil Jakhade cdns_torrent_phy_write(regmap, CMN_PLL0_VCOCAL_ITER_TMR, 0x0004); 122669d114acSSwapnil Jakhade cdns_torrent_phy_write(regmap, CMN_PLL1_VCOCAL_INIT_TMR, 0x00FA); 122769d114acSSwapnil Jakhade cdns_torrent_phy_write(regmap, CMN_PLL1_VCOCAL_ITER_TMR, 0x0004); 122869d114acSSwapnil Jakhade cdns_torrent_phy_write(regmap, CMN_PLL0_VCOCAL_REFTIM_START, 0x0317); 122969d114acSSwapnil Jakhade cdns_torrent_phy_write(regmap, CMN_PLL0_VCOCAL_TCTRL, 0x0003); 123069d114acSSwapnil Jakhade cdns_torrent_phy_write(regmap, CMN_PLL1_VCOCAL_REFTIM_START, 0x0317); 123169d114acSSwapnil Jakhade cdns_torrent_phy_write(regmap, CMN_PLL1_VCOCAL_TCTRL, 0x0003); 1232e4b496a3SSwapnil Jakhade } 1233e4b496a3SSwapnil Jakhade 1234e4b496a3SSwapnil Jakhade /* 1235e4b496a3SSwapnil Jakhade * Set registers responsible for enabling and configuring SSC, with second 1236e4b496a3SSwapnil Jakhade * register value provided by a parameter. 1237e4b496a3SSwapnil Jakhade */ 1238e4b496a3SSwapnil Jakhade static void cdns_torrent_dp_enable_ssc_25mhz(struct cdns_torrent_phy *cdns_phy, 1239e4b496a3SSwapnil Jakhade u32 ctrl2_val) 1240e4b496a3SSwapnil Jakhade { 124169d114acSSwapnil Jakhade struct regmap *regmap = cdns_phy->regmap_common_cdb; 124269d114acSSwapnil Jakhade 124369d114acSSwapnil Jakhade cdns_torrent_phy_write(regmap, CMN_PLL0_SS_CTRL1_M0, 0x0001); 124469d114acSSwapnil Jakhade cdns_torrent_phy_write(regmap, CMN_PLL0_SS_CTRL1_M0, ctrl2_val); 124569d114acSSwapnil Jakhade cdns_torrent_phy_write(regmap, CMN_PLL0_SS_CTRL1_M0, 0x007F); 124669d114acSSwapnil Jakhade cdns_torrent_phy_write(regmap, CMN_PLL0_SS_CTRL4_M0, 0x0003); 124769d114acSSwapnil Jakhade cdns_torrent_phy_write(regmap, CMN_PLL1_SS_CTRL1_M0, 0x0001); 124869d114acSSwapnil Jakhade cdns_torrent_phy_write(regmap, CMN_PLL1_SS_CTRL1_M0, ctrl2_val); 124969d114acSSwapnil Jakhade cdns_torrent_phy_write(regmap, CMN_PLL1_SS_CTRL1_M0, 0x007F); 125069d114acSSwapnil Jakhade cdns_torrent_phy_write(regmap, CMN_PLL1_SS_CTRL4_M0, 0x0003); 1251c589e701SYuti Amonkar } 1252c589e701SYuti Amonkar 125392e9ccc6SSwapnil Jakhade static 1254e4b496a3SSwapnil Jakhade void cdns_torrent_dp_pma_cmn_vco_cfg_25mhz(struct cdns_torrent_phy *cdns_phy, 1255e4b496a3SSwapnil Jakhade u32 rate, bool ssc) 1256c589e701SYuti Amonkar { 125769d114acSSwapnil Jakhade struct regmap *regmap = cdns_phy->regmap_common_cdb; 125869d114acSSwapnil Jakhade 1259c589e701SYuti Amonkar /* Assumes 25 MHz refclock */ 1260e4b496a3SSwapnil Jakhade switch (rate) { 1261c589e701SYuti Amonkar /* Setting VCO for 10.8GHz */ 1262c589e701SYuti Amonkar case 2700: 1263c589e701SYuti Amonkar case 5400: 126469d114acSSwapnil Jakhade cdns_torrent_phy_write(regmap, CMN_PLL0_INTDIV_M0, 0x01B0); 126569d114acSSwapnil Jakhade cdns_torrent_phy_write(regmap, CMN_PLL0_FRACDIVL_M0, 0x0000); 126669d114acSSwapnil Jakhade cdns_torrent_phy_write(regmap, CMN_PLL0_FRACDIVH_M0, 0x0002); 126769d114acSSwapnil Jakhade cdns_torrent_phy_write(regmap, CMN_PLL0_HIGH_THR_M0, 0x0120); 126869d114acSSwapnil Jakhade cdns_torrent_phy_write(regmap, CMN_PLL1_INTDIV_M0, 0x01B0); 126969d114acSSwapnil Jakhade cdns_torrent_phy_write(regmap, CMN_PLL1_FRACDIVL_M0, 0x0000); 127069d114acSSwapnil Jakhade cdns_torrent_phy_write(regmap, CMN_PLL1_FRACDIVH_M0, 0x0002); 127169d114acSSwapnil Jakhade cdns_torrent_phy_write(regmap, CMN_PLL1_HIGH_THR_M0, 0x0120); 1272e4b496a3SSwapnil Jakhade if (ssc) 1273e4b496a3SSwapnil Jakhade cdns_torrent_dp_enable_ssc_25mhz(cdns_phy, 0x0423); 1274c589e701SYuti Amonkar break; 1275c589e701SYuti Amonkar /* Setting VCO for 9.72GHz */ 1276e4b496a3SSwapnil Jakhade case 1620: 1277c589e701SYuti Amonkar case 2430: 1278c589e701SYuti Amonkar case 3240: 127969d114acSSwapnil Jakhade cdns_torrent_phy_write(regmap, CMN_PLL0_INTDIV_M0, 0x0184); 128069d114acSSwapnil Jakhade cdns_torrent_phy_write(regmap, CMN_PLL0_FRACDIVL_M0, 0xCCCD); 128169d114acSSwapnil Jakhade cdns_torrent_phy_write(regmap, CMN_PLL0_FRACDIVH_M0, 0x0002); 128269d114acSSwapnil Jakhade cdns_torrent_phy_write(regmap, CMN_PLL0_HIGH_THR_M0, 0x0104); 128369d114acSSwapnil Jakhade cdns_torrent_phy_write(regmap, CMN_PLL1_INTDIV_M0, 0x0184); 128469d114acSSwapnil Jakhade cdns_torrent_phy_write(regmap, CMN_PLL1_FRACDIVL_M0, 0xCCCD); 128569d114acSSwapnil Jakhade cdns_torrent_phy_write(regmap, CMN_PLL1_FRACDIVH_M0, 0x0002); 128669d114acSSwapnil Jakhade cdns_torrent_phy_write(regmap, CMN_PLL1_HIGH_THR_M0, 0x0104); 1287e4b496a3SSwapnil Jakhade if (ssc) 1288e4b496a3SSwapnil Jakhade cdns_torrent_dp_enable_ssc_25mhz(cdns_phy, 0x03B9); 1289c589e701SYuti Amonkar break; 1290c589e701SYuti Amonkar /* Setting VCO for 8.64GHz */ 1291c589e701SYuti Amonkar case 2160: 1292c589e701SYuti Amonkar case 4320: 129369d114acSSwapnil Jakhade cdns_torrent_phy_write(regmap, CMN_PLL0_INTDIV_M0, 0x0159); 129469d114acSSwapnil Jakhade cdns_torrent_phy_write(regmap, CMN_PLL0_FRACDIVL_M0, 0x999A); 129569d114acSSwapnil Jakhade cdns_torrent_phy_write(regmap, CMN_PLL0_FRACDIVH_M0, 0x0002); 129669d114acSSwapnil Jakhade cdns_torrent_phy_write(regmap, CMN_PLL0_HIGH_THR_M0, 0x00E7); 129769d114acSSwapnil Jakhade cdns_torrent_phy_write(regmap, CMN_PLL1_INTDIV_M0, 0x0159); 129869d114acSSwapnil Jakhade cdns_torrent_phy_write(regmap, CMN_PLL1_FRACDIVL_M0, 0x999A); 129969d114acSSwapnil Jakhade cdns_torrent_phy_write(regmap, CMN_PLL1_FRACDIVH_M0, 0x0002); 130069d114acSSwapnil Jakhade cdns_torrent_phy_write(regmap, CMN_PLL1_HIGH_THR_M0, 0x00E7); 1301e4b496a3SSwapnil Jakhade if (ssc) 1302e4b496a3SSwapnil Jakhade cdns_torrent_dp_enable_ssc_25mhz(cdns_phy, 0x034F); 1303c589e701SYuti Amonkar break; 1304c589e701SYuti Amonkar /* Setting VCO for 8.1GHz */ 1305c589e701SYuti Amonkar case 8100: 130669d114acSSwapnil Jakhade cdns_torrent_phy_write(regmap, CMN_PLL0_INTDIV_M0, 0x0144); 130769d114acSSwapnil Jakhade cdns_torrent_phy_write(regmap, CMN_PLL0_FRACDIVL_M0, 0x0000); 130869d114acSSwapnil Jakhade cdns_torrent_phy_write(regmap, CMN_PLL0_FRACDIVH_M0, 0x0002); 130969d114acSSwapnil Jakhade cdns_torrent_phy_write(regmap, CMN_PLL0_HIGH_THR_M0, 0x00D8); 131069d114acSSwapnil Jakhade cdns_torrent_phy_write(regmap, CMN_PLL1_INTDIV_M0, 0x0144); 131169d114acSSwapnil Jakhade cdns_torrent_phy_write(regmap, CMN_PLL1_FRACDIVL_M0, 0x0000); 131269d114acSSwapnil Jakhade cdns_torrent_phy_write(regmap, CMN_PLL1_FRACDIVH_M0, 0x0002); 131369d114acSSwapnil Jakhade cdns_torrent_phy_write(regmap, CMN_PLL1_HIGH_THR_M0, 0x00D8); 1314e4b496a3SSwapnil Jakhade if (ssc) 1315e4b496a3SSwapnil Jakhade cdns_torrent_dp_enable_ssc_25mhz(cdns_phy, 0x031A); 1316c589e701SYuti Amonkar break; 1317c589e701SYuti Amonkar } 1318c589e701SYuti Amonkar 131969d114acSSwapnil Jakhade cdns_torrent_phy_write(regmap, CMN_PDIAG_PLL0_CTRL_M0, 0x0002); 132069d114acSSwapnil Jakhade cdns_torrent_phy_write(regmap, CMN_PDIAG_PLL1_CTRL_M0, 0x0002); 1321e4b496a3SSwapnil Jakhade 1322e4b496a3SSwapnil Jakhade if (ssc) { 132369d114acSSwapnil Jakhade cdns_torrent_phy_write(regmap, 1324e4b496a3SSwapnil Jakhade CMN_PLL0_VCOCAL_PLLCNT_START, 0x0315); 132569d114acSSwapnil Jakhade cdns_torrent_phy_write(regmap, 1326e4b496a3SSwapnil Jakhade CMN_PLL0_LOCK_PLLCNT_THR, 0x0005); 132769d114acSSwapnil Jakhade cdns_torrent_phy_write(regmap, 1328e4b496a3SSwapnil Jakhade CMN_PLL1_VCOCAL_PLLCNT_START, 0x0315); 132969d114acSSwapnil Jakhade cdns_torrent_phy_write(regmap, 1330e4b496a3SSwapnil Jakhade CMN_PLL1_LOCK_PLLCNT_THR, 0x0005); 1331e4b496a3SSwapnil Jakhade } else { 133269d114acSSwapnil Jakhade cdns_torrent_phy_write(regmap, 1333e4b496a3SSwapnil Jakhade CMN_PLL0_VCOCAL_PLLCNT_START, 0x0317); 133469d114acSSwapnil Jakhade cdns_torrent_phy_write(regmap, 1335e4b496a3SSwapnil Jakhade CMN_PLL1_VCOCAL_PLLCNT_START, 0x0317); 1336e4b496a3SSwapnil Jakhade /* Set reset register values to disable SSC */ 133769d114acSSwapnil Jakhade cdns_torrent_phy_write(regmap, CMN_PLL0_SS_CTRL1_M0, 0x0002); 133869d114acSSwapnil Jakhade cdns_torrent_phy_write(regmap, CMN_PLL0_SS_CTRL2_M0, 0x0000); 133969d114acSSwapnil Jakhade cdns_torrent_phy_write(regmap, CMN_PLL0_SS_CTRL3_M0, 0x0000); 134069d114acSSwapnil Jakhade cdns_torrent_phy_write(regmap, CMN_PLL0_SS_CTRL4_M0, 0x0000); 134169d114acSSwapnil Jakhade cdns_torrent_phy_write(regmap, 1342e4b496a3SSwapnil Jakhade CMN_PLL0_LOCK_PLLCNT_THR, 0x0003); 134369d114acSSwapnil Jakhade cdns_torrent_phy_write(regmap, CMN_PLL1_SS_CTRL1_M0, 0x0002); 134469d114acSSwapnil Jakhade cdns_torrent_phy_write(regmap, CMN_PLL1_SS_CTRL2_M0, 0x0000); 134569d114acSSwapnil Jakhade cdns_torrent_phy_write(regmap, CMN_PLL1_SS_CTRL3_M0, 0x0000); 134669d114acSSwapnil Jakhade cdns_torrent_phy_write(regmap, CMN_PLL1_SS_CTRL4_M0, 0x0000); 134769d114acSSwapnil Jakhade cdns_torrent_phy_write(regmap, 1348e4b496a3SSwapnil Jakhade CMN_PLL1_LOCK_PLLCNT_THR, 0x0003); 1349c589e701SYuti Amonkar } 1350c589e701SYuti Amonkar 135169d114acSSwapnil Jakhade cdns_torrent_phy_write(regmap, CMN_PLL0_LOCK_REFCNT_START, 0x00C7); 135269d114acSSwapnil Jakhade cdns_torrent_phy_write(regmap, CMN_PLL0_LOCK_PLLCNT_START, 0x00C7); 135369d114acSSwapnil Jakhade cdns_torrent_phy_write(regmap, CMN_PLL1_LOCK_REFCNT_START, 0x00C7); 135469d114acSSwapnil Jakhade cdns_torrent_phy_write(regmap, CMN_PLL1_LOCK_PLLCNT_START, 0x00C7); 1355e4b496a3SSwapnil Jakhade } 1356e4b496a3SSwapnil Jakhade 1357e4b496a3SSwapnil Jakhade static void cdns_torrent_dp_pma_cmn_rate(struct cdns_torrent_phy *cdns_phy, 1358e4b496a3SSwapnil Jakhade u32 rate, u32 num_lanes) 1359c589e701SYuti Amonkar { 1360c589e701SYuti Amonkar unsigned int clk_sel_val = 0; 1361c589e701SYuti Amonkar unsigned int hsclk_div_val = 0; 1362c589e701SYuti Amonkar unsigned int i; 1363c589e701SYuti Amonkar 1364c589e701SYuti Amonkar /* 16'h0000 for single DP link configuration */ 136569d114acSSwapnil Jakhade regmap_field_write(cdns_phy->phy_pll_cfg, 0x0); 1366c589e701SYuti Amonkar 1367e4b496a3SSwapnil Jakhade switch (rate) { 1368c589e701SYuti Amonkar case 1620: 1369c589e701SYuti Amonkar clk_sel_val = 0x0f01; 1370c589e701SYuti Amonkar hsclk_div_val = 2; 1371c589e701SYuti Amonkar break; 1372c589e701SYuti Amonkar case 2160: 1373c589e701SYuti Amonkar case 2430: 1374c589e701SYuti Amonkar case 2700: 1375c589e701SYuti Amonkar clk_sel_val = 0x0701; 1376c589e701SYuti Amonkar hsclk_div_val = 1; 1377c589e701SYuti Amonkar break; 1378c589e701SYuti Amonkar case 3240: 1379c589e701SYuti Amonkar clk_sel_val = 0x0b00; 1380c589e701SYuti Amonkar hsclk_div_val = 2; 1381c589e701SYuti Amonkar break; 1382c589e701SYuti Amonkar case 4320: 1383c589e701SYuti Amonkar case 5400: 1384c589e701SYuti Amonkar clk_sel_val = 0x0301; 1385c589e701SYuti Amonkar hsclk_div_val = 0; 1386c589e701SYuti Amonkar break; 1387c589e701SYuti Amonkar case 8100: 1388c589e701SYuti Amonkar clk_sel_val = 0x0200; 1389c589e701SYuti Amonkar hsclk_div_val = 0; 1390c589e701SYuti Amonkar break; 1391c589e701SYuti Amonkar } 1392c589e701SYuti Amonkar 139369d114acSSwapnil Jakhade cdns_torrent_phy_write(cdns_phy->regmap_common_cdb, 1394ccb1b89dSSwapnil Jakhade CMN_PDIAG_PLL0_CLK_SEL_M0, clk_sel_val); 139569d114acSSwapnil Jakhade cdns_torrent_phy_write(cdns_phy->regmap_common_cdb, 1396e4b496a3SSwapnil Jakhade CMN_PDIAG_PLL1_CLK_SEL_M0, clk_sel_val); 1397c589e701SYuti Amonkar 1398c589e701SYuti Amonkar /* PMA lane configuration to deal with multi-link operation */ 1399e4b496a3SSwapnil Jakhade for (i = 0; i < num_lanes; i++) 140069d114acSSwapnil Jakhade cdns_torrent_phy_write(cdns_phy->regmap_tx_lane_cdb[i], 140169d114acSSwapnil Jakhade XCVR_DIAG_HSCLK_DIV, hsclk_div_val); 1402c589e701SYuti Amonkar } 1403c589e701SYuti Amonkar 140492e9ccc6SSwapnil Jakhade static void cdns_torrent_dp_pma_lane_cfg(struct cdns_torrent_phy *cdns_phy, 1405c589e701SYuti Amonkar unsigned int lane) 1406c589e701SYuti Amonkar { 1407e4b496a3SSwapnil Jakhade /* Per lane, refclock-dependent receiver detection setting */ 1408e4b496a3SSwapnil Jakhade if (cdns_phy->ref_clk_rate == REF_CLK_19_2MHz) 140969d114acSSwapnil Jakhade cdns_torrent_phy_write(cdns_phy->regmap_tx_lane_cdb[lane], 141069d114acSSwapnil Jakhade TX_RCVDET_ST_TMR, 0x0780); 1411e4b496a3SSwapnil Jakhade else if (cdns_phy->ref_clk_rate == REF_CLK_25MHz) 141269d114acSSwapnil Jakhade cdns_torrent_phy_write(cdns_phy->regmap_tx_lane_cdb[lane], 141369d114acSSwapnil Jakhade TX_RCVDET_ST_TMR, 0x09C4); 1414e4b496a3SSwapnil Jakhade 1415c589e701SYuti Amonkar /* Writing Tx/Rx Power State Controllers registers */ 141669d114acSSwapnil Jakhade cdns_torrent_phy_write(cdns_phy->regmap_tx_lane_cdb[lane], 141769d114acSSwapnil Jakhade TX_PSC_A0, 0x00FB); 141869d114acSSwapnil Jakhade cdns_torrent_phy_write(cdns_phy->regmap_tx_lane_cdb[lane], 141969d114acSSwapnil Jakhade TX_PSC_A2, 0x04AA); 142069d114acSSwapnil Jakhade cdns_torrent_phy_write(cdns_phy->regmap_tx_lane_cdb[lane], 142169d114acSSwapnil Jakhade TX_PSC_A3, 0x04AA); 142269d114acSSwapnil Jakhade cdns_torrent_phy_write(cdns_phy->regmap_rx_lane_cdb[lane], 142369d114acSSwapnil Jakhade RX_PSC_A0, 0x0000); 142469d114acSSwapnil Jakhade cdns_torrent_phy_write(cdns_phy->regmap_rx_lane_cdb[lane], 142569d114acSSwapnil Jakhade RX_PSC_A2, 0x0000); 142669d114acSSwapnil Jakhade cdns_torrent_phy_write(cdns_phy->regmap_rx_lane_cdb[lane], 142769d114acSSwapnil Jakhade RX_PSC_A3, 0x0000); 1428c589e701SYuti Amonkar 142969d114acSSwapnil Jakhade cdns_torrent_phy_write(cdns_phy->regmap_rx_lane_cdb[lane], 143069d114acSSwapnil Jakhade RX_PSC_CAL, 0x0000); 1431e4b496a3SSwapnil Jakhade 143269d114acSSwapnil Jakhade cdns_torrent_phy_write(cdns_phy->regmap_rx_lane_cdb[lane], 143369d114acSSwapnil Jakhade RX_REE_GCSM1_CTRL, 0x0000); 143469d114acSSwapnil Jakhade cdns_torrent_phy_write(cdns_phy->regmap_rx_lane_cdb[lane], 143569d114acSSwapnil Jakhade RX_REE_GCSM2_CTRL, 0x0000); 143669d114acSSwapnil Jakhade cdns_torrent_phy_write(cdns_phy->regmap_rx_lane_cdb[lane], 143769d114acSSwapnil Jakhade RX_REE_PERGCSM_CTRL, 0x0000); 1438e4b496a3SSwapnil Jakhade 143969d114acSSwapnil Jakhade cdns_torrent_phy_write(cdns_phy->regmap_tx_lane_cdb[lane], 144069d114acSSwapnil Jakhade XCVR_DIAG_BIDI_CTRL, 0x000F); 144169d114acSSwapnil Jakhade cdns_torrent_phy_write(cdns_phy->regmap_tx_lane_cdb[lane], 144269d114acSSwapnil Jakhade XCVR_DIAG_PLLDRC_CTRL, 0x0001); 144369d114acSSwapnil Jakhade cdns_torrent_phy_write(cdns_phy->regmap_tx_lane_cdb[lane], 144469d114acSSwapnil Jakhade XCVR_DIAG_HSCLK_SEL, 0x0000); 1445c589e701SYuti Amonkar } 1446c589e701SYuti Amonkar 144721c79146SSwapnil Jakhade static int cdns_torrent_dp_set_power_state(struct cdns_torrent_phy *cdns_phy, 144821c79146SSwapnil Jakhade u32 num_lanes, 144921c79146SSwapnil Jakhade enum phy_powerstate powerstate) 145021c79146SSwapnil Jakhade { 145121c79146SSwapnil Jakhade /* Register value for power state for a single byte. */ 145221c79146SSwapnil Jakhade u32 value_part; 145321c79146SSwapnil Jakhade u32 value; 145421c79146SSwapnil Jakhade u32 mask; 145521c79146SSwapnil Jakhade u32 read_val; 145621c79146SSwapnil Jakhade u32 ret; 1457cba472ecSSwapnil Jakhade struct regmap *regmap = cdns_phy->regmap_dptx_phy_reg; 145821c79146SSwapnil Jakhade 145921c79146SSwapnil Jakhade switch (powerstate) { 146021c79146SSwapnil Jakhade case (POWERSTATE_A0): 146121c79146SSwapnil Jakhade value_part = 0x01U; 146221c79146SSwapnil Jakhade break; 146321c79146SSwapnil Jakhade case (POWERSTATE_A2): 146421c79146SSwapnil Jakhade value_part = 0x04U; 146521c79146SSwapnil Jakhade break; 146621c79146SSwapnil Jakhade default: 146721c79146SSwapnil Jakhade /* Powerstate A3 */ 146821c79146SSwapnil Jakhade value_part = 0x08U; 146921c79146SSwapnil Jakhade break; 147021c79146SSwapnil Jakhade } 147121c79146SSwapnil Jakhade 147221c79146SSwapnil Jakhade /* Select values of registers and mask, depending on enabled 147321c79146SSwapnil Jakhade * lane count. 147421c79146SSwapnil Jakhade */ 147521c79146SSwapnil Jakhade switch (num_lanes) { 147621c79146SSwapnil Jakhade /* lane 0 */ 147721c79146SSwapnil Jakhade case (1): 147821c79146SSwapnil Jakhade value = value_part; 147921c79146SSwapnil Jakhade mask = 0x0000003FU; 148021c79146SSwapnil Jakhade break; 148121c79146SSwapnil Jakhade /* lanes 0-1 */ 148221c79146SSwapnil Jakhade case (2): 148321c79146SSwapnil Jakhade value = (value_part 148421c79146SSwapnil Jakhade | (value_part << 8)); 148521c79146SSwapnil Jakhade mask = 0x00003F3FU; 148621c79146SSwapnil Jakhade break; 148721c79146SSwapnil Jakhade /* lanes 0-3, all */ 148821c79146SSwapnil Jakhade default: 148921c79146SSwapnil Jakhade value = (value_part 149021c79146SSwapnil Jakhade | (value_part << 8) 149121c79146SSwapnil Jakhade | (value_part << 16) 149221c79146SSwapnil Jakhade | (value_part << 24)); 149321c79146SSwapnil Jakhade mask = 0x3F3F3F3FU; 149421c79146SSwapnil Jakhade break; 149521c79146SSwapnil Jakhade } 149621c79146SSwapnil Jakhade 149721c79146SSwapnil Jakhade /* Set power state A<n>. */ 1498cba472ecSSwapnil Jakhade cdns_torrent_dp_write(regmap, PHY_PMA_XCVR_POWER_STATE_REQ, value); 149921c79146SSwapnil Jakhade /* Wait, until PHY acknowledges power state completion. */ 1500cba472ecSSwapnil Jakhade ret = regmap_read_poll_timeout(regmap, PHY_PMA_XCVR_POWER_STATE_ACK, 1501cba472ecSSwapnil Jakhade read_val, (read_val & mask) == value, 0, 150221c79146SSwapnil Jakhade POLL_TIMEOUT_US); 1503cba472ecSSwapnil Jakhade cdns_torrent_dp_write(regmap, PHY_PMA_XCVR_POWER_STATE_REQ, 0x00000000); 150421c79146SSwapnil Jakhade ndelay(100); 150521c79146SSwapnil Jakhade 150621c79146SSwapnil Jakhade return ret; 150721c79146SSwapnil Jakhade } 150821c79146SSwapnil Jakhade 1509572d6592SSwapnil Jakhade static int cdns_torrent_dp_run(struct cdns_torrent_phy *cdns_phy, u32 num_lanes) 1510c589e701SYuti Amonkar { 1511c589e701SYuti Amonkar unsigned int read_val; 1512c589e701SYuti Amonkar int ret; 1513cba472ecSSwapnil Jakhade struct regmap *regmap = cdns_phy->regmap_dptx_phy_reg; 1514c589e701SYuti Amonkar 1515c589e701SYuti Amonkar /* 1516c589e701SYuti Amonkar * waiting for ACK of pma_xcvr_pllclk_en_ln_*, only for the 1517c589e701SYuti Amonkar * master lane 1518c589e701SYuti Amonkar */ 1519cba472ecSSwapnil Jakhade ret = regmap_read_poll_timeout(regmap, PHY_PMA_XCVR_PLLCLK_EN_ACK, 1520cba472ecSSwapnil Jakhade read_val, read_val & 1, 1521cba472ecSSwapnil Jakhade 0, POLL_TIMEOUT_US); 152221c79146SSwapnil Jakhade if (ret == -ETIMEDOUT) { 1523c589e701SYuti Amonkar dev_err(cdns_phy->dev, 1524c589e701SYuti Amonkar "timeout waiting for link PLL clock enable ack\n"); 152521c79146SSwapnil Jakhade return ret; 1526c589e701SYuti Amonkar } 1527c589e701SYuti Amonkar 1528c589e701SYuti Amonkar ndelay(100); 1529c589e701SYuti Amonkar 1530572d6592SSwapnil Jakhade ret = cdns_torrent_dp_set_power_state(cdns_phy, num_lanes, 153121c79146SSwapnil Jakhade POWERSTATE_A2); 153221c79146SSwapnil Jakhade if (ret) 153321c79146SSwapnil Jakhade return ret; 1534c589e701SYuti Amonkar 1535572d6592SSwapnil Jakhade ret = cdns_torrent_dp_set_power_state(cdns_phy, num_lanes, 153621c79146SSwapnil Jakhade POWERSTATE_A0); 1537c589e701SYuti Amonkar 153821c79146SSwapnil Jakhade return ret; 1539c589e701SYuti Amonkar } 1540c589e701SYuti Amonkar 1541afa4ba05SSwapnil Jakhade static int cdns_torrent_phy_on(struct phy *phy) 1542afa4ba05SSwapnil Jakhade { 1543afa4ba05SSwapnil Jakhade struct cdns_torrent_inst *inst = phy_get_drvdata(phy); 1544afa4ba05SSwapnil Jakhade struct cdns_torrent_phy *cdns_phy = dev_get_drvdata(phy->dev.parent); 1545afa4ba05SSwapnil Jakhade int ret; 1546afa4ba05SSwapnil Jakhade 1547afa4ba05SSwapnil Jakhade /* Take the PHY out of reset */ 1548afa4ba05SSwapnil Jakhade ret = reset_control_deassert(cdns_phy->phy_rst); 1549afa4ba05SSwapnil Jakhade if (ret) 1550afa4ba05SSwapnil Jakhade return ret; 1551afa4ba05SSwapnil Jakhade 1552afa4ba05SSwapnil Jakhade /* Take the PHY lane group out of reset */ 1553afa4ba05SSwapnil Jakhade return reset_control_deassert(inst->lnk_rst); 1554afa4ba05SSwapnil Jakhade } 1555afa4ba05SSwapnil Jakhade 1556afa4ba05SSwapnil Jakhade static int cdns_torrent_phy_off(struct phy *phy) 1557afa4ba05SSwapnil Jakhade { 1558afa4ba05SSwapnil Jakhade struct cdns_torrent_inst *inst = phy_get_drvdata(phy); 1559afa4ba05SSwapnil Jakhade struct cdns_torrent_phy *cdns_phy = dev_get_drvdata(phy->dev.parent); 1560afa4ba05SSwapnil Jakhade int ret; 1561afa4ba05SSwapnil Jakhade 1562afa4ba05SSwapnil Jakhade ret = reset_control_assert(cdns_phy->phy_rst); 1563afa4ba05SSwapnil Jakhade if (ret) 1564afa4ba05SSwapnil Jakhade return ret; 1565afa4ba05SSwapnil Jakhade 1566afa4ba05SSwapnil Jakhade return reset_control_assert(inst->lnk_rst); 1567afa4ba05SSwapnil Jakhade } 1568c589e701SYuti Amonkar 156969d114acSSwapnil Jakhade static struct regmap *cdns_regmap_init(struct device *dev, void __iomem *base, 157069d114acSSwapnil Jakhade u32 block_offset, 157169d114acSSwapnil Jakhade u8 reg_offset_shift, 157269d114acSSwapnil Jakhade const struct regmap_config *config) 157369d114acSSwapnil Jakhade { 157469d114acSSwapnil Jakhade struct cdns_regmap_cdb_context *ctx; 157569d114acSSwapnil Jakhade 157669d114acSSwapnil Jakhade ctx = devm_kzalloc(dev, sizeof(*ctx), GFP_KERNEL); 157769d114acSSwapnil Jakhade if (!ctx) 157869d114acSSwapnil Jakhade return ERR_PTR(-ENOMEM); 157969d114acSSwapnil Jakhade 158069d114acSSwapnil Jakhade ctx->dev = dev; 158169d114acSSwapnil Jakhade ctx->base = base + block_offset; 158269d114acSSwapnil Jakhade ctx->reg_offset_shift = reg_offset_shift; 158369d114acSSwapnil Jakhade 158469d114acSSwapnil Jakhade return devm_regmap_init(dev, NULL, ctx, config); 158569d114acSSwapnil Jakhade } 158669d114acSSwapnil Jakhade 158769d114acSSwapnil Jakhade static int cdns_regfield_init(struct cdns_torrent_phy *cdns_phy) 158869d114acSSwapnil Jakhade { 158969d114acSSwapnil Jakhade struct device *dev = cdns_phy->dev; 159069d114acSSwapnil Jakhade struct regmap_field *field; 159169d114acSSwapnil Jakhade struct regmap *regmap; 159269d114acSSwapnil Jakhade 159369d114acSSwapnil Jakhade regmap = cdns_phy->regmap_phy_pcs_common_cdb; 159469d114acSSwapnil Jakhade field = devm_regmap_field_alloc(dev, regmap, phy_pll_cfg); 159569d114acSSwapnil Jakhade if (IS_ERR(field)) { 159669d114acSSwapnil Jakhade dev_err(dev, "PHY_PLL_CFG reg field init failed\n"); 159769d114acSSwapnil Jakhade return PTR_ERR(field); 159869d114acSSwapnil Jakhade } 159969d114acSSwapnil Jakhade cdns_phy->phy_pll_cfg = field; 160069d114acSSwapnil Jakhade 160169d114acSSwapnil Jakhade regmap = cdns_phy->regmap_phy_pma_common_cdb; 160269d114acSSwapnil Jakhade field = devm_regmap_field_alloc(dev, regmap, phy_pma_cmn_ctrl_2); 160369d114acSSwapnil Jakhade if (IS_ERR(field)) { 160469d114acSSwapnil Jakhade dev_err(dev, "PHY_PMA_CMN_CTRL2 reg field init failed\n"); 160569d114acSSwapnil Jakhade return PTR_ERR(field); 160669d114acSSwapnil Jakhade } 160769d114acSSwapnil Jakhade cdns_phy->phy_pma_cmn_ctrl_2 = field; 160869d114acSSwapnil Jakhade 160969d114acSSwapnil Jakhade regmap = cdns_phy->regmap_phy_pma_common_cdb; 161069d114acSSwapnil Jakhade field = devm_regmap_field_alloc(dev, regmap, phy_pma_pll_raw_ctrl); 161169d114acSSwapnil Jakhade if (IS_ERR(field)) { 161269d114acSSwapnil Jakhade dev_err(dev, "PHY_PMA_PLL_RAW_CTRL reg field init failed\n"); 161369d114acSSwapnil Jakhade return PTR_ERR(field); 161469d114acSSwapnil Jakhade } 161569d114acSSwapnil Jakhade cdns_phy->phy_pma_pll_raw_ctrl = field; 161669d114acSSwapnil Jakhade 1617cba472ecSSwapnil Jakhade regmap = cdns_phy->regmap_dptx_phy_reg; 1618cba472ecSSwapnil Jakhade field = devm_regmap_field_alloc(dev, regmap, phy_reset_ctrl); 1619cba472ecSSwapnil Jakhade if (IS_ERR(field)) { 1620cba472ecSSwapnil Jakhade dev_err(dev, "PHY_RESET reg field init failed\n"); 1621cba472ecSSwapnil Jakhade return PTR_ERR(field); 1622cba472ecSSwapnil Jakhade } 1623cba472ecSSwapnil Jakhade cdns_phy->phy_reset_ctrl = field; 1624cba472ecSSwapnil Jakhade 162569d114acSSwapnil Jakhade return 0; 162669d114acSSwapnil Jakhade } 162769d114acSSwapnil Jakhade 162869d114acSSwapnil Jakhade static int cdns_regmap_init_torrent_dp(struct cdns_torrent_phy *cdns_phy, 162969d114acSSwapnil Jakhade void __iomem *sd_base, 163069d114acSSwapnil Jakhade void __iomem *base, 163169d114acSSwapnil Jakhade u8 block_offset_shift, 163269d114acSSwapnil Jakhade u8 reg_offset_shift) 163369d114acSSwapnil Jakhade { 163469d114acSSwapnil Jakhade struct device *dev = cdns_phy->dev; 163569d114acSSwapnil Jakhade struct regmap *regmap; 163669d114acSSwapnil Jakhade u32 block_offset; 163769d114acSSwapnil Jakhade int i; 163869d114acSSwapnil Jakhade 163969d114acSSwapnil Jakhade for (i = 0; i < MAX_NUM_LANES; i++) { 164069d114acSSwapnil Jakhade block_offset = TORRENT_TX_LANE_CDB_OFFSET(i, block_offset_shift, 164169d114acSSwapnil Jakhade reg_offset_shift); 164269d114acSSwapnil Jakhade regmap = cdns_regmap_init(dev, sd_base, block_offset, 164369d114acSSwapnil Jakhade reg_offset_shift, 164469d114acSSwapnil Jakhade &cdns_torrent_tx_lane_cdb_config[i]); 164569d114acSSwapnil Jakhade if (IS_ERR(regmap)) { 164669d114acSSwapnil Jakhade dev_err(dev, "Failed to init tx lane CDB regmap\n"); 164769d114acSSwapnil Jakhade return PTR_ERR(regmap); 164869d114acSSwapnil Jakhade } 164969d114acSSwapnil Jakhade cdns_phy->regmap_tx_lane_cdb[i] = regmap; 165069d114acSSwapnil Jakhade 165169d114acSSwapnil Jakhade block_offset = TORRENT_RX_LANE_CDB_OFFSET(i, block_offset_shift, 165269d114acSSwapnil Jakhade reg_offset_shift); 165369d114acSSwapnil Jakhade regmap = cdns_regmap_init(dev, sd_base, block_offset, 165469d114acSSwapnil Jakhade reg_offset_shift, 165569d114acSSwapnil Jakhade &cdns_torrent_rx_lane_cdb_config[i]); 165669d114acSSwapnil Jakhade if (IS_ERR(regmap)) { 165769d114acSSwapnil Jakhade dev_err(dev, "Failed to init rx lane CDB regmap\n"); 165869d114acSSwapnil Jakhade return PTR_ERR(regmap); 165969d114acSSwapnil Jakhade } 166069d114acSSwapnil Jakhade cdns_phy->regmap_rx_lane_cdb[i] = regmap; 166169d114acSSwapnil Jakhade } 166269d114acSSwapnil Jakhade 166369d114acSSwapnil Jakhade block_offset = TORRENT_COMMON_CDB_OFFSET; 166469d114acSSwapnil Jakhade regmap = cdns_regmap_init(dev, sd_base, block_offset, 166569d114acSSwapnil Jakhade reg_offset_shift, 166669d114acSSwapnil Jakhade &cdns_torrent_common_cdb_config); 166769d114acSSwapnil Jakhade if (IS_ERR(regmap)) { 166869d114acSSwapnil Jakhade dev_err(dev, "Failed to init common CDB regmap\n"); 166969d114acSSwapnil Jakhade return PTR_ERR(regmap); 167069d114acSSwapnil Jakhade } 167169d114acSSwapnil Jakhade cdns_phy->regmap_common_cdb = regmap; 167269d114acSSwapnil Jakhade 167369d114acSSwapnil Jakhade block_offset = TORRENT_PHY_PCS_COMMON_OFFSET(block_offset_shift); 167469d114acSSwapnil Jakhade regmap = cdns_regmap_init(dev, sd_base, block_offset, 167569d114acSSwapnil Jakhade reg_offset_shift, 167669d114acSSwapnil Jakhade &cdns_torrent_phy_pcs_cmn_cdb_config); 167769d114acSSwapnil Jakhade if (IS_ERR(regmap)) { 167869d114acSSwapnil Jakhade dev_err(dev, "Failed to init PHY PCS common CDB regmap\n"); 167969d114acSSwapnil Jakhade return PTR_ERR(regmap); 168069d114acSSwapnil Jakhade } 168169d114acSSwapnil Jakhade cdns_phy->regmap_phy_pcs_common_cdb = regmap; 168269d114acSSwapnil Jakhade 168369d114acSSwapnil Jakhade block_offset = TORRENT_PHY_PMA_COMMON_OFFSET(block_offset_shift); 168469d114acSSwapnil Jakhade regmap = cdns_regmap_init(dev, sd_base, block_offset, 168569d114acSSwapnil Jakhade reg_offset_shift, 168669d114acSSwapnil Jakhade &cdns_torrent_phy_pma_cmn_cdb_config); 168769d114acSSwapnil Jakhade if (IS_ERR(regmap)) { 168869d114acSSwapnil Jakhade dev_err(dev, "Failed to init PHY PMA common CDB regmap\n"); 168969d114acSSwapnil Jakhade return PTR_ERR(regmap); 169069d114acSSwapnil Jakhade } 169169d114acSSwapnil Jakhade cdns_phy->regmap_phy_pma_common_cdb = regmap; 169269d114acSSwapnil Jakhade 1693cba472ecSSwapnil Jakhade block_offset = TORRENT_DPTX_PHY_OFFSET; 1694cba472ecSSwapnil Jakhade regmap = cdns_regmap_init(dev, base, block_offset, 1695cba472ecSSwapnil Jakhade reg_offset_shift, 1696cba472ecSSwapnil Jakhade &cdns_torrent_dptx_phy_config); 1697cba472ecSSwapnil Jakhade if (IS_ERR(regmap)) { 1698cba472ecSSwapnil Jakhade dev_err(dev, "Failed to init DPTX PHY regmap\n"); 1699cba472ecSSwapnil Jakhade return PTR_ERR(regmap); 1700cba472ecSSwapnil Jakhade } 1701cba472ecSSwapnil Jakhade cdns_phy->regmap_dptx_phy_reg = regmap; 1702cba472ecSSwapnil Jakhade 170369d114acSSwapnil Jakhade return 0; 170469d114acSSwapnil Jakhade } 170569d114acSSwapnil Jakhade 170692e9ccc6SSwapnil Jakhade static int cdns_torrent_phy_probe(struct platform_device *pdev) 1707c589e701SYuti Amonkar { 1708c589e701SYuti Amonkar struct resource *regs; 170992e9ccc6SSwapnil Jakhade struct cdns_torrent_phy *cdns_phy; 1710c589e701SYuti Amonkar struct device *dev = &pdev->dev; 1711c589e701SYuti Amonkar struct phy_provider *phy_provider; 1712*29d1fd2fSSwapnil Jakhade const struct cdns_torrent_data *data; 1713afa4ba05SSwapnil Jakhade struct device_node *child; 1714afa4ba05SSwapnil Jakhade int ret, subnodes, node = 0, i; 171569d114acSSwapnil Jakhade 171669d114acSSwapnil Jakhade /* Get init data for this PHY */ 1717*29d1fd2fSSwapnil Jakhade data = of_device_get_match_data(dev); 1718*29d1fd2fSSwapnil Jakhade if (!data) 171969d114acSSwapnil Jakhade return -EINVAL; 172069d114acSSwapnil Jakhade 1721c589e701SYuti Amonkar cdns_phy = devm_kzalloc(dev, sizeof(*cdns_phy), GFP_KERNEL); 1722c589e701SYuti Amonkar if (!cdns_phy) 1723c589e701SYuti Amonkar return -ENOMEM; 1724c589e701SYuti Amonkar 1725afa4ba05SSwapnil Jakhade dev_set_drvdata(dev, cdns_phy); 1726afa4ba05SSwapnil Jakhade cdns_phy->dev = dev; 1727*29d1fd2fSSwapnil Jakhade cdns_phy->init_data = data; 1728c589e701SYuti Amonkar 1729afa4ba05SSwapnil Jakhade cdns_phy->phy_rst = devm_reset_control_get_exclusive_by_index(dev, 0); 1730afa4ba05SSwapnil Jakhade if (IS_ERR(cdns_phy->phy_rst)) { 1731afa4ba05SSwapnil Jakhade dev_err(dev, "%s: failed to get reset\n", 1732afa4ba05SSwapnil Jakhade dev->of_node->full_name); 1733afa4ba05SSwapnil Jakhade return PTR_ERR(cdns_phy->phy_rst); 1734afa4ba05SSwapnil Jakhade } 1735afa4ba05SSwapnil Jakhade 1736afa4ba05SSwapnil Jakhade cdns_phy->clk = devm_clk_get(dev, "refclk"); 1737afa4ba05SSwapnil Jakhade if (IS_ERR(cdns_phy->clk)) { 1738afa4ba05SSwapnil Jakhade dev_err(dev, "phy ref clock not found\n"); 1739afa4ba05SSwapnil Jakhade return PTR_ERR(cdns_phy->clk); 1740c589e701SYuti Amonkar } 1741c589e701SYuti Amonkar 1742c589e701SYuti Amonkar regs = platform_get_resource(pdev, IORESOURCE_MEM, 0); 174369d114acSSwapnil Jakhade cdns_phy->sd_base = devm_ioremap_resource(&pdev->dev, regs); 174469d114acSSwapnil Jakhade if (IS_ERR(cdns_phy->sd_base)) 174569d114acSSwapnil Jakhade return PTR_ERR(cdns_phy->sd_base); 174669d114acSSwapnil Jakhade 1747afa4ba05SSwapnil Jakhade subnodes = of_get_available_child_count(dev->of_node); 1748afa4ba05SSwapnil Jakhade if (subnodes == 0) { 1749afa4ba05SSwapnil Jakhade dev_err(dev, "No available link subnodes found\n"); 1750afa4ba05SSwapnil Jakhade return -EINVAL; 1751afa4ba05SSwapnil Jakhade } else if (subnodes != 1) { 1752afa4ba05SSwapnil Jakhade dev_err(dev, "Driver supports only one link subnode.\n"); 1753afa4ba05SSwapnil Jakhade return -EINVAL; 1754afa4ba05SSwapnil Jakhade } 1755c589e701SYuti Amonkar 1756afa4ba05SSwapnil Jakhade for_each_available_child_of_node(dev->of_node, child) { 1757afa4ba05SSwapnil Jakhade struct phy *gphy; 1758c589e701SYuti Amonkar 1759afa4ba05SSwapnil Jakhade cdns_phy->phys[node].lnk_rst = 1760afa4ba05SSwapnil Jakhade of_reset_control_array_get_exclusive(child); 1761afa4ba05SSwapnil Jakhade if (IS_ERR(cdns_phy->phys[node].lnk_rst)) { 1762afa4ba05SSwapnil Jakhade dev_err(dev, "%s: failed to get reset\n", 1763afa4ba05SSwapnil Jakhade child->full_name); 1764afa4ba05SSwapnil Jakhade ret = PTR_ERR(cdns_phy->phys[node].lnk_rst); 1765afa4ba05SSwapnil Jakhade goto put_lnk_rst; 1766afa4ba05SSwapnil Jakhade } 1767c589e701SYuti Amonkar 1768afa4ba05SSwapnil Jakhade if (of_property_read_u32(child, "reg", 1769afa4ba05SSwapnil Jakhade &cdns_phy->phys[node].mlane)) { 1770afa4ba05SSwapnil Jakhade dev_err(dev, "%s: No \"reg\"-property.\n", 1771afa4ba05SSwapnil Jakhade child->full_name); 1772afa4ba05SSwapnil Jakhade ret = -EINVAL; 1773afa4ba05SSwapnil Jakhade goto put_child; 1774afa4ba05SSwapnil Jakhade } 1775afa4ba05SSwapnil Jakhade 1776afa4ba05SSwapnil Jakhade if (cdns_phy->phys[node].mlane != 0) { 1777afa4ba05SSwapnil Jakhade dev_err(dev, 1778afa4ba05SSwapnil Jakhade "%s: Driver supports only lane-0 as master lane.\n", 1779afa4ba05SSwapnil Jakhade child->full_name); 1780afa4ba05SSwapnil Jakhade ret = -EINVAL; 1781afa4ba05SSwapnil Jakhade goto put_child; 1782afa4ba05SSwapnil Jakhade } 1783afa4ba05SSwapnil Jakhade 1784afa4ba05SSwapnil Jakhade if (of_property_read_u32(child, "cdns,phy-type", 1785afa4ba05SSwapnil Jakhade &cdns_phy->phys[node].phy_type)) { 1786afa4ba05SSwapnil Jakhade dev_err(dev, "%s: No \"cdns,phy-type\"-property.\n", 1787afa4ba05SSwapnil Jakhade child->full_name); 1788afa4ba05SSwapnil Jakhade ret = -EINVAL; 1789afa4ba05SSwapnil Jakhade goto put_child; 1790afa4ba05SSwapnil Jakhade } 1791afa4ba05SSwapnil Jakhade 1792afa4ba05SSwapnil Jakhade cdns_phy->phys[node].num_lanes = DEFAULT_NUM_LANES; 1793afa4ba05SSwapnil Jakhade of_property_read_u32(child, "cdns,num-lanes", 1794afa4ba05SSwapnil Jakhade &cdns_phy->phys[node].num_lanes); 1795afa4ba05SSwapnil Jakhade 1796afa4ba05SSwapnil Jakhade if (cdns_phy->phys[node].phy_type == PHY_TYPE_DP) { 1797afa4ba05SSwapnil Jakhade switch (cdns_phy->phys[node].num_lanes) { 1798c589e701SYuti Amonkar case 1: 1799c589e701SYuti Amonkar case 2: 1800c589e701SYuti Amonkar case 4: 1801c589e701SYuti Amonkar /* valid number of lanes */ 1802c589e701SYuti Amonkar break; 1803c589e701SYuti Amonkar default: 1804c589e701SYuti Amonkar dev_err(dev, "unsupported number of lanes: %d\n", 1805afa4ba05SSwapnil Jakhade cdns_phy->phys[node].num_lanes); 1806afa4ba05SSwapnil Jakhade ret = -EINVAL; 1807afa4ba05SSwapnil Jakhade goto put_child; 1808c589e701SYuti Amonkar } 1809c589e701SYuti Amonkar 1810c589e701SYuti Amonkar cdns_phy->max_bit_rate = DEFAULT_MAX_BIT_RATE; 1811afa4ba05SSwapnil Jakhade of_property_read_u32(child, "cdns,max-bit-rate", 1812afa4ba05SSwapnil Jakhade &cdns_phy->max_bit_rate); 1813c589e701SYuti Amonkar 1814c589e701SYuti Amonkar switch (cdns_phy->max_bit_rate) { 1815e4b496a3SSwapnil Jakhade case 1620: 1816c589e701SYuti Amonkar case 2160: 1817c589e701SYuti Amonkar case 2430: 1818c589e701SYuti Amonkar case 2700: 1819c589e701SYuti Amonkar case 3240: 1820c589e701SYuti Amonkar case 4320: 1821c589e701SYuti Amonkar case 5400: 1822c589e701SYuti Amonkar case 8100: 1823c589e701SYuti Amonkar /* valid bit rate */ 1824c589e701SYuti Amonkar break; 1825c589e701SYuti Amonkar default: 1826c589e701SYuti Amonkar dev_err(dev, "unsupported max bit rate: %dMbps\n", 1827c589e701SYuti Amonkar cdns_phy->max_bit_rate); 1828afa4ba05SSwapnil Jakhade ret = -EINVAL; 1829afa4ba05SSwapnil Jakhade goto put_child; 1830c589e701SYuti Amonkar } 1831c589e701SYuti Amonkar 1832afa4ba05SSwapnil Jakhade /* DPTX registers */ 1833afa4ba05SSwapnil Jakhade regs = platform_get_resource(pdev, IORESOURCE_MEM, 1); 1834afa4ba05SSwapnil Jakhade cdns_phy->base = devm_ioremap_resource(&pdev->dev, 1835afa4ba05SSwapnil Jakhade regs); 1836afa4ba05SSwapnil Jakhade if (IS_ERR(cdns_phy->base)) { 1837afa4ba05SSwapnil Jakhade ret = PTR_ERR(cdns_phy->base); 1838afa4ba05SSwapnil Jakhade goto put_child; 1839e4b496a3SSwapnil Jakhade } 1840e4b496a3SSwapnil Jakhade 1841afa4ba05SSwapnil Jakhade gphy = devm_phy_create(dev, child, 1842afa4ba05SSwapnil Jakhade &cdns_torrent_phy_ops); 1843afa4ba05SSwapnil Jakhade if (IS_ERR(gphy)) { 1844afa4ba05SSwapnil Jakhade ret = PTR_ERR(gphy); 1845afa4ba05SSwapnil Jakhade goto put_child; 1846afa4ba05SSwapnil Jakhade } 1847afa4ba05SSwapnil Jakhade 1848afa4ba05SSwapnil Jakhade dev_info(dev, "%d lanes, max bit rate %d.%03d Gbps\n", 1849afa4ba05SSwapnil Jakhade cdns_phy->phys[node].num_lanes, 1850afa4ba05SSwapnil Jakhade cdns_phy->max_bit_rate / 1000, 1851afa4ba05SSwapnil Jakhade cdns_phy->max_bit_rate % 1000); 18520ffcc378SSwapnil Jakhade 18530ffcc378SSwapnil Jakhade gphy->attrs.bus_width = cdns_phy->phys[node].num_lanes; 18540ffcc378SSwapnil Jakhade gphy->attrs.max_link_rate = cdns_phy->max_bit_rate; 18550ffcc378SSwapnil Jakhade gphy->attrs.mode = PHY_MODE_DP; 1856afa4ba05SSwapnil Jakhade } else { 1857afa4ba05SSwapnil Jakhade dev_err(dev, "Driver supports only PHY_TYPE_DP\n"); 1858afa4ba05SSwapnil Jakhade ret = -ENOTSUPP; 1859afa4ba05SSwapnil Jakhade goto put_child; 1860afa4ba05SSwapnil Jakhade } 1861afa4ba05SSwapnil Jakhade cdns_phy->phys[node].phy = gphy; 1862afa4ba05SSwapnil Jakhade phy_set_drvdata(gphy, &cdns_phy->phys[node]); 1863afa4ba05SSwapnil Jakhade 1864afa4ba05SSwapnil Jakhade node++; 1865afa4ba05SSwapnil Jakhade } 1866afa4ba05SSwapnil Jakhade cdns_phy->nsubnodes = node; 1867c589e701SYuti Amonkar 186869d114acSSwapnil Jakhade ret = cdns_regmap_init_torrent_dp(cdns_phy, cdns_phy->sd_base, 186969d114acSSwapnil Jakhade cdns_phy->base, 187069d114acSSwapnil Jakhade data->block_offset_shift, 187169d114acSSwapnil Jakhade data->reg_offset_shift); 187269d114acSSwapnil Jakhade if (ret) 1873afa4ba05SSwapnil Jakhade goto put_lnk_rst; 187469d114acSSwapnil Jakhade 187569d114acSSwapnil Jakhade ret = cdns_regfield_init(cdns_phy); 187669d114acSSwapnil Jakhade if (ret) 1877afa4ba05SSwapnil Jakhade goto put_lnk_rst; 187869d114acSSwapnil Jakhade 1879c589e701SYuti Amonkar phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate); 1880afa4ba05SSwapnil Jakhade if (IS_ERR(phy_provider)) { 1881afa4ba05SSwapnil Jakhade ret = PTR_ERR(phy_provider); 1882afa4ba05SSwapnil Jakhade goto put_lnk_rst; 1883afa4ba05SSwapnil Jakhade } 1884c589e701SYuti Amonkar 1885afa4ba05SSwapnil Jakhade return 0; 1886c589e701SYuti Amonkar 1887afa4ba05SSwapnil Jakhade put_child: 1888afa4ba05SSwapnil Jakhade node++; 1889afa4ba05SSwapnil Jakhade put_lnk_rst: 1890afa4ba05SSwapnil Jakhade for (i = 0; i < node; i++) 1891afa4ba05SSwapnil Jakhade reset_control_put(cdns_phy->phys[i].lnk_rst); 1892afa4ba05SSwapnil Jakhade of_node_put(child); 1893afa4ba05SSwapnil Jakhade return ret; 1894afa4ba05SSwapnil Jakhade } 1895afa4ba05SSwapnil Jakhade 1896afa4ba05SSwapnil Jakhade static int cdns_torrent_phy_remove(struct platform_device *pdev) 1897afa4ba05SSwapnil Jakhade { 1898afa4ba05SSwapnil Jakhade struct cdns_torrent_phy *cdns_phy = platform_get_drvdata(pdev); 1899afa4ba05SSwapnil Jakhade int i; 1900afa4ba05SSwapnil Jakhade 1901afa4ba05SSwapnil Jakhade reset_control_assert(cdns_phy->phy_rst); 1902afa4ba05SSwapnil Jakhade for (i = 0; i < cdns_phy->nsubnodes; i++) { 1903afa4ba05SSwapnil Jakhade reset_control_assert(cdns_phy->phys[i].lnk_rst); 1904afa4ba05SSwapnil Jakhade reset_control_put(cdns_phy->phys[i].lnk_rst); 1905afa4ba05SSwapnil Jakhade } 1906afa4ba05SSwapnil Jakhade 1907afa4ba05SSwapnil Jakhade return 0; 1908c589e701SYuti Amonkar } 1909c589e701SYuti Amonkar 191069d114acSSwapnil Jakhade static const struct cdns_torrent_data cdns_map_torrent = { 191169d114acSSwapnil Jakhade .block_offset_shift = 0x2, 191269d114acSSwapnil Jakhade .reg_offset_shift = 0x2, 191369d114acSSwapnil Jakhade }; 191469d114acSSwapnil Jakhade 1915597bf3f1SSwapnil Jakhade static const struct cdns_torrent_data ti_j721e_map_torrent = { 1916597bf3f1SSwapnil Jakhade .block_offset_shift = 0x0, 1917597bf3f1SSwapnil Jakhade .reg_offset_shift = 0x1, 1918597bf3f1SSwapnil Jakhade }; 1919597bf3f1SSwapnil Jakhade 192092e9ccc6SSwapnil Jakhade static const struct of_device_id cdns_torrent_phy_of_match[] = { 1921c589e701SYuti Amonkar { 192269d114acSSwapnil Jakhade .compatible = "cdns,torrent-phy", 192369d114acSSwapnil Jakhade .data = &cdns_map_torrent, 1924c589e701SYuti Amonkar }, 1925597bf3f1SSwapnil Jakhade { 1926597bf3f1SSwapnil Jakhade .compatible = "ti,j721e-serdes-10g", 1927597bf3f1SSwapnil Jakhade .data = &ti_j721e_map_torrent, 1928597bf3f1SSwapnil Jakhade }, 1929c589e701SYuti Amonkar {} 1930c589e701SYuti Amonkar }; 193192e9ccc6SSwapnil Jakhade MODULE_DEVICE_TABLE(of, cdns_torrent_phy_of_match); 1932c589e701SYuti Amonkar 193392e9ccc6SSwapnil Jakhade static struct platform_driver cdns_torrent_phy_driver = { 193492e9ccc6SSwapnil Jakhade .probe = cdns_torrent_phy_probe, 1935afa4ba05SSwapnil Jakhade .remove = cdns_torrent_phy_remove, 1936c589e701SYuti Amonkar .driver = { 193792e9ccc6SSwapnil Jakhade .name = "cdns-torrent-phy", 193892e9ccc6SSwapnil Jakhade .of_match_table = cdns_torrent_phy_of_match, 1939c589e701SYuti Amonkar } 1940c589e701SYuti Amonkar }; 194192e9ccc6SSwapnil Jakhade module_platform_driver(cdns_torrent_phy_driver); 1942c589e701SYuti Amonkar 1943c589e701SYuti Amonkar MODULE_AUTHOR("Cadence Design Systems, Inc."); 194492e9ccc6SSwapnil Jakhade MODULE_DESCRIPTION("Cadence Torrent PHY driver"); 1945c589e701SYuti Amonkar MODULE_LICENSE("GPL v2"); 1946