Commit 1c709ae1 authored by Xi Pardee's avatar Xi Pardee Committed by Hans de Goede

platform/x86:intel/pmc: Add support to handle multiple PMCs

To support platforms with multiple PMCs, add a PMC device structure to
support each PMC instance.
Signed-off-by: default avatarXi Pardee <xi.pardee@intel.com>
Reviewed-by: default avatarIlpo Järvinen <ilpo.jarvinen@linux.intel.com>
Link: https://lore.kernel.org/r/20230613225347.2720665-4-rajvi.jingar@linux.intel.comSigned-off-by: default avatarHans de Goede <hdegoede@redhat.com>
parent 80495120
...@@ -311,10 +311,11 @@ const struct pmc_reg_map adl_reg_map = { ...@@ -311,10 +311,11 @@ const struct pmc_reg_map adl_reg_map = {
int adl_core_init(struct pmc_dev *pmcdev) int adl_core_init(struct pmc_dev *pmcdev)
{ {
struct pmc *pmc = pmcdev->pmcs[PMC_IDX_MAIN];
int ret; int ret;
pmcdev->map = &adl_reg_map; pmc->map = &adl_reg_map;
ret = get_primary_reg_base(pmcdev); ret = get_primary_reg_base(pmc);
if (ret) if (ret)
return ret; return ret;
......
...@@ -206,10 +206,11 @@ const struct pmc_reg_map cnp_reg_map = { ...@@ -206,10 +206,11 @@ const struct pmc_reg_map cnp_reg_map = {
int cnp_core_init(struct pmc_dev *pmcdev) int cnp_core_init(struct pmc_dev *pmcdev)
{ {
struct pmc *pmc = pmcdev->pmcs[PMC_IDX_MAIN];
int ret; int ret;
pmcdev->map = &cnp_reg_map; pmc->map = &cnp_reg_map;
ret = get_primary_reg_base(pmcdev); ret = get_primary_reg_base(pmc);
if (ret) if (ret)
return ret; return ret;
......
This diff is collapsed.
...@@ -19,6 +19,7 @@ ...@@ -19,6 +19,7 @@
#define SLP_S0_RES_COUNTER_MASK GENMASK(31, 0) #define SLP_S0_RES_COUNTER_MASK GENMASK(31, 0)
#define PMC_BASE_ADDR_DEFAULT 0xFE000000 #define PMC_BASE_ADDR_DEFAULT 0xFE000000
#define MAX_NUM_PMC 3
/* Sunrise Point Power Management Controller PCI Device ID */ /* Sunrise Point Power Management Controller PCI Device ID */
#define SPT_PMC_PCI_DEVICE_ID 0x9d21 #define SPT_PMC_PCI_DEVICE_ID 0x9d21
...@@ -319,11 +320,25 @@ struct pmc_reg_map { ...@@ -319,11 +320,25 @@ struct pmc_reg_map {
}; };
/** /**
* struct pmc_dev - pmc device structure * struct pmc - pmc private info structure
* @base_addr: contains pmc base address * @base_addr: contains pmc base address
* @regbase: pointer to io-remapped memory location * @regbase: pointer to io-remapped memory location
* @map: pointer to pmc_reg_map struct that contains platform * @map: pointer to pmc_reg_map struct that contains platform
* specific attributes * specific attributes
* @lpm_req_regs: List of substate requirements
*
* pmc contains info about one power management controller device.
*/
struct pmc {
u64 base_addr;
void __iomem *regbase;
const struct pmc_reg_map *map;
u32 *lpm_req_regs;
};
/**
* struct pmc_dev - pmc device structure
* @devs: pointer to an array of pmc pointers
* @pdev: pointer to platform_device struct * @pdev: pointer to platform_device struct
* @dbgfs_dir: path to debugfs interface * @dbgfs_dir: path to debugfs interface
* @pmc_xram_read_bit: flag to indicate whether PMC XRAM shadow registers * @pmc_xram_read_bit: flag to indicate whether PMC XRAM shadow registers
...@@ -333,15 +348,12 @@ struct pmc_reg_map { ...@@ -333,15 +348,12 @@ struct pmc_reg_map {
* @s0ix_counter: S0ix residency (step adjusted) * @s0ix_counter: S0ix residency (step adjusted)
* @num_lpm_modes: Count of enabled modes * @num_lpm_modes: Count of enabled modes
* @lpm_en_modes: Array of enabled modes from lowest to highest priority * @lpm_en_modes: Array of enabled modes from lowest to highest priority
* @lpm_req_regs: List of substate requirements
* @resume: Function to perform platform specific resume * @resume: Function to perform platform specific resume
* *
* pmc_dev contains info about power management controller device. * pmc_dev contains info about power management controller device.
*/ */
struct pmc_dev { struct pmc_dev {
u32 base_addr; struct pmc *pmcs[MAX_NUM_PMC];
void __iomem *regbase;
const struct pmc_reg_map *map;
struct dentry *dbgfs_dir; struct dentry *dbgfs_dir;
struct platform_device *pdev; struct platform_device *pdev;
int pmc_xram_read_bit; int pmc_xram_read_bit;
...@@ -351,8 +363,19 @@ struct pmc_dev { ...@@ -351,8 +363,19 @@ struct pmc_dev {
u64 s0ix_counter; u64 s0ix_counter;
int num_lpm_modes; int num_lpm_modes;
int lpm_en_modes[LPM_MAX_NUM_MODES]; int lpm_en_modes[LPM_MAX_NUM_MODES];
u32 *lpm_req_regs;
int (*resume)(struct pmc_dev *pmcdev); int (*resume)(struct pmc_dev *pmcdev);
bool has_die_c6;
u32 die_c6_offset;
struct telem_endpoint *punit_ep;
};
enum pmc_index {
PMC_IDX_MAIN,
PMC_IDX_SOC = PMC_IDX_MAIN,
PMC_IDX_IOE,
PMC_IDX_PCH,
PMC_IDX_MAX
}; };
extern const struct pmc_bit_map msr_map[]; extern const struct pmc_bit_map msr_map[];
...@@ -425,7 +448,7 @@ extern void pmc_core_get_tgl_lpm_reqs(struct platform_device *pdev); ...@@ -425,7 +448,7 @@ extern void pmc_core_get_tgl_lpm_reqs(struct platform_device *pdev);
extern int pmc_core_send_ltr_ignore(struct pmc_dev *pmcdev, u32 value); extern int pmc_core_send_ltr_ignore(struct pmc_dev *pmcdev, u32 value);
int pmc_core_resume_common(struct pmc_dev *pmcdev); int pmc_core_resume_common(struct pmc_dev *pmcdev);
int get_primary_reg_base(struct pmc_dev *pmcdev); int get_primary_reg_base(struct pmc *pmc);
int spt_core_init(struct pmc_dev *pmcdev); int spt_core_init(struct pmc_dev *pmcdev);
int cnp_core_init(struct pmc_dev *pmcdev); int cnp_core_init(struct pmc_dev *pmcdev);
......
...@@ -52,6 +52,8 @@ const struct pmc_reg_map icl_reg_map = { ...@@ -52,6 +52,8 @@ const struct pmc_reg_map icl_reg_map = {
int icl_core_init(struct pmc_dev *pmcdev) int icl_core_init(struct pmc_dev *pmcdev)
{ {
pmcdev->map = &icl_reg_map; struct pmc *pmc = pmcdev->pmcs[PMC_IDX_MAIN];
return get_primary_reg_base(pmcdev);
pmc->map = &icl_reg_map;
return get_primary_reg_base(pmc);
} }
...@@ -508,15 +508,16 @@ static int mtl_resume(struct pmc_dev *pmcdev) ...@@ -508,15 +508,16 @@ static int mtl_resume(struct pmc_dev *pmcdev)
int mtl_core_init(struct pmc_dev *pmcdev) int mtl_core_init(struct pmc_dev *pmcdev)
{ {
struct pmc *pmc = pmcdev->pmcs[PMC_IDX_SOC];
int ret; int ret;
pmcdev->map = &mtl_socm_reg_map; pmc->map = &mtl_socm_reg_map;
mtl_d3_fixup(); mtl_d3_fixup();
pmcdev->resume = mtl_resume; pmcdev->resume = mtl_resume;
ret = get_primary_reg_base(pmcdev); ret = get_primary_reg_base(pmc);
if (ret) if (ret)
return ret; return ret;
......
...@@ -136,6 +136,8 @@ const struct pmc_reg_map spt_reg_map = { ...@@ -136,6 +136,8 @@ const struct pmc_reg_map spt_reg_map = {
int spt_core_init(struct pmc_dev *pmcdev) int spt_core_init(struct pmc_dev *pmcdev)
{ {
pmcdev->map = &spt_reg_map; struct pmc *pmc = pmcdev->pmcs[PMC_IDX_MAIN];
return get_primary_reg_base(pmcdev);
pmc->map = &spt_reg_map;
return get_primary_reg_base(pmc);
} }
...@@ -208,7 +208,8 @@ const struct pmc_reg_map tgl_reg_map = { ...@@ -208,7 +208,8 @@ const struct pmc_reg_map tgl_reg_map = {
void pmc_core_get_tgl_lpm_reqs(struct platform_device *pdev) void pmc_core_get_tgl_lpm_reqs(struct platform_device *pdev)
{ {
struct pmc_dev *pmcdev = platform_get_drvdata(pdev); struct pmc_dev *pmcdev = platform_get_drvdata(pdev);
const int num_maps = pmcdev->map->lpm_num_maps; struct pmc *pmc = pmcdev->pmcs[PMC_IDX_MAIN];
const int num_maps = pmc->map->lpm_num_maps;
u32 lpm_size = LPM_MAX_NUM_MODES * num_maps * 4; u32 lpm_size = LPM_MAX_NUM_MODES * num_maps * 4;
union acpi_object *out_obj; union acpi_object *out_obj;
struct acpi_device *adev; struct acpi_device *adev;
...@@ -246,7 +247,7 @@ void pmc_core_get_tgl_lpm_reqs(struct platform_device *pdev) ...@@ -246,7 +247,7 @@ void pmc_core_get_tgl_lpm_reqs(struct platform_device *pdev)
goto free_acpi_obj; goto free_acpi_obj;
memcpy(lpm_req_regs, addr, lpm_size); memcpy(lpm_req_regs, addr, lpm_size);
pmcdev->lpm_req_regs = lpm_req_regs; pmc->lpm_req_regs = lpm_req_regs;
free_acpi_obj: free_acpi_obj:
ACPI_FREE(out_obj); ACPI_FREE(out_obj);
...@@ -254,10 +255,11 @@ void pmc_core_get_tgl_lpm_reqs(struct platform_device *pdev) ...@@ -254,10 +255,11 @@ void pmc_core_get_tgl_lpm_reqs(struct platform_device *pdev)
int tgl_core_init(struct pmc_dev *pmcdev) int tgl_core_init(struct pmc_dev *pmcdev)
{ {
struct pmc *pmc = pmcdev->pmcs[PMC_IDX_MAIN];
int ret; int ret;
pmcdev->map = &tgl_reg_map; pmc->map = &tgl_reg_map;
ret = get_primary_reg_base(pmcdev); ret = get_primary_reg_base(pmc);
if (ret) if (ret)
return ret; return ret;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment