// SPDX-License-Identifier: ISC
/* Copyright (C) 2021 MediaTek Inc. */

#include <linux/kernel.h>
#include <linux/mmc/sdio_func.h>
#include <linux/module.h>
#include <linux/iopoll.h>

#include "mt7921.h"
#include "../sdio.h"
#include "mac.h"
#include "mcu.h"
#include "regs.h"

static int
mt7921s_mcu_send_message(struct mt76_dev *mdev, struct sk_buff *skb,
			 int cmd, int *seq)
{
	struct mt7921_dev *dev = container_of(mdev, struct mt7921_dev, mt76);
	enum mt7921_sdio_pkt_type type = MT7921_SDIO_CMD;
	enum mt76_mcuq_id txq = MT_MCUQ_WM;
	int ret, pad;

	/* We just return in case firmware assertion to avoid blocking the
	 * common workqueue to run, for example, the coredump work might be
	 * blocked by mt7921_mac_work that is excuting register access via sdio
	 * bus.
	 */
	if (dev->fw_assert)
		return -EBUSY;

	ret = mt76_connac2_mcu_fill_message(mdev, skb, cmd, seq);
	if (ret)
		return ret;

	mdev->mcu.timeout = 3 * HZ;

	if (cmd == MCU_CMD(FW_SCATTER))
		type = MT7921_SDIO_FWDL;

	mt7921_skb_add_usb_sdio_hdr(dev, skb, type);
	pad = round_up(skb->len, 4) - skb->len;
	__skb_put_zero(skb, pad);

	ret = mt76_tx_queue_skb_raw(dev, mdev->q_mcu[txq], skb, 0);
	if (ret)
		return ret;

	mt76_queue_kick(dev, mdev->q_mcu[txq]);

	return ret;
}

static u32 mt7921s_read_rm3r(struct mt7921_dev *dev)
{
	struct mt76_sdio *sdio = &dev->mt76.sdio;

	return sdio_readl(sdio->func, MCR_D2HRM3R, NULL);
}

static u32 mt7921s_clear_rm3r_drv_own(struct mt7921_dev *dev)
{
	struct mt76_sdio *sdio = &dev->mt76.sdio;
	u32 val;

	val = sdio_readl(sdio->func, MCR_D2HRM3R, NULL);
	if (val)
		sdio_writel(sdio->func, H2D_SW_INT_CLEAR_MAILBOX_ACK,
			    MCR_WSICR, NULL);

	return val;
}

int mt7921s_mcu_init(struct mt7921_dev *dev)
{
	static const struct mt76_mcu_ops mt7921s_mcu_ops = {
		.headroom = MT_SDIO_HDR_SIZE +
			    sizeof(struct mt76_connac2_mcu_txd),
		.tailroom = MT_SDIO_TAIL_SIZE,
		.mcu_skb_send_msg = mt7921s_mcu_send_message,
		.mcu_parse_response = mt7921_mcu_parse_response,
		.mcu_rr = mt76_connac_mcu_reg_rr,
		.mcu_wr = mt76_connac_mcu_reg_wr,
	};
	int ret;

	mt7921s_mcu_drv_pmctrl(dev);

	dev->mt76.mcu_ops = &mt7921s_mcu_ops;

	ret = mt7921_run_firmware(dev);
	if (ret)
		return ret;

	set_bit(MT76_STATE_MCU_RUNNING, &dev->mphy.state);

	return 0;
}

int mt7921s_mcu_drv_pmctrl(struct mt7921_dev *dev)
{
	struct sdio_func *func = dev->mt76.sdio.func;
	struct mt76_phy *mphy = &dev->mt76.phy;
	struct mt76_connac_pm *pm = &dev->pm;
	u32 status;
	int err;

	sdio_claim_host(func);

	sdio_writel(func, WHLPCR_FW_OWN_REQ_CLR, MCR_WHLPCR, NULL);

	err = readx_poll_timeout(mt76s_read_pcr, &dev->mt76, status,
				 status & WHLPCR_IS_DRIVER_OWN, 2000, 1000000);

	if (!err && test_bit(MT76_STATE_MCU_RUNNING, &dev->mphy.state))
		err = readx_poll_timeout(mt7921s_read_rm3r, dev, status,
					 status & D2HRM3R_IS_DRIVER_OWN,
					 2000, 1000000);

	sdio_release_host(func);

	if (err < 0) {
		dev_err(dev->mt76.dev, "driver own failed\n");
		return -EIO;
	}

	clear_bit(MT76_STATE_PM, &mphy->state);

	pm->stats.last_wake_event = jiffies;
	pm->stats.doze_time += pm->stats.last_wake_event -
			       pm->stats.last_doze_event;

	return 0;
}

int mt7921s_mcu_fw_pmctrl(struct mt7921_dev *dev)
{
	struct sdio_func *func = dev->mt76.sdio.func;
	struct mt76_phy *mphy = &dev->mt76.phy;
	struct mt76_connac_pm *pm = &dev->pm;
	u32 status;
	int err;

	sdio_claim_host(func);

	if (test_bit(MT76_STATE_MCU_RUNNING, &dev->mphy.state)) {
		err = readx_poll_timeout(mt7921s_clear_rm3r_drv_own,
					 dev, status,
					 !(status & D2HRM3R_IS_DRIVER_OWN),
					 2000, 1000000);
		if (err < 0) {
			dev_err(dev->mt76.dev, "mailbox ACK not cleared\n");
			goto out;
		}
	}

	sdio_writel(func, WHLPCR_FW_OWN_REQ_SET, MCR_WHLPCR, NULL);

	err = readx_poll_timeout(mt76s_read_pcr, &dev->mt76, status,
				 !(status & WHLPCR_IS_DRIVER_OWN), 2000, 1000000);
out:
	sdio_release_host(func);

	if (err < 0) {
		dev_err(dev->mt76.dev, "firmware own failed\n");
		clear_bit(MT76_STATE_PM, &mphy->state);
		return -EIO;
	}

	pm->stats.last_doze_event = jiffies;
	pm->stats.awake_time += pm->stats.last_doze_event -
				pm->stats.last_wake_event;

	return 0;
}
