/*
 * (C) Copyright 2002
 * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
 * Marius Groeger <mgroeger@sysgo.de>
 *
 * (C) Copyright 2002
 * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
 * Alex Zuepke <azu@sysgo.de>
 *
 * See file CREDITS for list of people who contributed to this
 * project.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation; either version 2 of
 * the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 * MA 02111-1307 USA
 */

#include <asm/io.h>
#include <asm/system.h>
#include <command.h>
#include <common.h>
#include <asm/arch/pxa-regs.h>

/* Flush I/D-cache */
static void cache_flush(void)
{
	unsigned long i = 0;

	asm ("mcr p15, 0, %0, c7, c5, 0" : : "r" (i));
}

int cleanup_before_linux(void)
{
	/*
	 * This function is called just before we call Linux. It prepares
	 * the processor for Linux by just disabling everything that can
	 * disturb booting Linux.
	 */

	disable_interrupts();
	icache_disable();
	dcache_disable();
	cache_flush();

	return 0;
}

void pxa_wait_ticks(int ticks)
{
	writel(0, OSCR);
	while (readl(OSCR) < ticks)
		asm volatile("" : : : "memory");
}

inline void writelrb(uint32_t val, uint32_t addr)
{
	writel(val, addr);
	asm volatile("" : : : "memory");
	readl(addr);
	asm volatile("" : : : "memory");
}

void pxa2xx_dram_init(void)
{
	uint32_t tmp;
	int i;
	/*
	 * 1) Initialize Asynchronous static memory controller
	 */

	writelrb(CONFIG_SYS_MSC0_VAL, MSC0);
	writelrb(CONFIG_SYS_MSC1_VAL, MSC1);
	writelrb(CONFIG_SYS_MSC2_VAL, MSC2);
	/*
	 * 2) Initialize Card Interface
	 */

	/* MECR: Memory Expansion Card Register */
	writelrb(CONFIG_SYS_MECR_VAL, MECR);
	/* MCMEM0: Card Interface slot 0 timing */
	writelrb(CONFIG_SYS_MCMEM0_VAL, MCMEM0);
	/* MCMEM1: Card Interface slot 1 timing */
	writelrb(CONFIG_SYS_MCMEM1_VAL, MCMEM1);
	/* MCATT0: Card Interface Attribute Space Timing, slot 0 */
	writelrb(CONFIG_SYS_MCATT0_VAL, MCATT0);
	/* MCATT1: Card Interface Attribute Space Timing, slot 1 */
	writelrb(CONFIG_SYS_MCATT1_VAL, MCATT1);
	/* MCIO0: Card Interface I/O Space Timing, slot 0 */
	writelrb(CONFIG_SYS_MCIO0_VAL, MCIO0);
	/* MCIO1: Card Interface I/O Space Timing, slot 1 */
	writelrb(CONFIG_SYS_MCIO1_VAL, MCIO1);

	/*
	 * 3) Configure Fly-By DMA register
	 */

	writelrb(CONFIG_SYS_FLYCNFG_VAL, FLYCNFG);

	/*
	 * 4) Initialize Timing for Sync Memory (SDCLK0)
	 */

	/*
	 * Before accessing MDREFR we need a valid DRI field, so we set
	 * this to power on defaults + DRI field.
	 */

	/* Read current MDREFR config and zero out DRI */
	tmp = readl(MDREFR) & ~0xfff;
	/* Add user-specified DRI */
	tmp |= CONFIG_SYS_MDREFR_VAL & 0xfff;
	/* Configure important bits */
	tmp |= MDREFR_K0RUN | MDREFR_SLFRSH;
	tmp &= ~(MDREFR_APD | MDREFR_E1PIN);

	/* Write MDREFR back */
	writelrb(tmp, MDREFR);

	/*
	 * 5) Initialize Synchronous Static Memory (Flash/Peripherals)
	 */

	/* Initialize SXCNFG register. Assert the enable bits.
	 *
	 * Write SXMRS to cause an MRS command to all enabled banks of
	 * synchronous static memory. Note that SXLCR need not be written
	 * at this time.
	 */
	writelrb(CONFIG_SYS_SXCNFG_VAL, SXCNFG);

	/*
	 * 6) Initialize SDRAM
	 */

	writelrb(CONFIG_SYS_MDREFR_VAL & ~MDREFR_SLFRSH, MDREFR);
	writelrb(CONFIG_SYS_MDREFR_VAL | MDREFR_E1PIN, MDREFR);

	/*
	 * 7) Write MDCNFG with MDCNFG:DEx deasserted (set to 0), to configure
	 *    but not enable each SDRAM partition pair.
	 */

	writelrb(CONFIG_SYS_MDCNFG_VAL &
		~(MDCNFG_DE0 | MDCNFG_DE1 | MDCNFG_DE2 | MDCNFG_DE3), MDCNFG);
	/* Wait for the clock to the SDRAMs to stabilize, 100..200 usec. */
	pxa_wait_ticks(0x300);

	/*
	 * 8) Trigger a number (usually 8) refresh cycles by attempting
	 *    non-burst read or write accesses to disabled SDRAM, as commonly
	 *    specified in the power up sequence documented in SDRAM data
	 *    sheets. The address(es) used for this purpose must not be
	 *    cacheable.
	 */
	for (i = 9; i >= 0; i--) {
		writel(i, 0xa0000000);
		asm volatile("" : : : "memory");
	}
	/*
	 * 9) Write MDCNFG with enable bits asserted (MDCNFG:DEx set to 1).
	 */

	tmp = CONFIG_SYS_MDCNFG_VAL &
		(MDCNFG_DE0 | MDCNFG_DE1 | MDCNFG_DE2 | MDCNFG_DE3);
	tmp |= readl(MDCNFG);
	writelrb(tmp, MDCNFG);

	/*
	 * 10) Write MDMRS.
	 */

	writelrb(CONFIG_SYS_MDMRS_VAL, MDMRS);

	/*
	 * 11) Enable APD
	 */

	if (CONFIG_SYS_MDREFR_VAL & MDREFR_APD) {
		tmp = readl(MDREFR);
		tmp |= MDREFR_APD;
		writelrb(tmp, MDREFR);
	}
}

void pxa_gpio_setup(void)
{
	writel(CONFIG_SYS_GPSR0_VAL, GPSR0);
	writel(CONFIG_SYS_GPSR1_VAL, GPSR1);
	writel(CONFIG_SYS_GPSR2_VAL, GPSR2);
#if defined(CONFIG_CPU_PXA27X)
	writel(CONFIG_SYS_GPSR3_VAL, GPSR3);
#endif

	writel(CONFIG_SYS_GPCR0_VAL, GPCR0);
	writel(CONFIG_SYS_GPCR1_VAL, GPCR1);
	writel(CONFIG_SYS_GPCR2_VAL, GPCR2);
#if defined(CONFIG_CPU_PXA27X)
	writel(CONFIG_SYS_GPCR3_VAL, GPCR3);
#endif

	writel(CONFIG_SYS_GPDR0_VAL, GPDR0);
	writel(CONFIG_SYS_GPDR1_VAL, GPDR1);
	writel(CONFIG_SYS_GPDR2_VAL, GPDR2);
#if defined(CONFIG_CPU_PXA27X)
	writel(CONFIG_SYS_GPDR3_VAL, GPDR3);
#endif

	writel(CONFIG_SYS_GAFR0_L_VAL, GAFR0_L);
	writel(CONFIG_SYS_GAFR0_U_VAL, GAFR0_U);
	writel(CONFIG_SYS_GAFR1_L_VAL, GAFR1_L);
	writel(CONFIG_SYS_GAFR1_U_VAL, GAFR1_U);
	writel(CONFIG_SYS_GAFR2_L_VAL, GAFR2_L);
	writel(CONFIG_SYS_GAFR2_U_VAL, GAFR2_U);
#if defined(CONFIG_CPU_PXA27X)
	writel(CONFIG_SYS_GAFR3_L_VAL, GAFR3_L);
	writel(CONFIG_SYS_GAFR3_U_VAL, GAFR3_U);
#endif

	writel(CONFIG_SYS_PSSR_VAL, PSSR);
}

void pxa_interrupt_setup(void)
{
	writel(0, ICLR);
	writel(0, ICMR);
#if defined(CONFIG_CPU_PXA27X)
	writel(0, ICLR2);
	writel(0, ICMR2);
#endif
}

void pxa_clock_setup(void)
{
	writel(CONFIG_SYS_CKEN, CKEN);
	writel(CONFIG_SYS_CCCR, CCCR);
	asm volatile("mcr	p14, 0, %0, c6, c0, 0" : : "r"(2));

	/* enable the 32Khz oscillator for RTC and PowerManager */
	writel(OSCC_OON, OSCC);
	while (!(readl(OSCC) & OSCC_OOK))
		asm volatile("" : : : "memory");
}

void pxa_wakeup(void)
{
	uint32_t rcsr;

	rcsr = readl(RCSR);
	writel(rcsr & (RCSR_GPR | RCSR_SMR | RCSR_WDR | RCSR_HWR), RCSR);

	/* Wakeup */
	if (rcsr & RCSR_SMR) {
		writel(PSSR_PH, PSSR);
		pxa2xx_dram_init();
		icache_disable();
		dcache_disable();
		asm volatile("mov	pc, %0" : : "r"(readl(PSPR)));
	}
}

int arch_cpu_init(void)
{
	pxa_gpio_setup();
	pxa_wakeup();
	pxa_interrupt_setup();
	pxa_clock_setup();
	return 0;
}

void i2c_clk_enable(void)
{
	/* Set the global I2C clock on */
	writel(readl(CKEN) | CKEN14_I2C, CKEN);
}

void reset_cpu(ulong ignored) __attribute__((noreturn));

void reset_cpu(ulong ignored)
{
	uint32_t tmp;

	setbits_le32(OWER, OWER_WME);

	tmp = readl(OSCR);
	tmp += 0x1000;
	writel(tmp, OSMR3);

	for (;;)
		;
}
