/*
 * SPDX-License-Identifier: BSD-2-Clause
 *
 * Copyright (c) 2022 StarFive
 *
 * Authors:
 *   Wei Liang Lim <weiliang.lim@starfivetech.com>
 *   Minda Chen <minda.chen@starfivetech.com>
 */

#include <libfdt.h>
#include <platform_override.h>
#include <sbi/sbi_error.h>
#include <sbi/sbi_bitops.h>
#include <sbi/sbi_system.h>
#include <sbi/sbi_console.h>
#include <sbi/sbi_timer.h>
#include <sbi/riscv_io.h>
#include <sbi_utils/fdt/fdt_helper.h>
#include <sbi_utils/reset/fdt_reset.h>
#include <sbi_utils/i2c/fdt_i2c.h>

struct pmic {
	struct i2c_adapter *adapter;
	u32 dev_addr;
	const char *compatible;
};

struct jh7110 {
	u64 pmu_reg_base;
	u64 clk_reg_base;
	u32 i2c_clk_offset;
};

static struct pmic pmic_inst;
static struct jh7110 jh7110_inst;
static u32 selected_hartid = -1;

/* PMU register define */
#define HW_EVENT_TURN_ON_MASK		0x04
#define HW_EVENT_TURN_OFF_MASK		0x08
#define SW_TURN_ON_POWER_MODE		0x0C
#define SW_TURN_OFF_POWER_MODE		0x10
#define SW_ENCOURAGE			0x44
#define PMU_INT_MASK			0x48
#define PCH_BYPASS			0x4C
#define PCH_PSTATE			0x50
#define PCH_TIMEOUT			0x54
#define LP_TIMEOUT			0x58
#define HW_TURN_ON_MODE			0x5C
#define CURR_POWER_MODE			0x80
#define PMU_EVENT_STATUS		0x88
#define PMU_INT_STATUS			0x8C

/* sw encourage cfg */
#define SW_MODE_ENCOURAGE_EN_LO		0x05
#define SW_MODE_ENCOURAGE_EN_HI		0x50
#define SW_MODE_ENCOURAGE_DIS_LO	0x0A
#define SW_MODE_ENCOURAGE_DIS_HI	0xA0
#define SW_MODE_ENCOURAGE_ON		0xFF

#define DEVICE_PD_MASK			0xfc
#define SYSTOP_CPU_PD_MASK		0x3

#define TIMEOUT_COUNT			100000
#define AXP15060_POWER_REG		0x32
#define AXP15060_POWER_OFF_BIT		BIT(7)
#define AXP15060_RESET_BIT		BIT(6)

#define I2C_APB_CLK_ENABLE_BIT		BIT(31)

static int pm_system_reset_check(u32 type, u32 reason)
{
	switch (type) {
	case SBI_SRST_RESET_TYPE_SHUTDOWN:
		return 1;
	case SBI_SRST_RESET_TYPE_COLD_REBOOT:
		return 255;
	default:
		break;
	}

	return 0;
}

static int wait_pmu_pd_state(u32 mask)
{
	int count = 0;
	unsigned long addr = jh7110_inst.pmu_reg_base;
	u32 val;

	do {
		val = readl((void *)(addr + CURR_POWER_MODE));
		if (val == mask)
			return 0;

		sbi_timer_udelay(2);
		count += 1;
		if (count == TIMEOUT_COUNT)
			return SBI_ETIMEDOUT;
	} while (1);
}

static int shutdown_device_power_domain(void)
{
	unsigned long addr = jh7110_inst.pmu_reg_base;
	u32 curr_mode;
	int ret = 0;

	curr_mode = readl((void *)(addr + CURR_POWER_MODE));
	curr_mode &= DEVICE_PD_MASK;

	if (curr_mode) {
		writel(curr_mode, (void *)(addr + SW_TURN_OFF_POWER_MODE));
		writel(SW_MODE_ENCOURAGE_ON, (void *)(addr + SW_ENCOURAGE));
		writel(SW_MODE_ENCOURAGE_DIS_LO, (void *)(addr + SW_ENCOURAGE));
		writel(SW_MODE_ENCOURAGE_DIS_HI, (void *)(addr + SW_ENCOURAGE));
		ret = wait_pmu_pd_state(SYSTOP_CPU_PD_MASK);
		if (ret)
			sbi_printf("%s shutdown device power %x error\n",
				   __func__, curr_mode);
	}
	return ret;
}

static void pmic_ops(struct pmic *pmic, int type)
{
	int ret = 0;
	u8 val;

	ret = shutdown_device_power_domain();

	if (ret)
		return;

	if (!sbi_strcmp("stf,axp15060-regulator", pmic->compatible)) {
		ret = i2c_adapter_reg_read(pmic->adapter, pmic->dev_addr,
					   AXP15060_POWER_REG, &val);

		if (ret) {
			sbi_printf("%s: cannot read pmic power register\n",
				   __func__);
			return;
		}

		val |= AXP15060_POWER_OFF_BIT;
		if (type == SBI_SRST_RESET_TYPE_SHUTDOWN)
			val |= AXP15060_POWER_OFF_BIT;
		else
			val |= AXP15060_RESET_BIT;

		ret = i2c_adapter_reg_write(pmic->adapter, pmic->dev_addr,
					    AXP15060_POWER_REG, val);
		if (ret)
			sbi_printf("%s: cannot write pmic power register\n",
				   __func__);
	}
}

static void pmic_i2c_clk_enable(void)
{
	unsigned long clock_base;
	unsigned int val;

	clock_base = jh7110_inst.clk_reg_base + jh7110_inst.i2c_clk_offset;
	val = readl((void *)clock_base);

	if (!val)
		writel(I2C_APB_CLK_ENABLE_BIT, (void *)clock_base);
}

static void pm_system_reset(u32 type, u32 reason)
{
	if (pmic_inst.adapter) {
		switch (type) {
		case SBI_SRST_RESET_TYPE_SHUTDOWN:
		case SBI_SRST_RESET_TYPE_COLD_REBOOT:
			/* i2c clk may be disabled by kernel driver */
			pmic_i2c_clk_enable();
			pmic_ops(&pmic_inst, type);
			break;
		default:
			break;
		}
	}

	sbi_hart_hang();
}

static struct sbi_system_reset_device pm_reset = {
	.name = "pm-reset",
	.system_reset_check = pm_system_reset_check,
	.system_reset = pm_system_reset
};

static int pm_reset_init(void *fdt, int nodeoff,
			 const struct fdt_match *match)
{
	int rc;
	int i2c_bus;
	struct i2c_adapter *adapter;
	u64 addr;

	rc = fdt_get_node_addr_size(fdt, nodeoff, 0, &addr, NULL);
	if (rc)
		return rc;

	pmic_inst.dev_addr = addr;
	pmic_inst.compatible = match->compatible;

	i2c_bus = fdt_parent_offset(fdt, nodeoff);
	if (i2c_bus < 0)
		return i2c_bus;

	/* i2c adapter get */
	rc = fdt_i2c_adapter_get(fdt, i2c_bus, &adapter);
	if (rc)
		return rc;

	pmic_inst.adapter = adapter;

	sbi_system_reset_add_device(&pm_reset);

	return 0;
}

static const struct fdt_match pm_reset_match[] = {
	{ .compatible = "stf,axp15060-regulator", .data = (void *)true },
	{ },
};

static struct fdt_reset fdt_reset_pmic = {
	.match_table = pm_reset_match,
	.init = pm_reset_init,
};

static int starfive_jh7110_inst_init(void *fdt)
{
	int noff, rc = 0;
	const fdt32_t *val;
	int len;
	u64 addr;

	noff = fdt_node_offset_by_compatible(fdt, -1, "starfive,jh7110-pmu");
	if (-1 < noff) {
		rc = fdt_get_node_addr_size(fdt, noff, 0, &addr, NULL);
		if (rc)
			goto err;
		jh7110_inst.pmu_reg_base = addr;
	}

	noff = fdt_node_offset_by_compatible(fdt, -1, "starfive,jh7110-syscrg");
	if (-1 < noff) {
		rc = fdt_get_node_addr_size(fdt, noff, 0, &addr, NULL);
		if (rc)
			goto err;
		jh7110_inst.clk_reg_base = addr;
	}

	if (pmic_inst.adapter) {
		/*
		 * The clocks property looks like this:
		 *    clocks = <&syscrg JH7110_SYSCLK_I2C5_APB>;
		 *
		 * So, check that the length is 8 bytes, and get
		 * the offset from the second value.
		 */
		val = fdt_getprop(fdt, pmic_inst.adapter->id, "clocks", &len);
		if (val && len == 8)
			jh7110_inst.i2c_clk_offset = fdt32_to_cpu(val[1]) << 2;
		else
			rc = SBI_EINVAL;
	}
err:
	return rc;
}

static int starfive_jh7110_final_init(bool cold_boot,
				      const struct fdt_match *match)
{
	void *fdt = fdt_get_address();

	if (cold_boot) {
		fdt_reset_driver_init(fdt, &fdt_reset_pmic);
		return starfive_jh7110_inst_init(fdt);
	}

	return 0;
}

static bool starfive_jh7110_cold_boot_allowed(u32 hartid,
				   const struct fdt_match *match)
{
	if (selected_hartid != -1)
		return (selected_hartid == hartid);

	return true;
}

static void starfive_jh7110_fw_init(void *fdt, const struct fdt_match *match)
{
	const fdt32_t *val;
	int len, coff;

	coff = fdt_path_offset(fdt, "/chosen");
	if (-1 < coff) {
		val = fdt_getprop(fdt, coff, "starfive,boot-hart-id", &len);
		if (val && len >= sizeof(fdt32_t))
			selected_hartid = (u32) fdt32_to_cpu(*val);
	}
}

static const struct fdt_match starfive_jh7110_match[] = {
	{ .compatible = "starfive,jh7110" },
	{ },
};

const struct platform_override starfive_jh7110 = {
	.match_table = starfive_jh7110_match,
	.cold_boot_allowed = starfive_jh7110_cold_boot_allowed,
	.fw_init = starfive_jh7110_fw_init,
	.final_init = starfive_jh7110_final_init,
};
