xref: /haiku/src/add-ons/kernel/drivers/graphics/radeon_hd/sensors.cpp (revision 25a7b01d15612846f332751841da3579db313082)
1 /*
2  * Copyright 2011-2012 Haiku, Inc. All rights reserved.
3  * Distributed under the terms of the MIT License.
4  *
5  * Authors:
6  *		Alexander von Gluck IV, kallisti5@unixzen.com
7  */
8 
9 
10 #include "sensors.h"
11 
12 
13 #define TRACE_DRIVER
14 #ifdef TRACE_DRIVER
15 #	define TRACE(x...) dprintf("radeon_hd: " x)
16 #else
17 #	define TRACE(x...) ;
18 #endif
19 
20 
21 int32
22 radeon_thermal_query(radeon_info &info)
23 {
24 	// return GPU temp in millidegrees C
25 
26 	uint32 rawTemp = 0;
27 	int32 finalTemp = 0;
28 
29 	if (info.chipsetID >= RADEON_LOMBOK) {
30 		rawTemp = (read32(info.registers + SI_CG_MULT_THERMAL_STATUS)
31 			& SI_CTF_TEMP_MASK) >> SI_CTF_TEMP_SHIFT;
32 
33 		if (rawTemp & 0x200)
34 			finalTemp = 255;
35 		else
36 			finalTemp = rawTemp & 0x1ff;
37 
38 		return finalTemp * 1000;
39 	} else if (info.chipsetID == RADEON_JUNIPER) {
40 		uint32 offset = (read32(info.registers + EVERGREEN_CG_THERMAL_CTRL)
41 			& EVERGREEN_TOFFSET_MASK) >> EVERGREEN_TOFFSET_SHIFT;
42 		rawTemp = (read32(info.registers + EVERGREEN_CG_TS0_STATUS)
43 			& EVERGREEN_TS0_ADC_DOUT_MASK) >> EVERGREEN_TS0_ADC_DOUT_SHIFT;
44 
45 		if (offset & 0x100)
46 			finalTemp = rawTemp / 2 - (0x200 - offset);
47 		else
48 			finalTemp = rawTemp / 2 + offset;
49 
50 		return finalTemp * 1000;
51 	} else if (info.chipsetID == RADEON_SUMO
52 		|| info.chipsetID == RADEON_SUMO2) {
53 		uint32 rawTemp = read32(info.registers + EVERGREEN_CG_THERMAL_STATUS)
54 			& 0xff;
55 		finalTemp = rawTemp - 49;
56 
57 		return finalTemp * 1000;
58 	} else if (info.chipsetID >= RADEON_CEDAR) {
59 		rawTemp = (read32(info.registers + EVERGREEN_CG_MULT_THERMAL_STATUS)
60 			& EVERGREEN_ASIC_T_MASK) >> EVERGREEN_ASIC_T_SHIFT;
61 
62 		if (rawTemp & 0x400)
63 			finalTemp = -256;
64 		else if (rawTemp & 0x200)
65 			finalTemp = 255;
66 		else if (rawTemp & 0x100) {
67 			finalTemp = rawTemp & 0x1ff;
68 			finalTemp |= ~0x1ff;
69 		} else
70 			finalTemp = rawTemp & 0xff;
71 
72 		return (finalTemp * 1000) / 2;
73 	} else if (info.chipsetID >= RADEON_RV770) {
74 		rawTemp = (read32(info.registers + R700_CG_MULT_THERMAL_STATUS)
75 			& R700_ASIC_T_MASK) >> R700_ASIC_T_SHIFT;
76 		if (rawTemp & 0x400)
77 			finalTemp = -256;
78 		else if (rawTemp & 0x200)
79 			finalTemp = 255;
80 		else if (rawTemp & 0x100) {
81 			finalTemp = rawTemp & 0x1ff;
82 			finalTemp |= ~0x1ff;
83 		} else
84 			finalTemp = rawTemp & 0xff;
85 
86 		return (finalTemp * 1000) / 2;
87 	} else if (info.chipsetID >= RADEON_R600) {
88 		rawTemp = (read32(info.registers + R600_CG_THERMAL_STATUS)
89 			& R600_ASIC_T_MASK) >> R600_ASIC_T_SHIFT;
90 		finalTemp = rawTemp & 0xff;
91 
92 		if (rawTemp & 0x100)
93 			finalTemp -= 256;
94 
95 		return finalTemp * 1000;
96 	}
97 
98 	return -1;
99 }
100