0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
0012
0013 #include <linux/acpi.h>
0014 #include <linux/bitfield.h>
0015 #include <linux/bits.h>
0016 #include <linux/debugfs.h>
0017 #include <linux/delay.h>
0018 #include <linux/io.h>
0019 #include <linux/iopoll.h>
0020 #include <linux/limits.h>
0021 #include <linux/module.h>
0022 #include <linux/pci.h>
0023 #include <linux/platform_device.h>
0024 #include <linux/rtc.h>
0025 #include <linux/suspend.h>
0026 #include <linux/seq_file.h>
0027 #include <linux/uaccess.h>
0028
0029
0030 #define AMD_PMC_REGISTER_MESSAGE 0x538
0031 #define AMD_PMC_REGISTER_RESPONSE 0x980
0032 #define AMD_PMC_REGISTER_ARGUMENT 0x9BC
0033
0034
0035 #define AMD_PMC_SCRATCH_REG_CZN 0x94
0036 #define AMD_PMC_SCRATCH_REG_YC 0xD14
0037
0038
0039 #define AMD_PMC_STB_INDEX_ADDRESS 0xF8
0040 #define AMD_PMC_STB_INDEX_DATA 0xFC
0041 #define AMD_PMC_STB_PMI_0 0x03E30600
0042 #define AMD_PMC_STB_PREDEF 0xC6000001
0043
0044
0045 #define STB_SPILL_TO_DRAM 0xBE
0046 #define AMD_S2D_REGISTER_MESSAGE 0xA20
0047 #define AMD_S2D_REGISTER_RESPONSE 0xA80
0048 #define AMD_S2D_REGISTER_ARGUMENT 0xA88
0049
0050
0051 #define S2D_TELEMETRY_BYTES_MAX 0x100000
0052 #define S2D_TELEMETRY_DRAMBYTES_MAX 0x1000000
0053
0054
0055 #define AMD_PMC_SMU_INDEX_ADDRESS 0xB8
0056 #define AMD_PMC_SMU_INDEX_DATA 0xBC
0057 #define AMD_PMC_MAPPING_SIZE 0x01000
0058 #define AMD_PMC_BASE_ADDR_OFFSET 0x10000
0059 #define AMD_PMC_BASE_ADDR_LO 0x13B102E8
0060 #define AMD_PMC_BASE_ADDR_HI 0x13B102EC
0061 #define AMD_PMC_BASE_ADDR_LO_MASK GENMASK(15, 0)
0062 #define AMD_PMC_BASE_ADDR_HI_MASK GENMASK(31, 20)
0063
0064
0065 #define AMD_PMC_RESULT_OK 0x01
0066 #define AMD_PMC_RESULT_CMD_REJECT_BUSY 0xFC
0067 #define AMD_PMC_RESULT_CMD_REJECT_PREREQ 0xFD
0068 #define AMD_PMC_RESULT_CMD_UNKNOWN 0xFE
0069 #define AMD_PMC_RESULT_FAILED 0xFF
0070
0071
0072 #define FCH_S0I3_ENTRY_TIME_L_OFFSET 0x30
0073 #define FCH_S0I3_ENTRY_TIME_H_OFFSET 0x34
0074 #define FCH_S0I3_EXIT_TIME_L_OFFSET 0x38
0075 #define FCH_S0I3_EXIT_TIME_H_OFFSET 0x3C
0076 #define FCH_SSC_MAPPING_SIZE 0x800
0077 #define FCH_BASE_PHY_ADDR_LOW 0xFED81100
0078 #define FCH_BASE_PHY_ADDR_HIGH 0x00000000
0079
0080
0081 #define SMU_MSG_GETSMUVERSION 0x02
0082 #define SMU_MSG_LOG_GETDRAM_ADDR_HI 0x04
0083 #define SMU_MSG_LOG_GETDRAM_ADDR_LO 0x05
0084 #define SMU_MSG_LOG_START 0x06
0085 #define SMU_MSG_LOG_RESET 0x07
0086 #define SMU_MSG_LOG_DUMP_DATA 0x08
0087 #define SMU_MSG_GET_SUP_CONSTRAINTS 0x09
0088
0089 #define AMD_CPU_ID_RV 0x15D0
0090 #define AMD_CPU_ID_RN 0x1630
0091 #define AMD_CPU_ID_PCO AMD_CPU_ID_RV
0092 #define AMD_CPU_ID_CZN AMD_CPU_ID_RN
0093 #define AMD_CPU_ID_YC 0x14B5
0094 #define AMD_CPU_ID_CB 0x14D8
0095 #define AMD_CPU_ID_PS 0x14E8
0096
0097 #define PMC_MSG_DELAY_MIN_US 50
0098 #define RESPONSE_REGISTER_LOOP_MAX 20000
0099
0100 #define SOC_SUBSYSTEM_IP_MAX 12
0101 #define DELAY_MIN_US 2000
0102 #define DELAY_MAX_US 3000
0103 #define FIFO_SIZE 4096
0104 enum amd_pmc_def {
0105 MSG_TEST = 0x01,
0106 MSG_OS_HINT_PCO,
0107 MSG_OS_HINT_RN,
0108 };
0109
0110 enum s2d_arg {
0111 S2D_TELEMETRY_SIZE = 0x01,
0112 S2D_PHYS_ADDR_LOW,
0113 S2D_PHYS_ADDR_HIGH,
0114 };
0115
0116 struct amd_pmc_bit_map {
0117 const char *name;
0118 u32 bit_mask;
0119 };
0120
0121 static const struct amd_pmc_bit_map soc15_ip_blk[] = {
0122 {"DISPLAY", BIT(0)},
0123 {"CPU", BIT(1)},
0124 {"GFX", BIT(2)},
0125 {"VDD", BIT(3)},
0126 {"ACP", BIT(4)},
0127 {"VCN", BIT(5)},
0128 {"ISP", BIT(6)},
0129 {"NBIO", BIT(7)},
0130 {"DF", BIT(8)},
0131 {"USB0", BIT(9)},
0132 {"USB1", BIT(10)},
0133 {"LAPIC", BIT(11)},
0134 {}
0135 };
0136
0137 struct amd_pmc_dev {
0138 void __iomem *regbase;
0139 void __iomem *smu_virt_addr;
0140 void __iomem *stb_virt_addr;
0141 void __iomem *fch_virt_addr;
0142 bool msg_port;
0143 u32 base_addr;
0144 u32 cpu_id;
0145 u32 active_ips;
0146
0147 u8 smu_program;
0148 u8 major;
0149 u8 minor;
0150 u8 rev;
0151 struct device *dev;
0152 struct pci_dev *rdev;
0153 struct mutex lock;
0154 #if IS_ENABLED(CONFIG_DEBUG_FS)
0155 struct dentry *dbgfs_dir;
0156 #endif
0157 };
0158
0159 static bool enable_stb;
0160 module_param(enable_stb, bool, 0644);
0161 MODULE_PARM_DESC(enable_stb, "Enable the STB debug mechanism");
0162
0163 static struct amd_pmc_dev pmc;
0164 static int amd_pmc_send_cmd(struct amd_pmc_dev *dev, u32 arg, u32 *data, u8 msg, bool ret);
0165 static int amd_pmc_read_stb(struct amd_pmc_dev *dev, u32 *buf);
0166 #ifdef CONFIG_SUSPEND
0167 static int amd_pmc_write_stb(struct amd_pmc_dev *dev, u32 data);
0168 #endif
0169
0170 static inline u32 amd_pmc_reg_read(struct amd_pmc_dev *dev, int reg_offset)
0171 {
0172 return ioread32(dev->regbase + reg_offset);
0173 }
0174
0175 static inline void amd_pmc_reg_write(struct amd_pmc_dev *dev, int reg_offset, u32 val)
0176 {
0177 iowrite32(val, dev->regbase + reg_offset);
0178 }
0179
0180 struct smu_metrics {
0181 u32 table_version;
0182 u32 hint_count;
0183 u32 s0i3_last_entry_status;
0184 u32 timein_s0i2;
0185 u64 timeentering_s0i3_lastcapture;
0186 u64 timeentering_s0i3_totaltime;
0187 u64 timeto_resume_to_os_lastcapture;
0188 u64 timeto_resume_to_os_totaltime;
0189 u64 timein_s0i3_lastcapture;
0190 u64 timein_s0i3_totaltime;
0191 u64 timein_swdrips_lastcapture;
0192 u64 timein_swdrips_totaltime;
0193 u64 timecondition_notmet_lastcapture[SOC_SUBSYSTEM_IP_MAX];
0194 u64 timecondition_notmet_totaltime[SOC_SUBSYSTEM_IP_MAX];
0195 } __packed;
0196
0197 static int amd_pmc_stb_debugfs_open(struct inode *inode, struct file *filp)
0198 {
0199 struct amd_pmc_dev *dev = filp->f_inode->i_private;
0200 u32 size = FIFO_SIZE * sizeof(u32);
0201 u32 *buf;
0202 int rc;
0203
0204 buf = kzalloc(size, GFP_KERNEL);
0205 if (!buf)
0206 return -ENOMEM;
0207
0208 rc = amd_pmc_read_stb(dev, buf);
0209 if (rc) {
0210 kfree(buf);
0211 return rc;
0212 }
0213
0214 filp->private_data = buf;
0215 return rc;
0216 }
0217
0218 static ssize_t amd_pmc_stb_debugfs_read(struct file *filp, char __user *buf, size_t size,
0219 loff_t *pos)
0220 {
0221 if (!filp->private_data)
0222 return -EINVAL;
0223
0224 return simple_read_from_buffer(buf, size, pos, filp->private_data,
0225 FIFO_SIZE * sizeof(u32));
0226 }
0227
0228 static int amd_pmc_stb_debugfs_release(struct inode *inode, struct file *filp)
0229 {
0230 kfree(filp->private_data);
0231 return 0;
0232 }
0233
0234 static const struct file_operations amd_pmc_stb_debugfs_fops = {
0235 .owner = THIS_MODULE,
0236 .open = amd_pmc_stb_debugfs_open,
0237 .read = amd_pmc_stb_debugfs_read,
0238 .release = amd_pmc_stb_debugfs_release,
0239 };
0240
0241 static int amd_pmc_stb_debugfs_open_v2(struct inode *inode, struct file *filp)
0242 {
0243 struct amd_pmc_dev *dev = filp->f_inode->i_private;
0244 u32 *buf;
0245
0246 buf = kzalloc(S2D_TELEMETRY_BYTES_MAX, GFP_KERNEL);
0247 if (!buf)
0248 return -ENOMEM;
0249
0250 memcpy_fromio(buf, dev->stb_virt_addr, S2D_TELEMETRY_BYTES_MAX);
0251 filp->private_data = buf;
0252
0253 return 0;
0254 }
0255
0256 static ssize_t amd_pmc_stb_debugfs_read_v2(struct file *filp, char __user *buf, size_t size,
0257 loff_t *pos)
0258 {
0259 if (!filp->private_data)
0260 return -EINVAL;
0261
0262 return simple_read_from_buffer(buf, size, pos, filp->private_data,
0263 S2D_TELEMETRY_BYTES_MAX);
0264 }
0265
0266 static int amd_pmc_stb_debugfs_release_v2(struct inode *inode, struct file *filp)
0267 {
0268 kfree(filp->private_data);
0269 return 0;
0270 }
0271
0272 static const struct file_operations amd_pmc_stb_debugfs_fops_v2 = {
0273 .owner = THIS_MODULE,
0274 .open = amd_pmc_stb_debugfs_open_v2,
0275 .read = amd_pmc_stb_debugfs_read_v2,
0276 .release = amd_pmc_stb_debugfs_release_v2,
0277 };
0278
0279 #if defined(CONFIG_SUSPEND) || defined(CONFIG_DEBUG_FS)
0280 static int amd_pmc_setup_smu_logging(struct amd_pmc_dev *dev)
0281 {
0282 if (dev->cpu_id == AMD_CPU_ID_PCO) {
0283 dev_warn_once(dev->dev, "SMU debugging info not supported on this platform\n");
0284 return -EINVAL;
0285 }
0286
0287
0288 if (!dev->active_ips)
0289 amd_pmc_send_cmd(dev, 0, &dev->active_ips, SMU_MSG_GET_SUP_CONSTRAINTS, 1);
0290
0291
0292 if (!dev->smu_virt_addr) {
0293 u32 phys_addr_low, phys_addr_hi;
0294 u64 smu_phys_addr;
0295
0296 amd_pmc_send_cmd(dev, 0, &phys_addr_low, SMU_MSG_LOG_GETDRAM_ADDR_LO, 1);
0297 amd_pmc_send_cmd(dev, 0, &phys_addr_hi, SMU_MSG_LOG_GETDRAM_ADDR_HI, 1);
0298 smu_phys_addr = ((u64)phys_addr_hi << 32 | phys_addr_low);
0299
0300 dev->smu_virt_addr = devm_ioremap(dev->dev, smu_phys_addr,
0301 sizeof(struct smu_metrics));
0302 if (!dev->smu_virt_addr)
0303 return -ENOMEM;
0304 }
0305
0306
0307 amd_pmc_send_cmd(dev, 0, NULL, SMU_MSG_LOG_RESET, 0);
0308 amd_pmc_send_cmd(dev, 0, NULL, SMU_MSG_LOG_START, 0);
0309
0310 return 0;
0311 }
0312
0313 static int amd_pmc_idlemask_read(struct amd_pmc_dev *pdev, struct device *dev,
0314 struct seq_file *s)
0315 {
0316 u32 val;
0317
0318 switch (pdev->cpu_id) {
0319 case AMD_CPU_ID_CZN:
0320 val = amd_pmc_reg_read(pdev, AMD_PMC_SCRATCH_REG_CZN);
0321 break;
0322 case AMD_CPU_ID_YC:
0323 case AMD_CPU_ID_CB:
0324 case AMD_CPU_ID_PS:
0325 val = amd_pmc_reg_read(pdev, AMD_PMC_SCRATCH_REG_YC);
0326 break;
0327 default:
0328 return -EINVAL;
0329 }
0330
0331 if (dev)
0332 dev_dbg(pdev->dev, "SMU idlemask s0i3: 0x%x\n", val);
0333
0334 if (s)
0335 seq_printf(s, "SMU idlemask : 0x%x\n", val);
0336
0337 return 0;
0338 }
0339
0340 static int get_metrics_table(struct amd_pmc_dev *pdev, struct smu_metrics *table)
0341 {
0342 if (!pdev->smu_virt_addr) {
0343 int ret = amd_pmc_setup_smu_logging(pdev);
0344
0345 if (ret)
0346 return ret;
0347 }
0348
0349 if (pdev->cpu_id == AMD_CPU_ID_PCO)
0350 return -ENODEV;
0351 memcpy_fromio(table, pdev->smu_virt_addr, sizeof(struct smu_metrics));
0352 return 0;
0353 }
0354 #endif
0355
0356 #ifdef CONFIG_SUSPEND
0357 static void amd_pmc_validate_deepest(struct amd_pmc_dev *pdev)
0358 {
0359 struct smu_metrics table;
0360
0361 if (get_metrics_table(pdev, &table))
0362 return;
0363
0364 if (!table.s0i3_last_entry_status)
0365 dev_warn(pdev->dev, "Last suspend didn't reach deepest state\n");
0366 else
0367 dev_dbg(pdev->dev, "Last suspend in deepest state for %lluus\n",
0368 table.timein_s0i3_lastcapture);
0369 }
0370 #endif
0371
0372 #ifdef CONFIG_DEBUG_FS
0373 static int smu_fw_info_show(struct seq_file *s, void *unused)
0374 {
0375 struct amd_pmc_dev *dev = s->private;
0376 struct smu_metrics table;
0377 int idx;
0378
0379 if (get_metrics_table(dev, &table))
0380 return -EINVAL;
0381
0382 seq_puts(s, "\n=== SMU Statistics ===\n");
0383 seq_printf(s, "Table Version: %d\n", table.table_version);
0384 seq_printf(s, "Hint Count: %d\n", table.hint_count);
0385 seq_printf(s, "Last S0i3 Status: %s\n", table.s0i3_last_entry_status ? "Success" :
0386 "Unknown/Fail");
0387 seq_printf(s, "Time (in us) to S0i3: %lld\n", table.timeentering_s0i3_lastcapture);
0388 seq_printf(s, "Time (in us) in S0i3: %lld\n", table.timein_s0i3_lastcapture);
0389 seq_printf(s, "Time (in us) to resume from S0i3: %lld\n",
0390 table.timeto_resume_to_os_lastcapture);
0391
0392 seq_puts(s, "\n=== Active time (in us) ===\n");
0393 for (idx = 0 ; idx < SOC_SUBSYSTEM_IP_MAX ; idx++) {
0394 if (soc15_ip_blk[idx].bit_mask & dev->active_ips)
0395 seq_printf(s, "%-8s : %lld\n", soc15_ip_blk[idx].name,
0396 table.timecondition_notmet_lastcapture[idx]);
0397 }
0398
0399 return 0;
0400 }
0401 DEFINE_SHOW_ATTRIBUTE(smu_fw_info);
0402
0403 static int s0ix_stats_show(struct seq_file *s, void *unused)
0404 {
0405 struct amd_pmc_dev *dev = s->private;
0406 u64 entry_time, exit_time, residency;
0407
0408
0409 if (!dev->fch_virt_addr) {
0410 u32 base_addr_lo = FCH_BASE_PHY_ADDR_LOW;
0411 u32 base_addr_hi = FCH_BASE_PHY_ADDR_HIGH;
0412 u64 fch_phys_addr = ((u64)base_addr_hi << 32 | base_addr_lo);
0413
0414 dev->fch_virt_addr = devm_ioremap(dev->dev, fch_phys_addr, FCH_SSC_MAPPING_SIZE);
0415 if (!dev->fch_virt_addr)
0416 return -ENOMEM;
0417 }
0418
0419 entry_time = ioread32(dev->fch_virt_addr + FCH_S0I3_ENTRY_TIME_H_OFFSET);
0420 entry_time = entry_time << 32 | ioread32(dev->fch_virt_addr + FCH_S0I3_ENTRY_TIME_L_OFFSET);
0421
0422 exit_time = ioread32(dev->fch_virt_addr + FCH_S0I3_EXIT_TIME_H_OFFSET);
0423 exit_time = exit_time << 32 | ioread32(dev->fch_virt_addr + FCH_S0I3_EXIT_TIME_L_OFFSET);
0424
0425
0426 residency = exit_time - entry_time;
0427 do_div(residency, 48);
0428
0429 seq_puts(s, "=== S0ix statistics ===\n");
0430 seq_printf(s, "S0ix Entry Time: %lld\n", entry_time);
0431 seq_printf(s, "S0ix Exit Time: %lld\n", exit_time);
0432 seq_printf(s, "Residency Time: %lld\n", residency);
0433
0434 return 0;
0435 }
0436 DEFINE_SHOW_ATTRIBUTE(s0ix_stats);
0437
0438 static int amd_pmc_get_smu_version(struct amd_pmc_dev *dev)
0439 {
0440 int rc;
0441 u32 val;
0442
0443 rc = amd_pmc_send_cmd(dev, 0, &val, SMU_MSG_GETSMUVERSION, 1);
0444 if (rc)
0445 return rc;
0446
0447 dev->smu_program = (val >> 24) & GENMASK(7, 0);
0448 dev->major = (val >> 16) & GENMASK(7, 0);
0449 dev->minor = (val >> 8) & GENMASK(7, 0);
0450 dev->rev = (val >> 0) & GENMASK(7, 0);
0451
0452 dev_dbg(dev->dev, "SMU program %u version is %u.%u.%u\n",
0453 dev->smu_program, dev->major, dev->minor, dev->rev);
0454
0455 return 0;
0456 }
0457
0458 static int amd_pmc_idlemask_show(struct seq_file *s, void *unused)
0459 {
0460 struct amd_pmc_dev *dev = s->private;
0461 int rc;
0462
0463
0464 if (!dev->major) {
0465 rc = amd_pmc_get_smu_version(dev);
0466 if (rc)
0467 return rc;
0468 }
0469
0470 if (dev->major > 56 || (dev->major >= 55 && dev->minor >= 37)) {
0471 rc = amd_pmc_idlemask_read(dev, NULL, s);
0472 if (rc)
0473 return rc;
0474 } else {
0475 seq_puts(s, "Unsupported SMU version for Idlemask\n");
0476 }
0477
0478 return 0;
0479 }
0480 DEFINE_SHOW_ATTRIBUTE(amd_pmc_idlemask);
0481
0482 static void amd_pmc_dbgfs_unregister(struct amd_pmc_dev *dev)
0483 {
0484 debugfs_remove_recursive(dev->dbgfs_dir);
0485 }
0486
0487 static void amd_pmc_dbgfs_register(struct amd_pmc_dev *dev)
0488 {
0489 dev->dbgfs_dir = debugfs_create_dir("amd_pmc", NULL);
0490 debugfs_create_file("smu_fw_info", 0644, dev->dbgfs_dir, dev,
0491 &smu_fw_info_fops);
0492 debugfs_create_file("s0ix_stats", 0644, dev->dbgfs_dir, dev,
0493 &s0ix_stats_fops);
0494 debugfs_create_file("amd_pmc_idlemask", 0644, dev->dbgfs_dir, dev,
0495 &amd_pmc_idlemask_fops);
0496
0497 if (enable_stb) {
0498 if (dev->cpu_id == AMD_CPU_ID_YC || dev->cpu_id == AMD_CPU_ID_CB ||
0499 dev->cpu_id == AMD_CPU_ID_PS)
0500 debugfs_create_file("stb_read", 0644, dev->dbgfs_dir, dev,
0501 &amd_pmc_stb_debugfs_fops_v2);
0502 else
0503 debugfs_create_file("stb_read", 0644, dev->dbgfs_dir, dev,
0504 &amd_pmc_stb_debugfs_fops);
0505 }
0506 }
0507 #else
0508 static inline void amd_pmc_dbgfs_register(struct amd_pmc_dev *dev)
0509 {
0510 }
0511
0512 static inline void amd_pmc_dbgfs_unregister(struct amd_pmc_dev *dev)
0513 {
0514 }
0515 #endif
0516
0517 static void amd_pmc_dump_registers(struct amd_pmc_dev *dev)
0518 {
0519 u32 value, message, argument, response;
0520
0521 if (dev->msg_port) {
0522 message = AMD_S2D_REGISTER_MESSAGE;
0523 argument = AMD_S2D_REGISTER_ARGUMENT;
0524 response = AMD_S2D_REGISTER_RESPONSE;
0525 } else {
0526 message = AMD_PMC_REGISTER_MESSAGE;
0527 argument = AMD_PMC_REGISTER_ARGUMENT;
0528 response = AMD_PMC_REGISTER_RESPONSE;
0529 }
0530
0531 value = amd_pmc_reg_read(dev, response);
0532 dev_dbg(dev->dev, "AMD_PMC_REGISTER_RESPONSE:%x\n", value);
0533
0534 value = amd_pmc_reg_read(dev, argument);
0535 dev_dbg(dev->dev, "AMD_PMC_REGISTER_ARGUMENT:%x\n", value);
0536
0537 value = amd_pmc_reg_read(dev, message);
0538 dev_dbg(dev->dev, "AMD_PMC_REGISTER_MESSAGE:%x\n", value);
0539 }
0540
0541 static int amd_pmc_send_cmd(struct amd_pmc_dev *dev, u32 arg, u32 *data, u8 msg, bool ret)
0542 {
0543 int rc;
0544 u32 val, message, argument, response;
0545
0546 mutex_lock(&dev->lock);
0547
0548 if (dev->msg_port) {
0549 message = AMD_S2D_REGISTER_MESSAGE;
0550 argument = AMD_S2D_REGISTER_ARGUMENT;
0551 response = AMD_S2D_REGISTER_RESPONSE;
0552 } else {
0553 message = AMD_PMC_REGISTER_MESSAGE;
0554 argument = AMD_PMC_REGISTER_ARGUMENT;
0555 response = AMD_PMC_REGISTER_RESPONSE;
0556 }
0557
0558
0559 rc = readx_poll_timeout(ioread32, dev->regbase + response,
0560 val, val != 0, PMC_MSG_DELAY_MIN_US,
0561 PMC_MSG_DELAY_MIN_US * RESPONSE_REGISTER_LOOP_MAX);
0562 if (rc) {
0563 dev_err(dev->dev, "failed to talk to SMU\n");
0564 goto out_unlock;
0565 }
0566
0567
0568 amd_pmc_reg_write(dev, response, 0);
0569
0570
0571 amd_pmc_reg_write(dev, argument, arg);
0572
0573
0574 amd_pmc_reg_write(dev, message, msg);
0575
0576
0577 rc = readx_poll_timeout(ioread32, dev->regbase + response,
0578 val, val != 0, PMC_MSG_DELAY_MIN_US,
0579 PMC_MSG_DELAY_MIN_US * RESPONSE_REGISTER_LOOP_MAX);
0580 if (rc) {
0581 dev_err(dev->dev, "SMU response timed out\n");
0582 goto out_unlock;
0583 }
0584
0585 switch (val) {
0586 case AMD_PMC_RESULT_OK:
0587 if (ret) {
0588
0589 usleep_range(DELAY_MIN_US, 10 * DELAY_MAX_US);
0590 *data = amd_pmc_reg_read(dev, argument);
0591 }
0592 break;
0593 case AMD_PMC_RESULT_CMD_REJECT_BUSY:
0594 dev_err(dev->dev, "SMU not ready. err: 0x%x\n", val);
0595 rc = -EBUSY;
0596 goto out_unlock;
0597 case AMD_PMC_RESULT_CMD_UNKNOWN:
0598 dev_err(dev->dev, "SMU cmd unknown. err: 0x%x\n", val);
0599 rc = -EINVAL;
0600 goto out_unlock;
0601 case AMD_PMC_RESULT_CMD_REJECT_PREREQ:
0602 case AMD_PMC_RESULT_FAILED:
0603 default:
0604 dev_err(dev->dev, "SMU cmd failed. err: 0x%x\n", val);
0605 rc = -EIO;
0606 goto out_unlock;
0607 }
0608
0609 out_unlock:
0610 mutex_unlock(&dev->lock);
0611 amd_pmc_dump_registers(dev);
0612 return rc;
0613 }
0614
0615 #ifdef CONFIG_SUSPEND
0616 static int amd_pmc_get_os_hint(struct amd_pmc_dev *dev)
0617 {
0618 switch (dev->cpu_id) {
0619 case AMD_CPU_ID_PCO:
0620 return MSG_OS_HINT_PCO;
0621 case AMD_CPU_ID_RN:
0622 case AMD_CPU_ID_YC:
0623 case AMD_CPU_ID_CB:
0624 case AMD_CPU_ID_PS:
0625 return MSG_OS_HINT_RN;
0626 }
0627 return -EINVAL;
0628 }
0629
0630 static int amd_pmc_verify_czn_rtc(struct amd_pmc_dev *pdev, u32 *arg)
0631 {
0632 struct rtc_device *rtc_device;
0633 time64_t then, now, duration;
0634 struct rtc_wkalrm alarm;
0635 struct rtc_time tm;
0636 int rc;
0637
0638 if (pdev->major < 64 || (pdev->major == 64 && pdev->minor < 53))
0639 return 0;
0640
0641 rtc_device = rtc_class_open("rtc0");
0642 if (!rtc_device)
0643 return 0;
0644 rc = rtc_read_alarm(rtc_device, &alarm);
0645 if (rc)
0646 return rc;
0647 if (!alarm.enabled) {
0648 dev_dbg(pdev->dev, "alarm not enabled\n");
0649 return 0;
0650 }
0651 rc = rtc_read_time(rtc_device, &tm);
0652 if (rc)
0653 return rc;
0654 then = rtc_tm_to_time64(&alarm.time);
0655 now = rtc_tm_to_time64(&tm);
0656 duration = then-now;
0657
0658
0659 if (then < now)
0660 return 0;
0661
0662
0663
0664
0665 if (duration <= 4 || duration > U16_MAX)
0666 return -EINVAL;
0667
0668 *arg |= (duration << 16);
0669 rc = rtc_alarm_irq_enable(rtc_device, 0);
0670 dev_dbg(pdev->dev, "wakeup timer programmed for %lld seconds\n", duration);
0671
0672 return rc;
0673 }
0674
0675 static void amd_pmc_s2idle_prepare(void)
0676 {
0677 struct amd_pmc_dev *pdev = &pmc;
0678 int rc;
0679 u8 msg;
0680 u32 arg = 1;
0681
0682
0683 amd_pmc_setup_smu_logging(pdev);
0684
0685
0686 if (pdev->cpu_id == AMD_CPU_ID_CZN) {
0687 rc = amd_pmc_verify_czn_rtc(pdev, &arg);
0688 if (rc) {
0689 dev_err(pdev->dev, "failed to set RTC: %d\n", rc);
0690 return;
0691 }
0692 }
0693
0694
0695 amd_pmc_idlemask_read(pdev, pdev->dev, NULL);
0696 msg = amd_pmc_get_os_hint(pdev);
0697 rc = amd_pmc_send_cmd(pdev, arg, NULL, msg, 0);
0698 if (rc) {
0699 dev_err(pdev->dev, "suspend failed: %d\n", rc);
0700 return;
0701 }
0702
0703 if (enable_stb) {
0704 rc = amd_pmc_write_stb(pdev, AMD_PMC_STB_PREDEF);
0705 if (rc)
0706 dev_err(pdev->dev, "error writing to STB: %d\n", rc);
0707 }
0708 }
0709
0710 static void amd_pmc_s2idle_restore(void)
0711 {
0712 struct amd_pmc_dev *pdev = &pmc;
0713 int rc;
0714 u8 msg;
0715
0716 msg = amd_pmc_get_os_hint(pdev);
0717 rc = amd_pmc_send_cmd(pdev, 0, NULL, msg, 0);
0718 if (rc)
0719 dev_err(pdev->dev, "resume failed: %d\n", rc);
0720
0721
0722 amd_pmc_send_cmd(pdev, 0, NULL, SMU_MSG_LOG_DUMP_DATA, 0);
0723
0724
0725 amd_pmc_idlemask_read(pdev, pdev->dev, NULL);
0726
0727
0728 if (enable_stb) {
0729 rc = amd_pmc_write_stb(pdev, AMD_PMC_STB_PREDEF + 1);
0730 if (rc)
0731 dev_err(pdev->dev, "error writing to STB: %d\n", rc);
0732 }
0733
0734
0735 amd_pmc_validate_deepest(pdev);
0736 }
0737
0738 static struct acpi_s2idle_dev_ops amd_pmc_s2idle_dev_ops = {
0739 .prepare = amd_pmc_s2idle_prepare,
0740 .restore = amd_pmc_s2idle_restore,
0741 };
0742 #endif
0743
0744 static const struct pci_device_id pmc_pci_ids[] = {
0745 { PCI_DEVICE(PCI_VENDOR_ID_AMD, AMD_CPU_ID_PS) },
0746 { PCI_DEVICE(PCI_VENDOR_ID_AMD, AMD_CPU_ID_CB) },
0747 { PCI_DEVICE(PCI_VENDOR_ID_AMD, AMD_CPU_ID_YC) },
0748 { PCI_DEVICE(PCI_VENDOR_ID_AMD, AMD_CPU_ID_CZN) },
0749 { PCI_DEVICE(PCI_VENDOR_ID_AMD, AMD_CPU_ID_RN) },
0750 { PCI_DEVICE(PCI_VENDOR_ID_AMD, AMD_CPU_ID_PCO) },
0751 { PCI_DEVICE(PCI_VENDOR_ID_AMD, AMD_CPU_ID_RV) },
0752 { }
0753 };
0754
0755 static int amd_pmc_s2d_init(struct amd_pmc_dev *dev)
0756 {
0757 u32 phys_addr_low, phys_addr_hi;
0758 u64 stb_phys_addr;
0759 u32 size = 0;
0760
0761
0762 dev->msg_port = 1;
0763
0764 amd_pmc_send_cmd(dev, S2D_TELEMETRY_SIZE, &size, STB_SPILL_TO_DRAM, 1);
0765 if (size != S2D_TELEMETRY_BYTES_MAX)
0766 return -EIO;
0767
0768
0769 amd_pmc_send_cmd(dev, S2D_PHYS_ADDR_LOW, &phys_addr_low, STB_SPILL_TO_DRAM, 1);
0770 amd_pmc_send_cmd(dev, S2D_PHYS_ADDR_HIGH, &phys_addr_hi, STB_SPILL_TO_DRAM, 1);
0771
0772 stb_phys_addr = ((u64)phys_addr_hi << 32 | phys_addr_low);
0773
0774
0775 dev->msg_port = 0;
0776
0777 dev->stb_virt_addr = devm_ioremap(dev->dev, stb_phys_addr, S2D_TELEMETRY_DRAMBYTES_MAX);
0778 if (!dev->stb_virt_addr)
0779 return -ENOMEM;
0780
0781 return 0;
0782 }
0783
0784 #ifdef CONFIG_SUSPEND
0785 static int amd_pmc_write_stb(struct amd_pmc_dev *dev, u32 data)
0786 {
0787 int err;
0788
0789 err = pci_write_config_dword(dev->rdev, AMD_PMC_STB_INDEX_ADDRESS, AMD_PMC_STB_PMI_0);
0790 if (err) {
0791 dev_err(dev->dev, "failed to write addr in stb: 0x%X\n",
0792 AMD_PMC_STB_INDEX_ADDRESS);
0793 return pcibios_err_to_errno(err);
0794 }
0795
0796 err = pci_write_config_dword(dev->rdev, AMD_PMC_STB_INDEX_DATA, data);
0797 if (err) {
0798 dev_err(dev->dev, "failed to write data in stb: 0x%X\n",
0799 AMD_PMC_STB_INDEX_DATA);
0800 return pcibios_err_to_errno(err);
0801 }
0802
0803 return 0;
0804 }
0805 #endif
0806
0807 static int amd_pmc_read_stb(struct amd_pmc_dev *dev, u32 *buf)
0808 {
0809 int i, err;
0810
0811 err = pci_write_config_dword(dev->rdev, AMD_PMC_STB_INDEX_ADDRESS, AMD_PMC_STB_PMI_0);
0812 if (err) {
0813 dev_err(dev->dev, "error writing addr to stb: 0x%X\n",
0814 AMD_PMC_STB_INDEX_ADDRESS);
0815 return pcibios_err_to_errno(err);
0816 }
0817
0818 for (i = 0; i < FIFO_SIZE; i++) {
0819 err = pci_read_config_dword(dev->rdev, AMD_PMC_STB_INDEX_DATA, buf++);
0820 if (err) {
0821 dev_err(dev->dev, "error reading data from stb: 0x%X\n",
0822 AMD_PMC_STB_INDEX_DATA);
0823 return pcibios_err_to_errno(err);
0824 }
0825 }
0826
0827 return 0;
0828 }
0829
0830 static int amd_pmc_probe(struct platform_device *pdev)
0831 {
0832 struct amd_pmc_dev *dev = &pmc;
0833 struct pci_dev *rdev;
0834 u32 base_addr_lo, base_addr_hi;
0835 u64 base_addr;
0836 int err;
0837 u32 val;
0838
0839 dev->dev = &pdev->dev;
0840
0841 rdev = pci_get_domain_bus_and_slot(0, 0, PCI_DEVFN(0, 0));
0842 if (!rdev || !pci_match_id(pmc_pci_ids, rdev)) {
0843 err = -ENODEV;
0844 goto err_pci_dev_put;
0845 }
0846
0847 dev->cpu_id = rdev->device;
0848 dev->rdev = rdev;
0849 err = pci_write_config_dword(rdev, AMD_PMC_SMU_INDEX_ADDRESS, AMD_PMC_BASE_ADDR_LO);
0850 if (err) {
0851 dev_err(dev->dev, "error writing to 0x%x\n", AMD_PMC_SMU_INDEX_ADDRESS);
0852 err = pcibios_err_to_errno(err);
0853 goto err_pci_dev_put;
0854 }
0855
0856 err = pci_read_config_dword(rdev, AMD_PMC_SMU_INDEX_DATA, &val);
0857 if (err) {
0858 err = pcibios_err_to_errno(err);
0859 goto err_pci_dev_put;
0860 }
0861
0862 base_addr_lo = val & AMD_PMC_BASE_ADDR_HI_MASK;
0863
0864 err = pci_write_config_dword(rdev, AMD_PMC_SMU_INDEX_ADDRESS, AMD_PMC_BASE_ADDR_HI);
0865 if (err) {
0866 dev_err(dev->dev, "error writing to 0x%x\n", AMD_PMC_SMU_INDEX_ADDRESS);
0867 err = pcibios_err_to_errno(err);
0868 goto err_pci_dev_put;
0869 }
0870
0871 err = pci_read_config_dword(rdev, AMD_PMC_SMU_INDEX_DATA, &val);
0872 if (err) {
0873 err = pcibios_err_to_errno(err);
0874 goto err_pci_dev_put;
0875 }
0876
0877 base_addr_hi = val & AMD_PMC_BASE_ADDR_LO_MASK;
0878 base_addr = ((u64)base_addr_hi << 32 | base_addr_lo);
0879
0880 dev->regbase = devm_ioremap(dev->dev, base_addr + AMD_PMC_BASE_ADDR_OFFSET,
0881 AMD_PMC_MAPPING_SIZE);
0882 if (!dev->regbase) {
0883 err = -ENOMEM;
0884 goto err_pci_dev_put;
0885 }
0886
0887 mutex_init(&dev->lock);
0888
0889 if (enable_stb && (dev->cpu_id == AMD_CPU_ID_YC || dev->cpu_id == AMD_CPU_ID_CB)) {
0890 err = amd_pmc_s2d_init(dev);
0891 if (err)
0892 return err;
0893 }
0894
0895 platform_set_drvdata(pdev, dev);
0896 #ifdef CONFIG_SUSPEND
0897 err = acpi_register_lps0_dev(&amd_pmc_s2idle_dev_ops);
0898 if (err)
0899 dev_warn(dev->dev, "failed to register LPS0 sleep handler, expect increased power consumption\n");
0900 #endif
0901
0902 amd_pmc_dbgfs_register(dev);
0903 return 0;
0904
0905 err_pci_dev_put:
0906 pci_dev_put(rdev);
0907 return err;
0908 }
0909
0910 static int amd_pmc_remove(struct platform_device *pdev)
0911 {
0912 struct amd_pmc_dev *dev = platform_get_drvdata(pdev);
0913
0914 #ifdef CONFIG_SUSPEND
0915 acpi_unregister_lps0_dev(&amd_pmc_s2idle_dev_ops);
0916 #endif
0917 amd_pmc_dbgfs_unregister(dev);
0918 pci_dev_put(dev->rdev);
0919 mutex_destroy(&dev->lock);
0920 return 0;
0921 }
0922
0923 static const struct acpi_device_id amd_pmc_acpi_ids[] = {
0924 {"AMDI0005", 0},
0925 {"AMDI0006", 0},
0926 {"AMDI0007", 0},
0927 {"AMDI0008", 0},
0928 {"AMD0004", 0},
0929 {"AMD0005", 0},
0930 { }
0931 };
0932 MODULE_DEVICE_TABLE(acpi, amd_pmc_acpi_ids);
0933
0934 static struct platform_driver amd_pmc_driver = {
0935 .driver = {
0936 .name = "amd_pmc",
0937 .acpi_match_table = amd_pmc_acpi_ids,
0938 },
0939 .probe = amd_pmc_probe,
0940 .remove = amd_pmc_remove,
0941 };
0942 module_platform_driver(amd_pmc_driver);
0943
0944 MODULE_LICENSE("GPL v2");
0945 MODULE_DESCRIPTION("AMD PMC Driver");