// SPDX-License-Identifier: GPL-2.0-only
/*
 * Callisto chip specific GXP MicroController Unit management.
 *
 * Copyright (C) 2022 Google LLC
 */

#include <linux/delay.h>

#include "gxp-internal.h"
#include "gxp-lpm.h"
#include "gxp-mcu.h"
#include "gxp-mcu-platform.h"

/* Setting bit 15 and 16 of GPOUT_LO_WRT register to 0 will hold MCU reset. */
#define GPOUT_LO_MCU_RESET (3u << 15)
#define GPOUT_LO_MCU_PSTATE (1u << 2)
#define GPOUT_LO_MCU_PREG (1u << 3)
#define GPIN_LO_MCU_PACCEPT (1u << 2)
#define GPIN_LO_MCU_PDENY (1u << 3)

int gxp_mcu_reset(struct gxp_dev *gxp, bool release_reset)
{
	struct gxp_mcu *mcu = &to_mcu_dev(gxp)->mcu;
	u32 gpout_lo_rd, gpin_lo_rd, orig;
	int i, ret = 0;

	/* 1. Read gpout_lo_rd register. */
	orig = gpout_lo_rd =
		lpm_read_32_psm(gxp, CORE_TO_PSM(GXP_MCU_CORE_ID), PSM_REG_GPOUT_LO_RD_OFFSET);

	/* 2. Toggle bit 15 and 16 of this register to '0'. */
	gpout_lo_rd &= ~GPOUT_LO_MCU_RESET;

	/* 3. Set psm in debug mode with debug_cfg.en=1 and debug_cfg.gpout_override=1. */
	lpm_write_32_psm(gxp, CORE_TO_PSM(GXP_MCU_CORE_ID), PSM_REG_DEBUG_CFG_OFFSET, 0b11);

	/* 4. Write the modified value from step2 to gpout_lo_wrt register. */
	lpm_write_32_psm(gxp, CORE_TO_PSM(GXP_MCU_CORE_ID), PSM_REG_GPOUT_LO_WRT_OFFSET,
			 gpout_lo_rd);

	/*
	 * 5. Wait for MCU being reset.
	 *
	 * Basically, to verify the MCU reset, we should poll bit 0 of MCU_RESET_STATUS register
	 * (CORERESET_N) to become 0.
	 *
	 * However, as we cannot access the register for the security reason, there is no way to
	 * poll it. Based on the experiment, resetting MCU was already done when the step 4 above
	 * is finished which took under 5 us. Therefore, waiting 1~2 ms as a margin should be
	 * enough.
	 */
	usleep_range(1000, 2000);

	gxp_mcu_reset_mailbox(mcu);

	if (!release_reset)
		return 0;

	/*
	 * 6. Modify gpout_lo_wrt register locally to set bit [3:2]={1,0} to let MCU transit to
	 * RUN state.
	 */
	gpout_lo_rd = (gpout_lo_rd | GPOUT_LO_MCU_PREG) & ~GPOUT_LO_MCU_PSTATE;
	lpm_write_32_psm(gxp, CORE_TO_PSM(GXP_MCU_CORE_ID), PSM_REG_GPOUT_LO_WRT_OFFSET,
			 gpout_lo_rd);

	/* 7. Toggle bit 15 and 16 of gpout_lo_wrt register to '1' to release reset. */
	gpout_lo_rd |= GPOUT_LO_MCU_RESET;
	lpm_write_32_psm(gxp, CORE_TO_PSM(GXP_MCU_CORE_ID), PSM_REG_GPOUT_LO_WRT_OFFSET,
			 gpout_lo_rd);

	/* 8. Poll gpin_lo_rd for one of bit 2 (paccept) and 3 (pdeny) becoming non-zero. */
	for (i = 10000; i > 0; i--) {
		gpin_lo_rd = lpm_read_32_psm(gxp, CORE_TO_PSM(GXP_MCU_CORE_ID),
					     PSM_REG_GPIN_LO_RD_OFFSET);
		if (gpin_lo_rd & (GPIN_LO_MCU_PACCEPT | GPIN_LO_MCU_PDENY))
			break;
		udelay(GXP_TIME_DELAY_FACTOR);
	}

	if (!i) {
		dev_warn(gxp->dev, "MCU is not responding to the power control");
		ret = -ETIMEDOUT;
	} else if (gpin_lo_rd & GPIN_LO_MCU_PDENY) {
		dev_warn(gxp->dev, "MCU denied the power control for reset");
		ret = -EAGAIN;
	}

	/* 9. Write gpout_lo_wrt the same as gpout_lo_rd of step 1. */
	lpm_write_32_psm(gxp, CORE_TO_PSM(GXP_MCU_CORE_ID), PSM_REG_GPOUT_LO_WRT_OFFSET, orig);

	/*
	 * 10. Move PSM back to func mode with gpout override disabled debug_cfg.en=0 and
	 * debug_cfg.gpout=0.
	 */
	lpm_write_32_psm(gxp, CORE_TO_PSM(GXP_MCU_CORE_ID), PSM_REG_DEBUG_CFG_OFFSET, 0);

	return ret;
}
