// SPDX-License-Identifier: GPL-2.0+
/*
 * Menlosystems M53Menlo board
 *
 * Copyright (C) 2012-2017 Marek Vasut <marex@denx.de>
 * Copyright (C) 2014-2017 Olaf Mandel <o.mandel@menlosystems.com>
 */

#include <common.h>
#include <dm.h>
#include <init.h>
#include <malloc.h>
#include <asm/global_data.h>
#include <asm/io.h>
#include <asm/arch/imx-regs.h>
#include <asm/arch/sys_proto.h>
#include <asm/arch/crm_regs.h>
#include <asm/arch/clock.h>
#include <asm/arch/iomux-mx53.h>
#include <asm/mach-imx/mx5_video.h>
#include <asm/mach-imx/video.h>
#include <asm/gpio.h>
#include <asm/spl.h>
#include <env.h>
#include <fdt_support.h>
#include <fsl_esdhc_imx.h>
#include <gzip.h>
#include <i2c.h>
#include <ipu_pixfmt.h>
#include <linux/bitops.h>
#include <linux/errno.h>
#include <linux/fb.h>
#include <mmc.h>
#include <netdev.h>
#include <spl.h>
#include <splash.h>
#include <usb/ehci-ci.h>
#include <video_console.h>

DECLARE_GLOBAL_DATA_PTR;

static u32 mx53_dram_size[2];

ulong board_get_usable_ram_top(ulong total_size)
{
	/*
	 * WARNING: We must override get_effective_memsize() function here
	 * to report only the size of the first DRAM bank. This is to make
	 * U-Boot relocator place U-Boot into valid memory, that is, at the
	 * end of the first DRAM bank. If we did not override this function
	 * like so, U-Boot would be placed at the address of the first DRAM
	 * bank + total DRAM size - sizeof(uboot), which in the setup where
	 * each DRAM bank contains 512MiB of DRAM would result in placing
	 * U-Boot into invalid memory area close to the end of the first
	 * DRAM bank.
	 */
	return PHYS_SDRAM_2 + mx53_dram_size[1];
}

int dram_init(void)
{
	mx53_dram_size[0] = get_ram_size((void *)PHYS_SDRAM_1, 1 << 30);
	mx53_dram_size[1] = get_ram_size((void *)PHYS_SDRAM_2, 1 << 30);

	gd->ram_size = mx53_dram_size[0] + mx53_dram_size[1];

	return 0;
}

int dram_init_banksize(void)
{
	gd->bd->bi_dram[0].start = PHYS_SDRAM_1;
	gd->bd->bi_dram[0].size = mx53_dram_size[0];

	gd->bd->bi_dram[1].start = PHYS_SDRAM_2;
	gd->bd->bi_dram[1].size = mx53_dram_size[1];

	return 0;
}

static void setup_iomux_uart(void)
{
	static const iomux_v3_cfg_t uart_pads[] = {
		MX53_PAD_PATA_DMACK__UART1_RXD_MUX,
		MX53_PAD_PATA_DIOW__UART1_TXD_MUX,
	};

	imx_iomux_v3_setup_multiple_pads(uart_pads, ARRAY_SIZE(uart_pads));
}

static void setup_iomux_fec(void)
{
	static const iomux_v3_cfg_t fec_pads[] = {
		/* MDIO pads */
		NEW_PAD_CTRL(MX53_PAD_FEC_MDIO__FEC_MDIO, PAD_CTL_HYS |
			PAD_CTL_DSE_HIGH | PAD_CTL_PUS_22K_UP | PAD_CTL_ODE),
		NEW_PAD_CTRL(MX53_PAD_FEC_MDC__FEC_MDC, PAD_CTL_DSE_HIGH),

		/* FEC 0 pads */
		NEW_PAD_CTRL(MX53_PAD_FEC_CRS_DV__FEC_RX_DV,
			     PAD_CTL_HYS | PAD_CTL_PKE),
		NEW_PAD_CTRL(MX53_PAD_FEC_REF_CLK__FEC_TX_CLK,
			     PAD_CTL_HYS | PAD_CTL_PKE),
		NEW_PAD_CTRL(MX53_PAD_FEC_RX_ER__FEC_RX_ER,
			     PAD_CTL_HYS | PAD_CTL_PKE),
		NEW_PAD_CTRL(MX53_PAD_FEC_TX_EN__FEC_TX_EN, PAD_CTL_DSE_HIGH),
		NEW_PAD_CTRL(MX53_PAD_FEC_RXD0__FEC_RDATA_0,
			     PAD_CTL_HYS | PAD_CTL_PKE),
		NEW_PAD_CTRL(MX53_PAD_FEC_RXD1__FEC_RDATA_1,
			     PAD_CTL_HYS | PAD_CTL_PKE),
		NEW_PAD_CTRL(MX53_PAD_FEC_TXD0__FEC_TDATA_0, PAD_CTL_DSE_HIGH),
		NEW_PAD_CTRL(MX53_PAD_FEC_TXD1__FEC_TDATA_1, PAD_CTL_DSE_HIGH),

		/* FEC 1 pads */
		NEW_PAD_CTRL(MX53_PAD_KEY_COL0__FEC_RDATA_3,
			     PAD_CTL_HYS | PAD_CTL_PKE),
		NEW_PAD_CTRL(MX53_PAD_KEY_ROW0__FEC_TX_ER,
			     PAD_CTL_HYS | PAD_CTL_PKE),
		NEW_PAD_CTRL(MX53_PAD_KEY_COL1__FEC_RX_CLK,
			     PAD_CTL_HYS | PAD_CTL_PKE),
		NEW_PAD_CTRL(MX53_PAD_KEY_ROW1__FEC_COL,
			     PAD_CTL_HYS | PAD_CTL_PKE),
		NEW_PAD_CTRL(MX53_PAD_KEY_COL2__FEC_RDATA_2,
			     PAD_CTL_HYS | PAD_CTL_PKE),
		NEW_PAD_CTRL(MX53_PAD_KEY_ROW2__FEC_TDATA_2, PAD_CTL_DSE_HIGH),
		NEW_PAD_CTRL(MX53_PAD_KEY_COL3__FEC_CRS,
			     PAD_CTL_HYS | PAD_CTL_PKE),
		NEW_PAD_CTRL(MX53_PAD_GPIO_19__FEC_TDATA_3, PAD_CTL_DSE_HIGH),
	};

	imx_iomux_v3_setup_multiple_pads(fec_pads, ARRAY_SIZE(fec_pads));
}

#ifdef CONFIG_FSL_ESDHC_IMX
struct fsl_esdhc_cfg esdhc_cfg = {
	MMC_SDHC1_BASE_ADDR,
};

int board_mmc_getcd(struct mmc *mmc)
{
	imx_iomux_v3_setup_pad(MX53_PAD_GPIO_1__GPIO1_1);
	gpio_direction_input(IMX_GPIO_NR(1, 1));

	return !gpio_get_value(IMX_GPIO_NR(1, 1));
}

#define SD_CMD_PAD_CTRL		(PAD_CTL_HYS | PAD_CTL_DSE_HIGH | \
				 PAD_CTL_PUS_100K_UP)
#define SD_PAD_CTRL		(PAD_CTL_HYS | PAD_CTL_PUS_47K_UP | \
				 PAD_CTL_DSE_HIGH)

int board_mmc_init(struct bd_info *bis)
{
	static const iomux_v3_cfg_t sd1_pads[] = {
		NEW_PAD_CTRL(MX53_PAD_SD1_CMD__ESDHC1_CMD, SD_CMD_PAD_CTRL),
		NEW_PAD_CTRL(MX53_PAD_SD1_CLK__ESDHC1_CLK, SD_PAD_CTRL),
		NEW_PAD_CTRL(MX53_PAD_SD1_DATA0__ESDHC1_DAT0, SD_PAD_CTRL),
		NEW_PAD_CTRL(MX53_PAD_SD1_DATA1__ESDHC1_DAT1, SD_PAD_CTRL),
		NEW_PAD_CTRL(MX53_PAD_SD1_DATA2__ESDHC1_DAT2, SD_PAD_CTRL),
		NEW_PAD_CTRL(MX53_PAD_SD1_DATA3__ESDHC1_DAT3, SD_PAD_CTRL),
	};

	esdhc_cfg.sdhc_clk = mxc_get_clock(MXC_ESDHC_CLK);

	imx_iomux_v3_setup_multiple_pads(sd1_pads, ARRAY_SIZE(sd1_pads));

	return fsl_esdhc_initialize(bis, &esdhc_cfg);
}
#endif

static void enable_lvds_clock(struct display_info_t const *dev, const u8 hclk)
{
	static struct mxc_ccm_reg *mxc_ccm = (struct mxc_ccm_reg *)MXC_CCM_BASE;
	int ret;

	/* For ETM0430G0DH6 model, this must be enabled before the clock. */
	gpio_direction_output(IMX_GPIO_NR(6, 0), 1);

	/*
	 * Set LVDS clock to 33.28 MHz for the display. The PLL4 is set to
	 * 233 MHz, divided by 7 by setting CCM_CSCMR2 LDB_DI0_IPU_DIV=1 .
	 */
	ret = mxc_set_clock(MXC_HCLK, hclk, MXC_LDB_CLK);
	if (ret)
		puts("IPU:   Failed to configure LDB clock\n");

	/* Configure CCM_CSCMR2 */
	clrsetbits_le32(&mxc_ccm->cscmr2,
			(0x7 << 26) | BIT(10) | BIT(8),
			(0x5 << 26) | BIT(10) | BIT(8));

	/* Configure LDB_CTRL */
	writel(0x201, 0x53fa8008);
}

static void enable_lvds_etm0430g0dh6(struct display_info_t const *dev)
{
	gpio_request(IMX_GPIO_NR(6, 0), "LCD");

	/* For ETM0430G0DH6 model, this must be enabled before the clock. */
	gpio_direction_output(IMX_GPIO_NR(6, 0), 1);

	/*
	 * Set LVDS clock to 9 MHz for the display. The PLL4 is set to
	 * 63 MHz, divided by 7 by setting CCM_CSCMR2 LDB_DI0_IPU_DIV=1 .
	 */
	enable_lvds_clock(dev, 63);
}

static void enable_lvds_etm0700g0dh6(struct display_info_t const *dev)
{
	gpio_request(IMX_GPIO_NR(6, 0), "LCD");

	/*
	 * Set LVDS clock to 33.28 MHz for the display. The PLL4 is set to
	 * 233 MHz, divided by 7 by setting CCM_CSCMR2 LDB_DI0_IPU_DIV=1 .
	 */
	enable_lvds_clock(dev, 233);

	/* For ETM0700G0DH6 model, this may be enabled after the clock. */
	gpio_direction_output(IMX_GPIO_NR(6, 0), 1);
}

static const char *lvds_compat_string;

static int detect_lvds(struct display_info_t const *dev)
{
	u8 touchid[23];
	u8 *touchptr = &touchid[0];
	int ret;

	ret = i2c_set_bus_num(0);
	if (ret)
		return 0;

	/* Touchscreen is at address 0x38, ID register is 0xbb. */
	ret = i2c_read(0x38, 0xbb, 1, touchid, sizeof(touchid));
	if (ret)
		return 0;

	/* EP0430 prefixes the response with 0xbb, skip it. */
	if (*touchptr == 0xbb)
		touchptr++;

	/* Skip the 'EP' prefix. */
	touchptr += 2;

	ret = !memcmp(touchptr, &dev->mode.name[7], 4);
	if (ret)
		lvds_compat_string = dev->mode.name;

	return ret;
}

void board_preboot_os(void)
{
	/* Power off the LCD to prevent awful color flicker */
	gpio_direction_output(IMX_GPIO_NR(6, 0), 0);
}

int ft_board_setup(void *blob, struct bd_info *bd)
{
	if (lvds_compat_string)
		do_fixup_by_path_string(blob, "/panel", "compatible",
					lvds_compat_string);

	return 0;
}

struct display_info_t const displays[] = {
	{
		.bus	= 0,
		.addr	= 0,
		.detect	= detect_lvds,
		.enable	= enable_lvds_etm0430g0dh6,
		.pixfmt	= IPU_PIX_FMT_RGB666,
		.mode	= {
			.name		= "edt,etm0430g0dh6",
			.refresh	= 60,
			.xres		= 480,
			.yres		= 272,
			.pixclock	= 111111, /* picosecond (9 MHz) */
			.left_margin	= 2,
			.right_margin	= 2,
			.upper_margin	= 2,
			.lower_margin	= 2,
			.hsync_len	= 41,
			.vsync_len	= 10,
			.sync		= 0x40000000,
			.vmode          = FB_VMODE_NONINTERLACED
		}
	}, {
		.bus	= 0,
		.addr	= 0,
		.detect	= detect_lvds,
		.enable	= enable_lvds_etm0700g0dh6,
		.pixfmt	= IPU_PIX_FMT_RGB666,
		.mode	= {
			.name		= "edt,etm0700g0dh6",
			.refresh	= 60,
			.xres		= 800,
			.yres		= 480,
			.pixclock	= 30048, /* picosecond (33.28 MHz) */
			.left_margin	= 40,
			.right_margin	= 88,
			.upper_margin	= 10,
			.lower_margin	= 33,
			.hsync_len	= 128,
			.vsync_len	= 2,
			.sync		= FB_SYNC_EXT,
			.vmode          = FB_VMODE_NONINTERLACED
		}
	}
};

size_t display_count = ARRAY_SIZE(displays);

#ifdef CONFIG_SPLASH_SCREEN
static struct splash_location default_splash_locations[] = {
	{
		.name		= "mmc_fs",
		.storage	= SPLASH_STORAGE_MMC,
		.flags		= SPLASH_STORAGE_FS,
		.devpart	= "0:1",
	},
};

int splash_screen_prepare(void)
{
	return splash_source_load(default_splash_locations,
				  ARRAY_SIZE(default_splash_locations));
}
#endif

int board_late_init(void)
{
#if defined(CONFIG_VIDEO_IPUV3)
	struct udevice *dev;
	int xpos, ypos, ret;
	char *s;
	void *dst;
	ulong addr, len;

	splash_get_pos(&xpos, &ypos);

	s = env_get("splashimage");
	if (!s)
		return 0;

	addr = hextoul(s, NULL);
	dst = malloc(CONFIG_SYS_VIDEO_LOGO_MAX_SIZE);
	if (!dst)
		return -ENOMEM;

	ret = splash_screen_prepare();
	if (ret < 0)
		goto splasherr;

	len = CONFIG_SYS_VIDEO_LOGO_MAX_SIZE;
	ret = gunzip(dst + 2, CONFIG_SYS_VIDEO_LOGO_MAX_SIZE - 2,
		     (uchar *)addr, &len);
	if (ret) {
		printf("Error: no valid bmp or bmp.gz image at %lx\n", addr);
		goto splasherr;
	}

	ret = uclass_get_device(UCLASS_VIDEO, 0, &dev);
	if (ret)
		goto splasherr;

	ret = video_bmp_display(dev, (ulong)dst + 2, xpos, ypos, true);
	if (ret)
		goto splasherr;

	return 0;

splasherr:
	free(dst);
#endif
	return 0;
}

#define I2C_PAD_CTRL	(PAD_CTL_SRE_FAST | PAD_CTL_DSE_HIGH | \
			 PAD_CTL_PUS_100K_UP | PAD_CTL_ODE)

static void setup_iomux_i2c(void)
{
	static const iomux_v3_cfg_t i2c_pads[] = {
		/* I2C1 */
		NEW_PAD_CTRL(MX53_PAD_EIM_D28__I2C1_SDA, I2C_PAD_CTRL),
		NEW_PAD_CTRL(MX53_PAD_EIM_D21__I2C1_SCL, I2C_PAD_CTRL),
		/* I2C2 */
		NEW_PAD_CTRL(MX53_PAD_EIM_D16__I2C2_SDA, I2C_PAD_CTRL),
		NEW_PAD_CTRL(MX53_PAD_EIM_EB2__I2C2_SCL, I2C_PAD_CTRL),
	};

	imx_iomux_v3_setup_multiple_pads(i2c_pads, ARRAY_SIZE(i2c_pads));
}

static void setup_iomux_video(void)
{
	static const iomux_v3_cfg_t lcd_pads[] = {
		MX53_PAD_LVDS0_TX3_P__LDB_LVDS0_TX3,
		MX53_PAD_LVDS0_CLK_P__LDB_LVDS0_CLK,
		MX53_PAD_LVDS0_TX2_P__LDB_LVDS0_TX2,
		MX53_PAD_LVDS0_TX1_P__LDB_LVDS0_TX1,
		MX53_PAD_LVDS0_TX0_P__LDB_LVDS0_TX0,
	};

	imx_iomux_v3_setup_multiple_pads(lcd_pads, ARRAY_SIZE(lcd_pads));
}

static void setup_iomux_nand(void)
{
	static const iomux_v3_cfg_t nand_pads[] = {
		NEW_PAD_CTRL(MX53_PAD_NANDF_WE_B__EMI_NANDF_WE_B,
			     PAD_CTL_DSE_HIGH),
		NEW_PAD_CTRL(MX53_PAD_NANDF_RE_B__EMI_NANDF_RE_B,
			     PAD_CTL_DSE_HIGH),
		NEW_PAD_CTRL(MX53_PAD_NANDF_CLE__EMI_NANDF_CLE,
			     PAD_CTL_DSE_HIGH),
		NEW_PAD_CTRL(MX53_PAD_NANDF_ALE__EMI_NANDF_ALE,
			     PAD_CTL_DSE_HIGH),
		NEW_PAD_CTRL(MX53_PAD_NANDF_WP_B__EMI_NANDF_WP_B,
			     PAD_CTL_PUS_100K_UP),
		NEW_PAD_CTRL(MX53_PAD_NANDF_RB0__EMI_NANDF_RB_0,
			     PAD_CTL_PUS_100K_UP),
		NEW_PAD_CTRL(MX53_PAD_NANDF_CS0__EMI_NANDF_CS_0,
			     PAD_CTL_DSE_HIGH),
		NEW_PAD_CTRL(MX53_PAD_PATA_DATA0__EMI_NANDF_D_0,
			     PAD_CTL_DSE_HIGH | PAD_CTL_PKE),
		NEW_PAD_CTRL(MX53_PAD_PATA_DATA1__EMI_NANDF_D_1,
			     PAD_CTL_DSE_HIGH | PAD_CTL_PKE),
		NEW_PAD_CTRL(MX53_PAD_PATA_DATA2__EMI_NANDF_D_2,
			     PAD_CTL_DSE_HIGH | PAD_CTL_PKE),
		NEW_PAD_CTRL(MX53_PAD_PATA_DATA3__EMI_NANDF_D_3,
			     PAD_CTL_DSE_HIGH | PAD_CTL_PKE),
		NEW_PAD_CTRL(MX53_PAD_PATA_DATA4__EMI_NANDF_D_4,
			     PAD_CTL_DSE_HIGH | PAD_CTL_PKE),
		NEW_PAD_CTRL(MX53_PAD_PATA_DATA5__EMI_NANDF_D_5,
			     PAD_CTL_DSE_HIGH | PAD_CTL_PKE),
		NEW_PAD_CTRL(MX53_PAD_PATA_DATA6__EMI_NANDF_D_6,
			     PAD_CTL_DSE_HIGH | PAD_CTL_PKE),
		NEW_PAD_CTRL(MX53_PAD_PATA_DATA7__EMI_NANDF_D_7,
			     PAD_CTL_DSE_HIGH | PAD_CTL_PKE),
	};

	imx_iomux_v3_setup_multiple_pads(nand_pads, ARRAY_SIZE(nand_pads));
}

static void m53_set_clock(void)
{
	int ret;
	const u32 ref_clk = MXC_HCLK;
	const u32 dramclk = 400;
	u32 cpuclk;

	gpio_request(IMX_GPIO_NR(4, 0), "CPUCLK");

	imx_iomux_v3_setup_pad(NEW_PAD_CTRL(MX53_PAD_GPIO_10__GPIO4_0,
					    PAD_CTL_DSE_HIGH | PAD_CTL_PKE));
	gpio_direction_input(IMX_GPIO_NR(4, 0));

	/* GPIO10 selects modules' CPU speed, 1 = 1200MHz ; 0 = 800MHz */
	cpuclk = gpio_get_value(IMX_GPIO_NR(4, 0)) ? 1200 : 800;

	ret = mxc_set_clock(ref_clk, cpuclk, MXC_ARM_CLK);
	if (ret)
		printf("CPU:   Switch CPU clock to %dMHz failed\n", cpuclk);

	ret = mxc_set_clock(ref_clk, dramclk, MXC_PERIPH_CLK);
	if (ret) {
		printf("CPU:   Switch peripheral clock to %dMHz failed\n",
		       dramclk);
	}

	ret = mxc_set_clock(ref_clk, dramclk, MXC_DDR_CLK);
	if (ret)
		printf("CPU:   Switch DDR clock to %dMHz failed\n", dramclk);
}

static void m53_set_nand(void)
{
	u32 i;

	/* NAND flash is muxed on ATA pins */
	setbits_le32(M4IF_BASE_ADDR + 0xc, M4IF_GENP_WEIM_MM_MASK);

	/* Wait for Grant/Ack sequence (see EIM_CSnGCR2:MUX16_BYP_GRANT) */
	for (i = 0x4; i < 0x94; i += 0x18) {
		clrbits_le32(WEIM_BASE_ADDR + i,
			     WEIM_GCR2_MUX16_BYP_GRANT_MASK);
	}

	mxc_set_clock(0, 33, MXC_NFC_CLK);
	enable_nfc_clk(1);
}

int board_early_init_f(void)
{
	setup_iomux_uart();
	setup_iomux_fec();
	setup_iomux_i2c();
	setup_iomux_nand();
	setup_iomux_video();

	m53_set_clock();

	mxc_set_sata_internal_clock();

	/* NAND clock @ 33MHz */
	m53_set_nand();

	return 0;
}

int board_init(void)
{
	gd->bd->bi_boot_params = PHYS_SDRAM_1 + 0x100;

	return 0;
}

int checkboard(void)
{
	puts("Board: Menlosystems M53Menlo\n");

	return 0;
}

/*
 * NAND SPL
 */
#ifdef CONFIG_SPL_BUILD
void spl_board_init(void)
{
	setup_iomux_nand();
	m53_set_clock();
	m53_set_nand();
}

u32 spl_boot_device(void)
{
	return BOOT_DEVICE_NAND;
}
#endif
