diff options
Diffstat (limited to 'drivers/gpu/drm/i915/display/intel_lt_phy.c')
| -rw-r--r-- | drivers/gpu/drm/i915/display/intel_lt_phy.c | 439 |
1 files changed, 383 insertions, 56 deletions
diff --git a/drivers/gpu/drm/i915/display/intel_lt_phy.c b/drivers/gpu/drm/i915/display/intel_lt_phy.c index af48d6cde226..a67eb4f7f897 100644 --- a/drivers/gpu/drm/i915/display/intel_lt_phy.c +++ b/drivers/gpu/drm/i915/display/intel_lt_phy.c @@ -6,7 +6,6 @@ #include <drm/drm_print.h> #include "i915_reg.h" -#include "i915_utils.h" #include "intel_cx0_phy.h" #include "intel_cx0_phy_regs.h" #include "intel_ddi.h" @@ -14,6 +13,7 @@ #include "intel_de.h" #include "intel_display.h" #include "intel_display_types.h" +#include "intel_display_utils.h" #include "intel_dpll_mgr.h" #include "intel_hdmi.h" #include "intel_lt_phy.h" @@ -31,6 +31,32 @@ #define INTEL_LT_PHY_BOTH_LANES (INTEL_LT_PHY_LANE1 |\ INTEL_LT_PHY_LANE0) #define MODE_DP 3 +#define Q32_TO_INT(x) ((x) >> 32) +#define Q32_TO_FRAC(x) ((x) & 0xFFFFFFFF) +#define DCO_MIN_FREQ_MHZ 11850 +#define REF_CLK_KHZ 38400 +#define TDC_RES_MULTIPLIER 10000000ULL + +struct phy_param_t { + u32 val; + u32 addr; +}; + +struct lt_phy_params { + struct phy_param_t pll_reg4; + struct phy_param_t pll_reg3; + struct phy_param_t pll_reg5; + struct phy_param_t pll_reg57; + struct phy_param_t lf; + struct phy_param_t tdc; + struct phy_param_t ssc; + struct phy_param_t bias2; + struct phy_param_t bias_trim; + struct phy_param_t dco_med; + struct phy_param_t dco_fine; + struct phy_param_t ssc_inj; + struct phy_param_t surv_bonus; +}; static const struct intel_lt_phy_pll_state xe3plpd_lt_dp_rbr = { .clock = 162000, @@ -1041,9 +1067,9 @@ static int __intel_lt_phy_p2p_write_once(struct intel_encoder *encoder, int ack; u32 val; - if (intel_de_wait_for_clear(display, XELPDP_PORT_M2P_MSGBUS_CTL(display, port, lane), - XELPDP_PORT_P2P_TRANSACTION_PENDING, - XELPDP_MSGBUS_TIMEOUT_SLOW)) { + if (intel_de_wait_for_clear_ms(display, XELPDP_PORT_M2P_MSGBUS_CTL(display, port, lane), + XELPDP_PORT_P2P_TRANSACTION_PENDING, + XELPDP_MSGBUS_TIMEOUT_MS)) { drm_dbg_kms(display->drm, "PHY %c Timeout waiting for previous transaction to complete. Resetting bus.\n", phy_name(phy)); @@ -1175,13 +1201,11 @@ intel_lt_phy_lane_reset(struct intel_encoder *encoder, XELPDP_LANE_PCLK_PLL_REQUEST(0), XELPDP_LANE_PCLK_PLL_REQUEST(0)); - if (intel_de_wait_custom(display, XELPDP_PORT_CLOCK_CTL(display, port), - XELPDP_LANE_PCLK_PLL_ACK(0), - XELPDP_LANE_PCLK_PLL_ACK(0), - XE3PLPD_MACCLK_TURNON_LATENCY_US, - XE3PLPD_MACCLK_TURNON_LATENCY_MS, NULL)) - drm_warn(display->drm, "PHY %c PLL MacCLK assertion Ack not done after %dus.\n", - phy_name(phy), XE3PLPD_MACCLK_TURNON_LATENCY_MS * 1000); + if (intel_de_wait_for_set_ms(display, XELPDP_PORT_CLOCK_CTL(display, port), + XELPDP_LANE_PCLK_PLL_ACK(0), + XE3PLPD_MACCLK_TURNON_LATENCY_MS)) + drm_warn(display->drm, "PHY %c PLL MacCLK assertion ack not done\n", + phy_name(phy)); intel_de_rmw(display, XELPDP_PORT_CLOCK_CTL(display, port), XELPDP_FORWARD_CLOCK_UNGATE, @@ -1190,18 +1214,17 @@ intel_lt_phy_lane_reset(struct intel_encoder *encoder, intel_de_rmw(display, XELPDP_PORT_BUF_CTL2(display, port), lane_pipe_reset | lane_phy_pulse_status, 0); - if (intel_de_wait_custom(display, XELPDP_PORT_BUF_CTL2(display, port), - lane_phy_current_status, 0, - XE3PLPD_RESET_END_LATENCY_US, 2, NULL)) - drm_warn(display->drm, - "PHY %c failed to bring out of Lane reset after %dus.\n", - phy_name(phy), XE3PLPD_RESET_END_LATENCY_US); + if (intel_de_wait_for_clear_ms(display, XELPDP_PORT_BUF_CTL2(display, port), + lane_phy_current_status, + XE3PLPD_RESET_END_LATENCY_MS)) + drm_warn(display->drm, "PHY %c failed to bring out of lane reset\n", + phy_name(phy)); - if (intel_de_wait_custom(display, XELPDP_PORT_BUF_CTL2(display, port), - lane_phy_pulse_status, lane_phy_pulse_status, - XE3PLPD_RATE_CALIB_DONE_LATENCY_US, 0, NULL)) - drm_warn(display->drm, "PHY %c PLL rate not changed after %dus.\n", - phy_name(phy), XE3PLPD_RATE_CALIB_DONE_LATENCY_US); + if (intel_de_wait_for_set_ms(display, XELPDP_PORT_BUF_CTL2(display, port), + lane_phy_pulse_status, + XE3PLPD_RATE_CALIB_DONE_LATENCY_MS)) + drm_warn(display->drm, "PHY %c PLL rate not changed\n", + phy_name(phy)); intel_de_rmw(display, XELPDP_PORT_BUF_CTL2(display, port), lane_phy_pulse_status, 0); } @@ -1356,10 +1379,308 @@ intel_lt_phy_pll_is_ssc_enabled(struct intel_crtc_state *crtc_state, return false; } +static u64 mul_q32_u32(u64 a_q32, u32 b) +{ + u64 p0, p1, carry, result; + u64 x_hi = a_q32 >> 32; + u64 x_lo = a_q32 & 0xFFFFFFFFULL; + + p0 = x_lo * (u64)b; + p1 = x_hi * (u64)b; + carry = p0 >> 32; + result = (p1 << 32) + (carry << 32) + (p0 & 0xFFFFFFFFULL); + + return result; +} + +static bool +calculate_target_dco_and_loop_cnt(u32 frequency_khz, u64 *target_dco_mhz, u32 *loop_cnt) +{ + u32 ppm_value = 1; + u32 dco_min_freq = DCO_MIN_FREQ_MHZ; + u32 dco_max_freq = 16200; + u32 dco_min_freq_low = 10000; + u32 dco_max_freq_low = 12000; + u64 val = 0; + u64 refclk_khz = REF_CLK_KHZ; + u64 m2div = 0; + u64 val_with_frac = 0; + u64 ppm = 0; + u64 temp0 = 0, temp1, scale; + int ppm_cnt, dco_count, y; + + for (ppm_cnt = 0; ppm_cnt < 5; ppm_cnt++) { + ppm_value = ppm_cnt == 2 ? 2 : 1; + for (dco_count = 0; dco_count < 2; dco_count++) { + if (dco_count == 1) { + dco_min_freq = dco_min_freq_low; + dco_max_freq = dco_max_freq_low; + } + for (y = 2; y <= 255; y += 2) { + val = div64_u64((u64)y * frequency_khz, 200); + m2div = div64_u64(((u64)(val) << 32), refclk_khz); + m2div = mul_q32_u32(m2div, 500); + val_with_frac = mul_q32_u32(m2div, refclk_khz); + val_with_frac = div64_u64(val_with_frac, 500); + temp1 = Q32_TO_INT(val_with_frac); + temp0 = (temp1 > val) ? (temp1 - val) : + (val - temp1); + ppm = div64_u64(temp0, val); + if (temp1 >= dco_min_freq && + temp1 <= dco_max_freq && + ppm < ppm_value) { + /* Round to two places */ + scale = (1ULL << 32) / 100; + temp0 = DIV_ROUND_UP_ULL(val_with_frac, + scale); + *target_dco_mhz = temp0 * scale; + *loop_cnt = y; + return true; + } + } + } + } + + return false; +} + +static void set_phy_vdr_addresses(struct lt_phy_params *p, int pll_type) +{ + p->pll_reg4.addr = PLL_REG_ADDR(PLL_REG4_ADDR, pll_type); + p->pll_reg3.addr = PLL_REG_ADDR(PLL_REG3_ADDR, pll_type); + p->pll_reg5.addr = PLL_REG_ADDR(PLL_REG5_ADDR, pll_type); + p->pll_reg57.addr = PLL_REG_ADDR(PLL_REG57_ADDR, pll_type); + p->lf.addr = PLL_REG_ADDR(PLL_LF_ADDR, pll_type); + p->tdc.addr = PLL_REG_ADDR(PLL_TDC_ADDR, pll_type); + p->ssc.addr = PLL_REG_ADDR(PLL_SSC_ADDR, pll_type); + p->bias2.addr = PLL_REG_ADDR(PLL_BIAS2_ADDR, pll_type); + p->bias_trim.addr = PLL_REG_ADDR(PLL_BIAS_TRIM_ADDR, pll_type); + p->dco_med.addr = PLL_REG_ADDR(PLL_DCO_MED_ADDR, pll_type); + p->dco_fine.addr = PLL_REG_ADDR(PLL_DCO_FINE_ADDR, pll_type); + p->ssc_inj.addr = PLL_REG_ADDR(PLL_SSC_INJ_ADDR, pll_type); + p->surv_bonus.addr = PLL_REG_ADDR(PLL_SURV_BONUS_ADDR, pll_type); +} + +static void compute_ssc(struct lt_phy_params *p, u32 ana_cfg) +{ + int ssc_stepsize = 0; + int ssc_steplen = 0; + int ssc_steplog = 0; + + p->ssc.val = (1 << 31) | (ana_cfg << 24) | (ssc_steplog << 16) | + (ssc_stepsize << 8) | ssc_steplen; +} + +static void compute_bias2(struct lt_phy_params *p) +{ + u32 ssc_en_local = 0; + u64 dynctrl_ovrd_en = 0; + + p->bias2.val = (dynctrl_ovrd_en << 31) | (ssc_en_local << 30) | + (1 << 23) | (1 << 24) | (32 << 16) | (1 << 8); +} + +static void compute_tdc(struct lt_phy_params *p, u64 tdc_fine) +{ + u32 settling_time = 15; + u32 bias_ovr_en = 1; + u32 coldstart = 1; + u32 true_lock = 2; + u32 early_lock = 1; + u32 lock_ovr_en = 1; + u32 lock_thr = tdc_fine ? 3 : 5; + u32 unlock_thr = tdc_fine ? 5 : 11; + + p->tdc.val = (u32)((2 << 30) + (settling_time << 16) + (bias_ovr_en << 15) + + (lock_ovr_en << 14) + (coldstart << 12) + (true_lock << 10) + + (early_lock << 8) + (unlock_thr << 4) + lock_thr); +} + +static void compute_dco_med(struct lt_phy_params *p) +{ + u32 cselmed_en = 0; + u32 cselmed_dyn_adj = 0; + u32 cselmed_ratio = 39; + u32 cselmed_thr = 8; + + p->dco_med.val = (cselmed_en << 31) + (cselmed_dyn_adj << 30) + + (cselmed_ratio << 24) + (cselmed_thr << 21); +} + +static void compute_dco_fine(struct lt_phy_params *p, u32 dco_12g) +{ + u32 dco_fine0_tune_2_0 = 0; + u32 dco_fine1_tune_2_0 = 0; + u32 dco_fine2_tune_2_0 = 0; + u32 dco_fine3_tune_2_0 = 0; + u32 dco_dith0_tune_2_0 = 0; + u32 dco_dith1_tune_2_0 = 0; + + dco_fine0_tune_2_0 = dco_12g ? 4 : 3; + dco_fine1_tune_2_0 = 2; + dco_fine2_tune_2_0 = dco_12g ? 2 : 1; + dco_fine3_tune_2_0 = 5; + dco_dith0_tune_2_0 = dco_12g ? 4 : 3; + dco_dith1_tune_2_0 = 2; + + p->dco_fine.val = (dco_dith1_tune_2_0 << 19) + + (dco_dith0_tune_2_0 << 16) + + (dco_fine3_tune_2_0 << 11) + + (dco_fine2_tune_2_0 << 8) + + (dco_fine1_tune_2_0 << 3) + + dco_fine0_tune_2_0; +} + +int +intel_lt_phy_calculate_hdmi_state(struct intel_lt_phy_pll_state *lt_state, + u32 frequency_khz) +{ +#define DATA_ASSIGN(i, pll_reg) \ + do { \ + lt_state->data[i][0] = (u8)((((pll_reg).val) & 0xFF000000) >> 24); \ + lt_state->data[i][1] = (u8)((((pll_reg).val) & 0x00FF0000) >> 16); \ + lt_state->data[i][2] = (u8)((((pll_reg).val) & 0x0000FF00) >> 8); \ + lt_state->data[i][3] = (u8)((((pll_reg).val) & 0x000000FF)); \ + } while (0) +#define ADDR_ASSIGN(i, pll_reg) \ + do { \ + lt_state->addr_msb[i] = ((pll_reg).addr >> 8) & 0xFF; \ + lt_state->addr_lsb[i] = (pll_reg).addr & 0xFF; \ + } while (0) + + bool found = false; + struct lt_phy_params p; + u32 dco_fmin = DCO_MIN_FREQ_MHZ; + u64 refclk_khz = REF_CLK_KHZ; + u32 refclk_mhz_int = REF_CLK_KHZ / 1000; + u64 m2div = 0; + u64 target_dco_mhz = 0; + u64 tdc_fine, tdc_targetcnt; + u64 feedfwd_gain ,feedfwd_cal_en; + u64 tdc_res = 30; + u32 prop_coeff; + u32 int_coeff; + u32 ndiv = 1; + u32 m1div = 1, m2div_int, m2div_frac; + u32 frac_en; + u32 ana_cfg; + u32 loop_cnt = 0; + u32 gain_ctrl = 2; + u32 postdiv = 0; + u32 dco_12g = 0; + u32 pll_type = 0; + u32 d1 = 2, d3 = 5, d4 = 0, d5 = 0; + u32 d6 = 0, d6_new = 0; + u32 d7, d8 = 0; + u32 bonus_7_0 = 0; + u32 csel2fo = 11; + u32 csel2fo_ovrd_en = 1; + u64 temp0, temp1, temp2, temp3; + + p.surv_bonus.val = (bonus_7_0 << 16); + p.pll_reg4.val = (refclk_mhz_int << 17) + + (ndiv << 9) + (1 << 4); + p.bias_trim.val = (csel2fo_ovrd_en << 30) + (csel2fo << 24); + p.ssc_inj.val = 0; + found = calculate_target_dco_and_loop_cnt(frequency_khz, &target_dco_mhz, &loop_cnt); + if (!found) + return -EINVAL; + + m2div = div64_u64(target_dco_mhz, (refclk_khz * ndiv * m1div)); + m2div = mul_q32_u32(m2div, 1000); + if (Q32_TO_INT(m2div) > 511) + return -EINVAL; + + m2div_int = (u32)Q32_TO_INT(m2div); + m2div_frac = (u32)(Q32_TO_FRAC(m2div)); + frac_en = (m2div_frac > 0) ? 1 : 0; + + if (frac_en > 0) + tdc_res = 70; + else + tdc_res = 36; + tdc_fine = tdc_res > 50 ? 1 : 0; + temp0 = tdc_res * 40 * 11; + temp1 = div64_u64(((4 * TDC_RES_MULTIPLIER) + temp0) * 500, temp0 * refclk_khz); + temp2 = div64_u64(temp0 * refclk_khz, 1000); + temp3 = div64_u64(((8 * TDC_RES_MULTIPLIER) + temp2), temp2); + tdc_targetcnt = tdc_res < 50 ? (int)(temp1) : (int)(temp3); + tdc_targetcnt = (int)(tdc_targetcnt / 2); + temp0 = mul_q32_u32(target_dco_mhz, tdc_res); + temp0 >>= 32; + feedfwd_gain = (m2div_frac > 0) ? div64_u64(m1div * TDC_RES_MULTIPLIER, temp0) : 0; + feedfwd_cal_en = frac_en; + + temp0 = (u32)Q32_TO_INT(target_dco_mhz); + prop_coeff = (temp0 >= dco_fmin) ? 3 : 4; + int_coeff = (temp0 >= dco_fmin) ? 7 : 8; + ana_cfg = (temp0 >= dco_fmin) ? 8 : 6; + dco_12g = (temp0 >= dco_fmin) ? 0 : 1; + + if (temp0 > 12960) + d7 = 10; + else + d7 = 8; + + d8 = loop_cnt / 2; + d4 = d8 * 2; + + /* Compute pll_reg3,5,57 & lf */ + p.pll_reg3.val = (u32)((d4 << 21) + (d3 << 18) + (d1 << 15) + (m2div_int << 5)); + p.pll_reg5.val = m2div_frac; + postdiv = (d5 == 0) ? 9 : d5; + d6_new = (d6 == 0) ? 40 : d6; + p.pll_reg57.val = (d7 << 24) + (postdiv << 15) + (d8 << 7) + d6_new; + p.lf.val = (u32)((frac_en << 31) + (1 << 30) + (frac_en << 29) + + (feedfwd_cal_en << 28) + (tdc_fine << 27) + + (gain_ctrl << 24) + (feedfwd_gain << 16) + + (int_coeff << 12) + (prop_coeff << 8) + tdc_targetcnt); + + compute_ssc(&p, ana_cfg); + compute_bias2(&p); + compute_tdc(&p, tdc_fine); + compute_dco_med(&p); + compute_dco_fine(&p, dco_12g); + + pll_type = ((frequency_khz == 10000) || (frequency_khz == 20000) || + (frequency_khz == 2500) || (dco_12g == 1)) ? 0 : 1; + set_phy_vdr_addresses(&p, pll_type); + + lt_state->config[0] = 0x84; + lt_state->config[1] = 0x2d; + ADDR_ASSIGN(0, p.pll_reg4); + ADDR_ASSIGN(1, p.pll_reg3); + ADDR_ASSIGN(2, p.pll_reg5); + ADDR_ASSIGN(3, p.pll_reg57); + ADDR_ASSIGN(4, p.lf); + ADDR_ASSIGN(5, p.tdc); + ADDR_ASSIGN(6, p.ssc); + ADDR_ASSIGN(7, p.bias2); + ADDR_ASSIGN(8, p.bias_trim); + ADDR_ASSIGN(9, p.dco_med); + ADDR_ASSIGN(10, p.dco_fine); + ADDR_ASSIGN(11, p.ssc_inj); + ADDR_ASSIGN(12, p.surv_bonus); + DATA_ASSIGN(0, p.pll_reg4); + DATA_ASSIGN(1, p.pll_reg3); + DATA_ASSIGN(2, p.pll_reg5); + DATA_ASSIGN(3, p.pll_reg57); + DATA_ASSIGN(4, p.lf); + DATA_ASSIGN(5, p.tdc); + DATA_ASSIGN(6, p.ssc); + DATA_ASSIGN(7, p.bias2); + DATA_ASSIGN(8, p.bias_trim); + DATA_ASSIGN(9, p.dco_med); + DATA_ASSIGN(10, p.dco_fine); + DATA_ASSIGN(11, p.ssc_inj); + DATA_ASSIGN(12, p.surv_bonus); + + return 0; +} + static int -intel_lt_phy_calc_hdmi_port_clock(const struct intel_lt_phy_pll_state *lt_state) +intel_lt_phy_calc_hdmi_port_clock(const struct intel_crtc_state *crtc_state) { -#define REF_CLK_KHZ 38400 #define REGVAL(i) ( \ (lt_state->data[i][3]) | \ (lt_state->data[i][2] << 8) | \ @@ -1367,6 +1688,9 @@ intel_lt_phy_calc_hdmi_port_clock(const struct intel_lt_phy_pll_state *lt_state) (lt_state->data[i][0] << 24) \ ) + struct intel_display *display = to_intel_display(crtc_state); + const struct intel_lt_phy_pll_state *lt_state = + &crtc_state->dpll_hw_state.ltpll; int clk = 0; u32 d8, pll_reg_5, pll_reg_3, pll_reg_57, m2div_frac, m2div_int; u64 temp0, temp1; @@ -1409,11 +1733,14 @@ intel_lt_phy_calc_hdmi_port_clock(const struct intel_lt_phy_pll_state *lt_state) * frequency = (m2div * refclk_khz / (d8 * 10)) */ d8 = (pll_reg_57 & REG_GENMASK(14, 7)) >> 7; + if (d8 == 0) { + drm_WARN_ON(display->drm, + "Invalid port clock using lowest HDMI portclock\n"); + return xe3plpd_lt_hdmi_252.clock; + } m2div_int = (pll_reg_3 & REG_GENMASK(14, 5)) >> 5; temp0 = ((u64)m2div_frac * REF_CLK_KHZ) >> 32; temp1 = (u64)m2div_int * REF_CLK_KHZ; - if (d8 == 0) - return 0; clk = div_u64((temp1 + temp0), d8 * 10); @@ -1442,7 +1769,7 @@ intel_lt_phy_calc_port_clock(struct intel_encoder *encoder, lt_state->config[0]); clk = intel_lt_phy_get_dp_clock(rate); } else { - clk = intel_lt_phy_calc_hdmi_port_clock(lt_state); + clk = intel_lt_phy_calc_hdmi_port_clock(crtc_state); } return clk; @@ -1472,7 +1799,10 @@ intel_lt_phy_pll_calc_state(struct intel_crtc_state *crtc_state, } } - /* TODO: Add a function to compute the data for HDMI TMDS*/ + if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI)) { + return intel_lt_phy_calculate_hdmi_state(&crtc_state->dpll_hw_state.ltpll, + crtc_state->port_clock); + } return -EINVAL; } @@ -1651,11 +1981,11 @@ void intel_lt_phy_pll_enable(struct intel_encoder *encoder, XELPDP_LANE_PCLK_PLL_REQUEST(0), 0); /* 8. Poll for PORT_CLOCK_CTL[PCLK PLL Ack LN0]= 0. */ - if (intel_de_wait_custom(display, XELPDP_PORT_CLOCK_CTL(display, port), - XELPDP_LANE_PCLK_PLL_ACK(0), 0, - XE3PLPD_MACCLK_TURNOFF_LATENCY_US, 0, NULL)) - drm_warn(display->drm, "PHY %c PLL MacCLK Ack deassertion Timeout after %dus.\n", - phy_name(phy), XE3PLPD_MACCLK_TURNOFF_LATENCY_US); + if (intel_de_wait_for_clear_us(display, XELPDP_PORT_CLOCK_CTL(display, port), + XELPDP_LANE_PCLK_PLL_ACK(0), + XE3PLPD_MACCLK_TURNOFF_LATENCY_US)) + drm_warn(display->drm, "PHY %c PLL MacCLK ack deassertion timeout\n", + phy_name(phy)); /* * 9. Follow the Display Voltage Frequency Switching - Sequence Before Frequency @@ -1671,12 +2001,11 @@ void intel_lt_phy_pll_enable(struct intel_encoder *encoder, XELPDP_LANE_PCLK_PLL_REQUEST(0)); /* 12. Poll for PORT_CLOCK_CTL[PCLK PLL Ack LN0]= 1. */ - if (intel_de_wait_custom(display, XELPDP_PORT_CLOCK_CTL(display, port), - XELPDP_LANE_PCLK_PLL_ACK(0), - XELPDP_LANE_PCLK_PLL_ACK(0), - XE3PLPD_MACCLK_TURNON_LATENCY_US, 2, NULL)) - drm_warn(display->drm, "PHY %c PLL MacCLK Ack assertion Timeout after %dus.\n", - phy_name(phy), XE3PLPD_MACCLK_TURNON_LATENCY_US); + if (intel_de_wait_for_set_ms(display, XELPDP_PORT_CLOCK_CTL(display, port), + XELPDP_LANE_PCLK_PLL_ACK(0), + XE3PLPD_MACCLK_TURNON_LATENCY_MS)) + drm_warn(display->drm, "PHY %c PLL MacCLK ack assertion timeout\n", + phy_name(phy)); /* * 13. Ungate the forward clock by setting @@ -1700,11 +2029,11 @@ void intel_lt_phy_pll_enable(struct intel_encoder *encoder, rate_update, MB_WRITE_COMMITTED); /* 16. Poll for PORT_BUF_CTL2 register PHY Pulse Status = 1 for Owned PHY Lanes. */ - if (intel_de_wait_custom(display, XELPDP_PORT_BUF_CTL2(display, port), - lane_phy_pulse_status, lane_phy_pulse_status, - XE3PLPD_RATE_CALIB_DONE_LATENCY_US, 2, NULL)) - drm_warn(display->drm, "PHY %c PLL rate not changed after %dus.\n", - phy_name(phy), XE3PLPD_RATE_CALIB_DONE_LATENCY_US); + if (intel_de_wait_for_set_ms(display, XELPDP_PORT_BUF_CTL2(display, port), + lane_phy_pulse_status, + XE3PLPD_RATE_CALIB_DONE_LATENCY_MS)) + drm_warn(display->drm, "PHY %c PLL rate not changed\n", + phy_name(phy)); /* 17. SW clears PORT_BUF_CTL2 [PHY Pulse Status]. */ intel_de_rmw(display, XELPDP_PORT_BUF_CTL2(display, port), @@ -1758,13 +2087,11 @@ void intel_lt_phy_pll_disable(struct intel_encoder *encoder) lane_pipe_reset); /* 3. Poll for PORT_BUF_CTL2<port> Lane<PHY Lanes Owned> PHY Current Status == 1. */ - if (intel_de_wait_custom(display, XELPDP_PORT_BUF_CTL2(display, port), - lane_phy_current_status, - lane_phy_current_status, - XE3PLPD_RESET_START_LATENCY_US, 0, NULL)) - drm_warn(display->drm, - "PHY %c failed to reset Lane after %dms.\n", - phy_name(phy), XE3PLPD_RESET_START_LATENCY_US); + if (intel_de_wait_for_set_us(display, XELPDP_PORT_BUF_CTL2(display, port), + lane_phy_current_status, + XE3PLPD_RESET_START_LATENCY_US)) + drm_warn(display->drm, "PHY %c failed to reset lane\n", + phy_name(phy)); /* 4. Clear for PHY pulse status on owned PHY lanes. */ intel_de_rmw(display, XELPDP_PORT_BUF_CTL2(display, port), @@ -1783,11 +2110,11 @@ void intel_lt_phy_pll_disable(struct intel_encoder *encoder) intel_de_write(display, DDI_CLK_VALFREQ(encoder->port), 0); /* 8. Poll for PORT_CLOCK_CTL[PCLK PLL Ack LN0]= 0. */ - if (intel_de_wait_custom(display, XELPDP_PORT_CLOCK_CTL(display, port), - XELPDP_LANE_PCLK_PLL_ACK(0), 0, - XE3PLPD_MACCLK_TURNOFF_LATENCY_US, 0, NULL)) - drm_warn(display->drm, "PHY %c PLL MacCLK Ack deassertion Timeout after %dus.\n", - phy_name(phy), XE3PLPD_MACCLK_TURNOFF_LATENCY_US); + if (intel_de_wait_for_clear_us(display, XELPDP_PORT_CLOCK_CTL(display, port), + XELPDP_LANE_PCLK_PLL_ACK(0), + XE3PLPD_MACCLK_TURNOFF_LATENCY_US)) + drm_warn(display->drm, "PHY %c PLL MacCLK ack deassertion timeout\n", + phy_name(phy)); /* * 9. Follow the Display Voltage Frequency Switching - |
