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
21int32
22radeon_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_CAPEVERDE) {
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