// SPDX-License-Identifier: GPL-2.0
/*
 * board/renesas/blanche/blanche.c
 *     This file is blanche board support.
 *
 * Copyright (C) 2016 Renesas Electronics Corporation
 */

#include <common.h>
#include <asm/arch/mmc.h>
#include <asm/arch/rcar-mstp.h>
#include <asm/arch/rmobile.h>
#include <asm/arch/sh_sdhi.h>
#include <asm/arch/sys_proto.h>
#include <asm/gpio.h>
#include <asm/io.h>
#include <asm/mach-types.h>
#include <asm/processor.h>
#include <dm.h>
#include <dm/platform_data/serial_sh.h>
#include <environment.h>
#include <i2c.h>
#include <linux/errno.h>
#include <malloc.h>
#include <miiphy.h>
#include <mmc.h>
#include <netdev.h>
#include "qos.h"

DECLARE_GLOBAL_DATA_PTR;

#define	CPG_PLL1CR	0xE6150028
#define	CPG_PLL3CR	0xE61500DC

#define TMU0_MSTP125	BIT(25)
#define QSPI_MSTP917	BIT(17)

struct reg_config {
	u16	off;
	u32	val;
};

static void blanche_init_sys(void)
{
	struct rcar_rwdt *rwdt = (struct rcar_rwdt *)RWDT_BASE;
	struct rcar_swdt *swdt = (struct rcar_swdt *)SWDT_BASE;
	u32 cpu_type;

	cpu_type = rmobile_get_cpu_type();
	if (cpu_type == 0x4A) {
		writel(0x4D000000, CPG_PLL1CR);
		writel(0x4F000000, CPG_PLL3CR);
	}

	/* Watchdog init */
	writel(0xA5A5A500, &rwdt->rwtcsra);
	writel(0xA5A5A500, &swdt->swtcsra);
}

static void blanche_init_pfc(void)
{
	static const struct reg_config pfc_with_unlock[] = {
		{ 0x0004, 0x0bffffff },
		{ 0x0008, 0x002fffff },
		{ 0x0014, 0x00000fff },
		{ 0x0018, 0x00010fff },
		{ 0x001c, 0x00010fff },
		{ 0x0020, 0x00010fff },
		{ 0x0024, 0x00010fff },
		{ 0x0028, 0x00010fff },
		{ 0x002c, 0x04006000 },
		{ 0x0030, 0x303fefe0 },
		{ 0x0058, 0x0002000e },
	};

	static const struct reg_config pfc_without_unlock[] = {
		{ 0x0108, 0x00000000 },
		{ 0x010c, 0x0803FF40 },
		{ 0x0110, 0x0000FFFF },
		{ 0x0114, 0x00010FFF },
		{ 0x011c, 0x0001AFFF },
		{ 0x0124, 0x0001CFFF },
		{ 0x0128, 0xC0438001 },
		{ 0x012c, 0x0FC00007 },
	};

	static const u32 pfc_base = 0xe6060000;

	unsigned int i;

	for (i = 0; i < ARRAY_SIZE(pfc_with_unlock); i++) {
		writel(~pfc_with_unlock[i].val, pfc_base);
		writel(pfc_with_unlock[i].val,
		       pfc_base | pfc_with_unlock[i].off);
	}

	for (i = 0; i < ARRAY_SIZE(pfc_without_unlock); i++)
		writel(pfc_without_unlock[i].val,
		       pfc_base | pfc_without_unlock[i].off);
}

static void blanche_init_lbsc(void)
{
	static const struct reg_config lbsc_config[] = {
		{ 0x00, 0x00000020 },
		{ 0x08, 0x00002020 },
		{ 0x30, 0x2a103320 },
		{ 0x38, 0x19102110 },
	};

	static const u32 lbsc_base = 0xfec00200;

	unsigned int i;

	for (i = 0; i < ARRAY_SIZE(lbsc_config); i++) {
		writel(lbsc_config[i].val,
		       lbsc_base | lbsc_config[i].off);
		writel(lbsc_config[i].val,
		       lbsc_base | (lbsc_config[i].off + 4));
	}
}

#if defined(CONFIG_MTD_NOR_FLASH)
static void dbsc_wait(u16 reg)
{
	static const u32 dbsc3_0_base = DBSC3_0_BASE;

	while (!(readl(dbsc3_0_base + reg) & BIT(0)))
		;
}

static void blanche_init_dbsc(void)
{
	static const struct reg_config dbsc_config1[] = {
		{ 0x0280, 0x0000a55a },
		{ 0x0018, 0x21000000 },
		{ 0x0018, 0x11000000 },
		{ 0x0018, 0x10000000 },
		{ 0x0290, 0x00000001 },
		{ 0x02a0, 0x80000000 },
		{ 0x0290, 0x00000004 },
	};

	static const struct reg_config dbsc_config2[] = {
		{ 0x0290, 0x00000006 },
		{ 0x02a0, 0x0001c000 },
	};

	static const struct reg_config dbsc_config4[] = {
		{ 0x0290, 0x0000000f },
		{ 0x02a0, 0x00181ee4 },
		{ 0x0290, 0x00000010 },
		{ 0x02a0, 0xf00464db },
		{ 0x0290, 0x00000061 },
		{ 0x02a0, 0x0000008d },
		{ 0x0290, 0x00000001 },
		{ 0x02a0, 0x00000073 },
		{ 0x0020, 0x00000007 },
		{ 0x0024, 0x0f030a02 },
		{ 0x0030, 0x00000001 },
		{ 0x00b0, 0x00000000 },
		{ 0x0040, 0x0000000b },
		{ 0x0044, 0x00000008 },
		{ 0x0048, 0x00000000 },
		{ 0x0050, 0x0000000b },
		{ 0x0054, 0x000c000b },
		{ 0x0058, 0x00000027 },
		{ 0x005c, 0x0000001c },
		{ 0x0060, 0x00000006 },
		{ 0x0064, 0x00000020 },
		{ 0x0068, 0x00000008 },
		{ 0x006c, 0x0000000c },
		{ 0x0070, 0x00000009 },
		{ 0x0074, 0x00000012 },
		{ 0x0078, 0x000000d0 },
		{ 0x007c, 0x00140005 },
		{ 0x0080, 0x00050004 },
		{ 0x0084, 0x70233005 },
		{ 0x0088, 0x000c0000 },
		{ 0x008c, 0x00000300 },
		{ 0x0090, 0x00000040 },
		{ 0x0100, 0x00000001 },
		{ 0x00c0, 0x00020001 },
		{ 0x00c8, 0x20082004 },
		{ 0x0380, 0x00020002 },
		{ 0x0390, 0x0000001f },
	};

	static const struct reg_config dbsc_config5[] = {
		{ 0x0244, 0x00000011 },
		{ 0x0290, 0x00000003 },
		{ 0x02a0, 0x0300c4e1 },
		{ 0x0290, 0x00000023 },
		{ 0x02a0, 0x00fcdb60 },
		{ 0x0290, 0x00000011 },
		{ 0x02a0, 0x1000040b },
		{ 0x0290, 0x00000012 },
		{ 0x02a0, 0x9d9cbb66 },
		{ 0x0290, 0x00000013 },
		{ 0x02a0, 0x1a868400 },
		{ 0x0290, 0x00000014 },
		{ 0x02a0, 0x300214d8 },
		{ 0x0290, 0x00000015 },
		{ 0x02a0, 0x00000d70 },
		{ 0x0290, 0x00000016 },
		{ 0x02a0, 0x00000004 },
		{ 0x0290, 0x00000017 },
		{ 0x02a0, 0x00000018 },
		{ 0x0290, 0x0000001a },
		{ 0x02a0, 0x910035c7 },
		{ 0x0290, 0x00000004 },
	};

	static const struct reg_config dbsc_config6[] = {
		{ 0x0290, 0x00000001 },
		{ 0x02a0, 0x00000181 },
		{ 0x0018, 0x11000000 },
		{ 0x0290, 0x00000004 },
	};

	static const struct reg_config dbsc_config7[] = {
		{ 0x0290, 0x00000001 },
		{ 0x02a0, 0x0000fe01 },
		{ 0x0304, 0x00000000 },
		{ 0x00f4, 0x01004c20 },
		{ 0x00f8, 0x014000aa },
		{ 0x00e0, 0x00000140 },
		{ 0x00e4, 0x00081860 },
		{ 0x00e8, 0x00010000 },
		{ 0x0290, 0x00000004 },
	};

	static const struct reg_config dbsc_config8[] = {
		{ 0x0014, 0x00000001 },
		{ 0x0010, 0x00000001 },
		{ 0x0280, 0x00000000 },
	};

	static const u32 dbsc3_0_base = DBSC3_0_BASE;
	unsigned int i;

	for (i = 0; i < ARRAY_SIZE(dbsc_config1); i++)
		writel(dbsc_config1[i].val, dbsc3_0_base | dbsc_config1[i].off);

	dbsc_wait(0x2a0);

	for (i = 0; i < ARRAY_SIZE(dbsc_config2); i++)
		writel(dbsc_config2[i].val, dbsc3_0_base | dbsc_config2[i].off);

	for (i = 0; i < ARRAY_SIZE(dbsc_config4); i++)
		writel(dbsc_config4[i].val, dbsc3_0_base | dbsc_config4[i].off);

	dbsc_wait(0x240);

	for (i = 0; i < ARRAY_SIZE(dbsc_config5); i++)
		writel(dbsc_config5[i].val, dbsc3_0_base | dbsc_config5[i].off);

	dbsc_wait(0x2a0);

	for (i = 0; i < ARRAY_SIZE(dbsc_config6); i++)
		writel(dbsc_config6[i].val, dbsc3_0_base | dbsc_config6[i].off);

	dbsc_wait(0x2a0);

	for (i = 0; i < ARRAY_SIZE(dbsc_config7); i++)
		writel(dbsc_config7[i].val, dbsc3_0_base | dbsc_config7[i].off);

	dbsc_wait(0x2a0);

	for (i = 0; i < ARRAY_SIZE(dbsc_config8); i++)
		writel(dbsc_config8[i].val, dbsc3_0_base | dbsc_config8[i].off);

}

static void s_init_wait(volatile unsigned int cnt)
{
	volatile u32 i = cnt * 0x10000;

	while (i-- > 0)
		;
}
#endif

void s_init(void)
{
	blanche_init_sys();
	qos_init();
	blanche_init_pfc();
	blanche_init_lbsc();
#if defined(CONFIG_MTD_NOR_FLASH)
	s_init_wait(10);
	blanche_init_dbsc();
#endif /* CONFIG_MTD_NOR_FLASH */
}

int board_early_init_f(void)
{
	/* TMU0 */
	mstp_clrbits_le32(MSTPSR1, SMSTPCR1, TMU0_MSTP125);
	/* QSPI */
	mstp_clrbits_le32(MSTPSR9, SMSTPCR9, QSPI_MSTP917);

	return 0;
}

int board_init(void)
{
	/* adress of boot parameters */
	gd->bd->bi_boot_params = CONFIG_SYS_SDRAM_BASE + 0x100;

	return 0;
}

/* Added for BLANCHE(R-CarV2H board) */
int board_eth_init(bd_t *bis)
{
	int rc = 0;

#ifdef CONFIG_SMC911X
	struct eth_device *dev;
	uchar eth_addr[6];

	rc = smc911x_initialize(0, CONFIG_SMC911X_BASE);

	if (!eth_env_get_enetaddr("ethaddr", eth_addr)) {
		dev = eth_get_dev_by_index(0);
		if (dev) {
			eth_env_set_enetaddr("ethaddr", dev->enetaddr);
		} else {
			printf("blanche: Couldn't get eth device\n");
			rc = -1;
		}
	}

#endif

	return rc;
}

int dram_init(void)
{
	if (fdtdec_setup_memory_size() != 0)
		return -EINVAL;

	return 0;
}

int dram_init_banksize(void)
{
	fdtdec_setup_memory_banksize();

	return 0;
}

void reset_cpu(ulong addr)
{
}
