drm/radeon: add get_temperature() callbacks for CIK (v2)
authorAlex Deucher <alexander.deucher@amd.com>
Fri, 21 Jun 2013 19:50:47 +0000 (15:50 -0400)
committerAlex Deucher <alexander.deucher@amd.com>
Fri, 30 Aug 2013 20:30:15 +0000 (16:30 -0400)
This added support for the on-chip thermal sensors on
CIK asics.

v2: fix register offset.

Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
drivers/gpu/drm/radeon/cik.c
drivers/gpu/drm/radeon/cikd.h
drivers/gpu/drm/radeon/radeon_asic.c
drivers/gpu/drm/radeon/radeon_asic.h
drivers/gpu/drm/radeon/radeon_pm.c

index 727c296662f13ee938fdfcbb6f47cc8143fb6074..d0804f79efed538c2bc51ab91a1521e9ff467ccc 100644 (file)
@@ -69,6 +69,43 @@ static void cik_program_aspm(struct radeon_device *rdev);
 static void cik_init_pg(struct radeon_device *rdev);
 static void cik_init_cg(struct radeon_device *rdev);
 
+/* get temperature in millidegrees */
+int ci_get_temp(struct radeon_device *rdev)
+{
+       u32 temp;
+       int actual_temp = 0;
+
+       temp = (RREG32_SMC(CG_MULT_THERMAL_STATUS) & CTF_TEMP_MASK) >>
+               CTF_TEMP_SHIFT;
+
+       if (temp & 0x200)
+               actual_temp = 255;
+       else
+               actual_temp = temp & 0x1ff;
+
+       actual_temp = actual_temp * 1000;
+
+       return actual_temp;
+}
+
+/* get temperature in millidegrees */
+int kv_get_temp(struct radeon_device *rdev)
+{
+       u32 temp;
+       int actual_temp = 0;
+
+       temp = RREG32_SMC(0xC0300E0C);
+
+       if (temp)
+               actual_temp = (temp / 8) - 49;
+       else
+               actual_temp = 0;
+
+       actual_temp = actual_temp * 1000;
+
+       return actual_temp;
+}
+
 /*
  * Indirect registers accessor
  */
index 116b3131a683ce8e42b1f44674735fea823df07d..65886caaf75639d2c2b233d5b4b39855036d4afb 100644 (file)
 #define GENERAL_PWRMGT                                    0xC0200000
 #       define GPU_COUNTER_CLK                            (1 << 15)
 
+#define        CG_MULT_THERMAL_STATUS                          0xC0300014
+#define                ASIC_MAX_TEMP(x)                        ((x) << 0)
+#define                ASIC_MAX_TEMP_MASK                      0x000001ff
+#define                ASIC_MAX_TEMP_SHIFT                     0
+#define                CTF_TEMP(x)                             ((x) << 9)
+#define                CTF_TEMP_MASK                           0x0003fe00
+#define                CTF_TEMP_SHIFT                          9
+
 #define        MPLL_BYPASSCLK_SEL                              0xC050019C
 #      define MPLL_CLKOUT_SEL(x)                       ((x) << 8)
 #      define MPLL_CLKOUT_SEL_MASK                     0xFF00
index 880551b6df619ff895a08b54c3da5591f698c9c1..3a55540fe2801a2424854af0e7a89248b46486f1 100644 (file)
@@ -2452,6 +2452,7 @@ static struct radeon_asic ci_asic = {
                .set_pcie_lanes = NULL,
                .set_clock_gating = NULL,
                .set_uvd_clocks = &cik_set_uvd_clocks,
+               .get_temperature = &ci_get_temp,
        },
        .pflip = {
                .pre_page_flip = &evergreen_pre_page_flip,
@@ -2607,6 +2608,7 @@ static struct radeon_asic kv_asic = {
                .set_pcie_lanes = NULL,
                .set_clock_gating = NULL,
                .set_uvd_clocks = &cik_set_uvd_clocks,
+               .get_temperature = &kv_get_temp,
        },
        .pflip = {
                .pre_page_flip = &evergreen_pre_page_flip,
index 3cf7d89c1bd8a554e3e1e7622f75c29c5bfe9afe..d5c6c5b10edfe2b6d4566c5f143b0546494312ce 100644 (file)
@@ -747,5 +747,7 @@ u32 cik_compute_ring_get_wptr(struct radeon_device *rdev,
                              struct radeon_ring *ring);
 void cik_compute_ring_set_wptr(struct radeon_device *rdev,
                               struct radeon_ring *ring);
+int ci_get_temp(struct radeon_device *rdev);
+int kv_get_temp(struct radeon_device *rdev);
 
 #endif
index 79a03de4ac0ac7e15f8e6d949585b40c62ac0769..1408014dce8fbe91193b30f2b024edce8b053f0f 100644 (file)
@@ -569,6 +569,8 @@ static int radeon_hwmon_init(struct radeon_device *rdev)
        case THERMAL_TYPE_NI:
        case THERMAL_TYPE_SUMO:
        case THERMAL_TYPE_SI:
+       case THERMAL_TYPE_CI:
+       case THERMAL_TYPE_KV:
                if (rdev->asic->pm.get_temperature == NULL)
                        return err;
                rdev->pm.int_hwmon_dev = hwmon_device_register(rdev->dev);