1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* 3 * AMD Platform Management Framework Driver 4 * 5 * Copyright (c) 2022, Advanced Micro Devices, Inc. 6 * All Rights Reserved. 7 * 8 * Author: Shyam Sundar S K <Shyam-sundar.S-k@amd.com> 9 */ 10 11 #include <linux/debugfs.h> 12 #include <linux/iopoll.h> 13 #include <linux/module.h> 14 #include <linux/pci.h> 15 #include <linux/platform_device.h> 16 #include <linux/power_supply.h> 17 #include "pmf.h" 18 19 /* PMF-SMU communication registers */ 20 #define AMD_PMF_REGISTER_MESSAGE 0xA18 21 #define AMD_PMF_REGISTER_RESPONSE 0xA78 22 #define AMD_PMF_REGISTER_ARGUMENT 0xA58 23 24 /* Base address of SMU for mapping physical address to virtual address */ 25 #define AMD_PMF_SMU_INDEX_ADDRESS 0xB8 26 #define AMD_PMF_SMU_INDEX_DATA 0xBC 27 #define AMD_PMF_MAPPING_SIZE 0x01000 28 #define AMD_PMF_BASE_ADDR_OFFSET 0x10000 29 #define AMD_PMF_BASE_ADDR_LO 0x13B102E8 30 #define AMD_PMF_BASE_ADDR_HI 0x13B102EC 31 #define AMD_PMF_BASE_ADDR_LO_MASK GENMASK(15, 0) 32 #define AMD_PMF_BASE_ADDR_HI_MASK GENMASK(31, 20) 33 34 /* SMU Response Codes */ 35 #define AMD_PMF_RESULT_OK 0x01 36 #define AMD_PMF_RESULT_CMD_REJECT_BUSY 0xFC 37 #define AMD_PMF_RESULT_CMD_REJECT_PREREQ 0xFD 38 #define AMD_PMF_RESULT_CMD_UNKNOWN 0xFE 39 #define AMD_PMF_RESULT_FAILED 0xFF 40 41 /* List of supported CPU ids */ 42 #define AMD_CPU_ID_RMB 0x14b5 43 #define AMD_CPU_ID_PS 0x14e8 44 45 #define PMF_MSG_DELAY_MIN_US 50 46 #define RESPONSE_REGISTER_LOOP_MAX 20000 47 48 #define DELAY_MIN_US 2000 49 #define DELAY_MAX_US 3000 50 51 /* override Metrics Table sample size time (in ms) */ 52 static int metrics_table_loop_ms = 1000; 53 module_param(metrics_table_loop_ms, int, 0644); 54 MODULE_PARM_DESC(metrics_table_loop_ms, "Metrics Table sample size time (default = 1000ms)"); 55 56 /* Force load on supported older platforms */ 57 static bool force_load; 58 module_param(force_load, bool, 0444); 59 MODULE_PARM_DESC(force_load, "Force load this driver on supported older platforms (experimental)"); 60 61 static int current_power_limits_show(struct seq_file *seq, void *unused) 62 { 63 struct amd_pmf_dev *dev = seq->private; 64 struct amd_pmf_static_slider_granular table; 65 int mode, src = 0; 66 67 mode = amd_pmf_get_pprof_modes(dev); 68 if (mode < 0) 69 return mode; 70 71 src = amd_pmf_get_power_source(); 72 amd_pmf_update_slider(dev, SLIDER_OP_GET, mode, &table); 73 seq_printf(seq, "spl:%u fppt:%u sppt:%u sppt_apu_only:%u stt_min:%u stt[APU]:%u stt[HS2]: %u\n", 74 table.prop[src][mode].spl, 75 table.prop[src][mode].fppt, 76 table.prop[src][mode].sppt, 77 table.prop[src][mode].sppt_apu_only, 78 table.prop[src][mode].stt_min, 79 table.prop[src][mode].stt_skin_temp[STT_TEMP_APU], 80 table.prop[src][mode].stt_skin_temp[STT_TEMP_HS2]); 81 return 0; 82 } 83 DEFINE_SHOW_ATTRIBUTE(current_power_limits); 84 85 static void amd_pmf_dbgfs_unregister(struct amd_pmf_dev *dev) 86 { 87 debugfs_remove_recursive(dev->dbgfs_dir); 88 } 89 90 static void amd_pmf_dbgfs_register(struct amd_pmf_dev *dev) 91 { 92 dev->dbgfs_dir = debugfs_create_dir("amd_pmf", NULL); 93 debugfs_create_file("current_power_limits", 0644, dev->dbgfs_dir, dev, 94 ¤t_power_limits_fops); 95 } 96 97 int amd_pmf_get_power_source(void) 98 { 99 if (power_supply_is_system_supplied() > 0) 100 return POWER_SOURCE_AC; 101 else 102 return POWER_SOURCE_DC; 103 } 104 105 static void amd_pmf_get_metrics(struct work_struct *work) 106 { 107 struct amd_pmf_dev *dev = container_of(work, struct amd_pmf_dev, work_buffer.work); 108 ktime_t time_elapsed_ms; 109 int socket_power; 110 111 mutex_lock(&dev->update_mutex); 112 /* Transfer table contents */ 113 memset(dev->buf, 0, sizeof(dev->m_table)); 114 amd_pmf_send_cmd(dev, SET_TRANSFER_TABLE, 0, 7, NULL); 115 memcpy(&dev->m_table, dev->buf, sizeof(dev->m_table)); 116 117 time_elapsed_ms = ktime_to_ms(ktime_get()) - dev->start_time; 118 /* Calculate the avg SoC power consumption */ 119 socket_power = dev->m_table.apu_power + dev->m_table.dgpu_power; 120 121 if (dev->amt_enabled) { 122 /* Apply the Auto Mode transition */ 123 amd_pmf_trans_automode(dev, socket_power, time_elapsed_ms); 124 } 125 126 if (dev->cnqf_enabled) { 127 /* Apply the CnQF transition */ 128 amd_pmf_trans_cnqf(dev, socket_power, time_elapsed_ms); 129 } 130 131 dev->start_time = ktime_to_ms(ktime_get()); 132 schedule_delayed_work(&dev->work_buffer, msecs_to_jiffies(metrics_table_loop_ms)); 133 mutex_unlock(&dev->update_mutex); 134 } 135 136 static inline u32 amd_pmf_reg_read(struct amd_pmf_dev *dev, int reg_offset) 137 { 138 return ioread32(dev->regbase + reg_offset); 139 } 140 141 static inline void amd_pmf_reg_write(struct amd_pmf_dev *dev, int reg_offset, u32 val) 142 { 143 iowrite32(val, dev->regbase + reg_offset); 144 } 145 146 static void __maybe_unused amd_pmf_dump_registers(struct amd_pmf_dev *dev) 147 { 148 u32 value; 149 150 value = amd_pmf_reg_read(dev, AMD_PMF_REGISTER_RESPONSE); 151 dev_dbg(dev->dev, "AMD_PMF_REGISTER_RESPONSE:%x\n", value); 152 153 value = amd_pmf_reg_read(dev, AMD_PMF_REGISTER_ARGUMENT); 154 dev_dbg(dev->dev, "AMD_PMF_REGISTER_ARGUMENT:%d\n", value); 155 156 value = amd_pmf_reg_read(dev, AMD_PMF_REGISTER_MESSAGE); 157 dev_dbg(dev->dev, "AMD_PMF_REGISTER_MESSAGE:%x\n", value); 158 } 159 160 int amd_pmf_send_cmd(struct amd_pmf_dev *dev, u8 message, bool get, u32 arg, u32 *data) 161 { 162 int rc; 163 u32 val; 164 165 mutex_lock(&dev->lock); 166 167 /* Wait until we get a valid response */ 168 rc = readx_poll_timeout(ioread32, dev->regbase + AMD_PMF_REGISTER_RESPONSE, 169 val, val != 0, PMF_MSG_DELAY_MIN_US, 170 PMF_MSG_DELAY_MIN_US * RESPONSE_REGISTER_LOOP_MAX); 171 if (rc) { 172 dev_err(dev->dev, "failed to talk to SMU\n"); 173 goto out_unlock; 174 } 175 176 /* Write zero to response register */ 177 amd_pmf_reg_write(dev, AMD_PMF_REGISTER_RESPONSE, 0); 178 179 /* Write argument into argument register */ 180 amd_pmf_reg_write(dev, AMD_PMF_REGISTER_ARGUMENT, arg); 181 182 /* Write message ID to message ID register */ 183 amd_pmf_reg_write(dev, AMD_PMF_REGISTER_MESSAGE, message); 184 185 /* Wait until we get a valid response */ 186 rc = readx_poll_timeout(ioread32, dev->regbase + AMD_PMF_REGISTER_RESPONSE, 187 val, val != 0, PMF_MSG_DELAY_MIN_US, 188 PMF_MSG_DELAY_MIN_US * RESPONSE_REGISTER_LOOP_MAX); 189 if (rc) { 190 dev_err(dev->dev, "SMU response timed out\n"); 191 goto out_unlock; 192 } 193 194 switch (val) { 195 case AMD_PMF_RESULT_OK: 196 if (get) { 197 /* PMFW may take longer time to return back the data */ 198 usleep_range(DELAY_MIN_US, 10 * DELAY_MAX_US); 199 *data = amd_pmf_reg_read(dev, AMD_PMF_REGISTER_ARGUMENT); 200 } 201 break; 202 case AMD_PMF_RESULT_CMD_REJECT_BUSY: 203 dev_err(dev->dev, "SMU not ready. err: 0x%x\n", val); 204 rc = -EBUSY; 205 goto out_unlock; 206 case AMD_PMF_RESULT_CMD_UNKNOWN: 207 dev_err(dev->dev, "SMU cmd unknown. err: 0x%x\n", val); 208 rc = -EINVAL; 209 goto out_unlock; 210 case AMD_PMF_RESULT_CMD_REJECT_PREREQ: 211 case AMD_PMF_RESULT_FAILED: 212 default: 213 dev_err(dev->dev, "SMU cmd failed. err: 0x%x\n", val); 214 rc = -EIO; 215 goto out_unlock; 216 } 217 218 out_unlock: 219 mutex_unlock(&dev->lock); 220 amd_pmf_dump_registers(dev); 221 return rc; 222 } 223 224 static const struct pci_device_id pmf_pci_ids[] = { 225 { PCI_DEVICE(PCI_VENDOR_ID_AMD, AMD_CPU_ID_RMB) }, 226 { PCI_DEVICE(PCI_VENDOR_ID_AMD, AMD_CPU_ID_PS) }, 227 { } 228 }; 229 230 int amd_pmf_init_metrics_table(struct amd_pmf_dev *dev) 231 { 232 u64 phys_addr; 233 u32 hi, low; 234 235 INIT_DELAYED_WORK(&dev->work_buffer, amd_pmf_get_metrics); 236 237 /* Get Metrics Table Address */ 238 dev->buf = kzalloc(sizeof(dev->m_table), GFP_KERNEL); 239 if (!dev->buf) 240 return -ENOMEM; 241 242 phys_addr = virt_to_phys(dev->buf); 243 hi = phys_addr >> 32; 244 low = phys_addr & GENMASK(31, 0); 245 246 amd_pmf_send_cmd(dev, SET_DRAM_ADDR_HIGH, 0, hi, NULL); 247 amd_pmf_send_cmd(dev, SET_DRAM_ADDR_LOW, 0, low, NULL); 248 249 /* 250 * Start collecting the metrics data after a small delay 251 * or else, we might end up getting stale values from PMFW. 252 */ 253 schedule_delayed_work(&dev->work_buffer, msecs_to_jiffies(metrics_table_loop_ms * 3)); 254 255 return 0; 256 } 257 258 static void amd_pmf_init_features(struct amd_pmf_dev *dev) 259 { 260 int ret; 261 262 /* Enable Static Slider */ 263 if (is_apmf_func_supported(dev, APMF_FUNC_STATIC_SLIDER_GRANULAR)) { 264 amd_pmf_init_sps(dev); 265 dev_dbg(dev->dev, "SPS enabled and Platform Profiles registered\n"); 266 } 267 268 /* Enable Auto Mode */ 269 if (is_apmf_func_supported(dev, APMF_FUNC_AUTO_MODE)) { 270 amd_pmf_init_auto_mode(dev); 271 dev_dbg(dev->dev, "Auto Mode Init done\n"); 272 } else if (is_apmf_func_supported(dev, APMF_FUNC_DYN_SLIDER_AC) || 273 is_apmf_func_supported(dev, APMF_FUNC_DYN_SLIDER_DC)) { 274 /* Enable Cool n Quiet Framework (CnQF) */ 275 ret = amd_pmf_init_cnqf(dev); 276 if (ret) 277 dev_warn(dev->dev, "CnQF Init failed\n"); 278 } 279 } 280 281 static void amd_pmf_deinit_features(struct amd_pmf_dev *dev) 282 { 283 if (is_apmf_func_supported(dev, APMF_FUNC_STATIC_SLIDER_GRANULAR)) 284 amd_pmf_deinit_sps(dev); 285 286 if (is_apmf_func_supported(dev, APMF_FUNC_AUTO_MODE)) { 287 amd_pmf_deinit_auto_mode(dev); 288 } else if (is_apmf_func_supported(dev, APMF_FUNC_DYN_SLIDER_AC) || 289 is_apmf_func_supported(dev, APMF_FUNC_DYN_SLIDER_DC)) { 290 amd_pmf_deinit_cnqf(dev); 291 } 292 } 293 294 static const struct acpi_device_id amd_pmf_acpi_ids[] = { 295 {"AMDI0100", 0x100}, 296 {"AMDI0102", 0}, 297 { } 298 }; 299 MODULE_DEVICE_TABLE(acpi, amd_pmf_acpi_ids); 300 301 static int amd_pmf_probe(struct platform_device *pdev) 302 { 303 const struct acpi_device_id *id; 304 struct amd_pmf_dev *dev; 305 struct pci_dev *rdev; 306 u32 base_addr_lo; 307 u32 base_addr_hi; 308 u64 base_addr; 309 u32 val; 310 int err; 311 312 id = acpi_match_device(amd_pmf_acpi_ids, &pdev->dev); 313 if (!id) 314 return -ENODEV; 315 316 if (id->driver_data == 0x100 && !force_load) 317 return -ENODEV; 318 319 dev = devm_kzalloc(&pdev->dev, sizeof(*dev), GFP_KERNEL); 320 if (!dev) 321 return -ENOMEM; 322 323 dev->dev = &pdev->dev; 324 325 rdev = pci_get_domain_bus_and_slot(0, 0, PCI_DEVFN(0, 0)); 326 if (!rdev || !pci_match_id(pmf_pci_ids, rdev)) { 327 pci_dev_put(rdev); 328 return -ENODEV; 329 } 330 331 dev->cpu_id = rdev->device; 332 err = pci_write_config_dword(rdev, AMD_PMF_SMU_INDEX_ADDRESS, AMD_PMF_BASE_ADDR_LO); 333 if (err) { 334 dev_err(dev->dev, "error writing to 0x%x\n", AMD_PMF_SMU_INDEX_ADDRESS); 335 pci_dev_put(rdev); 336 return pcibios_err_to_errno(err); 337 } 338 339 err = pci_read_config_dword(rdev, AMD_PMF_SMU_INDEX_DATA, &val); 340 if (err) { 341 pci_dev_put(rdev); 342 return pcibios_err_to_errno(err); 343 } 344 345 base_addr_lo = val & AMD_PMF_BASE_ADDR_HI_MASK; 346 347 err = pci_write_config_dword(rdev, AMD_PMF_SMU_INDEX_ADDRESS, AMD_PMF_BASE_ADDR_HI); 348 if (err) { 349 dev_err(dev->dev, "error writing to 0x%x\n", AMD_PMF_SMU_INDEX_ADDRESS); 350 pci_dev_put(rdev); 351 return pcibios_err_to_errno(err); 352 } 353 354 err = pci_read_config_dword(rdev, AMD_PMF_SMU_INDEX_DATA, &val); 355 if (err) { 356 pci_dev_put(rdev); 357 return pcibios_err_to_errno(err); 358 } 359 360 base_addr_hi = val & AMD_PMF_BASE_ADDR_LO_MASK; 361 pci_dev_put(rdev); 362 base_addr = ((u64)base_addr_hi << 32 | base_addr_lo); 363 364 dev->regbase = devm_ioremap(dev->dev, base_addr + AMD_PMF_BASE_ADDR_OFFSET, 365 AMD_PMF_MAPPING_SIZE); 366 if (!dev->regbase) 367 return -ENOMEM; 368 369 apmf_acpi_init(dev); 370 platform_set_drvdata(pdev, dev); 371 amd_pmf_init_features(dev); 372 apmf_install_handler(dev); 373 amd_pmf_dbgfs_register(dev); 374 375 mutex_init(&dev->lock); 376 mutex_init(&dev->update_mutex); 377 dev_info(dev->dev, "registered PMF device successfully\n"); 378 379 return 0; 380 } 381 382 static int amd_pmf_remove(struct platform_device *pdev) 383 { 384 struct amd_pmf_dev *dev = platform_get_drvdata(pdev); 385 386 mutex_destroy(&dev->lock); 387 mutex_destroy(&dev->update_mutex); 388 amd_pmf_deinit_features(dev); 389 apmf_acpi_deinit(dev); 390 amd_pmf_dbgfs_unregister(dev); 391 kfree(dev->buf); 392 return 0; 393 } 394 395 static const struct attribute_group *amd_pmf_driver_groups[] = { 396 &cnqf_feature_attribute_group, 397 NULL, 398 }; 399 400 static struct platform_driver amd_pmf_driver = { 401 .driver = { 402 .name = "amd-pmf", 403 .acpi_match_table = amd_pmf_acpi_ids, 404 .dev_groups = amd_pmf_driver_groups, 405 }, 406 .probe = amd_pmf_probe, 407 .remove = amd_pmf_remove, 408 }; 409 module_platform_driver(amd_pmf_driver); 410 411 MODULE_LICENSE("GPL"); 412 MODULE_DESCRIPTION("AMD Platform Management Framework Driver"); 413