Commit 284c01b7 authored by Gayatri Kammela's avatar Gayatri Kammela Committed by Hans de Goede

platform/x86: intel/pmc: Replace all the reg_map with init functions

The current implementation of pmc core driver has the reg_map assigned
to the CPUID of each platform. Replace the reg_map with init functions
that are defined for each platform.

This is a preparatory patch for redesigning the pmc core driver.

Cc: David E Box <david.e.box@linux.intel.com>
Reviewed-by: default avatar"David E. Box" <david.e.box@linux.intel.com>
Signed-off-by: default avatarGayatri Kammela <gayatri.kammela@linux.intel.com>
Signed-off-by: default avatar"David E. Box" <david.e.box@linux.intel.com>
Link: https://lore.kernel.org/r/20221114183257.2067662-2-gayatri.kammela@linux.intel.comReviewed-by: default avatarHans de Goede <hdegoede@redhat.com>
Signed-off-by: default avatarHans de Goede <hdegoede@redhat.com>
parent 260ad3de
...@@ -19,7 +19,6 @@ ...@@ -19,7 +19,6 @@
#include <linux/io.h> #include <linux/io.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/pci.h> #include <linux/pci.h>
#include <linux/platform_device.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/suspend.h> #include <linux/suspend.h>
#include <linux/uaccess.h> #include <linux/uaccess.h>
...@@ -1895,27 +1894,73 @@ static void pmc_core_dbgfs_register(struct pmc_dev *pmcdev) ...@@ -1895,27 +1894,73 @@ static void pmc_core_dbgfs_register(struct pmc_dev *pmcdev)
} }
} }
void spt_core_init(struct pmc_dev *pmcdev)
{
pmcdev->map = &spt_reg_map;
}
void cnp_core_init(struct pmc_dev *pmcdev)
{
pmcdev->map = &cnp_reg_map;
}
void icl_core_init(struct pmc_dev *pmcdev)
{
pmcdev->map = &icl_reg_map;
}
void tgl_core_configure(struct pmc_dev *pmcdev)
{
pmc_core_get_tgl_lpm_reqs(pmcdev->pdev);
/* Due to a hardware limitation, the GBE LTR blocks PC10
* when a cable is attached. Tell the PMC to ignore it.
*/
dev_dbg(&pmcdev->pdev->dev, "ignoring GBE LTR\n");
pmc_core_send_ltr_ignore(pmcdev, 3);
}
void tgl_core_init(struct pmc_dev *pmcdev)
{
pmcdev->map = &tgl_reg_map;
pmcdev->core_configure = tgl_core_configure;
}
void adl_core_configure(struct pmc_dev *pmcdev)
{
/* Due to a hardware limitation, the GBE LTR blocks PC10
* when a cable is attached. Tell the PMC to ignore it.
*/
dev_dbg(&pmcdev->pdev->dev, "ignoring GBE LTR\n");
pmc_core_send_ltr_ignore(pmcdev, 3);
}
void adl_core_init(struct pmc_dev *pmcdev)
{
pmcdev->map = &adl_reg_map;
pmcdev->core_configure = adl_core_configure;
}
static const struct x86_cpu_id intel_pmc_core_ids[] = { static const struct x86_cpu_id intel_pmc_core_ids[] = {
X86_MATCH_INTEL_FAM6_MODEL(SKYLAKE_L, &spt_reg_map), X86_MATCH_INTEL_FAM6_MODEL(SKYLAKE_L, spt_core_init),
X86_MATCH_INTEL_FAM6_MODEL(SKYLAKE, &spt_reg_map), X86_MATCH_INTEL_FAM6_MODEL(SKYLAKE, spt_core_init),
X86_MATCH_INTEL_FAM6_MODEL(KABYLAKE_L, &spt_reg_map), X86_MATCH_INTEL_FAM6_MODEL(KABYLAKE_L, spt_core_init),
X86_MATCH_INTEL_FAM6_MODEL(KABYLAKE, &spt_reg_map), X86_MATCH_INTEL_FAM6_MODEL(KABYLAKE, spt_core_init),
X86_MATCH_INTEL_FAM6_MODEL(CANNONLAKE_L, &cnp_reg_map), X86_MATCH_INTEL_FAM6_MODEL(CANNONLAKE_L, cnp_core_init),
X86_MATCH_INTEL_FAM6_MODEL(ICELAKE_L, &icl_reg_map), X86_MATCH_INTEL_FAM6_MODEL(ICELAKE_L, icl_core_init),
X86_MATCH_INTEL_FAM6_MODEL(ICELAKE_NNPI, &icl_reg_map), X86_MATCH_INTEL_FAM6_MODEL(ICELAKE_NNPI, icl_core_init),
X86_MATCH_INTEL_FAM6_MODEL(COMETLAKE, &cnp_reg_map), X86_MATCH_INTEL_FAM6_MODEL(COMETLAKE, cnp_core_init),
X86_MATCH_INTEL_FAM6_MODEL(COMETLAKE_L, &cnp_reg_map), X86_MATCH_INTEL_FAM6_MODEL(COMETLAKE_L, cnp_core_init),
X86_MATCH_INTEL_FAM6_MODEL(TIGERLAKE_L, &tgl_reg_map), X86_MATCH_INTEL_FAM6_MODEL(TIGERLAKE_L, tgl_core_init),
X86_MATCH_INTEL_FAM6_MODEL(TIGERLAKE, &tgl_reg_map), X86_MATCH_INTEL_FAM6_MODEL(TIGERLAKE, tgl_core_init),
X86_MATCH_INTEL_FAM6_MODEL(ATOM_TREMONT, &tgl_reg_map), X86_MATCH_INTEL_FAM6_MODEL(ATOM_TREMONT, tgl_core_init),
X86_MATCH_INTEL_FAM6_MODEL(ATOM_TREMONT_L, &icl_reg_map), X86_MATCH_INTEL_FAM6_MODEL(ATOM_TREMONT_L, icl_core_init),
X86_MATCH_INTEL_FAM6_MODEL(ROCKETLAKE, &tgl_reg_map), X86_MATCH_INTEL_FAM6_MODEL(ROCKETLAKE, tgl_core_init),
X86_MATCH_INTEL_FAM6_MODEL(ALDERLAKE_L, &tgl_reg_map), X86_MATCH_INTEL_FAM6_MODEL(ALDERLAKE_L, tgl_core_init),
X86_MATCH_INTEL_FAM6_MODEL(ALDERLAKE_N, &tgl_reg_map), X86_MATCH_INTEL_FAM6_MODEL(ALDERLAKE_N, tgl_core_init),
X86_MATCH_INTEL_FAM6_MODEL(ALDERLAKE, &adl_reg_map), X86_MATCH_INTEL_FAM6_MODEL(ALDERLAKE, adl_core_init),
X86_MATCH_INTEL_FAM6_MODEL(RAPTORLAKE_P, &tgl_reg_map), X86_MATCH_INTEL_FAM6_MODEL(RAPTORLAKE_P, tgl_core_init),
X86_MATCH_INTEL_FAM6_MODEL(RAPTORLAKE, &adl_reg_map), X86_MATCH_INTEL_FAM6_MODEL(RAPTORLAKE, adl_core_init),
X86_MATCH_INTEL_FAM6_MODEL(RAPTORLAKE_S, &adl_reg_map), X86_MATCH_INTEL_FAM6_MODEL(RAPTORLAKE_S, adl_core_init),
{} {}
}; };
...@@ -1975,6 +2020,7 @@ static int pmc_core_probe(struct platform_device *pdev) ...@@ -1975,6 +2020,7 @@ static int pmc_core_probe(struct platform_device *pdev)
static bool device_initialized; static bool device_initialized;
struct pmc_dev *pmcdev; struct pmc_dev *pmcdev;
const struct x86_cpu_id *cpu_id; const struct x86_cpu_id *cpu_id;
void (*core_init)(struct pmc_dev *pmcdev);
u64 slp_s0_addr; u64 slp_s0_addr;
if (device_initialized) if (device_initialized)
...@@ -1985,20 +2031,25 @@ static int pmc_core_probe(struct platform_device *pdev) ...@@ -1985,20 +2031,25 @@ static int pmc_core_probe(struct platform_device *pdev)
return -ENOMEM; return -ENOMEM;
platform_set_drvdata(pdev, pmcdev); platform_set_drvdata(pdev, pmcdev);
pmcdev->pdev = pdev;
cpu_id = x86_match_cpu(intel_pmc_core_ids); cpu_id = x86_match_cpu(intel_pmc_core_ids);
if (!cpu_id) if (!cpu_id)
return -ENODEV; return -ENODEV;
pmcdev->map = (struct pmc_reg_map *)cpu_id->driver_data; core_init = (void (*)(struct pmc_dev *))cpu_id->driver_data;
/* /*
* Coffee Lake has CPU ID of Kaby Lake and Cannon Lake PCH. So here * Coffee Lake has CPU ID of Kaby Lake and Cannon Lake PCH. So here
* Sunrisepoint PCH regmap can't be used. Use Cannon Lake PCH regmap * Sunrisepoint PCH regmap can't be used. Use Cannon Lake PCH regmap
* in this case. * in this case.
*/ */
if (pmcdev->map == &spt_reg_map && !pci_dev_present(pmc_pci_ids)) if (core_init == spt_core_init && !pci_dev_present(pmc_pci_ids))
pmcdev->map = &cnp_reg_map; core_init = cnp_core_init;
mutex_init(&pmcdev->lock);
core_init(pmcdev);
if (lpit_read_residency_count_address(&slp_s0_addr)) { if (lpit_read_residency_count_address(&slp_s0_addr)) {
pmcdev->base_addr = PMC_BASE_ADDR_DEFAULT; pmcdev->base_addr = PMC_BASE_ADDR_DEFAULT;
...@@ -2014,24 +2065,13 @@ static int pmc_core_probe(struct platform_device *pdev) ...@@ -2014,24 +2065,13 @@ static int pmc_core_probe(struct platform_device *pdev)
if (!pmcdev->regbase) if (!pmcdev->regbase)
return -ENOMEM; return -ENOMEM;
mutex_init(&pmcdev->lock); if (pmcdev->core_configure)
pmcdev->core_configure(pmcdev);
pmcdev->pmc_xram_read_bit = pmc_core_check_read_lock_bit(pmcdev); pmcdev->pmc_xram_read_bit = pmc_core_check_read_lock_bit(pmcdev);
pmc_core_get_low_power_modes(pdev); pmc_core_get_low_power_modes(pdev);
pmc_core_do_dmi_quirks(pmcdev); pmc_core_do_dmi_quirks(pmcdev);
if (pmcdev->map == &tgl_reg_map)
pmc_core_get_tgl_lpm_reqs(pdev);
/*
* On TGL and ADL, due to a hardware limitation, the GBE LTR blocks PC10
* when a cable is attached. Tell the PMC to ignore it.
*/
if (pmcdev->map == &tgl_reg_map || pmcdev->map == &adl_reg_map) {
dev_dbg(&pdev->dev, "ignoring GBE LTR\n");
pmc_core_send_ltr_ignore(pmcdev, 3);
}
pmc_core_dbgfs_register(pmcdev); pmc_core_dbgfs_register(pmcdev);
device_initialized = true; device_initialized = true;
......
...@@ -13,6 +13,7 @@ ...@@ -13,6 +13,7 @@
#define PMC_CORE_H #define PMC_CORE_H
#include <linux/bits.h> #include <linux/bits.h>
#include <linux/platform_device.h>
#define PMC_BASE_ADDR_DEFAULT 0xFE000000 #define PMC_BASE_ADDR_DEFAULT 0xFE000000
...@@ -312,6 +313,7 @@ struct pmc_reg_map { ...@@ -312,6 +313,7 @@ struct pmc_reg_map {
* @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
* @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
* used to read MPHY PG and PLL status are available * used to read MPHY PG and PLL status are available
...@@ -322,6 +324,7 @@ struct pmc_reg_map { ...@@ -322,6 +324,7 @@ struct pmc_reg_map {
* @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 * @lpm_req_regs: List of substate requirements
* @core_configure: Function pointer to configure the platform
* *
* pmc_dev contains info about power management controller device. * pmc_dev contains info about power management controller device.
*/ */
...@@ -330,6 +333,7 @@ struct pmc_dev { ...@@ -330,6 +333,7 @@ struct pmc_dev {
void __iomem *regbase; void __iomem *regbase;
const struct pmc_reg_map *map; const struct pmc_reg_map *map;
struct dentry *dbgfs_dir; struct dentry *dbgfs_dir;
struct platform_device *pdev;
int pmc_xram_read_bit; int pmc_xram_read_bit;
struct mutex lock; /* generic mutex lock for PMC Core */ struct mutex lock; /* generic mutex lock for PMC Core */
...@@ -339,8 +343,17 @@ struct pmc_dev { ...@@ -339,8 +343,17 @@ struct pmc_dev {
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; u32 *lpm_req_regs;
void (*core_configure)(struct pmc_dev *pmcdev);
}; };
void spt_core_init(struct pmc_dev *pmcdev);
void cnp_core_init(struct pmc_dev *pmcdev);
void icl_core_init(struct pmc_dev *pmcdev);
void tgl_core_init(struct pmc_dev *pmcdev);
void adl_core_init(struct pmc_dev *pmcdev);
void tgl_core_configure(struct pmc_dev *pmcdev);
void adl_core_configure(struct pmc_dev *pmcdev);
#define pmc_for_each_mode(i, mode, pmcdev) \ #define pmc_for_each_mode(i, mode, pmcdev) \
for (i = 0, mode = pmcdev->lpm_en_modes[i]; \ for (i = 0, mode = pmcdev->lpm_en_modes[i]; \
i < pmcdev->num_lpm_modes; \ i < pmcdev->num_lpm_modes; \
......
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