/*
 * GE B105v2, B125v2, B155v2
 *
 * Copyright 2018-2020 GE Inc.
 * Copyright 2018-2020 Collabora Ltd.
 *
 * SPDX-License-Identifier:    GPL-2.0+
 */

#include <asm/arch/clock.h>
#include <asm/arch/crm_regs.h>
#include <asm/arch/imx-regs.h>
#include <asm/arch/iomux.h>
#include <asm/arch/sys_proto.h>
#include <asm/global_data.h>
#include <asm/gpio.h>
#include <asm/io.h>
#include <asm/mach-imx/video.h>
#include <command.h>
#include <common.h>
#include <i2c.h>
#include <input.h>
#include <ipu_pixfmt.h>
#include <linux/delay.h>
#include <linux/fb.h>
#include <malloc.h>
#include <miiphy.h>
#include <micrel.h>
#include <netdev.h>
#include <panel.h>
#include <rtc.h>
#include <spi_flash.h>
#include <version.h>

#include "../common/vpd_reader.h"

DECLARE_GLOBAL_DATA_PTR;

#ifndef CONFIG_SPL_BUILD

#define B1X5V2_GE_VPD_OFFSET	0x0100000
#define B1X5V2_GE_VPD_SIZE	1022

#define VPD_TYPE_INVALID	0x00
#define VPD_BLOCK_NETWORK	0x20
#define VPD_BLOCK_HWID		0x44
#define VPD_MAC_ADDRESS_LENGTH	6

#define VPD_FLAG_VALID_MAC	BIT(1)

#define AR8035_PHY_ID			0x004dd072
#define AR8035_PHY_DEBUG_ADDR_REG	0x1d
#define AR8035_PHY_DEBUG_DATA_REG	0x1e
#define AR8035_HIB_CTRL_REG		0xb
#define AR8035_HIBERNATE_EN		(1 << 15)

static struct vpd_cache {
	bool is_read;
	u8 product_id;
	unsigned char mac[VPD_MAC_ADDRESS_LENGTH];
	u32 flags;
} vpd;

enum product_type {
	PRODUCT_TYPE_B105V2 = 6,
	PRODUCT_TYPE_B105PV2 = 7,
	PRODUCT_TYPE_B125V2 = 8,
	PRODUCT_TYPE_B125PV2 = 9,
	PRODUCT_TYPE_B155V2 = 10,

	PRODUCT_TYPE_INVALID = 0,
};

int dram_init(void) {
	gd->ram_size = imx_ddr_size();
	return 0;
}

int power_init_board(void)
{
	/* all required PMIC configuration happens via DT */
	return 0;
}

static int disable_phy_hibernation(struct phy_device *phydev)
{
	unsigned short val;

	if (phydev->drv->uid == AR8035_PHY_ID) {
		/* Disable hibernation, other configuration has been done by PHY driver */
		phy_write(phydev, MDIO_DEVAD_NONE, AR8035_PHY_DEBUG_ADDR_REG, AR8035_HIB_CTRL_REG);
		val = phy_read(phydev, MDIO_DEVAD_NONE, AR8035_PHY_DEBUG_DATA_REG);
		val &= ~AR8035_HIBERNATE_EN;
		phy_write(phydev, MDIO_DEVAD_NONE, AR8035_PHY_DEBUG_DATA_REG, val);
	} else {
		printf("Unknown PHY: %08x\n", phydev->drv->uid);
	}

	return 0;
}

int board_phy_config(struct phy_device *phydev)
{
	if (phydev->drv->config)
		phydev->drv->config(phydev);

	disable_phy_hibernation(phydev);

	return 0;
}

static int auo_g101evn01_detect(const struct display_info_t *info)
{
	char *dev = env_get("devicetype");
	return !strcmp(dev, "B105v2") || !strcmp(dev, "B105Pv2");
}

static int auo_g121ean01_detect(const struct display_info_t *info)
{
	char *dev = env_get("devicetype");
	return !strcmp(dev, "B125v2") || !strcmp(dev, "B125Pv2");;
}

static int auo_g156xtn01_detect(const struct display_info_t *info)
{
	char *dev = env_get("devicetype");
	return !strcmp(dev, "B155v2");
}

static void b1x5v2_backlight_enable(int percent)
{
	struct udevice *panel;
	int ret;

	ret = uclass_get_device(UCLASS_PANEL, 0, &panel);
	if (ret) {
		printf("Could not find panel: %d\n", ret);
		return;
	}

	panel_set_backlight(panel, percent);
	panel_enable_backlight(panel);

}

static void lcd_enable(const struct display_info_t *info)
{
	printf("Enable backlight...\n");
	b1x5v2_backlight_enable(100);
}

struct display_info_t const displays[] = {
{
	.di = 0,
	.bus = -1,
	.addr = -1,
	.pixfmt = IPU_PIX_FMT_RGB24,
	.detect = auo_g156xtn01_detect,
	.enable = lcd_enable,
	.mode = {
		.name = "AUO G156XTN01",
		.refresh = 60,
		.xres = 1368, /* because of i.MX6 limitation, actually 1366 */
		.yres = 768,
		.pixclock = 13158, /* 76 MHz in ps */
		.left_margin = 33,
		.right_margin = 67,
		.upper_margin = 4,
		.lower_margin = 4,
		.hsync_len = 94,
		.vsync_len = 30,
		.sync = FB_SYNC_EXT,
		.vmode = FB_VMODE_NONINTERLACED
	}
},
{
	.di = 0,
	.bus = -1,
	.addr = -1,
	.pixfmt = IPU_PIX_FMT_RGB24,
	.detect = auo_g121ean01_detect,
	.enable = lcd_enable,
	.mode = {
		.name = "AUO G121EAN01.4",
		.refresh = 60,
		.xres = 1280,
		.yres = 800,
		.pixclock = 14992, /* 66.7 MHz in ps */
		.left_margin = 8,
		.right_margin = 58,
		.upper_margin = 6,
		.lower_margin = 4,
		.hsync_len = 70,
		.vsync_len = 10,
		.sync = FB_SYNC_EXT,
		.vmode = FB_VMODE_NONINTERLACED
	}
},
{
	.di = 0,
	.bus = -1,
	.addr = -1,
	.pixfmt = IPU_PIX_FMT_RGB24,
	.detect = auo_g101evn01_detect,
	.enable = lcd_enable,
	.mode = {
		.name = "AUO G101EVN01.3",
		.refresh = 60,
		.xres = 1280,
		.yres = 800,
		.pixclock = 14992, /* 66.7 MHz in ps */
		.left_margin = 8,
		.right_margin = 58,
		.upper_margin = 6,
		.lower_margin = 4,
		.hsync_len = 70,
		.vsync_len = 10,
		.sync = FB_SYNC_EXT,
		.vmode = FB_VMODE_NONINTERLACED
	}
}
};
size_t display_count = ARRAY_SIZE(displays);

static void enable_videopll(void)
{
	struct mxc_ccm_reg *ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR;
	s32 timeout = 100000;

	setbits_le32(&ccm->analog_pll_video, BM_ANADIG_PLL_VIDEO_POWERDOWN);

	/* PLL_VIDEO  455MHz (24MHz * (37+11/12) / 2)
	 *   |
	 * PLL5
	 *   |
	 * CS2CDR[LDB_DI0_CLK_SEL]
	 *   |
	 *   +----> LDB_DI0_SERIAL_CLK_ROOT
	 *   |
	 *   +--> CSCMR2[LDB_DI0_IPU_DIV] --> LDB_DI0_IPU  455 / 7 = 65 MHz
	 */

	clrsetbits_le32(&ccm->analog_pll_video,
			BM_ANADIG_PLL_VIDEO_DIV_SELECT |
			BM_ANADIG_PLL_VIDEO_POST_DIV_SELECT,
			BF_ANADIG_PLL_VIDEO_DIV_SELECT(37) |
			BF_ANADIG_PLL_VIDEO_POST_DIV_SELECT(1));

	writel(BF_ANADIG_PLL_VIDEO_NUM_A(11), &ccm->analog_pll_video_num);
	writel(BF_ANADIG_PLL_VIDEO_DENOM_B(12), &ccm->analog_pll_video_denom);

	clrbits_le32(&ccm->analog_pll_video, BM_ANADIG_PLL_VIDEO_POWERDOWN);

	while (timeout--)
		if (readl(&ccm->analog_pll_video) & BM_ANADIG_PLL_VIDEO_LOCK)
			break;

	if (timeout < 0)
		printf("Warning: video pll lock timeout!\n");

	clrsetbits_le32(&ccm->analog_pll_video,
			BM_ANADIG_PLL_VIDEO_BYPASS,
			BM_ANADIG_PLL_VIDEO_ENABLE);
}

static void setup_display(void)
{
	struct mxc_ccm_reg *mxc_ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR;
	struct iomuxc *iomux = (struct iomuxc *)IOMUXC_BASE_ADDR;

	enable_videopll();

	/* When a reset/reboot is performed the display power needs to be turned
	 * off for atleast 500ms. The boot time is ~300ms, we need to wait for
	 * an additional 200ms here. Unfortunately we use external PMIC for
	 * doing the reset, so can not differentiate between POR vs soft reset
	 */
	mdelay(200);

	/* CCM_CSCMR2 -> ldb_di0_ipu_div [IMX6SDLRM page 839] */
	/* divide IPU clock by 7 */
	setbits_le32(&mxc_ccm->cscmr2, MXC_CCM_CSCMR2_LDB_DI0_IPU_DIV);

	/* CCM_CHSCCDR -> ipu1_di0_clk_sel [IMX6SDLRM page 849] */
	/* Set LDB_DI0 as clock source for IPU_DI0 */
	clrsetbits_le32(&mxc_ccm->chsccdr,
			MXC_CCM_CHSCCDR_IPU1_DI0_CLK_SEL_MASK,
			(CHSCCDR_CLK_SEL_LDB_DI0 <<
			MXC_CCM_CHSCCDR_IPU1_DI0_CLK_SEL_OFFSET));

	/* Turn on IPU LDB DI0 clocks */
	setbits_le32(&mxc_ccm->CCGR3, MXC_CCM_CCGR3_LDB_DI0_MASK);

	enable_ipu_clock();

	/* IOMUXC_GPR2 [IMX6SDLRM page 2049] */
	/* Set LDB Channel 0 in SPWG 24 Bit mode */
	writel(IOMUXC_GPR2_DI0_VS_POLARITY_ACTIVE_HIGH |
	       IOMUXC_GPR2_BIT_MAPPING_CH0_SPWG |
	       IOMUXC_GPR2_DATA_WIDTH_CH0_24BIT |
	       IOMUXC_GPR2_LVDS_CH0_MODE_ENABLED_DI0,
	       &iomux->gpr[2]);

	/* IOMUXC_GPR3 [IMX6SDLRM page 2051] */
	/* LVDS0 is connected to IPU DI0 */
	clrsetbits_le32(&iomux->gpr[3],
			IOMUXC_GPR3_LVDS0_MUX_CTL_MASK,
		       (IOMUXC_GPR3_MUX_SRC_IPU1_DI0 <<
			IOMUXC_GPR3_LVDS0_MUX_CTL_OFFSET));
}

/*
 * Do not overwrite the console
 * Use always serial for U-Boot console
 */
int overwrite_console(void)
{
	return 1;
}

int board_early_init_f(void)
{
	select_ldb_di_clock_source(MXC_PLL5_CLK);

	return 0;
}

static int eeti_touch_get_model(struct udevice *dev, char *result) {
	u8 query[68] = {0x67, 0x00, 0x42, 0x00, 0x03, 0x01, 'E', 0x00, 0x00, 0x00};
	struct i2c_msg qmsg = {
		.addr = 0x2a,
		.flags = 0,
		.len = sizeof(query),
		.buf = query,
	};
	u8 reply[66] = {0};
	struct i2c_msg rmsg = {
		.addr = 0x2a,
		.flags = I2C_M_RD,
		.len = sizeof(reply),
		.buf = reply,
	};
	int err;

	err = dm_i2c_xfer(dev, &qmsg, 1);
	if (err)
		return err;

	/*
	 * device sends IRQ when its ok to read. To keep the code
	 * simple we just wait an arbitrary, long enough time period.
	 */
	mdelay(10);

	err = dm_i2c_xfer(dev, &rmsg, 1);
	if (err)
		return err;

	if (reply[0] != 0x42 || reply[1] != 0x00 ||
	    reply[2] != 0x03 || reply[4] != 'E')
		return -EPROTO;

	memcpy(result, reply+5, 10);
	return 0;
}

static bool b1x5v2_board_is_p_model(void)
{
	struct udevice *bus = NULL;
	struct udevice *dev = NULL;
	int err;

	err = uclass_get_device_by_name(UCLASS_I2C, "i2c@21a0000", &bus);
	if (err || !bus) {
		printf("Could not get I2C bus: %d\n", err);
		return true;
	}

	/* The P models do not have this port expander */
	err = dm_i2c_probe(bus, 0x21, 0, &dev);
	if (err || !dev) {
		return true;
	}

	return false;
}

static enum product_type b1x5v2_board_type(void)
{
	struct udevice *bus = NULL;
	struct udevice *dev = NULL;
	char model[11] = {0};
	int err;
	int retry;

	err = uclass_get_device_by_name(UCLASS_I2C, "i2c@21a8000", &bus);
	if (err) {
		printf("Could not get I2C bus: %d\n", err);
		return PRODUCT_TYPE_INVALID;
	}

	err = dm_i2c_probe(bus, 0x41, 0, &dev);
	if (!err && dev) { /* Ilitek Touchscreen */
		if (b1x5v2_board_is_p_model()) {
			return PRODUCT_TYPE_B105PV2;
		} else {
			return PRODUCT_TYPE_B105V2;
		}
	}

	err = dm_i2c_probe(bus, 0x2a, 0, &dev);
	if (err || !dev) {
		printf("Could not find touchscreen: %d\n", err);
		return PRODUCT_TYPE_INVALID;
	}

	for (retry = 0; retry < 3; ++retry) {
		err = eeti_touch_get_model(dev, model);
		if (!err)
			break;
		printf("Retry %d read EETI touchscreen model: %d\n", retry + 1, err);
	}
	if (err) {
		printf("Could not read EETI touchscreen model: %d\n", err);
		return PRODUCT_TYPE_INVALID;
	}

	if (!strcmp(model, "Orion_1320")) { /* EETI EXC80H60 */
		if (b1x5v2_board_is_p_model()) {
			return PRODUCT_TYPE_B125PV2;
		} else {
			return PRODUCT_TYPE_B125V2;
		}
	} else if (!strcmp(model, "Orion_1343")) { /* EETI EXC80H84 */
		return PRODUCT_TYPE_B155V2;
	}

	printf("Unknown EETI touchscreen model: %s\n", model);
	return PRODUCT_TYPE_INVALID;
}

static void set_env_per_board_type(enum product_type type)
{
	switch (type) {
	case PRODUCT_TYPE_B105V2:
		env_set("resolution", "1280x800");
		env_set("devicetype", "B105v2");
		env_set("fdtfile", "imx6dl-b105v2.dtb");
		break;
	case PRODUCT_TYPE_B105PV2:
		env_set("resolution", "1280x800");
		env_set("devicetype", "B105Pv2");
		env_set("fdtfile", "imx6dl-b105pv2.dtb");
		break;
	case PRODUCT_TYPE_B125V2:
		env_set("resolution", "1280x800");
		env_set("devicetype", "B125v2");
		env_set("fdtfile", "imx6dl-b125v2.dtb");
		break;
	case PRODUCT_TYPE_B125PV2:
		env_set("resolution", "1280x800");
		env_set("devicetype", "B125Pv2");
		env_set("fdtfile", "imx6dl-b125pv2.dtb");
		break;
	case PRODUCT_TYPE_B155V2:
		env_set("resolution", "1366x768");
		env_set("devicetype", "B155v2");
		env_set("fdtfile", "imx6dl-b155v2.dtb");
		break;
	default:
		break;
	}
}

static int b1x5v2_board_type_autodetect(void)
{
	enum product_type product = b1x5v2_board_type();
	if (product != PRODUCT_TYPE_INVALID) {
		set_env_per_board_type(product);
		return 0;
	}
	return -1;
}

/*
 * Extracts MAC and product information from the VPD.
 */
static int vpd_callback(struct vpd_cache *vpd, u8 id, u8 version, u8 type,
			size_t size, u8 const *data)
{
	if (type == VPD_TYPE_INVALID)
		return 0;

	if (id == VPD_BLOCK_HWID && version == 1 && size >= 1) {
		vpd->product_id = data[0];
	} else if (id == VPD_BLOCK_NETWORK && version == 1) {
		if (size >= VPD_MAC_ADDRESS_LENGTH) {
			memcpy(vpd->mac, data, VPD_MAC_ADDRESS_LENGTH);
			vpd->flags |= VPD_FLAG_VALID_MAC;
		}
	}

	return 0;
}

static int read_spi_vpd(struct vpd_cache *cache,
		 int (*process_block)(struct vpd_cache *, u8 id, u8 version,
				      u8 type, size_t size, u8 const *data))
{
	static const int size = B1X5V2_GE_VPD_SIZE;
	struct udevice *dev;
	int ret;
	u8 *data;

	ret = uclass_get_device_by_name(UCLASS_SPI_FLASH, "m25p80@0", &dev);
	if (ret)
		return ret;

	data = malloc(size);
	if (!data)
		return -ENOMEM;

	ret = spi_flash_read_dm(dev, B1X5V2_GE_VPD_OFFSET, size, data);
	if (ret) {
		free(data);
		return ret;
	}

	ret = vpd_reader(size, data, cache, process_block);

	free(data);

	return ret;
}

int board_init(void)
{
	if (!read_spi_vpd(&vpd, vpd_callback)) {
		vpd.is_read = true;
	}

	/* address of boot parameters */
	gd->bd->bi_boot_params = PHYS_SDRAM + 0x100;
	setup_display();

	return 0;
}

static void init_bootcause(void)
{
	const char *cause;

	/* We care about WDOG only, treating everything else as
	 * a power-on-reset.
	 */
	if (get_imx_reset_cause() & 0x0010)
		cause = "WDOG";
	else
		cause = "POR";

	env_set("bootcause", cause);
}

int misc_init_r(void)
{
	init_bootcause();

	return 0;
}

#define M41T62_REG_FLAGS	0xf
#define M41T62_FLAGS_OF		(1 << 2)
static void check_time(void)
{
	struct udevice *rtc = NULL;
	struct rtc_time tm;
	u8 val;
	int ret;

	ret = uclass_get_device_by_name(UCLASS_RTC, "m41t62@68", &rtc);
	if (ret) {
		printf("Could not get RTC: %d\n", ret);
		env_set("rtc_status", "FAIL");
		return;
	}

	ret = dm_i2c_read(rtc, M41T62_REG_FLAGS, &val, sizeof(val));
	if (ret) {
		printf("Could not read RTC register: %d\n", ret);
		env_set("rtc_status", "FAIL");
		return;
	}

	ret = dm_rtc_reset(rtc);
	if (ret) {
		printf("Could not reset RTC: %d\n", ret);
		env_set("rtc_status", "FAIL");
		return;
	}

	if (val & M41T62_FLAGS_OF) {
		env_set("rtc_status", "STOP");
		return;
	}

	ret = dm_rtc_get(rtc, &tm);
	if (ret) {
		printf("Could not read RTC: %d\n", ret);
		env_set("rtc_status", "FAIL");
		return;
	}

	if (tm.tm_year > 2037) {
		tm.tm_sec  = 0;
		tm.tm_min  = 0;
		tm.tm_hour = 0;
		tm.tm_mday = 1;
		tm.tm_wday = 2;
		tm.tm_mon  = 1;
		tm.tm_year = 2036;

		ret = dm_rtc_set(rtc, &tm);
		if (ret) {
			printf("Could not update RTC: %d\n", ret);
			env_set("rtc_status", "FAIL");
			return;
		}

		printf("RTC behind 2037, capped to 2036 for userspace handling\n");
		env_set("rtc_status", "2038");
		return;
	}

	env_set("rtc_status", "OK");
}

static void process_vpd(struct vpd_cache *vpd)
{
	if (!vpd->is_read) {
		printf("VPD wasn't read\n");
		return;
	}

	if (vpd->flags & VPD_FLAG_VALID_MAC) {
		eth_env_set_enetaddr_by_index("eth", 0, vpd->mac);
		env_set("ethact", "eth0");
	}
}

int board_late_init(void)
{
	process_vpd(&vpd);

	if (vpd.product_id >= PRODUCT_TYPE_B105V2 &&
	    vpd.product_id <= PRODUCT_TYPE_B155V2) {
		set_env_per_board_type((enum product_type)vpd.product_id);
	} else {
		b1x5v2_board_type_autodetect();
	}

	printf("Board: GE %s\n", env_get("devicetype"));

	check_time();

	return 0;
}

#ifdef CONFIG_OF_BOARD_SETUP
int ft_board_setup(void *blob, struct bd_info *bd)
{
	char *rtc_status = env_get("rtc_status");

	fdt_setprop(blob, 0, "ge,boot-ver", version_string,
	                                    strlen(version_string) + 1);
	fdt_setprop(blob, 0, "ge,rtc-status", rtc_status,
	                                    strlen(rtc_status) + 1);

	return 0;
}
#endif

static int do_b1x5v2_autodetect(struct cmd_tbl *cmdtp, int flag, int argc, char * const argv[])
{
	int err;

	err = b1x5v2_board_type_autodetect();
	if (!err)
		printf("Identified %s\n", env_get("devicetype"));

	return 0;
}

U_BOOT_CMD(
       autodetect_devtype, 1,      1,      do_b1x5v2_autodetect,
       "autodetect b1x5v2 device type",
       ""
);

#endif // CONFIG_SPL_BUILD
