/*
 * 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>
 *
 * SPDX-License-Identifier:	GPL-2.0+
 */

#include <config.h>
#include <common.h>
#include <netdev.h>
#include <asm/io.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;
}

void dram_init_banksize(void)
{
	dram_init_banksize_int(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;
}
