// SPDX-License-Identifier: GPL-2.0+
/*
 * Copyright (C) 2010-2017 CS Systemes d'Information
 * Florent Trinh Thai <florent.trinh-thai@c-s.fr>
 * Christophe Leroy <christophe.leroy@c-s.fr>
 *
 * Board specific routines for the MCR3000 board
 */

#include <common.h>
#include <env.h>
#include <hwconfig.h>
#include <init.h>
#include <mpc8xx.h>
#include <fdt_support.h>
#include <serial.h>
#include <asm/io.h>
#include <dm/uclass.h>
#include <wdt.h>
#include <linux/delay.h>

DECLARE_GLOBAL_DATA_PTR;

#define SDRAM_MAX_SIZE			(32 * 1024 * 1024)

static const uint cs1_dram_table_66[] = {
	/* DRAM - single read. (offset 0 in upm RAM) */
	0x0F3DFC04, 0x0FEFBC04, 0x00BE7804, 0x0FFDF400,
	0x1FFFFC05, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,

	/* DRAM - burst read. (offset 8 in upm RAM) */
	0x0F3DFC04, 0x0FEFBC04, 0x00BF7C04, 0x00FFFC00,
	0x00FFFC00, 0x00FEF800, 0x0FFDF400, 0x1FFFFC05,
	0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
	0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,

	/* DRAM - single write. (offset 18 in upm RAM) */
	0x0F3DFC04, 0x0FEFB800, 0x00BF7404, 0x0FFEF804,
	0x0FFDF404, 0x1FFFFC05, 0xFFFFFFFF, 0xFFFFFFFF,

	/* DRAM - burst write. (offset 20 in upm RAM) */
	0x0F3DFC04, 0x0FEFB800, 0x00BF7400, 0x00FFFC00,
	0x00FFFC00, 0x00FFFC04,	0x0FFEF804, 0x0FFDF404,
	0x1FFFFC05, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
	0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,

	/* refresh  (offset 30 in upm RAM) */
	0x0FFDF404, 0x0FFEBC04, 0x0FFD7C84, 0x0FFFFC04,
	0x0FFFFC04, 0x0FFFFC04, 0x1FFFFC85, 0xFFFFFFFF,

	/* init */
	0x0FEEB874, 0x0FBD7474, 0x1FFFFC45, 0xFFFFFFFF,

	/* exception. (offset 3c in upm RAM) */
	0xFFFFFC05, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
};

int ft_board_setup(void *blob, struct bd_info *bd)
{
	const char *sync = "receive";

	ft_cpu_setup(blob, bd);

	/* BRG */
	do_fixup_by_path_u32(blob, "/soc/cpm", "brg-frequency",
			     bd->bi_busfreq, 1);

	/* MAC addr */
	fdt_fixup_ethernet(blob);

	/* Bus Frequency for CPM */
	do_fixup_by_path_u32(blob, "/soc", "bus-frequency", bd->bi_busfreq, 1);

	/* E1 interface - Set data rate */
	do_fixup_by_path_u32(blob, "/localbus/e1-wan", "data-rate", 2, 1);

	/* E1 interface - Set channel phase to 0 */
	do_fixup_by_path_u32(blob, "/localbus/e1-wan", "channel-phase", 0, 1);

	/* E1 interface - rising edge sync pulse transmit */
	do_fixup_by_path(blob, "/localbus/e1-wan", "rising-edge-sync-pulse",
			 sync, strlen(sync), 1);

	return 0;
}

int checkboard(void)
{
	serial_puts("BOARD: MCR3000 CSSI\n");

	return 0;
}

int dram_init(void)
{
	immap_t __iomem *immap = (immap_t __iomem *)CONFIG_SYS_IMMR;
	memctl8xx_t __iomem *memctl = &immap->im_memctl;

	printf("UPMA init for SDRAM (CAS latency 2), ");
	printf("init address 0x%08x, size ", (int)dram_init);
	/* Configure UPMA for cs1 */
	upmconfig(UPMA, (uint *)cs1_dram_table_66,
		  sizeof(cs1_dram_table_66) / sizeof(uint));
	udelay(10);
	out_be16(&memctl->memc_mptpr, 0x0200);
	out_be32(&memctl->memc_mamr, 0x14904000);
	udelay(10);
	out_be32(&memctl->memc_or1, CONFIG_SYS_OR1_PRELIM);
	out_be32(&memctl->memc_br1, CONFIG_SYS_BR1_PRELIM);
	udelay(10);
	out_be32(&memctl->memc_mcr, 0x80002830);
	out_be32(&memctl->memc_mar, 0x00000088);
	out_be32(&memctl->memc_mcr, 0x80002038);
	udelay(200);

	gd->ram_size = get_ram_size((long *)CONFIG_SYS_SDRAM_BASE,
				    SDRAM_MAX_SIZE);

	return 0;
}

int misc_init_r(void)
{
	immap_t __iomem *immr = (immap_t __iomem *)CONFIG_SYS_IMMR;
	iop8xx_t __iomem *iop = &immr->im_ioport;

	/* Set port C13 as GPIO (BTN_ACQ_AL) */
	clrbits_be16(&iop->iop_pcpar, 0x4);
	clrbits_be16(&iop->iop_pcdir, 0x4);

	/* if BTN_ACQ_AL is pressed then bootdelay is changed to 60 second */
	if ((in_be16(&iop->iop_pcdat) & 0x0004) == 0)
		env_set("bootdelay", "60");

	return 0;
}

int board_early_init_f(void)
{
	immap_t __iomem *immr = (immap_t __iomem *)CONFIG_SYS_IMMR;

	/*
	 * Erase FPGA(s) for reboot
	 */
	clrbits_be32(&immr->im_cpm.cp_pbdat, 0x00020000); /* PROGFPGA down */
	setbits_be32(&immr->im_cpm.cp_pbdir, 0x00020000); /* PROGFPGA output */
	udelay(1);				/* Wait more than 300ns */
	setbits_be32(&immr->im_cpm.cp_pbdat, 0x00020000); /* PROGFPGA up */

	return 0;
}

int board_early_init_r(void)
{
	struct udevice *watchdog_dev = NULL;

	if (uclass_get_device(UCLASS_WDT, 0, &watchdog_dev)) {
		puts("Cannot find watchdog!\n");
	} else {
		puts("Enabling watchdog.\n");
		wdt_start(watchdog_dev, 0xffff, 0);
	}

	return 0;
}
