Commit 53793d15 authored by Srinivas Pandruvada's avatar Srinivas Pandruvada Committed by Yingbao Jia
Browse files

platform/x86: ISST: Add suspend/resume callbacks

mainline inclusion
from mainline-v6.4-rc1
commit 91576aca
category: feature
bugzilla: https://gitee.com/openeuler/intel-kernel/issues/I8WOEO

Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=91576acab0203062b93a578a7d05c8fe9e527f80



-------------------------------------

To support S3/S4 with TPMI interface add suspend/resume callbacks.
Here HW state is stored in suspend callback and restored during
resume callback.

The hardware state which needs to be stored/restored:
- CLOS configuration
- CLOS Association
- SST-CP enable/disable status
- SST-PP perf level setting

Intel-SIG: commit 91576aca platform/x86: ISST: Add suspend/resume callbacks.
Backport Intel speed select ISST driver support on TPMI.

Signed-off-by: default avatarSrinivas Pandruvada <srinivas.pandruvada@linux.intel.com>
Suggested-by: default avatarHans de Goede <hdegoede@redhat.com>
Reviewed-by: default avatarZhang Rui <rui.zhang@intel.com>
Tested-by: default avatarPragya Tanwar <pragya.tanwar@intel.com>
Link: https://lore.kernel.org/r/20230308070642.1727167-9-srinivas.pandruvada@linux.intel.com


Reviewed-by: default avatarHans de Goede <hdegoede@redhat.com>
Signed-off-by: default avatarHans de Goede <hdegoede@redhat.com>
[ Yingbao Jia: amend commit log ]
Signed-off-by: default avatarYingbao Jia <yingbao.jia@intel.com>
parent 568e6cdd
Loading
Loading
Loading
Loading
+22 −0
Original line number Diff line number Diff line
@@ -34,6 +34,25 @@ static void intel_sst_remove(struct auxiliary_device *auxdev)
	tpmi_sst_exit();
}

static int intel_sst_suspend(struct device *dev)
{
	tpmi_sst_dev_suspend(to_auxiliary_dev(dev));

	return 0;
}

static int intel_sst_resume(struct device *dev)
{
	tpmi_sst_dev_resume(to_auxiliary_dev(dev));

	return 0;
}

static const struct dev_pm_ops intel_sst_pm_ops = {
	.suspend	= intel_sst_suspend,
	.resume		= intel_sst_resume,
};

static const struct auxiliary_device_id intel_sst_id_table[] = {
	{ .name = "intel_vsec.tpmi-sst" },
	{}
@@ -44,6 +63,9 @@ static struct auxiliary_driver intel_sst_aux_driver = {
	.id_table       = intel_sst_id_table,
	.remove         = intel_sst_remove,
	.probe          = intel_sst_probe,
	.driver = {
		.pm = &intel_sst_pm_ops,
	},
};

module_auxiliary_driver(intel_sst_aux_driver);
+49 −0
Original line number Diff line number Diff line
@@ -229,6 +229,10 @@ struct perf_level {
 * @status_offset:	Store the status offset for each PP-level
 * @sst_base:		Mapped SST base IO memory
 * @auxdev:		Auxiliary device instance enumerated this instance
 * @saved_sst_cp_control: Save SST-CP control configuration to store restore for suspend/resume
 * @saved_clos_configs:	Save SST-CP CLOS configuration to store restore for suspend/resume
 * @saved_clos_assocs:	Save SST-CP CLOS association to store restore for suspend/resume
 * @saved_pp_control:	Save SST-PP control information to store restore for suspend/resume
 *
 * This structure is used store complete SST information for a power_domain. This information
 * is used to read/write request for any SST IOCTL. Each physical CPU package can have multiple
@@ -250,6 +254,10 @@ struct tpmi_per_power_domain_info {
	struct pp_status_offset status_offset;
	void __iomem *sst_base;
	struct auxiliary_device *auxdev;
	u64 saved_sst_cp_control;
	u64 saved_clos_configs[4];
	u64 saved_clos_assocs[4];
	u64 saved_pp_control;
};

/**
@@ -1333,6 +1341,47 @@ void tpmi_sst_dev_remove(struct auxiliary_device *auxdev)
}
EXPORT_SYMBOL_NS_GPL(tpmi_sst_dev_remove, INTEL_TPMI_SST);

void tpmi_sst_dev_suspend(struct auxiliary_device *auxdev)
{
	struct tpmi_sst_struct *tpmi_sst = auxiliary_get_drvdata(auxdev);
	struct tpmi_per_power_domain_info *power_domain_info = tpmi_sst->power_domain_info;
	void __iomem *cp_base;

	cp_base = power_domain_info->sst_base + power_domain_info->sst_header.cp_offset;
	power_domain_info->saved_sst_cp_control = readq(cp_base + SST_CP_CONTROL_OFFSET);

	memcpy_fromio(power_domain_info->saved_clos_configs, cp_base + SST_CLOS_CONFIG_0_OFFSET,
		      sizeof(power_domain_info->saved_clos_configs));

	memcpy_fromio(power_domain_info->saved_clos_assocs, cp_base + SST_CLOS_ASSOC_0_OFFSET,
		      sizeof(power_domain_info->saved_clos_assocs));

	power_domain_info->saved_pp_control = readq(power_domain_info->sst_base +
						    power_domain_info->sst_header.pp_offset +
						    SST_PP_CONTROL_OFFSET);
}
EXPORT_SYMBOL_NS_GPL(tpmi_sst_dev_suspend, INTEL_TPMI_SST);

void tpmi_sst_dev_resume(struct auxiliary_device *auxdev)
{
	struct tpmi_sst_struct *tpmi_sst = auxiliary_get_drvdata(auxdev);
	struct tpmi_per_power_domain_info *power_domain_info = tpmi_sst->power_domain_info;
	void __iomem *cp_base;

	cp_base = power_domain_info->sst_base + power_domain_info->sst_header.cp_offset;
	writeq(power_domain_info->saved_sst_cp_control, cp_base + SST_CP_CONTROL_OFFSET);

	memcpy_toio(cp_base + SST_CLOS_CONFIG_0_OFFSET, power_domain_info->saved_clos_configs,
		    sizeof(power_domain_info->saved_clos_configs));

	memcpy_toio(cp_base + SST_CLOS_ASSOC_0_OFFSET, power_domain_info->saved_clos_assocs,
		    sizeof(power_domain_info->saved_clos_assocs));

	writeq(power_domain_info->saved_pp_control, power_domain_info->sst_base +
				power_domain_info->sst_header.pp_offset + SST_PP_CONTROL_OFFSET);
}
EXPORT_SYMBOL_NS_GPL(tpmi_sst_dev_resume, INTEL_TPMI_SST);

#define ISST_TPMI_API_VERSION	0x02

int tpmi_sst_init(void)
+2 −0
Original line number Diff line number Diff line
@@ -13,4 +13,6 @@ int tpmi_sst_init(void);
void tpmi_sst_exit(void);
int tpmi_sst_dev_add(struct auxiliary_device *auxdev);
void tpmi_sst_dev_remove(struct auxiliary_device *auxdev);
void tpmi_sst_dev_suspend(struct auxiliary_device *auxdev);
void tpmi_sst_dev_resume(struct auxiliary_device *auxdev);
#endif