0001
0002
0003
0004
0005
0006
0007
0008
0009 #include "vc4_hdmi.h"
0010 #include "vc4_regs.h"
0011 #include "vc4_hdmi_regs.h"
0012
0013 #define VC4_HDMI_TX_PHY_RESET_CTL_PLL_RESETB BIT(5)
0014 #define VC4_HDMI_TX_PHY_RESET_CTL_PLLDIV_RESETB BIT(4)
0015 #define VC4_HDMI_TX_PHY_RESET_CTL_TX_CK_RESET BIT(3)
0016 #define VC4_HDMI_TX_PHY_RESET_CTL_TX_2_RESET BIT(2)
0017 #define VC4_HDMI_TX_PHY_RESET_CTL_TX_1_RESET BIT(1)
0018 #define VC4_HDMI_TX_PHY_RESET_CTL_TX_0_RESET BIT(0)
0019
0020 #define VC4_HDMI_TX_PHY_POWERDOWN_CTL_RNDGEN_PWRDN BIT(4)
0021
0022 #define VC4_HDMI_TX_PHY_CTL_0_PREEMP_2_PREEMP_SHIFT 29
0023 #define VC4_HDMI_TX_PHY_CTL_0_PREEMP_2_PREEMP_MASK VC4_MASK(31, 29)
0024 #define VC4_HDMI_TX_PHY_CTL_0_PREEMP_2_MAINDRV_SHIFT 24
0025 #define VC4_HDMI_TX_PHY_CTL_0_PREEMP_2_MAINDRV_MASK VC4_MASK(28, 24)
0026 #define VC4_HDMI_TX_PHY_CTL_0_PREEMP_1_PREEMP_SHIFT 21
0027 #define VC4_HDMI_TX_PHY_CTL_0_PREEMP_1_PREEMP_MASK VC4_MASK(23, 21)
0028 #define VC4_HDMI_TX_PHY_CTL_0_PREEMP_1_MAINDRV_SHIFT 16
0029 #define VC4_HDMI_TX_PHY_CTL_0_PREEMP_1_MAINDRV_MASK VC4_MASK(20, 16)
0030 #define VC4_HDMI_TX_PHY_CTL_0_PREEMP_0_PREEMP_SHIFT 13
0031 #define VC4_HDMI_TX_PHY_CTL_0_PREEMP_0_PREEMP_MASK VC4_MASK(15, 13)
0032 #define VC4_HDMI_TX_PHY_CTL_0_PREEMP_0_MAINDRV_SHIFT 8
0033 #define VC4_HDMI_TX_PHY_CTL_0_PREEMP_0_MAINDRV_MASK VC4_MASK(12, 8)
0034 #define VC4_HDMI_TX_PHY_CTL_0_PREEMP_CK_PREEMP_SHIFT 5
0035 #define VC4_HDMI_TX_PHY_CTL_0_PREEMP_CK_PREEMP_MASK VC4_MASK(7, 5)
0036 #define VC4_HDMI_TX_PHY_CTL_0_PREEMP_CK_MAINDRV_SHIFT 0
0037 #define VC4_HDMI_TX_PHY_CTL_0_PREEMP_CK_MAINDRV_MASK VC4_MASK(4, 0)
0038
0039 #define VC4_HDMI_TX_PHY_CTL_1_RES_SEL_DATA2_SHIFT 15
0040 #define VC4_HDMI_TX_PHY_CTL_1_RES_SEL_DATA2_MASK VC4_MASK(19, 15)
0041 #define VC4_HDMI_TX_PHY_CTL_1_RES_SEL_DATA1_SHIFT 10
0042 #define VC4_HDMI_TX_PHY_CTL_1_RES_SEL_DATA1_MASK VC4_MASK(14, 10)
0043 #define VC4_HDMI_TX_PHY_CTL_1_RES_SEL_DATA0_SHIFT 5
0044 #define VC4_HDMI_TX_PHY_CTL_1_RES_SEL_DATA0_MASK VC4_MASK(9, 5)
0045 #define VC4_HDMI_TX_PHY_CTL_1_RES_SEL_CK_SHIFT 0
0046 #define VC4_HDMI_TX_PHY_CTL_1_RES_SEL_CK_MASK VC4_MASK(4, 0)
0047
0048 #define VC4_HDMI_TX_PHY_CTL_2_VCO_GAIN_SHIFT 16
0049 #define VC4_HDMI_TX_PHY_CTL_2_VCO_GAIN_MASK VC4_MASK(19, 16)
0050 #define VC4_HDMI_TX_PHY_CTL_2_TERM_RES_SELDATA2_SHIFT 12
0051 #define VC4_HDMI_TX_PHY_CTL_2_TERM_RES_SELDATA2_MASK VC4_MASK(15, 12)
0052 #define VC4_HDMI_TX_PHY_CTL_2_TERM_RES_SELDATA1_SHIFT 8
0053 #define VC4_HDMI_TX_PHY_CTL_2_TERM_RES_SELDATA1_MASK VC4_MASK(11, 8)
0054 #define VC4_HDMI_TX_PHY_CTL_2_TERM_RES_SELDATA0_SHIFT 4
0055 #define VC4_HDMI_TX_PHY_CTL_2_TERM_RES_SELDATA0_MASK VC4_MASK(7, 4)
0056 #define VC4_HDMI_TX_PHY_CTL_2_TERM_RES_SELCK_SHIFT 0
0057 #define VC4_HDMI_TX_PHY_CTL_2_TERM_RES_SELCK_MASK VC4_MASK(3, 0)
0058
0059 #define VC4_HDMI_TX_PHY_CTL_3_RP_SHIFT 17
0060 #define VC4_HDMI_TX_PHY_CTL_3_RP_MASK VC4_MASK(19, 17)
0061 #define VC4_HDMI_TX_PHY_CTL_3_RZ_SHIFT 12
0062 #define VC4_HDMI_TX_PHY_CTL_3_RZ_MASK VC4_MASK(16, 12)
0063 #define VC4_HDMI_TX_PHY_CTL_3_CP1_SHIFT 10
0064 #define VC4_HDMI_TX_PHY_CTL_3_CP1_MASK VC4_MASK(11, 10)
0065 #define VC4_HDMI_TX_PHY_CTL_3_CP_SHIFT 8
0066 #define VC4_HDMI_TX_PHY_CTL_3_CP_MASK VC4_MASK(9, 8)
0067 #define VC4_HDMI_TX_PHY_CTL_3_CZ_SHIFT 6
0068 #define VC4_HDMI_TX_PHY_CTL_3_CZ_MASK VC4_MASK(7, 6)
0069 #define VC4_HDMI_TX_PHY_CTL_3_ICP_SHIFT 0
0070 #define VC4_HDMI_TX_PHY_CTL_3_ICP_MASK VC4_MASK(5, 0)
0071
0072 #define VC4_HDMI_TX_PHY_PLL_CTL_0_MASH11_MODE BIT(13)
0073 #define VC4_HDMI_TX_PHY_PLL_CTL_0_VC_RANGE_EN BIT(12)
0074 #define VC4_HDMI_TX_PHY_PLL_CTL_0_EMULATE_VC_LOW BIT(11)
0075 #define VC4_HDMI_TX_PHY_PLL_CTL_0_EMULATE_VC_HIGH BIT(10)
0076 #define VC4_HDMI_TX_PHY_PLL_CTL_0_VCO_SEL_SHIFT 9
0077 #define VC4_HDMI_TX_PHY_PLL_CTL_0_VCO_SEL_MASK VC4_MASK(9, 9)
0078 #define VC4_HDMI_TX_PHY_PLL_CTL_0_VCO_FB_DIV2 BIT(8)
0079 #define VC4_HDMI_TX_PHY_PLL_CTL_0_VCO_POST_DIV2 BIT(7)
0080 #define VC4_HDMI_TX_PHY_PLL_CTL_0_VCO_CONT_EN BIT(6)
0081 #define VC4_HDMI_TX_PHY_PLL_CTL_0_ENA_VCO_CLK BIT(5)
0082
0083 #define VC4_HDMI_TX_PHY_PLL_CTL_1_CPP_SHIFT 16
0084 #define VC4_HDMI_TX_PHY_PLL_CTL_1_CPP_MASK VC4_MASK(27, 16)
0085 #define VC4_HDMI_TX_PHY_PLL_CTL_1_FREQ_DOUBLER_DELAY_SHIFT 14
0086 #define VC4_HDMI_TX_PHY_PLL_CTL_1_FREQ_DOUBLER_DELAY_MASK VC4_MASK(15, 14)
0087 #define VC4_HDMI_TX_PHY_PLL_CTL_1_FREQ_DOUBLER_ENABLE BIT(13)
0088 #define VC4_HDMI_TX_PHY_PLL_CTL_1_POST_RST_SEL_SHIFT 11
0089 #define VC4_HDMI_TX_PHY_PLL_CTL_1_POST_RST_SEL_MASK VC4_MASK(12, 11)
0090
0091 #define VC4_HDMI_TX_PHY_CLK_DIV_VCO_SHIFT 8
0092 #define VC4_HDMI_TX_PHY_CLK_DIV_VCO_MASK VC4_MASK(15, 8)
0093
0094 #define VC4_HDMI_TX_PHY_PLL_CFG_PDIV_SHIFT 0
0095 #define VC4_HDMI_TX_PHY_PLL_CFG_PDIV_MASK VC4_MASK(3, 0)
0096
0097 #define VC4_HDMI_TX_PHY_CHANNEL_SWAP_TXCK_OUT_SEL_MASK VC4_MASK(13, 12)
0098 #define VC4_HDMI_TX_PHY_CHANNEL_SWAP_TXCK_OUT_SEL_SHIFT 12
0099 #define VC4_HDMI_TX_PHY_CHANNEL_SWAP_TX2_OUT_SEL_MASK VC4_MASK(9, 8)
0100 #define VC4_HDMI_TX_PHY_CHANNEL_SWAP_TX2_OUT_SEL_SHIFT 8
0101 #define VC4_HDMI_TX_PHY_CHANNEL_SWAP_TX1_OUT_SEL_MASK VC4_MASK(5, 4)
0102 #define VC4_HDMI_TX_PHY_CHANNEL_SWAP_TX1_OUT_SEL_SHIFT 4
0103 #define VC4_HDMI_TX_PHY_CHANNEL_SWAP_TX0_OUT_SEL_MASK VC4_MASK(1, 0)
0104 #define VC4_HDMI_TX_PHY_CHANNEL_SWAP_TX0_OUT_SEL_SHIFT 0
0105
0106 #define VC4_HDMI_TX_PHY_PLL_CALIBRATION_CONFIG_1_MIN_LIMIT_MASK VC4_MASK(27, 0)
0107 #define VC4_HDMI_TX_PHY_PLL_CALIBRATION_CONFIG_1_MIN_LIMIT_SHIFT 0
0108
0109 #define VC4_HDMI_TX_PHY_PLL_CALIBRATION_CONFIG_2_MAX_LIMIT_MASK VC4_MASK(27, 0)
0110 #define VC4_HDMI_TX_PHY_PLL_CALIBRATION_CONFIG_2_MAX_LIMIT_SHIFT 0
0111
0112 #define VC4_HDMI_TX_PHY_PLL_CALIBRATION_CONFIG_4_STABLE_THRESHOLD_MASK VC4_MASK(31, 16)
0113 #define VC4_HDMI_TX_PHY_PLL_CALIBRATION_CONFIG_4_STABLE_THRESHOLD_SHIFT 16
0114 #define VC4_HDMI_TX_PHY_PLL_CALIBRATION_CONFIG_4_HOLD_THRESHOLD_MASK VC4_MASK(15, 0)
0115 #define VC4_HDMI_TX_PHY_PLL_CALIBRATION_CONFIG_4_HOLD_THRESHOLD_SHIFT 0
0116
0117 #define VC4_HDMI_RM_CONTROL_EN_FREEZE_COUNTERS BIT(19)
0118 #define VC4_HDMI_RM_CONTROL_EN_LOAD_INTEGRATOR BIT(17)
0119 #define VC4_HDMI_RM_CONTROL_FREE_RUN BIT(4)
0120
0121 #define VC4_HDMI_RM_OFFSET_ONLY BIT(31)
0122 #define VC4_HDMI_RM_OFFSET_OFFSET_SHIFT 0
0123 #define VC4_HDMI_RM_OFFSET_OFFSET_MASK VC4_MASK(30, 0)
0124
0125 #define VC4_HDMI_RM_FORMAT_SHIFT_SHIFT 24
0126 #define VC4_HDMI_RM_FORMAT_SHIFT_MASK VC4_MASK(25, 24)
0127
0128 #define OSCILLATOR_FREQUENCY 54000000
0129
0130 void vc4_hdmi_phy_init(struct vc4_hdmi *vc4_hdmi,
0131 struct vc4_hdmi_connector_state *conn_state)
0132 {
0133 unsigned long flags;
0134
0135
0136
0137
0138
0139 spin_lock_irqsave(&vc4_hdmi->hw_lock, flags);
0140
0141 HDMI_WRITE(HDMI_TX_PHY_RESET_CTL, 0xf << 16);
0142 HDMI_WRITE(HDMI_TX_PHY_RESET_CTL, 0);
0143
0144 spin_unlock_irqrestore(&vc4_hdmi->hw_lock, flags);
0145 }
0146
0147 void vc4_hdmi_phy_disable(struct vc4_hdmi *vc4_hdmi)
0148 {
0149 unsigned long flags;
0150
0151 spin_lock_irqsave(&vc4_hdmi->hw_lock, flags);
0152 HDMI_WRITE(HDMI_TX_PHY_RESET_CTL, 0xf << 16);
0153 spin_unlock_irqrestore(&vc4_hdmi->hw_lock, flags);
0154 }
0155
0156 void vc4_hdmi_phy_rng_enable(struct vc4_hdmi *vc4_hdmi)
0157 {
0158 unsigned long flags;
0159
0160 spin_lock_irqsave(&vc4_hdmi->hw_lock, flags);
0161 HDMI_WRITE(HDMI_TX_PHY_CTL_0,
0162 HDMI_READ(HDMI_TX_PHY_CTL_0) &
0163 ~VC4_HDMI_TX_PHY_RNG_PWRDN);
0164 spin_unlock_irqrestore(&vc4_hdmi->hw_lock, flags);
0165 }
0166
0167 void vc4_hdmi_phy_rng_disable(struct vc4_hdmi *vc4_hdmi)
0168 {
0169 unsigned long flags;
0170
0171 spin_lock_irqsave(&vc4_hdmi->hw_lock, flags);
0172 HDMI_WRITE(HDMI_TX_PHY_CTL_0,
0173 HDMI_READ(HDMI_TX_PHY_CTL_0) |
0174 VC4_HDMI_TX_PHY_RNG_PWRDN);
0175 spin_unlock_irqrestore(&vc4_hdmi->hw_lock, flags);
0176 }
0177
0178 static unsigned long long
0179 phy_get_vco_freq(unsigned long long clock, u8 *vco_sel, u8 *vco_div)
0180 {
0181 unsigned long long vco_freq = clock;
0182 unsigned int _vco_div = 0;
0183 unsigned int _vco_sel = 0;
0184
0185 while (vco_freq < 3000000000ULL) {
0186 _vco_div++;
0187 vco_freq = clock * _vco_div * 10;
0188 }
0189
0190 if (vco_freq > 4500000000ULL)
0191 _vco_sel = 1;
0192
0193 *vco_sel = _vco_sel;
0194 *vco_div = _vco_div;
0195
0196 return vco_freq;
0197 }
0198
0199 static u8 phy_get_cp_current(unsigned long vco_freq)
0200 {
0201 if (vco_freq < 3700000000ULL)
0202 return 0x1c;
0203
0204 return 0x18;
0205 }
0206
0207 static u32 phy_get_rm_offset(unsigned long long vco_freq)
0208 {
0209 unsigned long long fref = OSCILLATOR_FREQUENCY;
0210 u64 offset = 0;
0211
0212
0213 offset = vco_freq * 2;
0214 offset = offset << 22;
0215 do_div(offset, fref);
0216 offset >>= 2;
0217
0218 return offset;
0219 }
0220
0221 static u8 phy_get_vco_gain(unsigned long long vco_freq)
0222 {
0223 if (vco_freq < 3350000000ULL)
0224 return 0xf;
0225
0226 if (vco_freq < 3700000000ULL)
0227 return 0xc;
0228
0229 if (vco_freq < 4050000000ULL)
0230 return 0x6;
0231
0232 if (vco_freq < 4800000000ULL)
0233 return 0x5;
0234
0235 if (vco_freq < 5200000000ULL)
0236 return 0x7;
0237
0238 return 0x2;
0239 }
0240
0241 struct phy_lane_settings {
0242 struct {
0243 u8 preemphasis;
0244 u8 main_driver;
0245 } amplitude;
0246
0247 u8 res_sel_data;
0248 u8 term_res_sel_data;
0249 };
0250
0251 struct phy_settings {
0252 unsigned long long min_rate;
0253 unsigned long long max_rate;
0254 struct phy_lane_settings channel[3];
0255 struct phy_lane_settings clock;
0256 };
0257
0258 static const struct phy_settings vc5_hdmi_phy_settings[] = {
0259 {
0260 0, 50000000,
0261 {
0262 {{0x0, 0x0A}, 0x12, 0x0},
0263 {{0x0, 0x0A}, 0x12, 0x0},
0264 {{0x0, 0x0A}, 0x12, 0x0}
0265 },
0266 {{0x0, 0x0A}, 0x18, 0x0},
0267 },
0268 {
0269 50000001, 75000000,
0270 {
0271 {{0x0, 0x09}, 0x12, 0x0},
0272 {{0x0, 0x09}, 0x12, 0x0},
0273 {{0x0, 0x09}, 0x12, 0x0}
0274 },
0275 {{0x0, 0x0C}, 0x18, 0x3},
0276 },
0277 {
0278 75000001, 165000000,
0279 {
0280 {{0x0, 0x09}, 0x12, 0x0},
0281 {{0x0, 0x09}, 0x12, 0x0},
0282 {{0x0, 0x09}, 0x12, 0x0}
0283 },
0284 {{0x0, 0x0C}, 0x18, 0x3},
0285 },
0286 {
0287 165000001, 250000000,
0288 {
0289 {{0x0, 0x0F}, 0x12, 0x1},
0290 {{0x0, 0x0F}, 0x12, 0x1},
0291 {{0x0, 0x0F}, 0x12, 0x1}
0292 },
0293 {{0x0, 0x0C}, 0x18, 0x3},
0294 },
0295 {
0296 250000001, 340000000,
0297 {
0298 {{0x2, 0x0D}, 0x12, 0x1},
0299 {{0x2, 0x0D}, 0x12, 0x1},
0300 {{0x2, 0x0D}, 0x12, 0x1}
0301 },
0302 {{0x0, 0x0C}, 0x18, 0xF},
0303 },
0304 {
0305 340000001, 450000000,
0306 {
0307 {{0x0, 0x1B}, 0x12, 0xF},
0308 {{0x0, 0x1B}, 0x12, 0xF},
0309 {{0x0, 0x1B}, 0x12, 0xF}
0310 },
0311 {{0x0, 0x0A}, 0x12, 0xF},
0312 },
0313 {
0314 450000001, 600000000,
0315 {
0316 {{0x0, 0x1C}, 0x12, 0xF},
0317 {{0x0, 0x1C}, 0x12, 0xF},
0318 {{0x0, 0x1C}, 0x12, 0xF}
0319 },
0320 {{0x0, 0x0B}, 0x13, 0xF},
0321 },
0322 };
0323
0324 static const struct phy_settings *phy_get_settings(unsigned long long tmds_rate)
0325 {
0326 unsigned int count = ARRAY_SIZE(vc5_hdmi_phy_settings);
0327 unsigned int i;
0328
0329 for (i = 0; i < count; i++) {
0330 const struct phy_settings *s = &vc5_hdmi_phy_settings[i];
0331
0332 if (tmds_rate >= s->min_rate && tmds_rate <= s->max_rate)
0333 return s;
0334 }
0335
0336
0337
0338
0339
0340 return &vc5_hdmi_phy_settings[count - 1];
0341 }
0342
0343 static const struct phy_lane_settings *
0344 phy_get_channel_settings(enum vc4_hdmi_phy_channel chan,
0345 unsigned long long tmds_rate)
0346 {
0347 const struct phy_settings *settings = phy_get_settings(tmds_rate);
0348
0349 if (chan == PHY_LANE_CK)
0350 return &settings->clock;
0351
0352 return &settings->channel[chan];
0353 }
0354
0355 static void vc5_hdmi_reset_phy(struct vc4_hdmi *vc4_hdmi)
0356 {
0357 lockdep_assert_held(&vc4_hdmi->hw_lock);
0358
0359 HDMI_WRITE(HDMI_TX_PHY_RESET_CTL, 0x0f);
0360 HDMI_WRITE(HDMI_TX_PHY_POWERDOWN_CTL, BIT(10));
0361 }
0362
0363 void vc5_hdmi_phy_init(struct vc4_hdmi *vc4_hdmi,
0364 struct vc4_hdmi_connector_state *conn_state)
0365 {
0366 const struct phy_lane_settings *chan0_settings, *chan1_settings, *chan2_settings, *clock_settings;
0367 const struct vc4_hdmi_variant *variant = vc4_hdmi->variant;
0368 unsigned long long pixel_freq = conn_state->tmds_char_rate;
0369 unsigned long long vco_freq;
0370 unsigned char word_sel;
0371 unsigned long flags;
0372 u8 vco_sel, vco_div;
0373
0374 vco_freq = phy_get_vco_freq(pixel_freq, &vco_sel, &vco_div);
0375
0376 spin_lock_irqsave(&vc4_hdmi->hw_lock, flags);
0377
0378 vc5_hdmi_reset_phy(vc4_hdmi);
0379
0380 HDMI_WRITE(HDMI_TX_PHY_POWERDOWN_CTL,
0381 VC4_HDMI_TX_PHY_POWERDOWN_CTL_RNDGEN_PWRDN);
0382
0383 HDMI_WRITE(HDMI_TX_PHY_RESET_CTL,
0384 HDMI_READ(HDMI_TX_PHY_RESET_CTL) &
0385 ~VC4_HDMI_TX_PHY_RESET_CTL_TX_0_RESET &
0386 ~VC4_HDMI_TX_PHY_RESET_CTL_TX_1_RESET &
0387 ~VC4_HDMI_TX_PHY_RESET_CTL_TX_2_RESET &
0388 ~VC4_HDMI_TX_PHY_RESET_CTL_TX_CK_RESET);
0389
0390 HDMI_WRITE(HDMI_RM_CONTROL,
0391 HDMI_READ(HDMI_RM_CONTROL) |
0392 VC4_HDMI_RM_CONTROL_EN_FREEZE_COUNTERS |
0393 VC4_HDMI_RM_CONTROL_EN_LOAD_INTEGRATOR |
0394 VC4_HDMI_RM_CONTROL_FREE_RUN);
0395
0396 HDMI_WRITE(HDMI_TX_PHY_PLL_CALIBRATION_CONFIG_1,
0397 (HDMI_READ(HDMI_TX_PHY_PLL_CALIBRATION_CONFIG_1) &
0398 ~VC4_HDMI_TX_PHY_PLL_CALIBRATION_CONFIG_1_MIN_LIMIT_MASK) |
0399 VC4_SET_FIELD(0, VC4_HDMI_TX_PHY_PLL_CALIBRATION_CONFIG_1_MIN_LIMIT));
0400
0401 HDMI_WRITE(HDMI_TX_PHY_PLL_CALIBRATION_CONFIG_2,
0402 (HDMI_READ(HDMI_TX_PHY_PLL_CALIBRATION_CONFIG_2) &
0403 ~VC4_HDMI_TX_PHY_PLL_CALIBRATION_CONFIG_2_MAX_LIMIT_MASK) |
0404 VC4_SET_FIELD(0, VC4_HDMI_TX_PHY_PLL_CALIBRATION_CONFIG_2_MAX_LIMIT));
0405
0406 HDMI_WRITE(HDMI_RM_OFFSET,
0407 VC4_SET_FIELD(phy_get_rm_offset(vco_freq),
0408 VC4_HDMI_RM_OFFSET_OFFSET) |
0409 VC4_HDMI_RM_OFFSET_ONLY);
0410
0411 HDMI_WRITE(HDMI_TX_PHY_CLK_DIV,
0412 VC4_SET_FIELD(vco_div, VC4_HDMI_TX_PHY_CLK_DIV_VCO));
0413
0414 HDMI_WRITE(HDMI_TX_PHY_PLL_CALIBRATION_CONFIG_4,
0415 VC4_SET_FIELD(0xe147, VC4_HDMI_TX_PHY_PLL_CALIBRATION_CONFIG_4_HOLD_THRESHOLD) |
0416 VC4_SET_FIELD(0xe14, VC4_HDMI_TX_PHY_PLL_CALIBRATION_CONFIG_4_STABLE_THRESHOLD));
0417
0418 HDMI_WRITE(HDMI_TX_PHY_PLL_CTL_0,
0419 VC4_HDMI_TX_PHY_PLL_CTL_0_ENA_VCO_CLK |
0420 VC4_HDMI_TX_PHY_PLL_CTL_0_VCO_CONT_EN |
0421 VC4_HDMI_TX_PHY_PLL_CTL_0_MASH11_MODE |
0422 VC4_SET_FIELD(vco_sel, VC4_HDMI_TX_PHY_PLL_CTL_0_VCO_SEL));
0423
0424 HDMI_WRITE(HDMI_TX_PHY_PLL_CTL_1,
0425 HDMI_READ(HDMI_TX_PHY_PLL_CTL_1) |
0426 VC4_HDMI_TX_PHY_PLL_CTL_1_FREQ_DOUBLER_ENABLE |
0427 VC4_SET_FIELD(3, VC4_HDMI_TX_PHY_PLL_CTL_1_POST_RST_SEL) |
0428 VC4_SET_FIELD(1, VC4_HDMI_TX_PHY_PLL_CTL_1_FREQ_DOUBLER_DELAY) |
0429 VC4_SET_FIELD(0x8a, VC4_HDMI_TX_PHY_PLL_CTL_1_CPP));
0430
0431 HDMI_WRITE(HDMI_RM_FORMAT,
0432 HDMI_READ(HDMI_RM_FORMAT) |
0433 VC4_SET_FIELD(2, VC4_HDMI_RM_FORMAT_SHIFT));
0434
0435 HDMI_WRITE(HDMI_TX_PHY_PLL_CFG,
0436 HDMI_READ(HDMI_TX_PHY_PLL_CFG) |
0437 VC4_SET_FIELD(1, VC4_HDMI_TX_PHY_PLL_CFG_PDIV));
0438
0439 if (pixel_freq >= 340000000)
0440 word_sel = 3;
0441 else
0442 word_sel = 0;
0443 HDMI_WRITE(HDMI_TX_PHY_TMDS_CLK_WORD_SEL, word_sel);
0444
0445 HDMI_WRITE(HDMI_TX_PHY_CTL_3,
0446 VC4_SET_FIELD(phy_get_cp_current(vco_freq),
0447 VC4_HDMI_TX_PHY_CTL_3_ICP) |
0448 VC4_SET_FIELD(1, VC4_HDMI_TX_PHY_CTL_3_CP) |
0449 VC4_SET_FIELD(1, VC4_HDMI_TX_PHY_CTL_3_CP1) |
0450 VC4_SET_FIELD(3, VC4_HDMI_TX_PHY_CTL_3_CZ) |
0451 VC4_SET_FIELD(4, VC4_HDMI_TX_PHY_CTL_3_RP) |
0452 VC4_SET_FIELD(6, VC4_HDMI_TX_PHY_CTL_3_RZ));
0453
0454 chan0_settings =
0455 phy_get_channel_settings(variant->phy_lane_mapping[PHY_LANE_0],
0456 pixel_freq);
0457 chan1_settings =
0458 phy_get_channel_settings(variant->phy_lane_mapping[PHY_LANE_1],
0459 pixel_freq);
0460 chan2_settings =
0461 phy_get_channel_settings(variant->phy_lane_mapping[PHY_LANE_2],
0462 pixel_freq);
0463 clock_settings =
0464 phy_get_channel_settings(variant->phy_lane_mapping[PHY_LANE_CK],
0465 pixel_freq);
0466
0467 HDMI_WRITE(HDMI_TX_PHY_CTL_0,
0468 VC4_SET_FIELD(chan0_settings->amplitude.preemphasis,
0469 VC4_HDMI_TX_PHY_CTL_0_PREEMP_0_PREEMP) |
0470 VC4_SET_FIELD(chan0_settings->amplitude.main_driver,
0471 VC4_HDMI_TX_PHY_CTL_0_PREEMP_0_MAINDRV) |
0472 VC4_SET_FIELD(chan1_settings->amplitude.preemphasis,
0473 VC4_HDMI_TX_PHY_CTL_0_PREEMP_1_PREEMP) |
0474 VC4_SET_FIELD(chan1_settings->amplitude.main_driver,
0475 VC4_HDMI_TX_PHY_CTL_0_PREEMP_1_MAINDRV) |
0476 VC4_SET_FIELD(chan2_settings->amplitude.preemphasis,
0477 VC4_HDMI_TX_PHY_CTL_0_PREEMP_2_PREEMP) |
0478 VC4_SET_FIELD(chan2_settings->amplitude.main_driver,
0479 VC4_HDMI_TX_PHY_CTL_0_PREEMP_2_MAINDRV) |
0480 VC4_SET_FIELD(clock_settings->amplitude.preemphasis,
0481 VC4_HDMI_TX_PHY_CTL_0_PREEMP_CK_PREEMP) |
0482 VC4_SET_FIELD(clock_settings->amplitude.main_driver,
0483 VC4_HDMI_TX_PHY_CTL_0_PREEMP_CK_MAINDRV));
0484
0485 HDMI_WRITE(HDMI_TX_PHY_CTL_1,
0486 HDMI_READ(HDMI_TX_PHY_CTL_1) |
0487 VC4_SET_FIELD(chan0_settings->res_sel_data,
0488 VC4_HDMI_TX_PHY_CTL_1_RES_SEL_DATA0) |
0489 VC4_SET_FIELD(chan1_settings->res_sel_data,
0490 VC4_HDMI_TX_PHY_CTL_1_RES_SEL_DATA1) |
0491 VC4_SET_FIELD(chan2_settings->res_sel_data,
0492 VC4_HDMI_TX_PHY_CTL_1_RES_SEL_DATA2) |
0493 VC4_SET_FIELD(clock_settings->res_sel_data,
0494 VC4_HDMI_TX_PHY_CTL_1_RES_SEL_CK));
0495
0496 HDMI_WRITE(HDMI_TX_PHY_CTL_2,
0497 VC4_SET_FIELD(chan0_settings->term_res_sel_data,
0498 VC4_HDMI_TX_PHY_CTL_2_TERM_RES_SELDATA0) |
0499 VC4_SET_FIELD(chan1_settings->term_res_sel_data,
0500 VC4_HDMI_TX_PHY_CTL_2_TERM_RES_SELDATA1) |
0501 VC4_SET_FIELD(chan2_settings->term_res_sel_data,
0502 VC4_HDMI_TX_PHY_CTL_2_TERM_RES_SELDATA2) |
0503 VC4_SET_FIELD(clock_settings->term_res_sel_data,
0504 VC4_HDMI_TX_PHY_CTL_2_TERM_RES_SELCK) |
0505 VC4_SET_FIELD(phy_get_vco_gain(vco_freq),
0506 VC4_HDMI_TX_PHY_CTL_2_VCO_GAIN));
0507
0508 HDMI_WRITE(HDMI_TX_PHY_CHANNEL_SWAP,
0509 VC4_SET_FIELD(variant->phy_lane_mapping[PHY_LANE_0],
0510 VC4_HDMI_TX_PHY_CHANNEL_SWAP_TX0_OUT_SEL) |
0511 VC4_SET_FIELD(variant->phy_lane_mapping[PHY_LANE_1],
0512 VC4_HDMI_TX_PHY_CHANNEL_SWAP_TX1_OUT_SEL) |
0513 VC4_SET_FIELD(variant->phy_lane_mapping[PHY_LANE_2],
0514 VC4_HDMI_TX_PHY_CHANNEL_SWAP_TX2_OUT_SEL) |
0515 VC4_SET_FIELD(variant->phy_lane_mapping[PHY_LANE_CK],
0516 VC4_HDMI_TX_PHY_CHANNEL_SWAP_TXCK_OUT_SEL));
0517
0518 HDMI_WRITE(HDMI_TX_PHY_RESET_CTL,
0519 HDMI_READ(HDMI_TX_PHY_RESET_CTL) &
0520 ~(VC4_HDMI_TX_PHY_RESET_CTL_PLL_RESETB |
0521 VC4_HDMI_TX_PHY_RESET_CTL_PLLDIV_RESETB));
0522
0523 HDMI_WRITE(HDMI_TX_PHY_RESET_CTL,
0524 HDMI_READ(HDMI_TX_PHY_RESET_CTL) |
0525 VC4_HDMI_TX_PHY_RESET_CTL_PLL_RESETB |
0526 VC4_HDMI_TX_PHY_RESET_CTL_PLLDIV_RESETB);
0527
0528 spin_unlock_irqrestore(&vc4_hdmi->hw_lock, flags);
0529 }
0530
0531 void vc5_hdmi_phy_disable(struct vc4_hdmi *vc4_hdmi)
0532 {
0533 unsigned long flags;
0534
0535 spin_lock_irqsave(&vc4_hdmi->hw_lock, flags);
0536 vc5_hdmi_reset_phy(vc4_hdmi);
0537 spin_unlock_irqrestore(&vc4_hdmi->hw_lock, flags);
0538 }
0539
0540 void vc5_hdmi_phy_rng_enable(struct vc4_hdmi *vc4_hdmi)
0541 {
0542 unsigned long flags;
0543
0544 spin_lock_irqsave(&vc4_hdmi->hw_lock, flags);
0545 HDMI_WRITE(HDMI_TX_PHY_POWERDOWN_CTL,
0546 HDMI_READ(HDMI_TX_PHY_POWERDOWN_CTL) &
0547 ~VC4_HDMI_TX_PHY_POWERDOWN_CTL_RNDGEN_PWRDN);
0548 spin_unlock_irqrestore(&vc4_hdmi->hw_lock, flags);
0549 }
0550
0551 void vc5_hdmi_phy_rng_disable(struct vc4_hdmi *vc4_hdmi)
0552 {
0553 unsigned long flags;
0554
0555 spin_lock_irqsave(&vc4_hdmi->hw_lock, flags);
0556 HDMI_WRITE(HDMI_TX_PHY_POWERDOWN_CTL,
0557 HDMI_READ(HDMI_TX_PHY_POWERDOWN_CTL) |
0558 VC4_HDMI_TX_PHY_POWERDOWN_CTL_RNDGEN_PWRDN);
0559 spin_unlock_irqrestore(&vc4_hdmi->hw_lock, flags);
0560 }