From: "Ilpo Järvinen" <ilpo.jarvinen@linux.intel.com>
To: Xi Pardee <xi.pardee@linux.intel.com>
Cc: irenic.rajneesh@gmail.com, david.e.box@linux.intel.com,
Hans de Goede <hdegoede@redhat.com>,
platform-driver-x86@vger.kernel.org,
LKML <linux-kernel@vger.kernel.org>,
linux-pm@vger.kernel.org
Subject: Re: [PATCH v2 01/11] platform/x86:intel/pmc: Move PMC Core related functions
Date: Thu, 29 Aug 2024 13:49:54 +0300 (EEST) [thread overview]
Message-ID: <e4f44ead-b0a4-d42d-d3ba-85fa8f133305@linux.intel.com> (raw)
In-Reply-To: <20240828222932.1279508-2-xi.pardee@linux.intel.com>
[-- Attachment #1: Type: text/plain, Size: 14775 bytes --]
On Wed, 28 Aug 2024, Xi Pardee wrote:
> Move functions that implements PMC Core feature from core_ssram.c
> to core.c. This patch is a preparation step to introduce a new
> SSRAM Telemetry driver for the SSRAM device.
>
> Signed-off-by: Xi Pardee <xi.pardee@linux.intel.com>
Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
> ---
> drivers/platform/x86/intel/pmc/core.c | 168 +++++++++++++++++++
> drivers/platform/x86/intel/pmc/core.h | 8 +
> drivers/platform/x86/intel/pmc/core_ssram.c | 173 --------------------
> 3 files changed, 176 insertions(+), 173 deletions(-)
>
> diff --git a/drivers/platform/x86/intel/pmc/core.c b/drivers/platform/x86/intel/pmc/core.c
> index 01ae71c6df59..630ce2087552 100644
> --- a/drivers/platform/x86/intel/pmc/core.c
> +++ b/drivers/platform/x86/intel/pmc/core.c
> @@ -1604,6 +1604,173 @@ static const struct dev_pm_ops pmc_core_pm_ops = {
> SET_LATE_SYSTEM_SLEEP_PM_OPS(pmc_core_suspend, pmc_core_resume)
> };
>
> +static u32 pmc_core_find_guid(struct pmc_info *list, const struct pmc_reg_map *map)
> +{
> + for (; list->map; ++list)
> + if (list->map == map)
> + return list->guid;
> +
> + return 0;
> +}
> +
> +static int pmc_core_get_lpm_req(struct pmc_dev *pmcdev, struct pmc *pmc)
> +{
> + struct telem_endpoint *ep;
> + const u8 *lpm_indices;
> + int num_maps, mode_offset = 0;
> + int ret, mode, i;
> + int lpm_size;
> + u32 guid;
> +
> + lpm_indices = pmc->map->lpm_reg_index;
> + num_maps = pmc->map->lpm_num_maps;
> + lpm_size = LPM_MAX_NUM_MODES * num_maps;
> +
> + guid = pmc_core_find_guid(pmcdev->regmap_list, pmc->map);
> + if (!guid)
> + return -ENXIO;
> +
> + ep = pmt_telem_find_and_register_endpoint(pmcdev->ssram_pcidev, guid, 0);
> + if (IS_ERR(ep)) {
> + dev_dbg(&pmcdev->pdev->dev, "couldn't get telem endpoint %ld",
> + PTR_ERR(ep));
> + return -EPROBE_DEFER;
> + }
> +
> + pmc->lpm_req_regs = devm_kzalloc(&pmcdev->pdev->dev,
> + lpm_size * sizeof(u32),
> + GFP_KERNEL);
> + if (!pmc->lpm_req_regs) {
> + ret = -ENOMEM;
> + goto unregister_ep;
> + }
> +
> + /*
> + * PMC Low Power Mode (LPM) table
> + *
> + * In telemetry space, the LPM table contains a 4 byte header followed
> + * by 8 consecutive mode blocks (one for each LPM mode). Each block
> + * has a 4 byte header followed by a set of registers that describe the
> + * IP state requirements for the given mode. The IP mapping is platform
> + * specific but the same for each block, making for easy analysis.
> + * Platforms only use a subset of the space to track the requirements
> + * for their IPs. Callers provide the requirement registers they use as
> + * a list of indices. Each requirement register is associated with an
> + * IP map that's maintained by the caller.
> + *
> + * Header
> + * +----+----------------------------+----------------------------+
> + * | 0 | REVISION | ENABLED MODES |
> + * +----+--------------+-------------+-------------+--------------+
> + *
> + * Low Power Mode 0 Block
> + * +----+--------------+-------------+-------------+--------------+
> + * | 1 | SUB ID | SIZE | MAJOR | MINOR |
> + * +----+--------------+-------------+-------------+--------------+
> + * | 2 | LPM0 Requirements 0 |
> + * +----+---------------------------------------------------------+
> + * | | ... |
> + * +----+---------------------------------------------------------+
> + * | 29 | LPM0 Requirements 27 |
> + * +----+---------------------------------------------------------+
> + *
> + * ...
> + *
> + * Low Power Mode 7 Block
> + * +----+--------------+-------------+-------------+--------------+
> + * | | SUB ID | SIZE | MAJOR | MINOR |
> + * +----+--------------+-------------+-------------+--------------+
> + * | 60 | LPM7 Requirements 0 |
> + * +----+---------------------------------------------------------+
> + * | | ... |
> + * +----+---------------------------------------------------------+
> + * | 87 | LPM7 Requirements 27 |
> + * +----+---------------------------------------------------------+
> + *
> + */
> + mode_offset = LPM_HEADER_OFFSET + LPM_MODE_OFFSET;
> + pmc_for_each_mode(i, mode, pmcdev) {
> + u32 *req_offset = pmc->lpm_req_regs + (mode * num_maps);
> + int m;
> +
> + for (m = 0; m < num_maps; m++) {
> + u8 sample_id = lpm_indices[m] + mode_offset;
> +
> + ret = pmt_telem_read32(ep, sample_id, req_offset, 1);
> + if (ret) {
> + dev_err(&pmcdev->pdev->dev,
> + "couldn't read Low Power Mode requirements: %d\n", ret);
> + devm_kfree(&pmcdev->pdev->dev, pmc->lpm_req_regs);
> + goto unregister_ep;
> + }
> + ++req_offset;
> + }
> + mode_offset += LPM_REG_COUNT + LPM_MODE_OFFSET;
> + }
> +
> +unregister_ep:
> + pmt_telem_unregister_endpoint(ep);
> +
> + return ret;
> +}
> +
> +int pmc_core_ssram_get_lpm_reqs(struct pmc_dev *pmcdev)
> +{
> + int ret, i;
> +
> + if (!pmcdev->ssram_pcidev)
> + return -ENODEV;
> +
> + for (i = 0; i < ARRAY_SIZE(pmcdev->pmcs); ++i) {
> + if (!pmcdev->pmcs[i])
> + continue;
> +
> + ret = pmc_core_get_lpm_req(pmcdev, pmcdev->pmcs[i]);
> + if (ret)
> + return ret;
> + }
> +
> + return 0;
> +}
> +
> +const struct pmc_reg_map *pmc_core_find_regmap(struct pmc_info *list, u16 devid)
> +{
> + for (; list->map; ++list)
> + if (devid == list->devid)
> + return list->map;
> +
> + return NULL;
> +}
> +
> +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 = pmcdev->pmcs[pmc_index];
> +
> + if (!pwrm_base)
> + return -ENODEV;
> +
> + /* Memory for primary PMC has been allocated in core.c */
> + if (!pmc) {
> + pmc = devm_kzalloc(&pmcdev->pdev->dev, sizeof(*pmc), GFP_KERNEL);
> + if (!pmc)
> + return -ENOMEM;
> + }
> +
> + pmc->map = reg_map;
> + pmc->base_addr = pwrm_base;
> + pmc->regbase = ioremap(pmc->base_addr, pmc->map->regmap_length);
> +
> + if (!pmc->regbase) {
> + devm_kfree(&pmcdev->pdev->dev, pmc);
> + return -ENOMEM;
> + }
> +
> + pmcdev->pmcs[pmc_index] = pmc;
> +
> + return 0;
> +}
> +
> static const struct acpi_device_id pmc_core_acpi_ids[] = {
> {"INT33A1", 0}, /* _HID for Intel Power Engine, _CID PNP0D80*/
> { }
> @@ -1623,5 +1790,6 @@ static struct platform_driver pmc_core_driver = {
>
> module_platform_driver(pmc_core_driver);
>
> +MODULE_IMPORT_NS(INTEL_PMT_TELEMETRY);
> MODULE_LICENSE("GPL v2");
> MODULE_DESCRIPTION("Intel PMC Core Driver");
> diff --git a/drivers/platform/x86/intel/pmc/core.h b/drivers/platform/x86/intel/pmc/core.h
> index ea04de7eb9e8..9a1cc01f31d9 100644
> --- a/drivers/platform/x86/intel/pmc/core.h
> +++ b/drivers/platform/x86/intel/pmc/core.h
> @@ -24,6 +24,11 @@ struct telem_endpoint;
> #define MAX_NUM_PMC 3
> #define S0IX_BLK_SIZE 4
>
> +/* PCH query */
> +#define LPM_HEADER_OFFSET 1
> +#define LPM_REG_COUNT 28
> +#define LPM_MODE_OFFSET 1
> +
> /* Sunrise Point Power Management Controller PCI Device ID */
> #define SPT_PMC_PCI_DEVICE_ID 0x9d21
> #define SPT_PMC_BASE_ADDR_OFFSET 0x48
> @@ -589,6 +594,9 @@ extern void pmc_core_punit_pmt_init(struct pmc_dev *pmcdev, u32 guid);
> extern void pmc_core_set_device_d3(unsigned int device);
>
> extern int pmc_core_ssram_init(struct pmc_dev *pmcdev, int func);
> +extern const struct pmc_reg_map *pmc_core_find_regmap(struct pmc_info *list, u16 devid);
> +extern int pmc_core_pmc_add(struct pmc_dev *pmcdev, u64 pwrm_base,
> + const struct pmc_reg_map *reg_map, int pmc_index);
>
> 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 1bde86c54eb9..0a2bfca5ff41 100644
> --- a/drivers/platform/x86/intel/pmc/core_ssram.c
> +++ b/drivers/platform/x86/intel/pmc/core_ssram.c
> @@ -24,142 +24,8 @@
> #define SSRAM_IOE_OFFSET 0x68
> #define SSRAM_DEVID_OFFSET 0x70
>
> -/* PCH query */
> -#define LPM_HEADER_OFFSET 1
> -#define LPM_REG_COUNT 28
> -#define LPM_MODE_OFFSET 1
> -
> DEFINE_FREE(pmc_core_iounmap, void __iomem *, iounmap(_T));
>
> -static u32 pmc_core_find_guid(struct pmc_info *list, const struct pmc_reg_map *map)
> -{
> - for (; list->map; ++list)
> - if (list->map == map)
> - return list->guid;
> -
> - return 0;
> -}
> -
> -static int pmc_core_get_lpm_req(struct pmc_dev *pmcdev, struct pmc *pmc)
> -{
> - struct telem_endpoint *ep;
> - const u8 *lpm_indices;
> - int num_maps, mode_offset = 0;
> - int ret, mode, i;
> - int lpm_size;
> - u32 guid;
> -
> - lpm_indices = pmc->map->lpm_reg_index;
> - num_maps = pmc->map->lpm_num_maps;
> - lpm_size = LPM_MAX_NUM_MODES * num_maps;
> -
> - guid = pmc_core_find_guid(pmcdev->regmap_list, pmc->map);
> - if (!guid)
> - return -ENXIO;
> -
> - ep = pmt_telem_find_and_register_endpoint(pmcdev->ssram_pcidev, guid, 0);
> - if (IS_ERR(ep)) {
> - dev_dbg(&pmcdev->pdev->dev, "couldn't get telem endpoint %ld",
> - PTR_ERR(ep));
> - return -EPROBE_DEFER;
> - }
> -
> - pmc->lpm_req_regs = devm_kzalloc(&pmcdev->pdev->dev,
> - lpm_size * sizeof(u32),
> - GFP_KERNEL);
> - if (!pmc->lpm_req_regs) {
> - ret = -ENOMEM;
> - goto unregister_ep;
> - }
> -
> - /*
> - * PMC Low Power Mode (LPM) table
> - *
> - * In telemetry space, the LPM table contains a 4 byte header followed
> - * by 8 consecutive mode blocks (one for each LPM mode). Each block
> - * has a 4 byte header followed by a set of registers that describe the
> - * IP state requirements for the given mode. The IP mapping is platform
> - * specific but the same for each block, making for easy analysis.
> - * Platforms only use a subset of the space to track the requirements
> - * for their IPs. Callers provide the requirement registers they use as
> - * a list of indices. Each requirement register is associated with an
> - * IP map that's maintained by the caller.
> - *
> - * Header
> - * +----+----------------------------+----------------------------+
> - * | 0 | REVISION | ENABLED MODES |
> - * +----+--------------+-------------+-------------+--------------+
> - *
> - * Low Power Mode 0 Block
> - * +----+--------------+-------------+-------------+--------------+
> - * | 1 | SUB ID | SIZE | MAJOR | MINOR |
> - * +----+--------------+-------------+-------------+--------------+
> - * | 2 | LPM0 Requirements 0 |
> - * +----+---------------------------------------------------------+
> - * | | ... |
> - * +----+---------------------------------------------------------+
> - * | 29 | LPM0 Requirements 27 |
> - * +----+---------------------------------------------------------+
> - *
> - * ...
> - *
> - * Low Power Mode 7 Block
> - * +----+--------------+-------------+-------------+--------------+
> - * | | SUB ID | SIZE | MAJOR | MINOR |
> - * +----+--------------+-------------+-------------+--------------+
> - * | 60 | LPM7 Requirements 0 |
> - * +----+---------------------------------------------------------+
> - * | | ... |
> - * +----+---------------------------------------------------------+
> - * | 87 | LPM7 Requirements 27 |
> - * +----+---------------------------------------------------------+
> - *
> - */
> - mode_offset = LPM_HEADER_OFFSET + LPM_MODE_OFFSET;
> - pmc_for_each_mode(i, mode, pmcdev) {
> - u32 *req_offset = pmc->lpm_req_regs + (mode * num_maps);
> - int m;
> -
> - for (m = 0; m < num_maps; m++) {
> - u8 sample_id = lpm_indices[m] + mode_offset;
> -
> - ret = pmt_telem_read32(ep, sample_id, req_offset, 1);
> - if (ret) {
> - dev_err(&pmcdev->pdev->dev,
> - "couldn't read Low Power Mode requirements: %d\n", ret);
> - devm_kfree(&pmcdev->pdev->dev, pmc->lpm_req_regs);
> - goto unregister_ep;
> - }
> - ++req_offset;
> - }
> - mode_offset += LPM_REG_COUNT + LPM_MODE_OFFSET;
> - }
> -
> -unregister_ep:
> - pmt_telem_unregister_endpoint(ep);
> -
> - return ret;
> -}
> -
> -int pmc_core_ssram_get_lpm_reqs(struct pmc_dev *pmcdev)
> -{
> - int ret, i;
> -
> - if (!pmcdev->ssram_pcidev)
> - return -ENODEV;
> -
> - for (i = 0; i < ARRAY_SIZE(pmcdev->pmcs); ++i) {
> - if (!pmcdev->pmcs[i])
> - continue;
> -
> - ret = pmc_core_get_lpm_req(pmcdev, pmcdev->pmcs[i]);
> - if (ret)
> - return ret;
> - }
> -
> - return 0;
> -}
> -
> static void
> pmc_add_pmt(struct pmc_dev *pmcdev, u64 ssram_base, void __iomem *ssram)
> {
> @@ -203,50 +69,11 @@ pmc_add_pmt(struct pmc_dev *pmcdev, u64 ssram_base, void __iomem *ssram)
> intel_vsec_register(pcidev, &info);
> }
>
> -static const struct pmc_reg_map *pmc_core_find_regmap(struct pmc_info *list, u16 devid)
> -{
> - for (; list->map; ++list)
> - if (devid == list->devid)
> - return list->map;
> -
> - return NULL;
> -}
> -
> static inline u64 get_base(void __iomem *addr, u32 offset)
> {
> return lo_hi_readq(addr + offset) & GENMASK_ULL(63, 3);
> }
>
> -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 = pmcdev->pmcs[pmc_index];
> -
> - if (!pwrm_base)
> - return -ENODEV;
> -
> - /* Memory for primary PMC has been allocated in core.c */
> - if (!pmc) {
> - pmc = devm_kzalloc(&pmcdev->pdev->dev, sizeof(*pmc), GFP_KERNEL);
> - if (!pmc)
> - return -ENOMEM;
> - }
> -
> - pmc->map = reg_map;
> - pmc->base_addr = pwrm_base;
> - pmc->regbase = ioremap(pmc->base_addr, pmc->map->regmap_length);
> -
> - if (!pmc->regbase) {
> - devm_kfree(&pmcdev->pdev->dev, pmc);
> - return -ENOMEM;
> - }
> -
> - pmcdev->pmcs[pmc_index] = pmc;
> -
> - return 0;
> -}
> -
> static int
> pmc_core_ssram_get_pmc(struct pmc_dev *pmcdev, int pmc_idx, u32 offset)
> {
>
--
i.
next prev parent reply other threads:[~2024-08-29 10:50 UTC|newest]
Thread overview: 26+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-08-28 22:29 [PATCH v2 00/11] Create Intel PMC SSRAM Telemetry driver Xi Pardee
2024-08-28 22:29 ` [PATCH v2 01/11] platform/x86:intel/pmc: Move PMC Core related functions Xi Pardee
2024-08-29 10:49 ` Ilpo Järvinen [this message]
2024-08-28 22:29 ` [PATCH v2 02/11] platform/x86:intel/pmc: Rename core_ssram to ssram_telemetry Xi Pardee
2024-08-29 10:50 ` Ilpo Järvinen
2024-08-28 22:29 ` [PATCH v2 03/11] platform/x86:intel/pmc: Move PMC devid to core.h Xi Pardee
2024-08-29 10:52 ` Ilpo Järvinen
2024-09-10 6:55 ` Xi Pardee
2024-08-28 22:29 ` [PATCH v2 04/11] platform/x86:intel/pmc: Convert index variables to be unsigned Xi Pardee
2024-08-29 10:54 ` Ilpo Järvinen
2024-08-28 22:29 ` [PATCH v2 05/11] platform/x86:intel/pmc: Remove unneeded h file inclusion Xi Pardee
2024-08-29 11:02 ` Ilpo Järvinen
2024-09-10 7:08 ` Xi Pardee
2024-08-28 22:29 ` [PATCH v2 06/11] platform/x86:intel/pmc: Remove unneeded io operations Xi Pardee
2024-08-28 22:29 ` [PATCH v2 07/11] platform/x86:intel/pmc: Check return value of ioremap Xi Pardee
2024-08-29 11:06 ` Ilpo Järvinen
2024-09-10 6:53 ` Xi Pardee
2024-08-28 22:29 ` [PATCH v2 08/11] platform/x86:intel/pmc: Create Intel PMC SSRAM Telemetry driver Xi Pardee
2024-08-29 12:02 ` Ilpo Järvinen
2024-09-10 19:57 ` Xi Pardee
2024-08-28 22:29 ` [PATCH v2 09/11] platform/x86:intel/pmc: Add Lunar Lake SSRAM devid Xi Pardee
2024-08-29 12:03 ` Ilpo Järvinen
2024-08-28 22:29 ` [PATCH v2 10/11] platform/x86:intel/pmt: Get PMC from SSRAM for Lunar Lake Xi Pardee
2024-08-28 22:29 ` [PATCH v2 11/11] platform/x86:intel/pmc: Get LPM information " Xi Pardee
2024-08-29 12:13 ` Ilpo Järvinen
2024-09-10 0:49 ` Xi Pardee
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=e4f44ead-b0a4-d42d-d3ba-85fa8f133305@linux.intel.com \
--to=ilpo.jarvinen@linux.intel.com \
--cc=david.e.box@linux.intel.com \
--cc=hdegoede@redhat.com \
--cc=irenic.rajneesh@gmail.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-pm@vger.kernel.org \
--cc=platform-driver-x86@vger.kernel.org \
--cc=xi.pardee@linux.intel.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.