1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * Ampere Computing SoC's SMPro Hardware Monitoring Driver 4 * 5 * Copyright (c) 2022, Ampere Computing LLC 6 */ 7 #include <linux/bitfield.h> 8 #include <linux/bitops.h> 9 #include <linux/hwmon.h> 10 #include <linux/hwmon-sysfs.h> 11 #include <linux/kernel.h> 12 #include <linux/mod_devicetable.h> 13 #include <linux/module.h> 14 #include <linux/platform_device.h> 15 #include <linux/property.h> 16 #include <linux/regmap.h> 17 18 /* Logical Power Sensor Registers */ 19 #define SOC_TEMP 0x10 20 #define SOC_VRD_TEMP 0x11 21 #define DIMM_VRD_TEMP 0x12 22 #define CORE_VRD_TEMP 0x13 23 #define CH0_DIMM_TEMP 0x14 24 #define CH1_DIMM_TEMP 0x15 25 #define CH2_DIMM_TEMP 0x16 26 #define CH3_DIMM_TEMP 0x17 27 #define CH4_DIMM_TEMP 0x18 28 #define CH5_DIMM_TEMP 0x19 29 #define CH6_DIMM_TEMP 0x1A 30 #define CH7_DIMM_TEMP 0x1B 31 #define RCA_VRD_TEMP 0x1C 32 33 #define CORE_VRD_PWR 0x20 34 #define SOC_PWR 0x21 35 #define DIMM_VRD1_PWR 0x22 36 #define DIMM_VRD2_PWR 0x23 37 #define CORE_VRD_PWR_MW 0x26 38 #define SOC_PWR_MW 0x27 39 #define DIMM_VRD1_PWR_MW 0x28 40 #define DIMM_VRD2_PWR_MW 0x29 41 #define RCA_VRD_PWR 0x2A 42 #define RCA_VRD_PWR_MW 0x2B 43 44 #define MEM_HOT_THRESHOLD 0x32 45 #define SOC_VR_HOT_THRESHOLD 0x33 46 #define CORE_VRD_VOLT 0x34 47 #define SOC_VRD_VOLT 0x35 48 #define DIMM_VRD1_VOLT 0x36 49 #define DIMM_VRD2_VOLT 0x37 50 #define RCA_VRD_VOLT 0x38 51 52 #define CORE_VRD_CURR 0x39 53 #define SOC_VRD_CURR 0x3A 54 #define DIMM_VRD1_CURR 0x3B 55 #define DIMM_VRD2_CURR 0x3C 56 #define RCA_VRD_CURR 0x3D 57 58 struct smpro_hwmon { 59 struct regmap *regmap; 60 }; 61 62 struct smpro_sensor { 63 const u8 reg; 64 const u8 reg_ext; 65 const char *label; 66 }; 67 68 static const struct smpro_sensor temperature[] = { 69 { 70 .reg = SOC_TEMP, 71 .label = "temp1 SoC" 72 }, 73 { 74 .reg = SOC_VRD_TEMP, 75 .reg_ext = SOC_VR_HOT_THRESHOLD, 76 .label = "temp2 SoC VRD" 77 }, 78 { 79 .reg = DIMM_VRD_TEMP, 80 .label = "temp3 DIMM VRD" 81 }, 82 { 83 .reg = CORE_VRD_TEMP, 84 .label = "temp4 CORE VRD" 85 }, 86 { 87 .reg = CH0_DIMM_TEMP, 88 .reg_ext = MEM_HOT_THRESHOLD, 89 .label = "temp5 CH0 DIMM" 90 }, 91 { 92 .reg = CH1_DIMM_TEMP, 93 .reg_ext = MEM_HOT_THRESHOLD, 94 .label = "temp6 CH1 DIMM" 95 }, 96 { 97 .reg = CH2_DIMM_TEMP, 98 .reg_ext = MEM_HOT_THRESHOLD, 99 .label = "temp7 CH2 DIMM" 100 }, 101 { 102 .reg = CH3_DIMM_TEMP, 103 .reg_ext = MEM_HOT_THRESHOLD, 104 .label = "temp8 CH3 DIMM" 105 }, 106 { 107 .reg = CH4_DIMM_TEMP, 108 .reg_ext = MEM_HOT_THRESHOLD, 109 .label = "temp9 CH4 DIMM" 110 }, 111 { 112 .reg = CH5_DIMM_TEMP, 113 .reg_ext = MEM_HOT_THRESHOLD, 114 .label = "temp10 CH5 DIMM" 115 }, 116 { 117 .reg = CH6_DIMM_TEMP, 118 .reg_ext = MEM_HOT_THRESHOLD, 119 .label = "temp11 CH6 DIMM" 120 }, 121 { 122 .reg = CH7_DIMM_TEMP, 123 .reg_ext = MEM_HOT_THRESHOLD, 124 .label = "temp12 CH7 DIMM" 125 }, 126 { 127 .reg = RCA_VRD_TEMP, 128 .label = "temp13 RCA VRD" 129 }, 130 }; 131 132 static const struct smpro_sensor voltage[] = { 133 { 134 .reg = CORE_VRD_VOLT, 135 .label = "vout0 CORE VRD" 136 }, 137 { 138 .reg = SOC_VRD_VOLT, 139 .label = "vout1 SoC VRD" 140 }, 141 { 142 .reg = DIMM_VRD1_VOLT, 143 .label = "vout2 DIMM VRD1" 144 }, 145 { 146 .reg = DIMM_VRD2_VOLT, 147 .label = "vout3 DIMM VRD2" 148 }, 149 { 150 .reg = RCA_VRD_VOLT, 151 .label = "vout4 RCA VRD" 152 }, 153 }; 154 155 static const struct smpro_sensor curr_sensor[] = { 156 { 157 .reg = CORE_VRD_CURR, 158 .label = "iout1 CORE VRD" 159 }, 160 { 161 .reg = SOC_VRD_CURR, 162 .label = "iout2 SoC VRD" 163 }, 164 { 165 .reg = DIMM_VRD1_CURR, 166 .label = "iout3 DIMM VRD1" 167 }, 168 { 169 .reg = DIMM_VRD2_CURR, 170 .label = "iout4 DIMM VRD2" 171 }, 172 { 173 .reg = RCA_VRD_CURR, 174 .label = "iout5 RCA VRD" 175 }, 176 }; 177 178 static const struct smpro_sensor power[] = { 179 { 180 .reg = CORE_VRD_PWR, 181 .reg_ext = CORE_VRD_PWR_MW, 182 .label = "power1 CORE VRD" 183 }, 184 { 185 .reg = SOC_PWR, 186 .reg_ext = SOC_PWR_MW, 187 .label = "power2 SoC" 188 }, 189 { 190 .reg = DIMM_VRD1_PWR, 191 .reg_ext = DIMM_VRD1_PWR_MW, 192 .label = "power3 DIMM VRD1" 193 }, 194 { 195 .reg = DIMM_VRD2_PWR, 196 .reg_ext = DIMM_VRD2_PWR_MW, 197 .label = "power4 DIMM VRD2" 198 }, 199 { 200 .reg = RCA_VRD_PWR, 201 .reg_ext = RCA_VRD_PWR_MW, 202 .label = "power5 RCA VRD" 203 }, 204 }; 205 206 static int smpro_read_temp(struct device *dev, u32 attr, int channel, long *val) 207 { 208 struct smpro_hwmon *hwmon = dev_get_drvdata(dev); 209 unsigned int value; 210 int ret; 211 212 switch (attr) { 213 case hwmon_temp_input: 214 ret = regmap_read(hwmon->regmap, temperature[channel].reg, &value); 215 if (ret) 216 return ret; 217 break; 218 case hwmon_temp_crit: 219 ret = regmap_read(hwmon->regmap, temperature[channel].reg_ext, &value); 220 if (ret) 221 return ret; 222 break; 223 default: 224 return -EOPNOTSUPP; 225 } 226 227 *val = sign_extend32(value, 8) * 1000; 228 return 0; 229 } 230 231 static int smpro_read_in(struct device *dev, u32 attr, int channel, long *val) 232 { 233 struct smpro_hwmon *hwmon = dev_get_drvdata(dev); 234 unsigned int value; 235 int ret; 236 237 switch (attr) { 238 case hwmon_in_input: 239 ret = regmap_read(hwmon->regmap, voltage[channel].reg, &value); 240 if (ret < 0) 241 return ret; 242 /* 15-bit value in 1mV */ 243 *val = value & 0x7fff; 244 return 0; 245 default: 246 return -EOPNOTSUPP; 247 } 248 } 249 250 static int smpro_read_curr(struct device *dev, u32 attr, int channel, long *val) 251 { 252 struct smpro_hwmon *hwmon = dev_get_drvdata(dev); 253 unsigned int value; 254 int ret; 255 256 switch (attr) { 257 case hwmon_curr_input: 258 ret = regmap_read(hwmon->regmap, curr_sensor[channel].reg, &value); 259 if (ret < 0) 260 return ret; 261 /* Scale reported by the hardware is 1mA */ 262 *val = value & 0x7fff; 263 return 0; 264 default: 265 return -EOPNOTSUPP; 266 } 267 } 268 269 static int smpro_read_power(struct device *dev, u32 attr, int channel, long *val_pwr) 270 { 271 struct smpro_hwmon *hwmon = dev_get_drvdata(dev); 272 unsigned int val = 0, val_mw = 0; 273 int ret; 274 275 switch (attr) { 276 case hwmon_power_input: 277 ret = regmap_read(hwmon->regmap, power[channel].reg, &val); 278 if (ret) 279 return ret; 280 281 ret = regmap_read(hwmon->regmap, power[channel].reg_ext, &val_mw); 282 if (ret) 283 return ret; 284 /* 10-bit value */ 285 *val_pwr = (val & 0x3ff) * 1000000 + (val_mw & 0x3ff) * 1000; 286 return 0; 287 288 default: 289 return -EOPNOTSUPP; 290 } 291 } 292 293 static int smpro_read(struct device *dev, enum hwmon_sensor_types type, 294 u32 attr, int channel, long *val) 295 { 296 switch (type) { 297 case hwmon_temp: 298 return smpro_read_temp(dev, attr, channel, val); 299 case hwmon_in: 300 return smpro_read_in(dev, attr, channel, val); 301 case hwmon_power: 302 return smpro_read_power(dev, attr, channel, val); 303 case hwmon_curr: 304 return smpro_read_curr(dev, attr, channel, val); 305 default: 306 return -EOPNOTSUPP; 307 } 308 } 309 310 static int smpro_read_string(struct device *dev, enum hwmon_sensor_types type, 311 u32 attr, int channel, const char **str) 312 { 313 switch (type) { 314 case hwmon_temp: 315 switch (attr) { 316 case hwmon_temp_label: 317 *str = temperature[channel].label; 318 return 0; 319 default: 320 break; 321 } 322 break; 323 324 case hwmon_in: 325 switch (attr) { 326 case hwmon_in_label: 327 *str = voltage[channel].label; 328 return 0; 329 default: 330 break; 331 } 332 break; 333 334 case hwmon_curr: 335 switch (attr) { 336 case hwmon_curr_label: 337 *str = curr_sensor[channel].label; 338 return 0; 339 default: 340 break; 341 } 342 break; 343 344 case hwmon_power: 345 switch (attr) { 346 case hwmon_power_label: 347 *str = power[channel].label; 348 return 0; 349 default: 350 break; 351 } 352 break; 353 default: 354 break; 355 } 356 357 return -EOPNOTSUPP; 358 } 359 360 static umode_t smpro_is_visible(const void *data, enum hwmon_sensor_types type, 361 u32 attr, int channel) 362 { 363 const struct smpro_hwmon *hwmon = data; 364 unsigned int value; 365 int ret; 366 367 switch (type) { 368 case hwmon_temp: 369 switch (attr) { 370 case hwmon_temp_input: 371 case hwmon_temp_label: 372 case hwmon_temp_crit: 373 ret = regmap_read(hwmon->regmap, temperature[channel].reg, &value); 374 if (ret || value == 0xFFFF) 375 return 0; 376 break; 377 default: 378 break; 379 } 380 break; 381 default: 382 break; 383 } 384 385 return 0444; 386 } 387 388 static const struct hwmon_channel_info *smpro_info[] = { 389 HWMON_CHANNEL_INFO(temp, 390 HWMON_T_INPUT | HWMON_T_LABEL, 391 HWMON_T_INPUT | HWMON_T_LABEL | HWMON_T_CRIT, 392 HWMON_T_INPUT | HWMON_T_LABEL, 393 HWMON_T_INPUT | HWMON_T_LABEL, 394 HWMON_T_INPUT | HWMON_T_LABEL | HWMON_T_CRIT, 395 HWMON_T_INPUT | HWMON_T_LABEL | HWMON_T_CRIT, 396 HWMON_T_INPUT | HWMON_T_LABEL | HWMON_T_CRIT, 397 HWMON_T_INPUT | HWMON_T_LABEL | HWMON_T_CRIT, 398 HWMON_T_INPUT | HWMON_T_LABEL | HWMON_T_CRIT, 399 HWMON_T_INPUT | HWMON_T_LABEL | HWMON_T_CRIT, 400 HWMON_T_INPUT | HWMON_T_LABEL | HWMON_T_CRIT, 401 HWMON_T_INPUT | HWMON_T_LABEL | HWMON_T_CRIT, 402 HWMON_T_INPUT | HWMON_T_LABEL), 403 HWMON_CHANNEL_INFO(in, 404 HWMON_I_INPUT | HWMON_I_LABEL, 405 HWMON_I_INPUT | HWMON_I_LABEL, 406 HWMON_I_INPUT | HWMON_I_LABEL, 407 HWMON_I_INPUT | HWMON_I_LABEL, 408 HWMON_I_INPUT | HWMON_I_LABEL), 409 HWMON_CHANNEL_INFO(power, 410 HWMON_P_INPUT | HWMON_P_LABEL, 411 HWMON_P_INPUT | HWMON_P_LABEL, 412 HWMON_P_INPUT | HWMON_P_LABEL, 413 HWMON_P_INPUT | HWMON_P_LABEL, 414 HWMON_P_INPUT | HWMON_P_LABEL), 415 HWMON_CHANNEL_INFO(curr, 416 HWMON_C_INPUT | HWMON_C_LABEL, 417 HWMON_C_INPUT | HWMON_C_LABEL, 418 HWMON_C_INPUT | HWMON_C_LABEL, 419 HWMON_C_INPUT | HWMON_C_LABEL, 420 HWMON_C_INPUT | HWMON_C_LABEL), 421 NULL 422 }; 423 424 static const struct hwmon_ops smpro_hwmon_ops = { 425 .is_visible = smpro_is_visible, 426 .read = smpro_read, 427 .read_string = smpro_read_string, 428 }; 429 430 static const struct hwmon_chip_info smpro_chip_info = { 431 .ops = &smpro_hwmon_ops, 432 .info = smpro_info, 433 }; 434 435 static int smpro_hwmon_probe(struct platform_device *pdev) 436 { 437 struct smpro_hwmon *hwmon; 438 struct device *hwmon_dev; 439 440 hwmon = devm_kzalloc(&pdev->dev, sizeof(struct smpro_hwmon), GFP_KERNEL); 441 if (!hwmon) 442 return -ENOMEM; 443 444 hwmon->regmap = dev_get_regmap(pdev->dev.parent, NULL); 445 if (!hwmon->regmap) 446 return -ENODEV; 447 448 hwmon_dev = devm_hwmon_device_register_with_info(&pdev->dev, "smpro_hwmon", 449 hwmon, &smpro_chip_info, NULL); 450 451 return PTR_ERR_OR_ZERO(hwmon_dev); 452 } 453 454 static struct platform_driver smpro_hwmon_driver = { 455 .probe = smpro_hwmon_probe, 456 .driver = { 457 .name = "smpro-hwmon", 458 }, 459 }; 460 461 module_platform_driver(smpro_hwmon_driver); 462 463 MODULE_AUTHOR("Thu Nguyen <thu@os.amperecomputing.com>"); 464 MODULE_AUTHOR("Quan Nguyen <quan@os.amperecomputing.com>"); 465 MODULE_DESCRIPTION("Ampere Altra SMPro hwmon driver"); 466 MODULE_LICENSE("GPL"); 467