1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Copyright (C) 2015 Broadcom 4 * Copyright (c) 2014 The Linux Foundation. All rights reserved. 5 * Copyright (C) 2013 Red Hat 6 * Author: Rob Clark <robdclark@gmail.com> 7 */ 8 9 #include "vc4_hdmi.h" 10 #include "vc4_regs.h" 11 #include "vc4_hdmi_regs.h" 12 13 #define VC4_HDMI_TX_PHY_RESET_CTL_PLL_RESETB BIT(5) 14 #define VC4_HDMI_TX_PHY_RESET_CTL_PLLDIV_RESETB BIT(4) 15 #define VC4_HDMI_TX_PHY_RESET_CTL_TX_CK_RESET BIT(3) 16 #define VC4_HDMI_TX_PHY_RESET_CTL_TX_2_RESET BIT(2) 17 #define VC4_HDMI_TX_PHY_RESET_CTL_TX_1_RESET BIT(1) 18 #define VC4_HDMI_TX_PHY_RESET_CTL_TX_0_RESET BIT(0) 19 20 #define VC4_HDMI_TX_PHY_POWERDOWN_CTL_RNDGEN_PWRDN BIT(4) 21 22 #define VC4_HDMI_TX_PHY_CTL_0_PREEMP_2_PREEMP_SHIFT 29 23 #define VC4_HDMI_TX_PHY_CTL_0_PREEMP_2_PREEMP_MASK VC4_MASK(31, 29) 24 #define VC4_HDMI_TX_PHY_CTL_0_PREEMP_2_MAINDRV_SHIFT 24 25 #define VC4_HDMI_TX_PHY_CTL_0_PREEMP_2_MAINDRV_MASK VC4_MASK(28, 24) 26 #define VC4_HDMI_TX_PHY_CTL_0_PREEMP_1_PREEMP_SHIFT 21 27 #define VC4_HDMI_TX_PHY_CTL_0_PREEMP_1_PREEMP_MASK VC4_MASK(23, 21) 28 #define VC4_HDMI_TX_PHY_CTL_0_PREEMP_1_MAINDRV_SHIFT 16 29 #define VC4_HDMI_TX_PHY_CTL_0_PREEMP_1_MAINDRV_MASK VC4_MASK(20, 16) 30 #define VC4_HDMI_TX_PHY_CTL_0_PREEMP_0_PREEMP_SHIFT 13 31 #define VC4_HDMI_TX_PHY_CTL_0_PREEMP_0_PREEMP_MASK VC4_MASK(15, 13) 32 #define VC4_HDMI_TX_PHY_CTL_0_PREEMP_0_MAINDRV_SHIFT 8 33 #define VC4_HDMI_TX_PHY_CTL_0_PREEMP_0_MAINDRV_MASK VC4_MASK(12, 8) 34 #define VC4_HDMI_TX_PHY_CTL_0_PREEMP_CK_PREEMP_SHIFT 5 35 #define VC4_HDMI_TX_PHY_CTL_0_PREEMP_CK_PREEMP_MASK VC4_MASK(7, 5) 36 #define VC4_HDMI_TX_PHY_CTL_0_PREEMP_CK_MAINDRV_SHIFT 0 37 #define VC4_HDMI_TX_PHY_CTL_0_PREEMP_CK_MAINDRV_MASK VC4_MASK(4, 0) 38 39 #define VC4_HDMI_TX_PHY_CTL_1_RES_SEL_DATA2_SHIFT 15 40 #define VC4_HDMI_TX_PHY_CTL_1_RES_SEL_DATA2_MASK VC4_MASK(19, 15) 41 #define VC4_HDMI_TX_PHY_CTL_1_RES_SEL_DATA1_SHIFT 10 42 #define VC4_HDMI_TX_PHY_CTL_1_RES_SEL_DATA1_MASK VC4_MASK(14, 10) 43 #define VC4_HDMI_TX_PHY_CTL_1_RES_SEL_DATA0_SHIFT 5 44 #define VC4_HDMI_TX_PHY_CTL_1_RES_SEL_DATA0_MASK VC4_MASK(9, 5) 45 #define VC4_HDMI_TX_PHY_CTL_1_RES_SEL_CK_SHIFT 0 46 #define VC4_HDMI_TX_PHY_CTL_1_RES_SEL_CK_MASK VC4_MASK(4, 0) 47 48 #define VC4_HDMI_TX_PHY_CTL_2_VCO_GAIN_SHIFT 16 49 #define VC4_HDMI_TX_PHY_CTL_2_VCO_GAIN_MASK VC4_MASK(19, 16) 50 #define VC4_HDMI_TX_PHY_CTL_2_TERM_RES_SELDATA2_SHIFT 12 51 #define VC4_HDMI_TX_PHY_CTL_2_TERM_RES_SELDATA2_MASK VC4_MASK(15, 12) 52 #define VC4_HDMI_TX_PHY_CTL_2_TERM_RES_SELDATA1_SHIFT 8 53 #define VC4_HDMI_TX_PHY_CTL_2_TERM_RES_SELDATA1_MASK VC4_MASK(11, 8) 54 #define VC4_HDMI_TX_PHY_CTL_2_TERM_RES_SELDATA0_SHIFT 4 55 #define VC4_HDMI_TX_PHY_CTL_2_TERM_RES_SELDATA0_MASK VC4_MASK(7, 4) 56 #define VC4_HDMI_TX_PHY_CTL_2_TERM_RES_SELCK_SHIFT 0 57 #define VC4_HDMI_TX_PHY_CTL_2_TERM_RES_SELCK_MASK VC4_MASK(3, 0) 58 59 #define VC4_HDMI_TX_PHY_CTL_3_RP_SHIFT 17 60 #define VC4_HDMI_TX_PHY_CTL_3_RP_MASK VC4_MASK(19, 17) 61 #define VC4_HDMI_TX_PHY_CTL_3_RZ_SHIFT 12 62 #define VC4_HDMI_TX_PHY_CTL_3_RZ_MASK VC4_MASK(16, 12) 63 #define VC4_HDMI_TX_PHY_CTL_3_CP1_SHIFT 10 64 #define VC4_HDMI_TX_PHY_CTL_3_CP1_MASK VC4_MASK(11, 10) 65 #define VC4_HDMI_TX_PHY_CTL_3_CP_SHIFT 8 66 #define VC4_HDMI_TX_PHY_CTL_3_CP_MASK VC4_MASK(9, 8) 67 #define VC4_HDMI_TX_PHY_CTL_3_CZ_SHIFT 6 68 #define VC4_HDMI_TX_PHY_CTL_3_CZ_MASK VC4_MASK(7, 6) 69 #define VC4_HDMI_TX_PHY_CTL_3_ICP_SHIFT 0 70 #define VC4_HDMI_TX_PHY_CTL_3_ICP_MASK VC4_MASK(5, 0) 71 72 #define VC4_HDMI_TX_PHY_PLL_CTL_0_MASH11_MODE BIT(13) 73 #define VC4_HDMI_TX_PHY_PLL_CTL_0_VC_RANGE_EN BIT(12) 74 #define VC4_HDMI_TX_PHY_PLL_CTL_0_EMULATE_VC_LOW BIT(11) 75 #define VC4_HDMI_TX_PHY_PLL_CTL_0_EMULATE_VC_HIGH BIT(10) 76 #define VC4_HDMI_TX_PHY_PLL_CTL_0_VCO_SEL_SHIFT 9 77 #define VC4_HDMI_TX_PHY_PLL_CTL_0_VCO_SEL_MASK VC4_MASK(9, 9) 78 #define VC4_HDMI_TX_PHY_PLL_CTL_0_VCO_FB_DIV2 BIT(8) 79 #define VC4_HDMI_TX_PHY_PLL_CTL_0_VCO_POST_DIV2 BIT(7) 80 #define VC4_HDMI_TX_PHY_PLL_CTL_0_VCO_CONT_EN BIT(6) 81 #define VC4_HDMI_TX_PHY_PLL_CTL_0_ENA_VCO_CLK BIT(5) 82 83 #define VC4_HDMI_TX_PHY_PLL_CTL_1_CPP_SHIFT 16 84 #define VC4_HDMI_TX_PHY_PLL_CTL_1_CPP_MASK VC4_MASK(27, 16) 85 #define VC4_HDMI_TX_PHY_PLL_CTL_1_FREQ_DOUBLER_DELAY_SHIFT 14 86 #define VC4_HDMI_TX_PHY_PLL_CTL_1_FREQ_DOUBLER_DELAY_MASK VC4_MASK(15, 14) 87 #define VC4_HDMI_TX_PHY_PLL_CTL_1_FREQ_DOUBLER_ENABLE BIT(13) 88 #define VC4_HDMI_TX_PHY_PLL_CTL_1_POST_RST_SEL_SHIFT 11 89 #define VC4_HDMI_TX_PHY_PLL_CTL_1_POST_RST_SEL_MASK VC4_MASK(12, 11) 90 91 #define VC4_HDMI_TX_PHY_CLK_DIV_VCO_SHIFT 8 92 #define VC4_HDMI_TX_PHY_CLK_DIV_VCO_MASK VC4_MASK(15, 8) 93 94 #define VC4_HDMI_TX_PHY_PLL_CFG_PDIV_SHIFT 0 95 #define VC4_HDMI_TX_PHY_PLL_CFG_PDIV_MASK VC4_MASK(3, 0) 96 97 #define VC4_HDMI_TX_PHY_CHANNEL_SWAP_TXCK_OUT_SEL_MASK VC4_MASK(13, 12) 98 #define VC4_HDMI_TX_PHY_CHANNEL_SWAP_TXCK_OUT_SEL_SHIFT 12 99 #define VC4_HDMI_TX_PHY_CHANNEL_SWAP_TX2_OUT_SEL_MASK VC4_MASK(9, 8) 100 #define VC4_HDMI_TX_PHY_CHANNEL_SWAP_TX2_OUT_SEL_SHIFT 8 101 #define VC4_HDMI_TX_PHY_CHANNEL_SWAP_TX1_OUT_SEL_MASK VC4_MASK(5, 4) 102 #define VC4_HDMI_TX_PHY_CHANNEL_SWAP_TX1_OUT_SEL_SHIFT 4 103 #define VC4_HDMI_TX_PHY_CHANNEL_SWAP_TX0_OUT_SEL_MASK VC4_MASK(1, 0) 104 #define VC4_HDMI_TX_PHY_CHANNEL_SWAP_TX0_OUT_SEL_SHIFT 0 105 106 #define VC4_HDMI_TX_PHY_PLL_CALIBRATION_CONFIG_1_MIN_LIMIT_MASK VC4_MASK(27, 0) 107 #define VC4_HDMI_TX_PHY_PLL_CALIBRATION_CONFIG_1_MIN_LIMIT_SHIFT 0 108 109 #define VC4_HDMI_TX_PHY_PLL_CALIBRATION_CONFIG_2_MAX_LIMIT_MASK VC4_MASK(27, 0) 110 #define VC4_HDMI_TX_PHY_PLL_CALIBRATION_CONFIG_2_MAX_LIMIT_SHIFT 0 111 112 #define VC4_HDMI_TX_PHY_PLL_CALIBRATION_CONFIG_4_STABLE_THRESHOLD_MASK VC4_MASK(31, 16) 113 #define VC4_HDMI_TX_PHY_PLL_CALIBRATION_CONFIG_4_STABLE_THRESHOLD_SHIFT 16 114 #define VC4_HDMI_TX_PHY_PLL_CALIBRATION_CONFIG_4_HOLD_THRESHOLD_MASK VC4_MASK(15, 0) 115 #define VC4_HDMI_TX_PHY_PLL_CALIBRATION_CONFIG_4_HOLD_THRESHOLD_SHIFT 0 116 117 #define VC4_HDMI_RM_CONTROL_EN_FREEZE_COUNTERS BIT(19) 118 #define VC4_HDMI_RM_CONTROL_EN_LOAD_INTEGRATOR BIT(17) 119 #define VC4_HDMI_RM_CONTROL_FREE_RUN BIT(4) 120 121 #define VC4_HDMI_RM_OFFSET_ONLY BIT(31) 122 #define VC4_HDMI_RM_OFFSET_OFFSET_SHIFT 0 123 #define VC4_HDMI_RM_OFFSET_OFFSET_MASK VC4_MASK(30, 0) 124 125 #define VC4_HDMI_RM_FORMAT_SHIFT_SHIFT 24 126 #define VC4_HDMI_RM_FORMAT_SHIFT_MASK VC4_MASK(25, 24) 127 128 #define VC6_HDMI_TX_PHY_HDMI_POWERUP_CTL_BG_PWRUP BIT(8) 129 #define VC6_HDMI_TX_PHY_HDMI_POWERUP_CTL_LDO_PWRUP BIT(7) 130 #define VC6_HDMI_TX_PHY_HDMI_POWERUP_CTL_BIAS_PWRUP BIT(6) 131 #define VC6_HDMI_TX_PHY_HDMI_POWERUP_CTL_RNDGEN_PWRUP BIT(4) 132 #define VC6_HDMI_TX_PHY_HDMI_POWERUP_CTL_TX_CK_PWRUP BIT(3) 133 #define VC6_HDMI_TX_PHY_HDMI_POWERUP_CTL_TX_2_PWRUP BIT(2) 134 #define VC6_HDMI_TX_PHY_HDMI_POWERUP_CTL_TX_1_PWRUP BIT(1) 135 #define VC6_HDMI_TX_PHY_HDMI_POWERUP_CTL_TX_0_PWRUP BIT(0) 136 137 #define VC6_HDMI_TX_PHY_PLL_REFCLK_REFCLK_SEL_CMOS BIT(13) 138 #define VC6_HDMI_TX_PHY_PLL_REFCLK_REFFRQ_MASK VC4_MASK(9, 0) 139 140 #define VC6_HDMI_TX_PHY_PLL_POST_KDIV_CLK0_SEL_MASK VC4_MASK(3, 2) 141 #define VC6_HDMI_TX_PHY_PLL_POST_KDIV_KDIV_MASK VC4_MASK(1, 0) 142 143 #define VC6_HDMI_TX_PHY_PLL_VCOCLK_DIV_VCODIV_EN BIT(10) 144 #define VC6_HDMI_TX_PHY_PLL_VCOCLK_DIV_VCODIV_MASK VC4_MASK(9, 0) 145 146 #define VC6_HDMI_TX_PHY_HDMI_CTRL_CHX_EXT_CURRENT_CTL_MASK VC4_MASK(31, 28) 147 #define VC6_HDMI_TX_PHY_HDMI_CTRL_CHX_FFE_ENABLE_MASK VC4_MASK(27, 27) 148 #define VC6_HDMI_TX_PHY_HDMI_CTRL_CHX_SLEW_RATE_CTL_MASK VC4_MASK(26, 26) 149 #define VC6_HDMI_TX_PHY_HDMI_CTRL_CHX_FFE_POST_TAP_EN_MASK VC4_MASK(25, 25) 150 #define VC6_HDMI_TX_PHY_HDMI_CTRL_CHX_LDMOS_BIAS_CTL_MASK VC4_MASK(24, 23) 151 #define VC6_HDMI_TX_PHY_HDMI_CTRL_CHX_COM_MODE_LDMOS_EN_MASK VC4_MASK(22, 22) 152 #define VC6_HDMI_TX_PHY_HDMI_CTRL_CHX_EDGE_SEL_MASK VC4_MASK(21, 21) 153 #define VC6_HDMI_TX_PHY_HDMI_CTRL_CHX_EXT_CURRENT_SRC_HS_EN_MASK VC4_MASK(20, 20) 154 #define VC6_HDMI_TX_PHY_HDMI_CTRL_CHX_TERM_CTL_MASK VC4_MASK(19, 18) 155 #define VC6_HDMI_TX_PHY_HDMI_CTRL_CHX_EXT_CURRENT_SRC_EN_MASK VC4_MASK(17, 17) 156 #define VC6_HDMI_TX_PHY_HDMI_CTRL_CHX_INT_CURRENT_SRC_EN_MASK VC4_MASK(16, 16) 157 #define VC6_HDMI_TX_PHY_HDMI_CTRL_CHX_INT_CURRENT_CTL_MASK VC4_MASK(15, 12) 158 #define VC6_HDMI_TX_PHY_HDMI_CTRL_CHX_INT_CURRENT_SRC_HS_EN_MASK VC4_MASK(11, 11) 159 #define VC6_HDMI_TX_PHY_HDMI_CTRL_CHX_MAIN_TAP_CURRENT_SELECT_MASK VC4_MASK(10, 8) 160 #define VC6_HDMI_TX_PHY_HDMI_CTRL_CHX_POST_TAP_CURRENT_SELECT_MASK VC4_MASK(7, 5) 161 #define VC6_HDMI_TX_PHY_HDMI_CTRL_CHX_SLEW_CTL_SLOW_LOADING_MASK VC4_MASK(4, 3) 162 #define VC6_HDMI_TX_PHY_HDMI_CTRL_CHX_SLEW_CTL_SLOW_DRIVING_MASK VC4_MASK(2, 1) 163 #define VC6_HDMI_TX_PHY_HDMI_CTRL_CHX_FFE_PRE_TAP_EN_MASK VC4_MASK(0, 0) 164 165 #define VC6_HDMI_TX_PHY_PLL_RESET_CTL_PLL_PLLPOST_RESETB BIT(1) 166 #define VC6_HDMI_TX_PHY_PLL_RESET_CTL_PLL_RESETB BIT(0) 167 168 #define VC6_HDMI_TX_PHY_PLL_POWERUP_CTL_PLL_PWRUP BIT(0) 169 170 #define OSCILLATOR_FREQUENCY 54000000 171 172 void vc4_hdmi_phy_init(struct vc4_hdmi *vc4_hdmi, 173 struct drm_connector_state *conn_state) 174 { 175 unsigned long flags; 176 177 /* PHY should be in reset, like 178 * vc4_hdmi_encoder_disable() does. 179 */ 180 181 spin_lock_irqsave(&vc4_hdmi->hw_lock, flags); 182 183 HDMI_WRITE(HDMI_TX_PHY_RESET_CTL, 0xf << 16); 184 HDMI_WRITE(HDMI_TX_PHY_RESET_CTL, 0); 185 186 spin_unlock_irqrestore(&vc4_hdmi->hw_lock, flags); 187 } 188 189 void vc4_hdmi_phy_disable(struct vc4_hdmi *vc4_hdmi) 190 { 191 unsigned long flags; 192 193 spin_lock_irqsave(&vc4_hdmi->hw_lock, flags); 194 HDMI_WRITE(HDMI_TX_PHY_RESET_CTL, 0xf << 16); 195 spin_unlock_irqrestore(&vc4_hdmi->hw_lock, flags); 196 } 197 198 void vc4_hdmi_phy_rng_enable(struct vc4_hdmi *vc4_hdmi) 199 { 200 unsigned long flags; 201 202 spin_lock_irqsave(&vc4_hdmi->hw_lock, flags); 203 HDMI_WRITE(HDMI_TX_PHY_CTL_0, 204 HDMI_READ(HDMI_TX_PHY_CTL_0) & 205 ~VC4_HDMI_TX_PHY_RNG_PWRDN); 206 spin_unlock_irqrestore(&vc4_hdmi->hw_lock, flags); 207 } 208 209 void vc4_hdmi_phy_rng_disable(struct vc4_hdmi *vc4_hdmi) 210 { 211 unsigned long flags; 212 213 spin_lock_irqsave(&vc4_hdmi->hw_lock, flags); 214 HDMI_WRITE(HDMI_TX_PHY_CTL_0, 215 HDMI_READ(HDMI_TX_PHY_CTL_0) | 216 VC4_HDMI_TX_PHY_RNG_PWRDN); 217 spin_unlock_irqrestore(&vc4_hdmi->hw_lock, flags); 218 } 219 220 static unsigned long long 221 phy_get_vco_freq(unsigned long long clock, u8 *vco_sel, u8 *vco_div) 222 { 223 unsigned long long vco_freq = clock; 224 unsigned int _vco_div = 0; 225 unsigned int _vco_sel = 0; 226 227 while (vco_freq < 3000000000ULL) { 228 _vco_div++; 229 vco_freq = clock * _vco_div * 10; 230 } 231 232 if (vco_freq > 4500000000ULL) 233 _vco_sel = 1; 234 235 *vco_sel = _vco_sel; 236 *vco_div = _vco_div; 237 238 return vco_freq; 239 } 240 241 static u8 phy_get_cp_current(unsigned long vco_freq) 242 { 243 if (vco_freq < 3700000000ULL) 244 return 0x1c; 245 246 return 0x18; 247 } 248 249 static u32 phy_get_rm_offset(unsigned long long vco_freq) 250 { 251 unsigned long long fref = OSCILLATOR_FREQUENCY; 252 u64 offset = 0; 253 254 /* RM offset is stored as 9.22 format */ 255 offset = vco_freq * 2; 256 offset = offset << 22; 257 do_div(offset, fref); 258 offset >>= 2; 259 260 return offset; 261 } 262 263 static u8 phy_get_vco_gain(unsigned long long vco_freq) 264 { 265 if (vco_freq < 3350000000ULL) 266 return 0xf; 267 268 if (vco_freq < 3700000000ULL) 269 return 0xc; 270 271 if (vco_freq < 4050000000ULL) 272 return 0x6; 273 274 if (vco_freq < 4800000000ULL) 275 return 0x5; 276 277 if (vco_freq < 5200000000ULL) 278 return 0x7; 279 280 return 0x2; 281 } 282 283 struct phy_lane_settings { 284 struct { 285 u8 preemphasis; 286 u8 main_driver; 287 } amplitude; 288 289 u8 res_sel_data; 290 u8 term_res_sel_data; 291 }; 292 293 struct phy_settings { 294 unsigned long long min_rate; 295 unsigned long long max_rate; 296 struct phy_lane_settings channel[3]; 297 struct phy_lane_settings clock; 298 }; 299 300 static const struct phy_settings vc5_hdmi_phy_settings[] = { 301 { 302 0, 50000000, 303 { 304 {{0x0, 0x0A}, 0x12, 0x0}, 305 {{0x0, 0x0A}, 0x12, 0x0}, 306 {{0x0, 0x0A}, 0x12, 0x0} 307 }, 308 {{0x0, 0x0A}, 0x18, 0x0}, 309 }, 310 { 311 50000001, 75000000, 312 { 313 {{0x0, 0x09}, 0x12, 0x0}, 314 {{0x0, 0x09}, 0x12, 0x0}, 315 {{0x0, 0x09}, 0x12, 0x0} 316 }, 317 {{0x0, 0x0C}, 0x18, 0x3}, 318 }, 319 { 320 75000001, 165000000, 321 { 322 {{0x0, 0x09}, 0x12, 0x0}, 323 {{0x0, 0x09}, 0x12, 0x0}, 324 {{0x0, 0x09}, 0x12, 0x0} 325 }, 326 {{0x0, 0x0C}, 0x18, 0x3}, 327 }, 328 { 329 165000001, 250000000, 330 { 331 {{0x0, 0x0F}, 0x12, 0x1}, 332 {{0x0, 0x0F}, 0x12, 0x1}, 333 {{0x0, 0x0F}, 0x12, 0x1} 334 }, 335 {{0x0, 0x0C}, 0x18, 0x3}, 336 }, 337 { 338 250000001, 340000000, 339 { 340 {{0x2, 0x0D}, 0x12, 0x1}, 341 {{0x2, 0x0D}, 0x12, 0x1}, 342 {{0x2, 0x0D}, 0x12, 0x1} 343 }, 344 {{0x0, 0x0C}, 0x18, 0xF}, 345 }, 346 { 347 340000001, 450000000, 348 { 349 {{0x0, 0x1B}, 0x12, 0xF}, 350 {{0x0, 0x1B}, 0x12, 0xF}, 351 {{0x0, 0x1B}, 0x12, 0xF} 352 }, 353 {{0x0, 0x0A}, 0x12, 0xF}, 354 }, 355 { 356 450000001, 600000000, 357 { 358 {{0x0, 0x1C}, 0x12, 0xF}, 359 {{0x0, 0x1C}, 0x12, 0xF}, 360 {{0x0, 0x1C}, 0x12, 0xF} 361 }, 362 {{0x0, 0x0B}, 0x13, 0xF}, 363 }, 364 }; 365 366 static const struct phy_settings *phy_get_settings(unsigned long long tmds_rate) 367 { 368 unsigned int count = ARRAY_SIZE(vc5_hdmi_phy_settings); 369 unsigned int i; 370 371 for (i = 0; i < count; i++) { 372 const struct phy_settings *s = &vc5_hdmi_phy_settings[i]; 373 374 if (tmds_rate >= s->min_rate && tmds_rate <= s->max_rate) 375 return s; 376 } 377 378 /* 379 * If the pixel clock exceeds our max setting, try the max 380 * setting anyway. 381 */ 382 return &vc5_hdmi_phy_settings[count - 1]; 383 } 384 385 static const struct phy_lane_settings * 386 phy_get_channel_settings(enum vc4_hdmi_phy_channel chan, 387 unsigned long long tmds_rate) 388 { 389 const struct phy_settings *settings = phy_get_settings(tmds_rate); 390 391 if (chan == PHY_LANE_CK) 392 return &settings->clock; 393 394 return &settings->channel[chan]; 395 } 396 397 static void vc5_hdmi_reset_phy(struct vc4_hdmi *vc4_hdmi) 398 { 399 lockdep_assert_held(&vc4_hdmi->hw_lock); 400 401 HDMI_WRITE(HDMI_TX_PHY_RESET_CTL, 0x0f); 402 HDMI_WRITE(HDMI_TX_PHY_POWERDOWN_CTL, BIT(10)); 403 } 404 405 void vc5_hdmi_phy_init(struct vc4_hdmi *vc4_hdmi, 406 struct drm_connector_state *conn_state) 407 { 408 const struct phy_lane_settings *chan0_settings, *chan1_settings, *chan2_settings, *clock_settings; 409 const struct vc4_hdmi_variant *variant = vc4_hdmi->variant; 410 unsigned long long pixel_freq = conn_state->hdmi.tmds_char_rate; 411 unsigned long long vco_freq; 412 unsigned char word_sel; 413 unsigned long flags; 414 u8 vco_sel, vco_div; 415 416 vco_freq = phy_get_vco_freq(pixel_freq, &vco_sel, &vco_div); 417 418 spin_lock_irqsave(&vc4_hdmi->hw_lock, flags); 419 420 vc5_hdmi_reset_phy(vc4_hdmi); 421 422 HDMI_WRITE(HDMI_TX_PHY_POWERDOWN_CTL, 423 VC4_HDMI_TX_PHY_POWERDOWN_CTL_RNDGEN_PWRDN); 424 425 HDMI_WRITE(HDMI_TX_PHY_RESET_CTL, 426 HDMI_READ(HDMI_TX_PHY_RESET_CTL) & 427 ~VC4_HDMI_TX_PHY_RESET_CTL_TX_0_RESET & 428 ~VC4_HDMI_TX_PHY_RESET_CTL_TX_1_RESET & 429 ~VC4_HDMI_TX_PHY_RESET_CTL_TX_2_RESET & 430 ~VC4_HDMI_TX_PHY_RESET_CTL_TX_CK_RESET); 431 432 HDMI_WRITE(HDMI_RM_CONTROL, 433 HDMI_READ(HDMI_RM_CONTROL) | 434 VC4_HDMI_RM_CONTROL_EN_FREEZE_COUNTERS | 435 VC4_HDMI_RM_CONTROL_EN_LOAD_INTEGRATOR | 436 VC4_HDMI_RM_CONTROL_FREE_RUN); 437 438 HDMI_WRITE(HDMI_TX_PHY_PLL_CALIBRATION_CONFIG_1, 439 (HDMI_READ(HDMI_TX_PHY_PLL_CALIBRATION_CONFIG_1) & 440 ~VC4_HDMI_TX_PHY_PLL_CALIBRATION_CONFIG_1_MIN_LIMIT_MASK) | 441 VC4_SET_FIELD(0, VC4_HDMI_TX_PHY_PLL_CALIBRATION_CONFIG_1_MIN_LIMIT)); 442 443 HDMI_WRITE(HDMI_TX_PHY_PLL_CALIBRATION_CONFIG_2, 444 (HDMI_READ(HDMI_TX_PHY_PLL_CALIBRATION_CONFIG_2) & 445 ~VC4_HDMI_TX_PHY_PLL_CALIBRATION_CONFIG_2_MAX_LIMIT_MASK) | 446 VC4_SET_FIELD(0, VC4_HDMI_TX_PHY_PLL_CALIBRATION_CONFIG_2_MAX_LIMIT)); 447 448 HDMI_WRITE(HDMI_RM_OFFSET, 449 VC4_SET_FIELD(phy_get_rm_offset(vco_freq), 450 VC4_HDMI_RM_OFFSET_OFFSET) | 451 VC4_HDMI_RM_OFFSET_ONLY); 452 453 HDMI_WRITE(HDMI_TX_PHY_CLK_DIV, 454 VC4_SET_FIELD(vco_div, VC4_HDMI_TX_PHY_CLK_DIV_VCO)); 455 456 HDMI_WRITE(HDMI_TX_PHY_PLL_CALIBRATION_CONFIG_4, 457 VC4_SET_FIELD(0xe147, VC4_HDMI_TX_PHY_PLL_CALIBRATION_CONFIG_4_HOLD_THRESHOLD) | 458 VC4_SET_FIELD(0xe14, VC4_HDMI_TX_PHY_PLL_CALIBRATION_CONFIG_4_STABLE_THRESHOLD)); 459 460 HDMI_WRITE(HDMI_TX_PHY_PLL_CTL_0, 461 VC4_HDMI_TX_PHY_PLL_CTL_0_ENA_VCO_CLK | 462 VC4_HDMI_TX_PHY_PLL_CTL_0_VCO_CONT_EN | 463 VC4_HDMI_TX_PHY_PLL_CTL_0_MASH11_MODE | 464 VC4_SET_FIELD(vco_sel, VC4_HDMI_TX_PHY_PLL_CTL_0_VCO_SEL)); 465 466 HDMI_WRITE(HDMI_TX_PHY_PLL_CTL_1, 467 HDMI_READ(HDMI_TX_PHY_PLL_CTL_1) | 468 VC4_HDMI_TX_PHY_PLL_CTL_1_FREQ_DOUBLER_ENABLE | 469 VC4_SET_FIELD(3, VC4_HDMI_TX_PHY_PLL_CTL_1_POST_RST_SEL) | 470 VC4_SET_FIELD(1, VC4_HDMI_TX_PHY_PLL_CTL_1_FREQ_DOUBLER_DELAY) | 471 VC4_SET_FIELD(0x8a, VC4_HDMI_TX_PHY_PLL_CTL_1_CPP)); 472 473 HDMI_WRITE(HDMI_RM_FORMAT, 474 HDMI_READ(HDMI_RM_FORMAT) | 475 VC4_SET_FIELD(2, VC4_HDMI_RM_FORMAT_SHIFT)); 476 477 HDMI_WRITE(HDMI_TX_PHY_PLL_CFG, 478 HDMI_READ(HDMI_TX_PHY_PLL_CFG) | 479 VC4_SET_FIELD(1, VC4_HDMI_TX_PHY_PLL_CFG_PDIV)); 480 481 if (pixel_freq >= 340000000) 482 word_sel = 3; 483 else 484 word_sel = 0; 485 HDMI_WRITE(HDMI_TX_PHY_TMDS_CLK_WORD_SEL, word_sel); 486 487 HDMI_WRITE(HDMI_TX_PHY_CTL_3, 488 VC4_SET_FIELD(phy_get_cp_current(vco_freq), 489 VC4_HDMI_TX_PHY_CTL_3_ICP) | 490 VC4_SET_FIELD(1, VC4_HDMI_TX_PHY_CTL_3_CP) | 491 VC4_SET_FIELD(1, VC4_HDMI_TX_PHY_CTL_3_CP1) | 492 VC4_SET_FIELD(3, VC4_HDMI_TX_PHY_CTL_3_CZ) | 493 VC4_SET_FIELD(4, VC4_HDMI_TX_PHY_CTL_3_RP) | 494 VC4_SET_FIELD(6, VC4_HDMI_TX_PHY_CTL_3_RZ)); 495 496 chan0_settings = 497 phy_get_channel_settings(variant->phy_lane_mapping[PHY_LANE_0], 498 pixel_freq); 499 chan1_settings = 500 phy_get_channel_settings(variant->phy_lane_mapping[PHY_LANE_1], 501 pixel_freq); 502 chan2_settings = 503 phy_get_channel_settings(variant->phy_lane_mapping[PHY_LANE_2], 504 pixel_freq); 505 clock_settings = 506 phy_get_channel_settings(variant->phy_lane_mapping[PHY_LANE_CK], 507 pixel_freq); 508 509 HDMI_WRITE(HDMI_TX_PHY_CTL_0, 510 VC4_SET_FIELD(chan0_settings->amplitude.preemphasis, 511 VC4_HDMI_TX_PHY_CTL_0_PREEMP_0_PREEMP) | 512 VC4_SET_FIELD(chan0_settings->amplitude.main_driver, 513 VC4_HDMI_TX_PHY_CTL_0_PREEMP_0_MAINDRV) | 514 VC4_SET_FIELD(chan1_settings->amplitude.preemphasis, 515 VC4_HDMI_TX_PHY_CTL_0_PREEMP_1_PREEMP) | 516 VC4_SET_FIELD(chan1_settings->amplitude.main_driver, 517 VC4_HDMI_TX_PHY_CTL_0_PREEMP_1_MAINDRV) | 518 VC4_SET_FIELD(chan2_settings->amplitude.preemphasis, 519 VC4_HDMI_TX_PHY_CTL_0_PREEMP_2_PREEMP) | 520 VC4_SET_FIELD(chan2_settings->amplitude.main_driver, 521 VC4_HDMI_TX_PHY_CTL_0_PREEMP_2_MAINDRV) | 522 VC4_SET_FIELD(clock_settings->amplitude.preemphasis, 523 VC4_HDMI_TX_PHY_CTL_0_PREEMP_CK_PREEMP) | 524 VC4_SET_FIELD(clock_settings->amplitude.main_driver, 525 VC4_HDMI_TX_PHY_CTL_0_PREEMP_CK_MAINDRV)); 526 527 HDMI_WRITE(HDMI_TX_PHY_CTL_1, 528 HDMI_READ(HDMI_TX_PHY_CTL_1) | 529 VC4_SET_FIELD(chan0_settings->res_sel_data, 530 VC4_HDMI_TX_PHY_CTL_1_RES_SEL_DATA0) | 531 VC4_SET_FIELD(chan1_settings->res_sel_data, 532 VC4_HDMI_TX_PHY_CTL_1_RES_SEL_DATA1) | 533 VC4_SET_FIELD(chan2_settings->res_sel_data, 534 VC4_HDMI_TX_PHY_CTL_1_RES_SEL_DATA2) | 535 VC4_SET_FIELD(clock_settings->res_sel_data, 536 VC4_HDMI_TX_PHY_CTL_1_RES_SEL_CK)); 537 538 HDMI_WRITE(HDMI_TX_PHY_CTL_2, 539 VC4_SET_FIELD(chan0_settings->term_res_sel_data, 540 VC4_HDMI_TX_PHY_CTL_2_TERM_RES_SELDATA0) | 541 VC4_SET_FIELD(chan1_settings->term_res_sel_data, 542 VC4_HDMI_TX_PHY_CTL_2_TERM_RES_SELDATA1) | 543 VC4_SET_FIELD(chan2_settings->term_res_sel_data, 544 VC4_HDMI_TX_PHY_CTL_2_TERM_RES_SELDATA2) | 545 VC4_SET_FIELD(clock_settings->term_res_sel_data, 546 VC4_HDMI_TX_PHY_CTL_2_TERM_RES_SELCK) | 547 VC4_SET_FIELD(phy_get_vco_gain(vco_freq), 548 VC4_HDMI_TX_PHY_CTL_2_VCO_GAIN)); 549 550 HDMI_WRITE(HDMI_TX_PHY_CHANNEL_SWAP, 551 VC4_SET_FIELD(variant->phy_lane_mapping[PHY_LANE_0], 552 VC4_HDMI_TX_PHY_CHANNEL_SWAP_TX0_OUT_SEL) | 553 VC4_SET_FIELD(variant->phy_lane_mapping[PHY_LANE_1], 554 VC4_HDMI_TX_PHY_CHANNEL_SWAP_TX1_OUT_SEL) | 555 VC4_SET_FIELD(variant->phy_lane_mapping[PHY_LANE_2], 556 VC4_HDMI_TX_PHY_CHANNEL_SWAP_TX2_OUT_SEL) | 557 VC4_SET_FIELD(variant->phy_lane_mapping[PHY_LANE_CK], 558 VC4_HDMI_TX_PHY_CHANNEL_SWAP_TXCK_OUT_SEL)); 559 560 HDMI_WRITE(HDMI_TX_PHY_RESET_CTL, 561 HDMI_READ(HDMI_TX_PHY_RESET_CTL) & 562 ~(VC4_HDMI_TX_PHY_RESET_CTL_PLL_RESETB | 563 VC4_HDMI_TX_PHY_RESET_CTL_PLLDIV_RESETB)); 564 565 HDMI_WRITE(HDMI_TX_PHY_RESET_CTL, 566 HDMI_READ(HDMI_TX_PHY_RESET_CTL) | 567 VC4_HDMI_TX_PHY_RESET_CTL_PLL_RESETB | 568 VC4_HDMI_TX_PHY_RESET_CTL_PLLDIV_RESETB); 569 570 spin_unlock_irqrestore(&vc4_hdmi->hw_lock, flags); 571 } 572 573 void vc5_hdmi_phy_disable(struct vc4_hdmi *vc4_hdmi) 574 { 575 unsigned long flags; 576 577 spin_lock_irqsave(&vc4_hdmi->hw_lock, flags); 578 vc5_hdmi_reset_phy(vc4_hdmi); 579 spin_unlock_irqrestore(&vc4_hdmi->hw_lock, flags); 580 } 581 582 void vc5_hdmi_phy_rng_enable(struct vc4_hdmi *vc4_hdmi) 583 { 584 unsigned long flags; 585 586 spin_lock_irqsave(&vc4_hdmi->hw_lock, flags); 587 HDMI_WRITE(HDMI_TX_PHY_POWERDOWN_CTL, 588 HDMI_READ(HDMI_TX_PHY_POWERDOWN_CTL) & 589 ~VC4_HDMI_TX_PHY_POWERDOWN_CTL_RNDGEN_PWRDN); 590 spin_unlock_irqrestore(&vc4_hdmi->hw_lock, flags); 591 } 592 593 void vc5_hdmi_phy_rng_disable(struct vc4_hdmi *vc4_hdmi) 594 { 595 unsigned long flags; 596 597 spin_lock_irqsave(&vc4_hdmi->hw_lock, flags); 598 HDMI_WRITE(HDMI_TX_PHY_POWERDOWN_CTL, 599 HDMI_READ(HDMI_TX_PHY_POWERDOWN_CTL) | 600 VC4_HDMI_TX_PHY_POWERDOWN_CTL_RNDGEN_PWRDN); 601 spin_unlock_irqrestore(&vc4_hdmi->hw_lock, flags); 602 } 603 604 #define VC6_VCO_MIN_FREQ (8ULL * 1000 * 1000 * 1000) 605 #define VC6_VCO_MAX_FREQ (12ULL * 1000 * 1000 * 1000) 606 607 static unsigned long long 608 vc6_phy_get_vco_freq(unsigned long long tmds_rate, unsigned int *vco_div) 609 { 610 unsigned int min_div; 611 unsigned int max_div; 612 unsigned int div; 613 614 div = 0; 615 while (tmds_rate * div * 10 < VC6_VCO_MIN_FREQ) 616 div++; 617 min_div = div; 618 619 while (tmds_rate * (div + 1) * 10 < VC6_VCO_MAX_FREQ) 620 div++; 621 max_div = div; 622 623 div = min_div + (max_div - min_div) / 2; 624 625 *vco_div = div; 626 return tmds_rate * div * 10; 627 } 628 629 struct vc6_phy_lane_settings { 630 unsigned int ext_current_ctl:4; 631 unsigned int ffe_enable:1; 632 unsigned int slew_rate_ctl:1; 633 unsigned int ffe_post_tap_en:1; 634 unsigned int ldmos_bias_ctl:2; 635 unsigned int com_mode_ldmos_en:1; 636 unsigned int edge_sel:1; 637 unsigned int ext_current_src_hs_en:1; 638 unsigned int term_ctl:2; 639 unsigned int ext_current_src_en:1; 640 unsigned int int_current_src_en:1; 641 unsigned int int_current_ctl:4; 642 unsigned int int_current_src_hs_en:1; 643 unsigned int main_tap_current_select:3; 644 unsigned int post_tap_current_select:3; 645 unsigned int slew_ctl_slow_loading:2; 646 unsigned int slew_ctl_slow_driving:2; 647 unsigned int ffe_pre_tap_en:1; 648 }; 649 650 struct vc6_phy_settings { 651 unsigned long long min_rate; 652 unsigned long long max_rate; 653 struct vc6_phy_lane_settings channel[3]; 654 struct vc6_phy_lane_settings clock; 655 }; 656 657 static const struct vc6_phy_settings vc6_hdmi_phy_settings[] = { 658 { 659 0, 222000000, 660 { 661 { 662 /* 200mA */ 663 .ext_current_ctl = 8, 664 665 /* 0.85V */ 666 .ldmos_bias_ctl = 1, 667 668 /* Enable External Current Source */ 669 .ext_current_src_en = 1, 670 671 /* 200mA */ 672 .int_current_ctl = 8, 673 674 /* 17.6 mA */ 675 .main_tap_current_select = 7, 676 }, 677 { 678 /* 200mA */ 679 .ext_current_ctl = 8, 680 681 /* 0.85V */ 682 .ldmos_bias_ctl = 1, 683 684 /* Enable External Current Source */ 685 .ext_current_src_en = 1, 686 687 /* 200mA */ 688 .int_current_ctl = 8, 689 690 /* 17.6 mA */ 691 .main_tap_current_select = 7, 692 }, 693 { 694 /* 200mA */ 695 .ext_current_ctl = 8, 696 697 /* 0.85V */ 698 .ldmos_bias_ctl = 1, 699 700 /* Enable External Current Source */ 701 .ext_current_src_en = 1, 702 703 /* 200mA */ 704 .int_current_ctl = 8, 705 706 /* 17.6 mA */ 707 .main_tap_current_select = 7, 708 }, 709 }, 710 { 711 /* 200mA */ 712 .ext_current_ctl = 8, 713 714 /* 0.85V */ 715 .ldmos_bias_ctl = 1, 716 717 /* Enable External Current Source */ 718 .ext_current_src_en = 1, 719 720 /* 200mA */ 721 .int_current_ctl = 8, 722 723 /* 17.6 mA */ 724 .main_tap_current_select = 7, 725 }, 726 }, 727 { 728 222000001, 297000000, 729 { 730 { 731 /* 200mA and 180mA ?! */ 732 .ext_current_ctl = 12, 733 734 /* 0.85V */ 735 .ldmos_bias_ctl = 1, 736 737 /* 100 Ohm */ 738 .term_ctl = 1, 739 740 /* Enable External Current Source */ 741 .ext_current_src_en = 1, 742 743 /* Enable Internal Current Source */ 744 .int_current_src_en = 1, 745 }, 746 { 747 /* 200mA and 180mA ?! */ 748 .ext_current_ctl = 12, 749 750 /* 0.85V */ 751 .ldmos_bias_ctl = 1, 752 753 /* 100 Ohm */ 754 .term_ctl = 1, 755 756 /* Enable External Current Source */ 757 .ext_current_src_en = 1, 758 759 /* Enable Internal Current Source */ 760 .int_current_src_en = 1, 761 }, 762 { 763 /* 200mA and 180mA ?! */ 764 .ext_current_ctl = 12, 765 766 /* 0.85V */ 767 .ldmos_bias_ctl = 1, 768 769 /* 100 Ohm */ 770 .term_ctl = 1, 771 772 /* Enable External Current Source */ 773 .ext_current_src_en = 1, 774 775 /* Enable Internal Current Source */ 776 .int_current_src_en = 1, 777 }, 778 }, 779 { 780 /* 200mA and 180mA ?! */ 781 .ext_current_ctl = 12, 782 783 /* 0.85V */ 784 .ldmos_bias_ctl = 1, 785 786 /* 100 Ohm */ 787 .term_ctl = 1, 788 789 /* Enable External Current Source */ 790 .ext_current_src_en = 1, 791 792 /* Enable Internal Current Source */ 793 .int_current_src_en = 1, 794 795 /* Internal Current Source Half Swing Enable*/ 796 .int_current_src_hs_en = 1, 797 }, 798 }, 799 { 800 297000001, 597000044, 801 { 802 { 803 /* 200mA */ 804 .ext_current_ctl = 8, 805 806 /* Normal Slew Rate Control */ 807 .slew_rate_ctl = 1, 808 809 /* 0.85V */ 810 .ldmos_bias_ctl = 1, 811 812 /* 50 Ohms */ 813 .term_ctl = 3, 814 815 /* Enable External Current Source */ 816 .ext_current_src_en = 1, 817 818 /* Enable Internal Current Source */ 819 .int_current_src_en = 1, 820 821 /* 200mA */ 822 .int_current_ctl = 8, 823 824 /* 17.6 mA */ 825 .main_tap_current_select = 7, 826 }, 827 { 828 /* 200mA */ 829 .ext_current_ctl = 8, 830 831 /* Normal Slew Rate Control */ 832 .slew_rate_ctl = 1, 833 834 /* 0.85V */ 835 .ldmos_bias_ctl = 1, 836 837 /* 50 Ohms */ 838 .term_ctl = 3, 839 840 /* Enable External Current Source */ 841 .ext_current_src_en = 1, 842 843 /* Enable Internal Current Source */ 844 .int_current_src_en = 1, 845 846 /* 200mA */ 847 .int_current_ctl = 8, 848 849 /* 17.6 mA */ 850 .main_tap_current_select = 7, 851 }, 852 { 853 /* 200mA */ 854 .ext_current_ctl = 8, 855 856 /* Normal Slew Rate Control */ 857 .slew_rate_ctl = 1, 858 859 /* 0.85V */ 860 .ldmos_bias_ctl = 1, 861 862 /* 50 Ohms */ 863 .term_ctl = 3, 864 865 /* Enable External Current Source */ 866 .ext_current_src_en = 1, 867 868 /* Enable Internal Current Source */ 869 .int_current_src_en = 1, 870 871 /* 200mA */ 872 .int_current_ctl = 8, 873 874 /* 17.6 mA */ 875 .main_tap_current_select = 7, 876 }, 877 }, 878 { 879 /* 200mA */ 880 .ext_current_ctl = 8, 881 882 /* Normal Slew Rate Control */ 883 .slew_rate_ctl = 1, 884 885 /* 0.85V */ 886 .ldmos_bias_ctl = 1, 887 888 /* External Current Source Half Swing Enable*/ 889 .ext_current_src_hs_en = 1, 890 891 /* 50 Ohms */ 892 .term_ctl = 3, 893 894 /* Enable External Current Source */ 895 .ext_current_src_en = 1, 896 897 /* Enable Internal Current Source */ 898 .int_current_src_en = 1, 899 900 /* 200mA */ 901 .int_current_ctl = 8, 902 903 /* Internal Current Source Half Swing Enable*/ 904 .int_current_src_hs_en = 1, 905 906 /* 17.6 mA */ 907 .main_tap_current_select = 7, 908 }, 909 }, 910 }; 911 912 static const struct vc6_phy_settings * 913 vc6_phy_get_settings(unsigned long long tmds_rate) 914 { 915 unsigned int count = ARRAY_SIZE(vc6_hdmi_phy_settings); 916 unsigned int i; 917 918 for (i = 0; i < count; i++) { 919 const struct vc6_phy_settings *s = &vc6_hdmi_phy_settings[i]; 920 921 if (tmds_rate >= s->min_rate && tmds_rate <= s->max_rate) 922 return s; 923 } 924 925 /* 926 * If the pixel clock exceeds our max setting, try the max 927 * setting anyway. 928 */ 929 return &vc6_hdmi_phy_settings[count - 1]; 930 } 931 932 static const struct vc6_phy_lane_settings * 933 vc6_phy_get_channel_settings(enum vc4_hdmi_phy_channel chan, 934 unsigned long long tmds_rate) 935 { 936 const struct vc6_phy_settings *settings = vc6_phy_get_settings(tmds_rate); 937 938 if (chan == PHY_LANE_CK) 939 return &settings->clock; 940 941 return &settings->channel[chan]; 942 } 943 944 static void vc6_hdmi_reset_phy(struct vc4_hdmi *vc4_hdmi) 945 { 946 lockdep_assert_held(&vc4_hdmi->hw_lock); 947 948 HDMI_WRITE(HDMI_TX_PHY_RESET_CTL, 0); 949 HDMI_WRITE(HDMI_TX_PHY_POWERUP_CTL, 0); 950 } 951 952 void vc6_hdmi_phy_init(struct vc4_hdmi *vc4_hdmi, 953 struct drm_connector_state *conn_state) 954 { 955 const struct vc6_phy_lane_settings *chan0_settings; 956 const struct vc6_phy_lane_settings *chan1_settings; 957 const struct vc6_phy_lane_settings *chan2_settings; 958 const struct vc6_phy_lane_settings *clock_settings; 959 const struct vc4_hdmi_variant *variant = vc4_hdmi->variant; 960 unsigned long long pixel_freq = conn_state->hdmi.tmds_char_rate; 961 unsigned long long vco_freq; 962 unsigned char word_sel; 963 unsigned long flags; 964 unsigned int vco_div; 965 966 vco_freq = vc6_phy_get_vco_freq(pixel_freq, &vco_div); 967 968 spin_lock_irqsave(&vc4_hdmi->hw_lock, flags); 969 970 vc6_hdmi_reset_phy(vc4_hdmi); 971 972 HDMI_WRITE(HDMI_TX_PHY_PLL_MISC_0, 0x810c6000); 973 HDMI_WRITE(HDMI_TX_PHY_PLL_MISC_1, 0x00b8c451); 974 HDMI_WRITE(HDMI_TX_PHY_PLL_MISC_2, 0x46402e31); 975 HDMI_WRITE(HDMI_TX_PHY_PLL_MISC_3, 0x00b8c005); 976 HDMI_WRITE(HDMI_TX_PHY_PLL_MISC_4, 0x42410261); 977 HDMI_WRITE(HDMI_TX_PHY_PLL_MISC_5, 0xcc021001); 978 HDMI_WRITE(HDMI_TX_PHY_PLL_MISC_6, 0xc8301c80); 979 HDMI_WRITE(HDMI_TX_PHY_PLL_MISC_7, 0xb0804444); 980 HDMI_WRITE(HDMI_TX_PHY_PLL_MISC_8, 0xf80f8000); 981 982 HDMI_WRITE(HDMI_TX_PHY_PLL_REFCLK, 983 VC6_HDMI_TX_PHY_PLL_REFCLK_REFCLK_SEL_CMOS | 984 VC4_SET_FIELD(54, VC6_HDMI_TX_PHY_PLL_REFCLK_REFFRQ)); 985 986 HDMI_WRITE(HDMI_TX_PHY_RESET_CTL, 0x7f); 987 988 HDMI_WRITE(HDMI_RM_OFFSET, 989 VC4_HDMI_RM_OFFSET_ONLY | 990 VC4_SET_FIELD(phy_get_rm_offset(vco_freq), 991 VC4_HDMI_RM_OFFSET_OFFSET)); 992 993 HDMI_WRITE(HDMI_TX_PHY_PLL_VCOCLK_DIV, 994 VC6_HDMI_TX_PHY_PLL_VCOCLK_DIV_VCODIV_EN | 995 VC4_SET_FIELD(vco_div, 996 VC6_HDMI_TX_PHY_PLL_VCOCLK_DIV_VCODIV)); 997 998 HDMI_WRITE(HDMI_TX_PHY_PLL_CFG, 999 VC4_SET_FIELD(0, VC4_HDMI_TX_PHY_PLL_CFG_PDIV)); 1000 1001 HDMI_WRITE(HDMI_TX_PHY_PLL_POST_KDIV, 1002 VC4_SET_FIELD(2, VC6_HDMI_TX_PHY_PLL_POST_KDIV_CLK0_SEL) | 1003 VC4_SET_FIELD(1, VC6_HDMI_TX_PHY_PLL_POST_KDIV_KDIV)); 1004 1005 chan0_settings = 1006 vc6_phy_get_channel_settings(variant->phy_lane_mapping[PHY_LANE_0], 1007 pixel_freq); 1008 HDMI_WRITE(HDMI_TX_PHY_CTL_0, 1009 VC4_SET_FIELD(chan0_settings->ext_current_ctl, 1010 VC6_HDMI_TX_PHY_HDMI_CTRL_CHX_EXT_CURRENT_CTL) | 1011 VC4_SET_FIELD(chan0_settings->ffe_enable, 1012 VC6_HDMI_TX_PHY_HDMI_CTRL_CHX_FFE_ENABLE) | 1013 VC4_SET_FIELD(chan0_settings->slew_rate_ctl, 1014 VC6_HDMI_TX_PHY_HDMI_CTRL_CHX_SLEW_RATE_CTL) | 1015 VC4_SET_FIELD(chan0_settings->ffe_post_tap_en, 1016 VC6_HDMI_TX_PHY_HDMI_CTRL_CHX_FFE_POST_TAP_EN) | 1017 VC4_SET_FIELD(chan0_settings->ldmos_bias_ctl, 1018 VC6_HDMI_TX_PHY_HDMI_CTRL_CHX_LDMOS_BIAS_CTL) | 1019 VC4_SET_FIELD(chan0_settings->com_mode_ldmos_en, 1020 VC6_HDMI_TX_PHY_HDMI_CTRL_CHX_COM_MODE_LDMOS_EN) | 1021 VC4_SET_FIELD(chan0_settings->edge_sel, 1022 VC6_HDMI_TX_PHY_HDMI_CTRL_CHX_EDGE_SEL) | 1023 VC4_SET_FIELD(chan0_settings->ext_current_src_hs_en, 1024 VC6_HDMI_TX_PHY_HDMI_CTRL_CHX_EXT_CURRENT_SRC_HS_EN) | 1025 VC4_SET_FIELD(chan0_settings->term_ctl, 1026 VC6_HDMI_TX_PHY_HDMI_CTRL_CHX_TERM_CTL) | 1027 VC4_SET_FIELD(chan0_settings->ext_current_src_en, 1028 VC6_HDMI_TX_PHY_HDMI_CTRL_CHX_EXT_CURRENT_SRC_EN) | 1029 VC4_SET_FIELD(chan0_settings->int_current_src_en, 1030 VC6_HDMI_TX_PHY_HDMI_CTRL_CHX_INT_CURRENT_SRC_EN) | 1031 VC4_SET_FIELD(chan0_settings->int_current_ctl, 1032 VC6_HDMI_TX_PHY_HDMI_CTRL_CHX_INT_CURRENT_CTL) | 1033 VC4_SET_FIELD(chan0_settings->int_current_src_hs_en, 1034 VC6_HDMI_TX_PHY_HDMI_CTRL_CHX_INT_CURRENT_SRC_HS_EN) | 1035 VC4_SET_FIELD(chan0_settings->main_tap_current_select, 1036 VC6_HDMI_TX_PHY_HDMI_CTRL_CHX_MAIN_TAP_CURRENT_SELECT) | 1037 VC4_SET_FIELD(chan0_settings->post_tap_current_select, 1038 VC6_HDMI_TX_PHY_HDMI_CTRL_CHX_POST_TAP_CURRENT_SELECT) | 1039 VC4_SET_FIELD(chan0_settings->slew_ctl_slow_loading, 1040 VC6_HDMI_TX_PHY_HDMI_CTRL_CHX_SLEW_CTL_SLOW_LOADING) | 1041 VC4_SET_FIELD(chan0_settings->slew_ctl_slow_driving, 1042 VC6_HDMI_TX_PHY_HDMI_CTRL_CHX_SLEW_CTL_SLOW_DRIVING) | 1043 VC4_SET_FIELD(chan0_settings->ffe_pre_tap_en, 1044 VC6_HDMI_TX_PHY_HDMI_CTRL_CHX_FFE_PRE_TAP_EN)); 1045 1046 chan1_settings = 1047 vc6_phy_get_channel_settings(variant->phy_lane_mapping[PHY_LANE_1], 1048 pixel_freq); 1049 HDMI_WRITE(HDMI_TX_PHY_CTL_1, 1050 VC4_SET_FIELD(chan1_settings->ext_current_ctl, 1051 VC6_HDMI_TX_PHY_HDMI_CTRL_CHX_EXT_CURRENT_CTL) | 1052 VC4_SET_FIELD(chan1_settings->ffe_enable, 1053 VC6_HDMI_TX_PHY_HDMI_CTRL_CHX_FFE_ENABLE) | 1054 VC4_SET_FIELD(chan1_settings->slew_rate_ctl, 1055 VC6_HDMI_TX_PHY_HDMI_CTRL_CHX_SLEW_RATE_CTL) | 1056 VC4_SET_FIELD(chan1_settings->ffe_post_tap_en, 1057 VC6_HDMI_TX_PHY_HDMI_CTRL_CHX_FFE_POST_TAP_EN) | 1058 VC4_SET_FIELD(chan1_settings->ldmos_bias_ctl, 1059 VC6_HDMI_TX_PHY_HDMI_CTRL_CHX_LDMOS_BIAS_CTL) | 1060 VC4_SET_FIELD(chan1_settings->com_mode_ldmos_en, 1061 VC6_HDMI_TX_PHY_HDMI_CTRL_CHX_COM_MODE_LDMOS_EN) | 1062 VC4_SET_FIELD(chan1_settings->edge_sel, 1063 VC6_HDMI_TX_PHY_HDMI_CTRL_CHX_EDGE_SEL) | 1064 VC4_SET_FIELD(chan1_settings->ext_current_src_hs_en, 1065 VC6_HDMI_TX_PHY_HDMI_CTRL_CHX_EXT_CURRENT_SRC_HS_EN) | 1066 VC4_SET_FIELD(chan1_settings->term_ctl, 1067 VC6_HDMI_TX_PHY_HDMI_CTRL_CHX_TERM_CTL) | 1068 VC4_SET_FIELD(chan1_settings->ext_current_src_en, 1069 VC6_HDMI_TX_PHY_HDMI_CTRL_CHX_EXT_CURRENT_SRC_EN) | 1070 VC4_SET_FIELD(chan1_settings->int_current_src_en, 1071 VC6_HDMI_TX_PHY_HDMI_CTRL_CHX_INT_CURRENT_SRC_EN) | 1072 VC4_SET_FIELD(chan1_settings->int_current_ctl, 1073 VC6_HDMI_TX_PHY_HDMI_CTRL_CHX_INT_CURRENT_CTL) | 1074 VC4_SET_FIELD(chan1_settings->int_current_src_hs_en, 1075 VC6_HDMI_TX_PHY_HDMI_CTRL_CHX_INT_CURRENT_SRC_HS_EN) | 1076 VC4_SET_FIELD(chan1_settings->main_tap_current_select, 1077 VC6_HDMI_TX_PHY_HDMI_CTRL_CHX_MAIN_TAP_CURRENT_SELECT) | 1078 VC4_SET_FIELD(chan1_settings->post_tap_current_select, 1079 VC6_HDMI_TX_PHY_HDMI_CTRL_CHX_POST_TAP_CURRENT_SELECT) | 1080 VC4_SET_FIELD(chan1_settings->slew_ctl_slow_loading, 1081 VC6_HDMI_TX_PHY_HDMI_CTRL_CHX_SLEW_CTL_SLOW_LOADING) | 1082 VC4_SET_FIELD(chan1_settings->slew_ctl_slow_driving, 1083 VC6_HDMI_TX_PHY_HDMI_CTRL_CHX_SLEW_CTL_SLOW_DRIVING) | 1084 VC4_SET_FIELD(chan1_settings->ffe_pre_tap_en, 1085 VC6_HDMI_TX_PHY_HDMI_CTRL_CHX_FFE_PRE_TAP_EN)); 1086 1087 chan2_settings = 1088 vc6_phy_get_channel_settings(variant->phy_lane_mapping[PHY_LANE_2], 1089 pixel_freq); 1090 HDMI_WRITE(HDMI_TX_PHY_CTL_2, 1091 VC4_SET_FIELD(chan2_settings->ext_current_ctl, 1092 VC6_HDMI_TX_PHY_HDMI_CTRL_CHX_EXT_CURRENT_CTL) | 1093 VC4_SET_FIELD(chan2_settings->ffe_enable, 1094 VC6_HDMI_TX_PHY_HDMI_CTRL_CHX_FFE_ENABLE) | 1095 VC4_SET_FIELD(chan2_settings->slew_rate_ctl, 1096 VC6_HDMI_TX_PHY_HDMI_CTRL_CHX_SLEW_RATE_CTL) | 1097 VC4_SET_FIELD(chan2_settings->ffe_post_tap_en, 1098 VC6_HDMI_TX_PHY_HDMI_CTRL_CHX_FFE_POST_TAP_EN) | 1099 VC4_SET_FIELD(chan2_settings->ldmos_bias_ctl, 1100 VC6_HDMI_TX_PHY_HDMI_CTRL_CHX_LDMOS_BIAS_CTL) | 1101 VC4_SET_FIELD(chan2_settings->com_mode_ldmos_en, 1102 VC6_HDMI_TX_PHY_HDMI_CTRL_CHX_COM_MODE_LDMOS_EN) | 1103 VC4_SET_FIELD(chan2_settings->edge_sel, 1104 VC6_HDMI_TX_PHY_HDMI_CTRL_CHX_EDGE_SEL) | 1105 VC4_SET_FIELD(chan2_settings->ext_current_src_hs_en, 1106 VC6_HDMI_TX_PHY_HDMI_CTRL_CHX_EXT_CURRENT_SRC_HS_EN) | 1107 VC4_SET_FIELD(chan2_settings->term_ctl, 1108 VC6_HDMI_TX_PHY_HDMI_CTRL_CHX_TERM_CTL) | 1109 VC4_SET_FIELD(chan2_settings->ext_current_src_en, 1110 VC6_HDMI_TX_PHY_HDMI_CTRL_CHX_EXT_CURRENT_SRC_EN) | 1111 VC4_SET_FIELD(chan2_settings->int_current_src_en, 1112 VC6_HDMI_TX_PHY_HDMI_CTRL_CHX_INT_CURRENT_SRC_EN) | 1113 VC4_SET_FIELD(chan2_settings->int_current_ctl, 1114 VC6_HDMI_TX_PHY_HDMI_CTRL_CHX_INT_CURRENT_CTL) | 1115 VC4_SET_FIELD(chan2_settings->int_current_src_hs_en, 1116 VC6_HDMI_TX_PHY_HDMI_CTRL_CHX_INT_CURRENT_SRC_HS_EN) | 1117 VC4_SET_FIELD(chan2_settings->main_tap_current_select, 1118 VC6_HDMI_TX_PHY_HDMI_CTRL_CHX_MAIN_TAP_CURRENT_SELECT) | 1119 VC4_SET_FIELD(chan2_settings->post_tap_current_select, 1120 VC6_HDMI_TX_PHY_HDMI_CTRL_CHX_POST_TAP_CURRENT_SELECT) | 1121 VC4_SET_FIELD(chan2_settings->slew_ctl_slow_loading, 1122 VC6_HDMI_TX_PHY_HDMI_CTRL_CHX_SLEW_CTL_SLOW_LOADING) | 1123 VC4_SET_FIELD(chan2_settings->slew_ctl_slow_driving, 1124 VC6_HDMI_TX_PHY_HDMI_CTRL_CHX_SLEW_CTL_SLOW_DRIVING) | 1125 VC4_SET_FIELD(chan2_settings->ffe_pre_tap_en, 1126 VC6_HDMI_TX_PHY_HDMI_CTRL_CHX_FFE_PRE_TAP_EN)); 1127 1128 clock_settings = 1129 vc6_phy_get_channel_settings(variant->phy_lane_mapping[PHY_LANE_CK], 1130 pixel_freq); 1131 HDMI_WRITE(HDMI_TX_PHY_CTL_CK, 1132 VC4_SET_FIELD(clock_settings->ext_current_ctl, 1133 VC6_HDMI_TX_PHY_HDMI_CTRL_CHX_EXT_CURRENT_CTL) | 1134 VC4_SET_FIELD(clock_settings->ffe_enable, 1135 VC6_HDMI_TX_PHY_HDMI_CTRL_CHX_FFE_ENABLE) | 1136 VC4_SET_FIELD(clock_settings->slew_rate_ctl, 1137 VC6_HDMI_TX_PHY_HDMI_CTRL_CHX_SLEW_RATE_CTL) | 1138 VC4_SET_FIELD(clock_settings->ffe_post_tap_en, 1139 VC6_HDMI_TX_PHY_HDMI_CTRL_CHX_FFE_POST_TAP_EN) | 1140 VC4_SET_FIELD(clock_settings->ldmos_bias_ctl, 1141 VC6_HDMI_TX_PHY_HDMI_CTRL_CHX_LDMOS_BIAS_CTL) | 1142 VC4_SET_FIELD(clock_settings->com_mode_ldmos_en, 1143 VC6_HDMI_TX_PHY_HDMI_CTRL_CHX_COM_MODE_LDMOS_EN) | 1144 VC4_SET_FIELD(clock_settings->edge_sel, 1145 VC6_HDMI_TX_PHY_HDMI_CTRL_CHX_EDGE_SEL) | 1146 VC4_SET_FIELD(clock_settings->ext_current_src_hs_en, 1147 VC6_HDMI_TX_PHY_HDMI_CTRL_CHX_EXT_CURRENT_SRC_HS_EN) | 1148 VC4_SET_FIELD(clock_settings->term_ctl, 1149 VC6_HDMI_TX_PHY_HDMI_CTRL_CHX_TERM_CTL) | 1150 VC4_SET_FIELD(clock_settings->ext_current_src_en, 1151 VC6_HDMI_TX_PHY_HDMI_CTRL_CHX_EXT_CURRENT_SRC_EN) | 1152 VC4_SET_FIELD(clock_settings->int_current_src_en, 1153 VC6_HDMI_TX_PHY_HDMI_CTRL_CHX_INT_CURRENT_SRC_EN) | 1154 VC4_SET_FIELD(clock_settings->int_current_ctl, 1155 VC6_HDMI_TX_PHY_HDMI_CTRL_CHX_INT_CURRENT_CTL) | 1156 VC4_SET_FIELD(clock_settings->int_current_src_hs_en, 1157 VC6_HDMI_TX_PHY_HDMI_CTRL_CHX_INT_CURRENT_SRC_HS_EN) | 1158 VC4_SET_FIELD(clock_settings->main_tap_current_select, 1159 VC6_HDMI_TX_PHY_HDMI_CTRL_CHX_MAIN_TAP_CURRENT_SELECT) | 1160 VC4_SET_FIELD(clock_settings->post_tap_current_select, 1161 VC6_HDMI_TX_PHY_HDMI_CTRL_CHX_POST_TAP_CURRENT_SELECT) | 1162 VC4_SET_FIELD(clock_settings->slew_ctl_slow_loading, 1163 VC6_HDMI_TX_PHY_HDMI_CTRL_CHX_SLEW_CTL_SLOW_LOADING) | 1164 VC4_SET_FIELD(clock_settings->slew_ctl_slow_driving, 1165 VC6_HDMI_TX_PHY_HDMI_CTRL_CHX_SLEW_CTL_SLOW_DRIVING) | 1166 VC4_SET_FIELD(clock_settings->ffe_pre_tap_en, 1167 VC6_HDMI_TX_PHY_HDMI_CTRL_CHX_FFE_PRE_TAP_EN)); 1168 1169 if (pixel_freq >= 340000000) 1170 word_sel = 3; 1171 else 1172 word_sel = 0; 1173 HDMI_WRITE(HDMI_TX_PHY_TMDS_CLK_WORD_SEL, word_sel); 1174 1175 HDMI_WRITE(HDMI_TX_PHY_POWERUP_CTL, 1176 VC6_HDMI_TX_PHY_HDMI_POWERUP_CTL_BG_PWRUP | 1177 VC6_HDMI_TX_PHY_HDMI_POWERUP_CTL_LDO_PWRUP | 1178 VC6_HDMI_TX_PHY_HDMI_POWERUP_CTL_BIAS_PWRUP | 1179 VC6_HDMI_TX_PHY_HDMI_POWERUP_CTL_TX_CK_PWRUP | 1180 VC6_HDMI_TX_PHY_HDMI_POWERUP_CTL_TX_2_PWRUP | 1181 VC6_HDMI_TX_PHY_HDMI_POWERUP_CTL_TX_1_PWRUP | 1182 VC6_HDMI_TX_PHY_HDMI_POWERUP_CTL_TX_0_PWRUP); 1183 1184 HDMI_WRITE(HDMI_TX_PHY_PLL_POWERUP_CTL, 1185 VC6_HDMI_TX_PHY_PLL_POWERUP_CTL_PLL_PWRUP); 1186 1187 HDMI_WRITE(HDMI_TX_PHY_PLL_RESET_CTL, 1188 HDMI_READ(HDMI_TX_PHY_PLL_RESET_CTL) & 1189 ~VC6_HDMI_TX_PHY_PLL_RESET_CTL_PLL_RESETB); 1190 1191 HDMI_WRITE(HDMI_TX_PHY_PLL_RESET_CTL, 1192 HDMI_READ(HDMI_TX_PHY_PLL_RESET_CTL) | 1193 VC6_HDMI_TX_PHY_PLL_RESET_CTL_PLL_RESETB); 1194 1195 spin_unlock_irqrestore(&vc4_hdmi->hw_lock, flags); 1196 } 1197 1198 void vc6_hdmi_phy_disable(struct vc4_hdmi *vc4_hdmi) 1199 { 1200 } 1201