Lines Matching +full:thermal +full:- +full:sensors
21 * ----------
23 * ----------
25 * When we think of temperature sensors, we generally think of an external or
31 * sensors are often called Tdie, because they represent the temperature of a
35 * that have some amount of post-processing applied to them from different
38 * While AMD has various Tdie sensors (we'll get back to them later), the
40 * different and called Tctl, the control temperature. Unlike normal sensors
45 * 1) At a value of 95, the CPU will begin internal thermal throttling.
56 * earlier life of this driver. The addition of the various CCD-specific sensors
59 * -------------------------------------
60 * System Management Network and Sensors
61 * -------------------------------------
63 * The SMN (system management network) exists on a per-die basis. That is there
69 * As a result of this split there are two different groups of sensors that
75 * and is read-only for all intents and purposes for us due to its nature as a
82 * generally a fixed number of these die sensors at given offsets on the CPU.
83 * These are sourced by the thermal monitor and have a valid bit. The general
86 * -------------------
88 * -------------------
91 * /dev/sensors/cpu directory. Each DF maps to the cpuid.c procnode concept. The
92 * Tctl sensor is named 'procnode.%u'. The Tdie sensors are named
93 * 'procnode.%u:die.%u'. This allows us to have them exist on a per-DF basis.
95 * these are CCD-specific sensors rather than this driver itself.
100 * represents Tctl and a variable number of Tdie sensors based on how many the
103 * Because of our desire not to assume that these are specifically CCD sensors
105 * CCDs as a way to scope which Tdie sensors exist and instead leverage the
120 #include <sys/sensors.h>
141 * This represents the per-temperature data that we keep around per exposed
158 * sensors for it, both its Tctl and however many Tdie exist.
192 if (stt->stt_kind == SMNTEMP_K_TDIE) { in smntemp_temp_adjust()
196 if (THM_CURTEMP_GET_RANGE(stt->stt_raw) == THM_CURTEMP_RANGE_N49_206 || in smntemp_temp_adjust()
197 THM_CURTEMP_GET_TJ_SEL(stt->stt_raw) == THM_CURTEMP_TJ_SEL_RW) { in smntemp_temp_adjust()
211 ASSERT(MUTEX_HELD((&stt->stt_mutex))); in smntemp_temp_update()
213 if ((ret = amdzen_c_smn_read(stt->stt_df->sd_dfno, stt->stt_reg, in smntemp_temp_update()
218 stt->stt_last_read = gethrtime(); in smntemp_temp_update()
219 stt->stt_raw = reg; in smntemp_temp_update()
220 if (stt->stt_kind == SMNTEMP_K_TCTL) { in smntemp_temp_update()
230 stt->stt_temp = raw << THM_CURTEMP_TEMP_DEC_BITS; in smntemp_temp_update()
231 stt->stt_temp += decimal; in smntemp_temp_update()
239 ASSERT(MUTEX_HELD(&stt->stt_mutex)); in smntemp_temp_unit()
241 if (stt->stt_kind == SMNTEMP_K_TDIE) { in smntemp_temp_unit()
243 } else if (THM_CURTEMP_GET_TJ_SEL(stt->stt_raw) == in smntemp_temp_unit()
257 mutex_enter(&stt->stt_mutex); in smntemp_temp_read()
259 mutex_exit(&stt->stt_mutex); in smntemp_temp_read()
263 temp->sis_unit = smntemp_temp_unit(stt); in smntemp_temp_read()
264 temp->sis_value = stt->stt_temp; in smntemp_temp_read()
266 temp->sis_gran = THM_CURTEMP_TEMP_DEC_GRAN; in smntemp_temp_read()
267 mutex_exit(&stt->stt_mutex); in smntemp_temp_read()
281 if (stt->stt_kind == SMNTEMP_K_TDIE) { in smntemp_temp_kind()
282 kind->sik_kind = SENSOR_KIND_TEMPERATURE; in smntemp_temp_kind()
286 mutex_enter(&stt->stt_mutex); in smntemp_temp_kind()
287 if (stt->stt_raw == 0) { in smntemp_temp_kind()
290 mutex_exit(&stt->stt_mutex); in smntemp_temp_kind()
295 if (THM_CURTEMP_GET_TJ_SEL(stt->stt_raw) == THM_CURTEMP_TJ_SEL_TJ) { in smntemp_temp_kind()
296 kind->sik_kind = SENSOR_KIND_TEMPERATURE; in smntemp_temp_kind()
298 kind->sik_kind = SENSOR_KIND_SYNTHETIC; in smntemp_temp_kind()
299 kind->sik_derive = SENSOR_KIND_TEMPERATURE; in smntemp_temp_kind()
302 mutex_exit(&stt->stt_mutex); in smntemp_temp_kind()
319 temp->stt_kind = SMNTEMP_K_TDIE; in smntemp_create_tdie()
320 temp->stt_df = df; in smntemp_create_tdie()
321 temp->stt_reg = THM_DIE(ccdno, smn->smn_fam); in smntemp_create_tdie()
322 mutex_init(&temp->stt_mutex, NULL, MUTEX_DRIVER, NULL); in smntemp_create_tdie()
323 temp->stt_flags = SMNTEMP_F_MUTEX; in smntemp_create_tdie()
326 * Tdie sensors have a valid bit that we need to check before we in smntemp_create_tdie()
329 if (snprintf(buf, sizeof (buf), "procnode.%u.die.%u", df->sd_dfno, in smntemp_create_tdie()
331 dev_err(smn->smn_dip, CE_WARN, "!unexpected buffer name " in smntemp_create_tdie()
332 "overrun assembling DF/CCD %u/%u Tdie", df->sd_dfno, in smntemp_create_tdie()
337 if ((ret = amdzen_c_smn_read(temp->stt_df->sd_dfno, temp->stt_reg, in smntemp_create_tdie()
339 dev_err(smn->smn_dip, CE_WARN, "!unexpected SMN read failure " in smntemp_create_tdie()
340 "reading DF/CCD %u/%u Tdie: %d", df->sd_dfno, ccdno, ret); in smntemp_create_tdie()
345 * Tdie sensors have a valid bit in them. We more or less assume that in smntemp_create_tdie()
353 df->sd_nccd_valid++; in smntemp_create_tdie()
354 temp->stt_flags |= SMNTEMP_F_VALID; in smntemp_create_tdie()
356 if ((ret = ksensor_create(smn->smn_dip, &smntemp_temp_ops, temp, buf, in smntemp_create_tdie()
357 DDI_NT_SENSOR_TEMP_CPU, &temp->stt_ksensor)) != 0) { in smntemp_create_tdie()
358 dev_err(smn->smn_dip, CE_WARN, "!failed to create sensor %s: " in smntemp_create_tdie()
372 temp->stt_kind = SMNTEMP_K_TCTL; in smntemp_create_tctl()
373 temp->stt_df = df; in smntemp_create_tctl()
374 temp->stt_reg = THM_CURTEMP; in smntemp_create_tctl()
375 mutex_init(&temp->stt_mutex, NULL, MUTEX_DRIVER, NULL); in smntemp_create_tctl()
376 temp->stt_flags = SMNTEMP_F_VALID | SMNTEMP_F_MUTEX; in smntemp_create_tctl()
378 if (snprintf(buf, sizeof (buf), "procnode.%u", df->sd_dfno) >= in smntemp_create_tctl()
380 dev_err(smn->smn_dip, CE_WARN, "!unexpected buffer name " in smntemp_create_tctl()
381 "overrun assembling DF %u Tctl", df->sd_dfno); in smntemp_create_tctl()
385 if ((ret = ksensor_create(smn->smn_dip, &smntemp_temp_ops, temp, buf, in smntemp_create_tctl()
386 DDI_NT_SENSOR_TEMP_CPU, &temp->stt_ksensor)) != 0) { in smntemp_create_tctl()
387 dev_err(smn->smn_dip, CE_WARN, "!failed to create sensor %s: " in smntemp_create_tctl()
398 temp->stt_flags &= ~SMNTEMP_F_VALID; in smntemp_cleanup_temp()
399 if ((temp->stt_flags & SMNTEMP_F_MUTEX) != 0) { in smntemp_cleanup_temp()
400 mutex_destroy(&temp->stt_mutex); in smntemp_cleanup_temp()
401 temp->stt_flags &= ~SMNTEMP_F_MUTEX; in smntemp_cleanup_temp()
403 ASSERT0(temp->stt_flags); in smntemp_cleanup_temp()
409 (void) ksensor_remove(smn->smn_dip, KSENSOR_ALL_IDS); in smntemp_cleanup()
411 for (uint32_t dfno = 0; dfno < smn->smn_ndf; dfno++) { in smntemp_cleanup()
412 smntemp_df_t *df = &smn->smn_df[dfno]; in smntemp_cleanup()
413 smntemp_cleanup_temp(&df->sd_tctl); in smntemp_cleanup()
414 for (uint32_t ccdno = 0; ccdno < df->sd_nccd; ccdno++) { in smntemp_cleanup()
415 smntemp_cleanup_temp(&df->sd_tdie[ccdno]); in smntemp_cleanup()
418 if (df->sd_nccd > 0) { in smntemp_cleanup()
419 kmem_free(df->sd_tdie, df->sd_nccd * in smntemp_cleanup()
421 df->sd_nccd = 0; in smntemp_cleanup()
422 df->sd_tdie = NULL; in smntemp_cleanup()
425 if (smn->smn_ndf > 0) { in smntemp_cleanup()
426 kmem_free(smn->smn_df, sizeof (smntemp_df_t) * smn->smn_ndf); in smntemp_cleanup()
427 smn->smn_ndf = 0; in smntemp_cleanup()
428 smn->smn_df = NULL; in smntemp_cleanup()
431 if (smn->smn_dip != NULL) { in smntemp_cleanup()
432 ddi_remove_minor_node(smn->smn_dip, NULL); in smntemp_cleanup()
433 ddi_set_driver_private(smn->smn_dip, NULL); in smntemp_cleanup()
434 smn->smn_dip = NULL; in smntemp_cleanup()
449 if (smntemp->smn_dip != NULL) { in smntemp_attach()
453 smntemp->smn_dip = dip; in smntemp_attach()
454 smntemp->smn_fam = chiprev_family(cpuid_getchiprev(CPU)); in smntemp_attach()
460 smntemp->smn_ndf = amdzen_c_df_count(); in smntemp_attach()
461 if (smntemp->smn_ndf == 0) { in smntemp_attach()
465 smntemp->smn_df = kmem_zalloc(sizeof (smntemp_df_t) * smntemp->smn_ndf, in smntemp_attach()
467 for (uint32_t dfno = 0; dfno < smntemp->smn_ndf; dfno++) { in smntemp_attach()
468 smntemp_df_t *df = &smntemp->smn_df[dfno]; in smntemp_attach()
469 df->sd_dfno = dfno; in smntemp_attach()
470 df->sd_nccd = THM_DIE_MAX_UNITS(smntemp->smn_fam); in smntemp_attach()
472 if (!smntemp_create_tctl(smntemp, df, &df->sd_tctl)) { in smntemp_attach()
476 if (df->sd_nccd > 0) { in smntemp_attach()
477 df->sd_tdie = kmem_zalloc(sizeof (smntemp_temp_t) * in smntemp_attach()
478 df->sd_nccd, KM_SLEEP); in smntemp_attach()
481 for (uint32_t i = 0; i < df->sd_nccd; i++) { in smntemp_attach()
483 &df->sd_tdie[i], i)) { in smntemp_attach()
508 if (smntemp->smn_dip == NULL) { in smntemp_detach()
509 dev_err(smntemp->smn_dip, CE_WARN, "!asked to detach smn " in smntemp_detach()