/*
 * Copyright (c) 2017-2019, STMicroelectronics - All Rights Reserved
 *
 * SPDX-License-Identifier: BSD-3-Clause
 */

#include <errno.h>
#include <stdbool.h>

#include <libfdt.h>

#include <platform_def.h>

#include <common/debug.h>
#include <drivers/delay_timer.h>
#include <drivers/st/stm32mp_pmic.h>
#include <drivers/st/stm32_gpio.h>
#include <drivers/st/stm32mp1_clk.h>
#include <drivers/st/stpmic1.h>
#include <lib/mmio.h>
#include <lib/utils_def.h>

/* I2C Timing hard-coded value, for I2C clock source is HSI at 64MHz */
#define I2C_TIMING			0x10D07DB5

#define I2C_TIMEOUT			0xFFFFF

#define MASK_RESET_BUCK3		BIT(2)

#define STPMIC1_LDO12356_OUTPUT_MASK	(uint8_t)(GENMASK(6, 2))
#define STPMIC1_LDO12356_OUTPUT_SHIFT	2
#define STPMIC1_LDO3_MODE		(uint8_t)(BIT(7))
#define STPMIC1_LDO3_DDR_SEL		31U
#define STPMIC1_LDO3_1800000		(9U << STPMIC1_LDO12356_OUTPUT_SHIFT)

#define STPMIC1_BUCK_OUTPUT_SHIFT	2
#define STPMIC1_BUCK3_1V8		(39U << STPMIC1_BUCK_OUTPUT_SHIFT)

#define STPMIC1_DEFAULT_START_UP_DELAY_MS	1

static struct i2c_handle_s i2c_handle;
static uint32_t pmic_i2c_addr;

static int dt_get_pmic_node(void *fdt)
{
	return fdt_node_offset_by_compatible(fdt, -1, "st,stpmic1");
}

bool dt_check_pmic(void)
{
	int node;
	void *fdt;

	if (fdt_get_address(&fdt) == 0) {
		return false;
	}

	node = dt_get_pmic_node(fdt);
	if (node < 0) {
		VERBOSE("%s: No PMIC node found in DT\n", __func__);
		return false;
	}

	return fdt_check_status(node);
}

static int dt_pmic_i2c_config(struct dt_node_info *i2c_info)
{
	int pmic_node, i2c_node;
	void *fdt;
	const fdt32_t *cuint;

	if (fdt_get_address(&fdt) == 0) {
		return -ENOENT;
	}

	pmic_node = dt_get_pmic_node(fdt);
	if (pmic_node < 0) {
		return -FDT_ERR_NOTFOUND;
	}

	cuint = fdt_getprop(fdt, pmic_node, "reg", NULL);
	if (cuint == NULL) {
		return -FDT_ERR_NOTFOUND;
	}

	pmic_i2c_addr = fdt32_to_cpu(*cuint) << 1;
	if (pmic_i2c_addr > UINT16_MAX) {
		return -EINVAL;
	}

	i2c_node = fdt_parent_offset(fdt, pmic_node);
	if (i2c_node < 0) {
		return -FDT_ERR_NOTFOUND;
	}

	dt_fill_device_info(i2c_info, i2c_node);
	if (i2c_info->base == 0U) {
		return -FDT_ERR_NOTFOUND;
	}

	return dt_set_pinctrl_config(i2c_node);
}

int dt_pmic_enable_boot_on_regulators(void)
{
	int pmic_node, regulators_node, regulator_node;
	void *fdt;

	if (fdt_get_address(&fdt) == 0) {
		return -ENOENT;
	}

	pmic_node = dt_get_pmic_node(fdt);
	if (pmic_node < 0) {
		return -FDT_ERR_NOTFOUND;
	}

	regulators_node = fdt_subnode_offset(fdt, pmic_node, "regulators");

	fdt_for_each_subnode(regulator_node, fdt, regulators_node) {
		const fdt32_t *cuint;
		const char *node_name;
		uint16_t voltage;

		if (fdt_getprop(fdt, regulator_node, "regulator-boot-on",
				NULL) == NULL) {
			continue;
		}

		cuint = fdt_getprop(fdt, regulator_node,
				    "regulator-min-microvolt", NULL);
		if (cuint == NULL) {
			continue;
		}

		/* DT uses microvolts, whereas driver awaits millivolts */
		voltage = (uint16_t)(fdt32_to_cpu(*cuint) / 1000U);
		node_name = fdt_get_name(fdt, regulator_node, NULL);

		if (stpmic1_is_regulator_enabled(node_name) == 0U) {
			int status;

			status = stpmic1_regulator_voltage_set(node_name,
							       voltage);
			if (status != 0) {
				return status;
			}

			status = stpmic1_regulator_enable(node_name);
			if (status != 0) {
				return status;
			}
		}
	}

	return 0;
}

void initialize_pmic_i2c(void)
{
	int ret;
	struct dt_node_info i2c_info;

	if (dt_pmic_i2c_config(&i2c_info) != 0) {
		ERROR("I2C configuration failed\n");
		panic();
	}

	if (stm32mp1_clk_enable((uint32_t)i2c_info.clock) < 0) {
		ERROR("I2C clock enable failed\n");
		panic();
	}

	/* Initialize PMIC I2C */
	i2c_handle.i2c_base_addr		= i2c_info.base;
	i2c_handle.i2c_init.timing		= I2C_TIMING;
	i2c_handle.i2c_init.own_address1	= pmic_i2c_addr;
	i2c_handle.i2c_init.addressing_mode	= I2C_ADDRESSINGMODE_7BIT;
	i2c_handle.i2c_init.dual_address_mode	= I2C_DUALADDRESS_DISABLE;
	i2c_handle.i2c_init.own_address2	= 0;
	i2c_handle.i2c_init.own_address2_masks	= I2C_OAR2_OA2NOMASK;
	i2c_handle.i2c_init.general_call_mode	= I2C_GENERALCALL_DISABLE;
	i2c_handle.i2c_init.no_stretch_mode	= I2C_NOSTRETCH_DISABLE;

	ret = stm32_i2c_init(&i2c_handle);
	if (ret != 0) {
		ERROR("Cannot initialize I2C %x (%d)\n",
		      i2c_handle.i2c_base_addr, ret);
		panic();
	}

	ret = stm32_i2c_config_analog_filter(&i2c_handle,
					     I2C_ANALOGFILTER_ENABLE);
	if (ret != 0) {
		ERROR("Cannot initialize I2C analog filter (%d)\n", ret);
		panic();
	}

	ret = stm32_i2c_is_device_ready(&i2c_handle, (uint16_t)pmic_i2c_addr, 1,
					I2C_TIMEOUT);
	if (ret != 0) {
		ERROR("I2C device not ready (%d)\n", ret);
		panic();
	}

	stpmic1_bind_i2c(&i2c_handle, (uint16_t)pmic_i2c_addr);
}

void initialize_pmic(void)
{
	int status;
	uint8_t read_val;

	initialize_pmic_i2c();

	status = stpmic1_register_read(VERSION_STATUS_REG, &read_val);
	if (status != 0) {
		panic();
	}

	INFO("PMIC version = 0x%x\n", read_val);

	/* Keep VDD on during the reset cycle */
	status = stpmic1_register_update(MASK_RESET_BUCK_REG,
					MASK_RESET_BUCK3,
					MASK_RESET_BUCK3);
	if (status != 0) {
		panic();
	}
}

int pmic_ddr_power_init(enum ddr_type ddr_type)
{
	bool buck3_at_1v8 = false;
	uint8_t read_val;
	int status;

	switch (ddr_type) {
	case STM32MP_DDR3:
		/* Set LDO3 to sync mode */
		status = stpmic1_register_read(LDO3_CONTROL_REG, &read_val);
		if (status != 0) {
			return status;
		}

		read_val &= ~STPMIC1_LDO3_MODE;
		read_val &= ~STPMIC1_LDO12356_OUTPUT_MASK;
		read_val |= STPMIC1_LDO3_DDR_SEL <<
			    STPMIC1_LDO12356_OUTPUT_SHIFT;

		status = stpmic1_register_write(LDO3_CONTROL_REG, read_val);
		if (status != 0) {
			return status;
		}

		status = stpmic1_regulator_voltage_set("buck2", 1350);
		if (status != 0) {
			return status;
		}

		status = stpmic1_regulator_enable("buck2");
		if (status != 0) {
			return status;
		}

		mdelay(STPMIC1_DEFAULT_START_UP_DELAY_MS);

		status = stpmic1_regulator_enable("vref_ddr");
		if (status != 0) {
			return status;
		}

		mdelay(STPMIC1_DEFAULT_START_UP_DELAY_MS);

		status = stpmic1_regulator_enable("ldo3");
		if (status != 0) {
			return status;
		}

		mdelay(STPMIC1_DEFAULT_START_UP_DELAY_MS);
		break;

	case STM32MP_LPDDR2:
		/*
		 * Set LDO3 to 1.8V
		 * Set LDO3 to bypass mode if BUCK3 = 1.8V
		 * Set LDO3 to normal mode if BUCK3 != 1.8V
		 */
		status = stpmic1_register_read(BUCK3_CONTROL_REG, &read_val);
		if (status != 0) {
			return status;
		}

		if ((read_val & STPMIC1_BUCK3_1V8) == STPMIC1_BUCK3_1V8) {
			buck3_at_1v8 = true;
		}

		status = stpmic1_register_read(LDO3_CONTROL_REG, &read_val);
		if (status != 0) {
			return status;
		}

		read_val &= ~STPMIC1_LDO3_MODE;
		read_val &= ~STPMIC1_LDO12356_OUTPUT_MASK;
		read_val |= STPMIC1_LDO3_1800000;
		if (buck3_at_1v8) {
			read_val |= STPMIC1_LDO3_MODE;
		}

		status = stpmic1_register_write(LDO3_CONTROL_REG, read_val);
		if (status != 0) {
			return status;
		}

		status = stpmic1_regulator_voltage_set("buck2", 1200);
		if (status != 0) {
			return status;
		}

		status = stpmic1_regulator_enable("ldo3");
		if (status != 0) {
			return status;
		}

		mdelay(STPMIC1_DEFAULT_START_UP_DELAY_MS);

		status = stpmic1_regulator_enable("buck2");
		if (status != 0) {
			return status;
		}

		mdelay(STPMIC1_DEFAULT_START_UP_DELAY_MS);

		status = stpmic1_regulator_enable("vref_ddr");
		if (status != 0) {
			return status;
		}

		mdelay(STPMIC1_DEFAULT_START_UP_DELAY_MS);
		break;

	default:
		break;
	};

	return 0;
}
