// 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>
 *  Ricardo Martinez <ricardo.martinez@linux.intel.com>
 *  Sreehari Kancharla <sreehari.kancharla@intel.com>
 *
 * Contributors:
 *  Amir Hanania <amir.hanania@intel.com>
 *  Andy Shevchenko <andriy.shevchenko@linux.intel.com>
 *  Chiranjeevi Rapolu <chiranjeevi.rapolu@intel.com>
 *  Eliot Lee <eliot.lee@intel.com>
 *  Moises Veleta <moises.veleta@intel.com>
 */

#include <linux/atomic.h>
#include <linux/bits.h>
#include <linux/completion.h>
#include <linux/device.h>
#include <linux/dma-mapping.h>
#include <linux/gfp.h>
#include <linux/interrupt.h>
#include <linux/io.h>
#include <linux/iopoll.h>
#include <linux/jiffies.h>
#include <linux/list.h>
#include <linux/module.h>
#include <linux/mutex.h>
#include <linux/pci.h>
#include <linux/pm.h>
#include <linux/pm_runtime.h>
#include <linux/pm_wakeup.h>
#include <linux/spinlock.h>

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

#define T7XX_PCI_IREG_BASE		0
#define T7XX_PCI_EREG_BASE		2

#define T7XX_INIT_TIMEOUT		20
#define PM_SLEEP_DIS_TIMEOUT_MS		20
#define PM_ACK_TIMEOUT_MS		1500
#define PM_AUTOSUSPEND_MS		20000
#define PM_RESOURCE_POLL_TIMEOUT_US	10000
#define PM_RESOURCE_POLL_STEP_US	100

static const char * const t7xx_mode_names[] = {
	[T7XX_UNKNOWN] = "unknown",
	[T7XX_READY] = "ready",
	[T7XX_RESET] = "reset",
	[T7XX_FASTBOOT_SWITCHING] = "fastboot_switching",
	[T7XX_FASTBOOT_DOWNLOAD] = "fastboot_download",
	[T7XX_FASTBOOT_DUMP] = "fastboot_dump",
};

static_assert(ARRAY_SIZE(t7xx_mode_names) == T7XX_MODE_LAST);

static ssize_t t7xx_mode_store(struct device *dev,
			       struct device_attribute *attr,
			       const char *buf, size_t count)
{
	struct t7xx_pci_dev *t7xx_dev;
	struct pci_dev *pdev;
	enum t7xx_mode mode;
	int index = 0;

	pdev = to_pci_dev(dev);
	t7xx_dev = pci_get_drvdata(pdev);
	if (!t7xx_dev)
		return -ENODEV;

	mode = READ_ONCE(t7xx_dev->mode);

	index = sysfs_match_string(t7xx_mode_names, buf);
	if (index == mode)
		return -EBUSY;

	if (index == T7XX_FASTBOOT_SWITCHING) {
		if (mode == T7XX_FASTBOOT_DOWNLOAD)
			return count;

		WRITE_ONCE(t7xx_dev->mode, T7XX_FASTBOOT_SWITCHING);
		pm_runtime_resume(dev);
		t7xx_reset_device(t7xx_dev, FASTBOOT);
	} else if (index == T7XX_RESET) {
		pm_runtime_resume(dev);
		t7xx_reset_device(t7xx_dev, PLDR);
	}

	return count;
};

static ssize_t t7xx_mode_show(struct device *dev,
			      struct device_attribute *attr,
			      char *buf)
{
	enum t7xx_mode mode = T7XX_UNKNOWN;
	struct t7xx_pci_dev *t7xx_dev;
	struct pci_dev *pdev;

	pdev = to_pci_dev(dev);
	t7xx_dev = pci_get_drvdata(pdev);
	if (!t7xx_dev)
		return -ENODEV;

	mode = READ_ONCE(t7xx_dev->mode);
	if (mode < T7XX_MODE_LAST)
		return sysfs_emit(buf, "%s\n", t7xx_mode_names[mode]);

	return sysfs_emit(buf, "%s\n", t7xx_mode_names[T7XX_UNKNOWN]);
}

static DEVICE_ATTR_RW(t7xx_mode);

static struct attribute *t7xx_mode_attr[] = {
	&dev_attr_t7xx_mode.attr,
	NULL
};

static const struct attribute_group t7xx_mode_attribute_group = {
	.attrs = t7xx_mode_attr,
};

void t7xx_mode_update(struct t7xx_pci_dev *t7xx_dev, enum t7xx_mode mode)
{
	if (!t7xx_dev)
		return;

	WRITE_ONCE(t7xx_dev->mode, mode);
	sysfs_notify(&t7xx_dev->pdev->dev.kobj, NULL, "t7xx_mode");
}

enum t7xx_pm_state {
	MTK_PM_EXCEPTION,
	MTK_PM_INIT,		/* Device initialized, but handshake not completed */
	MTK_PM_SUSPENDED,
	MTK_PM_RESUMED,
};

static void t7xx_dev_set_sleep_capability(struct t7xx_pci_dev *t7xx_dev, bool enable)
{
	void __iomem *ctrl_reg = IREG_BASE(t7xx_dev) + T7XX_PCIE_MISC_CTRL;
	u32 value;

	value = ioread32(ctrl_reg);

	if (enable)
		value &= ~T7XX_PCIE_MISC_MAC_SLEEP_DIS;
	else
		value |= T7XX_PCIE_MISC_MAC_SLEEP_DIS;

	iowrite32(value, ctrl_reg);
}

static int t7xx_wait_pm_config(struct t7xx_pci_dev *t7xx_dev)
{
	int ret, val;

	ret = read_poll_timeout(ioread32, val,
				(val & T7XX_PCIE_RESOURCE_STS_MSK) == T7XX_PCIE_RESOURCE_STS_MSK,
				PM_RESOURCE_POLL_STEP_US, PM_RESOURCE_POLL_TIMEOUT_US, true,
				IREG_BASE(t7xx_dev) + T7XX_PCIE_RESOURCE_STATUS);
	if (ret == -ETIMEDOUT)
		dev_err(&t7xx_dev->pdev->dev, "PM configuration timed out\n");

	return ret;
}

static int t7xx_pci_pm_init(struct t7xx_pci_dev *t7xx_dev)
{
	struct pci_dev *pdev = t7xx_dev->pdev;

	INIT_LIST_HEAD(&t7xx_dev->md_pm_entities);
	mutex_init(&t7xx_dev->md_pm_entity_mtx);
	spin_lock_init(&t7xx_dev->md_pm_lock);
	init_completion(&t7xx_dev->sleep_lock_acquire);
	init_completion(&t7xx_dev->pm_sr_ack);
	init_completion(&t7xx_dev->init_done);
	atomic_set(&t7xx_dev->md_pm_state, MTK_PM_INIT);

	device_init_wakeup(&pdev->dev, true);
	dev_pm_set_driver_flags(&pdev->dev, pdev->dev.power.driver_flags |
				DPM_FLAG_NO_DIRECT_COMPLETE);

	iowrite32(T7XX_L1_BIT(0), IREG_BASE(t7xx_dev) + DISABLE_ASPM_LOWPWR);
	pm_runtime_set_autosuspend_delay(&pdev->dev, PM_AUTOSUSPEND_MS);
	pm_runtime_use_autosuspend(&pdev->dev);

	return 0;
}

void t7xx_pci_pm_init_late(struct t7xx_pci_dev *t7xx_dev)
{
	/* Enable the PCIe resource lock only after MD deep sleep is done */
	t7xx_mhccif_mask_clr(t7xx_dev,
			     D2H_INT_DS_LOCK_ACK |
			     D2H_INT_SUSPEND_ACK |
			     D2H_INT_RESUME_ACK |
			     D2H_INT_SUSPEND_ACK_AP |
			     D2H_INT_RESUME_ACK_AP);
	iowrite32(T7XX_L1_BIT(0), IREG_BASE(t7xx_dev) + ENABLE_ASPM_LOWPWR);
	atomic_set(&t7xx_dev->md_pm_state, MTK_PM_RESUMED);

	pm_runtime_mark_last_busy(&t7xx_dev->pdev->dev);
	pm_runtime_allow(&t7xx_dev->pdev->dev);
	pm_runtime_put_noidle(&t7xx_dev->pdev->dev);
	complete_all(&t7xx_dev->init_done);
}

static int t7xx_pci_pm_reinit(struct t7xx_pci_dev *t7xx_dev)
{
	/* The device is kept in FSM re-init flow
	 * so just roll back PM setting to the init setting.
	 */
	atomic_set(&t7xx_dev->md_pm_state, MTK_PM_INIT);

	pm_runtime_get_noresume(&t7xx_dev->pdev->dev);

	iowrite32(T7XX_L1_BIT(0), IREG_BASE(t7xx_dev) + DISABLE_ASPM_LOWPWR);
	return t7xx_wait_pm_config(t7xx_dev);
}

void t7xx_pci_pm_exp_detected(struct t7xx_pci_dev *t7xx_dev)
{
	iowrite32(T7XX_L1_BIT(0), IREG_BASE(t7xx_dev) + DISABLE_ASPM_LOWPWR);
	t7xx_wait_pm_config(t7xx_dev);
	atomic_set(&t7xx_dev->md_pm_state, MTK_PM_EXCEPTION);
}

int t7xx_pci_pm_entity_register(struct t7xx_pci_dev *t7xx_dev, struct md_pm_entity *pm_entity)
{
	struct md_pm_entity *entity;

	mutex_lock(&t7xx_dev->md_pm_entity_mtx);
	list_for_each_entry(entity, &t7xx_dev->md_pm_entities, entity) {
		if (entity->id == pm_entity->id) {
			mutex_unlock(&t7xx_dev->md_pm_entity_mtx);
			return -EEXIST;
		}
	}

	list_add_tail(&pm_entity->entity, &t7xx_dev->md_pm_entities);
	mutex_unlock(&t7xx_dev->md_pm_entity_mtx);
	return 0;
}

int t7xx_pci_pm_entity_unregister(struct t7xx_pci_dev *t7xx_dev, struct md_pm_entity *pm_entity)
{
	struct md_pm_entity *entity, *tmp_entity;

	mutex_lock(&t7xx_dev->md_pm_entity_mtx);
	list_for_each_entry_safe(entity, tmp_entity, &t7xx_dev->md_pm_entities, entity) {
		if (entity->id == pm_entity->id) {
			list_del(&pm_entity->entity);
			mutex_unlock(&t7xx_dev->md_pm_entity_mtx);
			return 0;
		}
	}

	mutex_unlock(&t7xx_dev->md_pm_entity_mtx);

	return -ENXIO;
}

int t7xx_pci_sleep_disable_complete(struct t7xx_pci_dev *t7xx_dev)
{
	struct device *dev = &t7xx_dev->pdev->dev;
	int ret;

	ret = wait_for_completion_timeout(&t7xx_dev->sleep_lock_acquire,
					  msecs_to_jiffies(PM_SLEEP_DIS_TIMEOUT_MS));
	if (!ret)
		dev_err_ratelimited(dev, "Resource wait complete timed out\n");

	return ret;
}

/**
 * t7xx_pci_disable_sleep() - Disable deep sleep capability.
 * @t7xx_dev: MTK device.
 *
 * Lock the deep sleep capability, note that the device can still go into deep sleep
 * state while device is in D0 state, from the host's point-of-view.
 *
 * If device is in deep sleep state, wake up the device and disable deep sleep capability.
 */
void t7xx_pci_disable_sleep(struct t7xx_pci_dev *t7xx_dev)
{
	unsigned long flags;

	spin_lock_irqsave(&t7xx_dev->md_pm_lock, flags);
	t7xx_dev->sleep_disable_count++;
	if (atomic_read(&t7xx_dev->md_pm_state) < MTK_PM_RESUMED)
		goto unlock_and_complete;

	if (t7xx_dev->sleep_disable_count == 1) {
		u32 status;

		reinit_completion(&t7xx_dev->sleep_lock_acquire);
		t7xx_dev_set_sleep_capability(t7xx_dev, false);

		status = ioread32(IREG_BASE(t7xx_dev) + T7XX_PCIE_RESOURCE_STATUS);
		if (status & T7XX_PCIE_RESOURCE_STS_MSK)
			goto unlock_and_complete;

		t7xx_mhccif_h2d_swint_trigger(t7xx_dev, H2D_CH_DS_LOCK);
	}
	spin_unlock_irqrestore(&t7xx_dev->md_pm_lock, flags);
	return;

unlock_and_complete:
	spin_unlock_irqrestore(&t7xx_dev->md_pm_lock, flags);
	complete_all(&t7xx_dev->sleep_lock_acquire);
}

/**
 * t7xx_pci_enable_sleep() - Enable deep sleep capability.
 * @t7xx_dev: MTK device.
 *
 * After enabling deep sleep, device can enter into deep sleep state.
 */
void t7xx_pci_enable_sleep(struct t7xx_pci_dev *t7xx_dev)
{
	unsigned long flags;

	spin_lock_irqsave(&t7xx_dev->md_pm_lock, flags);
	t7xx_dev->sleep_disable_count--;
	if (atomic_read(&t7xx_dev->md_pm_state) < MTK_PM_RESUMED)
		goto unlock;

	if (t7xx_dev->sleep_disable_count == 0)
		t7xx_dev_set_sleep_capability(t7xx_dev, true);

unlock:
	spin_unlock_irqrestore(&t7xx_dev->md_pm_lock, flags);
}

static int t7xx_send_pm_request(struct t7xx_pci_dev *t7xx_dev, u32 request)
{
	unsigned long wait_ret;

	reinit_completion(&t7xx_dev->pm_sr_ack);
	t7xx_mhccif_h2d_swint_trigger(t7xx_dev, request);
	wait_ret = wait_for_completion_timeout(&t7xx_dev->pm_sr_ack,
					       msecs_to_jiffies(PM_ACK_TIMEOUT_MS));
	if (!wait_ret)
		return -ETIMEDOUT;

	return 0;
}

static int __t7xx_pci_pm_suspend(struct pci_dev *pdev)
{
	enum t7xx_pm_id entity_id = PM_ENTITY_ID_INVALID;
	struct t7xx_pci_dev *t7xx_dev;
	struct md_pm_entity *entity;
	int ret;

	t7xx_dev = pci_get_drvdata(pdev);
	if (atomic_read(&t7xx_dev->md_pm_state) <= MTK_PM_INIT ||
	    READ_ONCE(t7xx_dev->mode) != T7XX_READY) {
		dev_err(&pdev->dev, "[PM] Exiting suspend, modem in invalid state\n");
		return -EFAULT;
	}

	iowrite32(T7XX_L1_BIT(0), IREG_BASE(t7xx_dev) + DISABLE_ASPM_LOWPWR);
	ret = t7xx_wait_pm_config(t7xx_dev);
	if (ret) {
		iowrite32(T7XX_L1_BIT(0), IREG_BASE(t7xx_dev) + ENABLE_ASPM_LOWPWR);
		return ret;
	}

	atomic_set(&t7xx_dev->md_pm_state, MTK_PM_SUSPENDED);
	t7xx_pcie_mac_clear_int(t7xx_dev, SAP_RGU_INT);
	t7xx_dev->rgu_pci_irq_en = false;

	list_for_each_entry(entity, &t7xx_dev->md_pm_entities, entity) {
		if (!entity->suspend)
			continue;

		ret = entity->suspend(t7xx_dev, entity->entity_param);
		if (ret) {
			entity_id = entity->id;
			dev_err(&pdev->dev, "[PM] Suspend error: %d, id: %d\n", ret, entity_id);
			goto abort_suspend;
		}
	}

	ret = t7xx_send_pm_request(t7xx_dev, H2D_CH_SUSPEND_REQ);
	if (ret) {
		dev_err(&pdev->dev, "[PM] MD suspend error: %d\n", ret);
		goto abort_suspend;
	}

	ret = t7xx_send_pm_request(t7xx_dev, H2D_CH_SUSPEND_REQ_AP);
	if (ret) {
		t7xx_send_pm_request(t7xx_dev, H2D_CH_RESUME_REQ);
		dev_err(&pdev->dev, "[PM] SAP suspend error: %d\n", ret);
		goto abort_suspend;
	}

	list_for_each_entry(entity, &t7xx_dev->md_pm_entities, entity) {
		if (entity->suspend_late)
			entity->suspend_late(t7xx_dev, entity->entity_param);
	}

	iowrite32(T7XX_L1_BIT(0), IREG_BASE(t7xx_dev) + ENABLE_ASPM_LOWPWR);
	return 0;

abort_suspend:
	list_for_each_entry(entity, &t7xx_dev->md_pm_entities, entity) {
		if (entity_id == entity->id)
			break;

		if (entity->resume)
			entity->resume(t7xx_dev, entity->entity_param);
	}

	iowrite32(T7XX_L1_BIT(0), IREG_BASE(t7xx_dev) + ENABLE_ASPM_LOWPWR);
	atomic_set(&t7xx_dev->md_pm_state, MTK_PM_RESUMED);
	t7xx_pcie_mac_set_int(t7xx_dev, SAP_RGU_INT);
	return ret;
}

static void t7xx_pcie_interrupt_reinit(struct t7xx_pci_dev *t7xx_dev)
{
	t7xx_pcie_set_mac_msix_cfg(t7xx_dev, EXT_INT_NUM);

	/* Disable interrupt first and let the IPs enable them */
	iowrite32(MSIX_MSK_SET_ALL, IREG_BASE(t7xx_dev) + IMASK_HOST_MSIX_CLR_GRP0_0);

	/* Device disables PCIe interrupts during resume and
	 * following function will re-enable PCIe interrupts.
	 */
	t7xx_pcie_mac_interrupts_en(t7xx_dev);
	t7xx_pcie_mac_set_int(t7xx_dev, MHCCIF_INT);
}

static int t7xx_pcie_reinit(struct t7xx_pci_dev *t7xx_dev, bool is_d3)
{
	int ret;

	ret = pcim_enable_device(t7xx_dev->pdev);
	if (ret)
		return ret;

	t7xx_pcie_mac_atr_init(t7xx_dev);
	t7xx_pcie_interrupt_reinit(t7xx_dev);

	if (is_d3) {
		t7xx_mhccif_init(t7xx_dev);
		t7xx_pci_pm_reinit(t7xx_dev);
	}

	return 0;
}

static int t7xx_send_fsm_command(struct t7xx_pci_dev *t7xx_dev, u32 event)
{
	struct t7xx_fsm_ctl *fsm_ctl = t7xx_dev->md->fsm_ctl;
	struct device *dev = &t7xx_dev->pdev->dev;
	int ret = -EINVAL;

	switch (event) {
	case FSM_CMD_STOP:
		ret = t7xx_fsm_append_cmd(fsm_ctl, FSM_CMD_STOP, FSM_CMD_FLAG_WAIT_FOR_COMPLETION);
		break;

	case FSM_CMD_START:
		t7xx_pcie_mac_clear_int(t7xx_dev, SAP_RGU_INT);
		t7xx_pcie_mac_clear_int_status(t7xx_dev, SAP_RGU_INT);
		t7xx_dev->rgu_pci_irq_en = true;
		t7xx_pcie_mac_set_int(t7xx_dev, SAP_RGU_INT);
		ret = t7xx_fsm_append_cmd(fsm_ctl, FSM_CMD_START, 0);
		break;

	default:
		break;
	}

	if (ret)
		dev_err(dev, "Failure handling FSM command %u, %d\n", event, ret);

	return ret;
}

int t7xx_pci_reprobe_early(struct t7xx_pci_dev *t7xx_dev)
{
	enum t7xx_mode mode = READ_ONCE(t7xx_dev->mode);
	int ret;

	if (mode == T7XX_FASTBOOT_DOWNLOAD)
		pm_runtime_put_noidle(&t7xx_dev->pdev->dev);

	ret = t7xx_send_fsm_command(t7xx_dev, FSM_CMD_STOP);
	if (ret)
		return ret;

	return 0;
}

int t7xx_pci_reprobe(struct t7xx_pci_dev *t7xx_dev, bool boot)
{
	int ret;

	ret = t7xx_pcie_reinit(t7xx_dev, boot);
	if (ret)
		return ret;

	t7xx_clear_rgu_irq(t7xx_dev);
	return t7xx_send_fsm_command(t7xx_dev, FSM_CMD_START);
}

static int __t7xx_pci_pm_resume(struct pci_dev *pdev, bool state_check)
{
	struct t7xx_pci_dev *t7xx_dev;
	struct md_pm_entity *entity;
	u32 prev_state;
	int ret = 0;

	t7xx_dev = pci_get_drvdata(pdev);
	if (atomic_read(&t7xx_dev->md_pm_state) <= MTK_PM_INIT) {
		iowrite32(T7XX_L1_BIT(0), IREG_BASE(t7xx_dev) + ENABLE_ASPM_LOWPWR);
		return 0;
	}

	t7xx_pcie_mac_interrupts_en(t7xx_dev);
	prev_state = ioread32(IREG_BASE(t7xx_dev) + T7XX_PCIE_PM_RESUME_STATE);

	if (state_check) {
		/* For D3/L3 resume, the device could boot so quickly that the
		 * initial value of the dummy register might be overwritten.
		 * Identify new boots if the ATR source address register is not initialized.
		 */
		u32 atr_reg_val = ioread32(IREG_BASE(t7xx_dev) +
					   ATR_PCIE_WIN0_T0_ATR_PARAM_SRC_ADDR);
		if (prev_state == PM_RESUME_REG_STATE_L3 ||
		    (prev_state == PM_RESUME_REG_STATE_INIT &&
		     atr_reg_val == ATR_SRC_ADDR_INVALID)) {
			ret = t7xx_pci_reprobe_early(t7xx_dev);
			if (ret)
				return ret;

			return t7xx_pci_reprobe(t7xx_dev, true);
		}

		if (prev_state == PM_RESUME_REG_STATE_EXP ||
		    prev_state == PM_RESUME_REG_STATE_L2_EXP) {
			if (prev_state == PM_RESUME_REG_STATE_L2_EXP) {
				ret = t7xx_pcie_reinit(t7xx_dev, false);
				if (ret)
					return ret;
			}

			atomic_set(&t7xx_dev->md_pm_state, MTK_PM_SUSPENDED);
			t7xx_dev->rgu_pci_irq_en = true;
			t7xx_pcie_mac_set_int(t7xx_dev, SAP_RGU_INT);

			t7xx_mhccif_mask_clr(t7xx_dev,
					     D2H_INT_EXCEPTION_INIT |
					     D2H_INT_EXCEPTION_INIT_DONE |
					     D2H_INT_EXCEPTION_CLEARQ_DONE |
					     D2H_INT_EXCEPTION_ALLQ_RESET |
					     D2H_INT_PORT_ENUM);

			return ret;
		}

		if (prev_state == PM_RESUME_REG_STATE_L2) {
			ret = t7xx_pcie_reinit(t7xx_dev, false);
			if (ret)
				return ret;

		} else if (prev_state != PM_RESUME_REG_STATE_L1 &&
			   prev_state != PM_RESUME_REG_STATE_INIT) {
			ret = t7xx_send_fsm_command(t7xx_dev, FSM_CMD_STOP);
			if (ret)
				return ret;

			t7xx_clear_rgu_irq(t7xx_dev);
			atomic_set(&t7xx_dev->md_pm_state, MTK_PM_SUSPENDED);
			return 0;
		}
	}

	iowrite32(T7XX_L1_BIT(0), IREG_BASE(t7xx_dev) + DISABLE_ASPM_LOWPWR);
	t7xx_wait_pm_config(t7xx_dev);

	list_for_each_entry(entity, &t7xx_dev->md_pm_entities, entity) {
		if (entity->resume_early)
			entity->resume_early(t7xx_dev, entity->entity_param);
	}

	ret = t7xx_send_pm_request(t7xx_dev, H2D_CH_RESUME_REQ);
	if (ret)
		dev_err(&pdev->dev, "[PM] MD resume error: %d\n", ret);

	ret = t7xx_send_pm_request(t7xx_dev, H2D_CH_RESUME_REQ_AP);
	if (ret)
		dev_err(&pdev->dev, "[PM] SAP resume error: %d\n", ret);

	list_for_each_entry(entity, &t7xx_dev->md_pm_entities, entity) {
		if (entity->resume) {
			ret = entity->resume(t7xx_dev, entity->entity_param);
			if (ret)
				dev_err(&pdev->dev, "[PM] Resume entry ID: %d error: %d\n",
					entity->id, ret);
		}
	}

	t7xx_dev->rgu_pci_irq_en = true;
	t7xx_pcie_mac_set_int(t7xx_dev, SAP_RGU_INT);
	iowrite32(T7XX_L1_BIT(0), IREG_BASE(t7xx_dev) + ENABLE_ASPM_LOWPWR);
	pm_runtime_mark_last_busy(&pdev->dev);
	atomic_set(&t7xx_dev->md_pm_state, MTK_PM_RESUMED);

	return ret;
}

static int t7xx_pci_pm_resume_noirq(struct device *dev)
{
	struct pci_dev *pdev = to_pci_dev(dev);
	struct t7xx_pci_dev *t7xx_dev;

	t7xx_dev = pci_get_drvdata(pdev);
	t7xx_pcie_mac_interrupts_dis(t7xx_dev);

	return 0;
}

static void t7xx_pci_shutdown(struct pci_dev *pdev)
{
	__t7xx_pci_pm_suspend(pdev);
}

static int t7xx_pci_pm_prepare(struct device *dev)
{
	struct pci_dev *pdev = to_pci_dev(dev);
	struct t7xx_pci_dev *t7xx_dev;

	t7xx_dev = pci_get_drvdata(pdev);
	if (!wait_for_completion_timeout(&t7xx_dev->init_done, T7XX_INIT_TIMEOUT * HZ)) {
		dev_warn(dev, "Not ready for system sleep.\n");
		return -ETIMEDOUT;
	}

	return 0;
}

static int t7xx_pci_pm_suspend(struct device *dev)
{
	return __t7xx_pci_pm_suspend(to_pci_dev(dev));
}

static int t7xx_pci_pm_resume(struct device *dev)
{
	return __t7xx_pci_pm_resume(to_pci_dev(dev), true);
}

static int t7xx_pci_pm_thaw(struct device *dev)
{
	return __t7xx_pci_pm_resume(to_pci_dev(dev), false);
}

static int t7xx_pci_pm_runtime_suspend(struct device *dev)
{
	return __t7xx_pci_pm_suspend(to_pci_dev(dev));
}

static int t7xx_pci_pm_runtime_resume(struct device *dev)
{
	return __t7xx_pci_pm_resume(to_pci_dev(dev), true);
}

static const struct dev_pm_ops t7xx_pci_pm_ops = {
	.prepare = t7xx_pci_pm_prepare,
	.suspend = t7xx_pci_pm_suspend,
	.resume = t7xx_pci_pm_resume,
	.resume_noirq = t7xx_pci_pm_resume_noirq,
	.freeze = t7xx_pci_pm_suspend,
	.thaw = t7xx_pci_pm_thaw,
	.poweroff = t7xx_pci_pm_suspend,
	.restore = t7xx_pci_pm_resume,
	.restore_noirq = t7xx_pci_pm_resume_noirq,
	.runtime_suspend = t7xx_pci_pm_runtime_suspend,
	.runtime_resume = t7xx_pci_pm_runtime_resume
};

static int t7xx_request_irq(struct pci_dev *pdev)
{
	struct t7xx_pci_dev *t7xx_dev;
	int ret = 0, i;

	t7xx_dev = pci_get_drvdata(pdev);

	for (i = 0; i < EXT_INT_NUM; i++) {
		const char *irq_descr;
		int irq_vec;

		if (!t7xx_dev->intr_handler[i])
			continue;

		irq_descr = devm_kasprintf(&pdev->dev, GFP_KERNEL, "%s_%d",
					   dev_driver_string(&pdev->dev), i);
		if (!irq_descr) {
			ret = -ENOMEM;
			break;
		}

		irq_vec = pci_irq_vector(pdev, i);
		ret = request_threaded_irq(irq_vec, t7xx_dev->intr_handler[i],
					   t7xx_dev->intr_thread[i], 0, irq_descr,
					   t7xx_dev->callback_param[i]);
		if (ret) {
			dev_err(&pdev->dev, "Failed to request IRQ: %d\n", ret);
			break;
		}
	}

	if (ret) {
		while (i--) {
			if (!t7xx_dev->intr_handler[i])
				continue;

			free_irq(pci_irq_vector(pdev, i), t7xx_dev->callback_param[i]);
		}
	}

	return ret;
}

static int t7xx_setup_msix(struct t7xx_pci_dev *t7xx_dev)
{
	struct pci_dev *pdev = t7xx_dev->pdev;
	int ret;

	/* Only using 6 interrupts, but HW-design requires power-of-2 IRQs allocation */
	ret = pci_alloc_irq_vectors(pdev, EXT_INT_NUM, EXT_INT_NUM, PCI_IRQ_MSIX);
	if (ret < 0) {
		dev_err(&pdev->dev, "Failed to allocate MSI-X entry: %d\n", ret);
		return ret;
	}

	ret = t7xx_request_irq(pdev);
	if (ret) {
		pci_free_irq_vectors(pdev);
		return ret;
	}

	t7xx_pcie_set_mac_msix_cfg(t7xx_dev, EXT_INT_NUM);
	return 0;
}

static int t7xx_interrupt_init(struct t7xx_pci_dev *t7xx_dev)
{
	int ret, i;

	if (!t7xx_dev->pdev->msix_cap)
		return -EINVAL;

	ret = t7xx_setup_msix(t7xx_dev);
	if (ret)
		return ret;

	/* IPs enable interrupts when ready */
	for (i = 0; i < EXT_INT_NUM; i++)
		t7xx_pcie_mac_set_int(t7xx_dev, i);

	return 0;
}

static void t7xx_pci_infracfg_ao_calc(struct t7xx_pci_dev *t7xx_dev)
{
	t7xx_dev->base_addr.infracfg_ao_base = t7xx_dev->base_addr.pcie_ext_reg_base +
					      INFRACFG_AO_DEV_CHIP -
					      t7xx_dev->base_addr.pcie_dev_reg_trsl_addr;
}

static int t7xx_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
{
	struct t7xx_pci_dev *t7xx_dev;
	int ret;

	t7xx_dev = devm_kzalloc(&pdev->dev, sizeof(*t7xx_dev), GFP_KERNEL);
	if (!t7xx_dev)
		return -ENOMEM;

	pci_set_drvdata(pdev, t7xx_dev);
	t7xx_dev->pdev = pdev;

	ret = pcim_enable_device(pdev);
	if (ret)
		return ret;

	pci_set_master(pdev);

	ret = pcim_iomap_regions(pdev, BIT(T7XX_PCI_IREG_BASE) | BIT(T7XX_PCI_EREG_BASE),
				 pci_name(pdev));
	if (ret) {
		dev_err(&pdev->dev, "Could not request BARs: %d\n", ret);
		return -ENOMEM;
	}

	ret = dma_set_mask(&pdev->dev, DMA_BIT_MASK(64));
	if (ret) {
		dev_err(&pdev->dev, "Could not set PCI DMA mask: %d\n", ret);
		return ret;
	}

	ret = dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(64));
	if (ret) {
		dev_err(&pdev->dev, "Could not set consistent PCI DMA mask: %d\n", ret);
		return ret;
	}

	IREG_BASE(t7xx_dev) = pcim_iomap_table(pdev)[T7XX_PCI_IREG_BASE];
	t7xx_dev->base_addr.pcie_ext_reg_base = pcim_iomap_table(pdev)[T7XX_PCI_EREG_BASE];

	ret = t7xx_pci_pm_init(t7xx_dev);
	if (ret)
		return ret;

	t7xx_pcie_mac_atr_init(t7xx_dev);
	t7xx_pci_infracfg_ao_calc(t7xx_dev);
	t7xx_mhccif_init(t7xx_dev);

	ret = t7xx_md_init(t7xx_dev);
	if (ret)
		return ret;

	t7xx_pcie_mac_interrupts_dis(t7xx_dev);

	ret = sysfs_create_group(&t7xx_dev->pdev->dev.kobj,
				 &t7xx_mode_attribute_group);
	if (ret)
		goto err_md_exit;

	ret = t7xx_interrupt_init(t7xx_dev);
	if (ret)
		goto err_remove_group;


	t7xx_pcie_mac_set_int(t7xx_dev, MHCCIF_INT);
	t7xx_pcie_mac_interrupts_en(t7xx_dev);

	return 0;

err_remove_group:
	sysfs_remove_group(&t7xx_dev->pdev->dev.kobj,
			   &t7xx_mode_attribute_group);

err_md_exit:
	t7xx_md_exit(t7xx_dev);
	return ret;
}

static void t7xx_pci_remove(struct pci_dev *pdev)
{
	struct t7xx_pci_dev *t7xx_dev;
	int i;

	t7xx_dev = pci_get_drvdata(pdev);

	sysfs_remove_group(&t7xx_dev->pdev->dev.kobj,
			   &t7xx_mode_attribute_group);
	t7xx_md_exit(t7xx_dev);

	for (i = 0; i < EXT_INT_NUM; i++) {
		if (!t7xx_dev->intr_handler[i])
			continue;

		free_irq(pci_irq_vector(pdev, i), t7xx_dev->callback_param[i]);
	}

	pci_free_irq_vectors(t7xx_dev->pdev);
}

static const struct pci_device_id t7xx_pci_table[] = {
	{ PCI_DEVICE(PCI_VENDOR_ID_MEDIATEK, 0x4d75) },
	{ PCI_DEVICE(0x14c0, 0x4d75) }, // Dell DW5933e
	{ }
};
MODULE_DEVICE_TABLE(pci, t7xx_pci_table);

static struct pci_driver t7xx_pci_driver = {
	.name = "mtk_t7xx",
	.id_table = t7xx_pci_table,
	.probe = t7xx_pci_probe,
	.remove = t7xx_pci_remove,
	.driver.pm = &t7xx_pci_pm_ops,
	.shutdown = t7xx_pci_shutdown,
};

module_pci_driver(t7xx_pci_driver);

MODULE_AUTHOR("MediaTek Inc");
MODULE_DESCRIPTION("MediaTek PCIe 5G WWAN modem T7xx driver");
MODULE_LICENSE("GPL");
