cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

amd-pmc.c (24333B)


      1// SPDX-License-Identifier: GPL-2.0-or-later
      2/*
      3 * AMD SoC Power Management Controller Driver
      4 *
      5 * Copyright (c) 2020, Advanced Micro Devices, Inc.
      6 * All Rights Reserved.
      7 *
      8 * Author: Shyam Sundar S K <Shyam-sundar.S-k@amd.com>
      9 */
     10
     11#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
     12
     13#include <linux/acpi.h>
     14#include <linux/bitfield.h>
     15#include <linux/bits.h>
     16#include <linux/debugfs.h>
     17#include <linux/delay.h>
     18#include <linux/io.h>
     19#include <linux/iopoll.h>
     20#include <linux/limits.h>
     21#include <linux/module.h>
     22#include <linux/pci.h>
     23#include <linux/platform_device.h>
     24#include <linux/rtc.h>
     25#include <linux/suspend.h>
     26#include <linux/seq_file.h>
     27#include <linux/uaccess.h>
     28
     29/* SMU communication registers */
     30#define AMD_PMC_REGISTER_MESSAGE	0x538
     31#define AMD_PMC_REGISTER_RESPONSE	0x980
     32#define AMD_PMC_REGISTER_ARGUMENT	0x9BC
     33
     34/* PMC Scratch Registers */
     35#define AMD_PMC_SCRATCH_REG_CZN		0x94
     36#define AMD_PMC_SCRATCH_REG_YC		0xD14
     37
     38/* STB Registers */
     39#define AMD_PMC_STB_INDEX_ADDRESS	0xF8
     40#define AMD_PMC_STB_INDEX_DATA		0xFC
     41#define AMD_PMC_STB_PMI_0		0x03E30600
     42#define AMD_PMC_STB_PREDEF		0xC6000001
     43
     44/* STB S2D(Spill to DRAM) has different message port offset */
     45#define STB_SPILL_TO_DRAM		0xBE
     46#define AMD_S2D_REGISTER_MESSAGE	0xA20
     47#define AMD_S2D_REGISTER_RESPONSE	0xA80
     48#define AMD_S2D_REGISTER_ARGUMENT	0xA88
     49
     50/* STB Spill to DRAM Parameters */
     51#define S2D_TELEMETRY_BYTES_MAX		0x100000
     52#define S2D_TELEMETRY_DRAMBYTES_MAX	0x1000000
     53
     54/* Base address of SMU for mapping physical address to virtual address */
     55#define AMD_PMC_SMU_INDEX_ADDRESS	0xB8
     56#define AMD_PMC_SMU_INDEX_DATA		0xBC
     57#define AMD_PMC_MAPPING_SIZE		0x01000
     58#define AMD_PMC_BASE_ADDR_OFFSET	0x10000
     59#define AMD_PMC_BASE_ADDR_LO		0x13B102E8
     60#define AMD_PMC_BASE_ADDR_HI		0x13B102EC
     61#define AMD_PMC_BASE_ADDR_LO_MASK	GENMASK(15, 0)
     62#define AMD_PMC_BASE_ADDR_HI_MASK	GENMASK(31, 20)
     63
     64/* SMU Response Codes */
     65#define AMD_PMC_RESULT_OK                    0x01
     66#define AMD_PMC_RESULT_CMD_REJECT_BUSY       0xFC
     67#define AMD_PMC_RESULT_CMD_REJECT_PREREQ     0xFD
     68#define AMD_PMC_RESULT_CMD_UNKNOWN           0xFE
     69#define AMD_PMC_RESULT_FAILED                0xFF
     70
     71/* FCH SSC Registers */
     72#define FCH_S0I3_ENTRY_TIME_L_OFFSET	0x30
     73#define FCH_S0I3_ENTRY_TIME_H_OFFSET	0x34
     74#define FCH_S0I3_EXIT_TIME_L_OFFSET	0x38
     75#define FCH_S0I3_EXIT_TIME_H_OFFSET	0x3C
     76#define FCH_SSC_MAPPING_SIZE		0x800
     77#define FCH_BASE_PHY_ADDR_LOW		0xFED81100
     78#define FCH_BASE_PHY_ADDR_HIGH		0x00000000
     79
     80/* SMU Message Definations */
     81#define SMU_MSG_GETSMUVERSION		0x02
     82#define SMU_MSG_LOG_GETDRAM_ADDR_HI	0x04
     83#define SMU_MSG_LOG_GETDRAM_ADDR_LO	0x05
     84#define SMU_MSG_LOG_START		0x06
     85#define SMU_MSG_LOG_RESET		0x07
     86#define SMU_MSG_LOG_DUMP_DATA		0x08
     87#define SMU_MSG_GET_SUP_CONSTRAINTS	0x09
     88/* List of supported CPU ids */
     89#define AMD_CPU_ID_RV			0x15D0
     90#define AMD_CPU_ID_RN			0x1630
     91#define AMD_CPU_ID_PCO			AMD_CPU_ID_RV
     92#define AMD_CPU_ID_CZN			AMD_CPU_ID_RN
     93#define AMD_CPU_ID_YC			0x14B5
     94
     95#define PMC_MSG_DELAY_MIN_US		50
     96#define RESPONSE_REGISTER_LOOP_MAX	20000
     97
     98#define SOC_SUBSYSTEM_IP_MAX	12
     99#define DELAY_MIN_US		2000
    100#define DELAY_MAX_US		3000
    101#define FIFO_SIZE		4096
    102enum amd_pmc_def {
    103	MSG_TEST = 0x01,
    104	MSG_OS_HINT_PCO,
    105	MSG_OS_HINT_RN,
    106};
    107
    108enum s2d_arg {
    109	S2D_TELEMETRY_SIZE = 0x01,
    110	S2D_PHYS_ADDR_LOW,
    111	S2D_PHYS_ADDR_HIGH,
    112};
    113
    114struct amd_pmc_bit_map {
    115	const char *name;
    116	u32 bit_mask;
    117};
    118
    119static const struct amd_pmc_bit_map soc15_ip_blk[] = {
    120	{"DISPLAY",	BIT(0)},
    121	{"CPU",		BIT(1)},
    122	{"GFX",		BIT(2)},
    123	{"VDD",		BIT(3)},
    124	{"ACP",		BIT(4)},
    125	{"VCN",		BIT(5)},
    126	{"ISP",		BIT(6)},
    127	{"NBIO",	BIT(7)},
    128	{"DF",		BIT(8)},
    129	{"USB0",	BIT(9)},
    130	{"USB1",	BIT(10)},
    131	{"LAPIC",	BIT(11)},
    132	{}
    133};
    134
    135struct amd_pmc_dev {
    136	void __iomem *regbase;
    137	void __iomem *smu_virt_addr;
    138	void __iomem *stb_virt_addr;
    139	void __iomem *fch_virt_addr;
    140	bool msg_port;
    141	u32 base_addr;
    142	u32 cpu_id;
    143	u32 active_ips;
    144/* SMU version information */
    145	u8 smu_program;
    146	u8 major;
    147	u8 minor;
    148	u8 rev;
    149	struct device *dev;
    150	struct pci_dev *rdev;
    151	struct mutex lock; /* generic mutex lock */
    152#if IS_ENABLED(CONFIG_DEBUG_FS)
    153	struct dentry *dbgfs_dir;
    154#endif /* CONFIG_DEBUG_FS */
    155};
    156
    157static bool enable_stb;
    158module_param(enable_stb, bool, 0644);
    159MODULE_PARM_DESC(enable_stb, "Enable the STB debug mechanism");
    160
    161static struct amd_pmc_dev pmc;
    162static int amd_pmc_send_cmd(struct amd_pmc_dev *dev, u32 arg, u32 *data, u8 msg, bool ret);
    163static int amd_pmc_read_stb(struct amd_pmc_dev *dev, u32 *buf);
    164#ifdef CONFIG_SUSPEND
    165static int amd_pmc_write_stb(struct amd_pmc_dev *dev, u32 data);
    166#endif
    167
    168static inline u32 amd_pmc_reg_read(struct amd_pmc_dev *dev, int reg_offset)
    169{
    170	return ioread32(dev->regbase + reg_offset);
    171}
    172
    173static inline void amd_pmc_reg_write(struct amd_pmc_dev *dev, int reg_offset, u32 val)
    174{
    175	iowrite32(val, dev->regbase + reg_offset);
    176}
    177
    178struct smu_metrics {
    179	u32 table_version;
    180	u32 hint_count;
    181	u32 s0i3_last_entry_status;
    182	u32 timein_s0i2;
    183	u64 timeentering_s0i3_lastcapture;
    184	u64 timeentering_s0i3_totaltime;
    185	u64 timeto_resume_to_os_lastcapture;
    186	u64 timeto_resume_to_os_totaltime;
    187	u64 timein_s0i3_lastcapture;
    188	u64 timein_s0i3_totaltime;
    189	u64 timein_swdrips_lastcapture;
    190	u64 timein_swdrips_totaltime;
    191	u64 timecondition_notmet_lastcapture[SOC_SUBSYSTEM_IP_MAX];
    192	u64 timecondition_notmet_totaltime[SOC_SUBSYSTEM_IP_MAX];
    193} __packed;
    194
    195static int amd_pmc_stb_debugfs_open(struct inode *inode, struct file *filp)
    196{
    197	struct amd_pmc_dev *dev = filp->f_inode->i_private;
    198	u32 size = FIFO_SIZE * sizeof(u32);
    199	u32 *buf;
    200	int rc;
    201
    202	buf = kzalloc(size, GFP_KERNEL);
    203	if (!buf)
    204		return -ENOMEM;
    205
    206	rc = amd_pmc_read_stb(dev, buf);
    207	if (rc) {
    208		kfree(buf);
    209		return rc;
    210	}
    211
    212	filp->private_data = buf;
    213	return rc;
    214}
    215
    216static ssize_t amd_pmc_stb_debugfs_read(struct file *filp, char __user *buf, size_t size,
    217					loff_t *pos)
    218{
    219	if (!filp->private_data)
    220		return -EINVAL;
    221
    222	return simple_read_from_buffer(buf, size, pos, filp->private_data,
    223				       FIFO_SIZE * sizeof(u32));
    224}
    225
    226static int amd_pmc_stb_debugfs_release(struct inode *inode, struct file *filp)
    227{
    228	kfree(filp->private_data);
    229	return 0;
    230}
    231
    232static const struct file_operations amd_pmc_stb_debugfs_fops = {
    233	.owner = THIS_MODULE,
    234	.open = amd_pmc_stb_debugfs_open,
    235	.read = amd_pmc_stb_debugfs_read,
    236	.release = amd_pmc_stb_debugfs_release,
    237};
    238
    239static int amd_pmc_stb_debugfs_open_v2(struct inode *inode, struct file *filp)
    240{
    241	struct amd_pmc_dev *dev = filp->f_inode->i_private;
    242	u32 *buf;
    243
    244	buf = kzalloc(S2D_TELEMETRY_BYTES_MAX, GFP_KERNEL);
    245	if (!buf)
    246		return -ENOMEM;
    247
    248	memcpy_fromio(buf, dev->stb_virt_addr, S2D_TELEMETRY_BYTES_MAX);
    249	filp->private_data = buf;
    250
    251	return 0;
    252}
    253
    254static ssize_t amd_pmc_stb_debugfs_read_v2(struct file *filp, char __user *buf, size_t size,
    255					   loff_t *pos)
    256{
    257	if (!filp->private_data)
    258		return -EINVAL;
    259
    260	return simple_read_from_buffer(buf, size, pos, filp->private_data,
    261					S2D_TELEMETRY_BYTES_MAX);
    262}
    263
    264static int amd_pmc_stb_debugfs_release_v2(struct inode *inode, struct file *filp)
    265{
    266	kfree(filp->private_data);
    267	return 0;
    268}
    269
    270static const struct file_operations amd_pmc_stb_debugfs_fops_v2 = {
    271	.owner = THIS_MODULE,
    272	.open = amd_pmc_stb_debugfs_open_v2,
    273	.read = amd_pmc_stb_debugfs_read_v2,
    274	.release = amd_pmc_stb_debugfs_release_v2,
    275};
    276
    277#if defined(CONFIG_SUSPEND) || defined(CONFIG_DEBUG_FS)
    278static int amd_pmc_setup_smu_logging(struct amd_pmc_dev *dev)
    279{
    280	if (dev->cpu_id == AMD_CPU_ID_PCO) {
    281		dev_warn_once(dev->dev, "SMU debugging info not supported on this platform\n");
    282		return -EINVAL;
    283	}
    284
    285	/* Get Active devices list from SMU */
    286	if (!dev->active_ips)
    287		amd_pmc_send_cmd(dev, 0, &dev->active_ips, SMU_MSG_GET_SUP_CONSTRAINTS, 1);
    288
    289	/* Get dram address */
    290	if (!dev->smu_virt_addr) {
    291		u32 phys_addr_low, phys_addr_hi;
    292		u64 smu_phys_addr;
    293
    294		amd_pmc_send_cmd(dev, 0, &phys_addr_low, SMU_MSG_LOG_GETDRAM_ADDR_LO, 1);
    295		amd_pmc_send_cmd(dev, 0, &phys_addr_hi, SMU_MSG_LOG_GETDRAM_ADDR_HI, 1);
    296		smu_phys_addr = ((u64)phys_addr_hi << 32 | phys_addr_low);
    297
    298		dev->smu_virt_addr = devm_ioremap(dev->dev, smu_phys_addr,
    299						  sizeof(struct smu_metrics));
    300		if (!dev->smu_virt_addr)
    301			return -ENOMEM;
    302	}
    303
    304	/* Start the logging */
    305	amd_pmc_send_cmd(dev, 0, NULL, SMU_MSG_LOG_RESET, 0);
    306	amd_pmc_send_cmd(dev, 0, NULL, SMU_MSG_LOG_START, 0);
    307
    308	return 0;
    309}
    310
    311static int amd_pmc_idlemask_read(struct amd_pmc_dev *pdev, struct device *dev,
    312				 struct seq_file *s)
    313{
    314	u32 val;
    315
    316	switch (pdev->cpu_id) {
    317	case AMD_CPU_ID_CZN:
    318		val = amd_pmc_reg_read(pdev, AMD_PMC_SCRATCH_REG_CZN);
    319		break;
    320	case AMD_CPU_ID_YC:
    321		val = amd_pmc_reg_read(pdev, AMD_PMC_SCRATCH_REG_YC);
    322		break;
    323	default:
    324		return -EINVAL;
    325	}
    326
    327	if (dev)
    328		dev_dbg(pdev->dev, "SMU idlemask s0i3: 0x%x\n", val);
    329
    330	if (s)
    331		seq_printf(s, "SMU idlemask : 0x%x\n", val);
    332
    333	return 0;
    334}
    335
    336static int get_metrics_table(struct amd_pmc_dev *pdev, struct smu_metrics *table)
    337{
    338	if (!pdev->smu_virt_addr) {
    339		int ret = amd_pmc_setup_smu_logging(pdev);
    340
    341		if (ret)
    342			return ret;
    343	}
    344
    345	if (pdev->cpu_id == AMD_CPU_ID_PCO)
    346		return -ENODEV;
    347	memcpy_fromio(table, pdev->smu_virt_addr, sizeof(struct smu_metrics));
    348	return 0;
    349}
    350#endif /* CONFIG_SUSPEND || CONFIG_DEBUG_FS */
    351
    352#ifdef CONFIG_SUSPEND
    353static void amd_pmc_validate_deepest(struct amd_pmc_dev *pdev)
    354{
    355	struct smu_metrics table;
    356
    357	if (get_metrics_table(pdev, &table))
    358		return;
    359
    360	if (!table.s0i3_last_entry_status)
    361		dev_warn(pdev->dev, "Last suspend didn't reach deepest state\n");
    362	else
    363		dev_dbg(pdev->dev, "Last suspend in deepest state for %lluus\n",
    364			 table.timein_s0i3_lastcapture);
    365}
    366#endif
    367
    368#ifdef CONFIG_DEBUG_FS
    369static int smu_fw_info_show(struct seq_file *s, void *unused)
    370{
    371	struct amd_pmc_dev *dev = s->private;
    372	struct smu_metrics table;
    373	int idx;
    374
    375	if (get_metrics_table(dev, &table))
    376		return -EINVAL;
    377
    378	seq_puts(s, "\n=== SMU Statistics ===\n");
    379	seq_printf(s, "Table Version: %d\n", table.table_version);
    380	seq_printf(s, "Hint Count: %d\n", table.hint_count);
    381	seq_printf(s, "Last S0i3 Status: %s\n", table.s0i3_last_entry_status ? "Success" :
    382		   "Unknown/Fail");
    383	seq_printf(s, "Time (in us) to S0i3: %lld\n", table.timeentering_s0i3_lastcapture);
    384	seq_printf(s, "Time (in us) in S0i3: %lld\n", table.timein_s0i3_lastcapture);
    385	seq_printf(s, "Time (in us) to resume from S0i3: %lld\n",
    386		   table.timeto_resume_to_os_lastcapture);
    387
    388	seq_puts(s, "\n=== Active time (in us) ===\n");
    389	for (idx = 0 ; idx < SOC_SUBSYSTEM_IP_MAX ; idx++) {
    390		if (soc15_ip_blk[idx].bit_mask & dev->active_ips)
    391			seq_printf(s, "%-8s : %lld\n", soc15_ip_blk[idx].name,
    392				   table.timecondition_notmet_lastcapture[idx]);
    393	}
    394
    395	return 0;
    396}
    397DEFINE_SHOW_ATTRIBUTE(smu_fw_info);
    398
    399static int s0ix_stats_show(struct seq_file *s, void *unused)
    400{
    401	struct amd_pmc_dev *dev = s->private;
    402	u64 entry_time, exit_time, residency;
    403
    404	/* Use FCH registers to get the S0ix stats */
    405	if (!dev->fch_virt_addr) {
    406		u32 base_addr_lo = FCH_BASE_PHY_ADDR_LOW;
    407		u32 base_addr_hi = FCH_BASE_PHY_ADDR_HIGH;
    408		u64 fch_phys_addr = ((u64)base_addr_hi << 32 | base_addr_lo);
    409
    410		dev->fch_virt_addr = devm_ioremap(dev->dev, fch_phys_addr, FCH_SSC_MAPPING_SIZE);
    411		if (!dev->fch_virt_addr)
    412			return -ENOMEM;
    413	}
    414
    415	entry_time = ioread32(dev->fch_virt_addr + FCH_S0I3_ENTRY_TIME_H_OFFSET);
    416	entry_time = entry_time << 32 | ioread32(dev->fch_virt_addr + FCH_S0I3_ENTRY_TIME_L_OFFSET);
    417
    418	exit_time = ioread32(dev->fch_virt_addr + FCH_S0I3_EXIT_TIME_H_OFFSET);
    419	exit_time = exit_time << 32 | ioread32(dev->fch_virt_addr + FCH_S0I3_EXIT_TIME_L_OFFSET);
    420
    421	/* It's in 48MHz. We need to convert it */
    422	residency = exit_time - entry_time;
    423	do_div(residency, 48);
    424
    425	seq_puts(s, "=== S0ix statistics ===\n");
    426	seq_printf(s, "S0ix Entry Time: %lld\n", entry_time);
    427	seq_printf(s, "S0ix Exit Time: %lld\n", exit_time);
    428	seq_printf(s, "Residency Time: %lld\n", residency);
    429
    430	return 0;
    431}
    432DEFINE_SHOW_ATTRIBUTE(s0ix_stats);
    433
    434static int amd_pmc_get_smu_version(struct amd_pmc_dev *dev)
    435{
    436	int rc;
    437	u32 val;
    438
    439	rc = amd_pmc_send_cmd(dev, 0, &val, SMU_MSG_GETSMUVERSION, 1);
    440	if (rc)
    441		return rc;
    442
    443	dev->smu_program = (val >> 24) & GENMASK(7, 0);
    444	dev->major = (val >> 16) & GENMASK(7, 0);
    445	dev->minor = (val >> 8) & GENMASK(7, 0);
    446	dev->rev = (val >> 0) & GENMASK(7, 0);
    447
    448	dev_dbg(dev->dev, "SMU program %u version is %u.%u.%u\n",
    449		dev->smu_program, dev->major, dev->minor, dev->rev);
    450
    451	return 0;
    452}
    453
    454static int amd_pmc_idlemask_show(struct seq_file *s, void *unused)
    455{
    456	struct amd_pmc_dev *dev = s->private;
    457	int rc;
    458
    459	/* we haven't yet read SMU version */
    460	if (!dev->major) {
    461		rc = amd_pmc_get_smu_version(dev);
    462		if (rc)
    463			return rc;
    464	}
    465
    466	if (dev->major > 56 || (dev->major >= 55 && dev->minor >= 37)) {
    467		rc = amd_pmc_idlemask_read(dev, NULL, s);
    468		if (rc)
    469			return rc;
    470	} else {
    471		seq_puts(s, "Unsupported SMU version for Idlemask\n");
    472	}
    473
    474	return 0;
    475}
    476DEFINE_SHOW_ATTRIBUTE(amd_pmc_idlemask);
    477
    478static void amd_pmc_dbgfs_unregister(struct amd_pmc_dev *dev)
    479{
    480	debugfs_remove_recursive(dev->dbgfs_dir);
    481}
    482
    483static void amd_pmc_dbgfs_register(struct amd_pmc_dev *dev)
    484{
    485	dev->dbgfs_dir = debugfs_create_dir("amd_pmc", NULL);
    486	debugfs_create_file("smu_fw_info", 0644, dev->dbgfs_dir, dev,
    487			    &smu_fw_info_fops);
    488	debugfs_create_file("s0ix_stats", 0644, dev->dbgfs_dir, dev,
    489			    &s0ix_stats_fops);
    490	debugfs_create_file("amd_pmc_idlemask", 0644, dev->dbgfs_dir, dev,
    491			    &amd_pmc_idlemask_fops);
    492	/* Enable STB only when the module_param is set */
    493	if (enable_stb) {
    494		if (dev->cpu_id == AMD_CPU_ID_YC)
    495			debugfs_create_file("stb_read", 0644, dev->dbgfs_dir, dev,
    496					    &amd_pmc_stb_debugfs_fops_v2);
    497		else
    498			debugfs_create_file("stb_read", 0644, dev->dbgfs_dir, dev,
    499					    &amd_pmc_stb_debugfs_fops);
    500	}
    501}
    502#else
    503static inline void amd_pmc_dbgfs_register(struct amd_pmc_dev *dev)
    504{
    505}
    506
    507static inline void amd_pmc_dbgfs_unregister(struct amd_pmc_dev *dev)
    508{
    509}
    510#endif /* CONFIG_DEBUG_FS */
    511
    512static void amd_pmc_dump_registers(struct amd_pmc_dev *dev)
    513{
    514	u32 value, message, argument, response;
    515
    516	if (dev->msg_port) {
    517		message = AMD_S2D_REGISTER_MESSAGE;
    518		argument = AMD_S2D_REGISTER_ARGUMENT;
    519		response = AMD_S2D_REGISTER_RESPONSE;
    520	} else {
    521		message = AMD_PMC_REGISTER_MESSAGE;
    522		argument = AMD_PMC_REGISTER_ARGUMENT;
    523		response = AMD_PMC_REGISTER_RESPONSE;
    524	}
    525
    526	value = amd_pmc_reg_read(dev, response);
    527	dev_dbg(dev->dev, "AMD_PMC_REGISTER_RESPONSE:%x\n", value);
    528
    529	value = amd_pmc_reg_read(dev, argument);
    530	dev_dbg(dev->dev, "AMD_PMC_REGISTER_ARGUMENT:%x\n", value);
    531
    532	value = amd_pmc_reg_read(dev, message);
    533	dev_dbg(dev->dev, "AMD_PMC_REGISTER_MESSAGE:%x\n", value);
    534}
    535
    536static int amd_pmc_send_cmd(struct amd_pmc_dev *dev, u32 arg, u32 *data, u8 msg, bool ret)
    537{
    538	int rc;
    539	u32 val, message, argument, response;
    540
    541	mutex_lock(&dev->lock);
    542
    543	if (dev->msg_port) {
    544		message = AMD_S2D_REGISTER_MESSAGE;
    545		argument = AMD_S2D_REGISTER_ARGUMENT;
    546		response = AMD_S2D_REGISTER_RESPONSE;
    547	} else {
    548		message = AMD_PMC_REGISTER_MESSAGE;
    549		argument = AMD_PMC_REGISTER_ARGUMENT;
    550		response = AMD_PMC_REGISTER_RESPONSE;
    551	}
    552
    553	/* Wait until we get a valid response */
    554	rc = readx_poll_timeout(ioread32, dev->regbase + response,
    555				val, val != 0, PMC_MSG_DELAY_MIN_US,
    556				PMC_MSG_DELAY_MIN_US * RESPONSE_REGISTER_LOOP_MAX);
    557	if (rc) {
    558		dev_err(dev->dev, "failed to talk to SMU\n");
    559		goto out_unlock;
    560	}
    561
    562	/* Write zero to response register */
    563	amd_pmc_reg_write(dev, response, 0);
    564
    565	/* Write argument into response register */
    566	amd_pmc_reg_write(dev, argument, arg);
    567
    568	/* Write message ID to message ID register */
    569	amd_pmc_reg_write(dev, message, msg);
    570
    571	/* Wait until we get a valid response */
    572	rc = readx_poll_timeout(ioread32, dev->regbase + response,
    573				val, val != 0, PMC_MSG_DELAY_MIN_US,
    574				PMC_MSG_DELAY_MIN_US * RESPONSE_REGISTER_LOOP_MAX);
    575	if (rc) {
    576		dev_err(dev->dev, "SMU response timed out\n");
    577		goto out_unlock;
    578	}
    579
    580	switch (val) {
    581	case AMD_PMC_RESULT_OK:
    582		if (ret) {
    583			/* PMFW may take longer time to return back the data */
    584			usleep_range(DELAY_MIN_US, 10 * DELAY_MAX_US);
    585			*data = amd_pmc_reg_read(dev, argument);
    586		}
    587		break;
    588	case AMD_PMC_RESULT_CMD_REJECT_BUSY:
    589		dev_err(dev->dev, "SMU not ready. err: 0x%x\n", val);
    590		rc = -EBUSY;
    591		goto out_unlock;
    592	case AMD_PMC_RESULT_CMD_UNKNOWN:
    593		dev_err(dev->dev, "SMU cmd unknown. err: 0x%x\n", val);
    594		rc = -EINVAL;
    595		goto out_unlock;
    596	case AMD_PMC_RESULT_CMD_REJECT_PREREQ:
    597	case AMD_PMC_RESULT_FAILED:
    598	default:
    599		dev_err(dev->dev, "SMU cmd failed. err: 0x%x\n", val);
    600		rc = -EIO;
    601		goto out_unlock;
    602	}
    603
    604out_unlock:
    605	mutex_unlock(&dev->lock);
    606	amd_pmc_dump_registers(dev);
    607	return rc;
    608}
    609
    610#ifdef CONFIG_SUSPEND
    611static int amd_pmc_get_os_hint(struct amd_pmc_dev *dev)
    612{
    613	switch (dev->cpu_id) {
    614	case AMD_CPU_ID_PCO:
    615		return MSG_OS_HINT_PCO;
    616	case AMD_CPU_ID_RN:
    617	case AMD_CPU_ID_YC:
    618		return MSG_OS_HINT_RN;
    619	}
    620	return -EINVAL;
    621}
    622
    623static int amd_pmc_verify_czn_rtc(struct amd_pmc_dev *pdev, u32 *arg)
    624{
    625	struct rtc_device *rtc_device;
    626	time64_t then, now, duration;
    627	struct rtc_wkalrm alarm;
    628	struct rtc_time tm;
    629	int rc;
    630
    631	if (pdev->major < 64 || (pdev->major == 64 && pdev->minor < 53))
    632		return 0;
    633
    634	rtc_device = rtc_class_open("rtc0");
    635	if (!rtc_device)
    636		return 0;
    637	rc = rtc_read_alarm(rtc_device, &alarm);
    638	if (rc)
    639		return rc;
    640	if (!alarm.enabled) {
    641		dev_dbg(pdev->dev, "alarm not enabled\n");
    642		return 0;
    643	}
    644	rc = rtc_read_time(rtc_device, &tm);
    645	if (rc)
    646		return rc;
    647	then = rtc_tm_to_time64(&alarm.time);
    648	now = rtc_tm_to_time64(&tm);
    649	duration = then-now;
    650
    651	/* in the past */
    652	if (then < now)
    653		return 0;
    654
    655	/* will be stored in upper 16 bits of s0i3 hint argument,
    656	 * so timer wakeup from s0i3 is limited to ~18 hours or less
    657	 */
    658	if (duration <= 4 || duration > U16_MAX)
    659		return -EINVAL;
    660
    661	*arg |= (duration << 16);
    662	rc = rtc_alarm_irq_enable(rtc_device, 0);
    663	dev_dbg(pdev->dev, "wakeup timer programmed for %lld seconds\n", duration);
    664
    665	return rc;
    666}
    667
    668static void amd_pmc_s2idle_prepare(void)
    669{
    670	struct amd_pmc_dev *pdev = &pmc;
    671	int rc;
    672	u8 msg;
    673	u32 arg = 1;
    674
    675	/* Reset and Start SMU logging - to monitor the s0i3 stats */
    676	amd_pmc_setup_smu_logging(pdev);
    677
    678	/* Activate CZN specific RTC functionality */
    679	if (pdev->cpu_id == AMD_CPU_ID_CZN) {
    680		rc = amd_pmc_verify_czn_rtc(pdev, &arg);
    681		if (rc) {
    682			dev_err(pdev->dev, "failed to set RTC: %d\n", rc);
    683			return;
    684		}
    685	}
    686
    687	/* Dump the IdleMask before we send hint to SMU */
    688	amd_pmc_idlemask_read(pdev, pdev->dev, NULL);
    689	msg = amd_pmc_get_os_hint(pdev);
    690	rc = amd_pmc_send_cmd(pdev, arg, NULL, msg, 0);
    691	if (rc) {
    692		dev_err(pdev->dev, "suspend failed: %d\n", rc);
    693		return;
    694	}
    695
    696	if (enable_stb) {
    697		rc = amd_pmc_write_stb(pdev, AMD_PMC_STB_PREDEF);
    698		if (rc)
    699			dev_err(pdev->dev, "error writing to STB: %d\n", rc);
    700	}
    701}
    702
    703static void amd_pmc_s2idle_restore(void)
    704{
    705	struct amd_pmc_dev *pdev = &pmc;
    706	int rc;
    707	u8 msg;
    708
    709	msg = amd_pmc_get_os_hint(pdev);
    710	rc = amd_pmc_send_cmd(pdev, 0, NULL, msg, 0);
    711	if (rc)
    712		dev_err(pdev->dev, "resume failed: %d\n", rc);
    713
    714	/* Let SMU know that we are looking for stats */
    715	amd_pmc_send_cmd(pdev, 0, NULL, SMU_MSG_LOG_DUMP_DATA, 0);
    716
    717	/* Dump the IdleMask to see the blockers */
    718	amd_pmc_idlemask_read(pdev, pdev->dev, NULL);
    719
    720	/* Write data incremented by 1 to distinguish in stb_read */
    721	if (enable_stb) {
    722		rc = amd_pmc_write_stb(pdev, AMD_PMC_STB_PREDEF + 1);
    723		if (rc)
    724			dev_err(pdev->dev, "error writing to STB: %d\n", rc);
    725	}
    726
    727	/* Notify on failed entry */
    728	amd_pmc_validate_deepest(pdev);
    729}
    730
    731static struct acpi_s2idle_dev_ops amd_pmc_s2idle_dev_ops = {
    732	.prepare = amd_pmc_s2idle_prepare,
    733	.restore = amd_pmc_s2idle_restore,
    734};
    735#endif
    736
    737static const struct pci_device_id pmc_pci_ids[] = {
    738	{ PCI_DEVICE(PCI_VENDOR_ID_AMD, AMD_CPU_ID_YC) },
    739	{ PCI_DEVICE(PCI_VENDOR_ID_AMD, AMD_CPU_ID_CZN) },
    740	{ PCI_DEVICE(PCI_VENDOR_ID_AMD, AMD_CPU_ID_RN) },
    741	{ PCI_DEVICE(PCI_VENDOR_ID_AMD, AMD_CPU_ID_PCO) },
    742	{ PCI_DEVICE(PCI_VENDOR_ID_AMD, AMD_CPU_ID_RV) },
    743	{ }
    744};
    745
    746static int amd_pmc_s2d_init(struct amd_pmc_dev *dev)
    747{
    748	u32 phys_addr_low, phys_addr_hi;
    749	u64 stb_phys_addr;
    750	u32 size = 0;
    751
    752	/* Spill to DRAM feature uses separate SMU message port */
    753	dev->msg_port = 1;
    754
    755	amd_pmc_send_cmd(dev, S2D_TELEMETRY_SIZE, &size, STB_SPILL_TO_DRAM, 1);
    756	if (size != S2D_TELEMETRY_BYTES_MAX)
    757		return -EIO;
    758
    759	/* Get STB DRAM address */
    760	amd_pmc_send_cmd(dev, S2D_PHYS_ADDR_LOW, &phys_addr_low, STB_SPILL_TO_DRAM, 1);
    761	amd_pmc_send_cmd(dev, S2D_PHYS_ADDR_HIGH, &phys_addr_hi, STB_SPILL_TO_DRAM, 1);
    762
    763	stb_phys_addr = ((u64)phys_addr_hi << 32 | phys_addr_low);
    764
    765	/* Clear msg_port for other SMU operation */
    766	dev->msg_port = 0;
    767
    768	dev->stb_virt_addr = devm_ioremap(dev->dev, stb_phys_addr, S2D_TELEMETRY_DRAMBYTES_MAX);
    769	if (!dev->stb_virt_addr)
    770		return -ENOMEM;
    771
    772	return 0;
    773}
    774
    775#ifdef CONFIG_SUSPEND
    776static int amd_pmc_write_stb(struct amd_pmc_dev *dev, u32 data)
    777{
    778	int err;
    779
    780	err = pci_write_config_dword(dev->rdev, AMD_PMC_STB_INDEX_ADDRESS, AMD_PMC_STB_PMI_0);
    781	if (err) {
    782		dev_err(dev->dev, "failed to write addr in stb: 0x%X\n",
    783			AMD_PMC_STB_INDEX_ADDRESS);
    784		return pcibios_err_to_errno(err);
    785	}
    786
    787	err = pci_write_config_dword(dev->rdev, AMD_PMC_STB_INDEX_DATA, data);
    788	if (err) {
    789		dev_err(dev->dev, "failed to write data in stb: 0x%X\n",
    790			AMD_PMC_STB_INDEX_DATA);
    791		return pcibios_err_to_errno(err);
    792	}
    793
    794	return 0;
    795}
    796#endif
    797
    798static int amd_pmc_read_stb(struct amd_pmc_dev *dev, u32 *buf)
    799{
    800	int i, err;
    801
    802	err = pci_write_config_dword(dev->rdev, AMD_PMC_STB_INDEX_ADDRESS, AMD_PMC_STB_PMI_0);
    803	if (err) {
    804		dev_err(dev->dev, "error writing addr to stb: 0x%X\n",
    805			AMD_PMC_STB_INDEX_ADDRESS);
    806		return pcibios_err_to_errno(err);
    807	}
    808
    809	for (i = 0; i < FIFO_SIZE; i++) {
    810		err = pci_read_config_dword(dev->rdev, AMD_PMC_STB_INDEX_DATA, buf++);
    811		if (err) {
    812			dev_err(dev->dev, "error reading data from stb: 0x%X\n",
    813				AMD_PMC_STB_INDEX_DATA);
    814			return pcibios_err_to_errno(err);
    815		}
    816	}
    817
    818	return 0;
    819}
    820
    821static int amd_pmc_probe(struct platform_device *pdev)
    822{
    823	struct amd_pmc_dev *dev = &pmc;
    824	struct pci_dev *rdev;
    825	u32 base_addr_lo, base_addr_hi;
    826	u64 base_addr;
    827	int err;
    828	u32 val;
    829
    830	dev->dev = &pdev->dev;
    831
    832	rdev = pci_get_domain_bus_and_slot(0, 0, PCI_DEVFN(0, 0));
    833	if (!rdev || !pci_match_id(pmc_pci_ids, rdev)) {
    834		err = -ENODEV;
    835		goto err_pci_dev_put;
    836	}
    837
    838	dev->cpu_id = rdev->device;
    839	dev->rdev = rdev;
    840	err = pci_write_config_dword(rdev, AMD_PMC_SMU_INDEX_ADDRESS, AMD_PMC_BASE_ADDR_LO);
    841	if (err) {
    842		dev_err(dev->dev, "error writing to 0x%x\n", AMD_PMC_SMU_INDEX_ADDRESS);
    843		err = pcibios_err_to_errno(err);
    844		goto err_pci_dev_put;
    845	}
    846
    847	err = pci_read_config_dword(rdev, AMD_PMC_SMU_INDEX_DATA, &val);
    848	if (err) {
    849		err = pcibios_err_to_errno(err);
    850		goto err_pci_dev_put;
    851	}
    852
    853	base_addr_lo = val & AMD_PMC_BASE_ADDR_HI_MASK;
    854
    855	err = pci_write_config_dword(rdev, AMD_PMC_SMU_INDEX_ADDRESS, AMD_PMC_BASE_ADDR_HI);
    856	if (err) {
    857		dev_err(dev->dev, "error writing to 0x%x\n", AMD_PMC_SMU_INDEX_ADDRESS);
    858		err = pcibios_err_to_errno(err);
    859		goto err_pci_dev_put;
    860	}
    861
    862	err = pci_read_config_dword(rdev, AMD_PMC_SMU_INDEX_DATA, &val);
    863	if (err) {
    864		err = pcibios_err_to_errno(err);
    865		goto err_pci_dev_put;
    866	}
    867
    868	base_addr_hi = val & AMD_PMC_BASE_ADDR_LO_MASK;
    869	base_addr = ((u64)base_addr_hi << 32 | base_addr_lo);
    870
    871	dev->regbase = devm_ioremap(dev->dev, base_addr + AMD_PMC_BASE_ADDR_OFFSET,
    872				    AMD_PMC_MAPPING_SIZE);
    873	if (!dev->regbase) {
    874		err = -ENOMEM;
    875		goto err_pci_dev_put;
    876	}
    877
    878	mutex_init(&dev->lock);
    879
    880	if (enable_stb && dev->cpu_id == AMD_CPU_ID_YC) {
    881		err = amd_pmc_s2d_init(dev);
    882		if (err)
    883			return err;
    884	}
    885
    886	platform_set_drvdata(pdev, dev);
    887#ifdef CONFIG_SUSPEND
    888	err = acpi_register_lps0_dev(&amd_pmc_s2idle_dev_ops);
    889	if (err)
    890		dev_warn(dev->dev, "failed to register LPS0 sleep handler, expect increased power consumption\n");
    891#endif
    892
    893	amd_pmc_dbgfs_register(dev);
    894	return 0;
    895
    896err_pci_dev_put:
    897	pci_dev_put(rdev);
    898	return err;
    899}
    900
    901static int amd_pmc_remove(struct platform_device *pdev)
    902{
    903	struct amd_pmc_dev *dev = platform_get_drvdata(pdev);
    904
    905#ifdef CONFIG_SUSPEND
    906	acpi_unregister_lps0_dev(&amd_pmc_s2idle_dev_ops);
    907#endif
    908	amd_pmc_dbgfs_unregister(dev);
    909	pci_dev_put(dev->rdev);
    910	mutex_destroy(&dev->lock);
    911	return 0;
    912}
    913
    914static const struct acpi_device_id amd_pmc_acpi_ids[] = {
    915	{"AMDI0005", 0},
    916	{"AMDI0006", 0},
    917	{"AMDI0007", 0},
    918	{"AMD0004", 0},
    919	{"AMD0005", 0},
    920	{ }
    921};
    922MODULE_DEVICE_TABLE(acpi, amd_pmc_acpi_ids);
    923
    924static struct platform_driver amd_pmc_driver = {
    925	.driver = {
    926		.name = "amd_pmc",
    927		.acpi_match_table = amd_pmc_acpi_ids,
    928	},
    929	.probe = amd_pmc_probe,
    930	.remove = amd_pmc_remove,
    931};
    932module_platform_driver(amd_pmc_driver);
    933
    934MODULE_LICENSE("GPL v2");
    935MODULE_DESCRIPTION("AMD PMC Driver");