From nobody Wed Dec 17 04:35:42 2025 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 vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id D06DFCE7A86 for ; Fri, 22 Sep 2023 21:30:53 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230014AbjIVVa4 (ORCPT ); Fri, 22 Sep 2023 17:30:56 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:42962 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229959AbjIVVal (ORCPT ); Fri, 22 Sep 2023 17:30:41 -0400 Received: from mgamail.intel.com (mgamail.intel.com [134.134.136.20]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 7DB7EFB; Fri, 22 Sep 2023 14:30:35 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1695418235; x=1726954235; h=from:to:subject:date:message-id:in-reply-to:references: mime-version:content-transfer-encoding; bh=LTJvjLbkvuQx4wE/Sd6xPXoCn0gNEKM0z+EbfC949UM=; b=Nxuyt8IUn4OrG1JZrz74MVL2Wjj4CZ9c7MgbfD3D0rqyJZgHq5iEX+od 2yEmbO/XUZX1WTmAiTPX07RkuZD2qQ5iDJc4KavZXufnHQHTW2ySMiVMg ggoGUjd1v0HIuxs/SkfXETcnBp/OhipYosAEiN5H8BMGU5ePOPt3F/VjU 5LudrkK/klDIEQ01YBeDBgHoc4atCJ1Sr9BaA5IcnkmKwmla8YLyA9V6i VZrZLGJPCm0KjhqCPMHcwFlIW1YKowjlAQeCETZVi7/uU3sqQPciHJgPn RCy1Tn2EpzAU0VkOoo8W5EYduUnNAbZqGeDIK4B+OG9xNFem7mdD/DoLT g==; X-IronPort-AV: E=McAfee;i="6600,9927,10841"; a="371264694" X-IronPort-AV: E=Sophos;i="6.03,169,1694761200"; d="scan'208";a="371264694" Received: from orsmga002.jf.intel.com ([10.7.209.21]) by orsmga101.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 22 Sep 2023 14:30:33 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6600,9927,10841"; a="747685324" X-IronPort-AV: E=Sophos;i="6.03,169,1694761200"; d="scan'208";a="747685324" Received: from linux.intel.com ([10.54.29.200]) by orsmga002.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 22 Sep 2023 14:30:33 -0700 Received: from debox1-desk4.intel.com (unknown [10.212.188.234]) by linux.intel.com (Postfix) with ESMTP id 684BA580DB2; Fri, 22 Sep 2023 14:30:33 -0700 (PDT) From: "David E. Box" To: linux-kernel@vger.kernel.org, david.e.box@linux.intel.com, platform-driver-x86@vger.kernel.org, ilpo.jarvinen@linux.intel.com, rajvi.jingar@linux.intel.com Subject: [PATCH 06/11] platform/x86/intel/pmc: Split pmc_core_ssram_get_pmc() Date: Fri, 22 Sep 2023 14:30:27 -0700 Message-Id: <20230922213032.1770590-7-david.e.box@linux.intel.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20230922213032.1770590-1-david.e.box@linux.intel.com> References: <20230922213032.1770590-1-david.e.box@linux.intel.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" Each PMC has an associated SSRAM device for accessing additional counters. However, only the first is discoverable as a PCI device to the OS. The remaining devices are hidden but their BARs are still accessible and their addresses are stored in the BAR of the exposed device. Clean up the code handling the SSRAM discovery. Create two separate functions for finding the primary and secondary PMCs. Also changes the return type from void to allow returning an error when failing to find the primary PMC. Signed-off-by: David E. Box --- drivers/platform/x86/intel/pmc/core.h | 2 +- drivers/platform/x86/intel/pmc/core_ssram.c | 127 ++++++++++++++------ drivers/platform/x86/intel/pmc/mtl.c | 10 +- 3 files changed, 96 insertions(+), 43 deletions(-) diff --git a/drivers/platform/x86/intel/pmc/core.h b/drivers/platform/x86/i= ntel/pmc/core.h index ccf24e0f5e50..edaa70067e41 100644 --- a/drivers/platform/x86/intel/pmc/core.h +++ b/drivers/platform/x86/intel/pmc/core.h @@ -492,7 +492,7 @@ int pmc_core_resume_common(struct pmc_dev *pmcdev); int get_primary_reg_base(struct pmc *pmc); extern void pmc_core_get_low_power_modes(struct pmc_dev *pmcdev); =20 -extern void pmc_core_ssram_init(struct pmc_dev *pmcdev); +extern int pmc_core_ssram_init(struct pmc_dev *pmcdev); =20 int spt_core_init(struct pmc_dev *pmcdev); int cnp_core_init(struct pmc_dev *pmcdev); diff --git a/drivers/platform/x86/intel/pmc/core_ssram.c b/drivers/platform= /x86/intel/pmc/core_ssram.c index 13fa16f0d52e..ab5cc07fb177 100644 --- a/drivers/platform/x86/intel/pmc/core_ssram.c +++ b/drivers/platform/x86/intel/pmc/core_ssram.c @@ -35,20 +35,20 @@ static inline u64 get_base(void __iomem *addr, u32 offs= et) return lo_hi_readq(addr + offset) & GENMASK_ULL(63, 3); } =20 -static void +static int pmc_core_pmc_add(struct pmc_dev *pmcdev, u64 pwrm_base, const struct pmc_reg_map *reg_map, int pmc_index) { struct pmc *pmc =3D pmcdev->pmcs[pmc_index]; =20 if (!pwrm_base) - return; + return -ENODEV; =20 /* Memory for primary PMC has been allocated in core.c */ if (!pmc) { pmc =3D devm_kzalloc(&pmcdev->pdev->dev, sizeof(*pmc), GFP_KERNEL); if (!pmc) - return; + return -ENOMEM; } =20 pmc->map =3D reg_map; @@ -57,77 +57,128 @@ pmc_core_pmc_add(struct pmc_dev *pmcdev, u64 pwrm_base, =20 if (!pmc->regbase) { devm_kfree(&pmcdev->pdev->dev, pmc); - return; + return -ENOMEM; } =20 pmcdev->pmcs[pmc_index] =3D pmc; + + return 0; } =20 -static void -pmc_core_ssram_get_pmc(struct pmc_dev *pmcdev, void __iomem *ssram, u32 of= fset, - int pmc_idx) +static int +pmc_core_get_secondary_pmc(struct pmc_dev *pmcdev, int pmc_idx, u32 offset) { - u64 pwrm_base; + struct pci_dev *ssram_pcidev =3D pmcdev->ssram_pcidev; + const struct pmc_reg_map *map; + void __iomem *main_ssram, *secondary_ssram; + u64 ssram_base, pwrm_base; u16 devid; + int ret; + + if (!pmcdev->regmap_list) + return -ENOENT; =20 - if (pmc_idx !=3D PMC_IDX_SOC) { - u64 ssram_base =3D get_base(ssram, offset); + /* + * The secondary PMC BARS (which are behind hidden PCI devices) are read + * from fixed offsets in MMIO of the primary PMC BAR. + */ + ssram_base =3D ssram_pcidev->resource[0].start; + main_ssram =3D ioremap(ssram_base, SSRAM_HDR_SIZE); + if (!main_ssram) + return -ENOMEM; + + ssram_base =3D get_base(main_ssram, offset); + secondary_ssram =3D ioremap(ssram_base, SSRAM_HDR_SIZE); + if (!secondary_ssram) { + ret =3D -ENOMEM; + goto secondary_remap_fail; + } =20 - if (!ssram_base) - return; + pwrm_base =3D get_base(secondary_ssram, SSRAM_PWRM_OFFSET); + devid =3D readw(secondary_ssram + SSRAM_DEVID_OFFSET); =20 - ssram =3D ioremap(ssram_base, SSRAM_HDR_SIZE); - if (!ssram) - return; + map =3D pmc_core_find_regmap(pmcdev->regmap_list, devid); + if (!map) { + ret =3D -ENODEV; + goto find_regmap_fail; } =20 + ret =3D pmc_core_pmc_add(pmcdev, pwrm_base, map, pmc_idx); + +find_regmap_fail: + iounmap(secondary_ssram); +secondary_remap_fail: + iounmap(main_ssram); + + return ret; + +} + +static int +pmc_core_get_primary_pmc(struct pmc_dev *pmcdev) +{ + struct pci_dev *ssram_pcidev =3D pmcdev->ssram_pcidev; + const struct pmc_reg_map *map; + void __iomem *ssram; + u64 ssram_base, pwrm_base; + u16 devid; + int ret; + + if (!pmcdev->regmap_list) + return -ENOENT; + + /* The primary PMC (SOC die) BAR is BAR 0 in config space. */ + ssram_base =3D ssram_pcidev->resource[0].start; + ssram =3D ioremap(ssram_base, SSRAM_HDR_SIZE); + if (!ssram) + return -ENOMEM; + pwrm_base =3D get_base(ssram, SSRAM_PWRM_OFFSET); devid =3D readw(ssram + SSRAM_DEVID_OFFSET); =20 - if (pmcdev->regmap_list) { - const struct pmc_reg_map *map; - - map =3D pmc_core_find_regmap(pmcdev->regmap_list, devid); - if (map) - pmc_core_pmc_add(pmcdev, pwrm_base, map, pmc_idx); + map =3D pmc_core_find_regmap(pmcdev->regmap_list, devid); + if (!map) { + ret =3D -ENODEV; + goto find_regmap_fail; } =20 - if (pmc_idx !=3D PMC_IDX_SOC) - iounmap(ssram); + ret =3D pmc_core_pmc_add(pmcdev, pwrm_base, map, PMC_IDX_MAIN); + +find_regmap_fail: + iounmap(ssram); + + return ret; } =20 -void pmc_core_ssram_init(struct pmc_dev *pmcdev) +int pmc_core_ssram_init(struct pmc_dev *pmcdev) { - void __iomem *ssram; struct pci_dev *pcidev; - u64 ssram_base; int ret; =20 pcidev =3D pci_get_domain_bus_and_slot(0, 0, PCI_DEVFN(20, 2)); if (!pcidev) - goto out; + return -ENODEV; =20 ret =3D pcim_enable_device(pcidev); if (ret) goto release_dev; =20 - ssram_base =3D pcidev->resource[0].start; - ssram =3D ioremap(ssram_base, SSRAM_HDR_SIZE); - if (!ssram) - goto disable_dev; - pmcdev->ssram_pcidev =3D pcidev; =20 - pmc_core_ssram_get_pmc(pmcdev, ssram, 0, PMC_IDX_SOC); - pmc_core_ssram_get_pmc(pmcdev, ssram, SSRAM_IOE_OFFSET, PMC_IDX_IOE); - pmc_core_ssram_get_pmc(pmcdev, ssram, SSRAM_PCH_OFFSET, PMC_IDX_PCH); + ret =3D pmc_core_get_primary_pmc(pmcdev); + if (ret) + goto disable_dev; =20 - iounmap(ssram); -out: - return; + pmc_core_get_secondary_pmc(pmcdev, PMC_IDX_IOE, SSRAM_IOE_OFFSET); + pmc_core_get_secondary_pmc(pmcdev, PMC_IDX_PCH, SSRAM_PCH_OFFSET); + + return 0; =20 disable_dev: + pmcdev->ssram_pcidev =3D NULL; pci_disable_device(pcidev); release_dev: pci_dev_put(pcidev); + + return ret; } diff --git a/drivers/platform/x86/intel/pmc/mtl.c b/drivers/platform/x86/in= tel/pmc/mtl.c index c3b5f4fe01d1..780874142a90 100644 --- a/drivers/platform/x86/intel/pmc/mtl.c +++ b/drivers/platform/x86/intel/pmc/mtl.c @@ -990,12 +990,14 @@ int mtl_core_init(struct pmc_dev *pmcdev) mtl_d3_fixup(); =20 pmcdev->resume =3D mtl_resume; - pmcdev->regmap_list =3D mtl_pmc_info_list; - pmc_core_ssram_init(pmcdev); =20 - /* If regbase not assigned, set map and discover using legacy method */ - if (!pmc->regbase) { + /* + * If ssram init fails use legacy method to at least get the + * primary PMC + */ + ret =3D pmc_core_ssram_init(pmcdev); + if (ret) { pmc->map =3D &mtl_socm_reg_map; ret =3D get_primary_reg_base(pmc); if (ret) --=20 2.34.1