// SPDX-License-Identifier: GPL-2.0
/*
 * Driver for Intel(R) servers with Integrated Memory/IO Hub-based memory controller.
 * Copyright (c) 2025, Intel Corporation.
 */

#include <linux/kernel.h>
#include <linux/io.h>
#include <asm/cpu_device_id.h>
#include <asm/intel-family.h>
#include <asm/mce.h>
#include <asm/cpu.h>
#include "edac_module.h"
#include "skx_common.h"

#define IMH_REVISION	"v0.0.1"
#define EDAC_MOD_STR	"imh_edac"

/* Debug macros */
#define imh_printk(level, fmt, arg...)	\
	edac_printk(level, "imh", fmt, ##arg)

/* Configuration Agent(Ubox) */
#define MMIO_BASE_H(reg)		(((u64)GET_BITFIELD(reg, 0, 29)) << 23)
#define SOCKET_ID(reg)			GET_BITFIELD(reg, 0, 3)

/* PUNIT */
#define DDR_IMC_BITMAP(reg)		GET_BITFIELD(reg, 23, 30)

/* Memory Controller */
#define ECC_ENABLED(reg)		GET_BITFIELD(reg, 2, 2)
#define DIMM_POPULATED(reg)		GET_BITFIELD(reg, 15, 15)

/* System Cache Agent(SCA) */
#define TOLM(reg)			(((u64)GET_BITFIELD(reg, 16, 31)) << 16)
#define TOHM(reg)			(((u64)GET_BITFIELD(reg, 16, 51)) << 16)

/* Home Agent (HA) */
#define NMCACHING(reg)			GET_BITFIELD(reg, 8, 8)

/**
 * struct local_reg - A register as described in the local package view.
 *
 * @pkg: (input)	The package where the register is located.
 * @pbase: (input)	The IP MMIO base physical address in the local package view.
 * @size: (input)	The IP MMIO size.
 * @offset: (input)	The register offset from the IP MMIO base @pbase.
 * @width: (input)	The register width in byte.
 * @vbase: (internal)	The IP MMIO base virtual address.
 * @val: (output)	The register value.
 */
struct local_reg {
	int pkg;
	u64 pbase;
	u32 size;
	u32 offset;
	u8  width;
	void __iomem *vbase;
	u64 val;
};

#define DEFINE_LOCAL_REG(name, cfg, package, north, ip_name, ip_idx, reg_name)	\
	struct local_reg name = {						\
		.pkg	= package,						\
		.pbase	= (north ? (cfg)->mmio_base_l_north :			\
			  (cfg)->mmio_base_l_south) +				\
			  (cfg)->ip_name##_base +				\
			  (cfg)->ip_name##_size * (ip_idx),			\
		.size	= (cfg)->ip_name##_size,				\
		.offset	= (cfg)->ip_name##_reg_##reg_name##_offset,		\
		.width	= (cfg)->ip_name##_reg_##reg_name##_width,		\
	}

static u64 readx(void __iomem *addr, u8 width)
{
	switch (width) {
	case 1:
		return readb(addr);
	case 2:
		return readw(addr);
	case 4:
		return readl(addr);
	case 8:
		return readq(addr);
	default:
		imh_printk(KERN_ERR, "Invalid reg 0x%p width %d\n", addr, width);
		return 0;
	}
}

static void __read_local_reg(void *reg)
{
	struct local_reg *r = (struct local_reg *)reg;

	r->val = readx(r->vbase + r->offset, r->width);
}

/* Read a local-view register. */
static bool read_local_reg(struct local_reg *reg)
{
	int cpu;

	/* Get the target CPU in the package @reg->pkg. */
	for_each_online_cpu(cpu) {
		if (reg->pkg == topology_physical_package_id(cpu))
			break;
	}

	if (cpu >= nr_cpu_ids)
		return false;

	reg->vbase = ioremap(reg->pbase, reg->size);
	if (!reg->vbase) {
		imh_printk(KERN_ERR, "Failed to ioremap 0x%llx\n", reg->pbase);
		return false;
	}

	/* Get the target CPU to read the register. */
	smp_call_function_single(cpu, __read_local_reg, reg, 1);
	iounmap(reg->vbase);

	return true;
}

/* Get the bitmap of memory controller instances in package @pkg. */
static u32 get_imc_bitmap(struct res_config *cfg, int pkg, bool north)
{
	DEFINE_LOCAL_REG(reg, cfg, pkg, north, pcu, 0, capid3);

	if (!read_local_reg(&reg))
		return 0;

	edac_dbg(2, "Pkg%d %s mc instances bitmap 0x%llx (reg 0x%llx)\n",
		 pkg, north ? "north" : "south",
		 DDR_IMC_BITMAP(reg.val), reg.val);

	return DDR_IMC_BITMAP(reg.val);
}

static void imc_release(struct device *dev)
{
	edac_dbg(2, "imc device %s released\n", dev_name(dev));
	kfree(dev);
}

static int __get_ddr_munits(struct res_config *cfg, struct skx_dev *d,
			    bool north, int lmc)
{
	unsigned long size = cfg->ddr_chan_mmio_sz * cfg->ddr_chan_num;
	unsigned long bitmap = get_imc_bitmap(cfg, d->pkg, north);
	void __iomem *mbase;
	struct device *dev;
	int i, rc, pmc;
	u64 base;

	for_each_set_bit(i, &bitmap, sizeof(bitmap) * 8) {
		base  = north ? d->mmio_base_h_north : d->mmio_base_h_south;
		base += cfg->ddr_imc_base + size * i;

		edac_dbg(2, "Pkg%d mc%d mmio base 0x%llx size 0x%lx\n",
			 d->pkg, lmc, base, size);

		/* Set up the imc MMIO. */
		mbase = ioremap(base, size);
		if (!mbase) {
			imh_printk(KERN_ERR, "Failed to ioremap 0x%llx\n", base);
			return -ENOMEM;
		}

		d->imc[lmc].mbase = mbase;
		d->imc[lmc].lmc = lmc;

		/* Create the imc device instance. */
		dev = kzalloc_obj(*dev);
		if (!dev)
			return -ENOMEM;

		dev->release = imc_release;
		device_initialize(dev);
		rc = dev_set_name(dev, "0x%llx", base);
		if (rc) {
			imh_printk(KERN_ERR, "Failed to set dev name\n");
			put_device(dev);
			return rc;
		}

		d->imc[lmc].dev = dev;

		/* Set up the imc index mapping. */
		pmc = north ? i : 8 + i;
		skx_set_mc_mapping(d, pmc, lmc);

		lmc++;
	}

	return lmc;
}

static bool get_ddr_munits(struct res_config *cfg, struct skx_dev *d)
{
	int lmc = __get_ddr_munits(cfg, d, true, 0);

	if (lmc < 0)
		return false;

	lmc = __get_ddr_munits(cfg, d, false, lmc);
	if (lmc <= 0)
		return false;

	return true;
}

static bool get_socket_id(struct res_config *cfg, struct skx_dev *d)
{
	DEFINE_LOCAL_REG(reg, cfg, d->pkg, true, ubox, 0, socket_id);
	u8 src_id;
	int i;

	if (!read_local_reg(&reg))
		return false;

	src_id = SOCKET_ID(reg.val);
	edac_dbg(2, "socket id 0x%x (reg 0x%llx)\n", src_id, reg.val);

	for (i = 0; i < cfg->ddr_imc_num; i++)
		d->imc[i].src_id   = src_id;

	return true;
}

/* Get TOLM (Top Of Low Memory) and TOHM (Top Of High Memory) parameters. */
static bool imh_get_tolm_tohm(struct res_config *cfg, u64 *tolm, u64 *tohm)
{
	DEFINE_LOCAL_REG(reg, cfg, 0, true, sca, 0, tolm);

	if (!read_local_reg(&reg))
		return false;

	*tolm = TOLM(reg.val);
	edac_dbg(2, "tolm 0x%llx (reg 0x%llx)\n", *tolm, reg.val);

	DEFINE_LOCAL_REG(reg2, cfg, 0, true, sca, 0, tohm);

	if (!read_local_reg(&reg2))
		return false;

	*tohm = TOHM(reg2.val);
	edac_dbg(2, "tohm 0x%llx (reg 0x%llx)\n", *tohm, reg2.val);

	return true;
}

/* Get the system-view MMIO_BASE_H for {north,south}-IMH. */
static int imh_get_all_mmio_base_h(struct res_config *cfg, struct list_head *edac_list)
{
	int i, n = topology_max_packages(), imc_num = cfg->ddr_imc_num + cfg->hbm_imc_num;
	struct skx_dev *d;

	for (i = 0; i < n; i++) {
		d = kzalloc_flex(*d, imc, imc_num);
		if (!d)
			return -ENOMEM;

		DEFINE_LOCAL_REG(reg, cfg, i, true, ubox, 0, mmio_base);

		/* Get MMIO_BASE_H for the north-IMH. */
		if (!read_local_reg(&reg) || !reg.val) {
			kfree(d);
			imh_printk(KERN_ERR, "Pkg%d has no north mmio_base_h\n", i);
			return -ENODEV;
		}

		d->mmio_base_h_north = MMIO_BASE_H(reg.val);
		edac_dbg(2, "Pkg%d north mmio_base_h 0x%llx (reg 0x%llx)\n",
			 i, d->mmio_base_h_north, reg.val);

		/* Get MMIO_BASE_H for the south-IMH (optional). */
		DEFINE_LOCAL_REG(reg2, cfg, i, false, ubox, 0, mmio_base);

		if (read_local_reg(&reg2)) {
			d->mmio_base_h_south = MMIO_BASE_H(reg2.val);
			edac_dbg(2, "Pkg%d south mmio_base_h 0x%llx (reg 0x%llx)\n",
				 i, d->mmio_base_h_south, reg2.val);
		}

		d->pkg = i;
		d->num_imc = imc_num;
		skx_init_mc_mapping(d);
		list_add_tail(&d->list, edac_list);
	}

	return 0;
}

/* Get the number of per-package memory controllers. */
static int imh_get_imc_num(struct res_config *cfg)
{
	int imc_num = hweight32(get_imc_bitmap(cfg, 0, true)) +
		      hweight32(get_imc_bitmap(cfg, 0, false));

	if (!imc_num) {
		imh_printk(KERN_ERR, "Invalid mc number\n");
		return -ENODEV;
	}

	if (cfg->ddr_imc_num != imc_num) {
		/*
		 * Update the configuration data to reflect the number of
		 * present DDR memory controllers.
		 */
		cfg->ddr_imc_num = imc_num;
		edac_dbg(2, "Set ddr mc number %d\n", imc_num);
	}

	return 0;
}

/* Get all memory controllers' parameters. */
static int imh_get_munits(struct res_config *cfg, struct list_head *edac_list)
{
	struct skx_imc *imc;
	struct skx_dev *d;
	u8 mc = 0;
	int i;

	list_for_each_entry(d, edac_list, list) {
		if (!get_ddr_munits(cfg, d)) {
			imh_printk(KERN_ERR, "No mc found\n");
			return -ENODEV;
		}

		if (!get_socket_id(cfg, d)) {
			imh_printk(KERN_ERR, "Failed to get socket id\n");
			return -ENODEV;
		}

		for (i = 0; i < cfg->ddr_imc_num; i++) {
			imc = &d->imc[i];
			if (!imc->mbase)
				continue;

			imc->chan_mmio_sz = cfg->ddr_chan_mmio_sz;
			imc->num_channels = cfg->ddr_chan_num;
			imc->num_dimms    = cfg->ddr_dimm_num;
			imc->mc		  = mc++;
		}
	}

	return 0;
}

static bool check_2lm_enabled(struct res_config *cfg, struct skx_dev *d, int ha_idx)
{
	DEFINE_LOCAL_REG(reg, cfg, d->pkg, true, ha, ha_idx, mode);

	if (!read_local_reg(&reg))
		return false;

	if (!NMCACHING(reg.val))
		return false;

	edac_dbg(2, "2-level memory configuration (reg 0x%llx, ha idx %d)\n", reg.val, ha_idx);
	return true;
}

/* Check whether the system has a 2-level memory configuration. */
static bool imh_2lm_enabled(struct res_config *cfg, struct list_head *head)
{
	struct skx_dev *d;
	int i;

	list_for_each_entry(d, head, list) {
		for (i = 0; i < cfg->ddr_imc_num; i++)
			if (check_2lm_enabled(cfg, d, i))
				return true;
	}

	return false;
}

/* Helpers to read memory controller registers */
static u64 read_imc_reg(struct skx_imc *imc, int chan, u32 offset, u8 width)
{
	return readx(imc->mbase + imc->chan_mmio_sz * chan + offset, width);
}

static u32 read_imc_mcmtr(struct res_config *cfg, struct skx_imc *imc, int chan)
{
	return (u32)read_imc_reg(imc, chan, cfg->ddr_reg_mcmtr_offset, cfg->ddr_reg_mcmtr_width);
}

static u32 read_imc_dimmmtr(struct res_config *cfg, struct skx_imc *imc, int chan, int dimm)
{
	return (u32)read_imc_reg(imc, chan, cfg->ddr_reg_dimmmtr_offset +
				 cfg->ddr_reg_dimmmtr_width * dimm,
				 cfg->ddr_reg_dimmmtr_width);
}

static bool ecc_enabled(u32 mcmtr)
{
	return (bool)ECC_ENABLED(mcmtr);
}

static bool dimm_populated(u32 dimmmtr)
{
	return (bool)DIMM_POPULATED(dimmmtr);
}

/* Get each DIMM's configurations of the memory controller @mci. */
static int imh_get_dimm_config(struct mem_ctl_info *mci, struct res_config *cfg)
{
	struct skx_pvt *pvt = mci->pvt_info;
	struct skx_imc *imc = pvt->imc;
	struct dimm_info *dimm;
	u32 mcmtr, dimmmtr;
	int i, j, ndimms;

	for (i = 0; i < imc->num_channels; i++) {
		if (!imc->mbase)
			continue;

		mcmtr = read_imc_mcmtr(cfg, imc, i);

		for (ndimms = 0, j = 0; j < imc->num_dimms; j++) {
			dimmmtr = read_imc_dimmmtr(cfg, imc, i, j);
			edac_dbg(1, "mcmtr 0x%x dimmmtr 0x%x (mc%d ch%d dimm%d)\n",
				 mcmtr, dimmmtr, imc->mc, i, j);

			if (!dimm_populated(dimmmtr))
				continue;

			dimm = edac_get_dimm(mci, i, j, 0);
			ndimms += skx_get_dimm_info(dimmmtr, 0, 0, dimm,
						    imc, i, j, cfg);
		}

		if (ndimms && !ecc_enabled(mcmtr)) {
			imh_printk(KERN_ERR, "ECC is disabled on mc%d ch%d\n",
				   imc->mc, i);
			return -ENODEV;
		}
	}

	return 0;
}

/* Register all memory controllers to the EDAC core. */
static int imh_register_mci(struct res_config *cfg, struct list_head *edac_list)
{
	struct skx_imc *imc;
	struct skx_dev *d;
	int i, rc;

	list_for_each_entry(d, edac_list, list) {
		for (i = 0; i < cfg->ddr_imc_num; i++) {
			imc = &d->imc[i];
			if (!imc->mbase)
				continue;

			rc = skx_register_mci(imc, imc->dev,
					      dev_name(imc->dev),
					      "Intel IMH-based Socket",
					      EDAC_MOD_STR,
					      imh_get_dimm_config, cfg);
			if (rc)
				return rc;
		}
	}

	return 0;
}

static struct res_config dmr_cfg = {
	.type				= DMR,
	.support_ddr5			= true,
	.mmio_base_l_north		= 0xf6800000,
	.mmio_base_l_south		= 0xf6000000,
	.ddr_chan_num			= 1,
	.ddr_dimm_num			= 2,
	.ddr_imc_base			= 0x39b000,
	.ddr_chan_mmio_sz		= 0x8000,
	.ddr_reg_mcmtr_offset		= 0x360,
	.ddr_reg_mcmtr_width		= 4,
	.ddr_reg_dimmmtr_offset		= 0x370,
	.ddr_reg_dimmmtr_width		= 4,
	.ubox_base			= 0x0,
	.ubox_size			= 0x2000,
	.ubox_reg_mmio_base_offset	= 0x580,
	.ubox_reg_mmio_base_width	= 4,
	.ubox_reg_socket_id_offset	= 0x1080,
	.ubox_reg_socket_id_width	= 4,
	.pcu_base			= 0x3000,
	.pcu_size			= 0x10000,
	.pcu_reg_capid3_offset		= 0x290,
	.pcu_reg_capid3_width		= 4,
	.sca_base			= 0x24c000,
	.sca_size			= 0x2500,
	.sca_reg_tolm_offset		= 0x2100,
	.sca_reg_tolm_width		= 8,
	.sca_reg_tohm_offset		= 0x2108,
	.sca_reg_tohm_width		= 8,
	.ha_base			= 0x3eb000,
	.ha_size			= 0x1000,
	.ha_reg_mode_offset		= 0x4a0,
	.ha_reg_mode_width		= 4,
};

static const struct x86_cpu_id imh_cpuids[] = {
	X86_MATCH_VFM(INTEL_DIAMONDRAPIDS_X, &dmr_cfg),
	{}
};
MODULE_DEVICE_TABLE(x86cpu, imh_cpuids);

static struct notifier_block imh_mce_dec = {
	.notifier_call	= skx_mce_check_error,
	.priority	= MCE_PRIO_EDAC,
};

static int __init imh_init(void)
{
	const struct x86_cpu_id *id;
	struct list_head *edac_list;
	struct res_config *cfg;
	const char *owner;
	u64 tolm, tohm;
	int rc;

	edac_dbg(2, "\n");

	if (ghes_get_devices())
		return -EBUSY;

	owner = edac_get_owner();
	if (owner && strncmp(owner, EDAC_MOD_STR, sizeof(EDAC_MOD_STR)))
		return -EBUSY;

	if (cpu_feature_enabled(X86_FEATURE_HYPERVISOR))
		return -ENODEV;

	id = x86_match_cpu(imh_cpuids);
	if (!id)
		return -ENODEV;
	cfg = (struct res_config *)id->driver_data;
	skx_set_res_cfg(cfg);

	if (!imh_get_tolm_tohm(cfg, &tolm, &tohm))
		return -ENODEV;

	skx_set_hi_lo(tolm, tohm);

	rc = imh_get_imc_num(cfg);
	if (rc < 0)
		goto fail;

	edac_list = skx_get_edac_list();

	rc = imh_get_all_mmio_base_h(cfg, edac_list);
	if (rc)
		goto fail;

	rc = imh_get_munits(cfg, edac_list);
	if (rc)
		goto fail;

	skx_set_mem_cfg(imh_2lm_enabled(cfg, edac_list));

	rc = imh_register_mci(cfg, edac_list);
	if (rc)
		goto fail;

	rc = skx_adxl_get();
	if (rc)
		goto fail;

	opstate_init();
	mce_register_decode_chain(&imh_mce_dec);
	skx_setup_debug("imh_test");

	imh_printk(KERN_INFO, "%s\n", IMH_REVISION);

	return 0;
fail:
	skx_remove();
	return rc;
}

static void __exit imh_exit(void)
{
	edac_dbg(2, "\n");

	skx_teardown_debug();
	mce_unregister_decode_chain(&imh_mce_dec);
	skx_adxl_put();
	skx_remove();
}

module_init(imh_init);
module_exit(imh_exit);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("Qiuxu Zhuo");
MODULE_DESCRIPTION("MC Driver for Intel servers using IMH-based memory controller");
