From patchwork Fri Nov 25 17:31:49 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?b?VmlsbGUgU3lyasOkbMOk?= X-Patchwork-Id: 13056189 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 082C4C4332F for ; Fri, 25 Nov 2022 17:32:11 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 2878710E777; Fri, 25 Nov 2022 17:32:10 +0000 (UTC) Received: from mga09.intel.com (mga09.intel.com [134.134.136.24]) by gabe.freedesktop.org (Postfix) with ESMTPS id B776410E776 for ; Fri, 25 Nov 2022 17:32:05 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1669397525; x=1700933525; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=zx9QSDikFiO9Gg3gGvgrZucmutO4bAw/vXOJiaczO7I=; b=GmwFbTrSD9PgzaB+jO17SAq1LdDRcQxa5MPUPoFOvwCzW22XtILcFD36 MCTvpr7st0pSYtYZg6sGXV+IWs4VudZiqoVoEleaAzAJIVrKtmkLxCnll ZEI6drHPKnrMQNBUNUGg8rkCR0thPnj8hJLc/PGo0hSl/3w1PmNe3V9tq mhqdKoRQ29rzVAnKquPqFJpLvMG4V57O1lDACBjDuL2QnxeOcCtIcGMEs reQTzoaXPApD46Ln+UEq40C2iJ2OFhAnaGTABmXqVaOkaEH9JpgJc7cug Gpyj0XY6RUI5NHPD3si5znIQfOLOazL0X5uTNKnmJ206/KsrtBYmNpAgu A==; X-IronPort-AV: E=McAfee;i="6500,9779,10542"; a="315674621" X-IronPort-AV: E=Sophos;i="5.96,194,1665471600"; d="scan'208";a="315674621" Received: from fmsmga008.fm.intel.com ([10.253.24.58]) by orsmga102.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 25 Nov 2022 09:32:05 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6500,9779,10542"; a="706124296" X-IronPort-AV: E=Sophos;i="5.96,194,1665471600"; d="scan'208";a="706124296" Received: from stinkpipe.fi.intel.com (HELO stinkbox) ([10.237.72.191]) by fmsmga008.fm.intel.com with SMTP; 25 Nov 2022 09:32:03 -0800 Received: by stinkbox (sSMTP sendmail emulation); Fri, 25 Nov 2022 19:32:02 +0200 From: Ville Syrjala To: intel-gfx@lists.freedesktop.org Date: Fri, 25 Nov 2022 19:31:49 +0200 Message-Id: <20221125173156.31689-3-ville.syrjala@linux.intel.com> X-Mailer: git-send-email 2.37.4 In-Reply-To: <20221125173156.31689-1-ville.syrjala@linux.intel.com> References: <20221125173156.31689-1-ville.syrjala@linux.intel.com> MIME-Version: 1.0 Subject: [Intel-gfx] [PATCH v2 2/9] drm/i915: Do panel VBT init early if the VBT declares an explicit panel type X-BeenThere: intel-gfx@lists.freedesktop.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Intel graphics driver community testing & development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Jani Nikula Errors-To: intel-gfx-bounces@lists.freedesktop.org Sender: "Intel-gfx" From: Ville Syrjälä Lots of ADL machines out there with bogus VBTs that declare two eDP child devices. In order for those to work we need to figure out which power sequencer to use before we try the EDID read. So let's do the panel VBT init early if we can, falling back to the post-EDID init otherwise. The post-EDID init panel_type=0xff approach of assuming the power sequencer should already be enabled doesn't really work with multiple eDP panels, and currently we just end up using the same power sequencer for both eDP ports, which at least confuses the wakeref tracking, and potentially also causes us to toggle the VDD for the panel when we should not. Cc: Animesh Manna Reviewed-by: Jani Nikula Signed-off-by: Ville Syrjälä --- drivers/gpu/drm/i915/display/icl_dsi.c | 2 +- drivers/gpu/drm/i915/display/intel_bios.c | 56 ++++++++++++++----- drivers/gpu/drm/i915/display/intel_bios.h | 11 ++-- .../drm/i915/display/intel_display_types.h | 2 +- drivers/gpu/drm/i915/display/intel_dp.c | 7 ++- drivers/gpu/drm/i915/display/intel_lvds.c | 4 +- drivers/gpu/drm/i915/display/intel_panel.c | 1 + drivers/gpu/drm/i915/display/intel_sdvo.c | 2 +- drivers/gpu/drm/i915/display/vlv_dsi.c | 2 +- 9 files changed, 61 insertions(+), 26 deletions(-) diff --git a/drivers/gpu/drm/i915/display/icl_dsi.c b/drivers/gpu/drm/i915/display/icl_dsi.c index d16b30a2dded..ae14c794c4bc 100644 --- a/drivers/gpu/drm/i915/display/icl_dsi.c +++ b/drivers/gpu/drm/i915/display/icl_dsi.c @@ -2043,7 +2043,7 @@ 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, NULL, NULL); + intel_bios_init_panel_late(dev_priv, &intel_connector->panel, NULL, NULL); mutex_lock(&dev_priv->drm.mode_config.mutex); intel_panel_add_vbt_lfp_fixed_mode(intel_connector); diff --git a/drivers/gpu/drm/i915/display/intel_bios.c b/drivers/gpu/drm/i915/display/intel_bios.c index c2987f2c2b2e..64f927f6479d 100644 --- a/drivers/gpu/drm/i915/display/intel_bios.c +++ b/drivers/gpu/drm/i915/display/intel_bios.c @@ -620,14 +620,14 @@ static void dump_pnp_id(struct drm_i915_private *i915, static int opregion_get_panel_type(struct drm_i915_private *i915, const struct intel_bios_encoder_data *devdata, - const struct edid *edid) + const struct edid *edid, bool use_fallback) { return intel_opregion_get_panel_type(i915); } static int vbt_get_panel_type(struct drm_i915_private *i915, const struct intel_bios_encoder_data *devdata, - const struct edid *edid) + const struct edid *edid, bool use_fallback) { const struct bdb_lvds_options *lvds_options; @@ -652,7 +652,7 @@ static int vbt_get_panel_type(struct drm_i915_private *i915, static int pnpid_get_panel_type(struct drm_i915_private *i915, const struct intel_bios_encoder_data *devdata, - const struct edid *edid) + const struct edid *edid, bool use_fallback) { const struct bdb_lvds_lfp_data *data; const struct bdb_lvds_lfp_data_ptrs *ptrs; @@ -701,9 +701,9 @@ static int pnpid_get_panel_type(struct drm_i915_private *i915, static int fallback_get_panel_type(struct drm_i915_private *i915, const struct intel_bios_encoder_data *devdata, - const struct edid *edid) + const struct edid *edid, bool use_fallback) { - return 0; + return use_fallback ? 0 : -1; } enum panel_type { @@ -715,13 +715,13 @@ enum panel_type { static int get_panel_type(struct drm_i915_private *i915, const struct intel_bios_encoder_data *devdata, - const struct edid *edid) + const struct edid *edid, bool use_fallback) { struct { const char *name; int (*get_panel_type)(struct drm_i915_private *i915, const struct intel_bios_encoder_data *devdata, - const struct edid *edid); + const struct edid *edid, bool use_fallback); int panel_type; } panel_types[] = { [PANEL_TYPE_OPREGION] = { @@ -744,7 +744,8 @@ static int get_panel_type(struct drm_i915_private *i915, int i; for (i = 0; i < ARRAY_SIZE(panel_types); i++) { - panel_types[i].panel_type = panel_types[i].get_panel_type(i915, devdata, edid); + panel_types[i].panel_type = panel_types[i].get_panel_type(i915, devdata, + edid, use_fallback); drm_WARN_ON(&i915->drm, panel_types[i].panel_type > 0xf && panel_types[i].panel_type != 0xff); @@ -3183,15 +3184,27 @@ 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, - const struct intel_bios_encoder_data *devdata, - const struct edid *edid) +static void intel_bios_init_panel(struct drm_i915_private *i915, + struct intel_panel *panel, + const struct intel_bios_encoder_data *devdata, + const struct edid *edid, + bool use_fallback) { + /* already have it? */ + if (panel->vbt.panel_type >= 0) { + drm_WARN_ON(&i915->drm, !use_fallback); + return; + } + + panel->vbt.panel_type = get_panel_type(i915, devdata, + edid, use_fallback); + if (panel->vbt.panel_type < 0) { + drm_WARN_ON(&i915->drm, use_fallback); + return; + } + init_vbt_panel_defaults(panel); - panel->vbt.panel_type = get_panel_type(i915, devdata, edid); - parse_panel_options(i915, panel); parse_generic_dtd(i915, panel); parse_lfp_data(i915, panel); @@ -3205,6 +3218,21 @@ void intel_bios_init_panel(struct drm_i915_private *i915, parse_mipi_sequence(i915, panel); } +void intel_bios_init_panel_early(struct drm_i915_private *i915, + struct intel_panel *panel, + const struct intel_bios_encoder_data *devdata) +{ + intel_bios_init_panel(i915, panel, devdata, NULL, false); +} + +void intel_bios_init_panel_late(struct drm_i915_private *i915, + struct intel_panel *panel, + const struct intel_bios_encoder_data *devdata, + const struct edid *edid) +{ + intel_bios_init_panel(i915, panel, devdata, edid, true); +} + /** * intel_bios_driver_remove - Free any resources allocated by intel_bios_init() * @i915: i915 device instance diff --git a/drivers/gpu/drm/i915/display/intel_bios.h b/drivers/gpu/drm/i915/display/intel_bios.h index e375405a7828..ff1fdd2e0c1c 100644 --- a/drivers/gpu/drm/i915/display/intel_bios.h +++ b/drivers/gpu/drm/i915/display/intel_bios.h @@ -232,10 +232,13 @@ 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, - const struct intel_bios_encoder_data *devdata, - const struct edid *edid); +void intel_bios_init_panel_early(struct drm_i915_private *dev_priv, + struct intel_panel *panel, + const struct intel_bios_encoder_data *devdata); +void intel_bios_init_panel_late(struct drm_i915_private *dev_priv, + struct intel_panel *panel, + const struct intel_bios_encoder_data *devdata, + const struct edid *edid); 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); diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h index ff3ef37d099e..cc64e787e401 100644 --- a/drivers/gpu/drm/i915/display/intel_display_types.h +++ b/drivers/gpu/drm/i915/display/intel_display_types.h @@ -291,7 +291,7 @@ struct intel_vbt_panel_data { struct drm_display_mode *sdvo_lvds_vbt_mode; /* if any */ /* Feature bits */ - unsigned int panel_type:4; + int panel_type; unsigned int lvds_dither:1; unsigned int bios_lvds_val; /* initial [PCH_]LVDS reg val in VBIOS */ diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c index cf8a2f644bab..c1bebe77ed8e 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.c +++ b/drivers/gpu/drm/i915/display/intel_dp.c @@ -5280,6 +5280,9 @@ static bool intel_edp_init_connector(struct intel_dp *intel_dp, return false; } + intel_bios_init_panel_early(dev_priv, &intel_connector->panel, + encoder->devdata); + intel_pps_init(intel_dp); /* Cache DPCD and EDID for edp. */ @@ -5315,8 +5318,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, - encoder->devdata, IS_ERR(edid) ? NULL : edid); + intel_bios_init_panel_late(dev_priv, &intel_connector->panel, + encoder->devdata, IS_ERR(edid) ? NULL : edid); intel_panel_add_edid_fixed_modes(intel_connector, true); diff --git a/drivers/gpu/drm/i915/display/intel_lvds.c b/drivers/gpu/drm/i915/display/intel_lvds.c index 7bf1bdfd03ec..aecec992cd0d 100644 --- a/drivers/gpu/drm/i915/display/intel_lvds.c +++ b/drivers/gpu/drm/i915/display/intel_lvds.c @@ -964,8 +964,8 @@ void intel_lvds_init(struct drm_i915_private *dev_priv) } intel_connector->edid = edid; - intel_bios_init_panel(dev_priv, &intel_connector->panel, NULL, - IS_ERR(edid) ? NULL : edid); + intel_bios_init_panel_late(dev_priv, &intel_connector->panel, NULL, + IS_ERR(edid) ? NULL : edid); /* Try EDID first */ intel_panel_add_edid_fixed_modes(intel_connector, true); diff --git a/drivers/gpu/drm/i915/display/intel_panel.c b/drivers/gpu/drm/i915/display/intel_panel.c index b49228eb79e7..609fcdbd7d58 100644 --- a/drivers/gpu/drm/i915/display/intel_panel.c +++ b/drivers/gpu/drm/i915/display/intel_panel.c @@ -665,6 +665,7 @@ void intel_panel_init_alloc(struct intel_connector *connector) { struct intel_panel *panel = &connector->panel; + connector->panel.vbt.panel_type = -1; INIT_LIST_HEAD(&panel->fixed_modes); } diff --git a/drivers/gpu/drm/i915/display/intel_sdvo.c b/drivers/gpu/drm/i915/display/intel_sdvo.c index 329b9d9af667..21805c15d5eb 100644 --- a/drivers/gpu/drm/i915/display/intel_sdvo.c +++ b/drivers/gpu/drm/i915/display/intel_sdvo.c @@ -2886,7 +2886,7 @@ intel_sdvo_lvds_init(struct intel_sdvo *intel_sdvo, u16 type) if (!intel_sdvo_create_enhance_property(intel_sdvo, intel_sdvo_connector)) goto err; - intel_bios_init_panel(i915, &intel_connector->panel, NULL, NULL); + intel_bios_init_panel_late(i915, &intel_connector->panel, NULL, NULL); /* * Fetch modes from VBT. For SDVO prefer the VBT mode since some diff --git a/drivers/gpu/drm/i915/display/vlv_dsi.c b/drivers/gpu/drm/i915/display/vlv_dsi.c index 84481030883a..662bdb656aa3 100644 --- a/drivers/gpu/drm/i915/display/vlv_dsi.c +++ b/drivers/gpu/drm/i915/display/vlv_dsi.c @@ -1916,7 +1916,7 @@ 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, NULL, NULL); + intel_bios_init_panel_late(dev_priv, &intel_connector->panel, NULL, NULL); if (intel_connector->panel.vbt.dsi.config->dual_link) intel_dsi->ports = BIT(PORT_A) | BIT(PORT_C);