// SPDX-License-Identifier: (BSD-3-Clause OR GPL-2.0-only)
/* Copyright(c) 2022 Intel Corporation */
#include <linux/bitfield.h>
#include <linux/iopoll.h>
#include "adf_accel_devices.h"
#include "adf_common_drv.h"
#include "adf_gen4_pm.h"
#include "adf_cfg_strings.h"
#include "icp_qat_fw_init_admin.h"
#include "adf_gen4_hw_data.h"
#include "adf_cfg.h"

enum qat_pm_host_msg {
	PM_NO_CHANGE = 0,
	PM_SET_MIN,
};

struct adf_gen4_pm_data {
	struct work_struct pm_irq_work;
	struct adf_accel_dev *accel_dev;
	u32 pm_int_sts;
};

static int send_host_msg(struct adf_accel_dev *accel_dev)
{
	void __iomem *pmisc = adf_get_pmisc_base(accel_dev);
	u32 msg;

	msg = ADF_CSR_RD(pmisc, ADF_GEN4_PM_HOST_MSG);
	if (msg & ADF_GEN4_PM_MSG_PENDING)
		return -EBUSY;

	/* Send HOST_MSG */
	msg = FIELD_PREP(ADF_GEN4_PM_MSG_PAYLOAD_BIT_MASK, PM_SET_MIN);
	msg |= ADF_GEN4_PM_MSG_PENDING;
	ADF_CSR_WR(pmisc, ADF_GEN4_PM_HOST_MSG, msg);

	/* Poll status register to make sure the HOST_MSG has been processed */
	return read_poll_timeout(ADF_CSR_RD, msg,
				!(msg & ADF_GEN4_PM_MSG_PENDING),
				ADF_GEN4_PM_MSG_POLL_DELAY_US,
				ADF_GEN4_PM_POLL_TIMEOUT_US, true, pmisc,
				ADF_GEN4_PM_HOST_MSG);
}

static void pm_bh_handler(struct work_struct *work)
{
	struct adf_gen4_pm_data *pm_data =
		container_of(work, struct adf_gen4_pm_data, pm_irq_work);
	struct adf_accel_dev *accel_dev = pm_data->accel_dev;
	void __iomem *pmisc = adf_get_pmisc_base(accel_dev);
	u32 pm_int_sts = pm_data->pm_int_sts;
	u32 val;

	/* PM Idle interrupt */
	if (pm_int_sts & ADF_GEN4_PM_IDLE_STS) {
		/* Issue host message to FW */
		if (send_host_msg(accel_dev))
			dev_warn_ratelimited(&GET_DEV(accel_dev),
					     "Failed to send host msg to FW\n");
	}

	/* Clear interrupt status */
	ADF_CSR_WR(pmisc, ADF_GEN4_PM_INTERRUPT, pm_int_sts);

	/* Reenable PM interrupt */
	val = ADF_CSR_RD(pmisc, ADF_GEN4_ERRMSK2);
	val &= ~ADF_GEN4_PM_SOU;
	ADF_CSR_WR(pmisc, ADF_GEN4_ERRMSK2, val);

	kfree(pm_data);
}

bool adf_gen4_handle_pm_interrupt(struct adf_accel_dev *accel_dev)
{
	void __iomem *pmisc = adf_get_pmisc_base(accel_dev);
	struct adf_gen4_pm_data *pm_data = NULL;
	u32 errsou2;
	u32 errmsk2;
	u32 val;

	/* Only handle the interrupt triggered by PM */
	errmsk2 = ADF_CSR_RD(pmisc, ADF_GEN4_ERRMSK2);
	if (errmsk2 & ADF_GEN4_PM_SOU)
		return false;

	errsou2 = ADF_CSR_RD(pmisc, ADF_GEN4_ERRSOU2);
	if (!(errsou2 & ADF_GEN4_PM_SOU))
		return false;

	/* Disable interrupt */
	val = ADF_CSR_RD(pmisc, ADF_GEN4_ERRMSK2);
	val |= ADF_GEN4_PM_SOU;
	ADF_CSR_WR(pmisc, ADF_GEN4_ERRMSK2, val);

	val = ADF_CSR_RD(pmisc, ADF_GEN4_PM_INTERRUPT);

	pm_data = kzalloc(sizeof(*pm_data), GFP_ATOMIC);
	if (!pm_data)
		return false;

	pm_data->pm_int_sts = val;
	pm_data->accel_dev = accel_dev;

	INIT_WORK(&pm_data->pm_irq_work, pm_bh_handler);
	adf_misc_wq_queue_work(&pm_data->pm_irq_work);

	return true;
}
EXPORT_SYMBOL_GPL(adf_gen4_handle_pm_interrupt);

int adf_gen4_enable_pm(struct adf_accel_dev *accel_dev)
{
	void __iomem *pmisc = adf_get_pmisc_base(accel_dev);
	int ret;
	u32 val;

	ret = adf_init_admin_pm(accel_dev, ADF_GEN4_PM_DEFAULT_IDLE_FILTER);
	if (ret)
		return ret;

	/* Enable default PM interrupts: IDLE, THROTTLE */
	val = ADF_CSR_RD(pmisc, ADF_GEN4_PM_INTERRUPT);
	val |= ADF_GEN4_PM_INT_EN_DEFAULT;

	/* Clear interrupt status */
	val |= ADF_GEN4_PM_INT_STS_MASK;
	ADF_CSR_WR(pmisc, ADF_GEN4_PM_INTERRUPT, val);

	/* Unmask PM Interrupt */
	val = ADF_CSR_RD(pmisc, ADF_GEN4_ERRMSK2);
	val &= ~ADF_GEN4_PM_SOU;
	ADF_CSR_WR(pmisc, ADF_GEN4_ERRMSK2, val);

	return 0;
}
EXPORT_SYMBOL_GPL(adf_gen4_enable_pm);
