// SPDX-License-Identifier: GPL-2.0
/*
 * DFL device driver for EMIF private feature
 *
 * Copyright (C) 2020 Intel Corporation, Inc.
 *
 */
#include <linux/bitfield.h>
#include <linux/dfl.h>
#include <linux/errno.h>
#include <linux/io.h>
#include <linux/iopoll.h>
#include <linux/io-64-nonatomic-lo-hi.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/spinlock.h>
#include <linux/types.h>

#define FME_FEATURE_ID_EMIF		0x9

#define EMIF_STAT			0x8
#define EMIF_STAT_INIT_DONE_SFT		0
#define EMIF_STAT_CALC_FAIL_SFT		8
#define EMIF_STAT_CLEAR_BUSY_SFT	16
#define EMIF_CTRL			0x10
#define EMIF_CTRL_CLEAR_EN_SFT		0
#define EMIF_CTRL_CLEAR_EN_MSK		GENMASK_ULL(3, 0)

#define EMIF_POLL_INVL			10000 /* us */
#define EMIF_POLL_TIMEOUT		5000000 /* us */

struct dfl_emif {
	struct device *dev;
	void __iomem *base;
	spinlock_t lock;	/* Serialises access to EMIF_CTRL reg */
};

struct emif_attr {
	struct device_attribute attr;
	u32 shift;
	u32 index;
};

#define to_emif_attr(dev_attr) \
	container_of(dev_attr, struct emif_attr, attr)

static ssize_t emif_state_show(struct device *dev,
			       struct device_attribute *attr, char *buf)
{
	struct emif_attr *eattr = to_emif_attr(attr);
	struct dfl_emif *de = dev_get_drvdata(dev);
	u64 val;

	val = readq(de->base + EMIF_STAT);

	return sysfs_emit(buf, "%u\n",
			  !!(val & BIT_ULL(eattr->shift + eattr->index)));
}

static ssize_t emif_clear_store(struct device *dev,
				struct device_attribute *attr,
				const char *buf, size_t count)
{
	struct emif_attr *eattr = to_emif_attr(attr);
	struct dfl_emif *de = dev_get_drvdata(dev);
	u64 clear_busy_msk, clear_en_msk, val;
	void __iomem *base = de->base;

	if (!sysfs_streq(buf, "1"))
		return -EINVAL;

	clear_busy_msk = BIT_ULL(EMIF_STAT_CLEAR_BUSY_SFT + eattr->index);
	clear_en_msk = BIT_ULL(EMIF_CTRL_CLEAR_EN_SFT + eattr->index);

	spin_lock(&de->lock);
	/* The CLEAR_EN field is WO, but other fields are RW */
	val = readq(base + EMIF_CTRL);
	val &= ~EMIF_CTRL_CLEAR_EN_MSK;
	val |= clear_en_msk;
	writeq(val, base + EMIF_CTRL);
	spin_unlock(&de->lock);

	if (readq_poll_timeout(base + EMIF_STAT, val,
			       !(val & clear_busy_msk),
			       EMIF_POLL_INVL, EMIF_POLL_TIMEOUT)) {
		dev_err(de->dev, "timeout, fail to clear\n");
		return -ETIMEDOUT;
	}

	return count;
}

#define emif_state_attr(_name, _shift, _index)				\
	static struct emif_attr emif_attr_##inf##_index##_##_name =	\
		{ .attr = __ATTR(inf##_index##_##_name, 0444,		\
				 emif_state_show, NULL),		\
		  .shift = (_shift), .index = (_index) }

#define emif_clear_attr(_index)						\
	static struct emif_attr emif_attr_##inf##_index##_clear =	\
		{ .attr = __ATTR(inf##_index##_clear, 0200,		\
				 NULL, emif_clear_store),		\
		  .index = (_index) }

emif_state_attr(init_done, EMIF_STAT_INIT_DONE_SFT, 0);
emif_state_attr(init_done, EMIF_STAT_INIT_DONE_SFT, 1);
emif_state_attr(init_done, EMIF_STAT_INIT_DONE_SFT, 2);
emif_state_attr(init_done, EMIF_STAT_INIT_DONE_SFT, 3);

emif_state_attr(cal_fail, EMIF_STAT_CALC_FAIL_SFT, 0);
emif_state_attr(cal_fail, EMIF_STAT_CALC_FAIL_SFT, 1);
emif_state_attr(cal_fail, EMIF_STAT_CALC_FAIL_SFT, 2);
emif_state_attr(cal_fail, EMIF_STAT_CALC_FAIL_SFT, 3);

emif_clear_attr(0);
emif_clear_attr(1);
emif_clear_attr(2);
emif_clear_attr(3);

static struct attribute *dfl_emif_attrs[] = {
	&emif_attr_inf0_init_done.attr.attr,
	&emif_attr_inf0_cal_fail.attr.attr,
	&emif_attr_inf0_clear.attr.attr,

	&emif_attr_inf1_init_done.attr.attr,
	&emif_attr_inf1_cal_fail.attr.attr,
	&emif_attr_inf1_clear.attr.attr,

	&emif_attr_inf2_init_done.attr.attr,
	&emif_attr_inf2_cal_fail.attr.attr,
	&emif_attr_inf2_clear.attr.attr,

	&emif_attr_inf3_init_done.attr.attr,
	&emif_attr_inf3_cal_fail.attr.attr,
	&emif_attr_inf3_clear.attr.attr,

	NULL,
};

static umode_t dfl_emif_visible(struct kobject *kobj,
				struct attribute *attr, int n)
{
	struct dfl_emif *de = dev_get_drvdata(kobj_to_dev(kobj));
	struct emif_attr *eattr = container_of(attr, struct emif_attr,
					       attr.attr);
	u64 val;

	/*
	 * This device supports upto 4 memory interfaces, but not all
	 * interfaces are used on different platforms. The read out value of
	 * CLEAN_EN field (which is a bitmap) could tell how many interfaces
	 * are available.
	 */
	val = FIELD_GET(EMIF_CTRL_CLEAR_EN_MSK, readq(de->base + EMIF_CTRL));

	return (val & BIT_ULL(eattr->index)) ? attr->mode : 0;
}

static const struct attribute_group dfl_emif_group = {
	.is_visible = dfl_emif_visible,
	.attrs = dfl_emif_attrs,
};

static const struct attribute_group *dfl_emif_groups[] = {
	&dfl_emif_group,
	NULL,
};

static int dfl_emif_probe(struct dfl_device *ddev)
{
	struct device *dev = &ddev->dev;
	struct dfl_emif *de;

	de = devm_kzalloc(dev, sizeof(*de), GFP_KERNEL);
	if (!de)
		return -ENOMEM;

	de->base = devm_ioremap_resource(dev, &ddev->mmio_res);
	if (IS_ERR(de->base))
		return PTR_ERR(de->base);

	de->dev = dev;
	spin_lock_init(&de->lock);
	dev_set_drvdata(dev, de);

	return 0;
}

static const struct dfl_device_id dfl_emif_ids[] = {
	{ FME_ID, FME_FEATURE_ID_EMIF },
	{ }
};
MODULE_DEVICE_TABLE(dfl, dfl_emif_ids);

static struct dfl_driver dfl_emif_driver = {
	.drv	= {
		.name       = "dfl-emif",
		.dev_groups = dfl_emif_groups,
	},
	.id_table = dfl_emif_ids,
	.probe   = dfl_emif_probe,
};
module_dfl_driver(dfl_emif_driver);

MODULE_DESCRIPTION("DFL EMIF driver");
MODULE_AUTHOR("Intel Corporation");
MODULE_LICENSE("GPL v2");
