/*
 * (C) Copyright 2000-2003
 * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
 * modified by Wolfgang Wegner <w.wegner@astro-kom.de> for ASTRO 5373l
 *
 * 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 <common.h>
#include <watchdog.h>
#include <command.h>
#include <asm/m5329.h>
#include <asm/immap_5329.h>
#include <asm/io.h>

/* needed for astro bus: */
#include <asm/uart.h>
#include "astro.h"

DECLARE_GLOBAL_DATA_PTR;
extern void uart_port_conf(void);

int checkboard(void)
{
	puts("Board: ");
	puts("ASTRO MCF5373L (Urmel) Board\n");
	return 0;
}

phys_size_t initdram(int board_type)
{
#if !defined(CONFIG_MONITOR_IS_IN_RAM)
	sdram_t *sdp = (sdram_t *)(MMAP_SDRAM);

	/*
	 * GPIO configuration for bus should be set correctly from reset,
	 * so we do not care! First, set up address space: at this point,
	 * we should be running from internal SRAM;
	 * so use CONFIG_SYS_SDRAM_BASE as the base address for SDRAM,
	 * and do not care where it is
	 */
	__raw_writel((CONFIG_SYS_SDRAM_BASE & 0xFFF00000) | 0x00000018,
			&sdp->cs0);
	__raw_writel((CONFIG_SYS_SDRAM_BASE & 0xFFF00000) | 0x00000000,
			&sdp->cs1);
	/*
	 * I am not sure from the data sheet, but it seems burst length
	 * has to be 8 for the 16 bit data bus we use;
	 * so these values are for BL = 8
	 */
	__raw_writel(0x33211530, &sdp->cfg1);
	__raw_writel(0x56570000, &sdp->cfg2);
	/* send PrechargeALL, REF and IREF remain cleared! */
	__raw_writel(0xE1462C02, &sdp->ctrl);
	udelay(1);
	/* refresh SDRAM twice */
	__raw_writel(0xE1462C04, &sdp->ctrl);
	udelay(1);
	__raw_writel(0xE1462C04, &sdp->ctrl);
	/* init MR  */
	__raw_writel(0x008D0000, &sdp->mode);
	/* initialize EMR */
	__raw_writel(0x80010000, &sdp->mode);
	/* wait until DLL is locked */
	udelay(1);
	/*
	 * enable automatic refresh, lock mode register,
	 * clear iref and ipall
	 */
	__raw_writel(0x71462C00, &sdp->ctrl);
	/* Dummy write to start SDRAM */
	writel(0, CONFIG_SYS_SDRAM_BASE);
#endif

	/*
	 * for get_ram_size() to work, both CS areas have to be
	 * configured, i.e. CS1 has to be explicitely disabled, else
	 * probing for memory will cause the SDRAM bus to hang!
	 * (Do not rely on the SDCS register(s) being set to 0x00000000
	 * during reset as stated in the data sheet.)
	 */
	return get_ram_size((unsigned long *)CONFIG_SYS_SDRAM_BASE,
				0x80000000 - CONFIG_SYS_SDRAM_BASE);
}

#define UART_BASE MMAP_UART0
int rs_serial_init(int port, int baud)
{
	uart_t *uart;
	u32 counter;

	switch (port) {
	case 0:
		uart = (uart_t *)(MMAP_UART0);
		break;
	case 1:
		uart = (uart_t *)(MMAP_UART1);
		break;
	case 2:
		uart = (uart_t *)(MMAP_UART2);
		break;
	default:
		uart = (uart_t *)(MMAP_UART0);
	}

	uart_port_conf();

	/* write to SICR: SIM2 = uart mode,dcd does not affect rx */
	writeb(UART_UCR_RESET_RX, &uart->ucr);
	writeb(UART_UCR_RESET_TX, &uart->ucr);
	writeb(UART_UCR_RESET_ERROR, &uart->ucr);
	writeb(UART_UCR_RESET_MR, &uart->ucr);
	__asm__ ("nop");

	writeb(0, &uart->uimr);

	/* write to CSR: RX/TX baud rate from timers */
	writeb(UART_UCSR_RCS_SYS_CLK | UART_UCSR_TCS_SYS_CLK, &uart->ucsr);

	writeb(UART_UMR_BC_8 | UART_UMR_PM_NONE, &uart->umr);
	writeb(UART_UMR_SB_STOP_BITS_1, &uart->umr);

	/* Setting up BaudRate */
	counter = (u32) (gd->bus_clk / (baud));
	counter >>= 5;

	/* write to CTUR: divide counter upper byte */
	writeb((u8) ((counter & 0xff00) >> 8), &uart->ubg1);
	/* write to CTLR: divide counter lower byte */
	writeb((u8) (counter & 0x00ff), &uart->ubg2);

	writeb(UART_UCR_RX_ENABLED | UART_UCR_TX_ENABLED, &uart->ucr);

	return 0;
}

void astro_put_char(char ch)
{
	uart_t *uart;
	unsigned long timer;

	uart = (uart_t *)(MMAP_UART0);
	/*
	 * Wait for last character to go. Timeout of 6ms should
	 * be enough for our lowest baud rate of 2400.
	 */
	timer = get_timer(0);
	while (get_timer(timer) < 6) {
		if (readb(&uart->usr) & UART_USR_TXRDY)
			break;
	}
	writeb(ch, &uart->utb);

	return;
}

int astro_is_char(void)
{
	uart_t *uart;

	uart = (uart_t *)(MMAP_UART0);
	return readb(&uart->usr) & UART_USR_RXRDY;
}

int astro_get_char(void)
{
	uart_t *uart;

	uart = (uart_t *)(MMAP_UART0);
	while (!(readb(&uart->usr) & UART_USR_RXRDY)) ;
	return readb(&uart->urb);
}

int misc_init_r(void)
{
	int retval = 0;

	puts("Configure Xilinx FPGA...");
	retval = astro5373l_xilinx_load();
	if (!retval) {
		puts("failed!\n");
		return retval;
	}
	puts("done\n");

	puts("Configure Altera FPGA...");
	retval = astro5373l_altera_load();
	if (!retval) {
		puts("failed!\n");
		return retval;
	}
	puts("done\n");

	return retval;
}
