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/iopoll.h> 12 #include <linux/module.h> 13 #include <linux/pci.h> 14 #include <linux/platform_device.h> 15 #include <linux/power_supply.h> 16 #include "pmf.h" 17 18 /* PMF-SMU communication registers */ 19 #define AMD_PMF_REGISTER_MESSAGE 0xA18 20 #define AMD_PMF_REGISTER_RESPONSE 0xA78 21 #define AMD_PMF_REGISTER_ARGUMENT 0xA58 22 23 /* Base address of SMU for mapping physical address to virtual address */ 24 #define AMD_PMF_SMU_INDEX_ADDRESS 0xB8 25 #define AMD_PMF_SMU_INDEX_DATA 0xBC 26 #define AMD_PMF_MAPPING_SIZE 0x01000 27 #define AMD_PMF_BASE_ADDR_OFFSET 0x10000 28 #define AMD_PMF_BASE_ADDR_LO 0x13B102E8 29 #define AMD_PMF_BASE_ADDR_HI 0x13B102EC 30 #define AMD_PMF_BASE_ADDR_LO_MASK GENMASK(15, 0) 31 #define AMD_PMF_BASE_ADDR_HI_MASK GENMASK(31, 20) 32 33 /* SMU Response Codes */ 34 #define AMD_PMF_RESULT_OK 0x01 35 #define AMD_PMF_RESULT_CMD_REJECT_BUSY 0xFC 36 #define AMD_PMF_RESULT_CMD_REJECT_PREREQ 0xFD 37 #define AMD_PMF_RESULT_CMD_UNKNOWN 0xFE 38 #define AMD_PMF_RESULT_FAILED 0xFF 39 40 /* List of supported CPU ids */ 41 #define AMD_CPU_ID_PS 0x14e8 42 43 #define PMF_MSG_DELAY_MIN_US 50 44 #define RESPONSE_REGISTER_LOOP_MAX 20000 45 46 #define DELAY_MIN_US 2000 47 #define DELAY_MAX_US 3000 48 49 int amd_pmf_get_power_source(void) 50 { 51 if (power_supply_is_system_supplied() > 0) 52 return POWER_SOURCE_AC; 53 else 54 return POWER_SOURCE_DC; 55 } 56 57 static inline u32 amd_pmf_reg_read(struct amd_pmf_dev *dev, int reg_offset) 58 { 59 return ioread32(dev->regbase + reg_offset); 60 } 61 62 static inline void amd_pmf_reg_write(struct amd_pmf_dev *dev, int reg_offset, u32 val) 63 { 64 iowrite32(val, dev->regbase + reg_offset); 65 } 66 67 static void __maybe_unused amd_pmf_dump_registers(struct amd_pmf_dev *dev) 68 { 69 u32 value; 70 71 value = amd_pmf_reg_read(dev, AMD_PMF_REGISTER_RESPONSE); 72 dev_dbg(dev->dev, "AMD_PMF_REGISTER_RESPONSE:%x\n", value); 73 74 value = amd_pmf_reg_read(dev, AMD_PMF_REGISTER_ARGUMENT); 75 dev_dbg(dev->dev, "AMD_PMF_REGISTER_ARGUMENT:%d\n", value); 76 77 value = amd_pmf_reg_read(dev, AMD_PMF_REGISTER_MESSAGE); 78 dev_dbg(dev->dev, "AMD_PMF_REGISTER_MESSAGE:%x\n", value); 79 } 80 81 int amd_pmf_send_cmd(struct amd_pmf_dev *dev, u8 message, bool get, u32 arg, u32 *data) 82 { 83 int rc; 84 u32 val; 85 86 mutex_lock(&dev->lock); 87 88 /* Wait until we get a valid response */ 89 rc = readx_poll_timeout(ioread32, dev->regbase + AMD_PMF_REGISTER_RESPONSE, 90 val, val != 0, PMF_MSG_DELAY_MIN_US, 91 PMF_MSG_DELAY_MIN_US * RESPONSE_REGISTER_LOOP_MAX); 92 if (rc) { 93 dev_err(dev->dev, "failed to talk to SMU\n"); 94 goto out_unlock; 95 } 96 97 /* Write zero to response register */ 98 amd_pmf_reg_write(dev, AMD_PMF_REGISTER_RESPONSE, 0); 99 100 /* Write argument into argument register */ 101 amd_pmf_reg_write(dev, AMD_PMF_REGISTER_ARGUMENT, arg); 102 103 /* Write message ID to message ID register */ 104 amd_pmf_reg_write(dev, AMD_PMF_REGISTER_MESSAGE, message); 105 106 /* Wait until we get a valid response */ 107 rc = readx_poll_timeout(ioread32, dev->regbase + AMD_PMF_REGISTER_RESPONSE, 108 val, val != 0, PMF_MSG_DELAY_MIN_US, 109 PMF_MSG_DELAY_MIN_US * RESPONSE_REGISTER_LOOP_MAX); 110 if (rc) { 111 dev_err(dev->dev, "SMU response timed out\n"); 112 goto out_unlock; 113 } 114 115 switch (val) { 116 case AMD_PMF_RESULT_OK: 117 if (get) { 118 /* PMFW may take longer time to return back the data */ 119 usleep_range(DELAY_MIN_US, 10 * DELAY_MAX_US); 120 *data = amd_pmf_reg_read(dev, AMD_PMF_REGISTER_ARGUMENT); 121 } 122 break; 123 case AMD_PMF_RESULT_CMD_REJECT_BUSY: 124 dev_err(dev->dev, "SMU not ready. err: 0x%x\n", val); 125 rc = -EBUSY; 126 goto out_unlock; 127 case AMD_PMF_RESULT_CMD_UNKNOWN: 128 dev_err(dev->dev, "SMU cmd unknown. err: 0x%x\n", val); 129 rc = -EINVAL; 130 goto out_unlock; 131 case AMD_PMF_RESULT_CMD_REJECT_PREREQ: 132 case AMD_PMF_RESULT_FAILED: 133 default: 134 dev_err(dev->dev, "SMU cmd failed. err: 0x%x\n", val); 135 rc = -EIO; 136 goto out_unlock; 137 } 138 139 out_unlock: 140 mutex_unlock(&dev->lock); 141 amd_pmf_dump_registers(dev); 142 return rc; 143 } 144 145 static const struct pci_device_id pmf_pci_ids[] = { 146 { PCI_DEVICE(PCI_VENDOR_ID_AMD, AMD_CPU_ID_PS) }, 147 { } 148 }; 149 150 static void amd_pmf_init_features(struct amd_pmf_dev *dev) 151 { 152 /* Enable Static Slider */ 153 if (is_apmf_func_supported(dev, APMF_FUNC_STATIC_SLIDER_GRANULAR)) { 154 amd_pmf_init_sps(dev); 155 dev_dbg(dev->dev, "SPS enabled and Platform Profiles registered\n"); 156 } 157 } 158 159 static void amd_pmf_deinit_features(struct amd_pmf_dev *dev) 160 { 161 if (is_apmf_func_supported(dev, APMF_FUNC_STATIC_SLIDER_GRANULAR)) 162 amd_pmf_deinit_sps(dev); 163 } 164 165 static const struct acpi_device_id amd_pmf_acpi_ids[] = { 166 {"AMDI0102", 0}, 167 { } 168 }; 169 MODULE_DEVICE_TABLE(acpi, amd_pmf_acpi_ids); 170 171 static int amd_pmf_probe(struct platform_device *pdev) 172 { 173 struct amd_pmf_dev *dev; 174 struct pci_dev *rdev; 175 u32 base_addr_lo; 176 u32 base_addr_hi; 177 u64 base_addr; 178 u32 val; 179 int err; 180 181 dev = devm_kzalloc(&pdev->dev, sizeof(*dev), GFP_KERNEL); 182 if (!dev) 183 return -ENOMEM; 184 185 dev->dev = &pdev->dev; 186 187 rdev = pci_get_domain_bus_and_slot(0, 0, PCI_DEVFN(0, 0)); 188 if (!rdev || !pci_match_id(pmf_pci_ids, rdev)) { 189 pci_dev_put(rdev); 190 return -ENODEV; 191 } 192 193 dev->cpu_id = rdev->device; 194 err = pci_write_config_dword(rdev, AMD_PMF_SMU_INDEX_ADDRESS, AMD_PMF_BASE_ADDR_LO); 195 if (err) { 196 dev_err(dev->dev, "error writing to 0x%x\n", AMD_PMF_SMU_INDEX_ADDRESS); 197 pci_dev_put(rdev); 198 return pcibios_err_to_errno(err); 199 } 200 201 err = pci_read_config_dword(rdev, AMD_PMF_SMU_INDEX_DATA, &val); 202 if (err) { 203 pci_dev_put(rdev); 204 return pcibios_err_to_errno(err); 205 } 206 207 base_addr_lo = val & AMD_PMF_BASE_ADDR_HI_MASK; 208 209 err = pci_write_config_dword(rdev, AMD_PMF_SMU_INDEX_ADDRESS, AMD_PMF_BASE_ADDR_HI); 210 if (err) { 211 dev_err(dev->dev, "error writing to 0x%x\n", AMD_PMF_SMU_INDEX_ADDRESS); 212 pci_dev_put(rdev); 213 return pcibios_err_to_errno(err); 214 } 215 216 err = pci_read_config_dword(rdev, AMD_PMF_SMU_INDEX_DATA, &val); 217 if (err) { 218 pci_dev_put(rdev); 219 return pcibios_err_to_errno(err); 220 } 221 222 base_addr_hi = val & AMD_PMF_BASE_ADDR_LO_MASK; 223 pci_dev_put(rdev); 224 base_addr = ((u64)base_addr_hi << 32 | base_addr_lo); 225 226 dev->regbase = devm_ioremap(dev->dev, base_addr + AMD_PMF_BASE_ADDR_OFFSET, 227 AMD_PMF_MAPPING_SIZE); 228 if (!dev->regbase) 229 return -ENOMEM; 230 231 apmf_acpi_init(dev); 232 platform_set_drvdata(pdev, dev); 233 amd_pmf_init_features(dev); 234 235 mutex_init(&dev->lock); 236 dev_info(dev->dev, "registered PMF device successfully\n"); 237 238 return 0; 239 } 240 241 static int amd_pmf_remove(struct platform_device *pdev) 242 { 243 struct amd_pmf_dev *dev = platform_get_drvdata(pdev); 244 245 mutex_destroy(&dev->lock); 246 amd_pmf_deinit_features(dev); 247 kfree(dev->buf); 248 return 0; 249 } 250 251 static struct platform_driver amd_pmf_driver = { 252 .driver = { 253 .name = "amd-pmf", 254 .acpi_match_table = amd_pmf_acpi_ids, 255 }, 256 .probe = amd_pmf_probe, 257 .remove = amd_pmf_remove, 258 }; 259 module_platform_driver(amd_pmf_driver); 260 261 MODULE_LICENSE("GPL"); 262 MODULE_DESCRIPTION("AMD Platform Management Framework Driver"); 263