diff options
Diffstat (limited to 'drivers/platform/x86/intel/pmc')
| -rw-r--r-- | drivers/platform/x86/intel/pmc/arl.c | 2 | ||||
| -rw-r--r-- | drivers/platform/x86/intel/pmc/core.c | 47 | ||||
| -rw-r--r-- | drivers/platform/x86/intel/pmc/core.h | 7 | ||||
| -rw-r--r-- | drivers/platform/x86/intel/pmc/lnl.c | 40 | 
4 files changed, 48 insertions, 48 deletions
| diff --git a/drivers/platform/x86/intel/pmc/arl.c b/drivers/platform/x86/intel/pmc/arl.c index 683ae828276b..34b4cd23bfe5 100644 --- a/drivers/platform/x86/intel/pmc/arl.c +++ b/drivers/platform/x86/intel/pmc/arl.c @@ -673,6 +673,7 @@ static struct pmc_info arl_pmc_info_list[] = {  };  #define ARL_NPU_PCI_DEV			0xad1d +#define ARL_GNA_PCI_DEV			0xae4c  /*   * Set power state of select devices that do not have drivers to D3   * so that they do not block Package C entry. @@ -680,6 +681,7 @@ static struct pmc_info arl_pmc_info_list[] = {  static void arl_d3_fixup(void)  {  	pmc_core_set_device_d3(ARL_NPU_PCI_DEV); +	pmc_core_set_device_d3(ARL_GNA_PCI_DEV);  }  static int arl_resume(struct pmc_dev *pmcdev) diff --git a/drivers/platform/x86/intel/pmc/core.c b/drivers/platform/x86/intel/pmc/core.c index 8f9c036809c7..10c96c1a850a 100644 --- a/drivers/platform/x86/intel/pmc/core.c +++ b/drivers/platform/x86/intel/pmc/core.c @@ -1389,6 +1389,15 @@ static int pmc_core_probe(struct platform_device *pdev)  		return -ENOMEM;  	pmcdev->pmcs[PMC_IDX_MAIN] = primary_pmc; +	/* The last element in msr_map is empty */ +	pmcdev->num_of_pkgc = ARRAY_SIZE(msr_map) - 1; +	pmcdev->pkgc_res_cnt = devm_kcalloc(&pdev->dev, +					    pmcdev->num_of_pkgc, +					    sizeof(*pmcdev->pkgc_res_cnt), +					    GFP_KERNEL); +	if (!pmcdev->pkgc_res_cnt) +		return -ENOMEM; +  	/*  	 * 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 @@ -1432,6 +1441,7 @@ static __maybe_unused int pmc_core_suspend(struct device *dev)  {  	struct pmc_dev *pmcdev = dev_get_drvdata(dev);  	struct pmc *pmc = pmcdev->pmcs[PMC_IDX_MAIN]; +	unsigned int i;  	if (pmcdev->suspend)  		pmcdev->suspend(pmcdev); @@ -1440,9 +1450,11 @@ static __maybe_unused int pmc_core_suspend(struct device *dev)  	if (pm_suspend_via_firmware())  		return 0; -	/* Save PC10 residency for checking later */ -	if (rdmsrl_safe(MSR_PKG_C10_RESIDENCY, &pmcdev->pc10_counter)) -		return -EIO; +	/* Save PKGC residency for checking later */ +	for (i = 0; i < pmcdev->num_of_pkgc; i++) { +		if (rdmsrl_safe(msr_map[i].bit_mask, &pmcdev->pkgc_res_cnt[i])) +			return -EIO; +	}  	/* Save S0ix residency for checking later */  	if (pmc_core_dev_state_get(pmc, &pmcdev->s0ix_counter)) @@ -1451,14 +1463,15 @@ static __maybe_unused int pmc_core_suspend(struct device *dev)  	return 0;  } -static inline bool pmc_core_is_pc10_failed(struct pmc_dev *pmcdev) +static inline bool pmc_core_is_deepest_pkgc_failed(struct pmc_dev *pmcdev)  { -	u64 pc10_counter; +	u32 deepest_pkgc_msr = msr_map[pmcdev->num_of_pkgc - 1].bit_mask; +	u64 deepest_pkgc_residency; -	if (rdmsrl_safe(MSR_PKG_C10_RESIDENCY, &pc10_counter)) +	if (rdmsrl_safe(deepest_pkgc_msr, &deepest_pkgc_residency))  		return false; -	if (pc10_counter == pmcdev->pc10_counter) +	if (deepest_pkgc_residency == pmcdev->pkgc_res_cnt[pmcdev->num_of_pkgc - 1])  		return true;  	return false; @@ -1497,10 +1510,22 @@ int pmc_core_resume_common(struct pmc_dev *pmcdev)  	if (!warn_on_s0ix_failures)  		return 0; -	if (pmc_core_is_pc10_failed(pmcdev)) { -		/* S0ix failed because of PC10 entry failure */ -		dev_info(dev, "CPU did not enter PC10!!! (PC10 cnt=0x%llx)\n", -			 pmcdev->pc10_counter); +	if (pmc_core_is_deepest_pkgc_failed(pmcdev)) { +		/* S0ix failed because of deepest PKGC entry failure */ +		dev_info(dev, "CPU did not enter %s!!! (%s cnt=0x%llx)\n", +			 msr_map[pmcdev->num_of_pkgc - 1].name, +			 msr_map[pmcdev->num_of_pkgc - 1].name, +			 pmcdev->pkgc_res_cnt[pmcdev->num_of_pkgc - 1]); + +		for (i = 0; i < pmcdev->num_of_pkgc; i++) { +			u64 pc_cnt; + +			if (!rdmsrl_safe(msr_map[i].bit_mask, &pc_cnt)) { +				dev_info(dev, "Prev %s cnt = 0x%llx, Current %s cnt = 0x%llx\n", +					 msr_map[i].name, pmcdev->pkgc_res_cnt[i], +					 msr_map[i].name, pc_cnt); +			} +		}  		return 0;  	} diff --git a/drivers/platform/x86/intel/pmc/core.h b/drivers/platform/x86/intel/pmc/core.h index 54137faaae2b..83504c49a0e3 100644 --- a/drivers/platform/x86/intel/pmc/core.h +++ b/drivers/platform/x86/intel/pmc/core.h @@ -385,7 +385,8 @@ struct pmc {   * @pmc_xram_read_bit:	flag to indicate whether PMC XRAM shadow registers   *			used to read MPHY PG and PLL status are available   * @mutex_lock:		mutex to complete one transcation - * @pc10_counter:	PC10 residency counter + * @pkgc_res_cnt:	Array of PKGC residency counters + * @num_of_pkgc:	Number of PKGC   * @s0ix_counter:	S0ix residency (step adjusted)   * @num_lpm_modes:	Count of enabled modes   * @lpm_en_modes:	Array of enabled modes from lowest to highest priority @@ -403,13 +404,15 @@ struct pmc_dev {  	int pmc_xram_read_bit;  	struct mutex lock; /* generic mutex lock for PMC Core */ -	u64 pc10_counter;  	u64 s0ix_counter;  	int num_lpm_modes;  	int lpm_en_modes[LPM_MAX_NUM_MODES];  	void (*suspend)(struct pmc_dev *pmcdev);  	int (*resume)(struct pmc_dev *pmcdev); +	u64 *pkgc_res_cnt; +	u8 num_of_pkgc; +  	bool has_die_c6;  	u32 die_c6_offset;  	struct telem_endpoint *punit_ep; diff --git a/drivers/platform/x86/intel/pmc/lnl.c b/drivers/platform/x86/intel/pmc/lnl.c index abad17cdd3d7..068d72504683 100644 --- a/drivers/platform/x86/intel/pmc/lnl.c +++ b/drivers/platform/x86/intel/pmc/lnl.c @@ -13,21 +13,6 @@  #include "core.h" -#define SOCM_LPM_REQ_GUID	0x11594920 - -#define PMC_DEVID_SOCM	0xa87f - -static const u8 LNL_LPM_REG_INDEX[] = {0, 4, 5, 6, 8, 9, 10, 11, 12, 13, 14, 15, 16, 20}; - -static struct pmc_info lnl_pmc_info_list[] = { -	{ -		.guid	= SOCM_LPM_REQ_GUID, -		.devid	= PMC_DEVID_SOCM, -		.map	= &lnl_socm_reg_map, -	}, -	{} -}; -  const struct pmc_bit_map lnl_ltr_show_map[] = {  	{"SOUTHPORT_A",		CNP_PMC_LTR_SPA},  	{"SOUTHPORT_B",		CNP_PMC_LTR_SPB}, @@ -490,7 +475,6 @@ const struct pmc_reg_map lnl_socm_reg_map = {  	.lpm_sts = lnl_lpm_maps,  	.lpm_status_offset = MTL_LPM_STATUS_OFFSET,  	.lpm_live_status_offset = MTL_LPM_LIVE_STATUS_OFFSET, -	.lpm_reg_index = LNL_LPM_REG_INDEX,  };  #define LNL_NPU_PCI_DEV		0x643e @@ -517,33 +501,19 @@ static int lnl_resume(struct pmc_dev *pmcdev)  int lnl_core_init(struct pmc_dev *pmcdev)  {  	int ret; -	int func = 2; -	bool ssram_init = true;  	struct pmc *pmc = pmcdev->pmcs[PMC_IDX_SOC];  	lnl_d3_fixup();  	pmcdev->suspend = cnl_suspend;  	pmcdev->resume = lnl_resume; -	pmcdev->regmap_list = lnl_pmc_info_list; -	ret = pmc_core_ssram_init(pmcdev, func); - -	/* If regbase not assigned, set map and discover using legacy method */ -	if (ret) { -		ssram_init = false; -		pmc->map = &lnl_socm_reg_map; -		ret = get_primary_reg_base(pmc); -		if (ret) -			return ret; -	} -	pmc_core_get_low_power_modes(pmcdev); +	pmc->map = &lnl_socm_reg_map; +	ret = get_primary_reg_base(pmc); +	if (ret) +		return ret; -	if (ssram_init) { -		ret = pmc_core_ssram_get_lpm_reqs(pmcdev); -		if (ret) -			return ret; -	} +	pmc_core_get_low_power_modes(pmcdev);  	return 0;  } |