Commit 3cf05076 authored by Ville Syrjälä's avatar Ville Syrjälä

drm/i915/bios: Split VBT data into per-panel vs. global parts

Move the panel specific VBT parsing to happen during the
output probing stage. Needs to be done because the VBT
parsing will need to look at the EDID to determine
the correct panel_type on some machines.

We split the parsed VBT data (i915->vbt) along the same
boundary. For the moment we just hoist all the panel
specific stuff into connector->panel.vbt since that seems
like the most convenient place for eg. the backlight code.

Note that we simply drop the drrs type check from
intel_drrs_frontbuffer_update() since that operates on the whole
device rather than a specific connector/encoder. But the check
was just a micro optimization so removing it doesn't actually
mattter for correctness.

TODO: Lot's of cleanup to be done in the future. Eg. most of
the DSI stuff could probably be eliminated entirely and just
parsed on demand during DSI init.

v2: Note the intel_drrs_frontbuffer_update() change
Signed-off-by: default avatarVille Syrjälä <ville.syrjala@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20220510104242.6099-13-ville.syrjala@linux.intel.comReviewed-by: default avatarJani Nikula <jani.nikula@intel.com>
parent c2fdb424
......@@ -1861,7 +1861,8 @@ 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 mipi_config *mipi_config = dev_priv->vbt.dsi.config;
struct intel_connector *connector = intel_dsi->attached_connector;
struct mipi_config *mipi_config = connector->panel.vbt.dsi.config;
u32 tlpx_ns;
u32 prepare_cnt, exit_zero_cnt, clk_zero_cnt, trail_cnt;
u32 ths_prepare_ns, tclk_trail_ns;
......@@ -2048,6 +2049,8 @@ 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);
......@@ -2061,13 +2064,13 @@ void icl_dsi_init(struct drm_i915_private *dev_priv)
intel_backlight_setup(intel_connector, INVALID_PIPE);
if (dev_priv->vbt.dsi.config->dual_link)
if (intel_connector->panel.vbt.dsi.config->dual_link)
intel_dsi->ports = BIT(PORT_A) | BIT(PORT_B);
else
intel_dsi->ports = BIT(port);
intel_dsi->dcs_backlight_ports = dev_priv->vbt.dsi.bl_ports;
intel_dsi->dcs_cabc_ports = dev_priv->vbt.dsi.cabc_ports;
intel_dsi->dcs_backlight_ports = intel_connector->panel.vbt.dsi.bl_ports;
intel_dsi->dcs_cabc_ports = intel_connector->panel.vbt.dsi.cabc_ports;
for_each_dsi_port(port, intel_dsi->ports) {
struct intel_dsi_host *host;
......
......@@ -1159,9 +1159,10 @@ 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 drm_i915_private *dev_priv)
static u16 get_vbt_pwm_freq(struct intel_connector *connector)
{
u16 pwm_freq_hz = dev_priv->vbt.backlight.pwm_freq_hz;
struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
u16 pwm_freq_hz = connector->panel.vbt.backlight.pwm_freq_hz;
if (pwm_freq_hz) {
drm_dbg_kms(&dev_priv->drm,
......@@ -1181,7 +1182,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(dev_priv);
u16 pwm_freq_hz = get_vbt_pwm_freq(connector);
u32 pwm;
if (!panel->backlight.pwm_funcs->hz_to_pwm) {
......@@ -1218,11 +1219,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, dev_priv->vbt.backlight.min_brightness, 0, 64);
if (min != dev_priv->vbt.backlight.min_brightness) {
min = clamp_t(int, connector->panel.vbt.backlight.min_brightness, 0, 64);
if (min != connector->panel.vbt.backlight.min_brightness) {
drm_dbg_kms(&dev_priv->drm,
"clamping VBT min backlight %d/255 to %d/255\n",
dev_priv->vbt.backlight.min_brightness, min);
connector->panel.vbt.backlight.min_brightness, min);
}
/* vbt value is a coefficient in range [0..255] */
......@@ -1411,7 +1412,7 @@ bxt_setup_backlight(struct intel_connector *connector, enum pipe unused)
struct intel_panel *panel = &connector->panel;
u32 pwm_ctl, val;
panel->backlight.controller = dev_priv->vbt.backlight.controller;
panel->backlight.controller = connector->panel.vbt.backlight.controller;
pwm_ctl = intel_de_read(dev_priv,
BXT_BLC_PWM_CTL(panel->backlight.controller));
......@@ -1484,7 +1485,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 (dev_priv->vbt.dsi.config->pwm_blc == PPS_BLC_PMIC) {
if (connector->panel.vbt.dsi.config->pwm_blc == PPS_BLC_PMIC) {
panel->backlight.pwm = pwm_get(dev->dev, "pwm_pmic_backlight");
desc = "PMIC";
} else {
......@@ -1513,11 +1514,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(dev_priv), level);
get_vbt_pwm_freq(connector), level);
} else {
/* Set period from VBT frequency, leave other settings at 0. */
panel->backlight.pwm_state.period =
NSEC_PER_SEC / get_vbt_pwm_freq(dev_priv);
NSEC_PER_SEC / get_vbt_pwm_freq(connector);
}
drm_info(&dev_priv->drm, "Using %s PWM for LCD backlight control\n",
......@@ -1602,7 +1603,7 @@ int intel_backlight_setup(struct intel_connector *connector, enum pipe pipe)
struct intel_panel *panel = &connector->panel;
int ret;
if (!dev_priv->vbt.backlight.present) {
if (!connector->panel.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");
......
This diff is collapsed.
......@@ -36,6 +36,7 @@ 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 {
......@@ -230,7 +231,9 @@ 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);
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);
......
......@@ -1042,17 +1042,18 @@ 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 i915->vbt.edp.hobl && !intel_dp->hobl_failed;
return connector->panel.vbt.edp.hobl && !intel_dp->hobl_failed;
}
static bool use_edp_low_vswing(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 i915->vbt.edp.low_vswing;
return connector->panel.vbt.edp.low_vswing;
}
static const struct intel_ddi_buf_trans *
......
......@@ -9580,7 +9580,6 @@ int intel_modeset_init_noirq(struct drm_i915_private *i915)
}
intel_bios_init(i915);
intel_bios_init_panel(i915);
ret = intel_vga_register(i915);
if (ret)
......
......@@ -279,6 +279,73 @@ 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;
......@@ -318,6 +385,8 @@ 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;
......
......@@ -1219,11 +1219,12 @@ 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 &&
dev_priv->vbt.edp.bpp && dev_priv->vbt.edp.bpp < bpp) {
intel_connector->panel.vbt.edp.bpp &&
intel_connector->panel.vbt.edp.bpp < bpp) {
drm_dbg_kms(&dev_priv->drm,
"clamping bpp for eDP panel to BIOS-provided %i\n",
dev_priv->vbt.edp.bpp);
bpp = dev_priv->vbt.edp.bpp;
intel_connector->panel.vbt.edp.bpp);
bpp = intel_connector->panel.vbt.edp.bpp;
}
}
......@@ -1879,7 +1880,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 = i915->vbt.edp.drrs_msa_timing_delay;
pipe_config->msa_timing_delay = connector->panel.vbt.edp.drrs_msa_timing_delay;
pipe_config->has_drrs = true;
......@@ -2712,8 +2713,10 @@ static void intel_edp_mso_mode_fixup(struct intel_connector *connector,
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 (dev_priv->vbt.edp.bpp && pipe_bpp > dev_priv->vbt.edp.bpp) {
if (connector->panel.vbt.edp.bpp && pipe_bpp > connector->panel.vbt.edp.bpp) {
/*
* This is a big fat ugly hack.
*
......@@ -2729,8 +2732,8 @@ void intel_edp_fixup_vbt_bpp(struct intel_encoder *encoder, int pipe_bpp)
*/
drm_dbg_kms(&dev_priv->drm,
"pipe has %d bpp for eDP panel, overriding BIOS-provided max %d bpp\n",
pipe_bpp, dev_priv->vbt.edp.bpp);
dev_priv->vbt.edp.bpp = pipe_bpp;
pipe_bpp, connector->panel.vbt.edp.bpp);
connector->panel.vbt.edp.bpp = pipe_bpp;
}
}
......@@ -5209,8 +5212,10 @@ 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,
dev_priv->vbt.drrs_type != DRRS_TYPE_NONE);
intel_connector->panel.vbt.drrs_type != DRRS_TYPE_NONE);
/* MSO requires information from the EDID */
intel_edp_mso_init(intel_dp);
......
......@@ -29,6 +29,7 @@ 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);
......
......@@ -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,
i915->vbt.backlight.pwm_freq_hz, intel_dp->edp_dpcd,
panel->vbt.backlight.pwm_freq_hz, intel_dp->edp_dpcd,
&current_level, &current_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 (i915->vbt.backlight.type) {
switch (panel->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 (i915->vbt.backlight.type != INTEL_BACKLIGHT_VESA_EDP_AUX_INTERFACE)
if (panel->vbt.backlight.type != INTEL_BACKLIGHT_VESA_EDP_AUX_INTERFACE)
try_intel_interface = true;
try_vesa_interface = true;
......
......@@ -217,9 +217,6 @@ 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;
......
......@@ -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 = dev_priv->vbt.dsi.orientation;
orientation = connector->panel.vbt.dsi.orientation;
if (orientation != DRM_MODE_PANEL_ORIENTATION_UNKNOWN)
return orientation;
......
......@@ -160,12 +160,10 @@ 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 (dev_priv->vbt.backlight.brightness_precision_bits > 8)
panel->backlight.max = (1 << dev_priv->vbt.backlight.brightness_precision_bits) - 1;
if (panel->vbt.backlight.brightness_precision_bits > 8)
panel->backlight.max = (1 << panel->vbt.backlight.brightness_precision_bits) - 1;
else
panel->backlight.max = PANEL_PWM_MAX_VALUE;
......@@ -185,11 +183,10 @@ 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 (dev_priv->vbt.backlight.type != INTEL_BACKLIGHT_DSI_DCS)
if (panel->vbt.backlight.type != INTEL_BACKLIGHT_DSI_DCS)
return -ENODEV;
if (drm_WARN_ON(dev, encoder->type != INTEL_OUTPUT_DSI))
......
......@@ -240,9 +240,10 @@ static const u8 *mipi_exec_delay(struct intel_dsi *intel_dsi, const u8 *data)
return data;
}
static void vlv_exec_gpio(struct drm_i915_private *dev_priv,
static void vlv_exec_gpio(struct intel_connector *connector,
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;
......@@ -256,7 +257,7 @@ static void vlv_exec_gpio(struct drm_i915_private *dev_priv,
map = &vlv_gpio_table[gpio_index];
if (dev_priv->vbt.dsi.seq_version >= 3) {
if (connector->panel.vbt.dsi.seq_version >= 3) {
/* XXX: this assumes vlv_gpio_table only has NC GPIOs. */
port = IOSF_PORT_GPIO_NC;
} else {
......@@ -287,14 +288,15 @@ static void vlv_exec_gpio(struct drm_i915_private *dev_priv,
vlv_iosf_sb_put(dev_priv, BIT(VLV_IOSF_SB_GPIO));
}
static void chv_exec_gpio(struct drm_i915_private *dev_priv,
static void chv_exec_gpio(struct intel_connector *connector,
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 (dev_priv->vbt.dsi.seq_version >= 3) {
if (connector->panel.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;
......@@ -340,9 +342,10 @@ static void chv_exec_gpio(struct drm_i915_private *dev_priv,
vlv_iosf_sb_put(dev_priv, BIT(VLV_IOSF_SB_GPIO));
}
static void bxt_exec_gpio(struct drm_i915_private *dev_priv,
static void bxt_exec_gpio(struct intel_connector *connector,
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];
......@@ -366,9 +369,11 @@ static void bxt_exec_gpio(struct drm_i915_private *dev_priv,
gpiod_set_value(gpio_desc, value);
}
static void icl_exec_gpio(struct drm_i915_private *dev_priv,
static void icl_exec_gpio(struct intel_connector *connector,
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");
}
......@@ -376,18 +381,19 @@ 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 (dev_priv->vbt.dsi.seq_version >= 3)
if (connector->panel.vbt.dsi.seq_version >= 3)
gpio_index = *data++;
gpio_number = *data++;
/* gpio source in sequence v2 only */
if (dev_priv->vbt.dsi.seq_version == 2)
if (connector->panel.vbt.dsi.seq_version == 2)
gpio_source = (*data >> 1) & 3;
else
gpio_source = 0;
......@@ -396,13 +402,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(dev_priv, gpio_source, gpio_index, value);
icl_exec_gpio(connector, gpio_source, gpio_index, value);
else if (IS_VALLEYVIEW(dev_priv))
vlv_exec_gpio(dev_priv, gpio_source, gpio_number, value);
vlv_exec_gpio(connector, gpio_source, gpio_number, value);
else if (IS_CHERRYVIEW(dev_priv))
chv_exec_gpio(dev_priv, gpio_source, gpio_number, value);
chv_exec_gpio(connector, gpio_source, gpio_number, value);
else
bxt_exec_gpio(dev_priv, gpio_source, gpio_index, value);
bxt_exec_gpio(connector, gpio_source, gpio_index, value);
return data;
}
......@@ -585,14 +591,15 @@ 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(dev_priv->vbt.dsi.sequence)))
seq_id >= ARRAY_SIZE(connector->panel.vbt.dsi.sequence)))
return;
data = dev_priv->vbt.dsi.sequence[seq_id];
data = connector->panel.vbt.dsi.sequence[seq_id];
if (!data)
return;
......@@ -605,7 +612,7 @@ static void intel_dsi_vbt_exec(struct intel_dsi *intel_dsi,
data++;
/* Skip Size of Sequence. */
if (dev_priv->vbt.dsi.seq_version >= 3)
if (connector->panel.vbt.dsi.seq_version >= 3)
data += 4;
while (1) {
......@@ -621,7 +628,7 @@ static void intel_dsi_vbt_exec(struct intel_dsi *intel_dsi,
mipi_elem_exec = NULL;
/* Size of Operation. */
if (dev_priv->vbt.dsi.seq_version >= 3)
if (connector->panel.vbt.dsi.seq_version >= 3)
operation_size = *data++;
if (mipi_elem_exec) {
......@@ -669,10 +676,10 @@ void intel_dsi_vbt_exec_sequence(struct intel_dsi *intel_dsi,
void intel_dsi_msleep(struct intel_dsi *intel_dsi, int msec)
{
struct drm_i915_private *dev_priv = to_i915(intel_dsi->base.base.dev);
struct intel_connector *connector = intel_dsi->attached_connector;
/* For v3 VBTs in vid-mode the delays are part of the VBT sequences */
if (is_vid_mode(intel_dsi) && dev_priv->vbt.dsi.seq_version >= 3)
if (is_vid_mode(intel_dsi) && connector->panel.vbt.dsi.seq_version >= 3)
return;
msleep(msec);
......@@ -734,9 +741,10 @@ 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 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;
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;
u16 burst_mode_ratio;
enum port port;
......@@ -872,7 +880,8 @@ 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 mipi_config *mipi_config = dev_priv->vbt.dsi.config;
struct intel_connector *connector = intel_dsi->attached_connector;
struct mipi_config *mipi_config = connector->panel.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;
......@@ -927,7 +936,8 @@ 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 mipi_config *mipi_config = dev_priv->vbt.dsi.config;
struct intel_connector *connector = intel_dsi->attached_connector;
struct mipi_config *mipi_config = connector->panel.vbt.dsi.config;
if (intel_dsi->gpio_panel) {
gpiod_put(intel_dsi->gpio_panel);
......
......@@ -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 = dev_priv->vbt.bios_lvds_val;
val = connector->panel.vbt.bios_lvds_val;
return (val & LVDS_CLKB_POWER_MASK) == LVDS_CLKB_POWER_UP;
}
......@@ -967,9 +967,11 @@ 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,
dev_priv->vbt.drrs_type != DRRS_TYPE_NONE);
intel_connector->panel.vbt.drrs_type != DRRS_TYPE_NONE);
/* Failed to get EDID, what about VBT? */
if (!intel_panel_preferred_fixed_mode(intel_connector))
......
......@@ -75,9 +75,8 @@ 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 = i915->vbt.seamless_drrs_min_refresh_rate;
int min_vrefresh = connector->panel.vbt.seamless_drrs_min_refresh_rate;
int max_vrefresh = drm_mode_vrefresh(adjusted_mode);
/* pick the fixed_mode with the lowest refresh rate */
......@@ -113,13 +112,11 @@ 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 i915->vbt.drrs_type;
return connector->panel.vbt.drrs_type;
}
int intel_panel_compute_config(struct intel_connector *connector,
......@@ -260,7 +257,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 = i915->vbt.lfp_lvds_vbt_mode;
mode = connector->panel.vbt.lfp_lvds_vbt_mode;
if (!mode)
return;
......@@ -274,7 +271,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 = i915->vbt.sdvo_lvds_vbt_mode;
mode = connector->panel.vbt.sdvo_lvds_vbt_mode;
if (!mode)
return;
......@@ -639,6 +636,8 @@ 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);
......
......@@ -209,7 +209,8 @@ static int
bxt_power_sequencer_idx(struct intel_dp *intel_dp)
{
struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
int backlight_controller = dev_priv->vbt.backlight.controller;
struct intel_connector *connector = intel_dp->attached_connector;
int backlight_controller = connector->panel.vbt.backlight.controller;
lockdep_assert_held(&dev_priv->pps_mutex);
......@@ -1189,8 +1190,9 @@ 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;
*vbt = dev_priv->vbt.edp.pps;
*vbt = connector->panel.vbt.edp.pps;
if (!pps_delays_valid(vbt))
return;
......
......@@ -399,6 +399,7 @@ 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;
......@@ -411,20 +412,20 @@ static u32 intel_psr1_get_tp_time(struct intel_dp *intel_dp)
goto check_tp3_sel;
}
if (dev_priv->vbt.psr.tp1_wakeup_time_us == 0)
if (connector->panel.vbt.psr.tp1_wakeup_time_us == 0)
val |= EDP_PSR_TP1_TIME_0us;
else if (dev_priv->vbt.psr.tp1_wakeup_time_us <= 100)
else if (connector->panel.vbt.psr.tp1_wakeup_time_us <= 100)
val |= EDP_PSR_TP1_TIME_100us;
else if (dev_priv->vbt.psr.tp1_wakeup_time_us <= 500)
else if (connector->panel.vbt.psr.tp1_wakeup_time_us <= 500)
val |= EDP_PSR_TP1_TIME_500us;
else
val |= EDP_PSR_TP1_TIME_2500us;
if (dev_priv->vbt.psr.tp2_tp3_wakeup_time_us == 0)
if (connector->panel.vbt.psr.tp2_tp3_wakeup_time_us == 0)
val |= EDP_PSR_TP2_TP3_TIME_0us;
else if (dev_priv->vbt.psr.tp2_tp3_wakeup_time_us <= 100)
else if (connector->panel.vbt.psr.tp2_tp3_wakeup_time_us <= 100)
val |= EDP_PSR_TP2_TP3_TIME_100us;
else if (dev_priv->vbt.psr.tp2_tp3_wakeup_time_us <= 500)
else if (connector->panel.vbt.psr.tp2_tp3_wakeup_time_us <= 500)
val |= EDP_PSR_TP2_TP3_TIME_500us;
else
val |= EDP_PSR_TP2_TP3_TIME_2500us;
......@@ -441,13 +442,14 @@ 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, dev_priv->vbt.psr.idle_frames);
idle_frames = max(6, connector->panel.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))
......@@ -483,18 +485,19 @@ 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 (dev_priv->vbt.psr.psr2_tp2_tp3_wakeup_time_us >= 0 &&
dev_priv->vbt.psr.psr2_tp2_tp3_wakeup_time_us <= 50)
if (connector->panel.vbt.psr.psr2_tp2_tp3_wakeup_time_us >= 0 &&
connector->panel.vbt.psr.psr2_tp2_tp3_wakeup_time_us <= 50)
val |= EDP_PSR2_TP2_TIME_50us;
else if (dev_priv->vbt.psr.psr2_tp2_tp3_wakeup_time_us <= 100)
else if (connector->panel.vbt.psr.psr2_tp2_tp3_wakeup_time_us <= 100)
val |= EDP_PSR2_TP2_TIME_100us;
else if (dev_priv->vbt.psr.psr2_tp2_tp3_wakeup_time_us <= 500)
else if (connector->panel.vbt.psr.psr2_tp2_tp3_wakeup_time_us <= 500)
val |= EDP_PSR2_TP2_TIME_500us;
else
val |= EDP_PSR2_TP2_TIME_2500us;
......@@ -2367,6 +2370,7 @@ 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);
......@@ -2391,13 +2395,13 @@ 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)
if (!connector->panel.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 = dev_priv->vbt.psr.full_link;
intel_dp->psr.link_standby = connector->panel.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);
......
......@@ -2868,6 +2868,7 @@ 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;
......@@ -2899,6 +2900,8 @@ 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.
......
......@@ -782,6 +782,7 @@ 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;
......@@ -838,7 +839,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 (dev_priv->vbt.dsi.sequence[MIPI_SEQ_DEASSERT_RESET]) {
if (connector->panel.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 {
......@@ -1690,7 +1691,8 @@ 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 mipi_config *mipi_config = dev_priv->vbt.dsi.config;
struct intel_connector *connector = intel_dsi->attached_connector;
struct mipi_config *mipi_config = connector->panel.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;
......@@ -1924,13 +1926,15 @@ void vlv_dsi_init(struct drm_i915_private *dev_priv)
intel_dsi->panel_power_off_time = ktime_get_boottime();
if (dev_priv->vbt.dsi.config->dual_link)
intel_bios_init_panel(dev_priv, &intel_connector->panel);
if (intel_connector->panel.vbt.dsi.config->dual_link)
intel_dsi->ports = BIT(PORT_A) | BIT(PORT_C);
else
intel_dsi->ports = BIT(port);
intel_dsi->dcs_backlight_ports = dev_priv->vbt.dsi.bl_ports;
intel_dsi->dcs_cabc_ports = dev_priv->vbt.dsi.cabc_ports;
intel_dsi->dcs_backlight_ports = intel_connector->panel.vbt.dsi.bl_ports;
intel_dsi->dcs_cabc_ports = intel_connector->panel.vbt.dsi.cabc_ports;
/* Create a DSI host (and a device) for each port. */
for_each_dsi_port(port, intel_dsi->ports) {
......
......@@ -193,12 +193,6 @@ 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)
......@@ -307,76 +301,19 @@ 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;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment