// SPDX-License-Identifier: GPL-2.0-only
/*
 * Copyright (c) 2021, MediaTek Inc.
 * Copyright (c) 2021-2022, Intel Corporation.
 *
 * Authors:
 *  Haijun Liu <haijun.liu@mediatek.com>
 *  Eliot Lee <eliot.lee@intel.com>
 *  Moises Veleta <moises.veleta@intel.com>
 *  Ricardo Martinez <ricardo.martinez@linux.intel.com>
 *
 * Contributors:
 *  Amir Hanania <amir.hanania@intel.com>
 *  Sreehari Kancharla <sreehari.kancharla@intel.com>
 */

#include <linux/bits.h>
#include <linux/bitfield.h>
#include <linux/completion.h>
#include <linux/device.h>
#include <linux/delay.h>
#include <linux/err.h>
#include <linux/gfp.h>
#include <linux/iopoll.h>
#include <linux/jiffies.h>
#include <linux/kernel.h>
#include <linux/kthread.h>
#include <linux/list.h>
#include <linux/slab.h>
#include <linux/spinlock.h>
#include <linux/string.h>
#include <linux/types.h>
#include <linux/wait.h>

#include "t7xx_hif_cldma.h"
#include "t7xx_mhccif.h"
#include "t7xx_modem_ops.h"
#include "t7xx_pci.h"
#include "t7xx_pcie_mac.h"
#include "t7xx_port_proxy.h"
#include "t7xx_reg.h"
#include "t7xx_state_monitor.h"

#define FSM_DRM_DISABLE_DELAY_MS		200
#define FSM_EVENT_POLL_INTERVAL_MS		20
#define FSM_MD_EX_REC_OK_TIMEOUT_MS		10000
#define FSM_MD_EX_PASS_TIMEOUT_MS		45000
#define FSM_CMD_TIMEOUT_MS			2000

void t7xx_fsm_notifier_register(struct t7xx_modem *md, struct t7xx_fsm_notifier *notifier)
{
	struct t7xx_fsm_ctl *ctl = md->fsm_ctl;
	unsigned long flags;

	spin_lock_irqsave(&ctl->notifier_lock, flags);
	list_add_tail(&notifier->entry, &ctl->notifier_list);
	spin_unlock_irqrestore(&ctl->notifier_lock, flags);
}

void t7xx_fsm_notifier_unregister(struct t7xx_modem *md, struct t7xx_fsm_notifier *notifier)
{
	struct t7xx_fsm_notifier *notifier_cur, *notifier_next;
	struct t7xx_fsm_ctl *ctl = md->fsm_ctl;
	unsigned long flags;

	spin_lock_irqsave(&ctl->notifier_lock, flags);
	list_for_each_entry_safe(notifier_cur, notifier_next, &ctl->notifier_list, entry) {
		if (notifier_cur == notifier)
			list_del(&notifier->entry);
	}
	spin_unlock_irqrestore(&ctl->notifier_lock, flags);
}

static void fsm_state_notify(struct t7xx_modem *md, enum md_state state)
{
	struct t7xx_fsm_ctl *ctl = md->fsm_ctl;
	struct t7xx_fsm_notifier *notifier;
	unsigned long flags;

	spin_lock_irqsave(&ctl->notifier_lock, flags);
	list_for_each_entry(notifier, &ctl->notifier_list, entry) {
		spin_unlock_irqrestore(&ctl->notifier_lock, flags);
		if (notifier->notifier_fn)
			notifier->notifier_fn(state, notifier->data);

		spin_lock_irqsave(&ctl->notifier_lock, flags);
	}
	spin_unlock_irqrestore(&ctl->notifier_lock, flags);
}

void t7xx_fsm_broadcast_state(struct t7xx_fsm_ctl *ctl, enum md_state state)
{
	ctl->md_state = state;

	/* Update to port first, otherwise sending message on HS2 may fail */
	t7xx_port_proxy_md_status_notify(ctl->md->port_prox, state);
	fsm_state_notify(ctl->md, state);
}

static void fsm_finish_command(struct t7xx_fsm_ctl *ctl, struct t7xx_fsm_command *cmd, int result)
{
	if (cmd->flag & FSM_CMD_FLAG_WAIT_FOR_COMPLETION) {
		*cmd->ret = result;
		complete_all(cmd->done);
	}

	kfree(cmd);
}

static void fsm_del_kf_event(struct t7xx_fsm_event *event)
{
	list_del(&event->entry);
	kfree(event);
}

static void fsm_flush_event_cmd_qs(struct t7xx_fsm_ctl *ctl)
{
	struct device *dev = &ctl->md->t7xx_dev->pdev->dev;
	struct t7xx_fsm_event *event, *evt_next;
	struct t7xx_fsm_command *cmd, *cmd_next;
	unsigned long flags;

	spin_lock_irqsave(&ctl->command_lock, flags);
	list_for_each_entry_safe(cmd, cmd_next, &ctl->command_queue, entry) {
		dev_warn(dev, "Unhandled command %d\n", cmd->cmd_id);
		list_del(&cmd->entry);
		fsm_finish_command(ctl, cmd, -EINVAL);
	}
	spin_unlock_irqrestore(&ctl->command_lock, flags);

	spin_lock_irqsave(&ctl->event_lock, flags);
	list_for_each_entry_safe(event, evt_next, &ctl->event_queue, entry) {
		dev_warn(dev, "Unhandled event %d\n", event->event_id);
		fsm_del_kf_event(event);
	}
	spin_unlock_irqrestore(&ctl->event_lock, flags);
}

static void fsm_wait_for_event(struct t7xx_fsm_ctl *ctl, enum t7xx_fsm_event_state event_expected,
			       enum t7xx_fsm_event_state event_ignore, int retries)
{
	struct t7xx_fsm_event *event;
	bool event_received = false;
	unsigned long flags;
	int cnt = 0;

	while (cnt++ < retries && !event_received) {
		bool sleep_required = true;

		if (kthread_should_stop())
			return;

		spin_lock_irqsave(&ctl->event_lock, flags);
		event = list_first_entry_or_null(&ctl->event_queue, struct t7xx_fsm_event, entry);
		if (event) {
			event_received = event->event_id == event_expected;
			if (event_received || event->event_id == event_ignore) {
				fsm_del_kf_event(event);
				sleep_required = false;
			}
		}
		spin_unlock_irqrestore(&ctl->event_lock, flags);

		if (sleep_required)
			msleep(FSM_EVENT_POLL_INTERVAL_MS);
	}
}

static void fsm_routine_exception(struct t7xx_fsm_ctl *ctl, struct t7xx_fsm_command *cmd,
				  enum t7xx_ex_reason reason)
{
	struct device *dev = &ctl->md->t7xx_dev->pdev->dev;

	if (ctl->curr_state != FSM_STATE_READY && ctl->curr_state != FSM_STATE_STARTING) {
		if (cmd)
			fsm_finish_command(ctl, cmd, -EINVAL);

		return;
	}

	ctl->curr_state = FSM_STATE_EXCEPTION;

	switch (reason) {
	case EXCEPTION_HS_TIMEOUT:
		dev_err(dev, "Boot Handshake failure\n");
		break;

	case EXCEPTION_EVENT:
		dev_err(dev, "Exception event\n");
		t7xx_fsm_broadcast_state(ctl, MD_STATE_EXCEPTION);
		t7xx_pci_pm_exp_detected(ctl->md->t7xx_dev);
		t7xx_md_exception_handshake(ctl->md);

		fsm_wait_for_event(ctl, FSM_EVENT_MD_EX_REC_OK, FSM_EVENT_MD_EX,
				   FSM_MD_EX_REC_OK_TIMEOUT_MS / FSM_EVENT_POLL_INTERVAL_MS);
		fsm_wait_for_event(ctl, FSM_EVENT_MD_EX_PASS, FSM_EVENT_INVALID,
				   FSM_MD_EX_PASS_TIMEOUT_MS / FSM_EVENT_POLL_INTERVAL_MS);
		break;

	default:
		dev_err(dev, "Exception %d\n", reason);
		break;
	}

	if (cmd)
		fsm_finish_command(ctl, cmd, 0);
}

static int fsm_stopped_handler(struct t7xx_fsm_ctl *ctl)
{
	ctl->curr_state = FSM_STATE_STOPPED;

	t7xx_fsm_broadcast_state(ctl, MD_STATE_STOPPED);
	return t7xx_md_reset(ctl->md->t7xx_dev);
}

static void fsm_routine_stopped(struct t7xx_fsm_ctl *ctl, struct t7xx_fsm_command *cmd)
{
	if (ctl->curr_state == FSM_STATE_STOPPED) {
		fsm_finish_command(ctl, cmd, -EINVAL);
		return;
	}

	fsm_finish_command(ctl, cmd, fsm_stopped_handler(ctl));
}

static void fsm_routine_stopping(struct t7xx_fsm_ctl *ctl, struct t7xx_fsm_command *cmd)
{
	struct t7xx_pci_dev *t7xx_dev;
	struct cldma_ctrl *md_ctrl;
	int err;

	if (ctl->curr_state == FSM_STATE_STOPPED || ctl->curr_state == FSM_STATE_STOPPING) {
		fsm_finish_command(ctl, cmd, -EINVAL);
		return;
	}

	md_ctrl = ctl->md->md_ctrl[CLDMA_ID_MD];
	t7xx_dev = ctl->md->t7xx_dev;

	ctl->curr_state = FSM_STATE_STOPPING;
	t7xx_fsm_broadcast_state(ctl, MD_STATE_WAITING_TO_STOP);
	t7xx_cldma_stop(md_ctrl);

	if (!ctl->md->rgu_irq_asserted) {
		t7xx_mhccif_h2d_swint_trigger(t7xx_dev, H2D_CH_DRM_DISABLE_AP);
		/* Wait for the DRM disable to take effect */
		msleep(FSM_DRM_DISABLE_DELAY_MS);

		err = t7xx_acpi_fldr_func(t7xx_dev);
		if (err)
			t7xx_mhccif_h2d_swint_trigger(t7xx_dev, H2D_CH_DEVICE_RESET);
	}

	fsm_finish_command(ctl, cmd, fsm_stopped_handler(ctl));
}

static void t7xx_fsm_broadcast_ready_state(struct t7xx_fsm_ctl *ctl)
{
	if (ctl->md_state != MD_STATE_WAITING_FOR_HS2)
		return;

	ctl->md_state = MD_STATE_READY;

	fsm_state_notify(ctl->md, MD_STATE_READY);
	t7xx_port_proxy_md_status_notify(ctl->md->port_prox, MD_STATE_READY);
}

static void fsm_routine_ready(struct t7xx_fsm_ctl *ctl)
{
	struct t7xx_modem *md = ctl->md;

	ctl->curr_state = FSM_STATE_READY;
	t7xx_fsm_broadcast_ready_state(ctl);
	t7xx_md_event_notify(md, FSM_READY);
}

static int fsm_routine_starting(struct t7xx_fsm_ctl *ctl)
{
	struct t7xx_modem *md = ctl->md;
	struct device *dev;

	ctl->curr_state = FSM_STATE_STARTING;

	t7xx_fsm_broadcast_state(ctl, MD_STATE_WAITING_FOR_HS1);
	t7xx_md_event_notify(md, FSM_START);

	wait_event_interruptible_timeout(ctl->async_hk_wq,
					 (md->core_md.ready && md->core_ap.ready) ||
					  ctl->exp_flg, HZ * 60);
	dev = &md->t7xx_dev->pdev->dev;

	if (ctl->exp_flg)
		dev_err(dev, "MD exception is captured during handshake\n");

	if (!md->core_md.ready) {
		dev_err(dev, "MD handshake timeout\n");
		if (md->core_md.handshake_ongoing)
			t7xx_fsm_append_event(ctl, FSM_EVENT_MD_HS2_EXIT, NULL, 0);

		fsm_routine_exception(ctl, NULL, EXCEPTION_HS_TIMEOUT);
		return -ETIMEDOUT;
	} else if (!md->core_ap.ready) {
		dev_err(dev, "AP handshake timeout\n");
		if (md->core_ap.handshake_ongoing)
			t7xx_fsm_append_event(ctl, FSM_EVENT_AP_HS2_EXIT, NULL, 0);

		fsm_routine_exception(ctl, NULL, EXCEPTION_HS_TIMEOUT);
		return -ETIMEDOUT;
	}

	t7xx_pci_pm_init_late(md->t7xx_dev);
	fsm_routine_ready(ctl);
	return 0;
}

static void fsm_routine_start(struct t7xx_fsm_ctl *ctl, struct t7xx_fsm_command *cmd)
{
	struct t7xx_modem *md = ctl->md;
	u32 dev_status;
	int ret;

	if (!md)
		return;

	if (ctl->curr_state != FSM_STATE_INIT && ctl->curr_state != FSM_STATE_PRE_START &&
	    ctl->curr_state != FSM_STATE_STOPPED) {
		fsm_finish_command(ctl, cmd, -EINVAL);
		return;
	}

	ctl->curr_state = FSM_STATE_PRE_START;
	t7xx_md_event_notify(md, FSM_PRE_START);

	ret = read_poll_timeout(ioread32, dev_status,
				(dev_status & MISC_STAGE_MASK) == LINUX_STAGE, 20000, 2000000,
				false, IREG_BASE(md->t7xx_dev) + T7XX_PCIE_MISC_DEV_STATUS);
	if (ret) {
		struct device *dev = &md->t7xx_dev->pdev->dev;

		fsm_finish_command(ctl, cmd, -ETIMEDOUT);
		dev_err(dev, "Invalid device status 0x%lx\n", dev_status & MISC_STAGE_MASK);
		return;
	}

	t7xx_cldma_hif_hw_init(md->md_ctrl[CLDMA_ID_AP]);
	t7xx_cldma_hif_hw_init(md->md_ctrl[CLDMA_ID_MD]);
	fsm_finish_command(ctl, cmd, fsm_routine_starting(ctl));
}

static int fsm_main_thread(void *data)
{
	struct t7xx_fsm_ctl *ctl = data;
	struct t7xx_fsm_command *cmd;
	unsigned long flags;

	while (!kthread_should_stop()) {
		if (wait_event_interruptible(ctl->command_wq, !list_empty(&ctl->command_queue) ||
					     kthread_should_stop()))
			continue;

		if (kthread_should_stop())
			break;

		spin_lock_irqsave(&ctl->command_lock, flags);
		cmd = list_first_entry(&ctl->command_queue, struct t7xx_fsm_command, entry);
		list_del(&cmd->entry);
		spin_unlock_irqrestore(&ctl->command_lock, flags);

		switch (cmd->cmd_id) {
		case FSM_CMD_START:
			fsm_routine_start(ctl, cmd);
			break;

		case FSM_CMD_EXCEPTION:
			fsm_routine_exception(ctl, cmd, FIELD_GET(FSM_CMD_EX_REASON, cmd->flag));
			break;

		case FSM_CMD_PRE_STOP:
			fsm_routine_stopping(ctl, cmd);
			break;

		case FSM_CMD_STOP:
			fsm_routine_stopped(ctl, cmd);
			break;

		default:
			fsm_finish_command(ctl, cmd, -EINVAL);
			fsm_flush_event_cmd_qs(ctl);
			break;
		}
	}

	return 0;
}

int t7xx_fsm_append_cmd(struct t7xx_fsm_ctl *ctl, enum t7xx_fsm_cmd_state cmd_id, unsigned int flag)
{
	DECLARE_COMPLETION_ONSTACK(done);
	struct t7xx_fsm_command *cmd;
	unsigned long flags;
	int ret;

	cmd = kzalloc(sizeof(*cmd), flag & FSM_CMD_FLAG_IN_INTERRUPT ? GFP_ATOMIC : GFP_KERNEL);
	if (!cmd)
		return -ENOMEM;

	INIT_LIST_HEAD(&cmd->entry);
	cmd->cmd_id = cmd_id;
	cmd->flag = flag;
	if (flag & FSM_CMD_FLAG_WAIT_FOR_COMPLETION) {
		cmd->done = &done;
		cmd->ret = &ret;
	}

	spin_lock_irqsave(&ctl->command_lock, flags);
	list_add_tail(&cmd->entry, &ctl->command_queue);
	spin_unlock_irqrestore(&ctl->command_lock, flags);

	wake_up(&ctl->command_wq);

	if (flag & FSM_CMD_FLAG_WAIT_FOR_COMPLETION) {
		unsigned long wait_ret;

		wait_ret = wait_for_completion_timeout(&done,
						       msecs_to_jiffies(FSM_CMD_TIMEOUT_MS));
		if (!wait_ret)
			return -ETIMEDOUT;

		return ret;
	}

	return 0;
}

int t7xx_fsm_append_event(struct t7xx_fsm_ctl *ctl, enum t7xx_fsm_event_state event_id,
			  unsigned char *data, unsigned int length)
{
	struct device *dev = &ctl->md->t7xx_dev->pdev->dev;
	struct t7xx_fsm_event *event;
	unsigned long flags;

	if (event_id <= FSM_EVENT_INVALID || event_id >= FSM_EVENT_MAX) {
		dev_err(dev, "Invalid event %d\n", event_id);
		return -EINVAL;
	}

	event = kmalloc(struct_size(event, data, length),
			in_interrupt() ? GFP_ATOMIC : GFP_KERNEL);
	if (!event)
		return -ENOMEM;

	INIT_LIST_HEAD(&event->entry);
	event->event_id = event_id;
	event->length = length;

	if (data && length)
		memcpy(event->data, data, length);

	spin_lock_irqsave(&ctl->event_lock, flags);
	list_add_tail(&event->entry, &ctl->event_queue);
	spin_unlock_irqrestore(&ctl->event_lock, flags);

	wake_up_all(&ctl->event_wq);
	return 0;
}

void t7xx_fsm_clr_event(struct t7xx_fsm_ctl *ctl, enum t7xx_fsm_event_state event_id)
{
	struct t7xx_fsm_event *event, *evt_next;
	unsigned long flags;

	spin_lock_irqsave(&ctl->event_lock, flags);
	list_for_each_entry_safe(event, evt_next, &ctl->event_queue, entry) {
		if (event->event_id == event_id)
			fsm_del_kf_event(event);
	}
	spin_unlock_irqrestore(&ctl->event_lock, flags);
}

enum md_state t7xx_fsm_get_md_state(struct t7xx_fsm_ctl *ctl)
{
	if (ctl)
		return ctl->md_state;

	return MD_STATE_INVALID;
}

unsigned int t7xx_fsm_get_ctl_state(struct t7xx_fsm_ctl *ctl)
{
	if (ctl)
		return ctl->curr_state;

	return FSM_STATE_STOPPED;
}

int t7xx_fsm_recv_md_intr(struct t7xx_fsm_ctl *ctl, enum t7xx_md_irq_type type)
{
	unsigned int cmd_flags = FSM_CMD_FLAG_IN_INTERRUPT;

	if (type == MD_IRQ_PORT_ENUM) {
		return t7xx_fsm_append_cmd(ctl, FSM_CMD_START, cmd_flags);
	} else if (type == MD_IRQ_CCIF_EX) {
		ctl->exp_flg = true;
		wake_up(&ctl->async_hk_wq);
		cmd_flags |= FIELD_PREP(FSM_CMD_EX_REASON, EXCEPTION_EVENT);
		return t7xx_fsm_append_cmd(ctl, FSM_CMD_EXCEPTION, cmd_flags);
	}

	return -EINVAL;
}

void t7xx_fsm_reset(struct t7xx_modem *md)
{
	struct t7xx_fsm_ctl *ctl = md->fsm_ctl;

	fsm_flush_event_cmd_qs(ctl);
	ctl->curr_state = FSM_STATE_STOPPED;
	ctl->exp_flg = false;
}

int t7xx_fsm_init(struct t7xx_modem *md)
{
	struct device *dev = &md->t7xx_dev->pdev->dev;
	struct t7xx_fsm_ctl *ctl;

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

	md->fsm_ctl = ctl;
	ctl->md = md;
	ctl->curr_state = FSM_STATE_INIT;
	INIT_LIST_HEAD(&ctl->command_queue);
	INIT_LIST_HEAD(&ctl->event_queue);
	init_waitqueue_head(&ctl->async_hk_wq);
	init_waitqueue_head(&ctl->event_wq);
	INIT_LIST_HEAD(&ctl->notifier_list);
	init_waitqueue_head(&ctl->command_wq);
	spin_lock_init(&ctl->event_lock);
	spin_lock_init(&ctl->command_lock);
	ctl->exp_flg = false;
	spin_lock_init(&ctl->notifier_lock);

	ctl->fsm_thread = kthread_run(fsm_main_thread, ctl, "t7xx_fsm");
	return PTR_ERR_OR_ZERO(ctl->fsm_thread);
}

void t7xx_fsm_uninit(struct t7xx_modem *md)
{
	struct t7xx_fsm_ctl *ctl = md->fsm_ctl;

	if (!ctl)
		return;

	if (ctl->fsm_thread)
		kthread_stop(ctl->fsm_thread);

	fsm_flush_event_cmd_qs(ctl);
}
