// SPDX-License-Identifier: GPL-2.0+
/*
 * Board initialization for EP93xx
 *
 * Copyright (C) 2013
 * Sergey Kostanbaev <sergey.kostanbaev <at> fairwaves.ru>
 *
 * Copyright (C) 2009
 * Matthias Kaehlcke <matthias <at> kaehlcke.net>
 *
 * (C) Copyright 2002 2003
 * Network Audio Technologies, Inc. <www.netaudiotech.com>
 * Adam Bezanson <bezanson <at> netaudiotech.com>
 */

#include <config.h>
#include <common.h>
#include <cpu_func.h>
#include <irq_func.h>
#include <net.h>
#include <netdev.h>
#include <status_led.h>
#include <asm/io.h>
#include <asm/mach-types.h>
#include <asm/arch/ep93xx.h>

DECLARE_GLOBAL_DATA_PTR;

/*
 * usb_div: 4, nbyp2: 1, pll2_en: 1
 * pll2_x1: 368640000.000000, pll2_x2ip: 15360000.000000,
 * pll2_x2: 384000000.000000, pll2_out: 192000000.000000
 */
#define CLKSET2_VAL	(23 << SYSCON_CLKSET_PLL_X2IPD_SHIFT |	\
			24 << SYSCON_CLKSET_PLL_X2FBD2_SHIFT |	\
			24 << SYSCON_CLKSET_PLL_X1FBD1_SHIFT |	\
			1 << SYSCON_CLKSET_PLL_PS_SHIFT |	\
			SYSCON_CLKSET2_PLL2_EN |		\
			SYSCON_CLKSET2_NBYP2 |			\
			3 << SYSCON_CLKSET2_USB_DIV_SHIFT)

#define SMC_BCR6_VALUE	(2 << SMC_BCR_IDCY_SHIFT | 5 << SMC_BCR_WST1_SHIFT | \
			SMC_BCR_BLE | 2 << SMC_BCR_WST2_SHIFT | \
			1 << SMC_BCR_MW_SHIFT)

/* delay execution before timers are initialized */
static inline void early_udelay(uint32_t usecs)
{
	/* loop takes 4 cycles at 5.0ns (fastest case, running at 200MHz) */
	register uint32_t loops = (usecs * 1000) / 20;

	__asm__ volatile ("1:\n"
			"subs %0, %1, #1\n"
			"bne 1b" : "=r" (loops) : "0" (loops));
}

#ifndef CONFIG_EP93XX_NO_FLASH_CFG
static void flash_cfg(void)
{
	struct smc_regs *smc = (struct smc_regs *)SMC_BASE;

	writel(SMC_BCR6_VALUE, &smc->bcr6);
}
#else
#define flash_cfg()
#endif

int board_init(void)
{
	/*
	 * Setup PLL2, PPL1 has been set during lowlevel init
	 */
	struct syscon_regs *syscon = (struct syscon_regs *)SYSCON_BASE;
	writel(CLKSET2_VAL, &syscon->clkset2);

	/*
	 * the user's guide recommends to wait at least 1 ms for PLL2 to
	 * stabilize
	 */
	early_udelay(1000);

	/* Go to Async mode */
	__asm__ volatile ("mrc p15, 0, r0, c1, c0, 0");
	__asm__ volatile ("orr r0, r0, #0xc0000000");
	__asm__ volatile ("mcr p15, 0, r0, c1, c0, 0");

	icache_enable();

#ifdef USE_920T_MMU
	dcache_enable();
#endif

	/* Machine number, as defined in linux/arch/arm/tools/mach-types */
	gd->bd->bi_arch_number = CONFIG_MACH_TYPE;

	/* adress of boot parameters */
	gd->bd->bi_boot_params = LINUX_BOOT_PARAM_ADDR;

	/* We have a console */
	gd->have_console = 1;

	enable_interrupts();

	flash_cfg();

	green_led_on();
	red_led_off();

	return 0;
}

int board_early_init_f(void)
{
	/*
	 * set UARTBAUD bit to drive UARTs with 14.7456MHz instead of
	 * 14.7456/2 MHz
	 */
	struct syscon_regs *syscon = (struct syscon_regs *)SYSCON_BASE;
	writel(SYSCON_PWRCNT_UART_BAUD, &syscon->pwrcnt);
	return 0;
}

int board_eth_init(bd_t *bd)
{
	return ep93xx_eth_initialize(0, MAC_BASE);
}

static void dram_fill_bank_addr(unsigned dram_addr_mask, unsigned dram_bank_cnt,
				unsigned dram_bank_base[CONFIG_NR_DRAM_BANKS])
{
	if (dram_bank_cnt == 1) {
		dram_bank_base[0] = PHYS_SDRAM_1;
	} else {
		/* Table lookup for holes in address space. Maximum memory
		 * for the single SDCS may be up to 256Mb. We start scanning
		 * banks from 1Mb, so it could be up to 128 banks theoretically.
		 * We need at maximum 7 bits for the loockup, 8 slots is
		 * enough for the worst case.
		 */
		unsigned tbl[8];
		unsigned i = dram_bank_cnt / 2;
		unsigned j = 0x00100000; /* 1 Mb */
		unsigned *ptbl = tbl;
		do {
			while (!(dram_addr_mask & j)) {
				j <<= 1;
			}
			*ptbl++ = j;
			j <<= 1;
			i >>= 1;
		} while (i != 0);

		for (i = dram_bank_cnt, j = 0;
		     (i != 0) && (j < CONFIG_NR_DRAM_BANKS); --i, ++j) {
			unsigned addr = PHYS_SDRAM_1;
			unsigned k;
			unsigned bit;

			for (k = 0, bit = 1; k < 8; k++, bit <<= 1) {
				if (bit & j)
					addr |= tbl[k];
			}

			dram_bank_base[j] = addr;
		}
	}
}

/* called in board_init_f (before relocation) */
static unsigned dram_init_banksize_int(int print)
{
	/*
	 * Collect information of banks that has been filled during lowlevel
	 * initialization
	 */
	unsigned i;
	unsigned dram_bank_base[CONFIG_NR_DRAM_BANKS];
	unsigned dram_total = 0;
	unsigned dram_bank_size = *(unsigned *)
				  (PHYS_SDRAM_1 | UBOOT_MEMORYCNF_BANK_SIZE);
	unsigned dram_addr_mask = *(unsigned *)
				  (PHYS_SDRAM_1 | UBOOT_MEMORYCNF_BANK_MASK);
	unsigned dram_bank_cnt = *(unsigned *)
				 (PHYS_SDRAM_1 | UBOOT_MEMORYCNF_BANK_COUNT);

	dram_fill_bank_addr(dram_addr_mask, dram_bank_cnt, dram_bank_base);

	for (i = 0; i < dram_bank_cnt; i++) {
		gd->bd->bi_dram[i].start = dram_bank_base[i];
		gd->bd->bi_dram[i].size = dram_bank_size;
		dram_total += dram_bank_size;
	}
	for (; i < CONFIG_NR_DRAM_BANKS; i++) {
		gd->bd->bi_dram[i].start = 0;
		gd->bd->bi_dram[i].size = 0;
	}

	if (print) {
		printf("DRAM mask: %08x\n", dram_addr_mask);
		printf("DRAM total %u banks:\n", dram_bank_cnt);
		printf("bank          base-address          size\n");

		if (dram_bank_cnt > CONFIG_NR_DRAM_BANKS) {
			printf("WARNING! UBoot was configured for %u banks,\n"
				"but %u has been found. "
				"Supressing extra memory banks\n",
				 CONFIG_NR_DRAM_BANKS, dram_bank_cnt);
			dram_bank_cnt = CONFIG_NR_DRAM_BANKS;
		}

		for (i = 0; i < dram_bank_cnt; i++) {
			printf("  %u             %08x            %08x\n",
			       i, dram_bank_base[i], dram_bank_size);
		}
		printf("  ------------------------------------------\n"
			"Total                              %9d\n\n",
			dram_total);
	}

	return dram_total;
}

int dram_init_banksize(void)
{
	dram_init_banksize_int(0);

	return 0;
}

/* called in board_init_f (before relocation) */
int dram_init(void)
{
	struct syscon_regs *syscon = (struct syscon_regs *)SYSCON_BASE;
	unsigned sec_id = readl(SECURITY_EXTENSIONID);
	unsigned chip_id = readl(&syscon->chipid);

	printf("CPU: Cirrus Logic ");
	switch (sec_id & 0x000001FE) {
	case 0x00000008:
		printf("EP9301");
		break;
	case 0x00000004:
		printf("EP9307");
		break;
	case 0x00000002:
		printf("EP931x");
		break;
	case 0x00000000:
		printf("EP9315");
		break;
	default:
		printf("<unknown>");
		break;
	}

	printf(" - Rev. ");
	switch (chip_id & 0xF0000000) {
	case 0x00000000:
		printf("A");
		break;
	case 0x10000000:
		printf("B");
		break;
	case 0x20000000:
		printf("C");
		break;
	case 0x30000000:
		printf("D0");
		break;
	case 0x40000000:
		printf("D1");
		break;
	case 0x50000000:
		printf("E0");
		break;
	case 0x60000000:
		printf("E1");
		break;
	case 0x70000000:
		printf("E2");
		break;
	default:
		printf("?");
		break;
	}
	printf(" (SecExtID=%.8x/ChipID=%.8x)\n", sec_id, chip_id);

	gd->ram_size = dram_init_banksize_int(1);
	return 0;
}
