// SPDX-License-Identifier: GPL-2.0-only
/*
 * Mapping of TPMI power domains CPU mapping
 *
 * Copyright (c) 2024, Intel Corporation.
 */

#include <linux/bitfield.h>
#include <linux/cleanup.h>
#include <linux/cpuhotplug.h>
#include <linux/cpumask.h>
#include <linux/errno.h>
#include <linux/export.h>
#include <linux/hashtable.h>
#include <linux/module.h>
#include <linux/mutex.h>
#include <linux/overflow.h>
#include <linux/slab.h>
#include <linux/topology.h>
#include <linux/types.h>

#include <asm/cpu_device_id.h>
#include <asm/intel-family.h>
#include <asm/msr.h>

#include "tpmi_power_domains.h"

#define MSR_PM_LOGICAL_ID       0x54

/*
 * Struct of MSR 0x54
 * [15:11] PM_DOMAIN_ID
 * [10:3] MODULE_ID (aka IDI_AGENT_ID)
 * [2:0] LP_ID
 * For Atom:
 *   [2] Always 0
 *   [1:0] core ID within module
 * For Core
 *   [2:1] Always 0
 *   [0] thread ID
 */

#define LP_ID_MASK		GENMASK_ULL(2, 0)
#define MODULE_ID_MASK		GENMASK_ULL(10, 3)
#define PM_DOMAIN_ID_MASK	GENMASK_ULL(15, 11)

/**
 * struct tpmi_cpu_info - Mapping information for a CPU
 * @hnode: Used to add mapping information to hash list
 * @linux_cpu:	Linux CPU number
 * @pkg_id: Package ID of this CPU
 * @punit_thread_id: Punit thread id of this CPU
 * @punit_core_id: Punit core id
 * @punit_domain_id: Power domain id from Punit
 *
 * Structure to store mapping information for a Linux CPU
 * to a Punit core, thread and power domain.
 */
struct tpmi_cpu_info {
	struct hlist_node hnode;
	int linux_cpu;
	u8 pkg_id;
	u8 punit_thread_id;
	u8 punit_core_id;
	u8 punit_domain_id;
};

static DEFINE_PER_CPU(struct tpmi_cpu_info, tpmi_cpu_info);

/* The dynamically assigned cpu hotplug state to free later */
static enum cpuhp_state tpmi_hp_state __read_mostly;

#define MAX_POWER_DOMAINS	8

static cpumask_t *tpmi_power_domain_mask;

/* Lock to protect tpmi_power_domain_mask and tpmi_cpu_hash */
static DEFINE_MUTEX(tpmi_lock);

static const struct x86_cpu_id tpmi_cpu_ids[] = {
	X86_MATCH_VFM(INTEL_GRANITERAPIDS_X,	NULL),
	X86_MATCH_VFM(INTEL_ATOM_CRESTMONT_X,	NULL),
	X86_MATCH_VFM(INTEL_ATOM_CRESTMONT,	NULL),
	X86_MATCH_VFM(INTEL_GRANITERAPIDS_D,	NULL),
	X86_MATCH_VFM(INTEL_PANTHERCOVE_X,	NULL),
	{}
};
MODULE_DEVICE_TABLE(x86cpu, tpmi_cpu_ids);

static DECLARE_HASHTABLE(tpmi_cpu_hash, 8);

static bool tpmi_domain_is_valid(struct tpmi_cpu_info *info)
{
	return info->pkg_id < topology_max_packages() &&
		info->punit_domain_id < MAX_POWER_DOMAINS;
}

int tpmi_get_linux_cpu_number(int package_id, int domain_id, int punit_core_id)
{
	struct tpmi_cpu_info *info;
	int ret = -EINVAL;

	guard(mutex)(&tpmi_lock);
	hash_for_each_possible(tpmi_cpu_hash, info, hnode, punit_core_id) {
		if (info->punit_domain_id == domain_id && info->pkg_id == package_id) {
			ret = info->linux_cpu;
			break;
		}
	}

	return ret;
}
EXPORT_SYMBOL_NS_GPL(tpmi_get_linux_cpu_number, INTEL_TPMI_POWER_DOMAIN);

int tpmi_get_punit_core_number(int cpu_no)
{
	if (cpu_no >= num_possible_cpus())
		return -EINVAL;

	return per_cpu(tpmi_cpu_info, cpu_no).punit_core_id;
}
EXPORT_SYMBOL_NS_GPL(tpmi_get_punit_core_number, INTEL_TPMI_POWER_DOMAIN);

int tpmi_get_power_domain_id(int cpu_no)
{
	if (cpu_no >= num_possible_cpus())
		return -EINVAL;

	return per_cpu(tpmi_cpu_info, cpu_no).punit_domain_id;
}
EXPORT_SYMBOL_NS_GPL(tpmi_get_power_domain_id, INTEL_TPMI_POWER_DOMAIN);

cpumask_t *tpmi_get_power_domain_mask(int cpu_no)
{
	struct tpmi_cpu_info *info;
	cpumask_t *mask;
	int index;

	if (cpu_no >= num_possible_cpus())
		return NULL;

	info = &per_cpu(tpmi_cpu_info, cpu_no);
	if (!tpmi_domain_is_valid(info))
		return NULL;

	index = info->pkg_id * MAX_POWER_DOMAINS + info->punit_domain_id;
	guard(mutex)(&tpmi_lock);
	mask = &tpmi_power_domain_mask[index];

	return mask;
}
EXPORT_SYMBOL_NS_GPL(tpmi_get_power_domain_mask, INTEL_TPMI_POWER_DOMAIN);

static int tpmi_get_logical_id(unsigned int cpu, struct tpmi_cpu_info *info)
{
	u64 data;
	int ret;

	ret = rdmsrl_safe(MSR_PM_LOGICAL_ID, &data);
	if (ret)
		return ret;

	info->punit_domain_id = FIELD_GET(PM_DOMAIN_ID_MASK, data);
	if (info->punit_domain_id >= MAX_POWER_DOMAINS)
		return -EINVAL;

	info->punit_thread_id = FIELD_GET(LP_ID_MASK, data);
	info->punit_core_id = FIELD_GET(MODULE_ID_MASK, data);
	info->pkg_id = topology_physical_package_id(cpu);
	info->linux_cpu = cpu;

	return 0;
}

static int tpmi_cpu_online(unsigned int cpu)
{
	struct tpmi_cpu_info *info = &per_cpu(tpmi_cpu_info, cpu);
	int ret, index;

	/* Don't fail CPU online for some bad mapping of CPUs */
	ret = tpmi_get_logical_id(cpu, info);
	if (ret)
		return 0;

	index = info->pkg_id * MAX_POWER_DOMAINS + info->punit_domain_id;

	guard(mutex)(&tpmi_lock);
	cpumask_set_cpu(cpu, &tpmi_power_domain_mask[index]);
	hash_add(tpmi_cpu_hash, &info->hnode, info->punit_core_id);

	return 0;
}

static int __init tpmi_init(void)
{
	const struct x86_cpu_id *id;
	u64 data;
	int ret;

	id = x86_match_cpu(tpmi_cpu_ids);
	if (!id)
		return -ENODEV;

	/* Check for MSR 0x54 presence */
	ret = rdmsrl_safe(MSR_PM_LOGICAL_ID, &data);
	if (ret)
		return ret;

	tpmi_power_domain_mask = kcalloc(size_mul(topology_max_packages(), MAX_POWER_DOMAINS),
					 sizeof(*tpmi_power_domain_mask), GFP_KERNEL);
	if (!tpmi_power_domain_mask)
		return -ENOMEM;

	ret = cpuhp_setup_state(CPUHP_AP_ONLINE_DYN,
				"platform/x86/tpmi_power_domains:online",
				tpmi_cpu_online, NULL);
	if (ret < 0) {
		kfree(tpmi_power_domain_mask);
		return ret;
	}

	tpmi_hp_state = ret;

	return 0;
}
module_init(tpmi_init)

static void __exit tpmi_exit(void)
{
	cpuhp_remove_state(tpmi_hp_state);
	kfree(tpmi_power_domain_mask);
}
module_exit(tpmi_exit)

MODULE_DESCRIPTION("TPMI Power Domains Mapping");
MODULE_LICENSE("GPL");
