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

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.com


Reviewed-by: default avatarJani Nikula <jani.nikula@intel.com>
parent c2fdb424
Loading
Loading
Loading
Loading
+7 −4
Original line number Diff line number Diff line
@@ -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;
+12 −11
Original line number Diff line number Diff line
@@ -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");
+197 −174

File changed.

Preview size limit exceeded, changes collapsed.

+4 −1
Original line number Diff line number Diff line
@@ -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);
+5 −4
Original line number Diff line number Diff line
@@ -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 *
Loading