/*
 * Copyright (C) 2012 Atmel Corporation
 *
 * 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 <asm/arch/at91_common.h>
#include <asm/arch/at91_pmc.h>
#include <asm/arch/gpio.h>
#include <asm/io.h>

unsigned int get_chip_id(void)
{
	/* The 0x40 is the offset of cidr in DBGU */
	return readl(ATMEL_BASE_DBGU + 0x40) & ~ARCH_ID_VERSION_MASK;
}

unsigned int get_extension_chip_id(void)
{
	/* The 0x44 is the offset of exid in DBGU */
	return readl(ATMEL_BASE_DBGU + 0x44);
}

unsigned int has_emac1()
{
	return cpu_is_at91sam9x25();
}

unsigned int has_emac0()
{
	return !(cpu_is_at91sam9g15());
}

unsigned int has_lcdc()
{
	return cpu_is_at91sam9g15() || cpu_is_at91sam9g35()
		|| cpu_is_at91sam9x35();
}

char *get_cpu_name()
{
	unsigned int extension_id = get_extension_chip_id();

	if (cpu_is_at91sam9x5()) {
		switch (extension_id) {
		case ARCH_EXID_AT91SAM9G15:
			return CONFIG_SYS_AT91_G15_CPU_NAME;
		case ARCH_EXID_AT91SAM9G25:
			return CONFIG_SYS_AT91_G25_CPU_NAME;
		case ARCH_EXID_AT91SAM9G35:
			return CONFIG_SYS_AT91_G35_CPU_NAME;
		case ARCH_EXID_AT91SAM9X25:
			return CONFIG_SYS_AT91_X25_CPU_NAME;
		case ARCH_EXID_AT91SAM9X35:
			return CONFIG_SYS_AT91_X35_CPU_NAME;
		default:
			return CONFIG_SYS_AT91_UNKNOWN_CPU;
		}
	} else {
		return CONFIG_SYS_AT91_UNKNOWN_CPU;
	}
}

void at91_seriald_hw_init(void)
{
	at91_pmc_t *pmc = (at91_pmc_t *) ATMEL_BASE_PMC;

	at91_set_a_periph(AT91_PIO_PORTA, 9, 0);	/* DRXD */
	at91_set_a_periph(AT91_PIO_PORTA, 10, 1);	/* DTXD */

	writel(1 << ATMEL_ID_SYS, &pmc->pcer);
}

void at91_serial0_hw_init(void)
{
	at91_pmc_t *pmc = (at91_pmc_t *) ATMEL_BASE_PMC;

	at91_set_a_periph(AT91_PIO_PORTA, 0, 1);	/* TXD */
	at91_set_a_periph(AT91_PIO_PORTA, 1, 0);	/* RXD */

	writel(1 << ATMEL_ID_USART0, &pmc->pcer);
}

void at91_serial1_hw_init(void)
{
	at91_pmc_t *pmc = (at91_pmc_t *) ATMEL_BASE_PMC;

	at91_set_a_periph(AT91_PIO_PORTA, 5, 1);	/* TXD */
	at91_set_a_periph(AT91_PIO_PORTA, 6, 0);	/* RXD */

	writel(1 << ATMEL_ID_USART1, &pmc->pcer);
}

void at91_serial2_hw_init(void)
{
	at91_pmc_t *pmc = (at91_pmc_t *) ATMEL_BASE_PMC;

	at91_set_a_periph(AT91_PIO_PORTA, 7, 1);	/* TXD */
	at91_set_a_periph(AT91_PIO_PORTA, 8, 0);	/* RXD */

	writel(1 << ATMEL_ID_USART2, &pmc->pcer);
}

#ifdef CONFIG_ATMEL_SPI
void at91_spi0_hw_init(unsigned long cs_mask)
{
	at91_pmc_t *pmc = (at91_pmc_t *) ATMEL_BASE_PMC;

	at91_set_a_periph(AT91_PIO_PORTA, 11, 0);	/* SPI0_MISO */
	at91_set_a_periph(AT91_PIO_PORTA, 12, 0);	/* SPI0_MOSI */
	at91_set_a_periph(AT91_PIO_PORTA, 13, 0);	/* SPI0_SPCK */

	/* Enable clock */
	writel(1 << ATMEL_ID_SPI0, &pmc->pcer);

	if (cs_mask & (1 << 0))
		at91_set_a_periph(AT91_PIO_PORTA, 14, 0);
	if (cs_mask & (1 << 1))
		at91_set_b_periph(AT91_PIO_PORTA, 7, 0);
	if (cs_mask & (1 << 2))
		at91_set_b_periph(AT91_PIO_PORTA, 1, 0);
	if (cs_mask & (1 << 3))
		at91_set_b_periph(AT91_PIO_PORTB, 3, 0);
	if (cs_mask & (1 << 4))
		at91_set_pio_output(AT91_PIO_PORTA, 14, 0);
	if (cs_mask & (1 << 5))
		at91_set_pio_output(AT91_PIO_PORTA, 7, 0);
	if (cs_mask & (1 << 6))
		at91_set_pio_output(AT91_PIO_PORTA, 1, 0);
	if (cs_mask & (1 << 7))
		at91_set_pio_output(AT91_PIO_PORTB, 3, 0);
}

void at91_spi1_hw_init(unsigned long cs_mask)
{
	at91_pmc_t *pmc = (at91_pmc_t *) ATMEL_BASE_PMC;

	at91_set_b_periph(AT91_PIO_PORTA, 21, 0);	/* SPI1_MISO */
	at91_set_b_periph(AT91_PIO_PORTA, 22, 0);	/* SPI1_MOSI */
	at91_set_b_periph(AT91_PIO_PORTA, 23, 0);	/* SPI1_SPCK */

	/* Enable clock */
	writel(1 << ATMEL_ID_SPI1, &pmc->pcer);

	if (cs_mask & (1 << 0))
		at91_set_b_periph(AT91_PIO_PORTA, 8, 0);
	if (cs_mask & (1 << 1))
		at91_set_b_periph(AT91_PIO_PORTA, 0, 0);
	if (cs_mask & (1 << 2))
		at91_set_b_periph(AT91_PIO_PORTA, 31, 0);
	if (cs_mask & (1 << 3))
		at91_set_b_periph(AT91_PIO_PORTA, 30, 0);
	if (cs_mask & (1 << 4))
		at91_set_pio_output(AT91_PIO_PORTA, 8, 0);
	if (cs_mask & (1 << 5))
		at91_set_pio_output(AT91_PIO_PORTA, 0, 0);
	if (cs_mask & (1 << 6))
		at91_set_pio_output(AT91_PIO_PORTA, 31, 0);
	if (cs_mask & (1 << 7))
		at91_set_pio_output(AT91_PIO_PORTA, 30, 0);
}
#endif

#ifdef CONFIG_MACB
void at91_macb_hw_init(void)
{
	at91_pmc_t *pmc = (at91_pmc_t *) ATMEL_BASE_PMC;

	if (has_emac0()) {
		/* Enable EMAC0 clock */
		writel(1 << ATMEL_ID_EMAC0, &pmc->pcer);
		/* EMAC0 pins setup */
		at91_set_a_periph(AT91_PIO_PORTB, 4, 0);	/* ETXCK */
		at91_set_a_periph(AT91_PIO_PORTB, 3, 0);	/* ERXDV */
		at91_set_a_periph(AT91_PIO_PORTB, 0, 0);	/* ERX0 */
		at91_set_a_periph(AT91_PIO_PORTB, 1, 0);	/* ERX1 */
		at91_set_a_periph(AT91_PIO_PORTB, 2, 0);	/* ERXER */
		at91_set_a_periph(AT91_PIO_PORTB, 7, 0);	/* ETXEN */
		at91_set_a_periph(AT91_PIO_PORTB, 9, 0);	/* ETX0 */
		at91_set_a_periph(AT91_PIO_PORTB, 10, 0);	/* ETX1 */
		at91_set_a_periph(AT91_PIO_PORTB, 5, 0);	/* EMDIO */
		at91_set_a_periph(AT91_PIO_PORTB, 6, 0);	/* EMDC */
	}

	if (has_emac1()) {
		/* Enable EMAC1 clock */
		writel(1 << ATMEL_ID_EMAC1, &pmc->pcer);
		/* EMAC1 pins setup */
		at91_set_b_periph(AT91_PIO_PORTC, 29, 0);	/* ETXCK */
		at91_set_b_periph(AT91_PIO_PORTC, 28, 0);	/* ECRSDV */
		at91_set_b_periph(AT91_PIO_PORTC, 20, 0);	/* ERXO */
		at91_set_b_periph(AT91_PIO_PORTC, 21, 0);	/* ERX1 */
		at91_set_b_periph(AT91_PIO_PORTC, 16, 0);	/* ERXER */
		at91_set_b_periph(AT91_PIO_PORTC, 27, 0);	/* ETXEN */
		at91_set_b_periph(AT91_PIO_PORTC, 18, 0);	/* ETX0 */
		at91_set_b_periph(AT91_PIO_PORTC, 19, 0);	/* ETX1 */
		at91_set_b_periph(AT91_PIO_PORTC, 31, 0);	/* EMDIO */
		at91_set_b_periph(AT91_PIO_PORTC, 30, 0);	/* EMDC */
	}

#ifndef CONFIG_RMII
	/* Only emac0 support MII */
	if (has_emac0()) {
		at91_set_b_periph(AT91_PIO_PORTB, 16, 0);	/* ECRS */
		at91_set_b_periph(AT91_PIO_PORTB, 17, 0);	/* ECOL */
		at91_set_b_periph(AT91_PIO_PORTB, 13, 0);	/* ERX2 */
		at91_set_b_periph(AT91_PIO_PORTB, 14, 0);	/* ERX3 */
		at91_set_b_periph(AT91_PIO_PORTB, 15, 0);	/* ERXCK */
		at91_set_b_periph(AT91_PIO_PORTB, 11, 0);	/* ETX2 */
		at91_set_b_periph(AT91_PIO_PORTB, 12, 0);	/* ETX3 */
		at91_set_b_periph(AT91_PIO_PORTB, 8, 0);	/* ETXER */
	}
#endif
}
#endif
