@@ -77,6 +77,20 @@ static DEFINE_MUTEX(nb_smu_ind_mutex);
7777#define ZEN_CUR_TEMP_RANGE_SEL_MASK BIT(19)
7878#define ZEN_CUR_TEMP_TJ_SEL_MASK GENMASK(17, 16)
7979
80+ /*
81+ * AMD's Industrial processor 3255 supports temperature from -40 deg to 105 deg Celsius.
82+ * Use the model name to identify 3255 CPUs and set a flag to display negative temperature.
83+ * Do not round off to zero for negative Tctl or Tdie values if the flag is set
84+ */
85+ #define AMD_I3255_STR "3255"
86+
87+ /*
88+ * PCI Device IDs for AMD's Family 1Ah-based SOCs.
89+ * Defining locally as IDs are not shared.
90+ */
91+ #define PCI_DEVICE_ID_AMD_1AH_M50H_DF_F3 0x12cb
92+ #define PCI_DEVICE_ID_AMD_1AH_M90H_DF_F3 0x127b
93+
8094struct k10temp_data {
8195 struct pci_dev * pdev ;
8296 void (* read_htcreg )(struct pci_dev * pdev , u32 * regval );
@@ -86,14 +100,14 @@ struct k10temp_data {
86100 u32 show_temp ;
87101 bool is_zen ;
88102 u32 ccd_offset ;
103+ bool disp_negative ;
89104};
90105
91106#define TCTL_BIT 0
92107#define TDIE_BIT 1
93108#define TCCD_BIT (x ) ((x) + 2)
94109
95110#define HAVE_TEMP (d , channel ) ((d)->show_temp & BIT(channel))
96- #define HAVE_TDIE (d ) HAVE_TEMP(d, TDIE_BIT)
97111
98112struct tctl_offset {
99113 u8 model ;
@@ -155,6 +169,13 @@ static void read_tempreg_nb_zen(struct pci_dev *pdev, u32 *regval)
155169 * regval = 0 ;
156170}
157171
172+ static int read_ccd_temp_reg (struct k10temp_data * data , int ccd , u32 * regval )
173+ {
174+ u16 node_id = amd_pci_dev_to_node_id (data -> pdev );
175+
176+ return amd_smn_read (node_id , ZEN_CCD_TEMP (data -> ccd_offset , ccd ), regval );
177+ }
178+
158179static long get_raw_temp (struct k10temp_data * data )
159180{
160181 u32 regval ;
@@ -211,18 +232,16 @@ static int k10temp_read_temp(struct device *dev, u32 attr, int channel,
211232 switch (channel ) {
212233 case 0 : /* Tctl */
213234 * val = get_raw_temp (data );
214- if (* val < 0 )
235+ if (* val < 0 && ! data -> disp_negative )
215236 * val = 0 ;
216237 break ;
217238 case 1 : /* Tdie */
218239 * val = get_raw_temp (data ) - data -> temp_offset ;
219- if (* val < 0 )
240+ if (* val < 0 && ! data -> disp_negative )
220241 * val = 0 ;
221242 break ;
222243 case 2 ... 13 : /* Tccd{1-12} */
223- ret = amd_smn_read (amd_pci_dev_to_node_id (data -> pdev ),
224- ZEN_CCD_TEMP (data -> ccd_offset , channel - 2 ),
225- & regval );
244+ ret = read_ccd_temp_reg (data , channel - 2 , & regval );
226245
227246 if (ret )
228247 return ret ;
@@ -262,11 +281,11 @@ static int k10temp_read(struct device *dev, enum hwmon_sensor_types type,
262281 }
263282}
264283
265- static umode_t k10temp_is_visible (const void * _data ,
284+ static umode_t k10temp_is_visible (const void * drvdata ,
266285 enum hwmon_sensor_types type ,
267286 u32 attr , int channel )
268287{
269- const struct k10temp_data * data = _data ;
288+ const struct k10temp_data * data = drvdata ;
270289 struct pci_dev * pdev = data -> pdev ;
271290 u32 reg ;
272291
@@ -377,8 +396,7 @@ static const struct hwmon_chip_info k10temp_chip_info = {
377396 .info = k10temp_info ,
378397};
379398
380- static void k10temp_get_ccd_support (struct pci_dev * pdev ,
381- struct k10temp_data * data , int limit )
399+ static void k10temp_get_ccd_support (struct k10temp_data * data , int limit )
382400{
383401 u32 regval ;
384402 int i ;
@@ -394,8 +412,7 @@ static void k10temp_get_ccd_support(struct pci_dev *pdev,
394412 * the register value. And this will incorrectly pass the TEMP_VALID
395413 * bit check.
396414 */
397- if (amd_smn_read (amd_pci_dev_to_node_id (pdev ),
398- ZEN_CCD_TEMP (data -> ccd_offset , i ), & regval ))
415+ if (read_ccd_temp_reg (data , i , & regval ))
399416 continue ;
400417
401418 if (regval & ZEN_CCD_TEMP_VALID )
@@ -428,70 +445,78 @@ static int k10temp_probe(struct pci_dev *pdev, const struct pci_device_id *id)
428445 data -> pdev = pdev ;
429446 data -> show_temp |= BIT (TCTL_BIT ); /* Always show Tctl */
430447
431- if (boot_cpu_data .x86 == 0x15 &&
448+ if (boot_cpu_data .x86 == 0x17 &&
449+ strstr (boot_cpu_data .x86_model_id , AMD_I3255_STR )) {
450+ data -> disp_negative = true;
451+ }
452+
453+ data -> is_zen = cpu_feature_enabled (X86_FEATURE_ZEN );
454+ if (data -> is_zen ) {
455+ data -> temp_adjust_mask = ZEN_CUR_TEMP_RANGE_SEL_MASK ;
456+ data -> read_tempreg = read_tempreg_nb_zen ;
457+ } else if (boot_cpu_data .x86 == 0x15 &&
432458 ((boot_cpu_data .x86_model & 0xf0 ) == 0x60 ||
433459 (boot_cpu_data .x86_model & 0xf0 ) == 0x70 )) {
434460 data -> read_htcreg = read_htcreg_nb_f15 ;
435461 data -> read_tempreg = read_tempreg_nb_f15 ;
436- } else if ( boot_cpu_data . x86 == 0x17 || boot_cpu_data . x86 == 0x18 ) {
437- data -> temp_adjust_mask = ZEN_CUR_TEMP_RANGE_SEL_MASK ;
438- data -> read_tempreg = read_tempreg_nb_zen ;
439- data -> is_zen = true;
462+ } else {
463+ data -> read_htcreg = read_htcreg_pci ;
464+ data -> read_tempreg = read_tempreg_pci ;
465+ }
440466
467+ if (boot_cpu_data .x86 == 0x17 || boot_cpu_data .x86 == 0x18 ) {
441468 switch (boot_cpu_data .x86_model ) {
442469 case 0x1 : /* Zen */
443470 case 0x8 : /* Zen+ */
444471 case 0x11 : /* Zen APU */
445472 case 0x18 : /* Zen+ APU */
446473 data -> ccd_offset = 0x154 ;
447- k10temp_get_ccd_support (pdev , data , 4 );
474+ k10temp_get_ccd_support (data , 4 );
448475 break ;
449476 case 0x31 : /* Zen2 Threadripper */
477+ case 0x47 : /* Cyan Skillfish */
450478 case 0x60 : /* Renoir */
451479 case 0x68 : /* Lucienne */
452480 case 0x71 : /* Zen2 */
453481 data -> ccd_offset = 0x154 ;
454- k10temp_get_ccd_support (pdev , data , 8 );
482+ k10temp_get_ccd_support (data , 8 );
455483 break ;
456484 case 0xa0 ... 0xaf :
457485 data -> ccd_offset = 0x300 ;
458- k10temp_get_ccd_support (pdev , data , 8 );
486+ k10temp_get_ccd_support (data , 8 );
459487 break ;
460488 }
461489 } else if (boot_cpu_data .x86 == 0x19 ) {
462- data -> temp_adjust_mask = ZEN_CUR_TEMP_RANGE_SEL_MASK ;
463- data -> read_tempreg = read_tempreg_nb_zen ;
464- data -> is_zen = true;
465-
466490 switch (boot_cpu_data .x86_model ) {
467491 case 0x0 ... 0x1 : /* Zen3 SP3/TR */
492+ case 0x8 : /* Zen3 TR Chagall */
468493 case 0x21 : /* Zen3 Ryzen Desktop */
469494 case 0x50 ... 0x5f : /* Green Sardine */
470495 data -> ccd_offset = 0x154 ;
471- k10temp_get_ccd_support (pdev , data , 8 );
496+ k10temp_get_ccd_support (data , 8 );
472497 break ;
473498 case 0x40 ... 0x4f : /* Yellow Carp */
474499 data -> ccd_offset = 0x300 ;
475- k10temp_get_ccd_support (pdev , data , 8 );
500+ k10temp_get_ccd_support (data , 8 );
476501 break ;
477502 case 0x60 ... 0x6f :
478503 case 0x70 ... 0x7f :
479504 data -> ccd_offset = 0x308 ;
480- k10temp_get_ccd_support (pdev , data , 8 );
505+ k10temp_get_ccd_support (data , 8 );
481506 break ;
482507 case 0x10 ... 0x1f :
483508 case 0xa0 ... 0xaf :
484509 data -> ccd_offset = 0x300 ;
485- k10temp_get_ccd_support (pdev , data , 12 );
510+ k10temp_get_ccd_support (data , 12 );
486511 break ;
487512 }
488513 } else if (boot_cpu_data .x86 == 0x1a ) {
489- data -> temp_adjust_mask = ZEN_CUR_TEMP_RANGE_SEL_MASK ;
490- data -> read_tempreg = read_tempreg_nb_zen ;
491- data -> is_zen = true ;
492- } else {
493- data -> read_htcreg = read_htcreg_pci ;
494- data -> read_tempreg = read_tempreg_pci ;
514+ switch ( boot_cpu_data . x86_model ) {
515+ case 0x40 ... 0x4f : /* Zen5 Ryzen Desktop */
516+ data -> ccd_offset = 0x308 ;
517+ k10temp_get_ccd_support ( data , 8 );
518+ break ;
519+ }
495520 }
496521
497522 for (i = 0 ; i < ARRAY_SIZE (tctl_offset_table ); i ++ ) {
@@ -525,6 +550,7 @@ static const struct pci_device_id k10temp_id_table[] = {
525550 { PCI_VDEVICE (AMD , PCI_DEVICE_ID_AMD_17H_DF_F3 ) },
526551 { PCI_VDEVICE (AMD , PCI_DEVICE_ID_AMD_17H_M10H_DF_F3 ) },
527552 { PCI_VDEVICE (AMD , PCI_DEVICE_ID_AMD_17H_M30H_DF_F3 ) },
553+ { PCI_VDEVICE (AMD , PCI_DEVICE_ID_AMD_17H_M40H_DF_F3 ) },
528554 { PCI_VDEVICE (AMD , PCI_DEVICE_ID_AMD_17H_M60H_DF_F3 ) },
529555 { PCI_VDEVICE (AMD , PCI_DEVICE_ID_AMD_17H_M70H_DF_F3 ) },
530556 { PCI_VDEVICE (AMD , PCI_DEVICE_ID_AMD_17H_MA0H_DF_F3 ) },
@@ -537,7 +563,10 @@ static const struct pci_device_id k10temp_id_table[] = {
537563 { PCI_VDEVICE (AMD , PCI_DEVICE_ID_AMD_19H_M78H_DF_F3 ) },
538564 { PCI_VDEVICE (AMD , PCI_DEVICE_ID_AMD_1AH_M00H_DF_F3 ) },
539565 { PCI_VDEVICE (AMD , PCI_DEVICE_ID_AMD_1AH_M20H_DF_F3 ) },
566+ { PCI_VDEVICE (AMD , PCI_DEVICE_ID_AMD_1AH_M50H_DF_F3 ) },
540567 { PCI_VDEVICE (AMD , PCI_DEVICE_ID_AMD_1AH_M60H_DF_F3 ) },
568+ { PCI_VDEVICE (AMD , PCI_DEVICE_ID_AMD_1AH_M70H_DF_F3 ) },
569+ { PCI_VDEVICE (AMD , PCI_DEVICE_ID_AMD_1AH_M90H_DF_F3 ) },
541570 { PCI_VDEVICE (HYGON , PCI_DEVICE_ID_AMD_17H_DF_F3 ) },
542571 {}
543572};
0 commit comments