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

Configure Feed

Select the types of activity you want to include in your feed.

at v6.14-rc4 1200 lines 38 kB view raw
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 172void 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 189void 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 198void 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 209void 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 220static unsigned long long 221phy_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 241static u8 phy_get_cp_current(unsigned long vco_freq) 242{ 243 if (vco_freq < 3700000000ULL) 244 return 0x1c; 245 246 return 0x18; 247} 248 249static 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 263static 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 283struct 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 293struct 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 300static 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 366static 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 385static const struct phy_lane_settings * 386phy_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 397static 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 405void 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 573void 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 582void 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 593void 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 607static unsigned long long 608vc6_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 629struct 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 650struct 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 657static 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 912static const struct vc6_phy_settings * 913vc6_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 932static const struct vc6_phy_lane_settings * 933vc6_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 944static 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 952void 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 1198void vc6_hdmi_phy_disable(struct vc4_hdmi *vc4_hdmi) 1199{ 1200}