/*
 * linux/arch/arm/mach-omap2/id.c
 *
 * OMAP2 CPU identification code
 *
 * Copyright (C) 2005 Nokia Corporation
 * Written by Tony Lindgren <tony@atomide.com>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 */

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>

#include <asm/io.h>

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

#if defined(CONFIG_ARCH_OMAP2420)
#define TAP_BASE	io_p2v(0x48014000)
#elif defined(CONFIG_ARCH_OMAP2430)
#define TAP_BASE	io_p2v(0x4900A000)
#elif defined(CONFIG_ARCH_OMAP34XX)
#define TAP_BASE	io_p2v(0x4830A000)
#endif

#define OMAP_TAP_IDCODE		0x0204
#if defined(CONFIG_ARCH_OMAP34XX)
#define OMAP_TAP_PROD_ID	0x0210
#else
#define OMAP_TAP_PROD_ID	0x0208
#endif

#define OMAP_TAP_DIE_ID_0	0x0218
#define OMAP_TAP_DIE_ID_1	0x021C
#define OMAP_TAP_DIE_ID_2	0x0220
#define OMAP_TAP_DIE_ID_3	0x0224

/* system_rev fields for OMAP2 processors:
 *   CPU id bits     [31:16],
 *   CPU device type [15:12], (unprg,normal,POP)
 *   CPU revision    [11:08]
 *   CPU class bits  [07:00]
 */

struct omap_id {
	u16	hawkeye;	/* Silicon type (Hawkeye id) */
	u8	dev;		/* Device type from production_id reg */
	u32	type;		/* combined type id copied to system_rev */
};

/* Register values to detect the OMAP version */
static struct omap_id omap_ids[] __initdata = {
	{ .hawkeye = 0xb5d9, .dev = 0x0, .type = 0x24200000 },
	{ .hawkeye = 0xb5d9, .dev = 0x1, .type = 0x24201000 },
	{ .hawkeye = 0xb5d9, .dev = 0x2, .type = 0x24202000 },
	{ .hawkeye = 0xb5d9, .dev = 0x4, .type = 0x24220000 },
	{ .hawkeye = 0xb5d9, .dev = 0x8, .type = 0x24230000 },
	{ .hawkeye = 0xb68a, .dev = 0x0, .type = 0x24300000 },
};

static struct omap_chip_id omap_chip;

/**
 * omap_chip_is - test whether currently running OMAP matches a chip type
 * @oc: omap_chip_t to test against
 *
 * Test whether the currently-running OMAP chip matches the supplied
 * chip type 'oc'.  Returns 1 upon a match; 0 upon failure.
 */
int omap_chip_is(struct omap_chip_id oci)
{
	return (oci.oc & omap_chip.oc) ? 1 : 0;
}
EXPORT_SYMBOL(omap_chip_is);

static u32 __init read_tap_reg(int reg)
{
	unsigned int regval = 0;
	u32 cpuid;

	/* Reading the IDCODE register on 3430 ES1 results in a
	 * data abort as the register is not exposed on the OCP
	 * Hence reading the Cortex Rev
	 */
	cpuid = read_cpuid(CPUID_ID);

	/* If the processor type is Cortex-A8 and the revision is 0x0
	 * it means its Cortex r0p0 which is 3430 ES1
	 */
	if ((((cpuid >> 4) & 0xFFF) == 0xC08) && ((cpuid & 0xF) == 0x0)) {
		switch (reg) {
		case OMAP_TAP_IDCODE  : regval = 0x0B7AE02F; break;
		/* Making DevType as 0xF in ES1 to differ from ES2 */
		case OMAP_TAP_PROD_ID : regval = 0x000F00F0; break;
		case OMAP_TAP_DIE_ID_0: regval = 0x01000000; break;
		case OMAP_TAP_DIE_ID_1: regval = 0x1012d687; break;
		case OMAP_TAP_DIE_ID_2:	regval = 0x00000000; break;
		case OMAP_TAP_DIE_ID_3:	regval = 0x2d2c0000; break;
		}
	} else
		regval = __raw_readl(TAP_BASE + reg);

	return regval;

}

/*
 * _set_system_rev - set the system_rev global based on current OMAP chip type
 *
 * Set the system_rev global.  This is primarily used by the cpu_is_omapxxxx()
 * macros.
 */
static void __init _set_system_rev(u32 type, u8 rev)
{
	u32 i, ctrl_status;

	/*
	 * system_rev encoding is as follows
	 * system_rev & 0xff000000 -> Omap Class (24xx/34xx)
	 * system_rev & 0xfff00000 -> Omap Sub Class (242x/343x)
	 * system_rev & 0xffff0000 -> Omap type (2420/2422/2423/2430/3430)
	 * system_rev & 0x0000f000 -> Silicon revision (ES1, ES2 )
	 * system_rev & 0x00000700 -> Device Type ( EMU/HS/GP/BAD )
	 * system_rev & 0x000000c0 -> IDCODE revision[6:7]
	 * system_rev & 0x0000003f -> sys_boot[0:5]
	 */
	/* Embedding the ES revision info in type field */
	system_rev = type;
	/* Also add IDCODE revision info only two lower bits */
	system_rev |= ((rev & 0x3) << 6);

	/* Add in the device type and sys_boot fields (see above) */
	if (cpu_is_omap24xx()) {
		i = OMAP24XX_CONTROL_STATUS;
	} else if (cpu_is_omap343x()) {
		i = OMAP343X_CONTROL_STATUS;
	} else {
		printk(KERN_ERR "id: unknown CPU type\n");
		BUG();
	}
	ctrl_status = omap_ctrl_readl(i);
	system_rev |= (ctrl_status & (OMAP2_SYSBOOT_5_MASK |
				      OMAP2_SYSBOOT_4_MASK |
				      OMAP2_SYSBOOT_3_MASK |
				      OMAP2_SYSBOOT_2_MASK |
				      OMAP2_SYSBOOT_1_MASK |
				      OMAP2_SYSBOOT_0_MASK));
	system_rev |= (ctrl_status & OMAP2_DEVICETYPE_MASK);
}


/*
 * _set_omap_chip - set the omap_chip global based on OMAP chip type
 *
 * Build the omap_chip bits.  This variable is used by powerdomain and
 * clockdomain code to indicate whether structures are applicable for
 * the current OMAP chip type by ANDing it against a 'platform' bitfield
 * in the structure.
 */
static void __init _set_omap_chip(void)
{
	if (cpu_is_omap343x()) {

		omap_chip.oc = CHIP_IS_OMAP3430;
		if (is_sil_rev_equal_to(OMAP3430_REV_ES1_0))
			omap_chip.oc |= CHIP_IS_OMAP3430ES1;
		else if (is_sil_rev_greater_than(OMAP3430_REV_ES1_0))
			omap_chip.oc |= CHIP_IS_OMAP3430ES2;

	} else if (cpu_is_omap243x()) {

		/* Currently only supports 2430ES2.1 and 2430-all */
		omap_chip.oc |= CHIP_IS_OMAP2430;

	} else if (cpu_is_omap242x()) {

		/* Currently only supports 2420ES2.1.1 and 2420-all */
		omap_chip.oc |= CHIP_IS_OMAP2420;

	} else {

		/* Current CPU not supported by this code. */
		printk(KERN_WARNING "OMAP chip type code does not yet support "
		       "this CPU type.\n");
		WARN_ON(1);

	}

}

void __init omap2_check_revision(void)
{
	int i, j;
	u32 idcode;
	u32 prod_id;
	u16 hawkeye;
	u8  dev_type;
	u8  rev;

	idcode = read_tap_reg(OMAP_TAP_IDCODE);
	prod_id = read_tap_reg(OMAP_TAP_PROD_ID);
	hawkeye = (idcode >> 12) & 0xffff;
	rev = (idcode >> 28) & 0x0f;
	dev_type = (prod_id >> 16) & 0x0f;

	pr_debug("OMAP_TAP_IDCODE 0x%08x REV %i HAWKEYE 0x%04x MANF %03x\n",
		 idcode, rev, hawkeye, (idcode >> 1) & 0x7ff);
	pr_debug("OMAP_TAP_DIE_ID_0: 0x%08x\n",
		 read_tap_reg(OMAP_TAP_DIE_ID_0));
	pr_debug("OMAP_TAP_DIE_ID_1: 0x%08x DEV_REV: %i\n",
		 read_tap_reg(OMAP_TAP_DIE_ID_1),
		 (read_tap_reg(OMAP_TAP_DIE_ID_1) >> 28) & 0xf);
	pr_debug("OMAP_TAP_DIE_ID_2: 0x%08x\n",
		 read_tap_reg(OMAP_TAP_DIE_ID_2));
	pr_debug("OMAP_TAP_DIE_ID_3: 0x%08x\n",
		 read_tap_reg(OMAP_TAP_DIE_ID_3));
	pr_debug("OMAP_TAP_PROD_ID_0: 0x%08x DEV_TYPE: %i\n",
		 prod_id, dev_type);

	/*
	 * Detection for 34xx ES2.0 and above can be done with just
	 * hawkeye and rev. See TRM 1.5.2 Device Identification.
	 * Note that rev cannot be used directly as ES1.0 uses value 0.
	 */
	if (hawkeye == 0xb7ae) {
		system_rev = 0x34300000 | ((1 + rev) << 12);
		pr_info("OMAP%04x ES2.%i\n", system_rev >> 16, rev);
		_set_omap_chip();
		return;
	}

	/* Check hawkeye ids */
	for (i = 0; i < ARRAY_SIZE(omap_ids); i++) {
		if (hawkeye == omap_ids[i].hawkeye)
			break;
	}

	if (i == ARRAY_SIZE(omap_ids)) {
		printk(KERN_ERR "Unknown OMAP CPU id\n");
		return;
	}

	for (j = i; j < ARRAY_SIZE(omap_ids); j++) {
		if (dev_type == omap_ids[j].dev)
			break;
	}

	if (j == ARRAY_SIZE(omap_ids)) {
		printk(KERN_ERR "Unknown OMAP device type. "
				"Handling it as OMAP%04x\n",
				omap_ids[i].type >> 16);
		j = i;
	}

	_set_system_rev(omap_ids[j].type, rev);

	_set_omap_chip();

	pr_info("OMAP%04x", system_rev >> 16);
	if ((system_rev >> 8) & 0x0f)
		pr_info("ES%x", (system_rev >> 12) & 0xf);
	pr_info("\n");

}

