From patchwork Mon Apr 18 10:54:03 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Gupta, Anshuman" X-Patchwork-Id: 12816481 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 96E08C433EF for ; Mon, 18 Apr 2022 10:54:28 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 0777610F57E; Mon, 18 Apr 2022 10:54:28 +0000 (UTC) Received: from mga02.intel.com (mga02.intel.com [134.134.136.20]) by gabe.freedesktop.org (Postfix) with ESMTPS id 80B6810F57E for ; Mon, 18 Apr 2022 10:54:26 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1650279266; x=1681815266; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=WiPOGW4Bqx/9F7tkZ4rtuw0EhPSCPZ7Le7JEUOPLxCk=; b=C9Z07cSxkYsZf4B169K3oM+hS51sHAgNCEQTjYYhnNYG3A64KDtdUomW hGoyIj9u9VFxdjO63i3PRDf8YW4D2+XrZDyjy+Ho2mCAR+GUxt0S8FTdw GClnhpCRbJdBMCxDC+qX8DfU3Q+1gp/7TZ9fUMlu9LP6kpRUFWhmjJQe+ qZ5bagnYQiNDdA5Wvadtb02Pg1yqeHhyhV1n/aM0twUW2wDYW9EFHwz3K favmWeGPIUO9E6LzW7ZGVtsR7tLBtsjxyrd1gdnfpjByf5ml61OYmO6fc q+LbnLtgs/BIRsQBvKQzxDS8TSfJsfBnVaOzUbAeSodtVA0guNwfYnJbk A==; X-IronPort-AV: E=McAfee;i="6400,9594,10320"; a="250798256" X-IronPort-AV: E=Sophos;i="5.90,269,1643702400"; d="scan'208";a="250798256" Received: from orsmga004.jf.intel.com ([10.7.209.38]) by orsmga101.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 18 Apr 2022 03:54:26 -0700 X-IronPort-AV: E=Sophos;i="5.90,269,1643702400"; d="scan'208";a="665139319" Received: from srr4-3-linux-105-anshuma1.iind.intel.com ([10.223.74.179]) by orsmga004-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 18 Apr 2022 03:54:23 -0700 From: Anshuman Gupta To: intel-gfx@lists.freedesktop.org Date: Mon, 18 Apr 2022 16:24:03 +0530 Message-Id: <20220418105408.13444-2-anshuman.gupta@intel.com> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20220418105408.13444-1-anshuman.gupta@intel.com> References: <20220418105408.13444-1-anshuman.gupta@intel.com> MIME-Version: 1.0 Subject: [Intel-gfx] [PATCH v4 1/6] drm/i915/opregion: Add intel_opregion_init() wrapper 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@intel.com, lucas.demarchi@intel.com, rodrigo.vivi@intel.com Errors-To: intel-gfx-bounces@lists.freedesktop.org Sender: "Intel-gfx" Adding intel_opregion_init() wrapper function, which encapsulates intel_opregion_setup() and will be used for other opregion specific initialization. Signed-off-by: Anshuman Gupta --- drivers/gpu/drm/i915/display/intel_opregion.c | 12 +++++++++++- drivers/gpu/drm/i915/display/intel_opregion.h | 4 ++-- drivers/gpu/drm/i915/i915_driver.c | 2 +- 3 files changed, 14 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_opregion.c b/drivers/gpu/drm/i915/display/intel_opregion.c index f31e8c3f8ce0..9b56064ddb5d 100644 --- a/drivers/gpu/drm/i915/display/intel_opregion.c +++ b/drivers/gpu/drm/i915/display/intel_opregion.c @@ -873,7 +873,7 @@ static int intel_load_vbt_firmware(struct drm_i915_private *dev_priv) return ret; } -int intel_opregion_setup(struct drm_i915_private *dev_priv) +static int intel_opregion_setup(struct drm_i915_private *dev_priv) { struct intel_opregion *opregion = &dev_priv->opregion; struct pci_dev *pdev = to_pci_dev(dev_priv->drm.dev); @@ -1232,3 +1232,13 @@ void intel_opregion_unregister(struct drm_i915_private *i915) opregion->vbt = NULL; opregion->lid_state = NULL; } + +/** + * intel_opregion_init() - Init ACPI opregion. + * @i915 i915 device priv data. + * opregion init wrapper function, which encapsulate intel_opregion_setup. + */ +int intel_opregion_init(struct drm_i915_private *i915) +{ + return intel_opregion_setup(i915); +} diff --git a/drivers/gpu/drm/i915/display/intel_opregion.h b/drivers/gpu/drm/i915/display/intel_opregion.h index 82cc0ba34af7..744d53c804e2 100644 --- a/drivers/gpu/drm/i915/display/intel_opregion.h +++ b/drivers/gpu/drm/i915/display/intel_opregion.h @@ -59,7 +59,7 @@ struct intel_opregion { #ifdef CONFIG_ACPI -int intel_opregion_setup(struct drm_i915_private *dev_priv); +int intel_opregion_init(struct drm_i915_private *i915); void intel_opregion_register(struct drm_i915_private *dev_priv); void intel_opregion_unregister(struct drm_i915_private *dev_priv); @@ -78,7 +78,7 @@ struct edid *intel_opregion_get_edid(struct intel_connector *connector); #else /* CONFIG_ACPI*/ -static inline int intel_opregion_setup(struct drm_i915_private *dev_priv) +static inline int intel_opregion_init(struct drm_i915_private *i915) { return 0; } diff --git a/drivers/gpu/drm/i915/i915_driver.c b/drivers/gpu/drm/i915/i915_driver.c index 3ffb617d75c9..c75548e1c7cf 100644 --- a/drivers/gpu/drm/i915/i915_driver.c +++ b/drivers/gpu/drm/i915/i915_driver.c @@ -634,7 +634,7 @@ static int i915_driver_hw_probe(struct drm_i915_private *dev_priv) if (ret) goto err_msi; - intel_opregion_setup(dev_priv); + intel_opregion_init(dev_priv); ret = intel_pcode_init(dev_priv); if (ret) From patchwork Mon Apr 18 10:54:04 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Gupta, Anshuman" X-Patchwork-Id: 12816482 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 E6753C433FE for ; Mon, 18 Apr 2022 10:54:31 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 697D910F57F; Mon, 18 Apr 2022 10:54:31 +0000 (UTC) Received: from mga02.intel.com (mga02.intel.com [134.134.136.20]) by gabe.freedesktop.org (Postfix) with ESMTPS id DF52B10F57F for ; Mon, 18 Apr 2022 10:54:29 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1650279269; x=1681815269; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=EsTreps34wHQq/JpTa/3TQgOKkUTkHCqKq4UDWEpZMc=; b=f+32bwOXe6vfeNDVUwxBLUkfmQ5rfFAaVMXfmdTlclfJIlXbzp/LZc2x 9wfOLb+btUHQPFpoeq/e10fkxzsZOl0cus9iZIksQAe/lxCiExZtbf+nV Ryp0oMOQcrt8vH+3wfPFZ/1JgNnp7/wnZG/wRXPphUwPaNRhE73Da7T2r IlyfrydjB5cEWjNj8LA4C/1eaRYnVZtB4HgKqKuln+wQCQqoT4mRA+rMq J3gP/ZquCYF7fYI04bK3VyLMlQbCO3GRl96HavKW0UpptuFrJC+ZDUnAz nYjlnHfQ7fseImDiTtSteg9rYRoe6JtMIFq8QtkGn4dq1iY3lbrByiBov g==; X-IronPort-AV: E=McAfee;i="6400,9594,10320"; a="250798267" X-IronPort-AV: E=Sophos;i="5.90,269,1643702400"; d="scan'208";a="250798267" Received: from orsmga004.jf.intel.com ([10.7.209.38]) by orsmga101.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 18 Apr 2022 03:54:29 -0700 X-IronPort-AV: E=Sophos;i="5.90,269,1643702400"; d="scan'208";a="665139336" Received: from srr4-3-linux-105-anshuma1.iind.intel.com ([10.223.74.179]) by orsmga004-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 18 Apr 2022 03:54:26 -0700 From: Anshuman Gupta To: intel-gfx@lists.freedesktop.org Date: Mon, 18 Apr 2022 16:24:04 +0530 Message-Id: <20220418105408.13444-3-anshuman.gupta@intel.com> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20220418105408.13444-1-anshuman.gupta@intel.com> References: <20220418105408.13444-1-anshuman.gupta@intel.com> MIME-Version: 1.0 Subject: [Intel-gfx] [PATCH v4 2/6] drm/i915/opregion: Abstract opregion function 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@intel.com, lucas.demarchi@intel.com, rodrigo.vivi@intel.com Errors-To: intel-gfx-bounces@lists.freedesktop.org Sender: "Intel-gfx" Abstract opregion operations like get opregion base, get rvda and opregion cleanup in form of i915_opregion_ops. This will be required to converge igfx and dgfx opregion. v2: - Keep only function pointer abstraction stuff. [Jani] - Add alloc_rvda error handling. v3: - Added necessary credit to Manasi for static analysis fix around drm_WARN_ON(&i915->drm, !opregion->asls || !opregion->header) v4: - intel_opregion_get_asls() returns asls. [Jani] - Added IS_ERR(rvda)in free_rvda(). [Jani] - Fix free_{opregion, rvda} abstraction level. [Jani] Cc: Jani Nikula Cc: Rodrigo Vivi Cc: Badal Nilawar Cc: Uma Shankar Signed-off-by: Manasi Navare Signed-off-by: Anshuman Gupta --- drivers/gpu/drm/i915/display/intel_opregion.c | 177 +++++++++++++----- drivers/gpu/drm/i915/display/intel_opregion.h | 3 + 2 files changed, 133 insertions(+), 47 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_opregion.c b/drivers/gpu/drm/i915/display/intel_opregion.c index 9b56064ddb5d..e43aac5c0425 100644 --- a/drivers/gpu/drm/i915/display/intel_opregion.c +++ b/drivers/gpu/drm/i915/display/intel_opregion.c @@ -138,6 +138,13 @@ struct opregion_asle_ext { u8 rsvd[764]; } __packed; +struct i915_opregion_func { + void *(*alloc_opregion)(struct drm_i915_private *i915); + void *(*alloc_rvda)(struct drm_i915_private *i915); + void (*free_rvda)(struct drm_i915_private *i915, void *rvda); + void (*free_opregion)(struct drm_i915_private *i915, void *opregion); +}; + /* Driver readiness indicator */ #define ASLE_ARDY_READY (1 << 0) #define ASLE_ARDY_NOT_READY (0 << 0) @@ -876,10 +883,7 @@ static int intel_load_vbt_firmware(struct drm_i915_private *dev_priv) static int intel_opregion_setup(struct drm_i915_private *dev_priv) { struct intel_opregion *opregion = &dev_priv->opregion; - struct pci_dev *pdev = to_pci_dev(dev_priv->drm.dev); - u32 asls, mboxes; - char buf[sizeof(OPREGION_SIGNATURE)]; - int err = 0; + u32 mboxes; void *base; const void *vbt; u32 vbt_size; @@ -890,27 +894,12 @@ static int intel_opregion_setup(struct drm_i915_private *dev_priv) BUILD_BUG_ON(sizeof(struct opregion_asle) != 0x100); BUILD_BUG_ON(sizeof(struct opregion_asle_ext) != 0x400); - pci_read_config_dword(pdev, ASLS, &asls); - drm_dbg(&dev_priv->drm, "graphic opregion physical addr: 0x%x\n", - asls); - if (asls == 0) { - drm_dbg(&dev_priv->drm, "ACPI OpRegion not supported!\n"); - return -ENOTSUPP; - } - INIT_WORK(&opregion->asle_work, asle_work); - base = memremap(asls, OPREGION_SIZE, MEMREMAP_WB); - if (!base) - return -ENOMEM; + base = opregion->opregion_func->alloc_opregion(dev_priv); + if (IS_ERR(base)) + return PTR_ERR(base); - memcpy(buf, base, sizeof(buf)); - - if (memcmp(buf, OPREGION_SIGNATURE, 16)) { - drm_dbg(&dev_priv->drm, "opregion signature mismatch\n"); - err = -EINVAL; - goto err_out; - } opregion->header = base; opregion->lid_state = base + ACPI_CLID; @@ -970,23 +959,10 @@ static int intel_opregion_setup(struct drm_i915_private *dev_priv) if (opregion->header->over.major >= 2 && opregion->asle && opregion->asle->rvda && opregion->asle->rvds) { - resource_size_t rvda = opregion->asle->rvda; - - /* - * opregion 2.0: rvda is the physical VBT address. - * - * opregion 2.1+: rvda is unsigned, relative offset from - * opregion base, and should never point within opregion. - */ - if (opregion->header->over.major > 2 || - opregion->header->over.minor >= 1) { - drm_WARN_ON(&dev_priv->drm, rvda < OPREGION_SIZE); - - rvda += asls; - } - opregion->rvda = memremap(rvda, opregion->asle->rvds, - MEMREMAP_WB); + opregion->rvda = opregion->opregion_func->alloc_rvda(dev_priv); + if (IS_ERR(opregion->rvda)) + goto mbox4_vbt; vbt = opregion->rvda; vbt_size = opregion->asle->rvds; @@ -999,11 +975,13 @@ static int intel_opregion_setup(struct drm_i915_private *dev_priv) } else { drm_dbg_kms(&dev_priv->drm, "Invalid VBT in ACPI OpRegion (RVDA)\n"); - memunmap(opregion->rvda); + opregion->opregion_func->free_rvda(dev_priv, opregion->rvda); opregion->rvda = NULL; } } +mbox4_vbt: + vbt = base + OPREGION_VBT_OFFSET; /* * The VBT specification says that if the ASLE ext mailbox is not used @@ -1028,9 +1006,6 @@ static int intel_opregion_setup(struct drm_i915_private *dev_priv) out: return 0; -err_out: - memunmap(base); - return err; } static int intel_use_opregion_panel_type_callback(const struct dmi_system_id *id) @@ -1215,11 +1190,11 @@ void intel_opregion_unregister(struct drm_i915_private *i915) } /* just clear all opregion memory pointers now */ - memunmap(opregion->header); - if (opregion->rvda) { - memunmap(opregion->rvda); - opregion->rvda = NULL; - } + opregion->opregion_func->free_rvda(i915, opregion->rvda); + opregion->rvda = NULL; + opregion->opregion_func->free_opregion(i915, opregion->header); + opregion->header = NULL; + if (opregion->vbt_firmware) { kfree(opregion->vbt_firmware); opregion->vbt_firmware = NULL; @@ -1233,6 +1208,110 @@ void intel_opregion_unregister(struct drm_i915_private *i915) opregion->lid_state = NULL; } +static u32 +intel_opregion_get_asls(struct drm_i915_private *i915) +{ + struct pci_dev *pdev = to_pci_dev(i915->drm.dev); + u32 asls; + + pci_read_config_dword(pdev, ASLS, &asls); + drm_dbg(&i915->drm, "graphic opregion physical addr: 0x%x\n", + asls); + + return asls; +} + +static void *intel_igfx_alloc_opregion(struct drm_i915_private *i915) +{ + struct intel_opregion *opregion = &i915->opregion; + char buf[sizeof(OPREGION_SIGNATURE)]; + int err = 0; + void *base; + u32 asls; + + asls = intel_opregion_get_asls(i915); + if (asls == 0) { + drm_dbg(&i915->drm, "ACPI OpRegion not supported!\n"); + return ERR_PTR(-EINVAL); + } + + opregion->asls = asls; + base = memremap(opregion->asls, OPREGION_SIZE, MEMREMAP_WB); + if (!base) + return ERR_PTR(-ENOMEM); + + memcpy(buf, base, sizeof(buf)); + + if (memcmp(buf, OPREGION_SIGNATURE, 16)) { + drm_dbg(&i915->drm, "opregion signature mismatch\n"); + err = -EINVAL; + goto err_out; + } + + return base; + +err_out: + memunmap(base); + + return ERR_PTR(err); +} + +static void *intel_igfx_alloc_rvda(struct drm_i915_private *i915) +{ + struct intel_opregion *opregion = &i915->opregion; + resource_size_t rvda; + void *opreg_rvda; + + if (drm_WARN_ON(&i915->drm, !opregion->asls || !opregion->header)) + return ERR_PTR(-ENODEV); + + rvda = opregion->asle->rvda; + + /* + * opregion 2.0: rvda is the physical VBT address. + * + * opregion 2.1+: rvda is unsigned, relative offset from + * opregion base, and should never point within opregion. + */ + if (opregion->header->over.major > 2 || + opregion->header->over.minor >= 1) { + drm_WARN_ON(&i915->drm, rvda < OPREGION_SIZE); + + rvda += opregion->asls; + } + + opreg_rvda = memremap(rvda, opregion->asle->rvds, MEMREMAP_WB); + if (!opreg_rvda) + return ERR_PTR(-ENOMEM); + + return opreg_rvda; +} + +static void intel_igfx_free_rvda(struct drm_i915_private *i915, void *rvda) +{ + if (IS_ERR(rvda)) + return; + + if (rvda) + memunmap(rvda); +} + +static void intel_igfx_free_opregion(struct drm_i915_private *i915, void *opreg) +{ + if (IS_ERR(opreg)) + return; + + if (opreg) + memunmap(opreg); +} + +static const struct i915_opregion_func igfx_opregion_func = { + .alloc_opregion = intel_igfx_alloc_opregion, + .alloc_rvda = intel_igfx_alloc_rvda, + .free_rvda = intel_igfx_free_rvda, + .free_opregion = intel_igfx_free_opregion, +}; + /** * intel_opregion_init() - Init ACPI opregion. * @i915 i915 device priv data. @@ -1240,5 +1319,9 @@ void intel_opregion_unregister(struct drm_i915_private *i915) */ int intel_opregion_init(struct drm_i915_private *i915) { + struct intel_opregion *opregion = &i915->opregion; + + opregion->opregion_func = &igfx_opregion_func; + return intel_opregion_setup(i915); } diff --git a/drivers/gpu/drm/i915/display/intel_opregion.h b/drivers/gpu/drm/i915/display/intel_opregion.h index 744d53c804e2..7500c396b74d 100644 --- a/drivers/gpu/drm/i915/display/intel_opregion.h +++ b/drivers/gpu/drm/i915/display/intel_opregion.h @@ -37,6 +37,7 @@ struct opregion_acpi; struct opregion_swsci; struct opregion_asle; struct opregion_asle_ext; +struct i915_opregion_func; struct intel_opregion { struct opregion_header *header; @@ -46,6 +47,8 @@ struct intel_opregion { u32 swsci_sbcb_sub_functions; struct opregion_asle *asle; struct opregion_asle_ext *asle_ext; + const struct i915_opregion_func *opregion_func; + resource_size_t asls; void *rvda; void *vbt_firmware; const void *vbt; From patchwork Mon Apr 18 10:54:05 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Gupta, Anshuman" X-Patchwork-Id: 12816483 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 9D021C433F5 for ; Mon, 18 Apr 2022 10:54:34 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 3EDA210F580; Mon, 18 Apr 2022 10:54:34 +0000 (UTC) Received: from mga02.intel.com (mga02.intel.com [134.134.136.20]) by gabe.freedesktop.org (Postfix) with ESMTPS id 8F0FF10F580 for ; Mon, 18 Apr 2022 10:54:32 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1650279272; x=1681815272; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=JeCKXwJfvj3mPd9/Xa6RwbmL8qkj843RGPKIDgZgiZU=; b=e6+ZUmXpAIdivaiQecGm6BB1kaS5rZM/epcLioOkpwzYYRUUwQBV5OMO BT/qDgYvunWEmBPeubiq+DVx3Hn5OO+hEeBbtzw8fEeL20SvtmJY7UxAH 6Lks5zdaRrPr8uKzx/ApbgPW5/ACie8/bdkLIzxwekYziA/IbF2Pynkpr 5VCKSJqlK3zgGRKbiABf8+DqRffpuIOaYZTurgjdKwn3DsSwi4N/fDuJb FqUttiYXhIUUU202zcUYcG+YtmU1tUgQPRm5reKzoAN9IwiZ39HTjo25F zAjaec6Li1yMaSLaIZW8vBzTbjXh0RrEtZbdKjlAavZJK9Fe0ibXJwXmy g==; X-IronPort-AV: E=McAfee;i="6400,9594,10320"; a="250798268" X-IronPort-AV: E=Sophos;i="5.90,269,1643702400"; d="scan'208";a="250798268" Received: from orsmga004.jf.intel.com ([10.7.209.38]) by orsmga101.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 18 Apr 2022 03:54:32 -0700 X-IronPort-AV: E=Sophos;i="5.90,269,1643702400"; d="scan'208";a="665139365" Received: from srr4-3-linux-105-anshuma1.iind.intel.com ([10.223.74.179]) by orsmga004-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 18 Apr 2022 03:54:29 -0700 From: Anshuman Gupta To: intel-gfx@lists.freedesktop.org Date: Mon, 18 Apr 2022 16:24:05 +0530 Message-Id: <20220418105408.13444-4-anshuman.gupta@intel.com> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20220418105408.13444-1-anshuman.gupta@intel.com> References: <20220418105408.13444-1-anshuman.gupta@intel.com> MIME-Version: 1.0 Subject: [Intel-gfx] [PATCH v4 3/6] drm/i915/opregion: Add dgfx opregion func 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@intel.com, lucas.demarchi@intel.com, rodrigo.vivi@intel.com Errors-To: intel-gfx-bounces@lists.freedesktop.org Sender: "Intel-gfx" Adding DGFX opregion dummy functions. These will be setup later to support dgfx opregion. Signed-off-by: Anshuman Gupta --- drivers/gpu/drm/i915/display/intel_opregion.c | 34 +++++++++++++++++-- 1 file changed, 32 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_opregion.c b/drivers/gpu/drm/i915/display/intel_opregion.c index e43aac5c0425..6bba0e2cff72 100644 --- a/drivers/gpu/drm/i915/display/intel_opregion.c +++ b/drivers/gpu/drm/i915/display/intel_opregion.c @@ -1312,16 +1312,46 @@ static const struct i915_opregion_func igfx_opregion_func = { .free_opregion = intel_igfx_free_opregion, }; +static void *intel_dgfx_alloc_opregion(struct drm_i915_private *i915) +{ + return ERR_PTR(-EOPNOTSUPP); +} + +static void *intel_dgfx_alloc_rvda(struct drm_i915_private *i915) +{ + return ERR_PTR(-EOPNOTSUPP); +} + +static void intel_dgfx_free_rvda(struct drm_i915_private *i915, void *rvda) +{ +} + +static void intel_dgfx_free_opregion(struct drm_i915_private *i915, void *opreg) +{ +} + +static const struct i915_opregion_func dgfx_opregion_func = { + .alloc_opregion = intel_dgfx_alloc_opregion, + .alloc_rvda = intel_dgfx_alloc_rvda, + .free_rvda = intel_dgfx_free_rvda, + .free_opregion = intel_dgfx_free_opregion, +}; + /** * intel_opregion_init() - Init ACPI opregion. * @i915 i915 device priv data. - * opregion init wrapper function, which encapsulate intel_opregion_setup. + * opregion init wrapper function. + * It initialize the dgfx/igfx opregion function pointers, + * and encapsulate intel_opregion_setup. */ int intel_opregion_init(struct drm_i915_private *i915) { struct intel_opregion *opregion = &i915->opregion; - opregion->opregion_func = &igfx_opregion_func; + if (IS_DGFX(i915)) + opregion->opregion_func = &dgfx_opregion_func; + else + opregion->opregion_func = &igfx_opregion_func; return intel_opregion_setup(i915); } From patchwork Mon Apr 18 10:54:06 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Gupta, Anshuman" X-Patchwork-Id: 12816484 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 9D29EC433F5 for ; Mon, 18 Apr 2022 10:54:38 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 0404F10F584; Mon, 18 Apr 2022 10:54:38 +0000 (UTC) Received: from mga02.intel.com (mga02.intel.com [134.134.136.20]) by gabe.freedesktop.org (Postfix) with ESMTPS id 5FF3010F582 for ; Mon, 18 Apr 2022 10:54:35 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1650279275; x=1681815275; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=AhQNzAHAU4k1A9ssUslI/owF+XXEY1s/dpk0Ht2gesU=; b=dZy+GYdXAxuNfKioPMxeY773FNjDRO1anL5tgbTurCb4DobPbKbjlrT7 jhouiGNzhpFdYs9x8PaeGaRMcQYR0BzLzdV/4mBBrmiMNHmJBrqLwCH5m 9GEl1G45GbM2EV2g7xvGA2OyIqmtPMjZ9DFJlAPRmRih7PStxLWRu078z mdMpk5aCGAI0csvY8o+iEybZXnDGz7lnZ7pTkWdrxfkQxgNrRu8aCkRnP JgP5zvgYIq+A2x+eh6bKdYvwJKz82NG9kvDy3TJjuoIEWYyaZ9f/kfIWD KZE4D4emUxpk6teTcIx3L0VqqedlUKoPpEAkj784puN4mdKcOpD4GKVz/ g==; X-IronPort-AV: E=McAfee;i="6400,9594,10320"; a="250798271" X-IronPort-AV: E=Sophos;i="5.90,269,1643702400"; d="scan'208";a="250798271" Received: from orsmga004.jf.intel.com ([10.7.209.38]) by orsmga101.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 18 Apr 2022 03:54:35 -0700 X-IronPort-AV: E=Sophos;i="5.90,269,1643702400"; d="scan'208";a="665139389" Received: from srr4-3-linux-105-anshuma1.iind.intel.com ([10.223.74.179]) by orsmga004-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 18 Apr 2022 03:54:32 -0700 From: Anshuman Gupta To: intel-gfx@lists.freedesktop.org Date: Mon, 18 Apr 2022 16:24:06 +0530 Message-Id: <20220418105408.13444-5-anshuman.gupta@intel.com> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20220418105408.13444-1-anshuman.gupta@intel.com> References: <20220418105408.13444-1-anshuman.gupta@intel.com> MIME-Version: 1.0 Subject: [Intel-gfx] [PATCH v4 4/6] drm/i915/opregion: Cond dgfx opregion func registration 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@intel.com, lucas.demarchi@intel.com, rodrigo.vivi@intel.com Errors-To: intel-gfx-bounces@lists.freedesktop.org Sender: "Intel-gfx" DGFX ASLS and OPROM OpRegion are only supported on the GFX Cards, which supports Display Engine. Register opregion function accordingly using the HAS_DISPLAY(). And early return intel_opregion_setup() if no opregion func to avoid NULL pointer oops. v2: - Change the commit log. v3: - Use nested condition for IS_DGFX() and HAS_DISPLAY(). [Jani] Cc: Badal Nilawar Cc: Jani Nikula Cc: Uma Shankar Signed-off-by: Anshuman Gupta --- drivers/gpu/drm/i915/display/intel_opregion.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_opregion.c b/drivers/gpu/drm/i915/display/intel_opregion.c index 6bba0e2cff72..8e5960ec30de 100644 --- a/drivers/gpu/drm/i915/display/intel_opregion.c +++ b/drivers/gpu/drm/i915/display/intel_opregion.c @@ -894,6 +894,9 @@ static int intel_opregion_setup(struct drm_i915_private *dev_priv) BUILD_BUG_ON(sizeof(struct opregion_asle) != 0x100); BUILD_BUG_ON(sizeof(struct opregion_asle_ext) != 0x400); + if (!opregion->opregion_func) + return 0; + INIT_WORK(&opregion->asle_work, asle_work); base = opregion->opregion_func->alloc_opregion(dev_priv); @@ -1348,10 +1351,12 @@ int intel_opregion_init(struct drm_i915_private *i915) { struct intel_opregion *opregion = &i915->opregion; - if (IS_DGFX(i915)) - opregion->opregion_func = &dgfx_opregion_func; - else + if (IS_DGFX(i915)) { + if (HAS_DISPLAY(i915)) + opregion->opregion_func = &dgfx_opregion_func; + } else { opregion->opregion_func = &igfx_opregion_func; + } return intel_opregion_setup(i915); } From patchwork Mon Apr 18 10:54:07 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Gupta, Anshuman" X-Patchwork-Id: 12816485 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 D0A7CC433F5 for ; Mon, 18 Apr 2022 10:54:41 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 57BF110F582; Mon, 18 Apr 2022 10:54:41 +0000 (UTC) Received: from mga02.intel.com (mga02.intel.com [134.134.136.20]) by gabe.freedesktop.org (Postfix) with ESMTPS id 04EBF10F585 for ; Mon, 18 Apr 2022 10:54:38 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1650279279; x=1681815279; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=y9+QaVW5X/uO+tgUM91c6Vis3w9+2tpQHIAEPwlzIYg=; b=NQr9/vus3Kq60ZdvZNXUf9edNH2YVD/r4HHuF7QwYbWO0L6rEJjJarsF KmrsQ3AzEkDmqNMwC1m6Pc6cwIg4mHyl94gM9sJtlePZkdtNWbLJmGbDw WavXgkEerABD4usZQOBdCk6nS2+8/5MX1316UrQDPN4GuYSZIR3oyrMl9 bcnB0houqnp6NrSkuA9HVrb6KVwGOj6nvH3TJn1GcrDfrXDODjbADubfH Ueayl/X0u3Hi9KzlgyvTzduNNWHeE3mDgiab/GQ1/mnCTaC9NzV7qdJ02 b7LEirJlgfBqOacdF+SaRwpB3tImAy5E/PrIaREJCbsYfzvwxVSSTbj+u Q==; X-IronPort-AV: E=McAfee;i="6400,9594,10320"; a="250798278" X-IronPort-AV: E=Sophos;i="5.90,269,1643702400"; d="scan'208";a="250798278" Received: from orsmga004.jf.intel.com ([10.7.209.38]) by orsmga101.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 18 Apr 2022 03:54:38 -0700 X-IronPort-AV: E=Sophos;i="5.90,269,1643702400"; d="scan'208";a="665139419" Received: from srr4-3-linux-105-anshuma1.iind.intel.com ([10.223.74.179]) by orsmga004-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 18 Apr 2022 03:54:35 -0700 From: Anshuman Gupta To: intel-gfx@lists.freedesktop.org Date: Mon, 18 Apr 2022 16:24:07 +0530 Message-Id: <20220418105408.13444-6-anshuman.gupta@intel.com> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20220418105408.13444-1-anshuman.gupta@intel.com> References: <20220418105408.13444-1-anshuman.gupta@intel.com> MIME-Version: 1.0 Subject: [Intel-gfx] [PATCH v4 5/6] drm/i915/dgfx: OPROM OpRegion Setup 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@intel.com, lucas.demarchi@intel.com, rodrigo.vivi@intel.com Errors-To: intel-gfx-bounces@lists.freedesktop.org Sender: "Intel-gfx" On igfx cards ACPI OpRegion retrieve through ASLS. System BIOS writes ASLS address to pci config space(0xFC) but on discrete cards OpRegion is part of PCI Option ROM(OPROM) along with other firmware images, i915 is interested only in Code Signature System(CSS) and OpRegion + VBT image. DGFX Cards has it dedicated flash, where OPROM reside. DGFX card provides SPI controller interface to read the OPROM. Read OPROM through SPI MMIO because PCI ROM mapping may does not work on some platforms due to the BIOS not leaving the OPROM mapped. In order to setup OpRegion and retrieve VBT from OpRegion, it is required to do OPROM sanity check. OPROM Sanity checks involves below steps. Verify OPROM images Signature as Documented in PCI firmware Specs 3.2. Verify Intel CSS image signature. Verify the Intel CSS image code type. Authenticate OPROM RSA Signature. (TODO) Verify OpRegion image Signature. After successful sanity check, driver will consume the OPROM config data to get opreg and vbt accordingly. v2: - Add kzalloc NULL check for oprom_opreg pointer. - Fixed memory leak in intel_spi_get_oprom_opreg(). v3: - Added kmemdup insead of kzalloc() + memcpy() in intel_dgfx_alloc_opregion(), and added necessary credit to Manasi. v4: - Fix free_{opregion, rvda} abstraction level. [Jani] PCI Firmware Spec: ID:12886 https://pcisig.com/specifications Cc: Jani Nikula Cc: Rodrigo Vivi Cc: Uma Shankar Cc: Badal Nilawar Signed-off-by: Manasi Navare Signed-off-by: Anshuman Gupta --- drivers/gpu/drm/i915/display/intel_opregion.c | 332 +++++++++++++++++- drivers/gpu/drm/i915/display/intel_opregion.h | 1 + 2 files changed, 320 insertions(+), 13 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_opregion.c b/drivers/gpu/drm/i915/display/intel_opregion.c index 8e5960ec30de..18770e564044 100644 --- a/drivers/gpu/drm/i915/display/intel_opregion.c +++ b/drivers/gpu/drm/i915/display/intel_opregion.c @@ -31,6 +31,7 @@ #include #include "i915_drv.h" +#include "i915_reg.h" #include "intel_acpi.h" #include "intel_backlight.h" #include "intel_display_types.h" @@ -145,6 +146,34 @@ struct i915_opregion_func { void (*free_opregion)(struct drm_i915_private *i915, void *opregion); }; +/* Refer 8_PCI_Firmware_v3.2_01-26-2015_ts_clean_Firmware_Final Page 77 */ +struct expansion_rom_header { + u16 signature; /* Offset[0x0]: Header 0x55 0xAA */ + u8 resvd[0x16]; + u16 pcistructoffset; /* Offset[0x18]: Contains pointer PCI Data Structure */ + u16 img_base; /* Offset[0x1A]: Offset to Oprom Image Base start */ +} __packed; + +struct pci_data_structure { + u32 signature; + u8 resvd[12]; + u16 img_len; + u8 resvd1[2]; + u8 code_type; + u8 last_img; + u8 resvd2[6]; +} __packed; + +/* PCI Firmware Spec specific Macro */ +#define LAST_IMG_INDICATOR 0x80 +#define OPROM_IMAGE_MAGIC 0xAA55 /* Little Endian */ +#define OPROM_IMAGE_PCIR_MAGIC 0x52494350 /* "PCIR" */ +#define OPROM_BYTE_BOUNDARY 512 /* OPROM image sizes are in 512 byte */ + +#define INTEL_CSS_SIGNATURE "$CPD" /* Code Signature System Signature */ +#define NUM_CSS_BYTES 4 +#define INTEL_OPROM_CSS_CODE_TYPE 0xF0 + /* Driver readiness indicator */ #define ASLE_ARDY_READY (1 << 0) #define ASLE_ARDY_NOT_READY (0 << 0) @@ -880,6 +909,196 @@ static int intel_load_vbt_firmware(struct drm_i915_private *dev_priv) return ret; } +/* Refer PCI Firmware Spec Chapter 5 */ +static int +pci_exp_rom_check_signature(struct drm_i915_private *i915, + struct expansion_rom_header *exprom_hdr, + struct pci_data_structure *exprom_pci_data) +{ + if (exprom_hdr->signature != OPROM_IMAGE_MAGIC) { + drm_err(&i915->drm, "Invalid PCI ROM header signature.\n"); + return -EINVAL; + } + + if (exprom_pci_data->signature != OPROM_IMAGE_PCIR_MAGIC) { + drm_err(&i915->drm, "Invalid PCI ROM data signature.\n"); + return -EINVAL; + } + + return 0; +} + +static u32 intel_spi_oprom_offset(struct drm_i915_private *i915) +{ + u32 static_region, offset; + + /* initialize SPI to read the OPROM */ + static_region = intel_uncore_read(&i915->uncore, SPI_STATIC_REGIONS); + static_region &= OPTIONROM_SPI_REGIONID_MASK; + intel_uncore_write(&i915->uncore, PRIMARY_SPI_REGIONID, static_region); + + /* read OPROM offset in SPI flash */ + offset = intel_uncore_read(&i915->uncore, OROM_OFFSET); + + return offset; +} + +static void intel_spi_read_oprom(struct drm_i915_private *i915, + u32 offset, size_t len, void *buf) +{ + u32 count, data; + u32 *word = buf; + + drm_WARN_ON(&i915->drm, !IS_ALIGNED(len, 4)); + + for (count = 0; count < len; count += 4) { + intel_uncore_write(&i915->uncore, PRIMARY_SPI_ADDRESS, offset + count); + data = intel_uncore_read(&i915->uncore, PRIMARY_SPI_TRIGGER); + word[count >> 2] = data; + } +} + +static int intel_verify_css(struct drm_i915_private *i915, + struct expansion_rom_header *exprom_hdr, + struct pci_data_structure *exprom_pci_data) +{ + if (exprom_pci_data->code_type != INTEL_OPROM_CSS_CODE_TYPE) { + drm_dbg_kms(&i915->drm, "Invalid OPROM CSS Code\n"); + return -EINVAL; + } + drm_dbg_kms(&i915->drm, "Found CSS image\n"); + /* + * TODO: Authticate OPROM RSA Signature if required in future + * pubic key and signature are present in CSS image. + */ + + return 0; +} + +/** + * intel_spi_get_oprom_opreg() get OPROM OpRegion image. + * @i915: pointer to i915 device. + * + * This function parses the DGFX OPROM to retieve the opregion. + * OPROM has bundled multiple images but i915 only interested + * in CSS and opregion image. + * + * + DGFX OPROM IMAGE LAYOUT + + * +--------+-------+---------------------------+ + * | Offset | Value | ROM Header Fields +-----> Image1 (CSS) + * +--------------------------------------------+ + * | 0h | 55h | ROM Signature Byte1 | + * | 1h | AAh | ROM Signature Byte2 | + * | 2h | xx | Reserved | + * | 18+19h| xx | Ptr to PCI DataStructure | + * +----------------+---------------------------+ + * | PCI Data Structure | + * +--------------------------------------------+ + * | . . . | + * | . . . | + * | 10 + xx + Image Length | + * | 14 + xx + Code Type | + * | 15 + xx + Last Image Indicator | + * | . . . | + * +--------------------------------------------+ + * | Signature and Public Key | + * +--------+-------+---------------------------+ + * | . | . | . | + * | . | . | . | + * +--------------------------------------------+ + * | Offset | Value | ROM Header Fields +-----> Image2 (opregion, vbt) (Offset: 0x800) + * +--------------------------------------------+ + * | 0h | 55h | ROM Signature Byte1 | + * | 1h | AAh | ROM Signature Byte2 | + * | 2h | xx | Reserved | + * | 18+19h| xx | Ptr to PCI DataStructure | + * +----------------+---------------------------+ + * | PCI Data Structure | + * +--------------------------------------------+ + * | . . . | + * | . . . | + * | 10 + xx + Image Length | + * | 14 + xx + Code Type | + * | 15 + xx + Last Image Indicator | + * | . . . | + * | 1A + 3C + Ptr to Opregion Signature | + * | . . . | + * | . . . | + * | 83Ch + IntelGraphicsMem | <---+ Opregion Signature + * +--------+-----------------------------------+ + * + * Return : Returns the opregion image blob which starts from opregion + * signature "IntelGraphicsMem". Error value in case of error + */ +static void * +intel_spi_get_oprom_opreg(struct drm_i915_private *i915) +{ + struct expansion_rom_header *exprom_hdr; + struct pci_data_structure *exprom_pci_data; + u8 img_sig[sizeof(OPREGION_SIGNATURE)]; + u32 oprom_offset, offset; + size_t img_len, opreg_len; + void *opreg = ERR_PTR(-ENXIO); + int ret; + + oprom_offset = intel_spi_oprom_offset(i915); + + exprom_hdr = kzalloc(sizeof(struct expansion_rom_header), GFP_KERNEL); + exprom_pci_data = kzalloc(sizeof(struct pci_data_structure), GFP_KERNEL); + if (!exprom_hdr || !exprom_pci_data) { + opreg = ERR_PTR(-ENOMEM); + goto err_free_hdr; + } + + for (offset = oprom_offset; exprom_pci_data->last_img != LAST_IMG_INDICATOR; + offset = offset + img_len) { + intel_spi_read_oprom(i915, offset, sizeof(struct expansion_rom_header), + exprom_hdr); + intel_spi_read_oprom(i915, offset + exprom_hdr->pcistructoffset, + sizeof(struct pci_data_structure), exprom_pci_data); + ret = pci_exp_rom_check_signature(i915, exprom_hdr, exprom_pci_data); + if (ret) { + opreg = ERR_PTR(ret); + goto err_free_hdr; + } + + img_len = exprom_pci_data->img_len * OPROM_BYTE_BOUNDARY; + + /* CSS or OpReg signature is present at exprom_hdr->img_base offset */ + intel_spi_read_oprom(i915, offset + exprom_hdr->img_base, + sizeof(OPREGION_SIGNATURE) - 1, img_sig); + + if (!memcmp(img_sig, INTEL_CSS_SIGNATURE, NUM_CSS_BYTES)) { + ret = intel_verify_css(i915, exprom_hdr, exprom_pci_data); + if (ret) { + opreg = ERR_PTR(ret); + goto err_free_hdr; + } + } else if (!memcmp(img_sig, OPREGION_SIGNATURE, sizeof(OPREGION_SIGNATURE) - 1)) { + opreg_len = img_len - exprom_hdr->img_base; + opreg_len = ALIGN(opreg_len, 4); + opreg = kzalloc(opreg_len, GFP_KERNEL); + + if (!opreg) { + opreg = ERR_PTR(-ENOMEM); + goto err_free_hdr; + } + + intel_spi_read_oprom(i915, offset + exprom_hdr->img_base, + opreg_len, opreg); + drm_dbg_kms(&i915->drm, "Found opregion image of size %zu\n", opreg_len); + break; + } + } + +err_free_hdr: + + kfree(exprom_pci_data); + kfree(exprom_hdr); + + return opreg; +} + static int intel_opregion_setup(struct drm_i915_private *dev_priv) { struct intel_opregion *opregion = &dev_priv->opregion; @@ -1007,6 +1226,17 @@ static int intel_opregion_setup(struct drm_i915_private *dev_priv) } out: + /* + * We might got VBT from OPROM OpRegion but we can't use OPROM OpRegion + * to write ACPI OpRegion MBOX. + */ + if (!opregion->asls) { + drm_dbg(&dev_priv->drm, "ACPI OpRegion MBOX is not supported!\n"); + opregion->acpi = NULL; + opregion->swsci = NULL; + opregion->asle = NULL; + } + return 0; } @@ -1224,10 +1454,24 @@ intel_opregion_get_asls(struct drm_i915_private *i915) return asls; } +static int +intel_opregion_verify_signature(struct drm_i915_private *i915, const void *base) +{ + char buf[sizeof(OPREGION_SIGNATURE)]; + + memcpy(buf, base, sizeof(buf)); + + if (memcmp(buf, OPREGION_SIGNATURE, 16)) { + drm_dbg(&i915->drm, "opregion signature mismatch\n"); + return -EINVAL; + } + + return 0; +} + static void *intel_igfx_alloc_opregion(struct drm_i915_private *i915) { struct intel_opregion *opregion = &i915->opregion; - char buf[sizeof(OPREGION_SIGNATURE)]; int err = 0; void *base; u32 asls; @@ -1243,20 +1487,13 @@ static void *intel_igfx_alloc_opregion(struct drm_i915_private *i915) if (!base) return ERR_PTR(-ENOMEM); - memcpy(buf, base, sizeof(buf)); - - if (memcmp(buf, OPREGION_SIGNATURE, 16)) { - drm_dbg(&i915->drm, "opregion signature mismatch\n"); - err = -EINVAL; - goto err_out; + err = intel_opregion_verify_signature(i915, base); + if (err) { + memunmap(base); + return ERR_PTR(err); } return base; - -err_out: - memunmap(base); - - return ERR_PTR(err); } static void *intel_igfx_alloc_rvda(struct drm_i915_private *i915) @@ -1315,9 +1552,70 @@ static const struct i915_opregion_func igfx_opregion_func = { .free_opregion = intel_igfx_free_opregion, }; +static void *intel_dgfx_setup_asls(struct drm_i915_private *i915) +{ + struct intel_opregion *opregion = &i915->opregion; + struct opregion_asle *asls_asle; + const struct opregion_asle *spi_asle; + void *base; + int ret; + + if (!opregion->dgfx_oprom_opreg) + return ERR_PTR(-EINVAL); + + spi_asle = opregion->dgfx_oprom_opreg + OPREGION_ASLE_OFFSET; + + /* + * DGFX MBD configs supports ASL storage. + * Populate the RVDA and RVDS field from OPROM opregion. + */ + base = memremap(opregion->asls, OPREGION_SIZE, MEMREMAP_WB); + if (!base) + return ERR_PTR(-ENOMEM); + + ret = intel_opregion_verify_signature(i915, base); + if (ret) { + memunmap(base); + return ERR_PTR(ret); + } + + asls_asle = base + OPREGION_ASLE_OFFSET; + asls_asle->rvda = spi_asle->rvda; + asls_asle->rvds = spi_asle->rvds; + + return base; +} + static void *intel_dgfx_alloc_opregion(struct drm_i915_private *i915) { - return ERR_PTR(-EOPNOTSUPP); + struct intel_opregion *opregion = &i915->opregion; + void *oprom_opreg; + void *asls_opreg; + + BUILD_BUG_ON(sizeof(struct expansion_rom_header) != 28); + BUILD_BUG_ON(sizeof(struct pci_data_structure) != 28); + + oprom_opreg = intel_spi_get_oprom_opreg(i915); + + if (IS_ERR(oprom_opreg)) { + drm_err(&i915->drm, "Unable to get opregion image from dgfx oprom Err: %ld\n", + PTR_ERR(oprom_opreg)); + return oprom_opreg; + } + + /* Cache the OPROM opregion + vbt image to retrieve vbt later */ + opregion->dgfx_oprom_opreg = oprom_opreg; + + opregion->asls = intel_opregion_get_asls(i915); + if (opregion->asls) { + asls_opreg = intel_dgfx_setup_asls(i915); + if (!IS_ERR(asls_opreg)) + return asls_opreg; + } + + oprom_opreg = kmemdup(opregion->dgfx_oprom_opreg, OPREGION_SIZE, GFP_KERNEL); + + return oprom_opreg ?: ERR_PTR(-ENOMEM); } static void *intel_dgfx_alloc_rvda(struct drm_i915_private *i915) @@ -1331,6 +1629,14 @@ static void intel_dgfx_free_rvda(struct drm_i915_private *i915, void *rvda) static void intel_dgfx_free_opregion(struct drm_i915_private *i915, void *opreg) { + if (IS_ERR(opreg)) + return; + + if (opreg) + memunmap(opreg); + else + kfree(opreg); + } static const struct i915_opregion_func dgfx_opregion_func = { diff --git a/drivers/gpu/drm/i915/display/intel_opregion.h b/drivers/gpu/drm/i915/display/intel_opregion.h index 7500c396b74d..65a9aa4fdb59 100644 --- a/drivers/gpu/drm/i915/display/intel_opregion.h +++ b/drivers/gpu/drm/i915/display/intel_opregion.h @@ -52,6 +52,7 @@ struct intel_opregion { void *rvda; void *vbt_firmware; const void *vbt; + const void *dgfx_oprom_opreg; u32 vbt_size; u32 *lid_state; struct work_struct asle_work; From patchwork Mon Apr 18 10:54:08 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Gupta, Anshuman" X-Patchwork-Id: 12816486 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 D6D8BC433EF for ; Mon, 18 Apr 2022 10:54:43 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 4CD4310F587; Mon, 18 Apr 2022 10:54:43 +0000 (UTC) Received: from mga02.intel.com (mga02.intel.com [134.134.136.20]) by gabe.freedesktop.org (Postfix) with ESMTPS id 7E97610F585 for ; Mon, 18 Apr 2022 10:54:41 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1650279281; x=1681815281; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=kY49xia2wvZJZrDoCe0k4OMg4tqLHRChDHiaLqMoKG0=; b=gFWMinJ3k/Zair4QepkR+4ZXCrtVW/nzMQCluV4IvcHLh/FdLFqEhGpt Hxr8YdS7xsDB62RuURqMjxphKTMFRnmPEwbzOU7X+AummJeDNCsNQMSPH KF7lkwLOwYmPvC5SNmXYxYCgEab0Huspltxq6dsewgT+fyNvkKIrXjLKh /4wYMjscC+BY0ypiLaZs95CdyIdacNw/fA5Et0Q+oWIukT7wsoP4T5vjP PjFgvLepk91w38e8olnKv0GnjaIj1LbIJKxSiyUg7li5AC4YlHwDBDVn4 X1zIEEp4gA+lusiTGkXUDhIcZ1cmw3wODcMs8+mSiZZYicJ9Ub4uNIktw w==; X-IronPort-AV: E=McAfee;i="6400,9594,10320"; a="250798283" X-IronPort-AV: E=Sophos;i="5.90,269,1643702400"; d="scan'208";a="250798283" Received: from orsmga004.jf.intel.com ([10.7.209.38]) by orsmga101.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 18 Apr 2022 03:54:41 -0700 X-IronPort-AV: E=Sophos;i="5.90,269,1643702400"; d="scan'208";a="665139446" Received: from srr4-3-linux-105-anshuma1.iind.intel.com ([10.223.74.179]) by orsmga004-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 18 Apr 2022 03:54:38 -0700 From: Anshuman Gupta To: intel-gfx@lists.freedesktop.org Date: Mon, 18 Apr 2022 16:24:08 +0530 Message-Id: <20220418105408.13444-7-anshuman.gupta@intel.com> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20220418105408.13444-1-anshuman.gupta@intel.com> References: <20220418105408.13444-1-anshuman.gupta@intel.com> MIME-Version: 1.0 Subject: [Intel-gfx] [PATCH v4 6/6] drm/i915/dgfx: Get VBT from rvda 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@intel.com, lucas.demarchi@intel.com, rodrigo.vivi@intel.com Errors-To: intel-gfx-bounces@lists.freedesktop.org Sender: "Intel-gfx" Since OpRegion ver 2.1 MBOX3 RVDA field is Relative address of Raw VBT data from OpRegion Base. Populate the opreion->rvda accordingly. As Intel DGFX cards supports OpRegion version 2.2 or greater, RVDA as an absolute VBT physical address (Ver 2.0) doesn't applicable to DGFX cards. v2: - Add kzalloc NULL check for opreg_rvda pointer. v3: - Added kmemdup() insead of kzalloc() + memcpy() in intel_dgfx_alloc_rvda(), and added necessary credit to Manasi. v4: - Added IS_ERR(rvda)in free_rvda(). [Jani] - Fix free_{opregion, rvda} abstraction level. [Jani] Cc: Jani Nikula Cc: Uma Shankar Cc: Rodrigo Vivi Cc: Badal Nilawar Signed-off-by: Manasi Navare Signed-off-by: Anshuman Gupta --- drivers/gpu/drm/i915/display/intel_opregion.c | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/display/intel_opregion.c b/drivers/gpu/drm/i915/display/intel_opregion.c index 18770e564044..0548fea0f2bc 100644 --- a/drivers/gpu/drm/i915/display/intel_opregion.c +++ b/drivers/gpu/drm/i915/display/intel_opregion.c @@ -1620,11 +1620,28 @@ static void *intel_dgfx_alloc_opregion(struct drm_i915_private *i915) static void *intel_dgfx_alloc_rvda(struct drm_i915_private *i915) { - return ERR_PTR(-EOPNOTSUPP); + struct intel_opregion *opregion = &i915->opregion; + void *opreg_rvda; + + if (!opregion->dgfx_oprom_opreg) + return ERR_PTR(-EINVAL); + + opreg_rvda = kmemdup(opregion->dgfx_oprom_opreg + opregion->asle->rvda, + opregion->asle->rvds, GFP_KERNEL); + + /* We got RVDA, OPROM opregion + vbt image not nedded anymore */ + kfree(opregion->dgfx_oprom_opreg); + opregion->dgfx_oprom_opreg = NULL; + + return opreg_rvda ?: ERR_PTR(-ENOMEM); } static void intel_dgfx_free_rvda(struct drm_i915_private *i915, void *rvda) { + if (IS_ERR(rvda)) + return; + + kfree(rvda); } static void intel_dgfx_free_opregion(struct drm_i915_private *i915, void *opreg)