1154ebdb7SSuraj Kandpal // SPDX-License-Identifier: MIT 2154ebdb7SSuraj Kandpal /* 3154ebdb7SSuraj Kandpal * Copyright © 2025 Intel Corporation 4154ebdb7SSuraj Kandpal */ 5154ebdb7SSuraj Kandpal 6154ebdb7SSuraj Kandpal #include <drm/drm_print.h> 7154ebdb7SSuraj Kandpal 8154ebdb7SSuraj Kandpal #include "i915_reg.h" 9154ebdb7SSuraj Kandpal #include "intel_cx0_phy.h" 10154ebdb7SSuraj Kandpal #include "intel_cx0_phy_regs.h" 1113ba213fSSuraj Kandpal #include "intel_ddi.h" 1213ba213fSSuraj Kandpal #include "intel_ddi_buf_trans.h" 13154ebdb7SSuraj Kandpal #include "intel_de.h" 14154ebdb7SSuraj Kandpal #include "intel_display.h" 15154ebdb7SSuraj Kandpal #include "intel_display_types.h" 16*4341dd24SJani Nikula #include "intel_display_utils.h" 17dc5742b6SSuraj Kandpal #include "intel_dpll_mgr.h" 183a323c7eSSuraj Kandpal #include "intel_hdmi.h" 19154ebdb7SSuraj Kandpal #include "intel_lt_phy.h" 20154ebdb7SSuraj Kandpal #include "intel_lt_phy_regs.h" 213383ba24SSuraj Kandpal #include "intel_panel.h" 22e1455196SSuraj Kandpal #include "intel_psr.h" 23154ebdb7SSuraj Kandpal #include "intel_tc.h" 24154ebdb7SSuraj Kandpal 2541d07bd2SSuraj Kandpal #define for_each_lt_phy_lane_in_mask(__lane_mask, __lane) \ 2641d07bd2SSuraj Kandpal for ((__lane) = 0; (__lane) < 2; (__lane)++) \ 2741d07bd2SSuraj Kandpal for_each_if((__lane_mask) & BIT(__lane)) 2841d07bd2SSuraj Kandpal 29154ebdb7SSuraj Kandpal #define INTEL_LT_PHY_LANE0 BIT(0) 30154ebdb7SSuraj Kandpal #define INTEL_LT_PHY_LANE1 BIT(1) 31154ebdb7SSuraj Kandpal #define INTEL_LT_PHY_BOTH_LANES (INTEL_LT_PHY_LANE1 |\ 32154ebdb7SSuraj Kandpal INTEL_LT_PHY_LANE0) 33e1455196SSuraj Kandpal #define MODE_DP 3 346fedb7bfSSuraj Kandpal #define Q32_TO_INT(x) ((x) >> 32) 356fedb7bfSSuraj Kandpal #define Q32_TO_FRAC(x) ((x) & 0xFFFFFFFF) 366fedb7bfSSuraj Kandpal #define DCO_MIN_FREQ_MHZ 11850 376fedb7bfSSuraj Kandpal #define REF_CLK_KHZ 38400 386fedb7bfSSuraj Kandpal #define TDC_RES_MULTIPLIER 10000000ULL 396fedb7bfSSuraj Kandpal 406fedb7bfSSuraj Kandpal struct phy_param_t { 416fedb7bfSSuraj Kandpal u32 val; 426fedb7bfSSuraj Kandpal u32 addr; 436fedb7bfSSuraj Kandpal }; 446fedb7bfSSuraj Kandpal 456fedb7bfSSuraj Kandpal struct lt_phy_params { 466fedb7bfSSuraj Kandpal struct phy_param_t pll_reg4; 476fedb7bfSSuraj Kandpal struct phy_param_t pll_reg3; 486fedb7bfSSuraj Kandpal struct phy_param_t pll_reg5; 496fedb7bfSSuraj Kandpal struct phy_param_t pll_reg57; 506fedb7bfSSuraj Kandpal struct phy_param_t lf; 516fedb7bfSSuraj Kandpal struct phy_param_t tdc; 526fedb7bfSSuraj Kandpal struct phy_param_t ssc; 536fedb7bfSSuraj Kandpal struct phy_param_t bias2; 546fedb7bfSSuraj Kandpal struct phy_param_t bias_trim; 556fedb7bfSSuraj Kandpal struct phy_param_t dco_med; 566fedb7bfSSuraj Kandpal struct phy_param_t dco_fine; 576fedb7bfSSuraj Kandpal struct phy_param_t ssc_inj; 586fedb7bfSSuraj Kandpal struct phy_param_t surv_bonus; 596fedb7bfSSuraj Kandpal }; 60154ebdb7SSuraj Kandpal 61dc5742b6SSuraj Kandpal static const struct intel_lt_phy_pll_state xe3plpd_lt_dp_rbr = { 62dc5742b6SSuraj Kandpal .clock = 162000, 63dc5742b6SSuraj Kandpal .config = { 64dc5742b6SSuraj Kandpal 0x83, 65dc5742b6SSuraj Kandpal 0x2d, 66dc5742b6SSuraj Kandpal 0x0, 67dc5742b6SSuraj Kandpal }, 68dc5742b6SSuraj Kandpal .addr_msb = { 69dc5742b6SSuraj Kandpal 0x87, 70dc5742b6SSuraj Kandpal 0x87, 71dc5742b6SSuraj Kandpal 0x87, 72dc5742b6SSuraj Kandpal 0x87, 73dc5742b6SSuraj Kandpal 0x88, 74dc5742b6SSuraj Kandpal 0x88, 75dc5742b6SSuraj Kandpal 0x88, 76dc5742b6SSuraj Kandpal 0x88, 77dc5742b6SSuraj Kandpal 0x88, 78dc5742b6SSuraj Kandpal 0x88, 79dc5742b6SSuraj Kandpal 0x88, 80dc5742b6SSuraj Kandpal 0x88, 81dc5742b6SSuraj Kandpal 0x88, 82dc5742b6SSuraj Kandpal }, 83dc5742b6SSuraj Kandpal .addr_lsb = { 84dc5742b6SSuraj Kandpal 0x10, 85dc5742b6SSuraj Kandpal 0x0c, 86dc5742b6SSuraj Kandpal 0x14, 87dc5742b6SSuraj Kandpal 0xe4, 88dc5742b6SSuraj Kandpal 0x0c, 89dc5742b6SSuraj Kandpal 0x10, 90dc5742b6SSuraj Kandpal 0x14, 91dc5742b6SSuraj Kandpal 0x18, 92dc5742b6SSuraj Kandpal 0x48, 93dc5742b6SSuraj Kandpal 0x40, 94dc5742b6SSuraj Kandpal 0x4c, 95dc5742b6SSuraj Kandpal 0x24, 96dc5742b6SSuraj Kandpal 0x44, 97dc5742b6SSuraj Kandpal }, 98dc5742b6SSuraj Kandpal .data = { 99dc5742b6SSuraj Kandpal { 0x0, 0x4c, 0x2, 0x0 }, 100dc5742b6SSuraj Kandpal { 0x5, 0xa, 0x2a, 0x20 }, 101dc5742b6SSuraj Kandpal { 0x80, 0x0, 0x0, 0x0 }, 102dc5742b6SSuraj Kandpal { 0x4, 0x4, 0x82, 0x28 }, 103dc5742b6SSuraj Kandpal { 0xfa, 0x16, 0x83, 0x11 }, 104dc5742b6SSuraj Kandpal { 0x80, 0x0f, 0xf9, 0x53 }, 105dc5742b6SSuraj Kandpal { 0x84, 0x26, 0x5, 0x4 }, 106dc5742b6SSuraj Kandpal { 0x0, 0xe0, 0x1, 0x0 }, 107dc5742b6SSuraj Kandpal { 0x4b, 0x48, 0x0, 0x0 }, 108dc5742b6SSuraj Kandpal { 0x27, 0x8, 0x0, 0x0 }, 109dc5742b6SSuraj Kandpal { 0x5a, 0x13, 0x29, 0x13 }, 110dc5742b6SSuraj Kandpal { 0x0, 0x5b, 0xe0, 0x0a }, 111dc5742b6SSuraj Kandpal { 0x0, 0x0, 0x0, 0x0 }, 112dc5742b6SSuraj Kandpal }, 113dc5742b6SSuraj Kandpal }; 114dc5742b6SSuraj Kandpal 115dc5742b6SSuraj Kandpal static const struct intel_lt_phy_pll_state xe3plpd_lt_dp_hbr1 = { 116dc5742b6SSuraj Kandpal .clock = 270000, 117dc5742b6SSuraj Kandpal .config = { 118dc5742b6SSuraj Kandpal 0x8b, 119dc5742b6SSuraj Kandpal 0x2d, 120dc5742b6SSuraj Kandpal 0x0, 121dc5742b6SSuraj Kandpal }, 122dc5742b6SSuraj Kandpal .addr_msb = { 123dc5742b6SSuraj Kandpal 0x87, 124dc5742b6SSuraj Kandpal 0x87, 125dc5742b6SSuraj Kandpal 0x87, 126dc5742b6SSuraj Kandpal 0x87, 127dc5742b6SSuraj Kandpal 0x88, 128dc5742b6SSuraj Kandpal 0x88, 129dc5742b6SSuraj Kandpal 0x88, 130dc5742b6SSuraj Kandpal 0x88, 131dc5742b6SSuraj Kandpal 0x88, 132dc5742b6SSuraj Kandpal 0x88, 133dc5742b6SSuraj Kandpal 0x88, 134dc5742b6SSuraj Kandpal 0x88, 135dc5742b6SSuraj Kandpal 0x88, 136dc5742b6SSuraj Kandpal }, 137dc5742b6SSuraj Kandpal .addr_lsb = { 138dc5742b6SSuraj Kandpal 0x10, 139dc5742b6SSuraj Kandpal 0x0c, 140dc5742b6SSuraj Kandpal 0x14, 141dc5742b6SSuraj Kandpal 0xe4, 142dc5742b6SSuraj Kandpal 0x0c, 143dc5742b6SSuraj Kandpal 0x10, 144dc5742b6SSuraj Kandpal 0x14, 145dc5742b6SSuraj Kandpal 0x18, 146dc5742b6SSuraj Kandpal 0x48, 147dc5742b6SSuraj Kandpal 0x40, 148dc5742b6SSuraj Kandpal 0x4c, 149dc5742b6SSuraj Kandpal 0x24, 150dc5742b6SSuraj Kandpal 0x44, 151dc5742b6SSuraj Kandpal }, 152dc5742b6SSuraj Kandpal .data = { 153dc5742b6SSuraj Kandpal { 0x0, 0x4c, 0x2, 0x0 }, 154dc5742b6SSuraj Kandpal { 0x3, 0xca, 0x34, 0xa0 }, 155dc5742b6SSuraj Kandpal { 0xe0, 0x0, 0x0, 0x0 }, 156dc5742b6SSuraj Kandpal { 0x5, 0x4, 0x81, 0xad }, 157dc5742b6SSuraj Kandpal { 0xfa, 0x11, 0x83, 0x11 }, 158dc5742b6SSuraj Kandpal { 0x80, 0x0f, 0xf9, 0x53 }, 159dc5742b6SSuraj Kandpal { 0x84, 0x26, 0x7, 0x4 }, 160dc5742b6SSuraj Kandpal { 0x0, 0xe0, 0x1, 0x0 }, 161dc5742b6SSuraj Kandpal { 0x43, 0x48, 0x0, 0x0 }, 162dc5742b6SSuraj Kandpal { 0x27, 0x8, 0x0, 0x0 }, 163dc5742b6SSuraj Kandpal { 0x5a, 0x13, 0x29, 0x13 }, 164dc5742b6SSuraj Kandpal { 0x0, 0x5b, 0xe0, 0x0d }, 165dc5742b6SSuraj Kandpal { 0x0, 0x0, 0x0, 0x0 }, 166dc5742b6SSuraj Kandpal }, 167dc5742b6SSuraj Kandpal }; 168dc5742b6SSuraj Kandpal 169dc5742b6SSuraj Kandpal static const struct intel_lt_phy_pll_state xe3plpd_lt_dp_hbr2 = { 170dc5742b6SSuraj Kandpal .clock = 540000, 171dc5742b6SSuraj Kandpal .config = { 172dc5742b6SSuraj Kandpal 0x93, 173dc5742b6SSuraj Kandpal 0x2d, 174dc5742b6SSuraj Kandpal 0x0, 175dc5742b6SSuraj Kandpal }, 176dc5742b6SSuraj Kandpal .addr_msb = { 177dc5742b6SSuraj Kandpal 0x87, 178dc5742b6SSuraj Kandpal 0x87, 179dc5742b6SSuraj Kandpal 0x87, 180dc5742b6SSuraj Kandpal 0x87, 181dc5742b6SSuraj Kandpal 0x88, 182dc5742b6SSuraj Kandpal 0x88, 183dc5742b6SSuraj Kandpal 0x88, 184dc5742b6SSuraj Kandpal 0x88, 185dc5742b6SSuraj Kandpal 0x88, 186dc5742b6SSuraj Kandpal 0x88, 187dc5742b6SSuraj Kandpal 0x88, 188dc5742b6SSuraj Kandpal 0x88, 189dc5742b6SSuraj Kandpal 0x88, 190dc5742b6SSuraj Kandpal }, 191dc5742b6SSuraj Kandpal .addr_lsb = { 192dc5742b6SSuraj Kandpal 0x10, 193dc5742b6SSuraj Kandpal 0x0c, 194dc5742b6SSuraj Kandpal 0x14, 195dc5742b6SSuraj Kandpal 0xe4, 196dc5742b6SSuraj Kandpal 0x0c, 197dc5742b6SSuraj Kandpal 0x10, 198dc5742b6SSuraj Kandpal 0x14, 199dc5742b6SSuraj Kandpal 0x18, 200dc5742b6SSuraj Kandpal 0x48, 201dc5742b6SSuraj Kandpal 0x40, 202dc5742b6SSuraj Kandpal 0x4c, 203dc5742b6SSuraj Kandpal 0x24, 204dc5742b6SSuraj Kandpal 0x44, 205dc5742b6SSuraj Kandpal }, 206dc5742b6SSuraj Kandpal .data = { 207dc5742b6SSuraj Kandpal { 0x0, 0x4c, 0x2, 0x0 }, 208dc5742b6SSuraj Kandpal { 0x1, 0x4d, 0x34, 0xa0 }, 209dc5742b6SSuraj Kandpal { 0xe0, 0x0, 0x0, 0x0 }, 210dc5742b6SSuraj Kandpal { 0xa, 0x4, 0x81, 0xda }, 211dc5742b6SSuraj Kandpal { 0xfa, 0x11, 0x83, 0x11 }, 212dc5742b6SSuraj Kandpal { 0x80, 0x0f, 0xf9, 0x53 }, 213dc5742b6SSuraj Kandpal { 0x84, 0x26, 0x7, 0x4 }, 214dc5742b6SSuraj Kandpal { 0x0, 0xe0, 0x1, 0x0 }, 215dc5742b6SSuraj Kandpal { 0x43, 0x48, 0x0, 0x0 }, 216dc5742b6SSuraj Kandpal { 0x27, 0x8, 0x0, 0x0 }, 217dc5742b6SSuraj Kandpal { 0x5a, 0x13, 0x29, 0x13 }, 218dc5742b6SSuraj Kandpal { 0x0, 0x5b, 0xe0, 0x0d }, 219dc5742b6SSuraj Kandpal { 0x0, 0x0, 0x0, 0x0 }, 220dc5742b6SSuraj Kandpal }, 221dc5742b6SSuraj Kandpal }; 222dc5742b6SSuraj Kandpal 223dc5742b6SSuraj Kandpal static const struct intel_lt_phy_pll_state xe3plpd_lt_dp_hbr3 = { 224dc5742b6SSuraj Kandpal .clock = 810000, 225dc5742b6SSuraj Kandpal .config = { 226dc5742b6SSuraj Kandpal 0x9b, 227dc5742b6SSuraj Kandpal 0x2d, 228dc5742b6SSuraj Kandpal 0x0, 229dc5742b6SSuraj Kandpal }, 230dc5742b6SSuraj Kandpal .addr_msb = { 231dc5742b6SSuraj Kandpal 0x87, 232dc5742b6SSuraj Kandpal 0x87, 233dc5742b6SSuraj Kandpal 0x87, 234dc5742b6SSuraj Kandpal 0x87, 235dc5742b6SSuraj Kandpal 0x88, 236dc5742b6SSuraj Kandpal 0x88, 237dc5742b6SSuraj Kandpal 0x88, 238dc5742b6SSuraj Kandpal 0x88, 239dc5742b6SSuraj Kandpal 0x88, 240dc5742b6SSuraj Kandpal 0x88, 241dc5742b6SSuraj Kandpal 0x88, 242dc5742b6SSuraj Kandpal 0x88, 243dc5742b6SSuraj Kandpal 0x88, 244dc5742b6SSuraj Kandpal }, 245dc5742b6SSuraj Kandpal .addr_lsb = { 246dc5742b6SSuraj Kandpal 0x10, 247dc5742b6SSuraj Kandpal 0x0c, 248dc5742b6SSuraj Kandpal 0x14, 249dc5742b6SSuraj Kandpal 0xe4, 250dc5742b6SSuraj Kandpal 0x0c, 251dc5742b6SSuraj Kandpal 0x10, 252dc5742b6SSuraj Kandpal 0x14, 253dc5742b6SSuraj Kandpal 0x18, 254dc5742b6SSuraj Kandpal 0x48, 255dc5742b6SSuraj Kandpal 0x40, 256dc5742b6SSuraj Kandpal 0x4c, 257dc5742b6SSuraj Kandpal 0x24, 258dc5742b6SSuraj Kandpal 0x44, 259dc5742b6SSuraj Kandpal }, 260dc5742b6SSuraj Kandpal .data = { 261dc5742b6SSuraj Kandpal { 0x0, 0x4c, 0x2, 0x0 }, 262dc5742b6SSuraj Kandpal { 0x1, 0x4a, 0x34, 0xa0 }, 263dc5742b6SSuraj Kandpal { 0xe0, 0x0, 0x0, 0x0 }, 264dc5742b6SSuraj Kandpal { 0x5, 0x4, 0x80, 0xa8 }, 265dc5742b6SSuraj Kandpal { 0xfa, 0x11, 0x83, 0x11 }, 266dc5742b6SSuraj Kandpal { 0x80, 0x0f, 0xf9, 0x53 }, 267dc5742b6SSuraj Kandpal { 0x84, 0x26, 0x7, 0x4 }, 268dc5742b6SSuraj Kandpal { 0x0, 0xe0, 0x1, 0x0 }, 269dc5742b6SSuraj Kandpal { 0x43, 0x48, 0x0, 0x0 }, 270dc5742b6SSuraj Kandpal { 0x27, 0x8, 0x0, 0x0 }, 271dc5742b6SSuraj Kandpal { 0x5a, 0x13, 0x29, 0x13 }, 272dc5742b6SSuraj Kandpal { 0x0, 0x5b, 0xe0, 0x0d }, 273dc5742b6SSuraj Kandpal { 0x0, 0x0, 0x0, 0x0 }, 274dc5742b6SSuraj Kandpal }, 275dc5742b6SSuraj Kandpal }; 276dc5742b6SSuraj Kandpal 277dc5742b6SSuraj Kandpal static const struct intel_lt_phy_pll_state xe3plpd_lt_dp_uhbr10 = { 278dc5742b6SSuraj Kandpal .clock = 1000000, 279dc5742b6SSuraj Kandpal .config = { 280dc5742b6SSuraj Kandpal 0x43, 281dc5742b6SSuraj Kandpal 0x2d, 282dc5742b6SSuraj Kandpal 0x0, 283dc5742b6SSuraj Kandpal }, 284dc5742b6SSuraj Kandpal .addr_msb = { 285dc5742b6SSuraj Kandpal 0x85, 286dc5742b6SSuraj Kandpal 0x85, 287dc5742b6SSuraj Kandpal 0x85, 288dc5742b6SSuraj Kandpal 0x85, 289dc5742b6SSuraj Kandpal 0x86, 290dc5742b6SSuraj Kandpal 0x86, 291dc5742b6SSuraj Kandpal 0x86, 292dc5742b6SSuraj Kandpal 0x86, 293dc5742b6SSuraj Kandpal 0x86, 294dc5742b6SSuraj Kandpal 0x86, 295dc5742b6SSuraj Kandpal 0x86, 296dc5742b6SSuraj Kandpal 0x86, 297dc5742b6SSuraj Kandpal 0x86, 298dc5742b6SSuraj Kandpal }, 299dc5742b6SSuraj Kandpal .addr_lsb = { 300dc5742b6SSuraj Kandpal 0x10, 301dc5742b6SSuraj Kandpal 0x0c, 302dc5742b6SSuraj Kandpal 0x14, 303dc5742b6SSuraj Kandpal 0xe4, 304dc5742b6SSuraj Kandpal 0x0c, 305dc5742b6SSuraj Kandpal 0x10, 306dc5742b6SSuraj Kandpal 0x14, 307dc5742b6SSuraj Kandpal 0x18, 308dc5742b6SSuraj Kandpal 0x48, 309dc5742b6SSuraj Kandpal 0x40, 310dc5742b6SSuraj Kandpal 0x4c, 311dc5742b6SSuraj Kandpal 0x24, 312dc5742b6SSuraj Kandpal 0x44, 313dc5742b6SSuraj Kandpal }, 314dc5742b6SSuraj Kandpal .data = { 315dc5742b6SSuraj Kandpal { 0x0, 0x4c, 0x2, 0x0 }, 316dc5742b6SSuraj Kandpal { 0x1, 0xa, 0x20, 0x80 }, 317dc5742b6SSuraj Kandpal { 0x6a, 0xaa, 0xaa, 0xab }, 318dc5742b6SSuraj Kandpal { 0x0, 0x3, 0x4, 0x94 }, 319dc5742b6SSuraj Kandpal { 0xfa, 0x1c, 0x83, 0x11 }, 320dc5742b6SSuraj Kandpal { 0x80, 0x0f, 0xf9, 0x53 }, 321dc5742b6SSuraj Kandpal { 0x84, 0x26, 0x4, 0x4 }, 322dc5742b6SSuraj Kandpal { 0x0, 0xe0, 0x1, 0x0 }, 323dc5742b6SSuraj Kandpal { 0x45, 0x48, 0x0, 0x0 }, 324dc5742b6SSuraj Kandpal { 0x27, 0x8, 0x0, 0x0 }, 325dc5742b6SSuraj Kandpal { 0x5a, 0x14, 0x2a, 0x14 }, 326dc5742b6SSuraj Kandpal { 0x0, 0x5b, 0xe0, 0x8 }, 327dc5742b6SSuraj Kandpal { 0x0, 0x0, 0x0, 0x0 }, 328dc5742b6SSuraj Kandpal }, 329dc5742b6SSuraj Kandpal }; 330dc5742b6SSuraj Kandpal 331dc5742b6SSuraj Kandpal static const struct intel_lt_phy_pll_state xe3plpd_lt_dp_uhbr13_5 = { 332dc5742b6SSuraj Kandpal .clock = 1350000, 333dc5742b6SSuraj Kandpal .config = { 334dc5742b6SSuraj Kandpal 0xcb, 335dc5742b6SSuraj Kandpal 0x2d, 336dc5742b6SSuraj Kandpal 0x0, 337dc5742b6SSuraj Kandpal }, 338dc5742b6SSuraj Kandpal .addr_msb = { 339dc5742b6SSuraj Kandpal 0x87, 340dc5742b6SSuraj Kandpal 0x87, 341dc5742b6SSuraj Kandpal 0x87, 342dc5742b6SSuraj Kandpal 0x87, 343dc5742b6SSuraj Kandpal 0x88, 344dc5742b6SSuraj Kandpal 0x88, 345dc5742b6SSuraj Kandpal 0x88, 346dc5742b6SSuraj Kandpal 0x88, 347dc5742b6SSuraj Kandpal 0x88, 348dc5742b6SSuraj Kandpal 0x88, 349dc5742b6SSuraj Kandpal 0x88, 350dc5742b6SSuraj Kandpal 0x88, 351dc5742b6SSuraj Kandpal 0x88, 352dc5742b6SSuraj Kandpal }, 353dc5742b6SSuraj Kandpal .addr_lsb = { 354dc5742b6SSuraj Kandpal 0x10, 355dc5742b6SSuraj Kandpal 0x0c, 356dc5742b6SSuraj Kandpal 0x14, 357dc5742b6SSuraj Kandpal 0xe4, 358dc5742b6SSuraj Kandpal 0x0c, 359dc5742b6SSuraj Kandpal 0x10, 360dc5742b6SSuraj Kandpal 0x14, 361dc5742b6SSuraj Kandpal 0x18, 362dc5742b6SSuraj Kandpal 0x48, 363dc5742b6SSuraj Kandpal 0x40, 364dc5742b6SSuraj Kandpal 0x4c, 365dc5742b6SSuraj Kandpal 0x24, 366dc5742b6SSuraj Kandpal 0x44, 367dc5742b6SSuraj Kandpal }, 368dc5742b6SSuraj Kandpal .data = { 369dc5742b6SSuraj Kandpal { 0x0, 0x4c, 0x2, 0x0 }, 370dc5742b6SSuraj Kandpal { 0x2, 0x9, 0x2b, 0xe0 }, 371dc5742b6SSuraj Kandpal { 0x90, 0x0, 0x0, 0x0 }, 372dc5742b6SSuraj Kandpal { 0x8, 0x4, 0x80, 0xe0 }, 373dc5742b6SSuraj Kandpal { 0xfa, 0x15, 0x83, 0x11 }, 374dc5742b6SSuraj Kandpal { 0x80, 0x0f, 0xf9, 0x53 }, 375dc5742b6SSuraj Kandpal { 0x84, 0x26, 0x6, 0x4 }, 376dc5742b6SSuraj Kandpal { 0x0, 0xe0, 0x1, 0x0 }, 377dc5742b6SSuraj Kandpal { 0x49, 0x48, 0x0, 0x0 }, 378dc5742b6SSuraj Kandpal { 0x27, 0x8, 0x0, 0x0 }, 379dc5742b6SSuraj Kandpal { 0x5a, 0x13, 0x29, 0x13 }, 380dc5742b6SSuraj Kandpal { 0x0, 0x57, 0xe0, 0x0c }, 381dc5742b6SSuraj Kandpal { 0x0, 0x0, 0x0, 0x0 }, 382dc5742b6SSuraj Kandpal }, 383dc5742b6SSuraj Kandpal }; 384dc5742b6SSuraj Kandpal 385dc5742b6SSuraj Kandpal static const struct intel_lt_phy_pll_state xe3plpd_lt_dp_uhbr20 = { 386dc5742b6SSuraj Kandpal .clock = 2000000, 387dc5742b6SSuraj Kandpal .config = { 388dc5742b6SSuraj Kandpal 0x53, 389dc5742b6SSuraj Kandpal 0x2d, 390dc5742b6SSuraj Kandpal 0x0, 391dc5742b6SSuraj Kandpal }, 392dc5742b6SSuraj Kandpal .addr_msb = { 393dc5742b6SSuraj Kandpal 0x85, 394dc5742b6SSuraj Kandpal 0x85, 395dc5742b6SSuraj Kandpal 0x85, 396dc5742b6SSuraj Kandpal 0x85, 397dc5742b6SSuraj Kandpal 0x86, 398dc5742b6SSuraj Kandpal 0x86, 399dc5742b6SSuraj Kandpal 0x86, 400dc5742b6SSuraj Kandpal 0x86, 401dc5742b6SSuraj Kandpal 0x86, 402dc5742b6SSuraj Kandpal 0x86, 403dc5742b6SSuraj Kandpal 0x86, 404dc5742b6SSuraj Kandpal 0x86, 405dc5742b6SSuraj Kandpal 0x86, 406dc5742b6SSuraj Kandpal }, 407dc5742b6SSuraj Kandpal .addr_lsb = { 408dc5742b6SSuraj Kandpal 0x10, 409dc5742b6SSuraj Kandpal 0x0c, 410dc5742b6SSuraj Kandpal 0x14, 411dc5742b6SSuraj Kandpal 0xe4, 412dc5742b6SSuraj Kandpal 0x0c, 413dc5742b6SSuraj Kandpal 0x10, 414dc5742b6SSuraj Kandpal 0x14, 415dc5742b6SSuraj Kandpal 0x18, 416dc5742b6SSuraj Kandpal 0x48, 417dc5742b6SSuraj Kandpal 0x40, 418dc5742b6SSuraj Kandpal 0x4c, 419dc5742b6SSuraj Kandpal 0x24, 420dc5742b6SSuraj Kandpal 0x44, 421dc5742b6SSuraj Kandpal }, 422dc5742b6SSuraj Kandpal .data = { 423dc5742b6SSuraj Kandpal { 0x0, 0x4c, 0x2, 0x0 }, 424dc5742b6SSuraj Kandpal { 0x1, 0xa, 0x20, 0x80 }, 425dc5742b6SSuraj Kandpal { 0x6a, 0xaa, 0xaa, 0xab }, 426dc5742b6SSuraj Kandpal { 0x0, 0x3, 0x4, 0x94 }, 427dc5742b6SSuraj Kandpal { 0xfa, 0x1c, 0x83, 0x11 }, 428dc5742b6SSuraj Kandpal { 0x80, 0x0f, 0xf9, 0x53 }, 429dc5742b6SSuraj Kandpal { 0x84, 0x26, 0x4, 0x4 }, 430dc5742b6SSuraj Kandpal { 0x0, 0xe0, 0x1, 0x0 }, 431dc5742b6SSuraj Kandpal { 0x45, 0x48, 0x0, 0x0 }, 432dc5742b6SSuraj Kandpal { 0x27, 0x8, 0x0, 0x0 }, 433dc5742b6SSuraj Kandpal { 0x5a, 0x14, 0x2a, 0x14 }, 434dc5742b6SSuraj Kandpal { 0x0, 0x5b, 0xe0, 0x8 }, 435dc5742b6SSuraj Kandpal { 0x0, 0x0, 0x0, 0x0 }, 436dc5742b6SSuraj Kandpal }, 437dc5742b6SSuraj Kandpal }; 438dc5742b6SSuraj Kandpal 439dc5742b6SSuraj Kandpal static const struct intel_lt_phy_pll_state * const xe3plpd_lt_dp_tables[] = { 440dc5742b6SSuraj Kandpal &xe3plpd_lt_dp_rbr, 441dc5742b6SSuraj Kandpal &xe3plpd_lt_dp_hbr1, 442dc5742b6SSuraj Kandpal &xe3plpd_lt_dp_hbr2, 443dc5742b6SSuraj Kandpal &xe3plpd_lt_dp_hbr3, 444dc5742b6SSuraj Kandpal &xe3plpd_lt_dp_uhbr10, 445dc5742b6SSuraj Kandpal &xe3plpd_lt_dp_uhbr13_5, 446dc5742b6SSuraj Kandpal &xe3plpd_lt_dp_uhbr20, 447dc5742b6SSuraj Kandpal NULL, 448dc5742b6SSuraj Kandpal }; 449dc5742b6SSuraj Kandpal 450dc5742b6SSuraj Kandpal static const struct intel_lt_phy_pll_state xe3plpd_lt_edp_2_16 = { 451dc5742b6SSuraj Kandpal .clock = 216000, 452dc5742b6SSuraj Kandpal .config = { 453dc5742b6SSuraj Kandpal 0xa3, 454dc5742b6SSuraj Kandpal 0x2d, 455dc5742b6SSuraj Kandpal 0x1, 456dc5742b6SSuraj Kandpal }, 457dc5742b6SSuraj Kandpal .addr_msb = { 458dc5742b6SSuraj Kandpal 0x87, 459dc5742b6SSuraj Kandpal 0x87, 460dc5742b6SSuraj Kandpal 0x87, 461dc5742b6SSuraj Kandpal 0x87, 462dc5742b6SSuraj Kandpal 0x88, 463dc5742b6SSuraj Kandpal 0x88, 464dc5742b6SSuraj Kandpal 0x88, 465dc5742b6SSuraj Kandpal 0x88, 466dc5742b6SSuraj Kandpal 0x88, 467dc5742b6SSuraj Kandpal 0x88, 468dc5742b6SSuraj Kandpal 0x88, 469dc5742b6SSuraj Kandpal 0x88, 470dc5742b6SSuraj Kandpal 0x88, 471dc5742b6SSuraj Kandpal }, 472dc5742b6SSuraj Kandpal .addr_lsb = { 473dc5742b6SSuraj Kandpal 0x10, 474dc5742b6SSuraj Kandpal 0x0c, 475dc5742b6SSuraj Kandpal 0x14, 476dc5742b6SSuraj Kandpal 0xe4, 477dc5742b6SSuraj Kandpal 0x0c, 478dc5742b6SSuraj Kandpal 0x10, 479dc5742b6SSuraj Kandpal 0x14, 480dc5742b6SSuraj Kandpal 0x18, 481dc5742b6SSuraj Kandpal 0x48, 482dc5742b6SSuraj Kandpal 0x40, 483dc5742b6SSuraj Kandpal 0x4c, 484dc5742b6SSuraj Kandpal 0x24, 485dc5742b6SSuraj Kandpal 0x44, 486dc5742b6SSuraj Kandpal }, 487dc5742b6SSuraj Kandpal .data = { 488dc5742b6SSuraj Kandpal { 0x0, 0x4c, 0x2, 0x0 }, 489dc5742b6SSuraj Kandpal { 0x3, 0xca, 0x2a, 0x20 }, 490dc5742b6SSuraj Kandpal { 0x80, 0x0, 0x0, 0x0 }, 491dc5742b6SSuraj Kandpal { 0x6, 0x4, 0x81, 0xbc }, 492dc5742b6SSuraj Kandpal { 0xfa, 0x16, 0x83, 0x11 }, 493dc5742b6SSuraj Kandpal { 0x80, 0x0f, 0xf9, 0x53 }, 494dc5742b6SSuraj Kandpal { 0x84, 0x26, 0x5, 0x4 }, 495dc5742b6SSuraj Kandpal { 0x0, 0xe0, 0x1, 0x0 }, 496dc5742b6SSuraj Kandpal { 0x4b, 0x48, 0x0, 0x0 }, 497dc5742b6SSuraj Kandpal { 0x27, 0x8, 0x0, 0x0 }, 498dc5742b6SSuraj Kandpal { 0x5a, 0x13, 0x29, 0x13 }, 499dc5742b6SSuraj Kandpal { 0x0, 0x5b, 0xe0, 0x0a }, 500dc5742b6SSuraj Kandpal { 0x0, 0x0, 0x0, 0x0 }, 501dc5742b6SSuraj Kandpal }, 502dc5742b6SSuraj Kandpal }; 503dc5742b6SSuraj Kandpal 504dc5742b6SSuraj Kandpal static const struct intel_lt_phy_pll_state xe3plpd_lt_edp_2_43 = { 505dc5742b6SSuraj Kandpal .clock = 243000, 506dc5742b6SSuraj Kandpal .config = { 507dc5742b6SSuraj Kandpal 0xab, 508dc5742b6SSuraj Kandpal 0x2d, 509dc5742b6SSuraj Kandpal 0x1, 510dc5742b6SSuraj Kandpal }, 511dc5742b6SSuraj Kandpal .addr_msb = { 512dc5742b6SSuraj Kandpal 0x87, 513dc5742b6SSuraj Kandpal 0x87, 514dc5742b6SSuraj Kandpal 0x87, 515dc5742b6SSuraj Kandpal 0x87, 516dc5742b6SSuraj Kandpal 0x88, 517dc5742b6SSuraj Kandpal 0x88, 518dc5742b6SSuraj Kandpal 0x88, 519dc5742b6SSuraj Kandpal 0x88, 520dc5742b6SSuraj Kandpal 0x88, 521dc5742b6SSuraj Kandpal 0x88, 522dc5742b6SSuraj Kandpal 0x88, 523dc5742b6SSuraj Kandpal 0x88, 524dc5742b6SSuraj Kandpal 0x88, 525dc5742b6SSuraj Kandpal }, 526dc5742b6SSuraj Kandpal .addr_lsb = { 527dc5742b6SSuraj Kandpal 0x10, 528dc5742b6SSuraj Kandpal 0x0c, 529dc5742b6SSuraj Kandpal 0x14, 530dc5742b6SSuraj Kandpal 0xe4, 531dc5742b6SSuraj Kandpal 0x0c, 532dc5742b6SSuraj Kandpal 0x10, 533dc5742b6SSuraj Kandpal 0x14, 534dc5742b6SSuraj Kandpal 0x18, 535dc5742b6SSuraj Kandpal 0x48, 536dc5742b6SSuraj Kandpal 0x40, 537dc5742b6SSuraj Kandpal 0x4c, 538dc5742b6SSuraj Kandpal 0x24, 539dc5742b6SSuraj Kandpal 0x44, 540dc5742b6SSuraj Kandpal }, 541dc5742b6SSuraj Kandpal .data = { 542dc5742b6SSuraj Kandpal { 0x0, 0x4c, 0x2, 0x0 }, 543dc5742b6SSuraj Kandpal { 0x3, 0xca, 0x2f, 0x60 }, 544dc5742b6SSuraj Kandpal { 0xb0, 0x0, 0x0, 0x0 }, 545dc5742b6SSuraj Kandpal { 0x6, 0x4, 0x81, 0xbc }, 546dc5742b6SSuraj Kandpal { 0xfa, 0x13, 0x83, 0x11 }, 547dc5742b6SSuraj Kandpal { 0x80, 0x0f, 0xf9, 0x53 }, 548dc5742b6SSuraj Kandpal { 0x84, 0x26, 0x6, 0x4 }, 549dc5742b6SSuraj Kandpal { 0x0, 0xe0, 0x1, 0x0 }, 550dc5742b6SSuraj Kandpal { 0x47, 0x48, 0x0, 0x0 }, 551dc5742b6SSuraj Kandpal { 0x0, 0x0, 0x0, 0x0 }, 552dc5742b6SSuraj Kandpal { 0x5a, 0x13, 0x29, 0x13 }, 553dc5742b6SSuraj Kandpal { 0x0, 0x5b, 0xe0, 0x0c }, 554dc5742b6SSuraj Kandpal { 0x0, 0x0, 0x0, 0x0 }, 555dc5742b6SSuraj Kandpal }, 556dc5742b6SSuraj Kandpal }; 557dc5742b6SSuraj Kandpal 558dc5742b6SSuraj Kandpal static const struct intel_lt_phy_pll_state xe3plpd_lt_edp_3_24 = { 559dc5742b6SSuraj Kandpal .clock = 324000, 560dc5742b6SSuraj Kandpal .config = { 561dc5742b6SSuraj Kandpal 0xb3, 562dc5742b6SSuraj Kandpal 0x2d, 563dc5742b6SSuraj Kandpal 0x1, 564dc5742b6SSuraj Kandpal }, 565dc5742b6SSuraj Kandpal .addr_msb = { 566dc5742b6SSuraj Kandpal 0x87, 567dc5742b6SSuraj Kandpal 0x87, 568dc5742b6SSuraj Kandpal 0x87, 569dc5742b6SSuraj Kandpal 0x87, 570dc5742b6SSuraj Kandpal 0x88, 571dc5742b6SSuraj Kandpal 0x88, 572dc5742b6SSuraj Kandpal 0x88, 573dc5742b6SSuraj Kandpal 0x88, 574dc5742b6SSuraj Kandpal 0x88, 575dc5742b6SSuraj Kandpal 0x88, 576dc5742b6SSuraj Kandpal 0x88, 577dc5742b6SSuraj Kandpal 0x88, 578dc5742b6SSuraj Kandpal 0x88, 579dc5742b6SSuraj Kandpal }, 580dc5742b6SSuraj Kandpal .addr_lsb = { 581dc5742b6SSuraj Kandpal 0x10, 582dc5742b6SSuraj Kandpal 0x0c, 583dc5742b6SSuraj Kandpal 0x14, 584dc5742b6SSuraj Kandpal 0xe4, 585dc5742b6SSuraj Kandpal 0x0c, 586dc5742b6SSuraj Kandpal 0x10, 587dc5742b6SSuraj Kandpal 0x14, 588dc5742b6SSuraj Kandpal 0x18, 589dc5742b6SSuraj Kandpal 0x48, 590dc5742b6SSuraj Kandpal 0x40, 591dc5742b6SSuraj Kandpal 0x4c, 592dc5742b6SSuraj Kandpal 0x24, 593dc5742b6SSuraj Kandpal 0x44, 594dc5742b6SSuraj Kandpal }, 595dc5742b6SSuraj Kandpal .data = { 596dc5742b6SSuraj Kandpal { 0x0, 0x4c, 0x2, 0x0 }, 597dc5742b6SSuraj Kandpal { 0x2, 0x8a, 0x2a, 0x20 }, 598dc5742b6SSuraj Kandpal { 0x80, 0x0, 0x0, 0x0 }, 599dc5742b6SSuraj Kandpal { 0x6, 0x4, 0x81, 0x28 }, 600dc5742b6SSuraj Kandpal { 0xfa, 0x16, 0x83, 0x11 }, 601dc5742b6SSuraj Kandpal { 0x80, 0x0f, 0xf9, 0x53 }, 602dc5742b6SSuraj Kandpal { 0x84, 0x26, 0x5, 0x4 }, 603dc5742b6SSuraj Kandpal { 0x0, 0xe0, 0x1, 0x0 }, 604dc5742b6SSuraj Kandpal { 0x4b, 0x48, 0x0, 0x0 }, 605dc5742b6SSuraj Kandpal { 0x27, 0x8, 0x0, 0x0 }, 606dc5742b6SSuraj Kandpal { 0x5a, 0x13, 0x29, 0x13 }, 607dc5742b6SSuraj Kandpal { 0x0, 0x5b, 0xe0, 0x0a }, 608dc5742b6SSuraj Kandpal { 0x0, 0x0, 0x0, 0x0 }, 609dc5742b6SSuraj Kandpal }, 610dc5742b6SSuraj Kandpal }; 611dc5742b6SSuraj Kandpal 612dc5742b6SSuraj Kandpal static const struct intel_lt_phy_pll_state xe3plpd_lt_edp_4_32 = { 613dc5742b6SSuraj Kandpal .clock = 432000, 614dc5742b6SSuraj Kandpal .config = { 615dc5742b6SSuraj Kandpal 0xbb, 616dc5742b6SSuraj Kandpal 0x2d, 617dc5742b6SSuraj Kandpal 0x1, 618dc5742b6SSuraj Kandpal }, 619dc5742b6SSuraj Kandpal .addr_msb = { 620dc5742b6SSuraj Kandpal 0x87, 621dc5742b6SSuraj Kandpal 0x87, 622dc5742b6SSuraj Kandpal 0x87, 623dc5742b6SSuraj Kandpal 0x87, 624dc5742b6SSuraj Kandpal 0x88, 625dc5742b6SSuraj Kandpal 0x88, 626dc5742b6SSuraj Kandpal 0x88, 627dc5742b6SSuraj Kandpal 0x88, 628dc5742b6SSuraj Kandpal 0x88, 629dc5742b6SSuraj Kandpal 0x88, 630dc5742b6SSuraj Kandpal 0x88, 631dc5742b6SSuraj Kandpal 0x88, 632dc5742b6SSuraj Kandpal 0x88, 633dc5742b6SSuraj Kandpal }, 634dc5742b6SSuraj Kandpal .addr_lsb = { 635dc5742b6SSuraj Kandpal 0x10, 636dc5742b6SSuraj Kandpal 0x0c, 637dc5742b6SSuraj Kandpal 0x14, 638dc5742b6SSuraj Kandpal 0xe4, 639dc5742b6SSuraj Kandpal 0x0c, 640dc5742b6SSuraj Kandpal 0x10, 641dc5742b6SSuraj Kandpal 0x14, 642dc5742b6SSuraj Kandpal 0x18, 643dc5742b6SSuraj Kandpal 0x48, 644dc5742b6SSuraj Kandpal 0x40, 645dc5742b6SSuraj Kandpal 0x4c, 646dc5742b6SSuraj Kandpal 0x24, 647dc5742b6SSuraj Kandpal 0x44, 648dc5742b6SSuraj Kandpal }, 649dc5742b6SSuraj Kandpal .data = { 650dc5742b6SSuraj Kandpal { 0x0, 0x4c, 0x2, 0x0 }, 651dc5742b6SSuraj Kandpal { 0x1, 0x4d, 0x2a, 0x20 }, 652dc5742b6SSuraj Kandpal { 0x80, 0x0, 0x0, 0x0 }, 653dc5742b6SSuraj Kandpal { 0xc, 0x4, 0x81, 0xbc }, 654dc5742b6SSuraj Kandpal { 0xfa, 0x16, 0x83, 0x11 }, 655dc5742b6SSuraj Kandpal { 0x80, 0x0f, 0xf9, 0x53 }, 656dc5742b6SSuraj Kandpal { 0x84, 0x26, 0x5, 0x4 }, 657dc5742b6SSuraj Kandpal { 0x0, 0xe0, 0x1, 0x0 }, 658dc5742b6SSuraj Kandpal { 0x4b, 0x48, 0x0, 0x0 }, 659dc5742b6SSuraj Kandpal { 0x27, 0x8, 0x0, 0x0 }, 660dc5742b6SSuraj Kandpal { 0x5a, 0x13, 0x29, 0x13 }, 661dc5742b6SSuraj Kandpal { 0x0, 0x5b, 0xe0, 0x0a }, 662dc5742b6SSuraj Kandpal { 0x0, 0x0, 0x0, 0x0 }, 663dc5742b6SSuraj Kandpal }, 664dc5742b6SSuraj Kandpal }; 665dc5742b6SSuraj Kandpal 666dc5742b6SSuraj Kandpal static const struct intel_lt_phy_pll_state xe3plpd_lt_edp_6_75 = { 667dc5742b6SSuraj Kandpal .clock = 675000, 668dc5742b6SSuraj Kandpal .config = { 669dc5742b6SSuraj Kandpal 0xdb, 670dc5742b6SSuraj Kandpal 0x2d, 671dc5742b6SSuraj Kandpal 0x1, 672dc5742b6SSuraj Kandpal }, 673dc5742b6SSuraj Kandpal .addr_msb = { 674dc5742b6SSuraj Kandpal 0x87, 675dc5742b6SSuraj Kandpal 0x87, 676dc5742b6SSuraj Kandpal 0x87, 677dc5742b6SSuraj Kandpal 0x87, 678dc5742b6SSuraj Kandpal 0x88, 679dc5742b6SSuraj Kandpal 0x88, 680dc5742b6SSuraj Kandpal 0x88, 681dc5742b6SSuraj Kandpal 0x88, 682dc5742b6SSuraj Kandpal 0x88, 683dc5742b6SSuraj Kandpal 0x88, 684dc5742b6SSuraj Kandpal 0x88, 685dc5742b6SSuraj Kandpal 0x88, 686dc5742b6SSuraj Kandpal 0x88, 687dc5742b6SSuraj Kandpal }, 688dc5742b6SSuraj Kandpal .addr_lsb = { 689dc5742b6SSuraj Kandpal 0x10, 690dc5742b6SSuraj Kandpal 0x0c, 691dc5742b6SSuraj Kandpal 0x14, 692dc5742b6SSuraj Kandpal 0xe4, 693dc5742b6SSuraj Kandpal 0x0c, 694dc5742b6SSuraj Kandpal 0x10, 695dc5742b6SSuraj Kandpal 0x14, 696dc5742b6SSuraj Kandpal 0x18, 697dc5742b6SSuraj Kandpal 0x48, 698dc5742b6SSuraj Kandpal 0x40, 699dc5742b6SSuraj Kandpal 0x4c, 700dc5742b6SSuraj Kandpal 0x24, 701dc5742b6SSuraj Kandpal 0x44, 702dc5742b6SSuraj Kandpal }, 703dc5742b6SSuraj Kandpal .data = { 704dc5742b6SSuraj Kandpal { 0x0, 0x4c, 0x2, 0x0 }, 705dc5742b6SSuraj Kandpal { 0x1, 0x4a, 0x2b, 0xe0 }, 706dc5742b6SSuraj Kandpal { 0x90, 0x0, 0x0, 0x0 }, 707dc5742b6SSuraj Kandpal { 0x6, 0x4, 0x80, 0xa8 }, 708dc5742b6SSuraj Kandpal { 0xfa, 0x15, 0x83, 0x11 }, 709dc5742b6SSuraj Kandpal { 0x80, 0x0f, 0xf9, 0x53 }, 710dc5742b6SSuraj Kandpal { 0x84, 0x26, 0x6, 0x4 }, 711dc5742b6SSuraj Kandpal { 0x0, 0xe0, 0x1, 0x0 }, 712dc5742b6SSuraj Kandpal { 0x49, 0x48, 0x0, 0x0 }, 713dc5742b6SSuraj Kandpal { 0x27, 0x8, 0x0, 0x0 }, 714dc5742b6SSuraj Kandpal { 0x5a, 0x13, 0x29, 0x13 }, 715dc5742b6SSuraj Kandpal { 0x0, 0x57, 0xe0, 0x0c }, 716dc5742b6SSuraj Kandpal { 0x0, 0x0, 0x0, 0x0 }, 717dc5742b6SSuraj Kandpal }, 718dc5742b6SSuraj Kandpal }; 719dc5742b6SSuraj Kandpal 720dc5742b6SSuraj Kandpal static const struct intel_lt_phy_pll_state * const xe3plpd_lt_edp_tables[] = { 721dc5742b6SSuraj Kandpal &xe3plpd_lt_dp_rbr, 722dc5742b6SSuraj Kandpal &xe3plpd_lt_edp_2_16, 723dc5742b6SSuraj Kandpal &xe3plpd_lt_edp_2_43, 724dc5742b6SSuraj Kandpal &xe3plpd_lt_dp_hbr1, 725dc5742b6SSuraj Kandpal &xe3plpd_lt_edp_3_24, 726dc5742b6SSuraj Kandpal &xe3plpd_lt_edp_4_32, 727dc5742b6SSuraj Kandpal &xe3plpd_lt_dp_hbr2, 728dc5742b6SSuraj Kandpal &xe3plpd_lt_edp_6_75, 729dc5742b6SSuraj Kandpal &xe3plpd_lt_dp_hbr3, 730dc5742b6SSuraj Kandpal NULL, 731dc5742b6SSuraj Kandpal }; 732dc5742b6SSuraj Kandpal 733dc5742b6SSuraj Kandpal static const struct intel_lt_phy_pll_state xe3plpd_lt_hdmi_252 = { 734dc5742b6SSuraj Kandpal .clock = 25200, 735dc5742b6SSuraj Kandpal .config = { 736dc5742b6SSuraj Kandpal 0x84, 737dc5742b6SSuraj Kandpal 0x2d, 738dc5742b6SSuraj Kandpal 0x0, 739dc5742b6SSuraj Kandpal }, 740dc5742b6SSuraj Kandpal .addr_msb = { 741dc5742b6SSuraj Kandpal 0x87, 742dc5742b6SSuraj Kandpal 0x87, 743dc5742b6SSuraj Kandpal 0x87, 744dc5742b6SSuraj Kandpal 0x87, 745dc5742b6SSuraj Kandpal 0x88, 746dc5742b6SSuraj Kandpal 0x88, 747dc5742b6SSuraj Kandpal 0x88, 748dc5742b6SSuraj Kandpal 0x88, 749dc5742b6SSuraj Kandpal 0x88, 750dc5742b6SSuraj Kandpal 0x88, 751dc5742b6SSuraj Kandpal 0x88, 752dc5742b6SSuraj Kandpal 0x88, 753dc5742b6SSuraj Kandpal 0x88, 754dc5742b6SSuraj Kandpal }, 755dc5742b6SSuraj Kandpal .addr_lsb = { 756dc5742b6SSuraj Kandpal 0x10, 757dc5742b6SSuraj Kandpal 0x0c, 758dc5742b6SSuraj Kandpal 0x14, 759dc5742b6SSuraj Kandpal 0xe4, 760dc5742b6SSuraj Kandpal 0x0c, 761dc5742b6SSuraj Kandpal 0x10, 762dc5742b6SSuraj Kandpal 0x14, 763dc5742b6SSuraj Kandpal 0x18, 764dc5742b6SSuraj Kandpal 0x48, 765dc5742b6SSuraj Kandpal 0x40, 766dc5742b6SSuraj Kandpal 0x4c, 767dc5742b6SSuraj Kandpal 0x24, 768dc5742b6SSuraj Kandpal 0x44, 769dc5742b6SSuraj Kandpal }, 770dc5742b6SSuraj Kandpal .data = { 771dc5742b6SSuraj Kandpal { 0x0, 0x4c, 0x2, 0x0 }, 772dc5742b6SSuraj Kandpal { 0x0c, 0x15, 0x27, 0x60 }, 773dc5742b6SSuraj Kandpal { 0x0, 0x0, 0x0, 0x0 }, 774dc5742b6SSuraj Kandpal { 0x8, 0x4, 0x98, 0x28 }, 775dc5742b6SSuraj Kandpal { 0x42, 0x0, 0x84, 0x10 }, 776dc5742b6SSuraj Kandpal { 0x80, 0x0f, 0xd9, 0xb5 }, 777dc5742b6SSuraj Kandpal { 0x86, 0x0, 0x0, 0x0 }, 778dc5742b6SSuraj Kandpal { 0x1, 0xa0, 0x1, 0x0 }, 779dc5742b6SSuraj Kandpal { 0x4b, 0x0, 0x0, 0x0 }, 780dc5742b6SSuraj Kandpal { 0x28, 0x0, 0x0, 0x0 }, 781dc5742b6SSuraj Kandpal { 0x0, 0x14, 0x2a, 0x14 }, 782dc5742b6SSuraj Kandpal { 0x0, 0x0, 0x0, 0x0 }, 783dc5742b6SSuraj Kandpal { 0x0, 0x0, 0x0, 0x0 }, 784dc5742b6SSuraj Kandpal }, 785dc5742b6SSuraj Kandpal }; 786dc5742b6SSuraj Kandpal 787dc5742b6SSuraj Kandpal static const struct intel_lt_phy_pll_state xe3plpd_lt_hdmi_272 = { 788dc5742b6SSuraj Kandpal .clock = 27200, 789dc5742b6SSuraj Kandpal .config = { 790dc5742b6SSuraj Kandpal 0x84, 791dc5742b6SSuraj Kandpal 0x2d, 792dc5742b6SSuraj Kandpal 0x0, 793dc5742b6SSuraj Kandpal }, 794dc5742b6SSuraj Kandpal .addr_msb = { 795dc5742b6SSuraj Kandpal 0x87, 796dc5742b6SSuraj Kandpal 0x87, 797dc5742b6SSuraj Kandpal 0x87, 798dc5742b6SSuraj Kandpal 0x87, 799dc5742b6SSuraj Kandpal 0x88, 800dc5742b6SSuraj Kandpal 0x88, 801dc5742b6SSuraj Kandpal 0x88, 802dc5742b6SSuraj Kandpal 0x88, 803dc5742b6SSuraj Kandpal 0x88, 804dc5742b6SSuraj Kandpal 0x88, 805dc5742b6SSuraj Kandpal 0x88, 806dc5742b6SSuraj Kandpal 0x88, 807dc5742b6SSuraj Kandpal 0x88, 808dc5742b6SSuraj Kandpal }, 809dc5742b6SSuraj Kandpal .addr_lsb = { 810dc5742b6SSuraj Kandpal 0x10, 811dc5742b6SSuraj Kandpal 0x0c, 812dc5742b6SSuraj Kandpal 0x14, 813dc5742b6SSuraj Kandpal 0xe4, 814dc5742b6SSuraj Kandpal 0x0c, 815dc5742b6SSuraj Kandpal 0x10, 816dc5742b6SSuraj Kandpal 0x14, 817dc5742b6SSuraj Kandpal 0x18, 818dc5742b6SSuraj Kandpal 0x48, 819dc5742b6SSuraj Kandpal 0x40, 820dc5742b6SSuraj Kandpal 0x4c, 821dc5742b6SSuraj Kandpal 0x24, 822dc5742b6SSuraj Kandpal 0x44, 823dc5742b6SSuraj Kandpal }, 824dc5742b6SSuraj Kandpal .data = { 825dc5742b6SSuraj Kandpal { 0x0, 0x4c, 0x2, 0x0 }, 826dc5742b6SSuraj Kandpal { 0x0b, 0x15, 0x26, 0xa0 }, 827dc5742b6SSuraj Kandpal { 0x60, 0x0, 0x0, 0x0 }, 828dc5742b6SSuraj Kandpal { 0x8, 0x4, 0x96, 0x28 }, 829dc5742b6SSuraj Kandpal { 0xfa, 0x0c, 0x84, 0x11 }, 830dc5742b6SSuraj Kandpal { 0x80, 0x0f, 0xd9, 0x53 }, 831dc5742b6SSuraj Kandpal { 0x86, 0x0, 0x0, 0x0 }, 832dc5742b6SSuraj Kandpal { 0x1, 0xa0, 0x1, 0x0 }, 833dc5742b6SSuraj Kandpal { 0x4b, 0x0, 0x0, 0x0 }, 834dc5742b6SSuraj Kandpal { 0x28, 0x0, 0x0, 0x0 }, 835dc5742b6SSuraj Kandpal { 0x0, 0x14, 0x2a, 0x14 }, 836dc5742b6SSuraj Kandpal { 0x0, 0x0, 0x0, 0x0 }, 837dc5742b6SSuraj Kandpal { 0x0, 0x0, 0x0, 0x0 }, 838dc5742b6SSuraj Kandpal }, 839dc5742b6SSuraj Kandpal }; 840dc5742b6SSuraj Kandpal 841dc5742b6SSuraj Kandpal static const struct intel_lt_phy_pll_state xe3plpd_lt_hdmi_742p5 = { 842dc5742b6SSuraj Kandpal .clock = 74250, 843dc5742b6SSuraj Kandpal .config = { 844dc5742b6SSuraj Kandpal 0x84, 845dc5742b6SSuraj Kandpal 0x2d, 846dc5742b6SSuraj Kandpal 0x0, 847dc5742b6SSuraj Kandpal }, 848dc5742b6SSuraj Kandpal .addr_msb = { 849dc5742b6SSuraj Kandpal 0x87, 850dc5742b6SSuraj Kandpal 0x87, 851dc5742b6SSuraj Kandpal 0x87, 852dc5742b6SSuraj Kandpal 0x87, 853dc5742b6SSuraj Kandpal 0x88, 854dc5742b6SSuraj Kandpal 0x88, 855dc5742b6SSuraj Kandpal 0x88, 856dc5742b6SSuraj Kandpal 0x88, 857dc5742b6SSuraj Kandpal 0x88, 858dc5742b6SSuraj Kandpal 0x88, 859dc5742b6SSuraj Kandpal 0x88, 860dc5742b6SSuraj Kandpal 0x88, 861dc5742b6SSuraj Kandpal 0x88, 862dc5742b6SSuraj Kandpal }, 863dc5742b6SSuraj Kandpal .addr_lsb = { 864dc5742b6SSuraj Kandpal 0x10, 865dc5742b6SSuraj Kandpal 0x0c, 866dc5742b6SSuraj Kandpal 0x14, 867dc5742b6SSuraj Kandpal 0xe4, 868dc5742b6SSuraj Kandpal 0x0c, 869dc5742b6SSuraj Kandpal 0x10, 870dc5742b6SSuraj Kandpal 0x14, 871dc5742b6SSuraj Kandpal 0x18, 872dc5742b6SSuraj Kandpal 0x48, 873dc5742b6SSuraj Kandpal 0x40, 874dc5742b6SSuraj Kandpal 0x4c, 875dc5742b6SSuraj Kandpal 0x24, 876dc5742b6SSuraj Kandpal 0x44, 877dc5742b6SSuraj Kandpal }, 878dc5742b6SSuraj Kandpal .data = { 879dc5742b6SSuraj Kandpal { 0x0, 0x4c, 0x2, 0x0 }, 880dc5742b6SSuraj Kandpal { 0x4, 0x15, 0x26, 0xa0 }, 881dc5742b6SSuraj Kandpal { 0x60, 0x0, 0x0, 0x0 }, 882dc5742b6SSuraj Kandpal { 0x8, 0x4, 0x88, 0x28 }, 883dc5742b6SSuraj Kandpal { 0xfa, 0x0c, 0x84, 0x11 }, 884dc5742b6SSuraj Kandpal { 0x80, 0x0f, 0xd9, 0x53 }, 885dc5742b6SSuraj Kandpal { 0x86, 0x0, 0x0, 0x0 }, 886dc5742b6SSuraj Kandpal { 0x1, 0xa0, 0x1, 0x0 }, 887dc5742b6SSuraj Kandpal { 0x4b, 0x0, 0x0, 0x0 }, 888dc5742b6SSuraj Kandpal { 0x28, 0x0, 0x0, 0x0 }, 889dc5742b6SSuraj Kandpal { 0x0, 0x14, 0x2a, 0x14 }, 890dc5742b6SSuraj Kandpal { 0x0, 0x0, 0x0, 0x0 }, 891dc5742b6SSuraj Kandpal { 0x0, 0x0, 0x0, 0x0 }, 892dc5742b6SSuraj Kandpal }, 893dc5742b6SSuraj Kandpal }; 894dc5742b6SSuraj Kandpal 895dc5742b6SSuraj Kandpal static const struct intel_lt_phy_pll_state xe3plpd_lt_hdmi_1p485 = { 896dc5742b6SSuraj Kandpal .clock = 148500, 897dc5742b6SSuraj Kandpal .config = { 898dc5742b6SSuraj Kandpal 0x84, 899dc5742b6SSuraj Kandpal 0x2d, 900dc5742b6SSuraj Kandpal 0x0, 901dc5742b6SSuraj Kandpal }, 902dc5742b6SSuraj Kandpal .addr_msb = { 903dc5742b6SSuraj Kandpal 0x87, 904dc5742b6SSuraj Kandpal 0x87, 905dc5742b6SSuraj Kandpal 0x87, 906dc5742b6SSuraj Kandpal 0x87, 907dc5742b6SSuraj Kandpal 0x88, 908dc5742b6SSuraj Kandpal 0x88, 909dc5742b6SSuraj Kandpal 0x88, 910dc5742b6SSuraj Kandpal 0x88, 911dc5742b6SSuraj Kandpal 0x88, 912dc5742b6SSuraj Kandpal 0x88, 913dc5742b6SSuraj Kandpal 0x88, 914dc5742b6SSuraj Kandpal 0x88, 915dc5742b6SSuraj Kandpal 0x88, 916dc5742b6SSuraj Kandpal }, 917dc5742b6SSuraj Kandpal .addr_lsb = { 918dc5742b6SSuraj Kandpal 0x10, 919dc5742b6SSuraj Kandpal 0x0c, 920dc5742b6SSuraj Kandpal 0x14, 921dc5742b6SSuraj Kandpal 0xe4, 922dc5742b6SSuraj Kandpal 0x0c, 923dc5742b6SSuraj Kandpal 0x10, 924dc5742b6SSuraj Kandpal 0x14, 925dc5742b6SSuraj Kandpal 0x18, 926dc5742b6SSuraj Kandpal 0x48, 927dc5742b6SSuraj Kandpal 0x40, 928dc5742b6SSuraj Kandpal 0x4c, 929dc5742b6SSuraj Kandpal 0x24, 930dc5742b6SSuraj Kandpal 0x44, 931dc5742b6SSuraj Kandpal }, 932dc5742b6SSuraj Kandpal .data = { 933dc5742b6SSuraj Kandpal { 0x0, 0x4c, 0x2, 0x0 }, 934dc5742b6SSuraj Kandpal { 0x2, 0x15, 0x26, 0xa0 }, 935dc5742b6SSuraj Kandpal { 0x60, 0x0, 0x0, 0x0 }, 936dc5742b6SSuraj Kandpal { 0x8, 0x4, 0x84, 0x28 }, 937dc5742b6SSuraj Kandpal { 0xfa, 0x0c, 0x84, 0x11 }, 938dc5742b6SSuraj Kandpal { 0x80, 0x0f, 0xd9, 0x53 }, 939dc5742b6SSuraj Kandpal { 0x86, 0x0, 0x0, 0x0 }, 940dc5742b6SSuraj Kandpal { 0x1, 0xa0, 0x1, 0x0 }, 941dc5742b6SSuraj Kandpal { 0x4b, 0x0, 0x0, 0x0 }, 942dc5742b6SSuraj Kandpal { 0x28, 0x0, 0x0, 0x0 }, 943dc5742b6SSuraj Kandpal { 0x0, 0x14, 0x2a, 0x14 }, 944dc5742b6SSuraj Kandpal { 0x0, 0x0, 0x0, 0x0 }, 945dc5742b6SSuraj Kandpal { 0x0, 0x0, 0x0, 0x0 }, 946dc5742b6SSuraj Kandpal }, 947dc5742b6SSuraj Kandpal }; 948dc5742b6SSuraj Kandpal 949dc5742b6SSuraj Kandpal static const struct intel_lt_phy_pll_state xe3plpd_lt_hdmi_5p94 = { 950dc5742b6SSuraj Kandpal .clock = 594000, 951dc5742b6SSuraj Kandpal .config = { 952dc5742b6SSuraj Kandpal 0x84, 953dc5742b6SSuraj Kandpal 0x2d, 954dc5742b6SSuraj Kandpal 0x0, 955dc5742b6SSuraj Kandpal }, 956dc5742b6SSuraj Kandpal .addr_msb = { 957dc5742b6SSuraj Kandpal 0x87, 958dc5742b6SSuraj Kandpal 0x87, 959dc5742b6SSuraj Kandpal 0x87, 960dc5742b6SSuraj Kandpal 0x87, 961dc5742b6SSuraj Kandpal 0x88, 962dc5742b6SSuraj Kandpal 0x88, 963dc5742b6SSuraj Kandpal 0x88, 964dc5742b6SSuraj Kandpal 0x88, 965dc5742b6SSuraj Kandpal 0x88, 966dc5742b6SSuraj Kandpal 0x88, 967dc5742b6SSuraj Kandpal 0x88, 968dc5742b6SSuraj Kandpal 0x88, 969dc5742b6SSuraj Kandpal 0x88, 970dc5742b6SSuraj Kandpal }, 971dc5742b6SSuraj Kandpal .addr_lsb = { 972dc5742b6SSuraj Kandpal 0x10, 973dc5742b6SSuraj Kandpal 0x0c, 974dc5742b6SSuraj Kandpal 0x14, 975dc5742b6SSuraj Kandpal 0xe4, 976dc5742b6SSuraj Kandpal 0x0c, 977dc5742b6SSuraj Kandpal 0x10, 978dc5742b6SSuraj Kandpal 0x14, 979dc5742b6SSuraj Kandpal 0x18, 980dc5742b6SSuraj Kandpal 0x48, 981dc5742b6SSuraj Kandpal 0x40, 982dc5742b6SSuraj Kandpal 0x4c, 983dc5742b6SSuraj Kandpal 0x24, 984dc5742b6SSuraj Kandpal 0x44, 985dc5742b6SSuraj Kandpal }, 986dc5742b6SSuraj Kandpal .data = { 987dc5742b6SSuraj Kandpal { 0x0, 0x4c, 0x2, 0x0 }, 988dc5742b6SSuraj Kandpal { 0x0, 0x95, 0x26, 0xa0 }, 989dc5742b6SSuraj Kandpal { 0x60, 0x0, 0x0, 0x0 }, 990dc5742b6SSuraj Kandpal { 0x8, 0x4, 0x81, 0x28 }, 991dc5742b6SSuraj Kandpal { 0xfa, 0x0c, 0x84, 0x11 }, 992dc5742b6SSuraj Kandpal { 0x80, 0x0f, 0xd9, 0x53 }, 993dc5742b6SSuraj Kandpal { 0x86, 0x0, 0x0, 0x0 }, 994dc5742b6SSuraj Kandpal { 0x1, 0xa0, 0x1, 0x0 }, 995dc5742b6SSuraj Kandpal { 0x4b, 0x0, 0x0, 0x0 }, 996dc5742b6SSuraj Kandpal { 0x28, 0x0, 0x0, 0x0 }, 997dc5742b6SSuraj Kandpal { 0x0, 0x14, 0x2a, 0x14 }, 998dc5742b6SSuraj Kandpal { 0x0, 0x0, 0x0, 0x0 }, 999dc5742b6SSuraj Kandpal { 0x0, 0x0, 0x0, 0x0 }, 1000dc5742b6SSuraj Kandpal }, 1001dc5742b6SSuraj Kandpal }; 1002dc5742b6SSuraj Kandpal 1003dc5742b6SSuraj Kandpal static const struct intel_lt_phy_pll_state * const xe3plpd_lt_hdmi_tables[] = { 1004dc5742b6SSuraj Kandpal &xe3plpd_lt_hdmi_252, 1005dc5742b6SSuraj Kandpal &xe3plpd_lt_hdmi_272, 1006dc5742b6SSuraj Kandpal &xe3plpd_lt_hdmi_742p5, 1007dc5742b6SSuraj Kandpal &xe3plpd_lt_hdmi_1p485, 1008dc5742b6SSuraj Kandpal &xe3plpd_lt_hdmi_5p94, 1009dc5742b6SSuraj Kandpal NULL, 1010dc5742b6SSuraj Kandpal }; 1011dc5742b6SSuraj Kandpal 1012154ebdb7SSuraj Kandpal static u8 intel_lt_phy_get_owned_lane_mask(struct intel_encoder *encoder) 1013154ebdb7SSuraj Kandpal { 1014154ebdb7SSuraj Kandpal struct intel_digital_port *dig_port = enc_to_dig_port(encoder); 1015154ebdb7SSuraj Kandpal 1016154ebdb7SSuraj Kandpal if (!intel_tc_port_in_dp_alt_mode(dig_port)) 1017154ebdb7SSuraj Kandpal return INTEL_LT_PHY_BOTH_LANES; 1018154ebdb7SSuraj Kandpal 1019154ebdb7SSuraj Kandpal return intel_tc_port_max_lane_count(dig_port) > 2 1020154ebdb7SSuraj Kandpal ? INTEL_LT_PHY_BOTH_LANES : INTEL_LT_PHY_LANE0; 1021154ebdb7SSuraj Kandpal } 1022154ebdb7SSuraj Kandpal 1023e1455196SSuraj Kandpal static u8 intel_lt_phy_read(struct intel_encoder *encoder, u8 lane_mask, u16 addr) 1024e1455196SSuraj Kandpal { 1025e1455196SSuraj Kandpal return intel_cx0_read(encoder, lane_mask, addr); 1026e1455196SSuraj Kandpal } 1027e1455196SSuraj Kandpal 10281dd885d5SSuraj Kandpal static void intel_lt_phy_write(struct intel_encoder *encoder, 10291dd885d5SSuraj Kandpal u8 lane_mask, u16 addr, u8 data, bool committed) 10301dd885d5SSuraj Kandpal { 10311dd885d5SSuraj Kandpal intel_cx0_write(encoder, lane_mask, addr, data, committed); 10321dd885d5SSuraj Kandpal } 10331dd885d5SSuraj Kandpal 103413ba213fSSuraj Kandpal static void intel_lt_phy_rmw(struct intel_encoder *encoder, 103513ba213fSSuraj Kandpal u8 lane_mask, u16 addr, u8 clear, u8 set, bool committed) 103613ba213fSSuraj Kandpal { 103713ba213fSSuraj Kandpal intel_cx0_rmw(encoder, lane_mask, addr, clear, set, committed); 103813ba213fSSuraj Kandpal } 103913ba213fSSuraj Kandpal 104041d07bd2SSuraj Kandpal static void intel_lt_phy_clear_status_p2p(struct intel_encoder *encoder, 104141d07bd2SSuraj Kandpal int lane) 104241d07bd2SSuraj Kandpal { 104341d07bd2SSuraj Kandpal struct intel_display *display = to_intel_display(encoder); 104441d07bd2SSuraj Kandpal 104541d07bd2SSuraj Kandpal intel_de_rmw(display, 104641d07bd2SSuraj Kandpal XE3PLPD_PORT_P2M_MSGBUS_STATUS_P2P(encoder->port, lane), 104741d07bd2SSuraj Kandpal XELPDP_PORT_P2M_RESPONSE_READY, 0); 104841d07bd2SSuraj Kandpal } 104941d07bd2SSuraj Kandpal 105041d07bd2SSuraj Kandpal static void 105141d07bd2SSuraj Kandpal assert_dc_off(struct intel_display *display) 105241d07bd2SSuraj Kandpal { 105341d07bd2SSuraj Kandpal bool enabled; 105441d07bd2SSuraj Kandpal 105541d07bd2SSuraj Kandpal enabled = intel_display_power_is_enabled(display, POWER_DOMAIN_DC_OFF); 105641d07bd2SSuraj Kandpal drm_WARN_ON(display->drm, !enabled); 105741d07bd2SSuraj Kandpal } 105841d07bd2SSuraj Kandpal 105941d07bd2SSuraj Kandpal static int __intel_lt_phy_p2p_write_once(struct intel_encoder *encoder, 106041d07bd2SSuraj Kandpal int lane, u16 addr, u8 data, 106141d07bd2SSuraj Kandpal i915_reg_t mac_reg_addr, 106241d07bd2SSuraj Kandpal u8 expected_mac_val) 106341d07bd2SSuraj Kandpal { 106441d07bd2SSuraj Kandpal struct intel_display *display = to_intel_display(encoder); 106541d07bd2SSuraj Kandpal enum port port = encoder->port; 106641d07bd2SSuraj Kandpal enum phy phy = intel_encoder_to_phy(encoder); 106741d07bd2SSuraj Kandpal int ack; 106841d07bd2SSuraj Kandpal u32 val; 106941d07bd2SSuraj Kandpal 107093e0f7c8SVille Syrjälä if (intel_de_wait_for_clear_ms(display, XELPDP_PORT_M2P_MSGBUS_CTL(display, port, lane), 107141d07bd2SSuraj Kandpal XELPDP_PORT_P2P_TRANSACTION_PENDING, 10722d41de25SVille Syrjälä XELPDP_MSGBUS_TIMEOUT_MS)) { 107341d07bd2SSuraj Kandpal drm_dbg_kms(display->drm, 107441d07bd2SSuraj Kandpal "PHY %c Timeout waiting for previous transaction to complete. Resetting bus.\n", 107541d07bd2SSuraj Kandpal phy_name(phy)); 107641d07bd2SSuraj Kandpal intel_cx0_bus_reset(encoder, lane); 107741d07bd2SSuraj Kandpal return -ETIMEDOUT; 107841d07bd2SSuraj Kandpal } 107941d07bd2SSuraj Kandpal 108041d07bd2SSuraj Kandpal intel_de_rmw(display, XELPDP_PORT_P2M_MSGBUS_STATUS(display, port, lane), 0, 0); 108141d07bd2SSuraj Kandpal 108241d07bd2SSuraj Kandpal intel_de_write(display, XELPDP_PORT_M2P_MSGBUS_CTL(display, port, lane), 108341d07bd2SSuraj Kandpal XELPDP_PORT_P2P_TRANSACTION_PENDING | 108441d07bd2SSuraj Kandpal XELPDP_PORT_M2P_COMMAND_WRITE_COMMITTED | 108541d07bd2SSuraj Kandpal XELPDP_PORT_M2P_DATA(data) | 108641d07bd2SSuraj Kandpal XELPDP_PORT_M2P_ADDRESS(addr)); 108741d07bd2SSuraj Kandpal 108841d07bd2SSuraj Kandpal ack = intel_cx0_wait_for_ack(encoder, XELPDP_PORT_P2M_COMMAND_WRITE_ACK, lane, &val); 108941d07bd2SSuraj Kandpal if (ack < 0) 109041d07bd2SSuraj Kandpal return ack; 109141d07bd2SSuraj Kandpal 109241d07bd2SSuraj Kandpal if (val & XELPDP_PORT_P2M_ERROR_SET) { 109341d07bd2SSuraj Kandpal drm_dbg_kms(display->drm, 109441d07bd2SSuraj Kandpal "PHY %c Error occurred during P2P write command. Status: 0x%x\n", 109541d07bd2SSuraj Kandpal phy_name(phy), val); 109641d07bd2SSuraj Kandpal intel_lt_phy_clear_status_p2p(encoder, lane); 109741d07bd2SSuraj Kandpal intel_cx0_bus_reset(encoder, lane); 109841d07bd2SSuraj Kandpal return -EINVAL; 109941d07bd2SSuraj Kandpal } 110041d07bd2SSuraj Kandpal 110141d07bd2SSuraj Kandpal /* 110241d07bd2SSuraj Kandpal * RE-VISIT: 110341d07bd2SSuraj Kandpal * This needs to be added to give PHY time to set everything up this was a requirement 110441d07bd2SSuraj Kandpal * to get the display up and running 110541d07bd2SSuraj Kandpal * This is the time PHY takes to settle down after programming the PHY. 110641d07bd2SSuraj Kandpal */ 110741d07bd2SSuraj Kandpal udelay(150); 110841d07bd2SSuraj Kandpal intel_clear_response_ready_flag(encoder, lane); 110941d07bd2SSuraj Kandpal intel_lt_phy_clear_status_p2p(encoder, lane); 111041d07bd2SSuraj Kandpal 111141d07bd2SSuraj Kandpal return 0; 111241d07bd2SSuraj Kandpal } 111341d07bd2SSuraj Kandpal 111441d07bd2SSuraj Kandpal static void __intel_lt_phy_p2p_write(struct intel_encoder *encoder, 111541d07bd2SSuraj Kandpal int lane, u16 addr, u8 data, 111641d07bd2SSuraj Kandpal i915_reg_t mac_reg_addr, 111741d07bd2SSuraj Kandpal u8 expected_mac_val) 111841d07bd2SSuraj Kandpal { 111941d07bd2SSuraj Kandpal struct intel_display *display = to_intel_display(encoder); 112041d07bd2SSuraj Kandpal enum phy phy = intel_encoder_to_phy(encoder); 112141d07bd2SSuraj Kandpal int i, status; 112241d07bd2SSuraj Kandpal 112341d07bd2SSuraj Kandpal assert_dc_off(display); 112441d07bd2SSuraj Kandpal 112541d07bd2SSuraj Kandpal /* 3 tries is assumed to be enough to write successfully */ 112641d07bd2SSuraj Kandpal for (i = 0; i < 3; i++) { 112741d07bd2SSuraj Kandpal status = __intel_lt_phy_p2p_write_once(encoder, lane, addr, data, mac_reg_addr, 112841d07bd2SSuraj Kandpal expected_mac_val); 112941d07bd2SSuraj Kandpal 113041d07bd2SSuraj Kandpal if (status == 0) 113141d07bd2SSuraj Kandpal return; 113241d07bd2SSuraj Kandpal } 113341d07bd2SSuraj Kandpal 113441d07bd2SSuraj Kandpal drm_err_once(display->drm, 113541d07bd2SSuraj Kandpal "PHY %c P2P Write %04x failed after %d retries.\n", phy_name(phy), addr, i); 113641d07bd2SSuraj Kandpal } 113741d07bd2SSuraj Kandpal 113841d07bd2SSuraj Kandpal static void intel_lt_phy_p2p_write(struct intel_encoder *encoder, 113941d07bd2SSuraj Kandpal u8 lane_mask, u16 addr, u8 data, 114041d07bd2SSuraj Kandpal i915_reg_t mac_reg_addr, 114141d07bd2SSuraj Kandpal u8 expected_mac_val) 114241d07bd2SSuraj Kandpal { 114341d07bd2SSuraj Kandpal int lane; 114441d07bd2SSuraj Kandpal 114541d07bd2SSuraj Kandpal for_each_lt_phy_lane_in_mask(lane_mask, lane) 114641d07bd2SSuraj Kandpal __intel_lt_phy_p2p_write(encoder, lane, addr, data, mac_reg_addr, expected_mac_val); 114741d07bd2SSuraj Kandpal } 114841d07bd2SSuraj Kandpal 1149154ebdb7SSuraj Kandpal static void 1150154ebdb7SSuraj Kandpal intel_lt_phy_setup_powerdown(struct intel_encoder *encoder, u8 lane_count) 1151154ebdb7SSuraj Kandpal { 1152154ebdb7SSuraj Kandpal /* 1153154ebdb7SSuraj Kandpal * The new PORT_BUF_CTL6 stuff for dc5 entry and exit needs to be handled 1154154ebdb7SSuraj Kandpal * by dmc firmware not explicitly mentioned in Bspec. This leaves this 1155154ebdb7SSuraj Kandpal * function as a wrapper only but keeping it expecting future changes. 1156154ebdb7SSuraj Kandpal */ 1157154ebdb7SSuraj Kandpal intel_cx0_setup_powerdown(encoder); 1158154ebdb7SSuraj Kandpal } 1159154ebdb7SSuraj Kandpal 1160154ebdb7SSuraj Kandpal static void 1161fc9be0a1SSuraj Kandpal intel_lt_phy_powerdown_change_sequence(struct intel_encoder *encoder, 1162fc9be0a1SSuraj Kandpal u8 lane_mask, u8 state) 1163fc9be0a1SSuraj Kandpal { 1164fc9be0a1SSuraj Kandpal intel_cx0_powerdown_change_sequence(encoder, lane_mask, state); 1165fc9be0a1SSuraj Kandpal } 1166fc9be0a1SSuraj Kandpal 1167fc9be0a1SSuraj Kandpal static void 1168154ebdb7SSuraj Kandpal intel_lt_phy_lane_reset(struct intel_encoder *encoder, 1169154ebdb7SSuraj Kandpal u8 lane_count) 1170154ebdb7SSuraj Kandpal { 1171154ebdb7SSuraj Kandpal struct intel_display *display = to_intel_display(encoder); 1172154ebdb7SSuraj Kandpal enum port port = encoder->port; 1173154ebdb7SSuraj Kandpal enum phy phy = intel_encoder_to_phy(encoder); 1174154ebdb7SSuraj Kandpal u8 owned_lane_mask = intel_lt_phy_get_owned_lane_mask(encoder); 1175154ebdb7SSuraj Kandpal u32 lane_pipe_reset = owned_lane_mask == INTEL_LT_PHY_BOTH_LANES 1176154ebdb7SSuraj Kandpal ? XELPDP_LANE_PIPE_RESET(0) | XELPDP_LANE_PIPE_RESET(1) 1177154ebdb7SSuraj Kandpal : XELPDP_LANE_PIPE_RESET(0); 1178154ebdb7SSuraj Kandpal u32 lane_phy_current_status = owned_lane_mask == INTEL_LT_PHY_BOTH_LANES 1179154ebdb7SSuraj Kandpal ? (XELPDP_LANE_PHY_CURRENT_STATUS(0) | 1180154ebdb7SSuraj Kandpal XELPDP_LANE_PHY_CURRENT_STATUS(1)) 1181154ebdb7SSuraj Kandpal : XELPDP_LANE_PHY_CURRENT_STATUS(0); 1182154ebdb7SSuraj Kandpal u32 lane_phy_pulse_status = owned_lane_mask == INTEL_LT_PHY_BOTH_LANES 1183154ebdb7SSuraj Kandpal ? (XE3PLPDP_LANE_PHY_PULSE_STATUS(0) | 1184154ebdb7SSuraj Kandpal XE3PLPDP_LANE_PHY_PULSE_STATUS(1)) 1185154ebdb7SSuraj Kandpal : XE3PLPDP_LANE_PHY_PULSE_STATUS(0); 1186154ebdb7SSuraj Kandpal 1187154ebdb7SSuraj Kandpal intel_de_rmw(display, XE3PLPD_PORT_BUF_CTL5(port), 1188154ebdb7SSuraj Kandpal XE3PLPD_MACCLK_RATE_MASK, XE3PLPD_MACCLK_RATE_DEF); 1189154ebdb7SSuraj Kandpal 1190154ebdb7SSuraj Kandpal intel_de_rmw(display, XELPDP_PORT_BUF_CTL1(display, port), 1191154ebdb7SSuraj Kandpal XE3PLPDP_PHY_MODE_MASK, XE3PLPDP_PHY_MODE_DP); 1192154ebdb7SSuraj Kandpal 1193154ebdb7SSuraj Kandpal intel_lt_phy_setup_powerdown(encoder, lane_count); 1194fc9be0a1SSuraj Kandpal intel_lt_phy_powerdown_change_sequence(encoder, owned_lane_mask, 1195fc9be0a1SSuraj Kandpal XELPDP_P2_STATE_RESET); 1196154ebdb7SSuraj Kandpal 1197154ebdb7SSuraj Kandpal intel_de_rmw(display, XE3PLPD_PORT_BUF_CTL5(port), 1198154ebdb7SSuraj Kandpal XE3PLPD_MACCLK_RESET_0, 0); 1199154ebdb7SSuraj Kandpal 1200154ebdb7SSuraj Kandpal intel_de_rmw(display, XELPDP_PORT_CLOCK_CTL(display, port), 1201154ebdb7SSuraj Kandpal XELPDP_LANE_PCLK_PLL_REQUEST(0), 1202154ebdb7SSuraj Kandpal XELPDP_LANE_PCLK_PLL_REQUEST(0)); 1203154ebdb7SSuraj Kandpal 12046be05d5bSVille Syrjälä if (intel_de_wait_for_set_ms(display, XELPDP_PORT_CLOCK_CTL(display, port), 12056be05d5bSVille Syrjälä XELPDP_LANE_PCLK_PLL_ACK(0), 12066be05d5bSVille Syrjälä XE3PLPD_MACCLK_TURNON_LATENCY_MS)) 1207dfd58249SVille Syrjälä drm_warn(display->drm, "PHY %c PLL MacCLK assertion ack not done\n", 1208dfd58249SVille Syrjälä phy_name(phy)); 1209154ebdb7SSuraj Kandpal 1210154ebdb7SSuraj Kandpal intel_de_rmw(display, XELPDP_PORT_CLOCK_CTL(display, port), 1211154ebdb7SSuraj Kandpal XELPDP_FORWARD_CLOCK_UNGATE, 1212154ebdb7SSuraj Kandpal XELPDP_FORWARD_CLOCK_UNGATE); 1213154ebdb7SSuraj Kandpal 1214154ebdb7SSuraj Kandpal intel_de_rmw(display, XELPDP_PORT_BUF_CTL2(display, port), 1215154ebdb7SSuraj Kandpal lane_pipe_reset | lane_phy_pulse_status, 0); 1216154ebdb7SSuraj Kandpal 12176be05d5bSVille Syrjälä if (intel_de_wait_for_clear_ms(display, XELPDP_PORT_BUF_CTL2(display, port), 12186be05d5bSVille Syrjälä lane_phy_current_status, 12196be05d5bSVille Syrjälä XE3PLPD_RESET_END_LATENCY_MS)) 1220dfd58249SVille Syrjälä drm_warn(display->drm, "PHY %c failed to bring out of lane reset\n", 1221dfd58249SVille Syrjälä phy_name(phy)); 1222154ebdb7SSuraj Kandpal 12236be05d5bSVille Syrjälä if (intel_de_wait_for_set_ms(display, XELPDP_PORT_BUF_CTL2(display, port), 12246be05d5bSVille Syrjälä lane_phy_pulse_status, 12256be05d5bSVille Syrjälä XE3PLPD_RATE_CALIB_DONE_LATENCY_MS)) 1226dfd58249SVille Syrjälä drm_warn(display->drm, "PHY %c PLL rate not changed\n", 1227dfd58249SVille Syrjälä phy_name(phy)); 1228154ebdb7SSuraj Kandpal 1229154ebdb7SSuraj Kandpal intel_de_rmw(display, XELPDP_PORT_BUF_CTL2(display, port), lane_phy_pulse_status, 0); 1230154ebdb7SSuraj Kandpal } 1231154ebdb7SSuraj Kandpal 12323a323c7eSSuraj Kandpal static void 12333a323c7eSSuraj Kandpal intel_lt_phy_program_port_clock_ctl(struct intel_encoder *encoder, 12343a323c7eSSuraj Kandpal const struct intel_crtc_state *crtc_state, 12353a323c7eSSuraj Kandpal bool lane_reversal) 12363a323c7eSSuraj Kandpal { 12373a323c7eSSuraj Kandpal struct intel_display *display = to_intel_display(encoder); 12383a323c7eSSuraj Kandpal u32 val = 0; 12393a323c7eSSuraj Kandpal 12403a323c7eSSuraj Kandpal intel_de_rmw(display, XELPDP_PORT_BUF_CTL1(display, encoder->port), 12413a323c7eSSuraj Kandpal XELPDP_PORT_REVERSAL, 12423a323c7eSSuraj Kandpal lane_reversal ? XELPDP_PORT_REVERSAL : 0); 12433a323c7eSSuraj Kandpal 12443a323c7eSSuraj Kandpal val |= XELPDP_FORWARD_CLOCK_UNGATE; 12453a323c7eSSuraj Kandpal 12463a323c7eSSuraj Kandpal /* 12473a323c7eSSuraj Kandpal * We actually mean MACCLK here and not MAXPCLK when using LT Phy 12483a323c7eSSuraj Kandpal * but since the register bits still remain the same we use 12493a323c7eSSuraj Kandpal * the same definition 12503a323c7eSSuraj Kandpal */ 12513a323c7eSSuraj Kandpal if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI) && 12523a323c7eSSuraj Kandpal intel_hdmi_is_frl(crtc_state->port_clock)) 12533a323c7eSSuraj Kandpal val |= XELPDP_DDI_CLOCK_SELECT_PREP(display, XELPDP_DDI_CLOCK_SELECT_DIV18CLK); 12543a323c7eSSuraj Kandpal else 12553a323c7eSSuraj Kandpal val |= XELPDP_DDI_CLOCK_SELECT_PREP(display, XELPDP_DDI_CLOCK_SELECT_MAXPCLK); 12563a323c7eSSuraj Kandpal 12573383ba24SSuraj Kandpal /* DP2.0 10G and 20G rates enable MPLLA*/ 12583383ba24SSuraj Kandpal if (crtc_state->port_clock == 1000000 || crtc_state->port_clock == 2000000) 12593383ba24SSuraj Kandpal val |= XELPDP_SSC_ENABLE_PLLA; 12603383ba24SSuraj Kandpal else 12613383ba24SSuraj Kandpal val |= crtc_state->dpll_hw_state.ltpll.ssc_enabled ? XELPDP_SSC_ENABLE_PLLB : 0; 12623383ba24SSuraj Kandpal 12633a323c7eSSuraj Kandpal intel_de_rmw(display, XELPDP_PORT_CLOCK_CTL(display, encoder->port), 12643a323c7eSSuraj Kandpal XELPDP_LANE1_PHY_CLOCK_SELECT | XELPDP_FORWARD_CLOCK_UNGATE | 12653a323c7eSSuraj Kandpal XELPDP_DDI_CLOCK_SELECT_MASK(display) | XELPDP_SSC_ENABLE_PLLA | 12663a323c7eSSuraj Kandpal XELPDP_SSC_ENABLE_PLLB, val); 12673a323c7eSSuraj Kandpal } 12683a323c7eSSuraj Kandpal 1269e1455196SSuraj Kandpal static u32 intel_lt_phy_get_dp_clock(u8 rate) 1270e1455196SSuraj Kandpal { 1271e1455196SSuraj Kandpal switch (rate) { 1272e1455196SSuraj Kandpal case 0: 1273e1455196SSuraj Kandpal return 162000; 1274e1455196SSuraj Kandpal case 1: 1275e1455196SSuraj Kandpal return 270000; 1276e1455196SSuraj Kandpal case 2: 1277e1455196SSuraj Kandpal return 540000; 1278e1455196SSuraj Kandpal case 3: 1279e1455196SSuraj Kandpal return 810000; 1280e1455196SSuraj Kandpal case 4: 1281e1455196SSuraj Kandpal return 216000; 1282e1455196SSuraj Kandpal case 5: 1283e1455196SSuraj Kandpal return 243000; 1284e1455196SSuraj Kandpal case 6: 1285e1455196SSuraj Kandpal return 324000; 1286e1455196SSuraj Kandpal case 7: 1287e1455196SSuraj Kandpal return 432000; 1288e1455196SSuraj Kandpal case 8: 1289e1455196SSuraj Kandpal return 1000000; 1290e1455196SSuraj Kandpal case 9: 1291e1455196SSuraj Kandpal return 1350000; 1292e1455196SSuraj Kandpal case 10: 1293e1455196SSuraj Kandpal return 2000000; 1294e1455196SSuraj Kandpal case 11: 1295e1455196SSuraj Kandpal return 675000; 1296e1455196SSuraj Kandpal default: 1297e1455196SSuraj Kandpal MISSING_CASE(rate); 1298e1455196SSuraj Kandpal return 0; 1299e1455196SSuraj Kandpal } 1300e1455196SSuraj Kandpal } 1301e1455196SSuraj Kandpal 1302e1455196SSuraj Kandpal static bool 1303e1455196SSuraj Kandpal intel_lt_phy_config_changed(struct intel_encoder *encoder, 1304e1455196SSuraj Kandpal const struct intel_crtc_state *crtc_state) 1305e1455196SSuraj Kandpal { 1306e1455196SSuraj Kandpal u8 val, rate; 1307e1455196SSuraj Kandpal u32 clock; 1308e1455196SSuraj Kandpal 1309e1455196SSuraj Kandpal val = intel_lt_phy_read(encoder, INTEL_LT_PHY_LANE0, 1310e1455196SSuraj Kandpal LT_PHY_VDR_0_CONFIG); 1311e1455196SSuraj Kandpal rate = REG_FIELD_GET8(LT_PHY_VDR_RATE_ENCODING_MASK, val); 1312e1455196SSuraj Kandpal 1313e1455196SSuraj Kandpal /* 1314e1455196SSuraj Kandpal * The only time we do not reconfigure the PLL is when we are 1315e1455196SSuraj Kandpal * using 1.62 Gbps clock since PHY PLL defaults to that 1316e1455196SSuraj Kandpal * otherwise we always need to reconfigure it. 1317e1455196SSuraj Kandpal */ 1318e1455196SSuraj Kandpal if (intel_crtc_has_dp_encoder(crtc_state)) { 1319e1455196SSuraj Kandpal clock = intel_lt_phy_get_dp_clock(rate); 1320e1455196SSuraj Kandpal if (crtc_state->port_clock == 1620000 && crtc_state->port_clock == clock) 1321e1455196SSuraj Kandpal return false; 1322e1455196SSuraj Kandpal } 1323e1455196SSuraj Kandpal 1324e1455196SSuraj Kandpal return true; 1325e1455196SSuraj Kandpal } 1326e1455196SSuraj Kandpal 1327e1455196SSuraj Kandpal static intel_wakeref_t intel_lt_phy_transaction_begin(struct intel_encoder *encoder) 1328e1455196SSuraj Kandpal { 1329e1455196SSuraj Kandpal struct intel_display *display = to_intel_display(encoder); 1330e1455196SSuraj Kandpal struct intel_dp *intel_dp = enc_to_intel_dp(encoder); 1331e1455196SSuraj Kandpal intel_wakeref_t wakeref; 1332e1455196SSuraj Kandpal 1333e1455196SSuraj Kandpal intel_psr_pause(intel_dp); 1334e1455196SSuraj Kandpal wakeref = intel_display_power_get(display, POWER_DOMAIN_DC_OFF); 1335e1455196SSuraj Kandpal 1336e1455196SSuraj Kandpal return wakeref; 1337e1455196SSuraj Kandpal } 1338e1455196SSuraj Kandpal 1339e1455196SSuraj Kandpal static void intel_lt_phy_transaction_end(struct intel_encoder *encoder, intel_wakeref_t wakeref) 1340e1455196SSuraj Kandpal { 1341e1455196SSuraj Kandpal struct intel_display *display = to_intel_display(encoder); 1342e1455196SSuraj Kandpal struct intel_dp *intel_dp = enc_to_intel_dp(encoder); 1343e1455196SSuraj Kandpal 1344e1455196SSuraj Kandpal intel_psr_resume(intel_dp); 1345e1455196SSuraj Kandpal intel_display_power_put(display, POWER_DOMAIN_DC_OFF, wakeref); 1346e1455196SSuraj Kandpal } 1347e1455196SSuraj Kandpal 1348dc5742b6SSuraj Kandpal static const struct intel_lt_phy_pll_state * const * 1349dc5742b6SSuraj Kandpal intel_lt_phy_pll_tables_get(struct intel_crtc_state *crtc_state, 1350dc5742b6SSuraj Kandpal struct intel_encoder *encoder) 1351dc5742b6SSuraj Kandpal { 1352dc5742b6SSuraj Kandpal if (intel_crtc_has_dp_encoder(crtc_state)) { 1353dc5742b6SSuraj Kandpal if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_EDP)) 1354dc5742b6SSuraj Kandpal return xe3plpd_lt_edp_tables; 1355dc5742b6SSuraj Kandpal 1356dc5742b6SSuraj Kandpal return xe3plpd_lt_dp_tables; 1357dc5742b6SSuraj Kandpal } else if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI)) { 1358dc5742b6SSuraj Kandpal return xe3plpd_lt_hdmi_tables; 1359dc5742b6SSuraj Kandpal } 1360dc5742b6SSuraj Kandpal 1361dc5742b6SSuraj Kandpal MISSING_CASE(encoder->type); 1362dc5742b6SSuraj Kandpal return NULL; 1363dc5742b6SSuraj Kandpal } 1364dc5742b6SSuraj Kandpal 13653383ba24SSuraj Kandpal static bool 13663383ba24SSuraj Kandpal intel_lt_phy_pll_is_ssc_enabled(struct intel_crtc_state *crtc_state, 13673383ba24SSuraj Kandpal struct intel_encoder *encoder) 13683383ba24SSuraj Kandpal { 13693383ba24SSuraj Kandpal struct intel_display *display = to_intel_display(encoder); 13703383ba24SSuraj Kandpal 13713383ba24SSuraj Kandpal if (intel_crtc_has_dp_encoder(crtc_state)) { 13723383ba24SSuraj Kandpal if (intel_panel_use_ssc(display)) { 13733383ba24SSuraj Kandpal struct intel_dp *intel_dp = enc_to_intel_dp(encoder); 13743383ba24SSuraj Kandpal 13753383ba24SSuraj Kandpal return (intel_dp->dpcd[DP_MAX_DOWNSPREAD] & DP_MAX_DOWNSPREAD_0_5); 13763383ba24SSuraj Kandpal } 13773383ba24SSuraj Kandpal } 13783383ba24SSuraj Kandpal 13793383ba24SSuraj Kandpal return false; 13803383ba24SSuraj Kandpal } 13813383ba24SSuraj Kandpal 13826fedb7bfSSuraj Kandpal static u64 mul_q32_u32(u64 a_q32, u32 b) 13836fedb7bfSSuraj Kandpal { 13846fedb7bfSSuraj Kandpal u64 p0, p1, carry, result; 13856fedb7bfSSuraj Kandpal u64 x_hi = a_q32 >> 32; 13866fedb7bfSSuraj Kandpal u64 x_lo = a_q32 & 0xFFFFFFFFULL; 13876fedb7bfSSuraj Kandpal 13886fedb7bfSSuraj Kandpal p0 = x_lo * (u64)b; 13896fedb7bfSSuraj Kandpal p1 = x_hi * (u64)b; 13906fedb7bfSSuraj Kandpal carry = p0 >> 32; 13916fedb7bfSSuraj Kandpal result = (p1 << 32) + (carry << 32) + (p0 & 0xFFFFFFFFULL); 13926fedb7bfSSuraj Kandpal 13936fedb7bfSSuraj Kandpal return result; 13946fedb7bfSSuraj Kandpal } 13956fedb7bfSSuraj Kandpal 13966fedb7bfSSuraj Kandpal static bool 13976fedb7bfSSuraj Kandpal calculate_target_dco_and_loop_cnt(u32 frequency_khz, u64 *target_dco_mhz, u32 *loop_cnt) 13986fedb7bfSSuraj Kandpal { 13996fedb7bfSSuraj Kandpal u32 ppm_value = 1; 14006fedb7bfSSuraj Kandpal u32 dco_min_freq = DCO_MIN_FREQ_MHZ; 14016fedb7bfSSuraj Kandpal u32 dco_max_freq = 16200; 14026fedb7bfSSuraj Kandpal u32 dco_min_freq_low = 10000; 14036fedb7bfSSuraj Kandpal u32 dco_max_freq_low = 12000; 14046fedb7bfSSuraj Kandpal u64 val = 0; 14056fedb7bfSSuraj Kandpal u64 refclk_khz = REF_CLK_KHZ; 14066fedb7bfSSuraj Kandpal u64 m2div = 0; 14076fedb7bfSSuraj Kandpal u64 val_with_frac = 0; 14086fedb7bfSSuraj Kandpal u64 ppm = 0; 14096fedb7bfSSuraj Kandpal u64 temp0 = 0, temp1, scale; 14106fedb7bfSSuraj Kandpal int ppm_cnt, dco_count, y; 14116fedb7bfSSuraj Kandpal 14126fedb7bfSSuraj Kandpal for (ppm_cnt = 0; ppm_cnt < 5; ppm_cnt++) { 14136fedb7bfSSuraj Kandpal ppm_value = ppm_cnt == 2 ? 2 : 1; 14146fedb7bfSSuraj Kandpal for (dco_count = 0; dco_count < 2; dco_count++) { 14156fedb7bfSSuraj Kandpal if (dco_count == 1) { 14166fedb7bfSSuraj Kandpal dco_min_freq = dco_min_freq_low; 14176fedb7bfSSuraj Kandpal dco_max_freq = dco_max_freq_low; 14186fedb7bfSSuraj Kandpal } 14196fedb7bfSSuraj Kandpal for (y = 2; y <= 255; y += 2) { 14206fedb7bfSSuraj Kandpal val = div64_u64((u64)y * frequency_khz, 200); 14216fedb7bfSSuraj Kandpal m2div = div64_u64(((u64)(val) << 32), refclk_khz); 14226fedb7bfSSuraj Kandpal m2div = mul_q32_u32(m2div, 500); 14236fedb7bfSSuraj Kandpal val_with_frac = mul_q32_u32(m2div, refclk_khz); 14246fedb7bfSSuraj Kandpal val_with_frac = div64_u64(val_with_frac, 500); 14256fedb7bfSSuraj Kandpal temp1 = Q32_TO_INT(val_with_frac); 14266fedb7bfSSuraj Kandpal temp0 = (temp1 > val) ? (temp1 - val) : 14276fedb7bfSSuraj Kandpal (val - temp1); 14286fedb7bfSSuraj Kandpal ppm = div64_u64(temp0, val); 14296fedb7bfSSuraj Kandpal if (temp1 >= dco_min_freq && 14306fedb7bfSSuraj Kandpal temp1 <= dco_max_freq && 14316fedb7bfSSuraj Kandpal ppm < ppm_value) { 14326fedb7bfSSuraj Kandpal /* Round to two places */ 14336fedb7bfSSuraj Kandpal scale = (1ULL << 32) / 100; 14346fedb7bfSSuraj Kandpal temp0 = DIV_ROUND_UP_ULL(val_with_frac, 14356fedb7bfSSuraj Kandpal scale); 14366fedb7bfSSuraj Kandpal *target_dco_mhz = temp0 * scale; 14376fedb7bfSSuraj Kandpal *loop_cnt = y; 14386fedb7bfSSuraj Kandpal return true; 14396fedb7bfSSuraj Kandpal } 14406fedb7bfSSuraj Kandpal } 14416fedb7bfSSuraj Kandpal } 14426fedb7bfSSuraj Kandpal } 14436fedb7bfSSuraj Kandpal 14446fedb7bfSSuraj Kandpal return false; 14456fedb7bfSSuraj Kandpal } 14466fedb7bfSSuraj Kandpal 14476fedb7bfSSuraj Kandpal static void set_phy_vdr_addresses(struct lt_phy_params *p, int pll_type) 14486fedb7bfSSuraj Kandpal { 14496fedb7bfSSuraj Kandpal p->pll_reg4.addr = PLL_REG_ADDR(PLL_REG4_ADDR, pll_type); 14506fedb7bfSSuraj Kandpal p->pll_reg3.addr = PLL_REG_ADDR(PLL_REG3_ADDR, pll_type); 14516fedb7bfSSuraj Kandpal p->pll_reg5.addr = PLL_REG_ADDR(PLL_REG5_ADDR, pll_type); 14526fedb7bfSSuraj Kandpal p->pll_reg57.addr = PLL_REG_ADDR(PLL_REG57_ADDR, pll_type); 14536fedb7bfSSuraj Kandpal p->lf.addr = PLL_REG_ADDR(PLL_LF_ADDR, pll_type); 14546fedb7bfSSuraj Kandpal p->tdc.addr = PLL_REG_ADDR(PLL_TDC_ADDR, pll_type); 14556fedb7bfSSuraj Kandpal p->ssc.addr = PLL_REG_ADDR(PLL_SSC_ADDR, pll_type); 14566fedb7bfSSuraj Kandpal p->bias2.addr = PLL_REG_ADDR(PLL_BIAS2_ADDR, pll_type); 14576fedb7bfSSuraj Kandpal p->bias_trim.addr = PLL_REG_ADDR(PLL_BIAS_TRIM_ADDR, pll_type); 14586fedb7bfSSuraj Kandpal p->dco_med.addr = PLL_REG_ADDR(PLL_DCO_MED_ADDR, pll_type); 14596fedb7bfSSuraj Kandpal p->dco_fine.addr = PLL_REG_ADDR(PLL_DCO_FINE_ADDR, pll_type); 14606fedb7bfSSuraj Kandpal p->ssc_inj.addr = PLL_REG_ADDR(PLL_SSC_INJ_ADDR, pll_type); 14616fedb7bfSSuraj Kandpal p->surv_bonus.addr = PLL_REG_ADDR(PLL_SURV_BONUS_ADDR, pll_type); 14626fedb7bfSSuraj Kandpal } 14636fedb7bfSSuraj Kandpal 14646fedb7bfSSuraj Kandpal static void compute_ssc(struct lt_phy_params *p, u32 ana_cfg) 14656fedb7bfSSuraj Kandpal { 14666fedb7bfSSuraj Kandpal int ssc_stepsize = 0; 14676fedb7bfSSuraj Kandpal int ssc_steplen = 0; 14686fedb7bfSSuraj Kandpal int ssc_steplog = 0; 14696fedb7bfSSuraj Kandpal 14706fedb7bfSSuraj Kandpal p->ssc.val = (1 << 31) | (ana_cfg << 24) | (ssc_steplog << 16) | 14716fedb7bfSSuraj Kandpal (ssc_stepsize << 8) | ssc_steplen; 14726fedb7bfSSuraj Kandpal } 14736fedb7bfSSuraj Kandpal 14746fedb7bfSSuraj Kandpal static void compute_bias2(struct lt_phy_params *p) 14756fedb7bfSSuraj Kandpal { 14766fedb7bfSSuraj Kandpal u32 ssc_en_local = 0; 14776fedb7bfSSuraj Kandpal u64 dynctrl_ovrd_en = 0; 14786fedb7bfSSuraj Kandpal 14796fedb7bfSSuraj Kandpal p->bias2.val = (dynctrl_ovrd_en << 31) | (ssc_en_local << 30) | 14806fedb7bfSSuraj Kandpal (1 << 23) | (1 << 24) | (32 << 16) | (1 << 8); 14816fedb7bfSSuraj Kandpal } 14826fedb7bfSSuraj Kandpal 14836fedb7bfSSuraj Kandpal static void compute_tdc(struct lt_phy_params *p, u64 tdc_fine) 14846fedb7bfSSuraj Kandpal { 14856fedb7bfSSuraj Kandpal u32 settling_time = 15; 14866fedb7bfSSuraj Kandpal u32 bias_ovr_en = 1; 14876fedb7bfSSuraj Kandpal u32 coldstart = 1; 14886fedb7bfSSuraj Kandpal u32 true_lock = 2; 14896fedb7bfSSuraj Kandpal u32 early_lock = 1; 14906fedb7bfSSuraj Kandpal u32 lock_ovr_en = 1; 14916fedb7bfSSuraj Kandpal u32 lock_thr = tdc_fine ? 3 : 5; 14926fedb7bfSSuraj Kandpal u32 unlock_thr = tdc_fine ? 5 : 11; 14936fedb7bfSSuraj Kandpal 14946fedb7bfSSuraj Kandpal p->tdc.val = (u32)((2 << 30) + (settling_time << 16) + (bias_ovr_en << 15) + 14956fedb7bfSSuraj Kandpal (lock_ovr_en << 14) + (coldstart << 12) + (true_lock << 10) + 14966fedb7bfSSuraj Kandpal (early_lock << 8) + (unlock_thr << 4) + lock_thr); 14976fedb7bfSSuraj Kandpal } 14986fedb7bfSSuraj Kandpal 14996fedb7bfSSuraj Kandpal static void compute_dco_med(struct lt_phy_params *p) 15006fedb7bfSSuraj Kandpal { 15016fedb7bfSSuraj Kandpal u32 cselmed_en = 0; 15026fedb7bfSSuraj Kandpal u32 cselmed_dyn_adj = 0; 15036fedb7bfSSuraj Kandpal u32 cselmed_ratio = 39; 15046fedb7bfSSuraj Kandpal u32 cselmed_thr = 8; 15056fedb7bfSSuraj Kandpal 15066fedb7bfSSuraj Kandpal p->dco_med.val = (cselmed_en << 31) + (cselmed_dyn_adj << 30) + 15076fedb7bfSSuraj Kandpal (cselmed_ratio << 24) + (cselmed_thr << 21); 15086fedb7bfSSuraj Kandpal } 15096fedb7bfSSuraj Kandpal 15106fedb7bfSSuraj Kandpal static void compute_dco_fine(struct lt_phy_params *p, u32 dco_12g) 15116fedb7bfSSuraj Kandpal { 15126fedb7bfSSuraj Kandpal u32 dco_fine0_tune_2_0 = 0; 15136fedb7bfSSuraj Kandpal u32 dco_fine1_tune_2_0 = 0; 15146fedb7bfSSuraj Kandpal u32 dco_fine2_tune_2_0 = 0; 15156fedb7bfSSuraj Kandpal u32 dco_fine3_tune_2_0 = 0; 15166fedb7bfSSuraj Kandpal u32 dco_dith0_tune_2_0 = 0; 15176fedb7bfSSuraj Kandpal u32 dco_dith1_tune_2_0 = 0; 15186fedb7bfSSuraj Kandpal 15196fedb7bfSSuraj Kandpal dco_fine0_tune_2_0 = dco_12g ? 4 : 3; 15206fedb7bfSSuraj Kandpal dco_fine1_tune_2_0 = 2; 15216fedb7bfSSuraj Kandpal dco_fine2_tune_2_0 = dco_12g ? 2 : 1; 15226fedb7bfSSuraj Kandpal dco_fine3_tune_2_0 = 5; 15236fedb7bfSSuraj Kandpal dco_dith0_tune_2_0 = dco_12g ? 4 : 3; 15246fedb7bfSSuraj Kandpal dco_dith1_tune_2_0 = 2; 15256fedb7bfSSuraj Kandpal 15266fedb7bfSSuraj Kandpal p->dco_fine.val = (dco_dith1_tune_2_0 << 19) + 15276fedb7bfSSuraj Kandpal (dco_dith0_tune_2_0 << 16) + 15286fedb7bfSSuraj Kandpal (dco_fine3_tune_2_0 << 11) + 15296fedb7bfSSuraj Kandpal (dco_fine2_tune_2_0 << 8) + 15306fedb7bfSSuraj Kandpal (dco_fine1_tune_2_0 << 3) + 15316fedb7bfSSuraj Kandpal dco_fine0_tune_2_0; 15326fedb7bfSSuraj Kandpal } 15336fedb7bfSSuraj Kandpal 15346fedb7bfSSuraj Kandpal int 15356fedb7bfSSuraj Kandpal intel_lt_phy_calculate_hdmi_state(struct intel_lt_phy_pll_state *lt_state, 15366fedb7bfSSuraj Kandpal u32 frequency_khz) 15376fedb7bfSSuraj Kandpal { 15386fedb7bfSSuraj Kandpal #define DATA_ASSIGN(i, pll_reg) \ 15396fedb7bfSSuraj Kandpal do { \ 15406fedb7bfSSuraj Kandpal lt_state->data[i][0] = (u8)((((pll_reg).val) & 0xFF000000) >> 24); \ 15416fedb7bfSSuraj Kandpal lt_state->data[i][1] = (u8)((((pll_reg).val) & 0x00FF0000) >> 16); \ 15426fedb7bfSSuraj Kandpal lt_state->data[i][2] = (u8)((((pll_reg).val) & 0x0000FF00) >> 8); \ 15436fedb7bfSSuraj Kandpal lt_state->data[i][3] = (u8)((((pll_reg).val) & 0x000000FF)); \ 15446fedb7bfSSuraj Kandpal } while (0) 15456fedb7bfSSuraj Kandpal #define ADDR_ASSIGN(i, pll_reg) \ 15466fedb7bfSSuraj Kandpal do { \ 15476fedb7bfSSuraj Kandpal lt_state->addr_msb[i] = ((pll_reg).addr >> 8) & 0xFF; \ 15486fedb7bfSSuraj Kandpal lt_state->addr_lsb[i] = (pll_reg).addr & 0xFF; \ 15496fedb7bfSSuraj Kandpal } while (0) 15506fedb7bfSSuraj Kandpal 15516fedb7bfSSuraj Kandpal bool found = false; 15526fedb7bfSSuraj Kandpal struct lt_phy_params p; 15536fedb7bfSSuraj Kandpal u32 dco_fmin = DCO_MIN_FREQ_MHZ; 15546fedb7bfSSuraj Kandpal u64 refclk_khz = REF_CLK_KHZ; 15556fedb7bfSSuraj Kandpal u32 refclk_mhz_int = REF_CLK_KHZ / 1000; 15566fedb7bfSSuraj Kandpal u64 m2div = 0; 15576fedb7bfSSuraj Kandpal u64 target_dco_mhz = 0; 15586fedb7bfSSuraj Kandpal u64 tdc_fine, tdc_targetcnt; 15596fedb7bfSSuraj Kandpal u64 feedfwd_gain ,feedfwd_cal_en; 15606fedb7bfSSuraj Kandpal u64 tdc_res = 30; 15616fedb7bfSSuraj Kandpal u32 prop_coeff; 15626fedb7bfSSuraj Kandpal u32 int_coeff; 15636fedb7bfSSuraj Kandpal u32 ndiv = 1; 15646fedb7bfSSuraj Kandpal u32 m1div = 1, m2div_int, m2div_frac; 15656fedb7bfSSuraj Kandpal u32 frac_en; 15666fedb7bfSSuraj Kandpal u32 ana_cfg; 15676fedb7bfSSuraj Kandpal u32 loop_cnt = 0; 15686fedb7bfSSuraj Kandpal u32 gain_ctrl = 2; 15696fedb7bfSSuraj Kandpal u32 postdiv = 0; 15706fedb7bfSSuraj Kandpal u32 dco_12g = 0; 15716fedb7bfSSuraj Kandpal u32 pll_type = 0; 15726fedb7bfSSuraj Kandpal u32 d1 = 2, d3 = 5, d4 = 0, d5 = 0; 15736fedb7bfSSuraj Kandpal u32 d6 = 0, d6_new = 0; 15746fedb7bfSSuraj Kandpal u32 d7, d8 = 0; 15756fedb7bfSSuraj Kandpal u32 bonus_7_0 = 0; 15766fedb7bfSSuraj Kandpal u32 csel2fo = 11; 15776fedb7bfSSuraj Kandpal u32 csel2fo_ovrd_en = 1; 15786fedb7bfSSuraj Kandpal u64 temp0, temp1, temp2, temp3; 15796fedb7bfSSuraj Kandpal 15806fedb7bfSSuraj Kandpal p.surv_bonus.val = (bonus_7_0 << 16); 15816fedb7bfSSuraj Kandpal p.pll_reg4.val = (refclk_mhz_int << 17) + 15826fedb7bfSSuraj Kandpal (ndiv << 9) + (1 << 4); 15836fedb7bfSSuraj Kandpal p.bias_trim.val = (csel2fo_ovrd_en << 30) + (csel2fo << 24); 15846fedb7bfSSuraj Kandpal p.ssc_inj.val = 0; 15856fedb7bfSSuraj Kandpal found = calculate_target_dco_and_loop_cnt(frequency_khz, &target_dco_mhz, &loop_cnt); 15866fedb7bfSSuraj Kandpal if (!found) 15876fedb7bfSSuraj Kandpal return -EINVAL; 15886fedb7bfSSuraj Kandpal 15896fedb7bfSSuraj Kandpal m2div = div64_u64(target_dco_mhz, (refclk_khz * ndiv * m1div)); 15906fedb7bfSSuraj Kandpal m2div = mul_q32_u32(m2div, 1000); 15916fedb7bfSSuraj Kandpal if (Q32_TO_INT(m2div) > 511) 15926fedb7bfSSuraj Kandpal return -EINVAL; 15936fedb7bfSSuraj Kandpal 15946fedb7bfSSuraj Kandpal m2div_int = (u32)Q32_TO_INT(m2div); 15956fedb7bfSSuraj Kandpal m2div_frac = (u32)(Q32_TO_FRAC(m2div)); 15966fedb7bfSSuraj Kandpal frac_en = (m2div_frac > 0) ? 1 : 0; 15976fedb7bfSSuraj Kandpal 15986fedb7bfSSuraj Kandpal if (frac_en > 0) 15996fedb7bfSSuraj Kandpal tdc_res = 70; 16006fedb7bfSSuraj Kandpal else 16016fedb7bfSSuraj Kandpal tdc_res = 36; 16026fedb7bfSSuraj Kandpal tdc_fine = tdc_res > 50 ? 1 : 0; 16036fedb7bfSSuraj Kandpal temp0 = tdc_res * 40 * 11; 16046fedb7bfSSuraj Kandpal temp1 = div64_u64(((4 * TDC_RES_MULTIPLIER) + temp0) * 500, temp0 * refclk_khz); 16056fedb7bfSSuraj Kandpal temp2 = div64_u64(temp0 * refclk_khz, 1000); 16066fedb7bfSSuraj Kandpal temp3 = div64_u64(((8 * TDC_RES_MULTIPLIER) + temp2), temp2); 16076fedb7bfSSuraj Kandpal tdc_targetcnt = tdc_res < 50 ? (int)(temp1) : (int)(temp3); 16086fedb7bfSSuraj Kandpal tdc_targetcnt = (int)(tdc_targetcnt / 2); 16096fedb7bfSSuraj Kandpal temp0 = mul_q32_u32(target_dco_mhz, tdc_res); 16106fedb7bfSSuraj Kandpal temp0 >>= 32; 16116fedb7bfSSuraj Kandpal feedfwd_gain = (m2div_frac > 0) ? div64_u64(m1div * TDC_RES_MULTIPLIER, temp0) : 0; 16126fedb7bfSSuraj Kandpal feedfwd_cal_en = frac_en; 16136fedb7bfSSuraj Kandpal 16146fedb7bfSSuraj Kandpal temp0 = (u32)Q32_TO_INT(target_dco_mhz); 16156fedb7bfSSuraj Kandpal prop_coeff = (temp0 >= dco_fmin) ? 3 : 4; 16166fedb7bfSSuraj Kandpal int_coeff = (temp0 >= dco_fmin) ? 7 : 8; 16176fedb7bfSSuraj Kandpal ana_cfg = (temp0 >= dco_fmin) ? 8 : 6; 16186fedb7bfSSuraj Kandpal dco_12g = (temp0 >= dco_fmin) ? 0 : 1; 16196fedb7bfSSuraj Kandpal 16206fedb7bfSSuraj Kandpal if (temp0 > 12960) 16216fedb7bfSSuraj Kandpal d7 = 10; 16226fedb7bfSSuraj Kandpal else 16236fedb7bfSSuraj Kandpal d7 = 8; 16246fedb7bfSSuraj Kandpal 16256fedb7bfSSuraj Kandpal d8 = loop_cnt / 2; 16266fedb7bfSSuraj Kandpal d4 = d8 * 2; 16276fedb7bfSSuraj Kandpal 16286fedb7bfSSuraj Kandpal /* Compute pll_reg3,5,57 & lf */ 16296fedb7bfSSuraj Kandpal p.pll_reg3.val = (u32)((d4 << 21) + (d3 << 18) + (d1 << 15) + (m2div_int << 5)); 16306fedb7bfSSuraj Kandpal p.pll_reg5.val = m2div_frac; 16316fedb7bfSSuraj Kandpal postdiv = (d5 == 0) ? 9 : d5; 16326fedb7bfSSuraj Kandpal d6_new = (d6 == 0) ? 40 : d6; 16336fedb7bfSSuraj Kandpal p.pll_reg57.val = (d7 << 24) + (postdiv << 15) + (d8 << 7) + d6_new; 16346fedb7bfSSuraj Kandpal p.lf.val = (u32)((frac_en << 31) + (1 << 30) + (frac_en << 29) + 16356fedb7bfSSuraj Kandpal (feedfwd_cal_en << 28) + (tdc_fine << 27) + 16366fedb7bfSSuraj Kandpal (gain_ctrl << 24) + (feedfwd_gain << 16) + 16376fedb7bfSSuraj Kandpal (int_coeff << 12) + (prop_coeff << 8) + tdc_targetcnt); 16386fedb7bfSSuraj Kandpal 16396fedb7bfSSuraj Kandpal compute_ssc(&p, ana_cfg); 16406fedb7bfSSuraj Kandpal compute_bias2(&p); 16416fedb7bfSSuraj Kandpal compute_tdc(&p, tdc_fine); 16426fedb7bfSSuraj Kandpal compute_dco_med(&p); 16436fedb7bfSSuraj Kandpal compute_dco_fine(&p, dco_12g); 16446fedb7bfSSuraj Kandpal 16456fedb7bfSSuraj Kandpal pll_type = ((frequency_khz == 10000) || (frequency_khz == 20000) || 16466fedb7bfSSuraj Kandpal (frequency_khz == 2500) || (dco_12g == 1)) ? 0 : 1; 16476fedb7bfSSuraj Kandpal set_phy_vdr_addresses(&p, pll_type); 16486fedb7bfSSuraj Kandpal 16496fedb7bfSSuraj Kandpal lt_state->config[0] = 0x84; 16506fedb7bfSSuraj Kandpal lt_state->config[1] = 0x2d; 16516fedb7bfSSuraj Kandpal ADDR_ASSIGN(0, p.pll_reg4); 16526fedb7bfSSuraj Kandpal ADDR_ASSIGN(1, p.pll_reg3); 16536fedb7bfSSuraj Kandpal ADDR_ASSIGN(2, p.pll_reg5); 16546fedb7bfSSuraj Kandpal ADDR_ASSIGN(3, p.pll_reg57); 16556fedb7bfSSuraj Kandpal ADDR_ASSIGN(4, p.lf); 16566fedb7bfSSuraj Kandpal ADDR_ASSIGN(5, p.tdc); 16576fedb7bfSSuraj Kandpal ADDR_ASSIGN(6, p.ssc); 16586fedb7bfSSuraj Kandpal ADDR_ASSIGN(7, p.bias2); 16596fedb7bfSSuraj Kandpal ADDR_ASSIGN(8, p.bias_trim); 16606fedb7bfSSuraj Kandpal ADDR_ASSIGN(9, p.dco_med); 16616fedb7bfSSuraj Kandpal ADDR_ASSIGN(10, p.dco_fine); 16626fedb7bfSSuraj Kandpal ADDR_ASSIGN(11, p.ssc_inj); 16636fedb7bfSSuraj Kandpal ADDR_ASSIGN(12, p.surv_bonus); 16646fedb7bfSSuraj Kandpal DATA_ASSIGN(0, p.pll_reg4); 16656fedb7bfSSuraj Kandpal DATA_ASSIGN(1, p.pll_reg3); 16666fedb7bfSSuraj Kandpal DATA_ASSIGN(2, p.pll_reg5); 16676fedb7bfSSuraj Kandpal DATA_ASSIGN(3, p.pll_reg57); 16686fedb7bfSSuraj Kandpal DATA_ASSIGN(4, p.lf); 16696fedb7bfSSuraj Kandpal DATA_ASSIGN(5, p.tdc); 16706fedb7bfSSuraj Kandpal DATA_ASSIGN(6, p.ssc); 16716fedb7bfSSuraj Kandpal DATA_ASSIGN(7, p.bias2); 16726fedb7bfSSuraj Kandpal DATA_ASSIGN(8, p.bias_trim); 16736fedb7bfSSuraj Kandpal DATA_ASSIGN(9, p.dco_med); 16746fedb7bfSSuraj Kandpal DATA_ASSIGN(10, p.dco_fine); 16756fedb7bfSSuraj Kandpal DATA_ASSIGN(11, p.ssc_inj); 16766fedb7bfSSuraj Kandpal DATA_ASSIGN(12, p.surv_bonus); 16776fedb7bfSSuraj Kandpal 16786fedb7bfSSuraj Kandpal return 0; 16796fedb7bfSSuraj Kandpal } 16806fedb7bfSSuraj Kandpal 16812435a11dSSuraj Kandpal static int 1682fa4aa0b2SSuraj Kandpal intel_lt_phy_calc_hdmi_port_clock(const struct intel_crtc_state *crtc_state) 16832435a11dSSuraj Kandpal { 16842435a11dSSuraj Kandpal #define REGVAL(i) ( \ 16852435a11dSSuraj Kandpal (lt_state->data[i][3]) | \ 16862435a11dSSuraj Kandpal (lt_state->data[i][2] << 8) | \ 16872435a11dSSuraj Kandpal (lt_state->data[i][1] << 16) | \ 16882435a11dSSuraj Kandpal (lt_state->data[i][0] << 24) \ 16892435a11dSSuraj Kandpal ) 16902435a11dSSuraj Kandpal 1691fa4aa0b2SSuraj Kandpal struct intel_display *display = to_intel_display(crtc_state); 1692fa4aa0b2SSuraj Kandpal const struct intel_lt_phy_pll_state *lt_state = 1693fa4aa0b2SSuraj Kandpal &crtc_state->dpll_hw_state.ltpll; 16942435a11dSSuraj Kandpal int clk = 0; 16952435a11dSSuraj Kandpal u32 d8, pll_reg_5, pll_reg_3, pll_reg_57, m2div_frac, m2div_int; 16962435a11dSSuraj Kandpal u64 temp0, temp1; 16972435a11dSSuraj Kandpal /* 16982435a11dSSuraj Kandpal * The algorithm uses '+' to combine bitfields when 16992435a11dSSuraj Kandpal * constructing PLL_reg3 and PLL_reg57: 17002435a11dSSuraj Kandpal * PLL_reg57 = (D7 << 24) + (postdiv << 15) + (D8 << 7) + D6_new; 17012435a11dSSuraj Kandpal * PLL_reg3 = (D4 << 21) + (D3 << 18) + (D1 << 15) + (m2div_int << 5); 17022435a11dSSuraj Kandpal * 17032435a11dSSuraj Kandpal * However, this is likely intended to be a bitwise OR operation, 17042435a11dSSuraj Kandpal * as each field occupies distinct, non-overlapping bits in the register. 17052435a11dSSuraj Kandpal * 17062435a11dSSuraj Kandpal * PLL_reg57 is composed of following fields packed into a 32-bit value: 17072435a11dSSuraj Kandpal * - D7: max value 10 -> fits in 4 bits -> placed at bits 24-27 17082435a11dSSuraj Kandpal * - postdiv: max value 9 -> fits in 4 bits -> placed at bits 15-18 17092435a11dSSuraj Kandpal * - D8: derived from loop_cnt / 2, max 127 -> fits in 7 bits 17102435a11dSSuraj Kandpal * (though 8 bits are given to it) -> placed at bits 7-14 17112435a11dSSuraj Kandpal * - D6_new: fits in lower 7 bits -> placed at bits 0-6 17122435a11dSSuraj Kandpal * PLL_reg57 = (D7 << 24) | (postdiv << 15) | (D8 << 7) | D6_new; 17132435a11dSSuraj Kandpal * 17142435a11dSSuraj Kandpal * Similarly, PLL_reg3 is packed as: 17152435a11dSSuraj Kandpal * - D4: max value 256 -> fits in 9 bits -> placed at bits 21-29 17162435a11dSSuraj Kandpal * - D3: max value 9 -> fits in 4 bits -> placed at bits 18-21 17172435a11dSSuraj Kandpal * - D1: max value 2 -> fits in 2 bits -> placed at bits 15-16 17182435a11dSSuraj Kandpal * - m2div_int: max value 511 -> fits in 9 bits (10 bits allocated) 17192435a11dSSuraj Kandpal * -> placed at bits 5-14 17202435a11dSSuraj Kandpal * PLL_reg3 = (D4 << 21) | (D3 << 18) | (D1 << 15) | (m2div_int << 5); 17212435a11dSSuraj Kandpal */ 17222435a11dSSuraj Kandpal pll_reg_5 = REGVAL(2); 17232435a11dSSuraj Kandpal pll_reg_3 = REGVAL(1); 17242435a11dSSuraj Kandpal pll_reg_57 = REGVAL(3); 17252435a11dSSuraj Kandpal m2div_frac = pll_reg_5; 17262435a11dSSuraj Kandpal 17272435a11dSSuraj Kandpal /* 17282435a11dSSuraj Kandpal * From forward algorithm we know 17292435a11dSSuraj Kandpal * m2div = 2 * m2 17302435a11dSSuraj Kandpal * val = y * frequency * 5 17312435a11dSSuraj Kandpal * So now, 17322435a11dSSuraj Kandpal * frequency = (m2 * 2 * refclk_khz / (d8 * 10)) 17332435a11dSSuraj Kandpal * frequency = (m2div * refclk_khz / (d8 * 10)) 17342435a11dSSuraj Kandpal */ 17352435a11dSSuraj Kandpal d8 = (pll_reg_57 & REG_GENMASK(14, 7)) >> 7; 1736fa4aa0b2SSuraj Kandpal if (d8 == 0) { 1737fa4aa0b2SSuraj Kandpal drm_WARN_ON(display->drm, 1738fa4aa0b2SSuraj Kandpal "Invalid port clock using lowest HDMI portclock\n"); 1739fa4aa0b2SSuraj Kandpal return xe3plpd_lt_hdmi_252.clock; 1740fa4aa0b2SSuraj Kandpal } 17412435a11dSSuraj Kandpal m2div_int = (pll_reg_3 & REG_GENMASK(14, 5)) >> 5; 17422435a11dSSuraj Kandpal temp0 = ((u64)m2div_frac * REF_CLK_KHZ) >> 32; 17432435a11dSSuraj Kandpal temp1 = (u64)m2div_int * REF_CLK_KHZ; 17442435a11dSSuraj Kandpal 17452435a11dSSuraj Kandpal clk = div_u64((temp1 + temp0), d8 * 10); 17462435a11dSSuraj Kandpal 17472435a11dSSuraj Kandpal return clk; 17482435a11dSSuraj Kandpal } 17492435a11dSSuraj Kandpal 17502435a11dSSuraj Kandpal int 17512435a11dSSuraj Kandpal intel_lt_phy_calc_port_clock(struct intel_encoder *encoder, 17522435a11dSSuraj Kandpal const struct intel_crtc_state *crtc_state) 17532435a11dSSuraj Kandpal { 17542435a11dSSuraj Kandpal int clk; 17552435a11dSSuraj Kandpal const struct intel_lt_phy_pll_state *lt_state = 17562435a11dSSuraj Kandpal &crtc_state->dpll_hw_state.ltpll; 17572435a11dSSuraj Kandpal u8 mode, rate; 17582435a11dSSuraj Kandpal 17592435a11dSSuraj Kandpal mode = REG_FIELD_GET8(LT_PHY_VDR_MODE_ENCODING_MASK, 17602435a11dSSuraj Kandpal lt_state->config[0]); 17612435a11dSSuraj Kandpal /* 17622435a11dSSuraj Kandpal * For edp/dp read the clock value from the tables 17632435a11dSSuraj Kandpal * and return the clock as the algorithm used for 17642435a11dSSuraj Kandpal * calculating the port clock does not exactly matches 17652435a11dSSuraj Kandpal * with edp/dp clock. 17662435a11dSSuraj Kandpal */ 17672435a11dSSuraj Kandpal if (mode == MODE_DP) { 17682435a11dSSuraj Kandpal rate = REG_FIELD_GET8(LT_PHY_VDR_RATE_ENCODING_MASK, 17692435a11dSSuraj Kandpal lt_state->config[0]); 17702435a11dSSuraj Kandpal clk = intel_lt_phy_get_dp_clock(rate); 17712435a11dSSuraj Kandpal } else { 1772fa4aa0b2SSuraj Kandpal clk = intel_lt_phy_calc_hdmi_port_clock(crtc_state); 17732435a11dSSuraj Kandpal } 17742435a11dSSuraj Kandpal 17752435a11dSSuraj Kandpal return clk; 17762435a11dSSuraj Kandpal } 17772435a11dSSuraj Kandpal 1778dc5742b6SSuraj Kandpal int 1779dc5742b6SSuraj Kandpal intel_lt_phy_pll_calc_state(struct intel_crtc_state *crtc_state, 1780dc5742b6SSuraj Kandpal struct intel_encoder *encoder) 1781dc5742b6SSuraj Kandpal { 1782dc5742b6SSuraj Kandpal const struct intel_lt_phy_pll_state * const *tables; 1783dc5742b6SSuraj Kandpal int i; 1784dc5742b6SSuraj Kandpal 1785dc5742b6SSuraj Kandpal tables = intel_lt_phy_pll_tables_get(crtc_state, encoder); 1786dc5742b6SSuraj Kandpal if (!tables) 1787dc5742b6SSuraj Kandpal return -EINVAL; 1788dc5742b6SSuraj Kandpal 1789dc5742b6SSuraj Kandpal for (i = 0; tables[i]; i++) { 1790dc5742b6SSuraj Kandpal if (crtc_state->port_clock == tables[i]->clock) { 1791dc5742b6SSuraj Kandpal crtc_state->dpll_hw_state.ltpll = *tables[i]; 17924f1118bfSSuraj Kandpal if (intel_crtc_has_dp_encoder(crtc_state)) { 17934f1118bfSSuraj Kandpal if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_EDP)) 17944f1118bfSSuraj Kandpal crtc_state->dpll_hw_state.ltpll.config[2] = 1; 17954f1118bfSSuraj Kandpal } 17963383ba24SSuraj Kandpal crtc_state->dpll_hw_state.ltpll.ssc_enabled = 17973383ba24SSuraj Kandpal intel_lt_phy_pll_is_ssc_enabled(crtc_state, encoder); 1798dc5742b6SSuraj Kandpal return 0; 1799dc5742b6SSuraj Kandpal } 1800dc5742b6SSuraj Kandpal } 1801dc5742b6SSuraj Kandpal 18026fedb7bfSSuraj Kandpal if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI)) { 18036fedb7bfSSuraj Kandpal return intel_lt_phy_calculate_hdmi_state(&crtc_state->dpll_hw_state.ltpll, 18046fedb7bfSSuraj Kandpal crtc_state->port_clock); 18056fedb7bfSSuraj Kandpal } 1806dc5742b6SSuraj Kandpal 1807dc5742b6SSuraj Kandpal return -EINVAL; 1808dc5742b6SSuraj Kandpal } 1809dc5742b6SSuraj Kandpal 18101dd885d5SSuraj Kandpal static void 18111dd885d5SSuraj Kandpal intel_lt_phy_program_pll(struct intel_encoder *encoder, 18121dd885d5SSuraj Kandpal const struct intel_crtc_state *crtc_state) 18131dd885d5SSuraj Kandpal { 18141dd885d5SSuraj Kandpal u8 owned_lane_mask = intel_lt_phy_get_owned_lane_mask(encoder); 18151dd885d5SSuraj Kandpal int i, j, k; 18161dd885d5SSuraj Kandpal 18171dd885d5SSuraj Kandpal intel_lt_phy_write(encoder, owned_lane_mask, LT_PHY_VDR_0_CONFIG, 18181dd885d5SSuraj Kandpal crtc_state->dpll_hw_state.ltpll.config[0], MB_WRITE_COMMITTED); 18191dd885d5SSuraj Kandpal intel_lt_phy_write(encoder, INTEL_LT_PHY_LANE0, LT_PHY_VDR_1_CONFIG, 18201dd885d5SSuraj Kandpal crtc_state->dpll_hw_state.ltpll.config[1], MB_WRITE_COMMITTED); 18211dd885d5SSuraj Kandpal intel_lt_phy_write(encoder, owned_lane_mask, LT_PHY_VDR_2_CONFIG, 18221dd885d5SSuraj Kandpal crtc_state->dpll_hw_state.ltpll.config[2], MB_WRITE_COMMITTED); 18231dd885d5SSuraj Kandpal 18241dd885d5SSuraj Kandpal for (i = 0; i <= 12; i++) { 18251dd885d5SSuraj Kandpal intel_lt_phy_write(encoder, INTEL_LT_PHY_LANE0, LT_PHY_VDR_X_ADDR_MSB(i), 18261dd885d5SSuraj Kandpal crtc_state->dpll_hw_state.ltpll.addr_msb[i], 18271dd885d5SSuraj Kandpal MB_WRITE_COMMITTED); 18281dd885d5SSuraj Kandpal intel_lt_phy_write(encoder, INTEL_LT_PHY_LANE0, LT_PHY_VDR_X_ADDR_LSB(i), 18291dd885d5SSuraj Kandpal crtc_state->dpll_hw_state.ltpll.addr_lsb[i], 18301dd885d5SSuraj Kandpal MB_WRITE_COMMITTED); 18311dd885d5SSuraj Kandpal 18321dd885d5SSuraj Kandpal for (j = 3, k = 0; j >= 0; j--, k++) 18331dd885d5SSuraj Kandpal intel_lt_phy_write(encoder, INTEL_LT_PHY_LANE0, 18341dd885d5SSuraj Kandpal LT_PHY_VDR_X_DATAY(i, j), 18351dd885d5SSuraj Kandpal crtc_state->dpll_hw_state.ltpll.data[i][k], 18361dd885d5SSuraj Kandpal MB_WRITE_COMMITTED); 18371dd885d5SSuraj Kandpal } 18381dd885d5SSuraj Kandpal } 18391dd885d5SSuraj Kandpal 1840a54bdcb7SSuraj Kandpal static void 1841a54bdcb7SSuraj Kandpal intel_lt_phy_enable_disable_tx(struct intel_encoder *encoder, 1842a54bdcb7SSuraj Kandpal const struct intel_crtc_state *crtc_state) 1843a54bdcb7SSuraj Kandpal { 1844a54bdcb7SSuraj Kandpal struct intel_digital_port *dig_port = enc_to_dig_port(encoder); 1845a54bdcb7SSuraj Kandpal bool lane_reversal = dig_port->lane_reversal; 1846a54bdcb7SSuraj Kandpal u8 lane_count = crtc_state->lane_count; 1847a54bdcb7SSuraj Kandpal bool is_dp_alt = 1848a54bdcb7SSuraj Kandpal intel_tc_port_in_dp_alt_mode(dig_port); 1849a54bdcb7SSuraj Kandpal enum intel_tc_pin_assignment tc_pin = 1850a54bdcb7SSuraj Kandpal intel_tc_port_get_pin_assignment(dig_port); 1851a54bdcb7SSuraj Kandpal u8 transmitter_mask = 0; 1852a54bdcb7SSuraj Kandpal 1853a54bdcb7SSuraj Kandpal /* 1854a54bdcb7SSuraj Kandpal * We have a two transmitters per lane and total of 2 PHY lanes so a total 1855a54bdcb7SSuraj Kandpal * of 4 transmitters. We prepare a mask of the lanes that need to be activated 1856a54bdcb7SSuraj Kandpal * and the transmitter which need to be activated for each lane. TX 0,1 correspond 1857a54bdcb7SSuraj Kandpal * to LANE0 and TX 2, 3 correspond to LANE1. 1858a54bdcb7SSuraj Kandpal */ 1859a54bdcb7SSuraj Kandpal 1860a54bdcb7SSuraj Kandpal switch (lane_count) { 1861a54bdcb7SSuraj Kandpal case 1: 1862a54bdcb7SSuraj Kandpal transmitter_mask = lane_reversal ? REG_BIT8(3) : REG_BIT8(0); 1863a54bdcb7SSuraj Kandpal if (is_dp_alt) { 1864a54bdcb7SSuraj Kandpal if (tc_pin == INTEL_TC_PIN_ASSIGNMENT_D) 1865a54bdcb7SSuraj Kandpal transmitter_mask = REG_BIT8(0); 1866a54bdcb7SSuraj Kandpal else 1867a54bdcb7SSuraj Kandpal transmitter_mask = REG_BIT8(1); 1868a54bdcb7SSuraj Kandpal } 1869a54bdcb7SSuraj Kandpal break; 1870a54bdcb7SSuraj Kandpal case 2: 1871a54bdcb7SSuraj Kandpal transmitter_mask = lane_reversal ? REG_GENMASK8(3, 2) : REG_GENMASK8(1, 0); 1872a54bdcb7SSuraj Kandpal if (is_dp_alt) 1873a54bdcb7SSuraj Kandpal transmitter_mask = REG_GENMASK8(1, 0); 1874a54bdcb7SSuraj Kandpal break; 1875a54bdcb7SSuraj Kandpal case 3: 1876a54bdcb7SSuraj Kandpal transmitter_mask = lane_reversal ? REG_GENMASK8(3, 1) : REG_GENMASK8(2, 0); 1877a54bdcb7SSuraj Kandpal if (is_dp_alt) 1878a54bdcb7SSuraj Kandpal transmitter_mask = REG_GENMASK8(2, 0); 1879a54bdcb7SSuraj Kandpal break; 1880a54bdcb7SSuraj Kandpal case 4: 1881a54bdcb7SSuraj Kandpal transmitter_mask = REG_GENMASK8(3, 0); 1882a54bdcb7SSuraj Kandpal break; 1883a54bdcb7SSuraj Kandpal default: 1884a54bdcb7SSuraj Kandpal MISSING_CASE(lane_count); 1885a54bdcb7SSuraj Kandpal transmitter_mask = REG_GENMASK8(3, 0); 1886a54bdcb7SSuraj Kandpal break; 1887a54bdcb7SSuraj Kandpal } 1888a54bdcb7SSuraj Kandpal 1889a54bdcb7SSuraj Kandpal if (transmitter_mask & BIT(0)) { 1890a54bdcb7SSuraj Kandpal intel_lt_phy_p2p_write(encoder, INTEL_LT_PHY_LANE0, LT_PHY_TXY_CTL10(0), 1891a54bdcb7SSuraj Kandpal LT_PHY_TX_LANE_ENABLE, LT_PHY_TXY_CTL10_MAC(0), 1892a54bdcb7SSuraj Kandpal LT_PHY_TX_LANE_ENABLE); 1893a54bdcb7SSuraj Kandpal } else { 1894a54bdcb7SSuraj Kandpal intel_lt_phy_p2p_write(encoder, INTEL_LT_PHY_LANE0, LT_PHY_TXY_CTL10(0), 1895a54bdcb7SSuraj Kandpal 0, LT_PHY_TXY_CTL10_MAC(0), 0); 1896a54bdcb7SSuraj Kandpal } 1897a54bdcb7SSuraj Kandpal 1898a54bdcb7SSuraj Kandpal if (transmitter_mask & BIT(1)) { 1899a54bdcb7SSuraj Kandpal intel_lt_phy_p2p_write(encoder, INTEL_LT_PHY_LANE0, LT_PHY_TXY_CTL10(1), 1900a54bdcb7SSuraj Kandpal LT_PHY_TX_LANE_ENABLE, LT_PHY_TXY_CTL10_MAC(1), 1901a54bdcb7SSuraj Kandpal LT_PHY_TX_LANE_ENABLE); 1902a54bdcb7SSuraj Kandpal } else { 1903a54bdcb7SSuraj Kandpal intel_lt_phy_p2p_write(encoder, INTEL_LT_PHY_LANE0, LT_PHY_TXY_CTL10(1), 1904a54bdcb7SSuraj Kandpal 0, LT_PHY_TXY_CTL10_MAC(1), 0); 1905a54bdcb7SSuraj Kandpal } 1906a54bdcb7SSuraj Kandpal 1907a54bdcb7SSuraj Kandpal if (transmitter_mask & BIT(2)) { 1908a54bdcb7SSuraj Kandpal intel_lt_phy_p2p_write(encoder, INTEL_LT_PHY_LANE1, LT_PHY_TXY_CTL10(0), 1909a54bdcb7SSuraj Kandpal LT_PHY_TX_LANE_ENABLE, LT_PHY_TXY_CTL10_MAC(0), 1910a54bdcb7SSuraj Kandpal LT_PHY_TX_LANE_ENABLE); 1911a54bdcb7SSuraj Kandpal } else { 1912a54bdcb7SSuraj Kandpal intel_lt_phy_p2p_write(encoder, INTEL_LT_PHY_LANE1, LT_PHY_TXY_CTL10(0), 1913a54bdcb7SSuraj Kandpal 0, LT_PHY_TXY_CTL10_MAC(0), 0); 1914a54bdcb7SSuraj Kandpal } 1915a54bdcb7SSuraj Kandpal 1916a54bdcb7SSuraj Kandpal if (transmitter_mask & BIT(3)) { 1917a54bdcb7SSuraj Kandpal intel_lt_phy_p2p_write(encoder, INTEL_LT_PHY_LANE1, LT_PHY_TXY_CTL10(1), 1918a54bdcb7SSuraj Kandpal LT_PHY_TX_LANE_ENABLE, LT_PHY_TXY_CTL10_MAC(1), 1919a54bdcb7SSuraj Kandpal LT_PHY_TX_LANE_ENABLE); 1920a54bdcb7SSuraj Kandpal } else { 1921a54bdcb7SSuraj Kandpal intel_lt_phy_p2p_write(encoder, INTEL_LT_PHY_LANE1, LT_PHY_TXY_CTL10(1), 1922a54bdcb7SSuraj Kandpal 0, LT_PHY_TXY_CTL10_MAC(1), 0); 1923a54bdcb7SSuraj Kandpal } 1924a54bdcb7SSuraj Kandpal } 1925a54bdcb7SSuraj Kandpal 1926154ebdb7SSuraj Kandpal void intel_lt_phy_pll_enable(struct intel_encoder *encoder, 1927154ebdb7SSuraj Kandpal const struct intel_crtc_state *crtc_state) 1928154ebdb7SSuraj Kandpal { 1929e1455196SSuraj Kandpal struct intel_display *display = to_intel_display(encoder); 19303a323c7eSSuraj Kandpal struct intel_digital_port *dig_port = enc_to_dig_port(encoder); 19313a323c7eSSuraj Kandpal bool lane_reversal = dig_port->lane_reversal; 1932fc9be0a1SSuraj Kandpal u8 owned_lane_mask = intel_lt_phy_get_owned_lane_mask(encoder); 193382b46083SSuraj Kandpal enum phy phy = intel_encoder_to_phy(encoder); 193482b46083SSuraj Kandpal enum port port = encoder->port; 1935e1455196SSuraj Kandpal intel_wakeref_t wakeref = 0; 193632865c2dSSuraj Kandpal u32 lane_phy_pulse_status = owned_lane_mask == INTEL_LT_PHY_BOTH_LANES 193732865c2dSSuraj Kandpal ? (XE3PLPDP_LANE_PHY_PULSE_STATUS(0) | 193832865c2dSSuraj Kandpal XE3PLPDP_LANE_PHY_PULSE_STATUS(1)) 193932865c2dSSuraj Kandpal : XE3PLPDP_LANE_PHY_PULSE_STATUS(0); 194032865c2dSSuraj Kandpal u8 rate_update; 1941e1455196SSuraj Kandpal 1942e1455196SSuraj Kandpal wakeref = intel_lt_phy_transaction_begin(encoder); 19433a323c7eSSuraj Kandpal 1944154ebdb7SSuraj Kandpal /* 1. Enable MacCLK at default 162 MHz frequency. */ 1945154ebdb7SSuraj Kandpal intel_lt_phy_lane_reset(encoder, crtc_state->lane_count); 1946154ebdb7SSuraj Kandpal 1947154ebdb7SSuraj Kandpal /* 2. Program PORT_CLOCK_CTL register to configure clock muxes, gating, and SSC. */ 19483a323c7eSSuraj Kandpal intel_lt_phy_program_port_clock_ctl(encoder, crtc_state, lane_reversal); 19493a323c7eSSuraj Kandpal 1950154ebdb7SSuraj Kandpal /* 3. Change owned PHY lanes power to Ready state. */ 1951fc9be0a1SSuraj Kandpal intel_lt_phy_powerdown_change_sequence(encoder, owned_lane_mask, 1952fc9be0a1SSuraj Kandpal XELPDP_P2_STATE_READY); 1953fc9be0a1SSuraj Kandpal 1954154ebdb7SSuraj Kandpal /* 1955154ebdb7SSuraj Kandpal * 4. Read the PHY message bus VDR register PHY_VDR_0_Config check enabled PLL type, 1956154ebdb7SSuraj Kandpal * encoded rate and encoded mode. 1957154ebdb7SSuraj Kandpal */ 1958e1455196SSuraj Kandpal if (intel_lt_phy_config_changed(encoder, crtc_state)) { 1959154ebdb7SSuraj Kandpal /* 1960154ebdb7SSuraj Kandpal * 5. Program the PHY internal PLL registers over PHY message bus for the desired 1961154ebdb7SSuraj Kandpal * frequency and protocol type 1962154ebdb7SSuraj Kandpal */ 19631dd885d5SSuraj Kandpal intel_lt_phy_program_pll(encoder, crtc_state); 19641dd885d5SSuraj Kandpal 1965154ebdb7SSuraj Kandpal /* 6. Use the P2P transaction flow */ 1966154ebdb7SSuraj Kandpal /* 1967154ebdb7SSuraj Kandpal * 6.1. Set the PHY VDR register 0xCC4[Rate Control VDR Update] = 1 over PHY message 1968154ebdb7SSuraj Kandpal * bus for Owned PHY Lanes. 1969154ebdb7SSuraj Kandpal */ 1970154ebdb7SSuraj Kandpal /* 1971e1455196SSuraj Kandpal * 6.2. Poll for P2P Transaction Ready = "1" and read the MAC message bus VDR 1972e1455196SSuraj Kandpal * register at offset 0xC00 for Owned PHY Lanes*. 1973154ebdb7SSuraj Kandpal */ 1974154ebdb7SSuraj Kandpal /* 6.3. Clear P2P transaction Ready bit. */ 197541d07bd2SSuraj Kandpal intel_lt_phy_p2p_write(encoder, owned_lane_mask, LT_PHY_RATE_UPDATE, 197641d07bd2SSuraj Kandpal LT_PHY_RATE_CONTROL_VDR_UPDATE, LT_PHY_MAC_VDR, 197741d07bd2SSuraj Kandpal LT_PHY_PCLKIN_GATE); 197841d07bd2SSuraj Kandpal 1979154ebdb7SSuraj Kandpal /* 7. Program PORT_CLOCK_CTL[PCLK PLL Request LN0] = 0. */ 198082b46083SSuraj Kandpal intel_de_rmw(display, XELPDP_PORT_CLOCK_CTL(display, port), 198182b46083SSuraj Kandpal XELPDP_LANE_PCLK_PLL_REQUEST(0), 0); 198282b46083SSuraj Kandpal 1983154ebdb7SSuraj Kandpal /* 8. Poll for PORT_CLOCK_CTL[PCLK PLL Ack LN0]= 0. */ 19840aed9d34SVille Syrjälä if (intel_de_wait_for_clear_us(display, XELPDP_PORT_CLOCK_CTL(display, port), 19850aed9d34SVille Syrjälä XELPDP_LANE_PCLK_PLL_ACK(0), 19860aed9d34SVille Syrjälä XE3PLPD_MACCLK_TURNOFF_LATENCY_US)) 1987dfd58249SVille Syrjälä drm_warn(display->drm, "PHY %c PLL MacCLK ack deassertion timeout\n", 1988dfd58249SVille Syrjälä phy_name(phy)); 198982b46083SSuraj Kandpal 1990154ebdb7SSuraj Kandpal /* 1991e1455196SSuraj Kandpal * 9. Follow the Display Voltage Frequency Switching - Sequence Before Frequency 1992e1455196SSuraj Kandpal * Change. We handle this step in bxt_set_cdclk(). 1993154ebdb7SSuraj Kandpal */ 1994154ebdb7SSuraj Kandpal /* 10. Program DDI_CLK_VALFREQ to match intended DDI clock frequency. */ 199532865c2dSSuraj Kandpal intel_de_write(display, DDI_CLK_VALFREQ(encoder->port), 199632865c2dSSuraj Kandpal crtc_state->port_clock); 199732865c2dSSuraj Kandpal 1998154ebdb7SSuraj Kandpal /* 11. Program PORT_CLOCK_CTL[PCLK PLL Request LN0] = 1. */ 199982b46083SSuraj Kandpal intel_de_rmw(display, XELPDP_PORT_CLOCK_CTL(display, port), 200082b46083SSuraj Kandpal XELPDP_LANE_PCLK_PLL_REQUEST(0), 200182b46083SSuraj Kandpal XELPDP_LANE_PCLK_PLL_REQUEST(0)); 200282b46083SSuraj Kandpal 2003154ebdb7SSuraj Kandpal /* 12. Poll for PORT_CLOCK_CTL[PCLK PLL Ack LN0]= 1. */ 20046be05d5bSVille Syrjälä if (intel_de_wait_for_set_ms(display, XELPDP_PORT_CLOCK_CTL(display, port), 20056be05d5bSVille Syrjälä XELPDP_LANE_PCLK_PLL_ACK(0), 20066be05d5bSVille Syrjälä XE3PLPD_MACCLK_TURNON_LATENCY_MS)) 2007dfd58249SVille Syrjälä drm_warn(display->drm, "PHY %c PLL MacCLK ack assertion timeout\n", 2008dfd58249SVille Syrjälä phy_name(phy)); 2009e1455196SSuraj Kandpal 2010ad7108f9SSuraj Kandpal /* 2011ad7108f9SSuraj Kandpal * 13. Ungate the forward clock by setting 2012ad7108f9SSuraj Kandpal * PORT_CLOCK_CTL[Forward Clock Ungate] = 1. 2013ad7108f9SSuraj Kandpal */ 201482b46083SSuraj Kandpal intel_de_rmw(display, XELPDP_PORT_CLOCK_CTL(display, port), 201582b46083SSuraj Kandpal XELPDP_FORWARD_CLOCK_UNGATE, 201682b46083SSuraj Kandpal XELPDP_FORWARD_CLOCK_UNGATE); 201782b46083SSuraj Kandpal 2018154ebdb7SSuraj Kandpal /* 14. SW clears PORT_BUF_CTL2 [PHY Pulse Status]. */ 201932865c2dSSuraj Kandpal intel_de_rmw(display, XELPDP_PORT_BUF_CTL2(display, port), 202032865c2dSSuraj Kandpal lane_phy_pulse_status, 202132865c2dSSuraj Kandpal lane_phy_pulse_status); 2022154ebdb7SSuraj Kandpal /* 2023ad7108f9SSuraj Kandpal * 15. Clear the PHY VDR register 0xCC4[Rate Control VDR Update] over 2024ad7108f9SSuraj Kandpal * PHY message bus for Owned PHY Lanes. 2025154ebdb7SSuraj Kandpal */ 202632865c2dSSuraj Kandpal rate_update = intel_lt_phy_read(encoder, INTEL_LT_PHY_LANE0, LT_PHY_RATE_UPDATE); 202732865c2dSSuraj Kandpal rate_update &= ~LT_PHY_RATE_CONTROL_VDR_UPDATE; 202832865c2dSSuraj Kandpal intel_lt_phy_write(encoder, owned_lane_mask, LT_PHY_RATE_UPDATE, 202932865c2dSSuraj Kandpal rate_update, MB_WRITE_COMMITTED); 203032865c2dSSuraj Kandpal 2031154ebdb7SSuraj Kandpal /* 16. Poll for PORT_BUF_CTL2 register PHY Pulse Status = 1 for Owned PHY Lanes. */ 20326be05d5bSVille Syrjälä if (intel_de_wait_for_set_ms(display, XELPDP_PORT_BUF_CTL2(display, port), 20336be05d5bSVille Syrjälä lane_phy_pulse_status, 20346be05d5bSVille Syrjälä XE3PLPD_RATE_CALIB_DONE_LATENCY_MS)) 2035dfd58249SVille Syrjälä drm_warn(display->drm, "PHY %c PLL rate not changed\n", 2036dfd58249SVille Syrjälä phy_name(phy)); 203732865c2dSSuraj Kandpal 2038154ebdb7SSuraj Kandpal /* 17. SW clears PORT_BUF_CTL2 [PHY Pulse Status]. */ 203932865c2dSSuraj Kandpal intel_de_rmw(display, XELPDP_PORT_BUF_CTL2(display, port), 204032865c2dSSuraj Kandpal lane_phy_pulse_status, 204132865c2dSSuraj Kandpal lane_phy_pulse_status); 2042ad7108f9SSuraj Kandpal } else { 2043ad7108f9SSuraj Kandpal intel_de_write(display, DDI_CLK_VALFREQ(encoder->port), crtc_state->port_clock); 2044ad7108f9SSuraj Kandpal } 204532865c2dSSuraj Kandpal 2046154ebdb7SSuraj Kandpal /* 2047154ebdb7SSuraj Kandpal * 18. Follow the Display Voltage Frequency Switching - Sequence After Frequency Change. 2048154ebdb7SSuraj Kandpal * We handle this step in bxt_set_cdclk() 2049154ebdb7SSuraj Kandpal */ 2050154ebdb7SSuraj Kandpal /* 19. Move the PHY powerdown state to Active and program to enable/disable transmitters */ 205132865c2dSSuraj Kandpal intel_lt_phy_powerdown_change_sequence(encoder, owned_lane_mask, 205232865c2dSSuraj Kandpal XELPDP_P0_STATE_ACTIVE); 2053e1455196SSuraj Kandpal 2054a54bdcb7SSuraj Kandpal intel_lt_phy_enable_disable_tx(encoder, crtc_state); 2055e1455196SSuraj Kandpal intel_lt_phy_transaction_end(encoder, wakeref); 2056154ebdb7SSuraj Kandpal } 2057fa5fd596SSuraj Kandpal 2058fa5fd596SSuraj Kandpal void intel_lt_phy_pll_disable(struct intel_encoder *encoder) 2059fa5fd596SSuraj Kandpal { 2060fa5fd596SSuraj Kandpal struct intel_display *display = to_intel_display(encoder); 2061fa5fd596SSuraj Kandpal enum phy phy = intel_encoder_to_phy(encoder); 2062fa5fd596SSuraj Kandpal enum port port = encoder->port; 2063fa5fd596SSuraj Kandpal intel_wakeref_t wakeref; 2064fa5fd596SSuraj Kandpal u8 owned_lane_mask = intel_lt_phy_get_owned_lane_mask(encoder); 2065fa5fd596SSuraj Kandpal u32 lane_pipe_reset = owned_lane_mask == INTEL_LT_PHY_BOTH_LANES 2066fa5fd596SSuraj Kandpal ? (XELPDP_LANE_PIPE_RESET(0) | 2067fa5fd596SSuraj Kandpal XELPDP_LANE_PIPE_RESET(1)) 2068fa5fd596SSuraj Kandpal : XELPDP_LANE_PIPE_RESET(0); 2069fa5fd596SSuraj Kandpal u32 lane_phy_current_status = owned_lane_mask == INTEL_LT_PHY_BOTH_LANES 2070fa5fd596SSuraj Kandpal ? (XELPDP_LANE_PHY_CURRENT_STATUS(0) | 2071fa5fd596SSuraj Kandpal XELPDP_LANE_PHY_CURRENT_STATUS(1)) 2072fa5fd596SSuraj Kandpal : XELPDP_LANE_PHY_CURRENT_STATUS(0); 2073fa5fd596SSuraj Kandpal u32 lane_phy_pulse_status = owned_lane_mask == INTEL_LT_PHY_BOTH_LANES 2074fa5fd596SSuraj Kandpal ? (XE3PLPDP_LANE_PHY_PULSE_STATUS(0) | 2075fa5fd596SSuraj Kandpal XE3PLPDP_LANE_PHY_PULSE_STATUS(1)) 2076fa5fd596SSuraj Kandpal : XE3PLPDP_LANE_PHY_PULSE_STATUS(0); 2077fa5fd596SSuraj Kandpal 2078fa5fd596SSuraj Kandpal wakeref = intel_lt_phy_transaction_begin(encoder); 2079fa5fd596SSuraj Kandpal 2080fa5fd596SSuraj Kandpal /* 1. Clear PORT_BUF_CTL2 [PHY Pulse Status]. */ 2081fa5fd596SSuraj Kandpal intel_de_rmw(display, XELPDP_PORT_BUF_CTL2(display, port), 2082fa5fd596SSuraj Kandpal lane_phy_pulse_status, 2083fa5fd596SSuraj Kandpal lane_phy_pulse_status); 2084fa5fd596SSuraj Kandpal 2085fa5fd596SSuraj Kandpal /* 2. Set PORT_BUF_CTL2<port> Lane<PHY Lanes Owned> Pipe Reset to 1. */ 2086fa5fd596SSuraj Kandpal intel_de_rmw(display, XELPDP_PORT_BUF_CTL2(display, port), lane_pipe_reset, 2087fa5fd596SSuraj Kandpal lane_pipe_reset); 2088fa5fd596SSuraj Kandpal 2089fa5fd596SSuraj Kandpal /* 3. Poll for PORT_BUF_CTL2<port> Lane<PHY Lanes Owned> PHY Current Status == 1. */ 20900aed9d34SVille Syrjälä if (intel_de_wait_for_set_us(display, XELPDP_PORT_BUF_CTL2(display, port), 20910aed9d34SVille Syrjälä lane_phy_current_status, 20920aed9d34SVille Syrjälä XE3PLPD_RESET_START_LATENCY_US)) 2093dfd58249SVille Syrjälä drm_warn(display->drm, "PHY %c failed to reset lane\n", 2094dfd58249SVille Syrjälä phy_name(phy)); 2095fa5fd596SSuraj Kandpal 2096fa5fd596SSuraj Kandpal /* 4. Clear for PHY pulse status on owned PHY lanes. */ 2097fa5fd596SSuraj Kandpal intel_de_rmw(display, XELPDP_PORT_BUF_CTL2(display, port), 2098fa5fd596SSuraj Kandpal lane_phy_pulse_status, 2099fa5fd596SSuraj Kandpal lane_phy_pulse_status); 2100fa5fd596SSuraj Kandpal 2101fa5fd596SSuraj Kandpal /* 2102fa5fd596SSuraj Kandpal * 5. Follow the Display Voltage Frequency Switching - 2103fa5fd596SSuraj Kandpal * Sequence Before Frequency Change. We handle this step in bxt_set_cdclk(). 2104fa5fd596SSuraj Kandpal */ 2105fa5fd596SSuraj Kandpal /* 6. Program PORT_CLOCK_CTL[PCLK PLL Request LN0] = 0. */ 2106fa5fd596SSuraj Kandpal intel_de_rmw(display, XELPDP_PORT_CLOCK_CTL(display, port), 2107fa5fd596SSuraj Kandpal XELPDP_LANE_PCLK_PLL_REQUEST(0), 0); 2108fa5fd596SSuraj Kandpal 2109fa5fd596SSuraj Kandpal /* 7. Program DDI_CLK_VALFREQ to 0. */ 2110fa5fd596SSuraj Kandpal intel_de_write(display, DDI_CLK_VALFREQ(encoder->port), 0); 2111fa5fd596SSuraj Kandpal 2112fa5fd596SSuraj Kandpal /* 8. Poll for PORT_CLOCK_CTL[PCLK PLL Ack LN0]= 0. */ 21130aed9d34SVille Syrjälä if (intel_de_wait_for_clear_us(display, XELPDP_PORT_CLOCK_CTL(display, port), 21140aed9d34SVille Syrjälä XELPDP_LANE_PCLK_PLL_ACK(0), 21150aed9d34SVille Syrjälä XE3PLPD_MACCLK_TURNOFF_LATENCY_US)) 2116dfd58249SVille Syrjälä drm_warn(display->drm, "PHY %c PLL MacCLK ack deassertion timeout\n", 2117dfd58249SVille Syrjälä phy_name(phy)); 2118fa5fd596SSuraj Kandpal 2119fa5fd596SSuraj Kandpal /* 2120fa5fd596SSuraj Kandpal * 9. Follow the Display Voltage Frequency Switching - 2121fa5fd596SSuraj Kandpal * Sequence After Frequency Change. We handle this step in bxt_set_cdclk(). 2122fa5fd596SSuraj Kandpal */ 2123fa5fd596SSuraj Kandpal /* 10. Program PORT_CLOCK_CTL register to disable and gate clocks. */ 2124fa5fd596SSuraj Kandpal intel_de_rmw(display, XELPDP_PORT_CLOCK_CTL(display, port), 2125fa5fd596SSuraj Kandpal XELPDP_DDI_CLOCK_SELECT_MASK(display) | XELPDP_FORWARD_CLOCK_UNGATE, 0); 2126fa5fd596SSuraj Kandpal 2127fa5fd596SSuraj Kandpal /* 11. Program PORT_BUF_CTL5[MacCLK Reset_0] = 1 to assert MacCLK reset. */ 2128fa5fd596SSuraj Kandpal intel_de_rmw(display, XE3PLPD_PORT_BUF_CTL5(port), 2129fa5fd596SSuraj Kandpal XE3PLPD_MACCLK_RESET_0, XE3PLPD_MACCLK_RESET_0); 2130fa5fd596SSuraj Kandpal 2131fa5fd596SSuraj Kandpal intel_lt_phy_transaction_end(encoder, wakeref); 2132fa5fd596SSuraj Kandpal } 213310928925SSuraj Kandpal 213413ba213fSSuraj Kandpal void intel_lt_phy_set_signal_levels(struct intel_encoder *encoder, 213513ba213fSSuraj Kandpal const struct intel_crtc_state *crtc_state) 213613ba213fSSuraj Kandpal { 213713ba213fSSuraj Kandpal struct intel_display *display = to_intel_display(encoder); 213813ba213fSSuraj Kandpal const struct intel_ddi_buf_trans *trans; 213913ba213fSSuraj Kandpal u8 owned_lane_mask; 214013ba213fSSuraj Kandpal intel_wakeref_t wakeref; 214113ba213fSSuraj Kandpal int n_entries, ln; 214213ba213fSSuraj Kandpal struct intel_digital_port *dig_port = enc_to_dig_port(encoder); 214313ba213fSSuraj Kandpal 214413ba213fSSuraj Kandpal if (intel_tc_port_in_tbt_alt_mode(dig_port)) 214513ba213fSSuraj Kandpal return; 214613ba213fSSuraj Kandpal 214713ba213fSSuraj Kandpal owned_lane_mask = intel_lt_phy_get_owned_lane_mask(encoder); 214813ba213fSSuraj Kandpal 214913ba213fSSuraj Kandpal wakeref = intel_lt_phy_transaction_begin(encoder); 215013ba213fSSuraj Kandpal 215113ba213fSSuraj Kandpal trans = encoder->get_buf_trans(encoder, crtc_state, &n_entries); 215213ba213fSSuraj Kandpal if (drm_WARN_ON_ONCE(display->drm, !trans)) { 215313ba213fSSuraj Kandpal intel_lt_phy_transaction_end(encoder, wakeref); 215413ba213fSSuraj Kandpal return; 215513ba213fSSuraj Kandpal } 215613ba213fSSuraj Kandpal 215713ba213fSSuraj Kandpal for (ln = 0; ln < crtc_state->lane_count; ln++) { 215813ba213fSSuraj Kandpal int level = intel_ddi_level(encoder, crtc_state, ln); 215913ba213fSSuraj Kandpal int lane = ln / 2; 216013ba213fSSuraj Kandpal int tx = ln % 2; 216113ba213fSSuraj Kandpal u8 lane_mask = lane == 0 ? INTEL_LT_PHY_LANE0 : INTEL_LT_PHY_LANE1; 216213ba213fSSuraj Kandpal 216313ba213fSSuraj Kandpal if (!(lane_mask & owned_lane_mask)) 216413ba213fSSuraj Kandpal continue; 216513ba213fSSuraj Kandpal 216613ba213fSSuraj Kandpal intel_lt_phy_rmw(encoder, lane_mask, LT_PHY_TXY_CTL8(tx), 216713ba213fSSuraj Kandpal LT_PHY_TX_SWING_LEVEL_MASK | LT_PHY_TX_SWING_MASK, 216813ba213fSSuraj Kandpal LT_PHY_TX_SWING_LEVEL(trans->entries[level].lt.txswing_level) | 216913ba213fSSuraj Kandpal LT_PHY_TX_SWING(trans->entries[level].lt.txswing), 217013ba213fSSuraj Kandpal MB_WRITE_COMMITTED); 217113ba213fSSuraj Kandpal 217213ba213fSSuraj Kandpal intel_lt_phy_rmw(encoder, lane_mask, LT_PHY_TXY_CTL2(tx), 217313ba213fSSuraj Kandpal LT_PHY_TX_CURSOR_MASK, 217413ba213fSSuraj Kandpal LT_PHY_TX_CURSOR(trans->entries[level].lt.pre_cursor), 217513ba213fSSuraj Kandpal MB_WRITE_COMMITTED); 217613ba213fSSuraj Kandpal intel_lt_phy_rmw(encoder, lane_mask, LT_PHY_TXY_CTL3(tx), 217713ba213fSSuraj Kandpal LT_PHY_TX_CURSOR_MASK, 217813ba213fSSuraj Kandpal LT_PHY_TX_CURSOR(trans->entries[level].lt.main_cursor), 217913ba213fSSuraj Kandpal MB_WRITE_COMMITTED); 218013ba213fSSuraj Kandpal intel_lt_phy_rmw(encoder, lane_mask, LT_PHY_TXY_CTL4(tx), 218113ba213fSSuraj Kandpal LT_PHY_TX_CURSOR_MASK, 218213ba213fSSuraj Kandpal LT_PHY_TX_CURSOR(trans->entries[level].lt.post_cursor), 218313ba213fSSuraj Kandpal MB_WRITE_COMMITTED); 218413ba213fSSuraj Kandpal } 218513ba213fSSuraj Kandpal 218613ba213fSSuraj Kandpal intel_lt_phy_transaction_end(encoder, wakeref); 218713ba213fSSuraj Kandpal } 218813ba213fSSuraj Kandpal 21893a6f155cSSuraj Kandpal void intel_lt_phy_dump_hw_state(struct intel_display *display, 21903a6f155cSSuraj Kandpal const struct intel_lt_phy_pll_state *hw_state) 21913a6f155cSSuraj Kandpal { 21923a6f155cSSuraj Kandpal int i, j; 21933a6f155cSSuraj Kandpal 21943a6f155cSSuraj Kandpal drm_dbg_kms(display->drm, "lt_phy_pll_hw_state:\n"); 21953a6f155cSSuraj Kandpal for (i = 0; i < 3; i++) { 21963a6f155cSSuraj Kandpal drm_dbg_kms(display->drm, "config[%d] = 0x%.4x,\n", 21973a6f155cSSuraj Kandpal i, hw_state->config[i]); 21983a6f155cSSuraj Kandpal } 21993a6f155cSSuraj Kandpal 22003a6f155cSSuraj Kandpal for (i = 0; i <= 12; i++) 22013a6f155cSSuraj Kandpal for (j = 3; j >= 0; j--) 22023a6f155cSSuraj Kandpal drm_dbg_kms(display->drm, "vdr_data[%d][%d] = 0x%.4x,\n", 22033a6f155cSSuraj Kandpal i, j, hw_state->data[i][j]); 22043a6f155cSSuraj Kandpal } 22053a6f155cSSuraj Kandpal 22063a6f155cSSuraj Kandpal bool 22073a6f155cSSuraj Kandpal intel_lt_phy_pll_compare_hw_state(const struct intel_lt_phy_pll_state *a, 22083a6f155cSSuraj Kandpal const struct intel_lt_phy_pll_state *b) 22093a6f155cSSuraj Kandpal { 22103a6f155cSSuraj Kandpal if (memcmp(&a->config, &b->config, sizeof(a->config)) != 0) 22113a6f155cSSuraj Kandpal return false; 22123a6f155cSSuraj Kandpal 22133a6f155cSSuraj Kandpal if (memcmp(&a->data, &b->data, sizeof(a->data)) != 0) 22143a6f155cSSuraj Kandpal return false; 22153a6f155cSSuraj Kandpal 22163a6f155cSSuraj Kandpal return true; 22173a6f155cSSuraj Kandpal } 22183a6f155cSSuraj Kandpal 221989e0a91eSSuraj Kandpal void intel_lt_phy_pll_readout_hw_state(struct intel_encoder *encoder, 222089e0a91eSSuraj Kandpal const struct intel_crtc_state *crtc_state, 222189e0a91eSSuraj Kandpal struct intel_lt_phy_pll_state *pll_state) 222289e0a91eSSuraj Kandpal { 222389e0a91eSSuraj Kandpal u8 owned_lane_mask; 222489e0a91eSSuraj Kandpal u8 lane; 222589e0a91eSSuraj Kandpal intel_wakeref_t wakeref; 222689e0a91eSSuraj Kandpal int i, j, k; 222789e0a91eSSuraj Kandpal 222889e0a91eSSuraj Kandpal pll_state->tbt_mode = intel_tc_port_in_tbt_alt_mode(enc_to_dig_port(encoder)); 222989e0a91eSSuraj Kandpal if (pll_state->tbt_mode) 223089e0a91eSSuraj Kandpal return; 223189e0a91eSSuraj Kandpal 223289e0a91eSSuraj Kandpal owned_lane_mask = intel_lt_phy_get_owned_lane_mask(encoder); 223389e0a91eSSuraj Kandpal lane = owned_lane_mask & INTEL_LT_PHY_LANE0 ? : INTEL_LT_PHY_LANE1; 223489e0a91eSSuraj Kandpal wakeref = intel_lt_phy_transaction_begin(encoder); 223589e0a91eSSuraj Kandpal 223689e0a91eSSuraj Kandpal pll_state->config[0] = intel_lt_phy_read(encoder, lane, LT_PHY_VDR_0_CONFIG); 223789e0a91eSSuraj Kandpal pll_state->config[1] = intel_lt_phy_read(encoder, INTEL_LT_PHY_LANE0, LT_PHY_VDR_1_CONFIG); 223889e0a91eSSuraj Kandpal pll_state->config[2] = intel_lt_phy_read(encoder, lane, LT_PHY_VDR_2_CONFIG); 223989e0a91eSSuraj Kandpal 224089e0a91eSSuraj Kandpal for (i = 0; i <= 12; i++) { 224189e0a91eSSuraj Kandpal for (j = 3, k = 0; j >= 0; j--, k++) 224289e0a91eSSuraj Kandpal pll_state->data[i][k] = 224389e0a91eSSuraj Kandpal intel_lt_phy_read(encoder, INTEL_LT_PHY_LANE0, 224489e0a91eSSuraj Kandpal LT_PHY_VDR_X_DATAY(i, j)); 224589e0a91eSSuraj Kandpal } 224689e0a91eSSuraj Kandpal 224789e0a91eSSuraj Kandpal pll_state->clock = 224889e0a91eSSuraj Kandpal intel_lt_phy_calc_port_clock(encoder, crtc_state); 224989e0a91eSSuraj Kandpal intel_lt_phy_transaction_end(encoder, wakeref); 225089e0a91eSSuraj Kandpal } 225189e0a91eSSuraj Kandpal 22529dcf1836SSuraj Kandpal void intel_lt_phy_pll_state_verify(struct intel_atomic_state *state, 22539dcf1836SSuraj Kandpal struct intel_crtc *crtc) 22549dcf1836SSuraj Kandpal { 22559dcf1836SSuraj Kandpal struct intel_display *display = to_intel_display(state); 22569dcf1836SSuraj Kandpal struct intel_digital_port *dig_port; 22579dcf1836SSuraj Kandpal const struct intel_crtc_state *new_crtc_state = 22589dcf1836SSuraj Kandpal intel_atomic_get_new_crtc_state(state, crtc); 22599dcf1836SSuraj Kandpal struct intel_encoder *encoder; 22609dcf1836SSuraj Kandpal struct intel_lt_phy_pll_state pll_hw_state = {}; 22619dcf1836SSuraj Kandpal const struct intel_lt_phy_pll_state *pll_sw_state = &new_crtc_state->dpll_hw_state.ltpll; 22629dcf1836SSuraj Kandpal int clock; 22639dcf1836SSuraj Kandpal int i, j; 22649dcf1836SSuraj Kandpal 22659dcf1836SSuraj Kandpal if (DISPLAY_VER(display) < 35) 22669dcf1836SSuraj Kandpal return; 22679dcf1836SSuraj Kandpal 22689dcf1836SSuraj Kandpal if (!new_crtc_state->hw.active) 22699dcf1836SSuraj Kandpal return; 22709dcf1836SSuraj Kandpal 22719dcf1836SSuraj Kandpal /* intel_get_crtc_new_encoder() only works for modeset/fastset commits */ 22729dcf1836SSuraj Kandpal if (!intel_crtc_needs_modeset(new_crtc_state) && 22739dcf1836SSuraj Kandpal !intel_crtc_needs_fastset(new_crtc_state)) 22749dcf1836SSuraj Kandpal return; 22759dcf1836SSuraj Kandpal 22769dcf1836SSuraj Kandpal encoder = intel_get_crtc_new_encoder(state, new_crtc_state); 22779dcf1836SSuraj Kandpal intel_lt_phy_pll_readout_hw_state(encoder, new_crtc_state, &pll_hw_state); 22789dcf1836SSuraj Kandpal clock = intel_lt_phy_calc_port_clock(encoder, new_crtc_state); 22799dcf1836SSuraj Kandpal 22809dcf1836SSuraj Kandpal dig_port = enc_to_dig_port(encoder); 22819dcf1836SSuraj Kandpal if (intel_tc_port_in_tbt_alt_mode(dig_port)) 22829dcf1836SSuraj Kandpal return; 22839dcf1836SSuraj Kandpal 22849dcf1836SSuraj Kandpal INTEL_DISPLAY_STATE_WARN(display, pll_hw_state.clock != clock, 22859dcf1836SSuraj Kandpal "[CRTC:%d:%s] mismatch in LT PHY: Register CLOCK (expected %d, found %d)", 22869dcf1836SSuraj Kandpal crtc->base.base.id, crtc->base.name, 22879dcf1836SSuraj Kandpal pll_sw_state->clock, pll_hw_state.clock); 22889dcf1836SSuraj Kandpal 22899dcf1836SSuraj Kandpal for (i = 0; i < 3; i++) { 22909dcf1836SSuraj Kandpal INTEL_DISPLAY_STATE_WARN(display, pll_hw_state.config[i] != pll_sw_state->config[i], 22919dcf1836SSuraj Kandpal "[CRTC:%d:%s] mismatch in LT PHY PLL CONFIG%d: (expected 0x%04x, found 0x%04x)", 22929dcf1836SSuraj Kandpal crtc->base.base.id, crtc->base.name, i, 22939dcf1836SSuraj Kandpal pll_sw_state->config[i], pll_hw_state.config[i]); 22949dcf1836SSuraj Kandpal } 22959dcf1836SSuraj Kandpal 22969dcf1836SSuraj Kandpal for (i = 0; i <= 12; i++) { 22979dcf1836SSuraj Kandpal for (j = 3; j >= 0; j--) 22989dcf1836SSuraj Kandpal INTEL_DISPLAY_STATE_WARN(display, 22999dcf1836SSuraj Kandpal pll_hw_state.data[i][j] != 23009dcf1836SSuraj Kandpal pll_sw_state->data[i][j], 23019dcf1836SSuraj Kandpal "[CRTC:%d:%s] mismatch in LT PHY PLL DATA[%d][%d]: (expected 0x%04x, found 0x%04x)", 23029dcf1836SSuraj Kandpal crtc->base.base.id, crtc->base.name, i, j, 23039dcf1836SSuraj Kandpal pll_sw_state->data[i][j], pll_hw_state.data[i][j]); 23049dcf1836SSuraj Kandpal } 23059dcf1836SSuraj Kandpal } 23069dcf1836SSuraj Kandpal 230710928925SSuraj Kandpal void intel_xe3plpd_pll_enable(struct intel_encoder *encoder, 230810928925SSuraj Kandpal const struct intel_crtc_state *crtc_state) 230910928925SSuraj Kandpal { 231010928925SSuraj Kandpal struct intel_digital_port *dig_port = enc_to_dig_port(encoder); 231110928925SSuraj Kandpal 231210928925SSuraj Kandpal if (intel_tc_port_in_tbt_alt_mode(dig_port)) 231310928925SSuraj Kandpal intel_mtl_tbt_pll_enable(encoder, crtc_state); 231410928925SSuraj Kandpal else 231510928925SSuraj Kandpal intel_lt_phy_pll_enable(encoder, crtc_state); 231610928925SSuraj Kandpal } 231710928925SSuraj Kandpal 231810928925SSuraj Kandpal void intel_xe3plpd_pll_disable(struct intel_encoder *encoder) 231910928925SSuraj Kandpal { 232010928925SSuraj Kandpal struct intel_digital_port *dig_port = enc_to_dig_port(encoder); 232110928925SSuraj Kandpal 232210928925SSuraj Kandpal if (intel_tc_port_in_tbt_alt_mode(dig_port)) 232310928925SSuraj Kandpal intel_mtl_tbt_pll_disable(encoder); 232410928925SSuraj Kandpal else 232510928925SSuraj Kandpal intel_lt_phy_pll_disable(encoder); 23269dcf1836SSuraj Kandpal 232710928925SSuraj Kandpal } 2328