Received: by 2002:a05:7412:d1aa:b0:fc:a2b0:25d7 with SMTP id ba42csp275612rdb; Mon, 29 Jan 2024 01:40:43 -0800 (PST) X-Google-Smtp-Source: AGHT+IHKQsaTbBcGdvLZnDXTBaCwS3uHD3OUotpJUX6kV4cTh5Pe5JyPuwGAig7F9TgRb8+j4w8X X-Received: by 2002:a17:902:f54d:b0:1d5:59eb:bae7 with SMTP id h13-20020a170902f54d00b001d559ebbae7mr2669488plf.19.1706521243329; Mon, 29 Jan 2024 01:40:43 -0800 (PST) ARC-Seal: i=2; a=rsa-sha256; t=1706521243; cv=pass; d=google.com; s=arc-20160816; b=zwF7YueoSliTUk4bTtCEXhQXpg35tblaTUioTe18Po+0g7mrwk8elFxNg89yZDxzj3 vsOqTxCaYnwnYFGFCFfpMVOM8w+l7ZtJBauKm8805wwmHByUPq2ZPFbhHH69MlWHEJbg ++0XwwlCzSjlCkmylMbRDAzVRM8y/ilSaPQD3OJoWUMxg+Od5KmQixanXwOEQ8UguYKw HoBgt7yspUvAK3UT4Wx4lKC4fP5zq4eNZ0gtmdhhWekQL/2KvGKhmk+VGHM/FNsNvwkS jE0pxOoRDyAuxQbZuwDPfXBtMH1H4ecRjFXITlsZrZXruBzkkmzInspkElDyTj7OmCqg vo/w== ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=mime-version:list-unsubscribe:list-subscribe:list-id:precedence :message-id:date:references:organization:in-reply-to:subject:cc:to :from:dkim-signature; bh=I5qQVMBuunDTX+H7VpG5CIrAXIykgwdTkqfGF4mQg0s=; fh=NHOmbAt2QFpyZl+Nyms/nhOTVn+A8eRo6kh8fj+QHDE=; b=COp/P0RCzYEPT3Crk4pcssuhLzom4pbP55ZgoR4gr53RgpqxR/m5OapXap5SZEcUPn HnyXuPmhX4DKARvVdjfbpos+W8sgRBO8Gzo12z4XiLtaX9kpc/YeaprgS+VyFxljBw0m LoNqoJbVJ78nDXJJx2Zf6uiNCIrSWCMi3cBD2ubZzuWg6v2e6GczBdpyvnLhh5FYO6UV udS6rYRjnlaQ73JDIJWSzP3zfSpd/SvhEgQn/CosDAO8lYBwgijMDpZFWqoTIkfJN+3M EypY5wLViGarEcbLVbez0tw68MBx49jbGH3LMRLGA97iGzDgoBmxFnItalsos8mG897Z 4OuQ== ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@intel.com header.s=Intel header.b=DiK3P93Z; arc=pass (i=1 spf=pass spfdomain=intel.com dkim=pass dkdomain=intel.com dmarc=pass fromdomain=linux.intel.com); spf=pass (google.com: domain of linux-kernel+bounces-42480-linux.lists.archive=gmail.com@vger.kernel.org designates 147.75.48.161 as permitted sender) smtp.mailfrom="linux-kernel+bounces-42480-linux.lists.archive=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=intel.com Return-Path: Received: from sy.mirrors.kernel.org (sy.mirrors.kernel.org. [147.75.48.161]) by mx.google.com with ESMTPS id p1-20020a170902e74100b001d8cbbc3290si2531449plf.300.2024.01.29.01.40.42 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 29 Jan 2024 01:40:43 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel+bounces-42480-linux.lists.archive=gmail.com@vger.kernel.org designates 147.75.48.161 as permitted sender) client-ip=147.75.48.161; Authentication-Results: mx.google.com; dkim=pass header.i=@intel.com header.s=Intel header.b=DiK3P93Z; arc=pass (i=1 spf=pass spfdomain=intel.com dkim=pass dkdomain=intel.com dmarc=pass fromdomain=linux.intel.com); spf=pass (google.com: domain of linux-kernel+bounces-42480-linux.lists.archive=gmail.com@vger.kernel.org designates 147.75.48.161 as permitted sender) smtp.mailfrom="linux-kernel+bounces-42480-linux.lists.archive=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=intel.com Received: from smtp.subspace.kernel.org (wormhole.subspace.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by sy.mirrors.kernel.org (Postfix) with ESMTPS id 425CFB222A8 for ; Mon, 29 Jan 2024 09:39:54 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id CD06F55784; Mon, 29 Jan 2024 09:39:43 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b="DiK3P93Z" Received: from mgamail.intel.com (mgamail.intel.com [192.198.163.9]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 67E9F55E63; Mon, 29 Jan 2024 09:39:40 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=192.198.163.9 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1706521182; cv=none; b=qClwbzzcFPFlJI9+L0xg7Z5hJBUbbdFuBUMnVAwSposkrVfbhn2xlBrt7KczDEevbf8p+nqukuzPYQzmwYkvJFgdWC6ts+92sqBVd4tNrZ7m/dH+5e67/7btF8K2S8CByC6FYOPxSmsoFlU+Rvtjj8x2U/iX7SmSWck2X2oAE5A= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1706521182; c=relaxed/simple; bh=vUokWzEw5+VC5jpC2OPRStu+GWoiZ2lrs+sppMiHM5k=; h=From:To:Cc:Subject:In-Reply-To:References:Date:Message-ID: MIME-Version:Content-Type; b=HV6Udwh272czUxQz686S+rvBw8jUj3iyyWi6j6b5spvLHC8lOjTIAPKRHGAFAoDdA4fiSvRF4FgM5A1S1TaAGqG05g/IL1V+7nLIDvyy0pUcMeUFvf2RU5ibtJ7p+cwEbkovQj1UnpJTy+/XqfuoW4NSHNKzT5VVb8101JOApEQ= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.intel.com; spf=pass smtp.mailfrom=intel.com; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b=DiK3P93Z; arc=none smtp.client-ip=192.198.163.9 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.intel.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=intel.com DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1706521180; x=1738057180; h=from:to:cc:subject:in-reply-to:references:date: message-id:mime-version; bh=vUokWzEw5+VC5jpC2OPRStu+GWoiZ2lrs+sppMiHM5k=; b=DiK3P93Zk8DZxJKkBJbtJAt8nTd9VgOgq7WddB1boej3/y6zu/jB2mje 6JDWppiqXnjdTecPIZXMGZo9ZhuFFQlM94aJXZSKA1Beqv0VJauX4SISr JR2qFdiFacmO7UEoCE3+kkoCS/X4ftQ9jehGMpnw4NlsLFdy+bzRWOU2X LERX/xLMjhEHsWg6TJEvcOJkPD/wQz/0spT3pQg1Ukw/utktXB/hTYI5O y7kt6rHEYJp51yL8q7RpnWAjT0tehKjfSPXwk8Sw0mke1JwHqWz1U9fmq AxqX1vv6/GoyRh+8IoIRnfjpBeV2aKqkveLhYG8x6PClWmjVU1+u8nhj6 A==; X-IronPort-AV: E=McAfee;i="6600,9927,10967"; a="9650774" X-IronPort-AV: E=Sophos;i="6.05,226,1701158400"; d="scan'208";a="9650774" Received: from fmviesa005.fm.intel.com ([10.60.135.145]) by fmvoesa103.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 29 Jan 2024 01:39:39 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.05,226,1701158400"; d="scan'208";a="3246388" Received: from hbrandbe-mobl.ger.corp.intel.com (HELO localhost) ([10.252.59.53]) by fmviesa005-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 29 Jan 2024 01:39:34 -0800 From: Jani Nikula To: Mario Limonciello , amd-gfx@lists.freedesktop.org, Alex Deucher , Harry Wentland , "Rafael J . Wysocki" , Hans de Goede Cc: open list , "open list:DRM DRIVERS" , Melissa Wen , "open list:ACPI" , Mario Limonciello , Mark Pearson Subject: Re: [PATCH 2/2] drm/amd: Fetch the EDID from _DDC if available for eDP In-Reply-To: <20240126184639.8187-3-mario.limonciello@amd.com> Organization: Intel Finland Oy - BIC 0357606-4 - Westendinkatu 7, 02160 Espoo References: <20240126184639.8187-1-mario.limonciello@amd.com> <20240126184639.8187-3-mario.limonciello@amd.com> Date: Mon, 29 Jan 2024 11:39:32 +0200 Message-ID: <87le88jx63.fsf@intel.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain On Fri, 26 Jan 2024, Mario Limonciello wrote: > Some manufacturers have intentionally put an EDID that differs from > the EDID on the internal panel on laptops. > > Attempt to fetch this EDID if it exists and prefer it over the EDID > that is provided by the panel. > > Signed-off-by: Mario Limonciello > --- > drivers/gpu/drm/amd/amdgpu/amdgpu.h | 2 ++ > drivers/gpu/drm/amd/amdgpu/amdgpu_acpi.c | 30 +++++++++++++++++++ > .../gpu/drm/amd/amdgpu/amdgpu_connectors.c | 5 ++++ > .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 8 ++++- > .../amd/display/amdgpu_dm/amdgpu_dm_helpers.c | 7 +++-- > 5 files changed, 49 insertions(+), 3 deletions(-) > > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h > index c5f3859fd682..99abe12567a4 100644 > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h > @@ -1520,6 +1520,7 @@ int amdgpu_acpi_get_mem_info(struct amdgpu_device *adev, int xcc_id, > > void amdgpu_acpi_get_backlight_caps(struct amdgpu_dm_backlight_caps *caps); > bool amdgpu_acpi_should_gpu_reset(struct amdgpu_device *adev); > +void *amdgpu_acpi_edid(struct amdgpu_device *adev, struct drm_connector *connector); > void amdgpu_acpi_detect(void); > void amdgpu_acpi_release(void); > #else > @@ -1537,6 +1538,7 @@ static inline int amdgpu_acpi_get_mem_info(struct amdgpu_device *adev, > } > static inline void amdgpu_acpi_fini(struct amdgpu_device *adev) { } > static inline bool amdgpu_acpi_should_gpu_reset(struct amdgpu_device *adev) { return false; } > +static inline void *amdgpu_acpi_edid(struct amdgpu_device *adev, struct drm_connector *connector) { return NULL; } > static inline void amdgpu_acpi_detect(void) { } > static inline void amdgpu_acpi_release(void) { } > static inline bool amdgpu_acpi_is_power_shift_control_supported(void) { return false; } > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_acpi.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_acpi.c > index e550067e5c5d..c106335f1f22 100644 > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_acpi.c > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_acpi.c > @@ -1380,6 +1380,36 @@ bool amdgpu_acpi_should_gpu_reset(struct amdgpu_device *adev) > #endif > } > > +/** > + * amdgpu_acpi_edid > + * @adev: amdgpu_device pointer > + * @connector: drm_connector pointer > + * > + * Returns the EDID used for the internal panel if present, NULL otherwise. > + */ > +void * > +amdgpu_acpi_edid(struct amdgpu_device *adev, struct drm_connector *connector) > +{ > + struct drm_device *ddev = adev_to_drm(adev); > + struct acpi_device *acpidev = ACPI_COMPANION(ddev->dev); > + void *edid; > + int r; > + > + if (!acpidev) > + return NULL; > + > + if (connector->connector_type != DRM_MODE_CONNECTOR_eDP) > + return NULL; > + > + r = acpi_video_get_edid(acpidev, ACPI_VIDEO_DISPLAY_LCD, -1, &edid); > + if (r < 0) { > + DRM_DEBUG_DRIVER("Failed to get EDID from ACPI: %d\n", r); > + return NULL; > + } > + > + return kmemdup(edid, r, GFP_KERNEL); > +} > + > /* > * amdgpu_acpi_detect - detect ACPI ATIF/ATCS methods > * > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c > index 9caba10315a8..c7e1563a46d3 100644 > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c > @@ -278,6 +278,11 @@ static void amdgpu_connector_get_edid(struct drm_connector *connector) > struct amdgpu_device *adev = drm_to_adev(dev); > struct amdgpu_connector *amdgpu_connector = to_amdgpu_connector(connector); > > + if (amdgpu_connector->edid) > + return; > + > + /* if the BIOS specifies the EDID via _DDC, prefer this */ > + amdgpu_connector->edid = amdgpu_acpi_edid(adev, connector); Imagine the EDID returned by acpi_video_get_edid() has edid->extensions bigger than 4. Of course it should not, but you have no guarantees, and it originates outside of the kernel. The real fix is to have the function return a struct drm_edid which tracks the allocation size separately. Unfortunately, it requires a bunch of changes along the way. We've mostly done it in i915, and I've sent a series to do this in drm/bridge [1]. Bottom line, we should stop using struct edid in drivers. They'll all parse the info differently, and from what I've seen, often wrong. BR, Jani. [1] https://patchwork.freedesktop.org/series/128149/ > if (amdgpu_connector->edid) > return; > > diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c > index cd98b3565178..1faa21f542bd 100644 > --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c > +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c > @@ -6562,17 +6562,23 @@ static void amdgpu_dm_connector_funcs_force(struct drm_connector *connector) > { > struct amdgpu_dm_connector *aconnector = to_amdgpu_dm_connector(connector); > struct amdgpu_connector *amdgpu_connector = to_amdgpu_connector(connector); > + struct amdgpu_device *adev = drm_to_adev(connector->dev); > struct dc_link *dc_link = aconnector->dc_link; > struct dc_sink *dc_em_sink = aconnector->dc_em_sink; > struct edid *edid; > > + /* prefer ACPI over panel for eDP */ > + edid = amdgpu_acpi_edid(adev, connector); > + > /* > * Note: drm_get_edid gets edid in the following order: > * 1) override EDID if set via edid_override debugfs, > * 2) firmware EDID if set via edid_firmware module parameter > * 3) regular DDC read. > */ > - edid = drm_get_edid(connector, &amdgpu_connector->ddc_bus->aux.ddc); > + if (!edid) > + edid = drm_get_edid(connector, &amdgpu_connector->ddc_bus->aux.ddc); > + > if (!edid) { > DRM_ERROR("No EDID found on connector: %s.\n", connector->name); > return; > diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c > index e3915c4f8566..6bf2a8867e76 100644 > --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c > +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c > @@ -895,6 +895,7 @@ enum dc_edid_status dm_helpers_read_local_edid( > { > struct amdgpu_dm_connector *aconnector = link->priv; > struct drm_connector *connector = &aconnector->base; > + struct amdgpu_device *adev = drm_to_adev(connector->dev); > struct i2c_adapter *ddc; > int retry = 3; > enum dc_edid_status edid_status; > @@ -909,8 +910,10 @@ enum dc_edid_status dm_helpers_read_local_edid( > * do check sum and retry to make sure read correct edid. > */ > do { > - > - edid = drm_get_edid(&aconnector->base, ddc); > + /* prefer ACPI over panel for eDP */ > + edid = amdgpu_acpi_edid(adev, connector); > + if (!edid) > + edid = drm_get_edid(&aconnector->base, ddc); > > /* DP Compliance Test 4.2.2.6 */ > if (link->aux_mode && connector->edid_corrupt) -- Jani Nikula, Intel