// SPDX-License-Identifier: GPL-2.0+
/*
 * board.c
 *
 * Board functions for Bosch Guardian
 *
 * Copyright (C) 2011, Texas Instruments, Incorporated - http://www.ti.com/
 * Copyright (C) 2018 Robert Bosch Power Tools GmbH
 */

#include <common.h>
#include <cpsw.h>
#include <dm.h>
#include <env_internal.h>
#include <errno.h>
#include <i2c.h>
#include <led.h>
#include <miiphy.h>
#include <panel.h>
#include <power/tps65217.h>
#include <power/tps65910.h>
#include <spl.h>
#include <watchdog.h>
#include <asm/arch/clock.h>
#include <asm/arch/cpu.h>
#include <asm/arch/ddr_defs.h>
#include <asm/arch/gpio.h>
#include <asm/arch/hardware.h>
#include <asm/arch/mem.h>
#include <asm/arch/mmc_host_def.h>
#include <asm/arch/omap.h>
#include <asm/arch/sys_proto.h>
#include <asm/emif.h>
#include <asm/gpio.h>
#include <asm/io.h>
#include "board.h"

DECLARE_GLOBAL_DATA_PTR;

#ifndef CONFIG_SKIP_LOWLEVEL_INIT
static struct ctrl_dev *cdev = (struct ctrl_dev *)CTRL_DEVICE_BASE;

static const struct ddr_data ddr3_data = {
	.datardsratio0 = MT41K128M16JT125K_RD_DQS,
	.datawdsratio0 = MT41K128M16JT125K_WR_DQS,
	.datafwsratio0 = MT41K128M16JT125K_PHY_FIFO_WE,
	.datawrsratio0 = MT41K128M16JT125K_PHY_WR_DATA,
};

static const struct cmd_control ddr3_cmd_ctrl_data = {
	.cmd0csratio = MT41K128M16JT125K_RATIO,
	.cmd0iclkout = MT41K128M16JT125K_INVERT_CLKOUT,

	.cmd1csratio = MT41K128M16JT125K_RATIO,
	.cmd1iclkout = MT41K128M16JT125K_INVERT_CLKOUT,

	.cmd2csratio = MT41K128M16JT125K_RATIO,
	.cmd2iclkout = MT41K128M16JT125K_INVERT_CLKOUT,
};

static struct emif_regs ddr3_emif_reg_data = {
	.sdram_config = MT41K128M16JT125K_EMIF_SDCFG,
	.ref_ctrl = MT41K128M16JT125K_EMIF_SDREF,
	.sdram_tim1 = MT41K128M16JT125K_EMIF_TIM1,
	.sdram_tim2 = MT41K128M16JT125K_EMIF_TIM2,
	.sdram_tim3 = MT41K128M16JT125K_EMIF_TIM3,
	.zq_config = MT41K128M16JT125K_ZQ_CFG,
	.emif_ddr_phy_ctlr_1 = MT41K128M16JT125K_EMIF_READ_LATENCY,
};

#define OSC	(V_OSCK / 1000000)
const struct dpll_params dpll_ddr = {
		400, OSC - 1, 1, -1, -1, -1, -1};

void am33xx_spl_board_init(void)
{
	int mpu_vdd;
	int usb_cur_lim;

	/* Get the frequency */
	dpll_mpu_opp100.m = am335x_get_efuse_mpu_max_freq(cdev);

	if (i2c_probe(TPS65217_CHIP_PM))
		return;

	/*
	 * Increase USB current limit to 1300mA or 1800mA and set
	 * the MPU voltage controller as needed.
	 */
	if (dpll_mpu_opp100.m == MPUPLL_M_1000) {
		usb_cur_lim = TPS65217_USB_INPUT_CUR_LIMIT_1800MA;
		mpu_vdd = TPS65217_DCDC_VOLT_SEL_1325MV;
	} else {
		usb_cur_lim = TPS65217_USB_INPUT_CUR_LIMIT_1300MA;
		mpu_vdd = TPS65217_DCDC_VOLT_SEL_1275MV;
	}

	if (tps65217_reg_write(TPS65217_PROT_LEVEL_NONE,
			       TPS65217_POWER_PATH,
			       usb_cur_lim,
			       TPS65217_USB_INPUT_CUR_LIMIT_MASK))
		puts("tps65217_reg_write failure\n");

	/* Set DCDC3 (CORE) voltage to 1.125V */
	if (tps65217_voltage_update(TPS65217_DEFDCDC3,
				    TPS65217_DCDC_VOLT_SEL_1125MV)) {
		puts("tps65217_voltage_update failure\n");
		return;
	}

	/* Set CORE Frequencies to OPP100 */
	do_setup_dpll(&dpll_core_regs, &dpll_core_opp100);

	/* Set DCDC2 (MPU) voltage */
	if (tps65217_voltage_update(TPS65217_DEFDCDC2, mpu_vdd)) {
		puts("tps65217_voltage_update failure\n");
		return;
	}

	/*
	 * Set LDO3 to 1.8V and LDO4 to 3.3V
	 */
	if (tps65217_reg_write(TPS65217_PROT_LEVEL_2,
			       TPS65217_DEFLS1,
			       TPS65217_LDO_VOLTAGE_OUT_1_8,
			       TPS65217_LDO_MASK))
		puts("tps65217_reg_write failure\n");

	if (tps65217_reg_write(TPS65217_PROT_LEVEL_2,
			       TPS65217_DEFLS2,
			       TPS65217_LDO_VOLTAGE_OUT_3_3,
			       TPS65217_LDO_MASK))
		puts("tps65217_reg_write failure\n");

	/* Set MPU Frequency to what we detected now that voltages are set */
	do_setup_dpll(&dpll_mpu_regs, &dpll_mpu_opp100);
}

const struct dpll_params *get_dpll_ddr_params(void)
{
	enable_i2c0_pin_mux();
	i2c_init(CONFIG_SYS_OMAP24_I2C_SPEED, CONFIG_SYS_OMAP24_I2C_SLAVE);

	return &dpll_ddr;
}

void set_uart_mux_conf(void)
{
	enable_uart0_pin_mux();
}

void set_mux_conf_regs(void)
{
	enable_board_pin_mux();
}

const struct ctrl_ioregs ioregs = {
	.cm0ioctl		= MT41K128M16JT125K_IOCTRL_VALUE,
	.cm1ioctl		= MT41K128M16JT125K_IOCTRL_VALUE,
	.cm2ioctl		= MT41K128M16JT125K_IOCTRL_VALUE,
	.dt0ioctl		= MT41K128M16JT125K_IOCTRL_VALUE,
	.dt1ioctl		= MT41K128M16JT125K_IOCTRL_VALUE,
};

void sdram_init(void)
{
	config_ddr(400, &ioregs,
		   &ddr3_data,
		   &ddr3_cmd_ctrl_data,
		   &ddr3_emif_reg_data, 0);
}
#endif

int board_init(void)
{
	save_omap_boot_params();

#if defined(CONFIG_HW_WATCHDOG)
	hw_watchdog_init();
#endif

	gd->bd->bi_boot_params = CONFIG_SYS_SDRAM_BASE + 0x100;

#ifdef CONFIG_MTD_RAW_NAND
	gpmc_init();
#endif
	return 0;
}

#ifdef CONFIG_BOARD_LATE_INIT
static void set_bootmode_env(void)
{
	char *boot_device_name = NULL;
	char *boot_mode_gpio = "gpio@44e07000_14";
	int   ret;
	int   value;

	struct gpio_desc boot_mode_desc;

	switch (gd->arch.omap_boot_device) {
	case BOOT_DEVICE_NAND:
		boot_device_name = "nand";
		break;
	case BOOT_DEVICE_USBETH:
		boot_device_name = "usbeth";
		break;
	default:
		break;
	}

	if (boot_device_name)
		env_set("boot_device", boot_device_name);

	ret = dm_gpio_lookup_name(boot_mode_gpio, &boot_mode_desc);
	if (ret) {
		printf("%s is not found\n", boot_mode_gpio);
		goto err;
	}

	ret = dm_gpio_request(&boot_mode_desc, "setup_bootmode_env");
	if (ret && ret != -EBUSY) {
		printf("requesting gpio: %s failed\n", boot_mode_gpio);
		goto err;
	}

	value = dm_gpio_get_value(&boot_mode_desc);
	value ? env_set("swi_status", "0") : env_set("swi_status", "1");
	return;

err:
	env_set("swi_status", "err");
}

int board_late_init(void)
{
#ifdef CONFIG_LED_GPIO
	led_default_state();
#endif
	set_bootmode_env();
	return 0;
}
#endif /* CONFIG_BOARD_LATE_INIT */
