/*
 * Copyright (c) 2020-2022, MediaTek Inc. All rights reserved.
 *
 * SPDX-License-Identifier: BSD-3-Clause
 */

#include <common/debug.h>
#include <drivers/delay_timer.h>
#include <lib/mmio.h>

#include "platform_def.h"
#include "pmic_wrap_init.h"

/* pmic wrap module wait_idle and read polling interval (in microseconds) */
enum pwrap_polling_interval {
	WAIT_IDLE_POLLING_DELAY_US	= 1,
	READ_POLLING_DELAY_US		= 2
};

static uint32_t pwrap_check_idle(void *wacs_register, uint32_t timeout_us)
{
	uint32_t reg_rdata = 0U, retry;

	retry = (timeout_us + WAIT_IDLE_POLLING_DELAY_US) /
		WAIT_IDLE_POLLING_DELAY_US;
	while (retry != 0) {
		udelay(WAIT_IDLE_POLLING_DELAY_US);
		reg_rdata = mmio_read_32((uintptr_t)wacs_register);
		/* if last read command timeout,clear vldclr bit
		 * read command state machine:FSM_REQ-->wfdle-->WFVLDCLR;
		 * write:FSM_REQ-->idle
		 */
		switch (GET_WACS_FSM(reg_rdata)) {
		case SWINF_FSM_WFVLDCLR:
			mmio_write_32((uintptr_t)&mtk_pwrap->wacs2_vldclr, 0x1);
			INFO("WACS_FSM = SWINF_FSM_WFVLDCLR\n");
			break;
		case SWINF_FSM_WFDLE:
			INFO("WACS_FSM = SWINF_FSM_WFDLE\n");
			break;
		case SWINF_FSM_REQ:
			INFO("WACS_FSM = SWINF_FSM_REQ\n");
			break;
		case SWINF_FSM_IDLE:
			goto done;
		default:
			break;
		}
		retry--;
	};

done:
	if (retry == 0) {
		/* timeout */
		return E_PWR_WAIT_IDLE_TIMEOUT;
	}

	return 0U;
}

static uint32_t pwrap_check_vldclr(void *wacs_register, uint32_t timeout_us)
{
	uint32_t reg_rdata = 0U, retry;

	retry = (timeout_us + READ_POLLING_DELAY_US) / READ_POLLING_DELAY_US;
	while (retry != 0) {
		udelay(READ_POLLING_DELAY_US);
		reg_rdata = mmio_read_32((uintptr_t)wacs_register);
		if (GET_WACS_FSM(reg_rdata) == SWINF_FSM_WFVLDCLR) {
			break;
		}
		retry--;
	};

	if (retry == 0) {
		/* timeout */
		return E_PWR_WAIT_IDLE_TIMEOUT;
	}

	return 0U;
}

static int32_t pwrap_wacs2(uint32_t write, uint32_t adr, uint32_t wdata,
			   uint32_t *rdata, uint32_t init_check)
{
	uint32_t reg_rdata, return_value;

	if (init_check != 0) {
		if ((mmio_read_32((uintptr_t)&mtk_pwrap->init_done) & 0x1) == 0) {
			ERROR("initialization isn't finished\n");
			return E_PWR_NOT_INIT_DONE;
		}
	}

	/* Wait for Software Interface FSM state to be IDLE. */
	return_value = pwrap_check_idle(&mtk_pwrap->wacs2_sta,
					PWRAP_WAIT_IDLE_US);
	if (return_value != 0) {
		return return_value;
	}

	/* Set the write data */
	if (write == 1) {
		/* Set the write data. */
		mmio_write_32((uintptr_t)&mtk_pwrap->wacs2_wdata, wdata);
	}

	/* Send the command. */
	mmio_write_32((uintptr_t)&mtk_pwrap->wacs2_cmd, (write << 29) | adr);

	if (write == 0) {
		/*
		 * Wait for Software Interface FSM state to be WFVLDCLR,
		 * read the data and clear the valid flag.
		 */
		return_value = pwrap_check_vldclr(&mtk_pwrap->wacs2_sta,
						  PWRAP_READ_US);
		if (return_value != 0) {
			return return_value;
		}

		if (rdata == NULL) {
			return E_PWR_INVALID_ARG;
		}

		reg_rdata = mmio_read_32((uintptr_t)&mtk_pwrap->wacs2_rdata);
		*rdata = reg_rdata;
		mmio_write_32((uintptr_t)&mtk_pwrap->wacs2_vldclr, 0x1);
	}

	return return_value;
}

/* external API for pmic_wrap user */
int32_t pwrap_read(uint32_t adr, uint32_t *rdata)
{
	return pwrap_wacs2(0, adr, 0, rdata, 1);
}

int32_t pwrap_write(uint32_t adr, uint32_t wdata)
{
	return pwrap_wacs2(1, adr, wdata, 0, 1);
}
