// SPDX-License-Identifier: GPL-2.0
/*
 * AMD Platform Management Framework Driver - Smart PC Capabilities
 *
 * Copyright (c) 2023, Advanced Micro Devices, Inc.
 * All Rights Reserved.
 *
 * Authors: Shyam Sundar S K <Shyam-sundar.S-k@amd.com>
 *          Patil Rajesh Reddy <Patil.Reddy@amd.com>
 */

#include <acpi/button.h>
#include <linux/amd-pmf-io.h>
#include <linux/power_supply.h>
#include <linux/units.h>
#include "pmf.h"

#ifdef CONFIG_AMD_PMF_DEBUG
static const char *ta_slider_as_str(unsigned int state)
{
	switch (state) {
	case TA_BEST_PERFORMANCE:
		return "PERFORMANCE";
	case TA_BETTER_PERFORMANCE:
		return "BALANCED";
	case TA_BEST_BATTERY:
		return "POWER_SAVER";
	default:
		return "Unknown TA Slider State";
	}
}

void amd_pmf_dump_ta_inputs(struct amd_pmf_dev *dev, struct ta_pmf_enact_table *in)
{
	dev_dbg(dev->dev, "==== TA inputs START ====\n");
	dev_dbg(dev->dev, "Slider State: %s\n", ta_slider_as_str(in->ev_info.power_slider));
	dev_dbg(dev->dev, "Power Source: %s\n", amd_pmf_source_as_str(in->ev_info.power_source));
	dev_dbg(dev->dev, "Battery Percentage: %u\n", in->ev_info.bat_percentage);
	dev_dbg(dev->dev, "Designed Battery Capacity: %u\n", in->ev_info.bat_design);
	dev_dbg(dev->dev, "Fully Charged Capacity: %u\n", in->ev_info.full_charge_capacity);
	dev_dbg(dev->dev, "Drain Rate: %d\n", in->ev_info.drain_rate);
	dev_dbg(dev->dev, "Socket Power: %u\n", in->ev_info.socket_power);
	dev_dbg(dev->dev, "Skin Temperature: %u\n", in->ev_info.skin_temperature);
	dev_dbg(dev->dev, "Avg C0 Residency: %u\n", in->ev_info.avg_c0residency);
	dev_dbg(dev->dev, "Max C0 Residency: %u\n", in->ev_info.max_c0residency);
	dev_dbg(dev->dev, "GFX Busy: %u\n", in->ev_info.gfx_busy);
	dev_dbg(dev->dev, "LID State: %s\n", in->ev_info.lid_state ? "close" : "open");
	dev_dbg(dev->dev, "User Presence: %s\n", in->ev_info.user_present ? "Present" : "Away");
	dev_dbg(dev->dev, "Ambient Light: %d\n", in->ev_info.ambient_light);
	dev_dbg(dev->dev, "==== TA inputs END ====\n");
}
#else
void amd_pmf_dump_ta_inputs(struct amd_pmf_dev *dev, struct ta_pmf_enact_table *in) {}
#endif

static void amd_pmf_get_c0_residency(u16 *core_res, size_t size, struct ta_pmf_enact_table *in)
{
	u16 max, avg = 0;
	int i;

	/* Get the avg and max C0 residency of all the cores */
	max = *core_res;
	for (i = 0; i < size; i++) {
		avg += core_res[i];
		if (core_res[i] > max)
			max = core_res[i];
	}
	avg = DIV_ROUND_CLOSEST(avg, size);
	in->ev_info.avg_c0residency = avg;
	in->ev_info.max_c0residency = max;
}

static void amd_pmf_get_smu_info(struct amd_pmf_dev *dev, struct ta_pmf_enact_table *in)
{
	/* Get the updated metrics table data */
	memset(dev->buf, 0, dev->mtable_size);
	amd_pmf_send_cmd(dev, SET_TRANSFER_TABLE, 0, 7, NULL);

	switch (dev->cpu_id) {
	case AMD_CPU_ID_PS:
		memcpy(&dev->m_table, dev->buf, dev->mtable_size);
		in->ev_info.socket_power = dev->m_table.apu_power + dev->m_table.dgpu_power;
		in->ev_info.skin_temperature = dev->m_table.skin_temp;
		in->ev_info.gfx_busy = dev->m_table.avg_gfx_activity;
		amd_pmf_get_c0_residency(dev->m_table.avg_core_c0residency,
					 ARRAY_SIZE(dev->m_table.avg_core_c0residency), in);
		break;
	case PCI_DEVICE_ID_AMD_1AH_M20H_ROOT:
	case PCI_DEVICE_ID_AMD_1AH_M60H_ROOT:
		memcpy(&dev->m_table_v2, dev->buf, dev->mtable_size);
		in->ev_info.socket_power = dev->m_table_v2.apu_power + dev->m_table_v2.dgpu_power;
		in->ev_info.skin_temperature = dev->m_table_v2.skin_temp;
		in->ev_info.gfx_busy = dev->m_table_v2.gfx_activity;
		amd_pmf_get_c0_residency(dev->m_table_v2.core_c0residency,
					 ARRAY_SIZE(dev->m_table_v2.core_c0residency), in);
		break;
	default:
		dev_err(dev->dev, "Unsupported CPU id: 0x%x", dev->cpu_id);
	}
}

static const char * const pmf_battery_supply_name[] = {
	"BATT",
	"BAT0",
};

static int amd_pmf_get_battery_prop(enum power_supply_property prop)
{
	union power_supply_propval value;
	struct power_supply *psy;
	int i, ret;

	for (i = 0; i < ARRAY_SIZE(pmf_battery_supply_name); i++) {
		psy = power_supply_get_by_name(pmf_battery_supply_name[i]);
		if (!psy)
			continue;

		ret = power_supply_get_property(psy, prop, &value);
		if (ret) {
			power_supply_put(psy);
			return ret;
		}
	}

	return value.intval;
}

static int amd_pmf_get_battery_info(struct amd_pmf_dev *dev, struct ta_pmf_enact_table *in)
{
	int val;

	val = amd_pmf_get_battery_prop(POWER_SUPPLY_PROP_PRESENT);
	if (val < 0)
		return val;
	if (val != 1)
		return -ENODEV;

	in->ev_info.bat_percentage = amd_pmf_get_battery_prop(POWER_SUPPLY_PROP_CAPACITY);
	/* all values in mWh metrics */
	in->ev_info.bat_design = amd_pmf_get_battery_prop(POWER_SUPPLY_PROP_ENERGY_FULL_DESIGN) /
		MILLIWATT_PER_WATT;
	in->ev_info.full_charge_capacity = amd_pmf_get_battery_prop(POWER_SUPPLY_PROP_ENERGY_FULL) /
		MILLIWATT_PER_WATT;
	in->ev_info.drain_rate = amd_pmf_get_battery_prop(POWER_SUPPLY_PROP_POWER_NOW) /
		MILLIWATT_PER_WATT;

	return 0;
}

static int amd_pmf_get_slider_info(struct amd_pmf_dev *dev, struct ta_pmf_enact_table *in)
{
	int val;

	switch (dev->current_profile) {
	case PLATFORM_PROFILE_PERFORMANCE:
		val = TA_BEST_PERFORMANCE;
		break;
	case PLATFORM_PROFILE_BALANCED:
		val = TA_BETTER_PERFORMANCE;
		break;
	case PLATFORM_PROFILE_LOW_POWER:
		val = TA_BEST_BATTERY;
		break;
	default:
		dev_err(dev->dev, "Unknown Platform Profile.\n");
		return -EOPNOTSUPP;
	}
	in->ev_info.power_slider = val;

	return 0;
}

static void amd_pmf_get_sensor_info(struct amd_pmf_dev *dev, struct ta_pmf_enact_table *in)
{
	struct amd_sfh_info sfh_info;

	/* Get the latest information from SFH */
	in->ev_info.user_present = false;

	/* Get ALS data */
	if (!amd_get_sfh_info(&sfh_info, MT_ALS))
		in->ev_info.ambient_light = sfh_info.ambient_light;
	else
		dev_dbg(dev->dev, "ALS is not enabled/detected\n");

	/* get HPD data */
	if (!amd_get_sfh_info(&sfh_info, MT_HPD)) {
		if (sfh_info.user_present == SFH_USER_PRESENT)
			in->ev_info.user_present = true;
	} else {
		dev_dbg(dev->dev, "HPD is not enabled/detected\n");
	}
}

void amd_pmf_populate_ta_inputs(struct amd_pmf_dev *dev, struct ta_pmf_enact_table *in)
{
	/* TA side lid open is 1 and close is 0, hence the ! here */
	in->ev_info.lid_state = !acpi_lid_open();
	in->ev_info.power_source = amd_pmf_get_power_source();
	amd_pmf_get_smu_info(dev, in);
	amd_pmf_get_battery_info(dev, in);
	amd_pmf_get_slider_info(dev, in);
	amd_pmf_get_sensor_info(dev, in);
}
