⛏️ index : haiku.git

/*
 * Copyright 2011-2012 Haiku, Inc. All rights reserved.
 * Distributed under the terms of the MIT License.
 *
 * Authors:
 *		Alexander von Gluck IV, kallisti5@unixzen.com
 */


#include "sensors.h"


#define TRACE_DRIVER
#ifdef TRACE_DRIVER
#	define TRACE(x...) dprintf("radeon_hd: " x)
#else
#	define TRACE(x...) ;
#endif


int32
radeon_thermal_query(radeon_info &info)
{
	// return GPU temp in millidegrees C

	uint32 rawTemp = 0;
	int32 finalTemp = 0;

	if (info.chipsetID >= RADEON_CAPEVERDE) {
		rawTemp = (read32(info.registers + SI_CG_MULT_THERMAL_STATUS)
			& SI_CTF_TEMP_MASK) >> SI_CTF_TEMP_SHIFT;

		if (rawTemp & 0x200)
			finalTemp = 255;
		else
			finalTemp = rawTemp & 0x1ff;

		return finalTemp * 1000;
	} else if (info.chipsetID == RADEON_JUNIPER) {
		uint32 offset = (read32(info.registers + EVERGREEN_CG_THERMAL_CTRL)
			& EVERGREEN_TOFFSET_MASK) >> EVERGREEN_TOFFSET_SHIFT;
		rawTemp = (read32(info.registers + EVERGREEN_CG_TS0_STATUS)
			& EVERGREEN_TS0_ADC_DOUT_MASK) >> EVERGREEN_TS0_ADC_DOUT_SHIFT;

		if (offset & 0x100)
			finalTemp = rawTemp / 2 - (0x200 - offset);
		else
			finalTemp = rawTemp / 2 + offset;

		return finalTemp * 1000;
	} else if (info.chipsetID == RADEON_SUMO
		|| info.chipsetID == RADEON_SUMO2) {
		uint32 rawTemp = read32(info.registers + EVERGREEN_CG_THERMAL_STATUS)
			& 0xff;
		finalTemp = rawTemp - 49;

		return finalTemp * 1000;
	} else if (info.chipsetID >= RADEON_CEDAR) {
		rawTemp = (read32(info.registers + EVERGREEN_CG_MULT_THERMAL_STATUS)
			& EVERGREEN_ASIC_T_MASK) >> EVERGREEN_ASIC_T_SHIFT;

		if (rawTemp & 0x400)
			finalTemp = -256;
		else if (rawTemp & 0x200)
			finalTemp = 255;
		else if (rawTemp & 0x100) {
			finalTemp = rawTemp & 0x1ff;
			finalTemp |= ~0x1ff;
		} else
			finalTemp = rawTemp & 0xff;

		return (finalTemp * 1000) / 2;
	} else if (info.chipsetID >= RADEON_RV770) {
		rawTemp = (read32(info.registers + R700_CG_MULT_THERMAL_STATUS)
			& R700_ASIC_T_MASK) >> R700_ASIC_T_SHIFT;
		if (rawTemp & 0x400)
			finalTemp = -256;
		else if (rawTemp & 0x200)
			finalTemp = 255;
		else if (rawTemp & 0x100) {
			finalTemp = rawTemp & 0x1ff;
			finalTemp |= ~0x1ff;
		} else
			finalTemp = rawTemp & 0xff;

		return (finalTemp * 1000) / 2;
	} else if (info.chipsetID >= RADEON_R600) {
		rawTemp = (read32(info.registers + R600_CG_THERMAL_STATUS)
			& R600_ASIC_T_MASK) >> R600_ASIC_T_SHIFT;
		finalTemp = rawTemp & 0xff;

		if (rawTemp & 0x100)
			finalTemp -= 256;

		return finalTemp * 1000;
	}

	return -1;
}