spacepaste

  1.  
  2. --- drivers/hwmon/k10temp.c 2017-09-14 13:25:55.605917971 +0200
  3. +++ drivers/hwmon/k10temp.c 2017-09-14 13:25:55.605917971 +0200
  4. @@ -36,6 +36,10 @@
  5. /* Provide lock for writing to NB_SMU_IND_ADDR */
  6. static DEFINE_MUTEX(nb_smu_ind_mutex);
  7. +#ifndef PCI_DEVICE_ID_AMD_17H_DF_F3
  8. +#define PCI_DEVICE_ID_AMD_17H_DF_F3 0x1463
  9. +#endif
  10. +
  11. /* CPUID function 0x80000001, ebx */
  12. #define CPUID_PKGTYPE_MASK 0xf0000000
  13. #define CPUID_PKGTYPE_F 0x00000000
  14. @@ -61,31 +65,72 @@
  15. */
  16. #define F15H_M60H_REPORTED_TEMP_CTRL_OFFSET 0xd8200ca4
  17. -static void amd_nb_smu_index_read(struct pci_dev *pdev, unsigned int devfn,
  18. - int offset, u32 *val)
  19. +/* F17h M01h Access througn SMN */
  20. +#define F17H_M01H_REPORTED_TEMP_CTRL_OFFSET 0x00059800
  21. +
  22. +struct k10temp_data {
  23. + struct pci_dev *pdev;
  24. + void (*read_tempreg)(struct pci_dev *pdev, u32 *regval);
  25. + int temp_offset;
  26. +};
  27. +
  28. +struct tctl_offset {
  29. + u8 model;
  30. + char const *id;
  31. + int offset;
  32. +};
  33. +
  34. +static const struct tctl_offset tctl_offset_table[] = {
  35. + { 0x17, "AMD Ryzen 7 1600X", 20000 },
  36. + { 0x17, "AMD Ryzen 7 1700X", 20000 },
  37. + { 0x17, "AMD Ryzen 7 1800X", 20000 },
  38. + { 0x17, "AMD Ryzen Threadripper 1950X", 27000 },
  39. + { 0x17, "AMD Ryzen Threadripper 1920X", 27000 },
  40. + { 0x17, "AMD Ryzen Threadripper 1950", 10000 },
  41. + { 0x17, "AMD Ryzen Threadripper 1920", 10000 },
  42. + { 0x17, "AMD Ryzen Threadripper 1910", 10000 },
  43. +};
  44. +
  45. +static void read_tempreg_pci(struct pci_dev *pdev, u32 *regval)
  46. +{
  47. + pci_read_config_dword(pdev, REG_REPORTED_TEMPERATURE, regval);
  48. +}
  49. +
  50. +static void amd_nb_index_read(struct pci_dev *pdev, unsigned int devfn,
  51. + unsigned int base, int offset, u32 *val)
  52. {
  53. mutex_lock(&nb_smu_ind_mutex);
  54. pci_bus_write_config_dword(pdev->bus, devfn,
  55. - 0xb8, offset);
  56. + base, offset);
  57. pci_bus_read_config_dword(pdev->bus, devfn,
  58. - 0xbc, val);
  59. + base + 4, val);
  60. mutex_unlock(&nb_smu_ind_mutex);
  61. }
  62. +static void read_tempreg_nb_f15(struct pci_dev *pdev, u32 *regval)
  63. +{
  64. + amd_nb_index_read(pdev, PCI_DEVFN(0, 0), 0xb8,
  65. + F15H_M60H_REPORTED_TEMP_CTRL_OFFSET, regval);
  66. +}
  67. +
  68. +static void read_tempreg_nb_f17(struct pci_dev *pdev, u32 *regval)
  69. +{
  70. + amd_nb_index_read(pdev, PCI_DEVFN(0, 0), 0x60,
  71. + F17H_M01H_REPORTED_TEMP_CTRL_OFFSET, regval);
  72. +}
  73. +
  74. static ssize_t temp1_input_show(struct device *dev,
  75. struct device_attribute *attr, char *buf)
  76. {
  77. + struct k10temp_data *data = dev_get_drvdata(dev);
  78. u32 regval;
  79. - struct pci_dev *pdev = dev_get_drvdata(dev);
  80. + int temp;
  81. - if (boot_cpu_data.x86 == 0x15 && boot_cpu_data.x86_model == 0x60) {
  82. - amd_nb_smu_index_read(pdev, PCI_DEVFN(0, 0),
  83. - F15H_M60H_REPORTED_TEMP_CTRL_OFFSET,
  84. - &regval);
  85. - } else {
  86. - pci_read_config_dword(pdev, REG_REPORTED_TEMPERATURE, &regval);
  87. - }
  88. - return sprintf(buf, "%u\n", (regval >> 21) * 125);
  89. + data->read_tempreg(data->pdev, &regval);
  90. + temp = (regval >> 21) * 125;
  91. + temp -= data->temp_offset;
  92. +
  93. + return sprintf(buf, "%u\n", temp);
  94. }
  95. static ssize_t temp1_max_show(struct device *dev,
  96. @@ -98,11 +143,12 @@
  97. struct device_attribute *devattr, char *buf)
  98. {
  99. struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
  100. + struct k10temp_data *data = dev_get_drvdata(dev);
  101. int show_hyst = attr->index;
  102. u32 regval;
  103. int value;
  104. - pci_read_config_dword(dev_get_drvdata(dev),
  105. + pci_read_config_dword(data->pdev,
  106. REG_HARDWARE_THERMAL_CONTROL, &regval);
  107. value = ((regval >> 16) & 0x7f) * 500 + 52000;
  108. if (show_hyst)
  109. @@ -119,7 +165,8 @@
  110. struct attribute *attr, int index)
  111. {
  112. struct device *dev = container_of(kobj, struct device, kobj);
  113. - struct pci_dev *pdev = dev_get_drvdata(dev);
  114. + struct k10temp_data *data = dev_get_drvdata(dev);
  115. + struct pci_dev *pdev = data->pdev;
  116. if (index >= 2) {
  117. u32 reg_caps, reg_htc;
  118. @@ -187,7 +234,9 @@
  119. {
  120. int unreliable = has_erratum_319(pdev);
  121. struct device *dev = &pdev->dev;
  122. + struct k10temp_data *data;
  123. struct device *hwmon_dev;
  124. + int i;
  125. if (unreliable) {
  126. if (!force) {
  127. @@ -199,7 +248,31 @@
  128. "unreliable CPU thermal sensor; check erratum 319\n");
  129. }
  130. - hwmon_dev = devm_hwmon_device_register_with_groups(dev, "k10temp", pdev,
  131. + data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
  132. + if (!data)
  133. + return -ENOMEM;
  134. +
  135. + data->pdev = pdev;
  136. +
  137. + if (boot_cpu_data.x86 == 0x15 && (boot_cpu_data.x86_model == 0x60 ||
  138. + boot_cpu_data.x86_model == 0x70))
  139. + data->read_tempreg = read_tempreg_nb_f15;
  140. + else if (boot_cpu_data.x86 == 0x17)
  141. + data->read_tempreg = read_tempreg_nb_f17;
  142. + else
  143. + data->read_tempreg = read_tempreg_pci;
  144. +
  145. + for (i = 0; i < ARRAY_SIZE(tctl_offset_table); i++) {
  146. + const struct tctl_offset *entry = &tctl_offset_table[i];
  147. +
  148. + if (boot_cpu_data.x86 == entry->model &&
  149. + strstr(boot_cpu_data.x86_model_id, entry->id)) {
  150. + data->temp_offset = entry->offset;
  151. + break;
  152. + }
  153. + }
  154. +
  155. + hwmon_dev = devm_hwmon_device_register_with_groups(dev, "k10temp", data,
  156. k10temp_groups);
  157. return PTR_ERR_OR_ZERO(hwmon_dev);
  158. }
  159. @@ -214,6 +287,7 @@
  160. { PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_15H_M60H_NB_F3) },
  161. { PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_16H_NB_F3) },
  162. { PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_16H_M30H_NB_F3) },
  163. + { PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_17H_DF_F3) },
  164. {}
  165. };
  166. MODULE_DEVICE_TABLE(pci, k10temp_id_table);
  167.