// SPDX-License-Identifier: GPL-2.0
/*
 * NHI specific operations
 *
 * Copyright (C) 2019, Intel Corporation
 * Author: Mika Westerberg <mika.westerberg@linux.intel.com>
 */

#include <linux/delay.h>
#include <linux/suspend.h>

#include "nhi.h"
#include "nhi_regs.h"
#include "tb.h"

/* Ice Lake specific NHI operations */

#define ICL_LC_MAILBOX_TIMEOUT	500 /* ms */

static int check_for_device(struct device *dev, void *data)
{
	return tb_is_switch(dev);
}

static bool icl_nhi_is_device_connected(struct tb_nhi *nhi)
{
	struct tb *tb = pci_get_drvdata(nhi->pdev);
	int ret;

	ret = device_for_each_child(&tb->root_switch->dev, NULL,
				    check_for_device);
	return ret > 0;
}

static int icl_nhi_force_power(struct tb_nhi *nhi, bool power)
{
	u32 vs_cap;

	/*
	 * The Thunderbolt host controller is present always in Ice Lake
	 * but the firmware may not be loaded and running (depending
	 * whether there is device connected and so on). Each time the
	 * controller is used we need to "Force Power" it first and wait
	 * for the firmware to indicate it is up and running. This "Force
	 * Power" is really not about actually powering on/off the
	 * controller so it is accessible even if "Force Power" is off.
	 *
	 * The actual power management happens inside shared ACPI power
	 * resources using standard ACPI methods.
	 */
	pci_read_config_dword(nhi->pdev, VS_CAP_22, &vs_cap);
	if (power) {
		vs_cap &= ~VS_CAP_22_DMA_DELAY_MASK;
		vs_cap |= 0x22 << VS_CAP_22_DMA_DELAY_SHIFT;
		vs_cap |= VS_CAP_22_FORCE_POWER;
	} else {
		vs_cap &= ~VS_CAP_22_FORCE_POWER;
	}
	pci_write_config_dword(nhi->pdev, VS_CAP_22, vs_cap);

	if (power) {
		unsigned int retries = 350;
		u32 val;

		/* Wait until the firmware tells it is up and running */
		do {
			pci_read_config_dword(nhi->pdev, VS_CAP_9, &val);
			if (val & VS_CAP_9_FW_READY)
				return 0;
			usleep_range(3000, 3100);
		} while (--retries);

		return -ETIMEDOUT;
	}

	return 0;
}

static void icl_nhi_lc_mailbox_cmd(struct tb_nhi *nhi, enum icl_lc_mailbox_cmd cmd)
{
	u32 data;

	data = (cmd << VS_CAP_19_CMD_SHIFT) & VS_CAP_19_CMD_MASK;
	pci_write_config_dword(nhi->pdev, VS_CAP_19, data | VS_CAP_19_VALID);
}

static int icl_nhi_lc_mailbox_cmd_complete(struct tb_nhi *nhi, int timeout)
{
	unsigned long end;
	u32 data;

	if (!timeout)
		goto clear;

	end = jiffies + msecs_to_jiffies(timeout);
	do {
		pci_read_config_dword(nhi->pdev, VS_CAP_18, &data);
		if (data & VS_CAP_18_DONE)
			goto clear;
		usleep_range(1000, 1100);
	} while (time_before(jiffies, end));

	return -ETIMEDOUT;

clear:
	/* Clear the valid bit */
	pci_write_config_dword(nhi->pdev, VS_CAP_19, 0);
	return 0;
}

static void icl_nhi_set_ltr(struct tb_nhi *nhi)
{
	u32 max_ltr, ltr;

	pci_read_config_dword(nhi->pdev, VS_CAP_16, &max_ltr);
	max_ltr &= 0xffff;
	/* Program the same value for both snoop and no-snoop */
	ltr = max_ltr << 16 | max_ltr;
	pci_write_config_dword(nhi->pdev, VS_CAP_15, ltr);
}

static int icl_nhi_suspend(struct tb_nhi *nhi)
{
	struct tb *tb = pci_get_drvdata(nhi->pdev);
	int ret;

	if (icl_nhi_is_device_connected(nhi))
		return 0;

	if (tb_switch_is_icm(tb->root_switch)) {
		/*
		 * If there is no device connected we need to perform
		 * both: a handshake through LC mailbox and force power
		 * down before entering D3.
		 */
		icl_nhi_lc_mailbox_cmd(nhi, ICL_LC_PREPARE_FOR_RESET);
		ret = icl_nhi_lc_mailbox_cmd_complete(nhi, ICL_LC_MAILBOX_TIMEOUT);
		if (ret)
			return ret;
	}

	return icl_nhi_force_power(nhi, false);
}

static int icl_nhi_suspend_noirq(struct tb_nhi *nhi, bool wakeup)
{
	struct tb *tb = pci_get_drvdata(nhi->pdev);
	enum icl_lc_mailbox_cmd cmd;

	if (!pm_suspend_via_firmware())
		return icl_nhi_suspend(nhi);

	if (!tb_switch_is_icm(tb->root_switch))
		return 0;

	cmd = wakeup ? ICL_LC_GO2SX : ICL_LC_GO2SX_NO_WAKE;
	icl_nhi_lc_mailbox_cmd(nhi, cmd);
	return icl_nhi_lc_mailbox_cmd_complete(nhi, ICL_LC_MAILBOX_TIMEOUT);
}

static int icl_nhi_resume(struct tb_nhi *nhi)
{
	int ret;

	ret = icl_nhi_force_power(nhi, true);
	if (ret)
		return ret;

	icl_nhi_set_ltr(nhi);
	return 0;
}

static void icl_nhi_shutdown(struct tb_nhi *nhi)
{
	icl_nhi_force_power(nhi, false);
}

const struct tb_nhi_ops icl_nhi_ops = {
	.init = icl_nhi_resume,
	.suspend_noirq = icl_nhi_suspend_noirq,
	.resume_noirq = icl_nhi_resume,
	.runtime_suspend = icl_nhi_suspend,
	.runtime_resume = icl_nhi_resume,
	.shutdown = icl_nhi_shutdown,
};
