diff --git a/Makefile b/Makefile index 7df4c195c8ab..2ecedf786e27 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ # SPDX-License-Identifier: GPL-2.0 VERSION = 5 PATCHLEVEL = 19 -SUBLEVEL = 12 +SUBLEVEL = 13 EXTRAVERSION = NAME = Superb Owl diff --git a/drivers/gpu/drm/i915/display/g4x_dp.c b/drivers/gpu/drm/i915/display/g4x_dp.c index 82ad8fe7440c..5a957acebfd6 100644 --- a/drivers/gpu/drm/i915/display/g4x_dp.c +++ b/drivers/gpu/drm/i915/display/g4x_dp.c @@ -395,8 +395,26 @@ static void intel_dp_get_config(struct intel_encoder *encoder, intel_dotclock_calculate(pipe_config->port_clock, &pipe_config->dp_m_n); - if (intel_dp_is_edp(intel_dp)) - intel_edp_fixup_vbt_bpp(encoder, pipe_config->pipe_bpp); + if (intel_dp_is_edp(intel_dp) && dev_priv->vbt.edp.bpp && + pipe_config->pipe_bpp > dev_priv->vbt.edp.bpp) { + /* + * This is a big fat ugly hack. + * + * Some machines in UEFI boot mode provide us a VBT that has 18 + * bpp and 1.62 GHz link bandwidth for eDP, which for reasons + * unknown we fail to light up. Yet the same BIOS boots up with + * 24 bpp and 2.7 GHz link. Use the same bpp as the BIOS uses as + * max, not what it tells us to use. + * + * Note: This will still be broken if the eDP panel is not lit + * up by the BIOS, and thus we can't get the mode at module + * load. + */ + drm_dbg_kms(&dev_priv->drm, + "pipe has %d bpp for eDP panel, overriding BIOS-provided max %d bpp\n", + pipe_config->pipe_bpp, dev_priv->vbt.edp.bpp); + dev_priv->vbt.edp.bpp = pipe_config->pipe_bpp; + } } static void diff --git a/drivers/gpu/drm/i915/display/icl_dsi.c b/drivers/gpu/drm/i915/display/icl_dsi.c index f416499dad6f..5508ebb9eb43 100644 --- a/drivers/gpu/drm/i915/display/icl_dsi.c +++ b/drivers/gpu/drm/i915/display/icl_dsi.c @@ -1864,8 +1864,7 @@ static void icl_dphy_param_init(struct intel_dsi *intel_dsi) { struct drm_device *dev = intel_dsi->base.base.dev; struct drm_i915_private *dev_priv = to_i915(dev); - struct intel_connector *connector = intel_dsi->attached_connector; - struct mipi_config *mipi_config = connector->panel.vbt.dsi.config; + struct mipi_config *mipi_config = dev_priv->vbt.dsi.config; u32 tlpx_ns; u32 prepare_cnt, exit_zero_cnt, clk_zero_cnt, trail_cnt; u32 ths_prepare_ns, tclk_trail_ns; @@ -2052,8 +2051,6 @@ void icl_dsi_init(struct drm_i915_private *dev_priv) /* attach connector to encoder */ intel_connector_attach_encoder(intel_connector, encoder); - intel_bios_init_panel(dev_priv, &intel_connector->panel); - mutex_lock(&dev->mode_config.mutex); intel_panel_add_vbt_lfp_fixed_mode(intel_connector); mutex_unlock(&dev->mode_config.mutex); @@ -2067,20 +2064,13 @@ void icl_dsi_init(struct drm_i915_private *dev_priv) intel_backlight_setup(intel_connector, INVALID_PIPE); - if (intel_connector->panel.vbt.dsi.config->dual_link) + if (dev_priv->vbt.dsi.config->dual_link) intel_dsi->ports = BIT(PORT_A) | BIT(PORT_B); else intel_dsi->ports = BIT(port); - if (drm_WARN_ON(&dev_priv->drm, intel_connector->panel.vbt.dsi.bl_ports & ~intel_dsi->ports)) - intel_connector->panel.vbt.dsi.bl_ports &= intel_dsi->ports; - - intel_dsi->dcs_backlight_ports = intel_connector->panel.vbt.dsi.bl_ports; - - if (drm_WARN_ON(&dev_priv->drm, intel_connector->panel.vbt.dsi.cabc_ports & ~intel_dsi->ports)) - intel_connector->panel.vbt.dsi.cabc_ports &= intel_dsi->ports; - - intel_dsi->dcs_cabc_ports = intel_connector->panel.vbt.dsi.cabc_ports; + intel_dsi->dcs_backlight_ports = dev_priv->vbt.dsi.bl_ports; + intel_dsi->dcs_cabc_ports = dev_priv->vbt.dsi.cabc_ports; for_each_dsi_port(port, intel_dsi->ports) { struct intel_dsi_host *host; diff --git a/drivers/gpu/drm/i915/display/intel_backlight.c b/drivers/gpu/drm/i915/display/intel_backlight.c index 5182bb66bd28..3e200a2e4ba2 100644 --- a/drivers/gpu/drm/i915/display/intel_backlight.c +++ b/drivers/gpu/drm/i915/display/intel_backlight.c @@ -1158,10 +1158,9 @@ static u32 vlv_hz_to_pwm(struct intel_connector *connector, u32 pwm_freq_hz) return DIV_ROUND_CLOSEST(clock, pwm_freq_hz * mul); } -static u16 get_vbt_pwm_freq(struct intel_connector *connector) +static u16 get_vbt_pwm_freq(struct drm_i915_private *dev_priv) { - struct drm_i915_private *dev_priv = to_i915(connector->base.dev); - u16 pwm_freq_hz = connector->panel.vbt.backlight.pwm_freq_hz; + u16 pwm_freq_hz = dev_priv->vbt.backlight.pwm_freq_hz; if (pwm_freq_hz) { drm_dbg_kms(&dev_priv->drm, @@ -1181,7 +1180,7 @@ static u32 get_backlight_max_vbt(struct intel_connector *connector) { struct drm_i915_private *dev_priv = to_i915(connector->base.dev); struct intel_panel *panel = &connector->panel; - u16 pwm_freq_hz = get_vbt_pwm_freq(connector); + u16 pwm_freq_hz = get_vbt_pwm_freq(dev_priv); u32 pwm; if (!panel->backlight.pwm_funcs->hz_to_pwm) { @@ -1218,11 +1217,11 @@ static u32 get_backlight_min_vbt(struct intel_connector *connector) * against this by letting the minimum be at most (arbitrarily chosen) * 25% of the max. */ - min = clamp_t(int, connector->panel.vbt.backlight.min_brightness, 0, 64); - if (min != connector->panel.vbt.backlight.min_brightness) { + min = clamp_t(int, dev_priv->vbt.backlight.min_brightness, 0, 64); + if (min != dev_priv->vbt.backlight.min_brightness) { drm_dbg_kms(&dev_priv->drm, "clamping VBT min backlight %d/255 to %d/255\n", - connector->panel.vbt.backlight.min_brightness, min); + dev_priv->vbt.backlight.min_brightness, min); } /* vbt value is a coefficient in range [0..255] */ @@ -1411,7 +1410,7 @@ bxt_setup_backlight(struct intel_connector *connector, enum pipe unused) struct intel_panel *panel = &connector->panel; u32 pwm_ctl, val; - panel->backlight.controller = connector->panel.vbt.backlight.controller; + panel->backlight.controller = dev_priv->vbt.backlight.controller; pwm_ctl = intel_de_read(dev_priv, BXT_BLC_PWM_CTL(panel->backlight.controller)); @@ -1484,7 +1483,7 @@ static int ext_pwm_setup_backlight(struct intel_connector *connector, u32 level; /* Get the right PWM chip for DSI backlight according to VBT */ - if (connector->panel.vbt.dsi.config->pwm_blc == PPS_BLC_PMIC) { + if (dev_priv->vbt.dsi.config->pwm_blc == PPS_BLC_PMIC) { panel->backlight.pwm = pwm_get(dev->dev, "pwm_pmic_backlight"); desc = "PMIC"; } else { @@ -1513,11 +1512,11 @@ static int ext_pwm_setup_backlight(struct intel_connector *connector, drm_dbg_kms(&dev_priv->drm, "PWM already enabled at freq %ld, VBT freq %d, level %d\n", NSEC_PER_SEC / (unsigned long)panel->backlight.pwm_state.period, - get_vbt_pwm_freq(connector), level); + get_vbt_pwm_freq(dev_priv), level); } else { /* Set period from VBT frequency, leave other settings at 0. */ panel->backlight.pwm_state.period = - NSEC_PER_SEC / get_vbt_pwm_freq(connector); + NSEC_PER_SEC / get_vbt_pwm_freq(dev_priv); } drm_info(&dev_priv->drm, "Using %s PWM for LCD backlight control\n", @@ -1602,7 +1601,7 @@ int intel_backlight_setup(struct intel_connector *connector, enum pipe pipe) struct intel_panel *panel = &connector->panel; int ret; - if (!connector->panel.vbt.backlight.present) { + if (!dev_priv->vbt.backlight.present) { if (dev_priv->quirks & QUIRK_BACKLIGHT_PRESENT) { drm_dbg_kms(&dev_priv->drm, "no backlight present per VBT, but present per quirk\n"); diff --git a/drivers/gpu/drm/i915/display/intel_bios.c b/drivers/gpu/drm/i915/display/intel_bios.c index b5de61fe9cc6..91caf4523b34 100644 --- a/drivers/gpu/drm/i915/display/intel_bios.c +++ b/drivers/gpu/drm/i915/display/intel_bios.c @@ -682,8 +682,7 @@ static int get_panel_type(struct drm_i915_private *i915) /* Parse general panel options */ static void -parse_panel_options(struct drm_i915_private *i915, - struct intel_panel *panel) +parse_panel_options(struct drm_i915_private *i915) { const struct bdb_lvds_options *lvds_options; int panel_type; @@ -693,11 +692,11 @@ parse_panel_options(struct drm_i915_private *i915, if (!lvds_options) return; - panel->vbt.lvds_dither = lvds_options->pixel_dither; + i915->vbt.lvds_dither = lvds_options->pixel_dither; panel_type = get_panel_type(i915); - panel->vbt.panel_type = panel_type; + i915->vbt.panel_type = panel_type; drrs_mode = (lvds_options->dps_panel_type_bits >> (panel_type * 2)) & MODE_MASK; @@ -708,16 +707,16 @@ parse_panel_options(struct drm_i915_private *i915, */ switch (drrs_mode) { case 0: - panel->vbt.drrs_type = DRRS_TYPE_STATIC; + i915->vbt.drrs_type = DRRS_TYPE_STATIC; drm_dbg_kms(&i915->drm, "DRRS supported mode is static\n"); break; case 2: - panel->vbt.drrs_type = DRRS_TYPE_SEAMLESS; + i915->vbt.drrs_type = DRRS_TYPE_SEAMLESS; drm_dbg_kms(&i915->drm, "DRRS supported mode is seamless\n"); break; default: - panel->vbt.drrs_type = DRRS_TYPE_NONE; + i915->vbt.drrs_type = DRRS_TYPE_NONE; drm_dbg_kms(&i915->drm, "DRRS not supported (VBT input)\n"); break; @@ -726,14 +725,13 @@ parse_panel_options(struct drm_i915_private *i915, static void parse_lfp_panel_dtd(struct drm_i915_private *i915, - struct intel_panel *panel, const struct bdb_lvds_lfp_data *lvds_lfp_data, const struct bdb_lvds_lfp_data_ptrs *lvds_lfp_data_ptrs) { const struct lvds_dvo_timing *panel_dvo_timing; const struct lvds_fp_timing *fp_timing; struct drm_display_mode *panel_fixed_mode; - int panel_type = panel->vbt.panel_type; + int panel_type = i915->vbt.panel_type; panel_dvo_timing = get_lvds_dvo_timing(lvds_lfp_data, lvds_lfp_data_ptrs, @@ -745,7 +743,7 @@ parse_lfp_panel_dtd(struct drm_i915_private *i915, fill_detail_timing_data(panel_fixed_mode, panel_dvo_timing); - panel->vbt.lfp_lvds_vbt_mode = panel_fixed_mode; + i915->vbt.lfp_lvds_vbt_mode = panel_fixed_mode; drm_dbg_kms(&i915->drm, "Found panel mode in BIOS VBT legacy lfp table: " DRM_MODE_FMT "\n", @@ -758,21 +756,20 @@ parse_lfp_panel_dtd(struct drm_i915_private *i915, /* check the resolution, just to be sure */ if (fp_timing->x_res == panel_fixed_mode->hdisplay && fp_timing->y_res == panel_fixed_mode->vdisplay) { - panel->vbt.bios_lvds_val = fp_timing->lvds_reg_val; + i915->vbt.bios_lvds_val = fp_timing->lvds_reg_val; drm_dbg_kms(&i915->drm, "VBT initial LVDS value %x\n", - panel->vbt.bios_lvds_val); + i915->vbt.bios_lvds_val); } } static void -parse_lfp_data(struct drm_i915_private *i915, - struct intel_panel *panel) +parse_lfp_data(struct drm_i915_private *i915) { const struct bdb_lvds_lfp_data *data; const struct bdb_lvds_lfp_data_tail *tail; const struct bdb_lvds_lfp_data_ptrs *ptrs; - int panel_type = panel->vbt.panel_type; + int panel_type = i915->vbt.panel_type; ptrs = find_section(i915, BDB_LVDS_LFP_DATA_PTRS); if (!ptrs) @@ -782,25 +779,24 @@ parse_lfp_data(struct drm_i915_private *i915, if (!data) return; - if (!panel->vbt.lfp_lvds_vbt_mode) - parse_lfp_panel_dtd(i915, panel, data, ptrs); + if (!i915->vbt.lfp_lvds_vbt_mode) + parse_lfp_panel_dtd(i915, data, ptrs); tail = get_lfp_data_tail(data, ptrs); if (!tail) return; if (i915->vbt.version >= 188) { - panel->vbt.seamless_drrs_min_refresh_rate = + i915->vbt.seamless_drrs_min_refresh_rate = tail->seamless_drrs_min_refresh_rate[panel_type]; drm_dbg_kms(&i915->drm, "Seamless DRRS min refresh rate: %d Hz\n", - panel->vbt.seamless_drrs_min_refresh_rate); + i915->vbt.seamless_drrs_min_refresh_rate); } } static void -parse_generic_dtd(struct drm_i915_private *i915, - struct intel_panel *panel) +parse_generic_dtd(struct drm_i915_private *i915) { const struct bdb_generic_dtd *generic_dtd; const struct generic_dtd_entry *dtd; @@ -835,14 +831,14 @@ parse_generic_dtd(struct drm_i915_private *i915, num_dtd = (get_blocksize(generic_dtd) - sizeof(struct bdb_generic_dtd)) / generic_dtd->gdtd_size; - if (panel->vbt.panel_type >= num_dtd) { + if (i915->vbt.panel_type >= num_dtd) { drm_err(&i915->drm, "Panel type %d not found in table of %d DTD's\n", - panel->vbt.panel_type, num_dtd); + i915->vbt.panel_type, num_dtd); return; } - dtd = &generic_dtd->dtd[panel->vbt.panel_type]; + dtd = &generic_dtd->dtd[i915->vbt.panel_type]; panel_fixed_mode = kzalloc(sizeof(*panel_fixed_mode), GFP_KERNEL); if (!panel_fixed_mode) @@ -885,16 +881,15 @@ parse_generic_dtd(struct drm_i915_private *i915, "Found panel mode in BIOS VBT generic dtd table: " DRM_MODE_FMT "\n", DRM_MODE_ARG(panel_fixed_mode)); - panel->vbt.lfp_lvds_vbt_mode = panel_fixed_mode; + i915->vbt.lfp_lvds_vbt_mode = panel_fixed_mode; } static void -parse_lfp_backlight(struct drm_i915_private *i915, - struct intel_panel *panel) +parse_lfp_backlight(struct drm_i915_private *i915) { const struct bdb_lfp_backlight_data *backlight_data; const struct lfp_backlight_data_entry *entry; - int panel_type = panel->vbt.panel_type; + int panel_type = i915->vbt.panel_type; u16 level; backlight_data = find_section(i915, BDB_LVDS_BACKLIGHT); @@ -910,15 +905,15 @@ parse_lfp_backlight(struct drm_i915_private *i915, entry = &backlight_data->data[panel_type]; - panel->vbt.backlight.present = entry->type == BDB_BACKLIGHT_TYPE_PWM; - if (!panel->vbt.backlight.present) { + i915->vbt.backlight.present = entry->type == BDB_BACKLIGHT_TYPE_PWM; + if (!i915->vbt.backlight.present) { drm_dbg_kms(&i915->drm, "PWM backlight not present in VBT (type %u)\n", entry->type); return; } - panel->vbt.backlight.type = INTEL_BACKLIGHT_DISPLAY_DDI; + i915->vbt.backlight.type = INTEL_BACKLIGHT_DISPLAY_DDI; if (i915->vbt.version >= 191) { size_t exp_size; @@ -933,13 +928,13 @@ parse_lfp_backlight(struct drm_i915_private *i915, const struct lfp_backlight_control_method *method; method = &backlight_data->backlight_control[panel_type]; - panel->vbt.backlight.type = method->type; - panel->vbt.backlight.controller = method->controller; + i915->vbt.backlight.type = method->type; + i915->vbt.backlight.controller = method->controller; } } - panel->vbt.backlight.pwm_freq_hz = entry->pwm_freq_hz; - panel->vbt.backlight.active_low_pwm = entry->active_low_pwm; + i915->vbt.backlight.pwm_freq_hz = entry->pwm_freq_hz; + i915->vbt.backlight.active_low_pwm = entry->active_low_pwm; if (i915->vbt.version >= 234) { u16 min_level; @@ -960,29 +955,28 @@ parse_lfp_backlight(struct drm_i915_private *i915, drm_warn(&i915->drm, "Brightness min level > 255\n"); level = 255; } - panel->vbt.backlight.min_brightness = min_level; + i915->vbt.backlight.min_brightness = min_level; - panel->vbt.backlight.brightness_precision_bits = + i915->vbt.backlight.brightness_precision_bits = backlight_data->brightness_precision_bits[panel_type]; } else { level = backlight_data->level[panel_type]; - panel->vbt.backlight.min_brightness = entry->min_brightness; + i915->vbt.backlight.min_brightness = entry->min_brightness; } drm_dbg_kms(&i915->drm, "VBT backlight PWM modulation frequency %u Hz, " "active %s, min brightness %u, level %u, controller %u\n", - panel->vbt.backlight.pwm_freq_hz, - panel->vbt.backlight.active_low_pwm ? "low" : "high", - panel->vbt.backlight.min_brightness, + i915->vbt.backlight.pwm_freq_hz, + i915->vbt.backlight.active_low_pwm ? "low" : "high", + i915->vbt.backlight.min_brightness, level, - panel->vbt.backlight.controller); + i915->vbt.backlight.controller); } /* Try to find sdvo panel data */ static void -parse_sdvo_panel_data(struct drm_i915_private *i915, - struct intel_panel *panel) +parse_sdvo_panel_data(struct drm_i915_private *i915) { const struct bdb_sdvo_panel_dtds *dtds; struct drm_display_mode *panel_fixed_mode; @@ -1015,7 +1009,7 @@ parse_sdvo_panel_data(struct drm_i915_private *i915, fill_detail_timing_data(panel_fixed_mode, &dtds->dtds[index]); - panel->vbt.sdvo_lvds_vbt_mode = panel_fixed_mode; + i915->vbt.sdvo_lvds_vbt_mode = panel_fixed_mode; drm_dbg_kms(&i915->drm, "Found SDVO panel mode in BIOS VBT tables: " DRM_MODE_FMT "\n", @@ -1194,17 +1188,6 @@ parse_driver_features(struct drm_i915_private *i915) driver->lvds_config != BDB_DRIVER_FEATURE_INT_SDVO_LVDS) i915->vbt.int_lvds_support = 0; } -} - -static void -parse_panel_driver_features(struct drm_i915_private *i915, - struct intel_panel *panel) -{ - const struct bdb_driver_features *driver; - - driver = find_section(i915, BDB_DRIVER_FEATURES); - if (!driver) - return; if (i915->vbt.version < 228) { drm_dbg_kms(&i915->drm, "DRRS State Enabled:%d\n", @@ -1216,18 +1199,17 @@ parse_panel_driver_features(struct drm_i915_private *i915, * driver->drrs_enabled=false */ if (!driver->drrs_enabled) - panel->vbt.drrs_type = DRRS_TYPE_NONE; + i915->vbt.drrs_type = DRRS_TYPE_NONE; - panel->vbt.psr.enable = driver->psr_enabled; + i915->vbt.psr.enable = driver->psr_enabled; } } static void -parse_power_conservation_features(struct drm_i915_private *i915, - struct intel_panel *panel) +parse_power_conservation_features(struct drm_i915_private *i915) { const struct bdb_lfp_power *power; - u8 panel_type = panel->vbt.panel_type; + u8 panel_type = i915->vbt.panel_type; if (i915->vbt.version < 228) return; @@ -1236,7 +1218,7 @@ parse_power_conservation_features(struct drm_i915_private *i915, if (!power) return; - panel->vbt.psr.enable = power->psr & BIT(panel_type); + i915->vbt.psr.enable = power->psr & BIT(panel_type); /* * If DRRS is not supported, drrs_type has to be set to 0. @@ -1245,20 +1227,19 @@ parse_power_conservation_features(struct drm_i915_private *i915, * power->drrs & BIT(panel_type)=false */ if (!(power->drrs & BIT(panel_type))) - panel->vbt.drrs_type = DRRS_TYPE_NONE; + i915->vbt.drrs_type = DRRS_TYPE_NONE; if (i915->vbt.version >= 232) - panel->vbt.edp.hobl = power->hobl & BIT(panel_type); + i915->vbt.edp.hobl = power->hobl & BIT(panel_type); } static void -parse_edp(struct drm_i915_private *i915, - struct intel_panel *panel) +parse_edp(struct drm_i915_private *i915) { const struct bdb_edp *edp; const struct edp_power_seq *edp_pps; const struct edp_fast_link_params *edp_link_params; - int panel_type = panel->vbt.panel_type; + int panel_type = i915->vbt.panel_type; edp = find_section(i915, BDB_EDP); if (!edp) @@ -1266,13 +1247,13 @@ parse_edp(struct drm_i915_private *i915, switch ((edp->color_depth >> (panel_type * 2)) & 3) { case EDP_18BPP: - panel->vbt.edp.bpp = 18; + i915->vbt.edp.bpp = 18; break; case EDP_24BPP: - panel->vbt.edp.bpp = 24; + i915->vbt.edp.bpp = 24; break; case EDP_30BPP: - panel->vbt.edp.bpp = 30; + i915->vbt.edp.bpp = 30; break; } @@ -1280,14 +1261,14 @@ parse_edp(struct drm_i915_private *i915, edp_pps = &edp->power_seqs[panel_type]; edp_link_params = &edp->fast_link_params[panel_type]; - panel->vbt.edp.pps = *edp_pps; + i915->vbt.edp.pps = *edp_pps; switch (edp_link_params->rate) { case EDP_RATE_1_62: - panel->vbt.edp.rate = DP_LINK_BW_1_62; + i915->vbt.edp.rate = DP_LINK_BW_1_62; break; case EDP_RATE_2_7: - panel->vbt.edp.rate = DP_LINK_BW_2_7; + i915->vbt.edp.rate = DP_LINK_BW_2_7; break; default: drm_dbg_kms(&i915->drm, @@ -1298,13 +1279,13 @@ parse_edp(struct drm_i915_private *i915, switch (edp_link_params->lanes) { case EDP_LANE_1: - panel->vbt.edp.lanes = 1; + i915->vbt.edp.lanes = 1; break; case EDP_LANE_2: - panel->vbt.edp.lanes = 2; + i915->vbt.edp.lanes = 2; break; case EDP_LANE_4: - panel->vbt.edp.lanes = 4; + i915->vbt.edp.lanes = 4; break; default: drm_dbg_kms(&i915->drm, @@ -1315,16 +1296,16 @@ parse_edp(struct drm_i915_private *i915, switch (edp_link_params->preemphasis) { case EDP_PREEMPHASIS_NONE: - panel->vbt.edp.preemphasis = DP_TRAIN_PRE_EMPH_LEVEL_0; + i915->vbt.edp.preemphasis = DP_TRAIN_PRE_EMPH_LEVEL_0; break; case EDP_PREEMPHASIS_3_5dB: - panel->vbt.edp.preemphasis = DP_TRAIN_PRE_EMPH_LEVEL_1; + i915->vbt.edp.preemphasis = DP_TRAIN_PRE_EMPH_LEVEL_1; break; case EDP_PREEMPHASIS_6dB: - panel->vbt.edp.preemphasis = DP_TRAIN_PRE_EMPH_LEVEL_2; + i915->vbt.edp.preemphasis = DP_TRAIN_PRE_EMPH_LEVEL_2; break; case EDP_PREEMPHASIS_9_5dB: - panel->vbt.edp.preemphasis = DP_TRAIN_PRE_EMPH_LEVEL_3; + i915->vbt.edp.preemphasis = DP_TRAIN_PRE_EMPH_LEVEL_3; break; default: drm_dbg_kms(&i915->drm, @@ -1335,16 +1316,16 @@ parse_edp(struct drm_i915_private *i915, switch (edp_link_params->vswing) { case EDP_VSWING_0_4V: - panel->vbt.edp.vswing = DP_TRAIN_VOLTAGE_SWING_LEVEL_0; + i915->vbt.edp.vswing = DP_TRAIN_VOLTAGE_SWING_LEVEL_0; break; case EDP_VSWING_0_6V: - panel->vbt.edp.vswing = DP_TRAIN_VOLTAGE_SWING_LEVEL_1; + i915->vbt.edp.vswing = DP_TRAIN_VOLTAGE_SWING_LEVEL_1; break; case EDP_VSWING_0_8V: - panel->vbt.edp.vswing = DP_TRAIN_VOLTAGE_SWING_LEVEL_2; + i915->vbt.edp.vswing = DP_TRAIN_VOLTAGE_SWING_LEVEL_2; break; case EDP_VSWING_1_2V: - panel->vbt.edp.vswing = DP_TRAIN_VOLTAGE_SWING_LEVEL_3; + i915->vbt.edp.vswing = DP_TRAIN_VOLTAGE_SWING_LEVEL_3; break; default: drm_dbg_kms(&i915->drm, @@ -1358,25 +1339,24 @@ parse_edp(struct drm_i915_private *i915, /* Don't read from VBT if module parameter has valid value*/ if (i915->params.edp_vswing) { - panel->vbt.edp.low_vswing = + i915->vbt.edp.low_vswing = i915->params.edp_vswing == 1; } else { vswing = (edp->edp_vswing_preemph >> (panel_type * 4)) & 0xF; - panel->vbt.edp.low_vswing = vswing == 0; + i915->vbt.edp.low_vswing = vswing == 0; } } - panel->vbt.edp.drrs_msa_timing_delay = + i915->vbt.edp.drrs_msa_timing_delay = (edp->sdrrs_msa_timing_delay >> (panel_type * 2)) & 3; } static void -parse_psr(struct drm_i915_private *i915, - struct intel_panel *panel) +parse_psr(struct drm_i915_private *i915) { const struct bdb_psr *psr; const struct psr_table *psr_table; - int panel_type = panel->vbt.panel_type; + int panel_type = i915->vbt.panel_type; psr = find_section(i915, BDB_PSR); if (!psr) { @@ -1386,11 +1366,11 @@ parse_psr(struct drm_i915_private *i915, psr_table = &psr->psr_table[panel_type]; - panel->vbt.psr.full_link = psr_table->full_link; - panel->vbt.psr.require_aux_wakeup = psr_table->require_aux_to_wakeup; + i915->vbt.psr.full_link = psr_table->full_link; + i915->vbt.psr.require_aux_wakeup = psr_table->require_aux_to_wakeup; /* Allowed VBT values goes from 0 to 15 */ - panel->vbt.psr.idle_frames = psr_table->idle_frames < 0 ? 0 : + i915->vbt.psr.idle_frames = psr_table->idle_frames < 0 ? 0 : psr_table->idle_frames > 15 ? 15 : psr_table->idle_frames; /* @@ -1401,13 +1381,13 @@ parse_psr(struct drm_i915_private *i915, (DISPLAY_VER(i915) >= 9 && !IS_BROXTON(i915))) { switch (psr_table->tp1_wakeup_time) { case 0: - panel->vbt.psr.tp1_wakeup_time_us = 500; + i915->vbt.psr.tp1_wakeup_time_us = 500; break; case 1: - panel->vbt.psr.tp1_wakeup_time_us = 100; + i915->vbt.psr.tp1_wakeup_time_us = 100; break; case 3: - panel->vbt.psr.tp1_wakeup_time_us = 0; + i915->vbt.psr.tp1_wakeup_time_us = 0; break; default: drm_dbg_kms(&i915->drm, @@ -1415,19 +1395,19 @@ parse_psr(struct drm_i915_private *i915, psr_table->tp1_wakeup_time); fallthrough; case 2: - panel->vbt.psr.tp1_wakeup_time_us = 2500; + i915->vbt.psr.tp1_wakeup_time_us = 2500; break; } switch (psr_table->tp2_tp3_wakeup_time) { case 0: - panel->vbt.psr.tp2_tp3_wakeup_time_us = 500; + i915->vbt.psr.tp2_tp3_wakeup_time_us = 500; break; case 1: - panel->vbt.psr.tp2_tp3_wakeup_time_us = 100; + i915->vbt.psr.tp2_tp3_wakeup_time_us = 100; break; case 3: - panel->vbt.psr.tp2_tp3_wakeup_time_us = 0; + i915->vbt.psr.tp2_tp3_wakeup_time_us = 0; break; default: drm_dbg_kms(&i915->drm, @@ -1435,12 +1415,12 @@ parse_psr(struct drm_i915_private *i915, psr_table->tp2_tp3_wakeup_time); fallthrough; case 2: - panel->vbt.psr.tp2_tp3_wakeup_time_us = 2500; + i915->vbt.psr.tp2_tp3_wakeup_time_us = 2500; break; } } else { - panel->vbt.psr.tp1_wakeup_time_us = psr_table->tp1_wakeup_time * 100; - panel->vbt.psr.tp2_tp3_wakeup_time_us = psr_table->tp2_tp3_wakeup_time * 100; + i915->vbt.psr.tp1_wakeup_time_us = psr_table->tp1_wakeup_time * 100; + i915->vbt.psr.tp2_tp3_wakeup_time_us = psr_table->tp2_tp3_wakeup_time * 100; } if (i915->vbt.version >= 226) { @@ -1462,66 +1442,62 @@ parse_psr(struct drm_i915_private *i915, wakeup_time = 2500; break; } - panel->vbt.psr.psr2_tp2_tp3_wakeup_time_us = wakeup_time; + i915->vbt.psr.psr2_tp2_tp3_wakeup_time_us = wakeup_time; } else { /* Reusing PSR1 wakeup time for PSR2 in older VBTs */ - panel->vbt.psr.psr2_tp2_tp3_wakeup_time_us = panel->vbt.psr.tp2_tp3_wakeup_time_us; + i915->vbt.psr.psr2_tp2_tp3_wakeup_time_us = i915->vbt.psr.tp2_tp3_wakeup_time_us; } } static void parse_dsi_backlight_ports(struct drm_i915_private *i915, - struct intel_panel *panel, - enum port port) + u16 version, enum port port) { - enum port port_bc = DISPLAY_VER(i915) >= 11 ? PORT_B : PORT_C; - - if (!panel->vbt.dsi.config->dual_link || i915->vbt.version < 197) { - panel->vbt.dsi.bl_ports = BIT(port); - if (panel->vbt.dsi.config->cabc_supported) - panel->vbt.dsi.cabc_ports = BIT(port); + if (!i915->vbt.dsi.config->dual_link || version < 197) { + i915->vbt.dsi.bl_ports = BIT(port); + if (i915->vbt.dsi.config->cabc_supported) + i915->vbt.dsi.cabc_ports = BIT(port); return; } - switch (panel->vbt.dsi.config->dl_dcs_backlight_ports) { + switch (i915->vbt.dsi.config->dl_dcs_backlight_ports) { case DL_DCS_PORT_A: - panel->vbt.dsi.bl_ports = BIT(PORT_A); + i915->vbt.dsi.bl_ports = BIT(PORT_A); break; case DL_DCS_PORT_C: - panel->vbt.dsi.bl_ports = BIT(port_bc); + i915->vbt.dsi.bl_ports = BIT(PORT_C); break; default: case DL_DCS_PORT_A_AND_C: - panel->vbt.dsi.bl_ports = BIT(PORT_A) | BIT(port_bc); + i915->vbt.dsi.bl_ports = BIT(PORT_A) | BIT(PORT_C); break; } - if (!panel->vbt.dsi.config->cabc_supported) + if (!i915->vbt.dsi.config->cabc_supported) return; - switch (panel->vbt.dsi.config->dl_dcs_cabc_ports) { + switch (i915->vbt.dsi.config->dl_dcs_cabc_ports) { case DL_DCS_PORT_A: - panel->vbt.dsi.cabc_ports = BIT(PORT_A); + i915->vbt.dsi.cabc_ports = BIT(PORT_A); break; case DL_DCS_PORT_C: - panel->vbt.dsi.cabc_ports = BIT(port_bc); + i915->vbt.dsi.cabc_ports = BIT(PORT_C); break; default: case DL_DCS_PORT_A_AND_C: - panel->vbt.dsi.cabc_ports = - BIT(PORT_A) | BIT(port_bc); + i915->vbt.dsi.cabc_ports = + BIT(PORT_A) | BIT(PORT_C); break; } } static void -parse_mipi_config(struct drm_i915_private *i915, - struct intel_panel *panel) +parse_mipi_config(struct drm_i915_private *i915) { const struct bdb_mipi_config *start; const struct mipi_config *config; const struct mipi_pps_data *pps; - int panel_type = panel->vbt.panel_type; + int panel_type = i915->vbt.panel_type; enum port port; /* parse MIPI blocks only if LFP type is MIPI */ @@ -1529,7 +1505,7 @@ parse_mipi_config(struct drm_i915_private *i915, return; /* Initialize this to undefined indicating no generic MIPI support */ - panel->vbt.dsi.panel_id = MIPI_DSI_UNDEFINED_PANEL_ID; + i915->vbt.dsi.panel_id = MIPI_DSI_UNDEFINED_PANEL_ID; /* Block #40 is already parsed and panel_fixed_mode is * stored in i915->lfp_lvds_vbt_mode @@ -1556,17 +1532,17 @@ parse_mipi_config(struct drm_i915_private *i915, pps = &start->pps[panel_type]; /* store as of now full data. Trim when we realise all is not needed */ - panel->vbt.dsi.config = kmemdup(config, sizeof(struct mipi_config), GFP_KERNEL); - if (!panel->vbt.dsi.config) + i915->vbt.dsi.config = kmemdup(config, sizeof(struct mipi_config), GFP_KERNEL); + if (!i915->vbt.dsi.config) return; - panel->vbt.dsi.pps = kmemdup(pps, sizeof(struct mipi_pps_data), GFP_KERNEL); - if (!panel->vbt.dsi.pps) { - kfree(panel->vbt.dsi.config); + i915->vbt.dsi.pps = kmemdup(pps, sizeof(struct mipi_pps_data), GFP_KERNEL); + if (!i915->vbt.dsi.pps) { + kfree(i915->vbt.dsi.config); return; } - parse_dsi_backlight_ports(i915, panel, port); + parse_dsi_backlight_ports(i915, i915->vbt.version, port); /* FIXME is the 90 vs. 270 correct? */ switch (config->rotation) { @@ -1575,25 +1551,25 @@ parse_mipi_config(struct drm_i915_private *i915, * Most (all?) VBTs claim 0 degrees despite having * an upside down panel, thus we do not trust this. */ - panel->vbt.dsi.orientation = + i915->vbt.dsi.orientation = DRM_MODE_PANEL_ORIENTATION_UNKNOWN; break; case ENABLE_ROTATION_90: - panel->vbt.dsi.orientation = + i915->vbt.dsi.orientation = DRM_MODE_PANEL_ORIENTATION_RIGHT_UP; break; case ENABLE_ROTATION_180: - panel->vbt.dsi.orientation = + i915->vbt.dsi.orientation = DRM_MODE_PANEL_ORIENTATION_BOTTOM_UP; break; case ENABLE_ROTATION_270: - panel->vbt.dsi.orientation = + i915->vbt.dsi.orientation = DRM_MODE_PANEL_ORIENTATION_LEFT_UP; break; } /* We have mandatory mipi config blocks. Initialize as generic panel */ - panel->vbt.dsi.panel_id = MIPI_DSI_GENERIC_PANEL_ID; + i915->vbt.dsi.panel_id = MIPI_DSI_GENERIC_PANEL_ID; } /* Find the sequence block and size for the given panel. */ @@ -1756,14 +1732,13 @@ static int goto_next_sequence_v3(const u8 *data, int index, int total) * Get len of pre-fixed deassert fragment from a v1 init OTP sequence, * skip all delay + gpio operands and stop at the first DSI packet op. */ -static int get_init_otp_deassert_fragment_len(struct drm_i915_private *i915, - struct intel_panel *panel) +static int get_init_otp_deassert_fragment_len(struct drm_i915_private *i915) { - const u8 *data = panel->vbt.dsi.sequence[MIPI_SEQ_INIT_OTP]; + const u8 *data = i915->vbt.dsi.sequence[MIPI_SEQ_INIT_OTP]; int index, len; if (drm_WARN_ON(&i915->drm, - !data || panel->vbt.dsi.seq_version != 1)) + !data || i915->vbt.dsi.seq_version != 1)) return 0; /* index = 1 to skip sequence byte */ @@ -1791,8 +1766,7 @@ static int get_init_otp_deassert_fragment_len(struct drm_i915_private *i915, * these devices we split the init OTP sequence into a deassert sequence and * the actual init OTP part. */ -static void fixup_mipi_sequences(struct drm_i915_private *i915, - struct intel_panel *panel) +static void fixup_mipi_sequences(struct drm_i915_private *i915) { u8 *init_otp; int len; @@ -1802,18 +1776,18 @@ static void fixup_mipi_sequences(struct drm_i915_private *i915, return; /* Limit this to v1 vid-mode sequences */ - if (panel->vbt.dsi.config->is_cmd_mode || - panel->vbt.dsi.seq_version != 1) + if (i915->vbt.dsi.config->is_cmd_mode || + i915->vbt.dsi.seq_version != 1) return; /* Only do this if there are otp and assert seqs and no deassert seq */ - if (!panel->vbt.dsi.sequence[MIPI_SEQ_INIT_OTP] || - !panel->vbt.dsi.sequence[MIPI_SEQ_ASSERT_RESET] || - panel->vbt.dsi.sequence[MIPI_SEQ_DEASSERT_RESET]) + if (!i915->vbt.dsi.sequence[MIPI_SEQ_INIT_OTP] || + !i915->vbt.dsi.sequence[MIPI_SEQ_ASSERT_RESET] || + i915->vbt.dsi.sequence[MIPI_SEQ_DEASSERT_RESET]) return; /* The deassert-sequence ends at the first DSI packet */ - len = get_init_otp_deassert_fragment_len(i915, panel); + len = get_init_otp_deassert_fragment_len(i915); if (!len) return; @@ -1821,26 +1795,25 @@ static void fixup_mipi_sequences(struct drm_i915_private *i915, "Using init OTP fragment to deassert reset\n"); /* Copy the fragment, update seq byte and terminate it */ - init_otp = (u8 *)panel->vbt.dsi.sequence[MIPI_SEQ_INIT_OTP]; - panel->vbt.dsi.deassert_seq = kmemdup(init_otp, len + 1, GFP_KERNEL); - if (!panel->vbt.dsi.deassert_seq) + init_otp = (u8 *)i915->vbt.dsi.sequence[MIPI_SEQ_INIT_OTP]; + i915->vbt.dsi.deassert_seq = kmemdup(init_otp, len + 1, GFP_KERNEL); + if (!i915->vbt.dsi.deassert_seq) return; - panel->vbt.dsi.deassert_seq[0] = MIPI_SEQ_DEASSERT_RESET; - panel->vbt.dsi.deassert_seq[len] = MIPI_SEQ_ELEM_END; + i915->vbt.dsi.deassert_seq[0] = MIPI_SEQ_DEASSERT_RESET; + i915->vbt.dsi.deassert_seq[len] = MIPI_SEQ_ELEM_END; /* Use the copy for deassert */ - panel->vbt.dsi.sequence[MIPI_SEQ_DEASSERT_RESET] = - panel->vbt.dsi.deassert_seq; + i915->vbt.dsi.sequence[MIPI_SEQ_DEASSERT_RESET] = + i915->vbt.dsi.deassert_seq; /* Replace the last byte of the fragment with init OTP seq byte */ init_otp[len - 1] = MIPI_SEQ_INIT_OTP; /* And make MIPI_MIPI_SEQ_INIT_OTP point to it */ - panel->vbt.dsi.sequence[MIPI_SEQ_INIT_OTP] = init_otp + len - 1; + i915->vbt.dsi.sequence[MIPI_SEQ_INIT_OTP] = init_otp + len - 1; } static void -parse_mipi_sequence(struct drm_i915_private *i915, - struct intel_panel *panel) +parse_mipi_sequence(struct drm_i915_private *i915) { - int panel_type = panel->vbt.panel_type; + int panel_type = i915->vbt.panel_type; const struct bdb_mipi_sequence *sequence; const u8 *seq_data; u32 seq_size; @@ -1848,7 +1821,7 @@ parse_mipi_sequence(struct drm_i915_private *i915, int index = 0; /* Only our generic panel driver uses the sequence block. */ - if (panel->vbt.dsi.panel_id != MIPI_DSI_GENERIC_PANEL_ID) + if (i915->vbt.dsi.panel_id != MIPI_DSI_GENERIC_PANEL_ID) return; sequence = find_section(i915, BDB_MIPI_SEQUENCE); @@ -1894,7 +1867,7 @@ parse_mipi_sequence(struct drm_i915_private *i915, drm_dbg_kms(&i915->drm, "Unsupported sequence %u\n", seq_id); - panel->vbt.dsi.sequence[seq_id] = data + index; + i915->vbt.dsi.sequence[seq_id] = data + index; if (sequence->version >= 3) index = goto_next_sequence_v3(data, index, seq_size); @@ -1907,18 +1880,18 @@ parse_mipi_sequence(struct drm_i915_private *i915, } } - panel->vbt.dsi.data = data; - panel->vbt.dsi.size = seq_size; - panel->vbt.dsi.seq_version = sequence->version; + i915->vbt.dsi.data = data; + i915->vbt.dsi.size = seq_size; + i915->vbt.dsi.seq_version = sequence->version; - fixup_mipi_sequences(i915, panel); + fixup_mipi_sequences(i915); drm_dbg(&i915->drm, "MIPI related VBT parsing complete\n"); return; err: kfree(data); - memset(panel->vbt.dsi.sequence, 0, sizeof(panel->vbt.dsi.sequence)); + memset(i915->vbt.dsi.sequence, 0, sizeof(i915->vbt.dsi.sequence)); } static void @@ -2672,6 +2645,15 @@ init_vbt_defaults(struct drm_i915_private *i915) { i915->vbt.crt_ddc_pin = GMBUS_PIN_VGADDC; + /* Default to having backlight */ + i915->vbt.backlight.present = true; + + /* LFP panel data */ + i915->vbt.lvds_dither = 1; + + /* SDVO panel data */ + i915->vbt.sdvo_lvds_vbt_mode = NULL; + /* general features */ i915->vbt.int_tv_support = 1; i915->vbt.int_crt_support = 1; @@ -2691,17 +2673,6 @@ init_vbt_defaults(struct drm_i915_private *i915) i915->vbt.lvds_ssc_freq); } -/* Common defaults which may be overridden by VBT. */ -static void -init_vbt_panel_defaults(struct intel_panel *panel) -{ - /* Default to having backlight */ - panel->vbt.backlight.present = true; - - /* LFP panel data */ - panel->vbt.lvds_dither = true; -} - /* Defaults to initialize only if there is no VBT. */ static void init_vbt_missing_defaults(struct drm_i915_private *i915) @@ -2988,7 +2959,17 @@ void intel_bios_init(struct drm_i915_private *i915) /* Grab useful general definitions */ parse_general_features(i915); parse_general_definitions(i915); + parse_panel_options(i915); + parse_generic_dtd(i915); + parse_lfp_data(i915); + parse_lfp_backlight(i915); + parse_sdvo_panel_data(i915); parse_driver_features(i915); + parse_power_conservation_features(i915); + parse_edp(i915); + parse_psr(i915); + parse_mipi_config(i915); + parse_mipi_sequence(i915); /* Depends on child device list */ parse_compression_parameters(i915); @@ -3007,24 +2988,6 @@ void intel_bios_init(struct drm_i915_private *i915) kfree(oprom_vbt); } -void intel_bios_init_panel(struct drm_i915_private *i915, - struct intel_panel *panel) -{ - init_vbt_panel_defaults(panel); - - parse_panel_options(i915, panel); - parse_generic_dtd(i915, panel); - parse_lfp_data(i915, panel); - parse_lfp_backlight(i915, panel); - parse_sdvo_panel_data(i915, panel); - parse_panel_driver_features(i915, panel); - parse_power_conservation_features(i915, panel); - parse_edp(i915, panel); - parse_psr(i915, panel); - parse_mipi_config(i915, panel); - parse_mipi_sequence(i915, panel); -} - /** * intel_bios_driver_remove - Free any resources allocated by intel_bios_init() * @i915: i915 device instance @@ -3044,22 +3007,19 @@ void intel_bios_driver_remove(struct drm_i915_private *i915) list_del(&entry->node); kfree(entry); } -} -void intel_bios_fini_panel(struct intel_panel *panel) -{ - kfree(panel->vbt.sdvo_lvds_vbt_mode); - panel->vbt.sdvo_lvds_vbt_mode = NULL; - kfree(panel->vbt.lfp_lvds_vbt_mode); - panel->vbt.lfp_lvds_vbt_mode = NULL; - kfree(panel->vbt.dsi.data); - panel->vbt.dsi.data = NULL; - kfree(panel->vbt.dsi.pps); - panel->vbt.dsi.pps = NULL; - kfree(panel->vbt.dsi.config); - panel->vbt.dsi.config = NULL; - kfree(panel->vbt.dsi.deassert_seq); - panel->vbt.dsi.deassert_seq = NULL; + kfree(i915->vbt.sdvo_lvds_vbt_mode); + i915->vbt.sdvo_lvds_vbt_mode = NULL; + kfree(i915->vbt.lfp_lvds_vbt_mode); + i915->vbt.lfp_lvds_vbt_mode = NULL; + kfree(i915->vbt.dsi.data); + i915->vbt.dsi.data = NULL; + kfree(i915->vbt.dsi.pps); + i915->vbt.dsi.pps = NULL; + kfree(i915->vbt.dsi.config); + i915->vbt.dsi.config = NULL; + kfree(i915->vbt.dsi.deassert_seq); + i915->vbt.dsi.deassert_seq = NULL; } /** diff --git a/drivers/gpu/drm/i915/display/intel_bios.h b/drivers/gpu/drm/i915/display/intel_bios.h index 86129f015718..4709c4d29805 100644 --- a/drivers/gpu/drm/i915/display/intel_bios.h +++ b/drivers/gpu/drm/i915/display/intel_bios.h @@ -36,7 +36,6 @@ struct drm_i915_private; struct intel_bios_encoder_data; struct intel_crtc_state; struct intel_encoder; -struct intel_panel; enum port; enum intel_backlight_type { @@ -231,9 +230,6 @@ struct mipi_pps_data { } __packed; void intel_bios_init(struct drm_i915_private *dev_priv); -void intel_bios_init_panel(struct drm_i915_private *dev_priv, - struct intel_panel *panel); -void intel_bios_fini_panel(struct intel_panel *panel); void intel_bios_driver_remove(struct drm_i915_private *dev_priv); bool intel_bios_is_valid_vbt(const void *buf, size_t size); bool intel_bios_is_tv_present(struct drm_i915_private *dev_priv); diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c index 333871cf3a2c..9e6fa59eabba 100644 --- a/drivers/gpu/drm/i915/display/intel_ddi.c +++ b/drivers/gpu/drm/i915/display/intel_ddi.c @@ -3433,8 +3433,26 @@ static void intel_ddi_get_config(struct intel_encoder *encoder, pipe_config->has_audio = intel_ddi_is_audio_enabled(dev_priv, cpu_transcoder); - if (encoder->type == INTEL_OUTPUT_EDP) - intel_edp_fixup_vbt_bpp(encoder, pipe_config->pipe_bpp); + if (encoder->type == INTEL_OUTPUT_EDP && dev_priv->vbt.edp.bpp && + pipe_config->pipe_bpp > dev_priv->vbt.edp.bpp) { + /* + * This is a big fat ugly hack. + * + * Some machines in UEFI boot mode provide us a VBT that has 18 + * bpp and 1.62 GHz link bandwidth for eDP, which for reasons + * unknown we fail to light up. Yet the same BIOS boots up with + * 24 bpp and 2.7 GHz link. Use the same bpp as the BIOS uses as + * max, not what it tells us to use. + * + * Note: This will still be broken if the eDP panel is not lit + * up by the BIOS, and thus we can't get the mode at module + * load. + */ + drm_dbg_kms(&dev_priv->drm, + "pipe has %d bpp for eDP panel, overriding BIOS-provided max %d bpp\n", + pipe_config->pipe_bpp, dev_priv->vbt.edp.bpp); + dev_priv->vbt.edp.bpp = pipe_config->pipe_bpp; + } ddi_dotclock_get(pipe_config); diff --git a/drivers/gpu/drm/i915/display/intel_ddi_buf_trans.c b/drivers/gpu/drm/i915/display/intel_ddi_buf_trans.c index b490acd0ab69..85f58dd3df72 100644 --- a/drivers/gpu/drm/i915/display/intel_ddi_buf_trans.c +++ b/drivers/gpu/drm/i915/display/intel_ddi_buf_trans.c @@ -1062,18 +1062,17 @@ bool is_hobl_buf_trans(const struct intel_ddi_buf_trans *table) static bool use_edp_hobl(struct intel_encoder *encoder) { + struct drm_i915_private *i915 = to_i915(encoder->base.dev); struct intel_dp *intel_dp = enc_to_intel_dp(encoder); - struct intel_connector *connector = intel_dp->attached_connector; - return connector->panel.vbt.edp.hobl && !intel_dp->hobl_failed; + return i915->vbt.edp.hobl && !intel_dp->hobl_failed; } static bool use_edp_low_vswing(struct intel_encoder *encoder) { - struct intel_dp *intel_dp = enc_to_intel_dp(encoder); - struct intel_connector *connector = intel_dp->attached_connector; + struct drm_i915_private *i915 = to_i915(encoder->base.dev); - return connector->panel.vbt.edp.low_vswing; + return i915->vbt.edp.low_vswing; } static const struct intel_ddi_buf_trans * diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h index e2561c5d4953..408152f9f46a 100644 --- a/drivers/gpu/drm/i915/display/intel_display_types.h +++ b/drivers/gpu/drm/i915/display/intel_display_types.h @@ -279,73 +279,6 @@ struct intel_panel_bl_funcs { u32 (*hz_to_pwm)(struct intel_connector *connector, u32 hz); }; -enum drrs_type { - DRRS_TYPE_NONE, - DRRS_TYPE_STATIC, - DRRS_TYPE_SEAMLESS, -}; - -struct intel_vbt_panel_data { - struct drm_display_mode *lfp_lvds_vbt_mode; /* if any */ - struct drm_display_mode *sdvo_lvds_vbt_mode; /* if any */ - - /* Feature bits */ - unsigned int panel_type:4; - unsigned int lvds_dither:1; - unsigned int bios_lvds_val; /* initial [PCH_]LVDS reg val in VBIOS */ - - u8 seamless_drrs_min_refresh_rate; - enum drrs_type drrs_type; - - struct { - int rate; - int lanes; - int preemphasis; - int vswing; - int bpp; - struct edp_power_seq pps; - u8 drrs_msa_timing_delay; - bool low_vswing; - bool initialized; - bool hobl; - } edp; - - struct { - bool enable; - bool full_link; - bool require_aux_wakeup; - int idle_frames; - int tp1_wakeup_time_us; - int tp2_tp3_wakeup_time_us; - int psr2_tp2_tp3_wakeup_time_us; - } psr; - - struct { - u16 pwm_freq_hz; - u16 brightness_precision_bits; - bool present; - bool active_low_pwm; - u8 min_brightness; /* min_brightness/255 of max */ - u8 controller; /* brightness controller number */ - enum intel_backlight_type type; - } backlight; - - /* MIPI DSI */ - struct { - u16 panel_id; - struct mipi_config *config; - struct mipi_pps_data *pps; - u16 bl_ports; - u16 cabc_ports; - u8 seq_version; - u32 size; - u8 *data; - const u8 *sequence[MIPI_SEQ_MAX]; - u8 *deassert_seq; /* Used by fixup_mipi_sequences() */ - enum drm_panel_orientation orientation; - } dsi; -}; - struct intel_panel { struct list_head fixed_modes; @@ -385,8 +318,6 @@ struct intel_panel { const struct intel_panel_bl_funcs *pwm_funcs; void (*power)(struct intel_connector *, bool enable); } backlight; - - struct intel_vbt_panel_data vbt; }; struct intel_digital_port; diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c index 0efec6023fbe..fe8b6b72970a 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.c +++ b/drivers/gpu/drm/i915/display/intel_dp.c @@ -1246,12 +1246,11 @@ static int intel_dp_max_bpp(struct intel_dp *intel_dp, if (intel_dp_is_edp(intel_dp)) { /* Get bpp from vbt only for panels that dont have bpp in edid */ if (intel_connector->base.display_info.bpc == 0 && - intel_connector->panel.vbt.edp.bpp && - intel_connector->panel.vbt.edp.bpp < bpp) { + dev_priv->vbt.edp.bpp && dev_priv->vbt.edp.bpp < bpp) { drm_dbg_kms(&dev_priv->drm, "clamping bpp for eDP panel to BIOS-provided %i\n", - intel_connector->panel.vbt.edp.bpp); - bpp = intel_connector->panel.vbt.edp.bpp; + dev_priv->vbt.edp.bpp); + bpp = dev_priv->vbt.edp.bpp; } } @@ -1908,7 +1907,7 @@ intel_dp_drrs_compute_config(struct intel_connector *connector, } if (IS_IRONLAKE(i915) || IS_SANDYBRIDGE(i915) || IS_IVYBRIDGE(i915)) - pipe_config->msa_timing_delay = connector->panel.vbt.edp.drrs_msa_timing_delay; + pipe_config->msa_timing_delay = i915->vbt.edp.drrs_msa_timing_delay; pipe_config->has_drrs = true; @@ -2738,33 +2737,6 @@ static void intel_edp_mso_mode_fixup(struct intel_connector *connector, DRM_MODE_ARG(mode)); } -void intel_edp_fixup_vbt_bpp(struct intel_encoder *encoder, int pipe_bpp) -{ - struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); - struct intel_dp *intel_dp = enc_to_intel_dp(encoder); - struct intel_connector *connector = intel_dp->attached_connector; - - if (connector->panel.vbt.edp.bpp && pipe_bpp > connector->panel.vbt.edp.bpp) { - /* - * This is a big fat ugly hack. - * - * Some machines in UEFI boot mode provide us a VBT that has 18 - * bpp and 1.62 GHz link bandwidth for eDP, which for reasons - * unknown we fail to light up. Yet the same BIOS boots up with - * 24 bpp and 2.7 GHz link. Use the same bpp as the BIOS uses as - * max, not what it tells us to use. - * - * Note: This will still be broken if the eDP panel is not lit - * up by the BIOS, and thus we can't get the mode at module - * load. - */ - drm_dbg_kms(&dev_priv->drm, - "pipe has %d bpp for eDP panel, overriding BIOS-provided max %d bpp\n", - pipe_bpp, connector->panel.vbt.edp.bpp); - connector->panel.vbt.edp.bpp = pipe_bpp; - } -} - static void intel_edp_mso_init(struct intel_dp *intel_dp) { struct drm_i915_private *i915 = dp_to_i915(intel_dp); @@ -5240,10 +5212,8 @@ static bool intel_edp_init_connector(struct intel_dp *intel_dp, } intel_connector->edid = edid; - intel_bios_init_panel(dev_priv, &intel_connector->panel); - intel_panel_add_edid_fixed_modes(intel_connector, - intel_connector->panel.vbt.drrs_type != DRRS_TYPE_NONE); + dev_priv->vbt.drrs_type != DRRS_TYPE_NONE); /* MSO requires information from the EDID */ intel_edp_mso_init(intel_dp); diff --git a/drivers/gpu/drm/i915/display/intel_dp.h b/drivers/gpu/drm/i915/display/intel_dp.h index a54902c713a3..d457e17bdc57 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.h +++ b/drivers/gpu/drm/i915/display/intel_dp.h @@ -29,7 +29,6 @@ struct link_config_limits { int min_bpp, max_bpp; }; -void intel_edp_fixup_vbt_bpp(struct intel_encoder *encoder, int pipe_bpp); void intel_dp_adjust_compliance_config(struct intel_dp *intel_dp, struct intel_crtc_state *pipe_config, struct link_config_limits *limits); @@ -64,7 +63,6 @@ enum irqreturn intel_dp_hpd_pulse(struct intel_digital_port *dig_port, void intel_edp_backlight_on(const struct intel_crtc_state *crtc_state, const struct drm_connector_state *conn_state); void intel_edp_backlight_off(const struct drm_connector_state *conn_state); -void intel_edp_fixup_vbt_bpp(struct intel_encoder *encoder, int pipe_bpp); void intel_dp_mst_suspend(struct drm_i915_private *dev_priv); void intel_dp_mst_resume(struct drm_i915_private *dev_priv); int intel_dp_max_link_rate(struct intel_dp *intel_dp); diff --git a/drivers/gpu/drm/i915/display/intel_dp_aux_backlight.c b/drivers/gpu/drm/i915/display/intel_dp_aux_backlight.c index c92d5bb2326a..fb6cf30ee628 100644 --- a/drivers/gpu/drm/i915/display/intel_dp_aux_backlight.c +++ b/drivers/gpu/drm/i915/display/intel_dp_aux_backlight.c @@ -370,7 +370,7 @@ static int intel_dp_aux_vesa_setup_backlight(struct intel_connector *connector, int ret; ret = drm_edp_backlight_init(&intel_dp->aux, &panel->backlight.edp.vesa.info, - panel->vbt.backlight.pwm_freq_hz, intel_dp->edp_dpcd, + i915->vbt.backlight.pwm_freq_hz, intel_dp->edp_dpcd, ¤t_level, ¤t_mode); if (ret < 0) return ret; @@ -454,7 +454,7 @@ int intel_dp_aux_init_backlight_funcs(struct intel_connector *connector) case INTEL_DP_AUX_BACKLIGHT_OFF: return -ENODEV; case INTEL_DP_AUX_BACKLIGHT_AUTO: - switch (panel->vbt.backlight.type) { + switch (i915->vbt.backlight.type) { case INTEL_BACKLIGHT_VESA_EDP_AUX_INTERFACE: try_vesa_interface = true; break; @@ -466,7 +466,7 @@ int intel_dp_aux_init_backlight_funcs(struct intel_connector *connector) } break; case INTEL_DP_AUX_BACKLIGHT_ON: - if (panel->vbt.backlight.type != INTEL_BACKLIGHT_VESA_EDP_AUX_INTERFACE) + if (i915->vbt.backlight.type != INTEL_BACKLIGHT_VESA_EDP_AUX_INTERFACE) try_intel_interface = true; try_vesa_interface = true; diff --git a/drivers/gpu/drm/i915/display/intel_drrs.c b/drivers/gpu/drm/i915/display/intel_drrs.c index 7da4a9cbe4ba..166caf293f7b 100644 --- a/drivers/gpu/drm/i915/display/intel_drrs.c +++ b/drivers/gpu/drm/i915/display/intel_drrs.c @@ -217,6 +217,9 @@ static void intel_drrs_frontbuffer_update(struct drm_i915_private *dev_priv, { struct intel_crtc *crtc; + if (dev_priv->vbt.drrs_type != DRRS_TYPE_SEAMLESS) + return; + for_each_intel_crtc(&dev_priv->drm, crtc) { unsigned int frontbuffer_bits; diff --git a/drivers/gpu/drm/i915/display/intel_dsi.c b/drivers/gpu/drm/i915/display/intel_dsi.c index 35e121cd226c..389a8c24cdc1 100644 --- a/drivers/gpu/drm/i915/display/intel_dsi.c +++ b/drivers/gpu/drm/i915/display/intel_dsi.c @@ -102,7 +102,7 @@ intel_dsi_get_panel_orientation(struct intel_connector *connector) struct drm_i915_private *dev_priv = to_i915(connector->base.dev); enum drm_panel_orientation orientation; - orientation = connector->panel.vbt.dsi.orientation; + orientation = dev_priv->vbt.dsi.orientation; if (orientation != DRM_MODE_PANEL_ORIENTATION_UNKNOWN) return orientation; diff --git a/drivers/gpu/drm/i915/display/intel_dsi_dcs_backlight.c b/drivers/gpu/drm/i915/display/intel_dsi_dcs_backlight.c index 1bc7118c56a2..7d234429e71e 100644 --- a/drivers/gpu/drm/i915/display/intel_dsi_dcs_backlight.c +++ b/drivers/gpu/drm/i915/display/intel_dsi_dcs_backlight.c @@ -160,10 +160,12 @@ static void dcs_enable_backlight(const struct intel_crtc_state *crtc_state, static int dcs_setup_backlight(struct intel_connector *connector, enum pipe unused) { + struct drm_device *dev = connector->base.dev; + struct drm_i915_private *dev_priv = to_i915(dev); struct intel_panel *panel = &connector->panel; - if (panel->vbt.backlight.brightness_precision_bits > 8) - panel->backlight.max = (1 << panel->vbt.backlight.brightness_precision_bits) - 1; + if (dev_priv->vbt.backlight.brightness_precision_bits > 8) + panel->backlight.max = (1 << dev_priv->vbt.backlight.brightness_precision_bits) - 1; else panel->backlight.max = PANEL_PWM_MAX_VALUE; @@ -183,10 +185,11 @@ static const struct intel_panel_bl_funcs dcs_bl_funcs = { int intel_dsi_dcs_init_backlight_funcs(struct intel_connector *intel_connector) { struct drm_device *dev = intel_connector->base.dev; + struct drm_i915_private *dev_priv = to_i915(dev); struct intel_encoder *encoder = intel_attached_encoder(intel_connector); struct intel_panel *panel = &intel_connector->panel; - if (panel->vbt.backlight.type != INTEL_BACKLIGHT_DSI_DCS) + if (dev_priv->vbt.backlight.type != INTEL_BACKLIGHT_DSI_DCS) return -ENODEV; if (drm_WARN_ON(dev, encoder->type != INTEL_OUTPUT_DSI)) diff --git a/drivers/gpu/drm/i915/display/intel_dsi_vbt.c b/drivers/gpu/drm/i915/display/intel_dsi_vbt.c index 75e8cc4337c9..dd24aef925f2 100644 --- a/drivers/gpu/drm/i915/display/intel_dsi_vbt.c +++ b/drivers/gpu/drm/i915/display/intel_dsi_vbt.c @@ -240,10 +240,9 @@ static const u8 *mipi_exec_delay(struct intel_dsi *intel_dsi, const u8 *data) return data; } -static void vlv_exec_gpio(struct intel_connector *connector, +static void vlv_exec_gpio(struct drm_i915_private *dev_priv, u8 gpio_source, u8 gpio_index, bool value) { - struct drm_i915_private *dev_priv = to_i915(connector->base.dev); struct gpio_map *map; u16 pconf0, padval; u32 tmp; @@ -257,7 +256,7 @@ static void vlv_exec_gpio(struct intel_connector *connector, map = &vlv_gpio_table[gpio_index]; - if (connector->panel.vbt.dsi.seq_version >= 3) { + if (dev_priv->vbt.dsi.seq_version >= 3) { /* XXX: this assumes vlv_gpio_table only has NC GPIOs. */ port = IOSF_PORT_GPIO_NC; } else { @@ -288,15 +287,14 @@ static void vlv_exec_gpio(struct intel_connector *connector, vlv_iosf_sb_put(dev_priv, BIT(VLV_IOSF_SB_GPIO)); } -static void chv_exec_gpio(struct intel_connector *connector, +static void chv_exec_gpio(struct drm_i915_private *dev_priv, u8 gpio_source, u8 gpio_index, bool value) { - struct drm_i915_private *dev_priv = to_i915(connector->base.dev); u16 cfg0, cfg1; u16 family_num; u8 port; - if (connector->panel.vbt.dsi.seq_version >= 3) { + if (dev_priv->vbt.dsi.seq_version >= 3) { if (gpio_index >= CHV_GPIO_IDX_START_SE) { /* XXX: it's unclear whether 255->57 is part of SE. */ gpio_index -= CHV_GPIO_IDX_START_SE; @@ -342,10 +340,9 @@ static void chv_exec_gpio(struct intel_connector *connector, vlv_iosf_sb_put(dev_priv, BIT(VLV_IOSF_SB_GPIO)); } -static void bxt_exec_gpio(struct intel_connector *connector, +static void bxt_exec_gpio(struct drm_i915_private *dev_priv, u8 gpio_source, u8 gpio_index, bool value) { - struct drm_i915_private *dev_priv = to_i915(connector->base.dev); /* XXX: this table is a quick ugly hack. */ static struct gpio_desc *bxt_gpio_table[U8_MAX + 1]; struct gpio_desc *gpio_desc = bxt_gpio_table[gpio_index]; @@ -369,11 +366,9 @@ static void bxt_exec_gpio(struct intel_connector *connector, gpiod_set_value(gpio_desc, value); } -static void icl_exec_gpio(struct intel_connector *connector, +static void icl_exec_gpio(struct drm_i915_private *dev_priv, u8 gpio_source, u8 gpio_index, bool value) { - struct drm_i915_private *dev_priv = to_i915(connector->base.dev); - drm_dbg_kms(&dev_priv->drm, "Skipping ICL GPIO element execution\n"); } @@ -381,19 +376,18 @@ static const u8 *mipi_exec_gpio(struct intel_dsi *intel_dsi, const u8 *data) { struct drm_device *dev = intel_dsi->base.base.dev; struct drm_i915_private *dev_priv = to_i915(dev); - struct intel_connector *connector = intel_dsi->attached_connector; u8 gpio_source, gpio_index = 0, gpio_number; bool value; drm_dbg_kms(&dev_priv->drm, "\n"); - if (connector->panel.vbt.dsi.seq_version >= 3) + if (dev_priv->vbt.dsi.seq_version >= 3) gpio_index = *data++; gpio_number = *data++; /* gpio source in sequence v2 only */ - if (connector->panel.vbt.dsi.seq_version == 2) + if (dev_priv->vbt.dsi.seq_version == 2) gpio_source = (*data >> 1) & 3; else gpio_source = 0; @@ -402,13 +396,13 @@ static const u8 *mipi_exec_gpio(struct intel_dsi *intel_dsi, const u8 *data) value = *data++ & 1; if (DISPLAY_VER(dev_priv) >= 11) - icl_exec_gpio(connector, gpio_source, gpio_index, value); + icl_exec_gpio(dev_priv, gpio_source, gpio_index, value); else if (IS_VALLEYVIEW(dev_priv)) - vlv_exec_gpio(connector, gpio_source, gpio_number, value); + vlv_exec_gpio(dev_priv, gpio_source, gpio_number, value); else if (IS_CHERRYVIEW(dev_priv)) - chv_exec_gpio(connector, gpio_source, gpio_number, value); + chv_exec_gpio(dev_priv, gpio_source, gpio_number, value); else - bxt_exec_gpio(connector, gpio_source, gpio_index, value); + bxt_exec_gpio(dev_priv, gpio_source, gpio_index, value); return data; } @@ -591,15 +585,14 @@ static void intel_dsi_vbt_exec(struct intel_dsi *intel_dsi, enum mipi_seq seq_id) { struct drm_i915_private *dev_priv = to_i915(intel_dsi->base.base.dev); - struct intel_connector *connector = intel_dsi->attached_connector; const u8 *data; fn_mipi_elem_exec mipi_elem_exec; if (drm_WARN_ON(&dev_priv->drm, - seq_id >= ARRAY_SIZE(connector->panel.vbt.dsi.sequence))) + seq_id >= ARRAY_SIZE(dev_priv->vbt.dsi.sequence))) return; - data = connector->panel.vbt.dsi.sequence[seq_id]; + data = dev_priv->vbt.dsi.sequence[seq_id]; if (!data) return; @@ -612,7 +605,7 @@ static void intel_dsi_vbt_exec(struct intel_dsi *intel_dsi, data++; /* Skip Size of Sequence. */ - if (connector->panel.vbt.dsi.seq_version >= 3) + if (dev_priv->vbt.dsi.seq_version >= 3) data += 4; while (1) { @@ -628,7 +621,7 @@ static void intel_dsi_vbt_exec(struct intel_dsi *intel_dsi, mipi_elem_exec = NULL; /* Size of Operation. */ - if (connector->panel.vbt.dsi.seq_version >= 3) + if (dev_priv->vbt.dsi.seq_version >= 3) operation_size = *data++; if (mipi_elem_exec) { @@ -676,10 +669,10 @@ void intel_dsi_vbt_exec_sequence(struct intel_dsi *intel_dsi, void intel_dsi_msleep(struct intel_dsi *intel_dsi, int msec) { - struct intel_connector *connector = intel_dsi->attached_connector; + struct drm_i915_private *dev_priv = to_i915(intel_dsi->base.base.dev); /* For v3 VBTs in vid-mode the delays are part of the VBT sequences */ - if (is_vid_mode(intel_dsi) && connector->panel.vbt.dsi.seq_version >= 3) + if (is_vid_mode(intel_dsi) && dev_priv->vbt.dsi.seq_version >= 3) return; msleep(msec); @@ -741,10 +734,9 @@ bool intel_dsi_vbt_init(struct intel_dsi *intel_dsi, u16 panel_id) { struct drm_device *dev = intel_dsi->base.base.dev; struct drm_i915_private *dev_priv = to_i915(dev); - struct intel_connector *connector = intel_dsi->attached_connector; - struct mipi_config *mipi_config = connector->panel.vbt.dsi.config; - struct mipi_pps_data *pps = connector->panel.vbt.dsi.pps; - struct drm_display_mode *mode = connector->panel.vbt.lfp_lvds_vbt_mode; + struct mipi_config *mipi_config = dev_priv->vbt.dsi.config; + struct mipi_pps_data *pps = dev_priv->vbt.dsi.pps; + struct drm_display_mode *mode = dev_priv->vbt.lfp_lvds_vbt_mode; u16 burst_mode_ratio; enum port port; @@ -880,8 +872,7 @@ void intel_dsi_vbt_gpio_init(struct intel_dsi *intel_dsi, bool panel_is_on) { struct drm_device *dev = intel_dsi->base.base.dev; struct drm_i915_private *dev_priv = to_i915(dev); - struct intel_connector *connector = intel_dsi->attached_connector; - struct mipi_config *mipi_config = connector->panel.vbt.dsi.config; + struct mipi_config *mipi_config = dev_priv->vbt.dsi.config; enum gpiod_flags flags = panel_is_on ? GPIOD_OUT_HIGH : GPIOD_OUT_LOW; bool want_backlight_gpio = false; bool want_panel_gpio = false; @@ -936,8 +927,7 @@ void intel_dsi_vbt_gpio_cleanup(struct intel_dsi *intel_dsi) { struct drm_device *dev = intel_dsi->base.base.dev; struct drm_i915_private *dev_priv = to_i915(dev); - struct intel_connector *connector = intel_dsi->attached_connector; - struct mipi_config *mipi_config = connector->panel.vbt.dsi.config; + struct mipi_config *mipi_config = dev_priv->vbt.dsi.config; if (intel_dsi->gpio_panel) { gpiod_put(intel_dsi->gpio_panel); diff --git a/drivers/gpu/drm/i915/display/intel_lvds.c b/drivers/gpu/drm/i915/display/intel_lvds.c index 9f250a70519a..e8478161f8b9 100644 --- a/drivers/gpu/drm/i915/display/intel_lvds.c +++ b/drivers/gpu/drm/i915/display/intel_lvds.c @@ -809,7 +809,7 @@ static bool compute_is_dual_link_lvds(struct intel_lvds_encoder *lvds_encoder) else val &= ~(LVDS_DETECTED | LVDS_PIPE_SEL_MASK); if (val == 0) - val = connector->panel.vbt.bios_lvds_val; + val = dev_priv->vbt.bios_lvds_val; return (val & LVDS_CLKB_POWER_MASK) == LVDS_CLKB_POWER_UP; } @@ -967,11 +967,9 @@ void intel_lvds_init(struct drm_i915_private *dev_priv) } intel_connector->edid = edid; - intel_bios_init_panel(dev_priv, &intel_connector->panel); - /* Try EDID first */ intel_panel_add_edid_fixed_modes(intel_connector, - intel_connector->panel.vbt.drrs_type != DRRS_TYPE_NONE); + dev_priv->vbt.drrs_type != DRRS_TYPE_NONE); /* Failed to get EDID, what about VBT? */ if (!intel_panel_preferred_fixed_mode(intel_connector)) diff --git a/drivers/gpu/drm/i915/display/intel_panel.c b/drivers/gpu/drm/i915/display/intel_panel.c index d055e4118558..d1d1b59102d6 100644 --- a/drivers/gpu/drm/i915/display/intel_panel.c +++ b/drivers/gpu/drm/i915/display/intel_panel.c @@ -75,8 +75,9 @@ const struct drm_display_mode * intel_panel_downclock_mode(struct intel_connector *connector, const struct drm_display_mode *adjusted_mode) { + struct drm_i915_private *i915 = to_i915(connector->base.dev); const struct drm_display_mode *fixed_mode, *best_mode = NULL; - int min_vrefresh = connector->panel.vbt.seamless_drrs_min_refresh_rate; + int min_vrefresh = i915->vbt.seamless_drrs_min_refresh_rate; int max_vrefresh = drm_mode_vrefresh(adjusted_mode); /* pick the fixed_mode with the lowest refresh rate */ @@ -112,11 +113,13 @@ int intel_panel_get_modes(struct intel_connector *connector) enum drrs_type intel_panel_drrs_type(struct intel_connector *connector) { + struct drm_i915_private *i915 = to_i915(connector->base.dev); + if (list_empty(&connector->panel.fixed_modes) || list_is_singular(&connector->panel.fixed_modes)) return DRRS_TYPE_NONE; - return connector->panel.vbt.drrs_type; + return i915->vbt.drrs_type; } int intel_panel_compute_config(struct intel_connector *connector, @@ -257,7 +260,7 @@ void intel_panel_add_vbt_lfp_fixed_mode(struct intel_connector *connector) struct drm_i915_private *i915 = to_i915(connector->base.dev); const struct drm_display_mode *mode; - mode = connector->panel.vbt.lfp_lvds_vbt_mode; + mode = i915->vbt.lfp_lvds_vbt_mode; if (!mode) return; @@ -271,7 +274,7 @@ void intel_panel_add_vbt_sdvo_fixed_mode(struct intel_connector *connector) struct drm_i915_private *i915 = to_i915(connector->base.dev); const struct drm_display_mode *mode; - mode = connector->panel.vbt.sdvo_lvds_vbt_mode; + mode = i915->vbt.sdvo_lvds_vbt_mode; if (!mode) return; @@ -636,8 +639,6 @@ void intel_panel_fini(struct intel_connector *connector) intel_backlight_destroy(panel); - intel_bios_fini_panel(panel); - list_for_each_entry_safe(fixed_mode, next, &panel->fixed_modes, head) { list_del(&fixed_mode->head); drm_mode_destroy(connector->base.dev, fixed_mode); diff --git a/drivers/gpu/drm/i915/display/intel_pps.c b/drivers/gpu/drm/i915/display/intel_pps.c index a226e4e5c569..5a598dd06039 100644 --- a/drivers/gpu/drm/i915/display/intel_pps.c +++ b/drivers/gpu/drm/i915/display/intel_pps.c @@ -209,8 +209,7 @@ static int bxt_power_sequencer_idx(struct intel_dp *intel_dp) { struct drm_i915_private *dev_priv = dp_to_i915(intel_dp); - struct intel_connector *connector = intel_dp->attached_connector; - int backlight_controller = connector->panel.vbt.backlight.controller; + int backlight_controller = dev_priv->vbt.backlight.controller; lockdep_assert_held(&dev_priv->pps_mutex); @@ -1160,84 +1159,53 @@ intel_pps_verify_state(struct intel_dp *intel_dp) } } -static void pps_init_delays_cur(struct intel_dp *intel_dp, - struct edp_power_seq *cur) +static void pps_init_delays(struct intel_dp *intel_dp) { struct drm_i915_private *dev_priv = dp_to_i915(intel_dp); + struct edp_power_seq cur, vbt, spec, + *final = &intel_dp->pps.pps_delays; lockdep_assert_held(&dev_priv->pps_mutex); - intel_pps_readout_hw_state(intel_dp, cur); - - intel_pps_dump_state(intel_dp, "cur", cur); -} + /* already initialized? */ + if (final->t11_t12 != 0) + return; -static void pps_init_delays_vbt(struct intel_dp *intel_dp, - struct edp_power_seq *vbt) -{ - struct drm_i915_private *dev_priv = dp_to_i915(intel_dp); - struct intel_connector *connector = intel_dp->attached_connector; + intel_pps_readout_hw_state(intel_dp, &cur); - *vbt = connector->panel.vbt.edp.pps; + intel_pps_dump_state(intel_dp, "cur", &cur); + vbt = dev_priv->vbt.edp.pps; /* On Toshiba Satellite P50-C-18C system the VBT T12 delay * of 500ms appears to be too short. Ocassionally the panel * just fails to power back on. Increasing the delay to 800ms * seems sufficient to avoid this problem. */ if (dev_priv->quirks & QUIRK_INCREASE_T12_DELAY) { - vbt->t11_t12 = max_t(u16, vbt->t11_t12, 1300 * 10); + vbt.t11_t12 = max_t(u16, vbt.t11_t12, 1300 * 10); drm_dbg_kms(&dev_priv->drm, "Increasing T12 panel delay as per the quirk to %d\n", - vbt->t11_t12); + vbt.t11_t12); } - /* T11_T12 delay is special and actually in units of 100ms, but zero * based in the hw (so we need to add 100 ms). But the sw vbt * table multiplies it with 1000 to make it in units of 100usec, * too. */ - vbt->t11_t12 += 100 * 10; - - intel_pps_dump_state(intel_dp, "vbt", vbt); -} - -static void pps_init_delays_spec(struct intel_dp *intel_dp, - struct edp_power_seq *spec) -{ - struct drm_i915_private *dev_priv = dp_to_i915(intel_dp); - - lockdep_assert_held(&dev_priv->pps_mutex); + vbt.t11_t12 += 100 * 10; /* Upper limits from eDP 1.3 spec. Note that we use the clunky units of * our hw here, which are all in 100usec. */ - spec->t1_t3 = 210 * 10; - spec->t8 = 50 * 10; /* no limit for t8, use t7 instead */ - spec->t9 = 50 * 10; /* no limit for t9, make it symmetric with t8 */ - spec->t10 = 500 * 10; + spec.t1_t3 = 210 * 10; + spec.t8 = 50 * 10; /* no limit for t8, use t7 instead */ + spec.t9 = 50 * 10; /* no limit for t9, make it symmetric with t8 */ + spec.t10 = 500 * 10; /* This one is special and actually in units of 100ms, but zero * based in the hw (so we need to add 100 ms). But the sw vbt * table multiplies it with 1000 to make it in units of 100usec, * too. */ - spec->t11_t12 = (510 + 100) * 10; - - intel_pps_dump_state(intel_dp, "spec", spec); -} - -static void pps_init_delays(struct intel_dp *intel_dp) -{ - struct drm_i915_private *dev_priv = dp_to_i915(intel_dp); - struct edp_power_seq cur, vbt, spec, - *final = &intel_dp->pps.pps_delays; - - lockdep_assert_held(&dev_priv->pps_mutex); - - /* already initialized? */ - if (final->t11_t12 != 0) - return; + spec.t11_t12 = (510 + 100) * 10; - pps_init_delays_cur(intel_dp, &cur); - pps_init_delays_vbt(intel_dp, &vbt); - pps_init_delays_spec(intel_dp, &spec); + intel_pps_dump_state(intel_dp, "vbt", &vbt); /* Use the max of the register settings and vbt. If both are * unset, fall back to the spec limits. */ diff --git a/drivers/gpu/drm/i915/display/intel_psr.c b/drivers/gpu/drm/i915/display/intel_psr.c index 8f09203e0cf0..06db407e2749 100644 --- a/drivers/gpu/drm/i915/display/intel_psr.c +++ b/drivers/gpu/drm/i915/display/intel_psr.c @@ -86,13 +86,10 @@ static bool psr_global_enabled(struct intel_dp *intel_dp) { - struct intel_connector *connector = intel_dp->attached_connector; struct drm_i915_private *i915 = dp_to_i915(intel_dp); switch (intel_dp->psr.debug & I915_PSR_DEBUG_MODE_MASK) { case I915_PSR_DEBUG_DEFAULT: - if (i915->params.enable_psr == -1) - return connector->panel.vbt.psr.enable; return i915->params.enable_psr; case I915_PSR_DEBUG_DISABLE: return false; @@ -402,7 +399,6 @@ static void intel_psr_enable_sink(struct intel_dp *intel_dp) static u32 intel_psr1_get_tp_time(struct intel_dp *intel_dp) { - struct intel_connector *connector = intel_dp->attached_connector; struct drm_i915_private *dev_priv = dp_to_i915(intel_dp); u32 val = 0; @@ -415,20 +411,20 @@ static u32 intel_psr1_get_tp_time(struct intel_dp *intel_dp) goto check_tp3_sel; } - if (connector->panel.vbt.psr.tp1_wakeup_time_us == 0) + if (dev_priv->vbt.psr.tp1_wakeup_time_us == 0) val |= EDP_PSR_TP1_TIME_0us; - else if (connector->panel.vbt.psr.tp1_wakeup_time_us <= 100) + else if (dev_priv->vbt.psr.tp1_wakeup_time_us <= 100) val |= EDP_PSR_TP1_TIME_100us; - else if (connector->panel.vbt.psr.tp1_wakeup_time_us <= 500) + else if (dev_priv->vbt.psr.tp1_wakeup_time_us <= 500) val |= EDP_PSR_TP1_TIME_500us; else val |= EDP_PSR_TP1_TIME_2500us; - if (connector->panel.vbt.psr.tp2_tp3_wakeup_time_us == 0) + if (dev_priv->vbt.psr.tp2_tp3_wakeup_time_us == 0) val |= EDP_PSR_TP2_TP3_TIME_0us; - else if (connector->panel.vbt.psr.tp2_tp3_wakeup_time_us <= 100) + else if (dev_priv->vbt.psr.tp2_tp3_wakeup_time_us <= 100) val |= EDP_PSR_TP2_TP3_TIME_100us; - else if (connector->panel.vbt.psr.tp2_tp3_wakeup_time_us <= 500) + else if (dev_priv->vbt.psr.tp2_tp3_wakeup_time_us <= 500) val |= EDP_PSR_TP2_TP3_TIME_500us; else val |= EDP_PSR_TP2_TP3_TIME_2500us; @@ -445,14 +441,13 @@ static u32 intel_psr1_get_tp_time(struct intel_dp *intel_dp) static u8 psr_compute_idle_frames(struct intel_dp *intel_dp) { - struct intel_connector *connector = intel_dp->attached_connector; struct drm_i915_private *dev_priv = dp_to_i915(intel_dp); int idle_frames; /* Let's use 6 as the minimum to cover all known cases including the * off-by-one issue that HW has in some cases. */ - idle_frames = max(6, connector->panel.vbt.psr.idle_frames); + idle_frames = max(6, dev_priv->vbt.psr.idle_frames); idle_frames = max(idle_frames, intel_dp->psr.sink_sync_latency + 1); if (drm_WARN_ON(&dev_priv->drm, idle_frames > 0xf)) @@ -488,19 +483,18 @@ static void hsw_activate_psr1(struct intel_dp *intel_dp) static u32 intel_psr2_get_tp_time(struct intel_dp *intel_dp) { - struct intel_connector *connector = intel_dp->attached_connector; struct drm_i915_private *dev_priv = dp_to_i915(intel_dp); u32 val = 0; if (dev_priv->params.psr_safest_params) return EDP_PSR2_TP2_TIME_2500us; - if (connector->panel.vbt.psr.psr2_tp2_tp3_wakeup_time_us >= 0 && - connector->panel.vbt.psr.psr2_tp2_tp3_wakeup_time_us <= 50) + if (dev_priv->vbt.psr.psr2_tp2_tp3_wakeup_time_us >= 0 && + dev_priv->vbt.psr.psr2_tp2_tp3_wakeup_time_us <= 50) val |= EDP_PSR2_TP2_TIME_50us; - else if (connector->panel.vbt.psr.psr2_tp2_tp3_wakeup_time_us <= 100) + else if (dev_priv->vbt.psr.psr2_tp2_tp3_wakeup_time_us <= 100) val |= EDP_PSR2_TP2_TIME_100us; - else if (connector->panel.vbt.psr.psr2_tp2_tp3_wakeup_time_us <= 500) + else if (dev_priv->vbt.psr.psr2_tp2_tp3_wakeup_time_us <= 500) val |= EDP_PSR2_TP2_TIME_500us; else val |= EDP_PSR2_TP2_TIME_2500us; @@ -2350,7 +2344,6 @@ void intel_psr_flush(struct drm_i915_private *dev_priv, */ void intel_psr_init(struct intel_dp *intel_dp) { - struct intel_connector *connector = intel_dp->attached_connector; struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp); struct drm_i915_private *dev_priv = dp_to_i915(intel_dp); @@ -2374,10 +2367,14 @@ void intel_psr_init(struct intel_dp *intel_dp) intel_dp->psr.source_support = true; + if (dev_priv->params.enable_psr == -1) + if (!dev_priv->vbt.psr.enable) + dev_priv->params.enable_psr = 0; + /* Set link_standby x link_off defaults */ if (DISPLAY_VER(dev_priv) < 12) /* For new platforms up to TGL let's respect VBT back again */ - intel_dp->psr.link_standby = connector->panel.vbt.psr.full_link; + intel_dp->psr.link_standby = dev_priv->vbt.psr.full_link; INIT_WORK(&intel_dp->psr.work, intel_psr_work); INIT_DELAYED_WORK(&intel_dp->psr.dc3co_work, tgl_dc3co_disable_work); diff --git a/drivers/gpu/drm/i915/display/intel_sdvo.c b/drivers/gpu/drm/i915/display/intel_sdvo.c index 14a64bd61176..d81855d57cdc 100644 --- a/drivers/gpu/drm/i915/display/intel_sdvo.c +++ b/drivers/gpu/drm/i915/display/intel_sdvo.c @@ -2869,7 +2869,6 @@ static bool intel_sdvo_lvds_init(struct intel_sdvo *intel_sdvo, int device) { struct drm_encoder *encoder = &intel_sdvo->base.base; - struct drm_i915_private *i915 = to_i915(encoder->dev); struct drm_connector *connector; struct intel_connector *intel_connector; struct intel_sdvo_connector *intel_sdvo_connector; @@ -2901,8 +2900,6 @@ intel_sdvo_lvds_init(struct intel_sdvo *intel_sdvo, int device) if (!intel_sdvo_create_enhance_property(intel_sdvo, intel_sdvo_connector)) goto err; - intel_bios_init_panel(i915, &intel_connector->panel); - /* * Fetch modes from VBT. For SDVO prefer the VBT mode since some * SDVO->LVDS transcoders can't cope with the EDID mode. diff --git a/drivers/gpu/drm/i915/display/vlv_dsi.c b/drivers/gpu/drm/i915/display/vlv_dsi.c index 02f75e95b2ec..1954f07f0d3e 100644 --- a/drivers/gpu/drm/i915/display/vlv_dsi.c +++ b/drivers/gpu/drm/i915/display/vlv_dsi.c @@ -782,7 +782,6 @@ static void intel_dsi_pre_enable(struct intel_atomic_state *state, { struct intel_dsi *intel_dsi = enc_to_intel_dsi(encoder); struct intel_crtc *crtc = to_intel_crtc(pipe_config->uapi.crtc); - struct intel_connector *connector = to_intel_connector(conn_state->connector); struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); enum pipe pipe = crtc->pipe; enum port port; @@ -839,7 +838,7 @@ static void intel_dsi_pre_enable(struct intel_atomic_state *state, * the delay in that case. If there is no deassert-seq, then an * unconditional msleep is used to give the panel time to power-on. */ - if (connector->panel.vbt.dsi.sequence[MIPI_SEQ_DEASSERT_RESET]) { + if (dev_priv->vbt.dsi.sequence[MIPI_SEQ_DEASSERT_RESET]) { intel_dsi_msleep(intel_dsi, intel_dsi->panel_on_delay); intel_dsi_vbt_exec_sequence(intel_dsi, MIPI_SEQ_DEASSERT_RESET); } else { @@ -1691,8 +1690,7 @@ static void vlv_dphy_param_init(struct intel_dsi *intel_dsi) { struct drm_device *dev = intel_dsi->base.base.dev; struct drm_i915_private *dev_priv = to_i915(dev); - struct intel_connector *connector = intel_dsi->attached_connector; - struct mipi_config *mipi_config = connector->panel.vbt.dsi.config; + struct mipi_config *mipi_config = dev_priv->vbt.dsi.config; u32 tlpx_ns, extra_byte_count, tlpx_ui; u32 ui_num, ui_den; u32 prepare_cnt, exit_zero_cnt, clk_zero_cnt, trail_cnt; @@ -1926,22 +1924,13 @@ void vlv_dsi_init(struct drm_i915_private *dev_priv) intel_dsi->panel_power_off_time = ktime_get_boottime(); - intel_bios_init_panel(dev_priv, &intel_connector->panel); - - if (intel_connector->panel.vbt.dsi.config->dual_link) + if (dev_priv->vbt.dsi.config->dual_link) intel_dsi->ports = BIT(PORT_A) | BIT(PORT_C); else intel_dsi->ports = BIT(port); - if (drm_WARN_ON(&dev_priv->drm, intel_connector->panel.vbt.dsi.bl_ports & ~intel_dsi->ports)) - intel_connector->panel.vbt.dsi.bl_ports &= intel_dsi->ports; - - intel_dsi->dcs_backlight_ports = intel_connector->panel.vbt.dsi.bl_ports; - - if (drm_WARN_ON(&dev_priv->drm, intel_connector->panel.vbt.dsi.cabc_ports & ~intel_dsi->ports)) - intel_connector->panel.vbt.dsi.cabc_ports &= intel_dsi->ports; - - intel_dsi->dcs_cabc_ports = intel_connector->panel.vbt.dsi.cabc_ports; + intel_dsi->dcs_backlight_ports = dev_priv->vbt.dsi.bl_ports; + intel_dsi->dcs_cabc_ports = dev_priv->vbt.dsi.cabc_ports; /* Create a DSI host (and a device) for each port. */ for_each_dsi_port(port, intel_dsi->ports) { diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 554d79bc0312..5184d70d4838 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -194,6 +194,12 @@ struct drm_i915_display_funcs { #define I915_COLOR_UNEVICTABLE (-1) /* a non-vma sharing the address space */ +enum drrs_type { + DRRS_TYPE_NONE, + DRRS_TYPE_STATIC, + DRRS_TYPE_SEAMLESS, +}; + #define QUIRK_LVDS_SSC_DISABLE (1<<1) #define QUIRK_INVERT_BRIGHTNESS (1<<2) #define QUIRK_BACKLIGHT_PRESENT (1<<3) @@ -302,19 +308,76 @@ struct intel_vbt_data { /* bdb version */ u16 version; + struct drm_display_mode *lfp_lvds_vbt_mode; /* if any */ + struct drm_display_mode *sdvo_lvds_vbt_mode; /* if any */ + /* Feature bits */ unsigned int int_tv_support:1; + unsigned int lvds_dither:1; unsigned int int_crt_support:1; unsigned int lvds_use_ssc:1; unsigned int int_lvds_support:1; unsigned int display_clock_mode:1; unsigned int fdi_rx_polarity_inverted:1; + unsigned int panel_type:4; int lvds_ssc_freq; + unsigned int bios_lvds_val; /* initial [PCH_]LVDS reg val in VBIOS */ enum drm_panel_orientation orientation; bool override_afc_startup; u8 override_afc_startup_val; + u8 seamless_drrs_min_refresh_rate; + enum drrs_type drrs_type; + + struct { + int rate; + int lanes; + int preemphasis; + int vswing; + int bpp; + struct edp_power_seq pps; + u8 drrs_msa_timing_delay; + bool low_vswing; + bool initialized; + bool hobl; + } edp; + + struct { + bool enable; + bool full_link; + bool require_aux_wakeup; + int idle_frames; + int tp1_wakeup_time_us; + int tp2_tp3_wakeup_time_us; + int psr2_tp2_tp3_wakeup_time_us; + } psr; + + struct { + u16 pwm_freq_hz; + u16 brightness_precision_bits; + bool present; + bool active_low_pwm; + u8 min_brightness; /* min_brightness/255 of max */ + u8 controller; /* brightness controller number */ + enum intel_backlight_type type; + } backlight; + + /* MIPI DSI */ + struct { + u16 panel_id; + struct mipi_config *config; + struct mipi_pps_data *pps; + u16 bl_ports; + u16 cabc_ports; + u8 seq_version; + u32 size; + u8 *data; + const u8 *sequence[MIPI_SEQ_MAX]; + u8 *deassert_seq; /* Used by fixup_mipi_sequences() */ + enum drm_panel_orientation orientation; + } dsi; + int crt_ddc_pin; struct list_head display_devices;