/*
 * arch/arm/mach-at91/include/mach/uncompress.h
 *
 * Copyright (C) 2003 SAN People
 * Copyright (C) 2012 Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
 *
 * 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
 */

#ifndef __ASM_ARCH_UNCOMPRESS_H
#define __ASM_ARCH_UNCOMPRESS_H

#include <linux/io.h>
#include <linux/atmel_serial.h>
#include <mach/hardware.h>

#include <mach/at91_dbgu.h>
#include <mach/cpu.h>

void __iomem *at91_uart;

static const u32 uarts_rm9200[] = {
	AT91_BASE_DBGU0,
	AT91RM9200_BASE_US0,
	AT91RM9200_BASE_US1,
	AT91RM9200_BASE_US2,
	AT91RM9200_BASE_US3,
	0,
};

static const u32 uarts_sam9260[] = {
	AT91_BASE_DBGU0,
	AT91SAM9260_BASE_US0,
	AT91SAM9260_BASE_US1,
	AT91SAM9260_BASE_US2,
	AT91SAM9260_BASE_US3,
	AT91SAM9260_BASE_US4,
	AT91SAM9260_BASE_US5,
	0,
};

static const u32 uarts_sam9261[] = {
	AT91_BASE_DBGU0,
	AT91SAM9261_BASE_US0,
	AT91SAM9261_BASE_US1,
	AT91SAM9261_BASE_US2,
	0,
};

static const u32 uarts_sam9263[] = {
	AT91_BASE_DBGU1,
	AT91SAM9263_BASE_US0,
	AT91SAM9263_BASE_US1,
	AT91SAM9263_BASE_US2,
	0,
};

static const u32 uarts_sam9g45[] = {
	AT91_BASE_DBGU1,
	AT91SAM9G45_BASE_US0,
	AT91SAM9G45_BASE_US1,
	AT91SAM9G45_BASE_US2,
	AT91SAM9G45_BASE_US3,
	0,
};

static const u32 uarts_sam9rl[] = {
	AT91_BASE_DBGU0,
	AT91SAM9RL_BASE_US0,
	AT91SAM9RL_BASE_US1,
	AT91SAM9RL_BASE_US2,
	AT91SAM9RL_BASE_US3,
	0,
};

static const u32 uarts_sam9x5[] = {
	AT91_BASE_DBGU0,
	AT91SAM9X5_BASE_USART0,
	AT91SAM9X5_BASE_USART1,
	AT91SAM9X5_BASE_USART2,
	0,
};

static const u32 uarts_sama5d3[] = {
	AT91_BASE_DBGU1,
	SAMA5D3_BASE_USART0,
	SAMA5D3_BASE_USART1,
	SAMA5D3_BASE_USART2,
	SAMA5D3_BASE_USART3,
	0,
};

static const u32 uarts_sama5d4[] = {
	AT91_BASE_DBGU2,
	SAMA5D4_BASE_USART3,
	0,
};

static inline const u32* decomp_soc_detect(void __iomem *dbgu_base)
{
	u32 cidr, socid;

	cidr = __raw_readl(dbgu_base + AT91_DBGU_CIDR);
	socid = cidr & ~AT91_CIDR_VERSION;

	switch (socid) {
	case ARCH_ID_AT91RM9200:
		return uarts_rm9200;

	case ARCH_ID_AT91SAM9G20:
	case ARCH_ID_AT91SAM9260:
		return uarts_sam9260;

	case ARCH_ID_AT91SAM9261:
		return uarts_sam9261;

	case ARCH_ID_AT91SAM9263:
		return uarts_sam9263;

	case ARCH_ID_AT91SAM9G45:
		return uarts_sam9g45;

	case ARCH_ID_AT91SAM9RL64:
		return uarts_sam9rl;

	case ARCH_ID_AT91SAM9N12:
	case ARCH_ID_AT91SAM9X5:
		return uarts_sam9x5;

	case ARCH_ID_SAMA5:
		cidr = __raw_readl(dbgu_base + AT91_DBGU_EXID);
		if (cidr & ARCH_EXID_SAMA5D3)
			return uarts_sama5d3;
		else if (cidr & ARCH_EXID_SAMA5D4)
			return uarts_sama5d4;

		break;
	}

	/* at91sam9g10 */
	if ((cidr & ~AT91_CIDR_EXT) == ARCH_ID_AT91SAM9G10) {
		return uarts_sam9261;
	}
	/* at91sam9xe */
	else if ((cidr & AT91_CIDR_ARCH) == ARCH_FAMILY_AT91SAM9XE) {
		return uarts_sam9260;
	}

	return NULL;
}

static inline void arch_decomp_setup(void)
{
	int i = 0;
	const u32* usarts;

	usarts = decomp_soc_detect((void __iomem *)AT91_BASE_DBGU0);
	if (!usarts)
		usarts = decomp_soc_detect((void __iomem *)AT91_BASE_DBGU1);
	if (!usarts)
		usarts = decomp_soc_detect((void __iomem *)AT91_BASE_DBGU2);
	if (!usarts) {
		at91_uart = NULL;
		return;
	}

	do {
		/* physical address */
		at91_uart = (void __iomem *)usarts[i];

		if (__raw_readl(at91_uart + ATMEL_US_BRGR))
			return;
		i++;
	} while (usarts[i]);

	at91_uart = NULL;
}

/*
 * The following code assumes the serial port has already been
 * initialized by the bootloader.  If you didn't setup a port in
 * your bootloader then nothing will appear (which might be desired).
 *
 * This does not append a newline
 */
static void putc(int c)
{
	if (!at91_uart)
		return;

	while (!(__raw_readl(at91_uart + ATMEL_US_CSR) & ATMEL_US_TXRDY))
		barrier();
	__raw_writel(c, at91_uart + ATMEL_US_THR);
}

static inline void flush(void)
{
	if (!at91_uart)
		return;

	/* wait for transmission to complete */
	while (!(__raw_readl(at91_uart + ATMEL_US_CSR) & ATMEL_US_TXEMPTY))
		barrier();
}

#endif
