/*
 * Copyright 2012 Advanced Micro Devices, Inc.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 * OTHER DEALINGS IN THE SOFTWARE.
 *
 */

#include "drmP.h"
#include "radeon.h"
#include "sumod.h"
#include "sumo_dpm.h"
#include "ppsmc.h"

#define SUMO_SMU_SERVICE_ROUTINE_PG_INIT        1
#define SUMO_SMU_SERVICE_ROUTINE_ALTVDDNB_NOTIFY  27
#define SUMO_SMU_SERVICE_ROUTINE_GFX_SRV_ID_20  20

struct sumo_power_info *sumo_get_pi(struct radeon_device *rdev);

static void sumo_send_msg_to_smu(struct radeon_device *rdev, u32 id)
{
	u32 gfx_int_req;
	int i;

	for (i = 0; i < rdev->usec_timeout; i++) {
		if (RREG32(GFX_INT_STATUS) & INT_DONE)
			break;
		udelay(1);
	}

	gfx_int_req = SERV_INDEX(id) | INT_REQ;
	WREG32(GFX_INT_REQ, gfx_int_req);

	for (i = 0; i < rdev->usec_timeout; i++) {
		if (RREG32(GFX_INT_REQ) & INT_REQ)
			break;
		udelay(1);
	}

	for (i = 0; i < rdev->usec_timeout; i++) {
		if (RREG32(GFX_INT_STATUS) & INT_ACK)
			break;
		udelay(1);
	}

	for (i = 0; i < rdev->usec_timeout; i++) {
		if (RREG32(GFX_INT_STATUS) & INT_DONE)
			break;
		udelay(1);
	}

	gfx_int_req &= ~INT_REQ;
	WREG32(GFX_INT_REQ, gfx_int_req);
}

void sumo_initialize_m3_arb(struct radeon_device *rdev)
{
	struct sumo_power_info *pi = sumo_get_pi(rdev);
	u32 i;

	if (!pi->enable_dynamic_m3_arbiter)
		return;

	for (i = 0; i < NUMBER_OF_M3ARB_PARAM_SETS; i++)
		WREG32_RCU(MCU_M3ARB_PARAMS + (i * 4),
			   pi->sys_info.csr_m3_arb_cntl_default[i]);

	for (; i < NUMBER_OF_M3ARB_PARAM_SETS * 2; i++)
		WREG32_RCU(MCU_M3ARB_PARAMS + (i * 4),
			   pi->sys_info.csr_m3_arb_cntl_uvd[i % NUMBER_OF_M3ARB_PARAM_SETS]);

	for (; i < NUMBER_OF_M3ARB_PARAM_SETS * 3; i++)
		WREG32_RCU(MCU_M3ARB_PARAMS + (i * 4),
			   pi->sys_info.csr_m3_arb_cntl_fs3d[i % NUMBER_OF_M3ARB_PARAM_SETS]);
}

static bool sumo_is_alt_vddnb_supported(struct radeon_device *rdev)
{
	struct sumo_power_info *pi = sumo_get_pi(rdev);
	bool return_code = false;

	if (!pi->enable_alt_vddnb)
		return return_code;

	if ((rdev->family == CHIP_SUMO) || (rdev->family == CHIP_SUMO2)) {
		if (pi->fw_version >= 0x00010C00)
			return_code = true;
	}

	return return_code;
}

void sumo_smu_notify_alt_vddnb_change(struct radeon_device *rdev,
				      bool powersaving, bool force_nbps1)
{
	u32 param = 0;

	if (!sumo_is_alt_vddnb_supported(rdev))
		return;

	if (powersaving)
		param |= 1;

	if (force_nbps1)
		param |= 2;

	WREG32_RCU(RCU_ALTVDDNB_NOTIFY, param);

	sumo_send_msg_to_smu(rdev, SUMO_SMU_SERVICE_ROUTINE_ALTVDDNB_NOTIFY);
}

void sumo_smu_pg_init(struct radeon_device *rdev)
{
	sumo_send_msg_to_smu(rdev, SUMO_SMU_SERVICE_ROUTINE_PG_INIT);
}

static u32 sumo_power_of_4(u32 unit)
{
	u32 ret = 1;
	u32 i;

	for (i = 0; i < unit; i++)
		ret *= 4;

	return ret;
}

void sumo_enable_boost_timer(struct radeon_device *rdev)
{
	struct sumo_power_info *pi = sumo_get_pi(rdev);
	u32 period, unit, timer_value;
	u32 xclk = radeon_get_xclk(rdev);

	unit = (RREG32_RCU(RCU_LCLK_SCALING_CNTL) & LCLK_SCALING_TIMER_PRESCALER_MASK)
		>> LCLK_SCALING_TIMER_PRESCALER_SHIFT;

	period = 100 * (xclk / 100 / sumo_power_of_4(unit));

	timer_value = (period << 16) | (unit << 4);

	WREG32_RCU(RCU_GNB_PWR_REP_TIMER_CNTL, timer_value);
	WREG32_RCU(RCU_BOOST_MARGIN, pi->sys_info.sclk_dpm_boost_margin);
	WREG32_RCU(RCU_THROTTLE_MARGIN, pi->sys_info.sclk_dpm_throttle_margin);
	WREG32_RCU(GNB_TDP_LIMIT, pi->sys_info.gnb_tdp_limit);
	WREG32_RCU(RCU_SclkDpmTdpLimitPG, pi->sys_info.sclk_dpm_tdp_limit_pg);

	sumo_send_msg_to_smu(rdev, SUMO_SMU_SERVICE_ROUTINE_GFX_SRV_ID_20);
}

void sumo_set_tdp_limit(struct radeon_device *rdev, u32 index, u32 tdp_limit)
{
	u32 regoffset = 0;
	u32 shift = 0;
	u32 mask = 0xFFF;
	u32 sclk_dpm_tdp_limit;

	switch (index) {
	case 0:
		regoffset = RCU_SclkDpmTdpLimit01;
		shift = 16;
		break;
	case 1:
		regoffset = RCU_SclkDpmTdpLimit01;
		shift = 0;
		break;
	case 2:
		regoffset = RCU_SclkDpmTdpLimit23;
		shift = 16;
		break;
	case 3:
		regoffset = RCU_SclkDpmTdpLimit23;
		shift = 0;
		break;
	case 4:
		regoffset = RCU_SclkDpmTdpLimit47;
		shift = 16;
		break;
	case 7:
		regoffset = RCU_SclkDpmTdpLimit47;
		shift = 0;
		break;
	default:
		break;
	}

	sclk_dpm_tdp_limit = RREG32_RCU(regoffset);
	sclk_dpm_tdp_limit &= ~(mask << shift);
	sclk_dpm_tdp_limit |= (tdp_limit << shift);
	WREG32_RCU(regoffset, sclk_dpm_tdp_limit);
}

void sumo_boost_state_enable(struct radeon_device *rdev, bool enable)
{
	u32 boost_disable = RREG32_RCU(RCU_GPU_BOOST_DISABLE);

	boost_disable &= 0xFFFFFFFE;
	boost_disable |= (enable ? 0 : 1);
	WREG32_RCU(RCU_GPU_BOOST_DISABLE, boost_disable);
}

u32 sumo_get_running_fw_version(struct radeon_device *rdev)
{
	return RREG32_RCU(RCU_FW_VERSION);
}

