2005-11-10 17:26:51 +03:00
/*
* linux / arch / arm / mach - omap2 / id . c
*
* OMAP2 CPU identification code
*
* Copyright ( C ) 2005 Nokia Corporation
* Written by Tony Lindgren < tony @ atomide . com >
*
2011-02-17 20:55:03 +03:00
* Copyright ( C ) 2009 - 11 Texas Instruments
2009-05-29 01:16:04 +04:00
* Added OMAP4 support - Santosh Shilimkar < santosh . shilimkar @ ti . com >
*
2005-11-10 17:26:51 +03:00
* 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>
2008-09-06 15:10:45 +04:00
# include <linux/io.h>
2005-11-10 17:26:51 +03:00
2008-08-10 21:08:10 +04:00
# include <asm/cputype.h>
2005-11-10 17:26:51 +03:00
2011-11-11 01:45:17 +04:00
# include "common.h"
2009-10-20 20:40:47 +04:00
# include <plat/cpu.h>
2006-12-07 04:14:05 +03:00
2010-08-02 15:21:41 +04:00
# include <mach/id.h>
2010-10-08 21:40:20 +04:00
# include "control.h"
2008-12-11 04:36:31 +03:00
static unsigned int omap_revision ;
2011-12-19 14:20:14 +04:00
static const char * cpu_rev ;
2011-07-02 06:30:22 +04:00
u32 omap_features ;
2008-12-11 04:36:31 +03:00
unsigned int omap_rev ( void )
{
return omap_revision ;
}
EXPORT_SYMBOL ( omap_rev ) ;
2008-07-03 13:24:45 +04:00
2009-06-23 14:30:23 +04:00
int omap_type ( void )
{
u32 val = 0 ;
2009-11-22 21:11:24 +03:00
if ( cpu_is_omap24xx ( ) ) {
2009-06-23 14:30:23 +04:00
val = omap_ctrl_readl ( OMAP24XX_CONTROL_STATUS ) ;
2012-03-06 04:11:01 +04:00
} else if ( cpu_is_am33xx ( ) ) {
val = omap_ctrl_readl ( AM33XX_CONTROL_STATUS ) ;
2009-11-22 21:11:24 +03:00
} else if ( cpu_is_omap34xx ( ) ) {
2009-06-23 14:30:23 +04:00
val = omap_ctrl_readl ( OMAP343X_CONTROL_STATUS ) ;
2010-02-18 11:59:10 +03:00
} else if ( cpu_is_omap44xx ( ) ) {
2010-09-28 00:02:58 +04:00
val = omap_ctrl_readl ( OMAP4_CTRL_MODULE_CORE_STATUS ) ;
2009-11-22 21:11:24 +03:00
} else {
2009-06-23 14:30:23 +04:00
pr_err ( " Cannot detect omap type! \n " ) ;
goto out ;
}
val & = OMAP2_DEVICETYPE_MASK ;
val > > = 8 ;
out :
return val ;
}
EXPORT_SYMBOL ( omap_type ) ;
2008-12-11 04:36:30 +03:00
/*----------------------------------------------------------------------------*/
2008-07-03 13:24:45 +04:00
2008-12-11 04:36:30 +03:00
# define OMAP_TAP_IDCODE 0x0204
# 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
2008-07-03 13:24:45 +04:00
2011-03-13 01:50:54 +03:00
# define OMAP_TAP_DIE_ID_44XX_0 0x0200
# define OMAP_TAP_DIE_ID_44XX_1 0x0208
# define OMAP_TAP_DIE_ID_44XX_2 0x020c
# define OMAP_TAP_DIE_ID_44XX_3 0x0210
2008-12-11 04:36:30 +03:00
# define read_tap_reg(reg) __raw_readl(tap_base + (reg))
2008-07-03 13:24:45 +04:00
2008-12-11 04:36:30 +03:00
struct omap_id {
u16 hawkeye ; /* Silicon type (Hawkeye id) */
u8 dev ; /* Device type from production_id reg */
2008-12-11 04:36:31 +03:00
u32 type ; /* Combined type id copied to omap_revision */
2008-12-11 04:36:30 +03:00
} ;
2008-07-03 13:24:45 +04:00
2008-12-11 04:36:30 +03:00
/* Register values to detect the OMAP version */
static struct omap_id omap_ids [ ] __initdata = {
{ . hawkeye = 0xb5d9 , . dev = 0x0 , . type = 0x24200024 } ,
{ . hawkeye = 0xb5d9 , . dev = 0x1 , . type = 0x24201024 } ,
{ . hawkeye = 0xb5d9 , . dev = 0x2 , . type = 0x24202024 } ,
{ . hawkeye = 0xb5d9 , . dev = 0x4 , . type = 0x24220024 } ,
{ . hawkeye = 0xb5d9 , . dev = 0x8 , . type = 0x24230024 } ,
{ . hawkeye = 0xb68a , . dev = 0x0 , . type = 0x24300024 } ,
} ;
2008-07-03 13:24:45 +04:00
2008-12-11 04:36:30 +03:00
static void __iomem * tap_base ;
static u16 tap_prod_id ;
2005-11-10 17:26:51 +03:00
2010-08-02 15:21:41 +04:00
void omap_get_die_id ( struct omap_die_id * odi )
{
2011-03-13 01:50:54 +03:00
if ( cpu_is_omap44xx ( ) ) {
odi - > id_0 = read_tap_reg ( OMAP_TAP_DIE_ID_44XX_0 ) ;
odi - > id_1 = read_tap_reg ( OMAP_TAP_DIE_ID_44XX_1 ) ;
odi - > id_2 = read_tap_reg ( OMAP_TAP_DIE_ID_44XX_2 ) ;
odi - > id_3 = read_tap_reg ( OMAP_TAP_DIE_ID_44XX_3 ) ;
return ;
}
2010-08-02 15:21:41 +04:00
odi - > id_0 = read_tap_reg ( OMAP_TAP_DIE_ID_0 ) ;
odi - > id_1 = read_tap_reg ( OMAP_TAP_DIE_ID_1 ) ;
odi - > id_2 = read_tap_reg ( OMAP_TAP_DIE_ID_2 ) ;
odi - > id_3 = read_tap_reg ( OMAP_TAP_DIE_ID_3 ) ;
}
2011-12-19 14:20:15 +04:00
void __init omap2xxx_check_revision ( void )
2005-11-10 17:26:51 +03:00
{
int i , j ;
2008-12-11 04:36:30 +03:00
u32 idcode , prod_id ;
2005-11-10 17:26:51 +03:00
u16 hawkeye ;
2008-12-11 04:36:30 +03:00
u8 dev_type , rev ;
2010-08-02 15:21:41 +04:00
struct omap_die_id odi ;
2005-11-10 17:26:51 +03:00
idcode = read_tap_reg ( OMAP_TAP_IDCODE ) ;
2008-10-06 16:49:16 +04:00
prod_id = read_tap_reg ( tap_prod_id ) ;
2005-11-10 17:26:51 +03:00
hawkeye = ( idcode > > 12 ) & 0xffff ;
rev = ( idcode > > 28 ) & 0x0f ;
dev_type = ( prod_id > > 16 ) & 0x0f ;
2010-08-02 15:21:41 +04:00
omap_get_die_id ( & odi ) ;
2005-11-10 17:26:51 +03:00
2008-07-03 13:24:45 +04:00
pr_debug ( " OMAP_TAP_IDCODE 0x%08x REV %i HAWKEYE 0x%04x MANF %03x \n " ,
idcode , rev , hawkeye , ( idcode > > 1 ) & 0x7ff ) ;
2010-08-02 15:21:41 +04:00
pr_debug ( " OMAP_TAP_DIE_ID_0: 0x%08x \n " , odi . id_0 ) ;
2008-07-03 13:24:45 +04:00
pr_debug ( " OMAP_TAP_DIE_ID_1: 0x%08x DEV_REV: %i \n " ,
2010-08-02 15:21:41 +04:00
odi . id_1 , ( odi . id_1 > > 28 ) & 0xf ) ;
pr_debug ( " OMAP_TAP_DIE_ID_2: 0x%08x \n " , odi . id_2 ) ;
pr_debug ( " OMAP_TAP_DIE_ID_3: 0x%08x \n " , odi . id_3 ) ;
2008-07-03 13:24:45 +04:00
pr_debug ( " OMAP_TAP_PROD_ID_0: 0x%08x DEV_TYPE: %i \n " ,
prod_id , dev_type ) ;
2005-11-10 17:26:51 +03:00
/* 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 ;
}
2008-12-11 04:36:31 +03:00
pr_info ( " OMAP%04x " , omap_rev ( ) > > 16 ) ;
if ( ( omap_rev ( ) > > 8 ) & 0x0f )
pr_info ( " ES%x " , ( omap_rev ( ) > > 12 ) & 0xf ) ;
2008-07-03 13:24:45 +04:00
pr_info ( " \n " ) ;
2008-12-11 04:36:30 +03:00
}
2011-12-19 14:20:14 +04:00
# define OMAP3_SHOW_FEATURE(feat) \
if ( omap3_has_ # # feat ( ) ) \
printk ( # feat " " ) ;
static void __init omap3_cpuinfo ( void )
{
const char * cpu_name ;
/*
* OMAP3430 and OMAP3530 are assumed to be same .
*
* OMAP3525 , OMAP3515 and OMAP3503 can be detected only based
* on available features . Upon detection , update the CPU id
* and CPU class bits .
*/
if ( cpu_is_omap3630 ( ) ) {
cpu_name = " OMAP3630 " ;
2012-05-01 03:37:10 +04:00
} else if ( soc_is_am35xx ( ) ) {
2011-12-19 14:20:14 +04:00
cpu_name = ( omap3_has_sgx ( ) ) ? " AM3517 " : " AM3505 " ;
} else if ( cpu_is_ti816x ( ) ) {
cpu_name = " TI816X " ;
} else if ( cpu_is_am335x ( ) ) {
cpu_name = " AM335X " ;
} else if ( cpu_is_ti814x ( ) ) {
cpu_name = " TI814X " ;
} else if ( omap3_has_iva ( ) & & omap3_has_sgx ( ) ) {
/* OMAP3430, OMAP3525, OMAP3515, OMAP3503 devices */
cpu_name = " OMAP3430/3530 " ;
} else if ( omap3_has_iva ( ) ) {
cpu_name = " OMAP3525 " ;
} else if ( omap3_has_sgx ( ) ) {
cpu_name = " OMAP3515 " ;
} else {
cpu_name = " OMAP3503 " ;
}
/* Print verbose information */
pr_info ( " %s ES%s ( " , cpu_name , cpu_rev ) ;
OMAP3_SHOW_FEATURE ( l2cache ) ;
OMAP3_SHOW_FEATURE ( iva ) ;
OMAP3_SHOW_FEATURE ( sgx ) ;
OMAP3_SHOW_FEATURE ( neon ) ;
OMAP3_SHOW_FEATURE ( isp ) ;
OMAP3_SHOW_FEATURE ( 192 mhz_clk ) ;
printk ( " ) \n " ) ;
}
2009-11-22 21:10:53 +03:00
# define OMAP3_CHECK_FEATURE(status,feat) \
if ( ( ( status & OMAP3_ # # feat # # _MASK ) \
> > OMAP3_ # # feat # # _SHIFT ) ! = FEAT_ # # feat # # _NONE ) { \
2011-07-02 06:30:22 +04:00
omap_features | = OMAP3_HAS_ # # feat ; \
2009-11-22 21:10:53 +03:00
}
2011-12-19 14:20:15 +04:00
void __init omap3xxx_check_features ( void )
2009-11-22 21:10:53 +03:00
{
u32 status ;
2011-07-02 06:30:22 +04:00
omap_features = 0 ;
2009-11-22 21:10:53 +03:00
status = omap_ctrl_readl ( OMAP3_CONTROL_OMAP_STATUS ) ;
OMAP3_CHECK_FEATURE ( status , L2CACHE ) ;
OMAP3_CHECK_FEATURE ( status , IVA ) ;
OMAP3_CHECK_FEATURE ( status , SGX ) ;
OMAP3_CHECK_FEATURE ( status , NEON ) ;
OMAP3_CHECK_FEATURE ( status , ISP ) ;
2010-02-23 08:09:10 +03:00
if ( cpu_is_omap3630 ( ) )
2011-07-02 06:30:22 +04:00
omap_features | = OMAP3_HAS_192MHZ_CLK ;
ARM: OMAP3: PM: fix I/O wakeup and I/O chain clock control detection
The way that we detect which OMAP3 chips support I/O wakeup and
software I/O chain clock control is broken.
Currently, I/O wakeup is marked as present for all OMAP3 SoCs other
than the AM3505/3517. The TI81xx family of SoCs are at present
considered to be OMAP3 SoCs, but don't support I/O wakeup. To resolve
this, convert the existing blacklist approach to an explicit,
whitelist support, in which only SoCs which are known to support I/O
wakeup are listed. (At present, this only includes OMAP34xx,
OMAP3503, OMAP3515, OMAP3525, OMAP3530, and OMAP36xx.)
Also, the current code incorrectly detects the presence of a
software-controllable I/O chain clock on several chips that don't
support it. This results in writes to reserved bitfields, unnecessary
delays, and console messages on kernels running on those chips:
http://www.spinics.net/lists/linux-omap/msg58735.html
Convert this test to a feature test with a chip-by-chip whitelist.
Thanks to Dave Hylands <dhylands@gmail.com> for reporting this problem
and doing some testing to help isolate the cause. Thanks to Steve
Sakoman <sakoman@gmail.com> for catching a bug in the first version of
this patch. Thanks to Russell King <linux@arm.linux.org.uk> for
comments.
Signed-off-by: Paul Walmsley <paul@pwsan.com>
Cc: Dave Hylands <dhylands@gmail.com>
Cc: Steve Sakoman <sakoman@gmail.com>
Tested-by: Steve Sakoman <sakoman@gmail.com>
Cc: Russell King - ARM Linux <linux@arm.linux.org.uk>
Signed-off-by: Kevin Hilman <khilman@ti.com>
2011-10-07 03:18:45 +04:00
if ( cpu_is_omap3430 ( ) | | cpu_is_omap3630 ( ) )
2011-07-02 06:30:22 +04:00
omap_features | = OMAP3_HAS_IO_WAKEUP ;
ARM: OMAP3: PM: fix I/O wakeup and I/O chain clock control detection
The way that we detect which OMAP3 chips support I/O wakeup and
software I/O chain clock control is broken.
Currently, I/O wakeup is marked as present for all OMAP3 SoCs other
than the AM3505/3517. The TI81xx family of SoCs are at present
considered to be OMAP3 SoCs, but don't support I/O wakeup. To resolve
this, convert the existing blacklist approach to an explicit,
whitelist support, in which only SoCs which are known to support I/O
wakeup are listed. (At present, this only includes OMAP34xx,
OMAP3503, OMAP3515, OMAP3525, OMAP3530, and OMAP36xx.)
Also, the current code incorrectly detects the presence of a
software-controllable I/O chain clock on several chips that don't
support it. This results in writes to reserved bitfields, unnecessary
delays, and console messages on kernels running on those chips:
http://www.spinics.net/lists/linux-omap/msg58735.html
Convert this test to a feature test with a chip-by-chip whitelist.
Thanks to Dave Hylands <dhylands@gmail.com> for reporting this problem
and doing some testing to help isolate the cause. Thanks to Steve
Sakoman <sakoman@gmail.com> for catching a bug in the first version of
this patch. Thanks to Russell King <linux@arm.linux.org.uk> for
comments.
Signed-off-by: Paul Walmsley <paul@pwsan.com>
Cc: Dave Hylands <dhylands@gmail.com>
Cc: Steve Sakoman <sakoman@gmail.com>
Tested-by: Steve Sakoman <sakoman@gmail.com>
Cc: Russell King - ARM Linux <linux@arm.linux.org.uk>
Signed-off-by: Kevin Hilman <khilman@ti.com>
2011-10-07 03:18:45 +04:00
if ( cpu_is_omap3630 ( ) | | omap_rev ( ) = = OMAP3430_REV_ES3_1 | |
omap_rev ( ) = = OMAP3430_REV_ES3_1_2 )
omap_features | = OMAP3_HAS_IO_CHAIN_CTRL ;
2009-11-22 21:10:53 +03:00
2011-07-02 06:30:22 +04:00
omap_features | = OMAP3_HAS_SDRC ;
2011-02-16 19:31:39 +03:00
2009-11-22 21:10:53 +03:00
/*
* TODO : Get additional info ( where applicable )
* e . g . Size of L2 cache .
*/
2011-12-19 14:20:15 +04:00
omap3_cpuinfo ( ) ;
2009-11-22 21:10:53 +03:00
}
2011-12-19 14:20:15 +04:00
void __init omap4xxx_check_features ( void )
2011-07-02 06:30:22 +04:00
{
u32 si_type ;
if ( cpu_is_omap443x ( ) )
omap_features | = OMAP4_HAS_MPU_1GHZ ;
if ( cpu_is_omap446x ( ) ) {
si_type =
read_tap_reg ( OMAP4_CTRL_MODULE_CORE_STD_FUSE_PROD_ID_1 ) ;
switch ( ( si_type & ( 3 < < 16 ) ) > > 16 ) {
case 2 :
/* High performance device */
omap_features | = OMAP4_HAS_MPU_1_5GHZ ;
break ;
case 1 :
default :
/* Standard device */
omap_features | = OMAP4_HAS_MPU_1_2GHZ ;
break ;
}
}
}
2011-12-19 14:20:15 +04:00
void __init ti81xx_check_features ( void )
2011-02-16 19:31:39 +03:00
{
2011-07-02 06:30:22 +04:00
omap_features = OMAP3_HAS_NEON ;
2011-12-19 14:20:15 +04:00
omap3_cpuinfo ( ) ;
2011-02-16 19:31:39 +03:00
}
2011-12-19 14:20:15 +04:00
void __init omap3xxx_check_revision ( void )
2008-12-11 04:36:30 +03:00
{
u32 cpuid , idcode ;
u16 hawkeye ;
u8 rev ;
/*
* We cannot access revision registers on ES1 .0 .
* If the processor type is Cortex - A8 and the revision is 0x0
* it means its Cortex r0p0 which is 3430 ES1 .0 .
*/
cpuid = read_cpuid ( CPUID_ID ) ;
if ( ( ( ( cpuid > > 4 ) & 0xfff ) = = 0xc08 ) & & ( ( cpuid & 0xf ) = = 0x0 ) ) {
2008-12-11 04:36:31 +03:00
omap_revision = OMAP3430_REV_ES1_0 ;
2011-12-19 14:20:14 +04:00
cpu_rev = " 1.0 " ;
2009-11-22 21:10:54 +03:00
return ;
2008-12-11 04:36:30 +03:00
}
/*
* Detection for 34 xx ES2 .0 and above can be done with just
* hawkeye and rev . See TRM 1.5 .2 Device Identification .
* Note that rev does not map directly to our defined processor
* revision numbers as ES1 .0 uses value 0.
*/
idcode = read_tap_reg ( OMAP_TAP_IDCODE ) ;
hawkeye = ( idcode > > 12 ) & 0xffff ;
rev = ( idcode > > 28 ) & 0xff ;
2008-07-03 13:24:45 +04:00
2009-11-22 21:10:56 +03:00
switch ( hawkeye ) {
case 0xb7ae :
/* Handle 34xx/35xx devices */
2008-12-11 04:36:30 +03:00
switch ( rev ) {
2009-11-22 21:10:54 +03:00
case 0 : /* Take care of early samples */
case 1 :
2008-12-11 04:36:31 +03:00
omap_revision = OMAP3430_REV_ES2_0 ;
2011-12-19 14:20:14 +04:00
cpu_rev = " 2.0 " ;
2008-12-11 04:36:30 +03:00
break ;
case 2 :
2008-12-11 04:36:31 +03:00
omap_revision = OMAP3430_REV_ES2_1 ;
2011-12-19 14:20:14 +04:00
cpu_rev = " 2.1 " ;
2008-12-11 04:36:30 +03:00
break ;
case 3 :
2008-12-11 04:36:31 +03:00
omap_revision = OMAP3430_REV_ES3_0 ;
2011-12-19 14:20:14 +04:00
cpu_rev = " 3.0 " ;
2008-12-11 04:36:30 +03:00
break ;
2009-01-29 19:57:16 +03:00
case 4 :
2010-01-20 02:40:26 +03:00
omap_revision = OMAP3430_REV_ES3_1 ;
2011-12-19 14:20:14 +04:00
cpu_rev = " 3.1 " ;
2010-01-20 02:40:26 +03:00
break ;
case 7 :
2009-11-22 21:11:24 +03:00
/* FALLTHROUGH */
2008-12-11 04:36:30 +03:00
default :
/* Use the latest known revision as default */
2010-01-20 02:40:26 +03:00
omap_revision = OMAP3430_REV_ES3_1_2 ;
2011-12-19 14:20:14 +04:00
cpu_rev = " 3.1.2 " ;
2008-12-11 04:36:30 +03:00
}
2009-11-22 21:10:56 +03:00
break ;
2009-11-22 21:10:58 +03:00
case 0xb868 :
2011-09-14 05:52:13 +04:00
/*
* Handle OMAP / AM 3505 / 3517 devices
2009-11-22 21:10:58 +03:00
*
2011-09-14 05:52:13 +04:00
* Set the device to be OMAP3517 here . Actual device
2009-11-22 21:10:58 +03:00
* is identified later based on the features .
*/
2011-09-14 05:52:14 +04:00
switch ( rev ) {
case 0 :
2012-05-01 03:37:10 +04:00
omap_revision = AM35XX_REV_ES1_0 ;
2011-12-19 14:20:14 +04:00
cpu_rev = " 1.0 " ;
2011-09-14 05:52:14 +04:00
break ;
case 1 :
/* FALLTHROUGH */
default :
2012-05-01 03:37:10 +04:00
omap_revision = AM35XX_REV_ES1_1 ;
2011-12-19 14:20:14 +04:00
cpu_rev = " 1.1 " ;
2011-09-14 05:52:14 +04:00
}
2009-11-22 21:10:58 +03:00
break ;
2009-11-22 21:11:24 +03:00
case 0xb891 :
2010-08-03 23:59:24 +04:00
/* Handle 36xx devices */
switch ( rev ) {
case 0 : /* Take care of early samples */
omap_revision = OMAP3630_REV_ES1_0 ;
2011-12-19 14:20:14 +04:00
cpu_rev = " 1.0 " ;
2010-08-03 23:59:24 +04:00
break ;
case 1 :
omap_revision = OMAP3630_REV_ES1_1 ;
2011-12-19 14:20:14 +04:00
cpu_rev = " 1.1 " ;
2010-08-03 23:59:24 +04:00
break ;
case 2 :
2011-09-14 05:52:15 +04:00
/* FALLTHROUGH */
2010-08-03 23:59:24 +04:00
default :
2011-09-14 05:52:15 +04:00
omap_revision = OMAP3630_REV_ES1_2 ;
2011-12-19 14:20:14 +04:00
cpu_rev = " 1.2 " ;
2010-08-03 23:59:24 +04:00
}
2010-08-16 10:21:19 +04:00
break ;
2011-02-16 19:31:39 +03:00
case 0xb81e :
switch ( rev ) {
case 0 :
omap_revision = TI8168_REV_ES1_0 ;
2011-12-19 14:20:14 +04:00
cpu_rev = " 1.0 " ;
2011-02-16 19:31:39 +03:00
break ;
case 1 :
2011-09-14 05:52:15 +04:00
/* FALLTHROUGH */
2011-02-16 19:31:39 +03:00
default :
2011-09-14 05:52:15 +04:00
omap_revision = TI8168_REV_ES1_1 ;
2011-12-19 14:20:14 +04:00
cpu_rev = " 1.1 " ;
2011-09-14 05:52:15 +04:00
break ;
2011-02-16 19:31:39 +03:00
}
break ;
2011-12-13 22:46:43 +04:00
case 0xb944 :
omap_revision = AM335X_REV_ES1_0 ;
2011-12-19 14:20:14 +04:00
cpu_rev = " 1.0 " ;
2012-01-23 11:56:47 +04:00
break ;
2011-12-13 22:46:45 +04:00
case 0xb8f2 :
switch ( rev ) {
case 0 :
/* FALLTHROUGH */
case 1 :
omap_revision = TI8148_REV_ES1_0 ;
2011-12-19 14:20:14 +04:00
cpu_rev = " 1.0 " ;
2011-12-13 22:46:45 +04:00
break ;
case 2 :
omap_revision = TI8148_REV_ES2_0 ;
2011-12-19 14:20:14 +04:00
cpu_rev = " 2.0 " ;
2011-12-13 22:46:45 +04:00
break ;
case 3 :
/* FALLTHROUGH */
default :
omap_revision = TI8148_REV_ES2_1 ;
2011-12-19 14:20:14 +04:00
cpu_rev = " 2.1 " ;
2011-12-13 22:46:45 +04:00
break ;
}
2011-12-13 22:46:43 +04:00
break ;
2009-11-22 21:10:56 +03:00
default :
2011-09-14 05:52:15 +04:00
/* Unknown default to latest silicon rev as default */
2011-09-14 05:52:15 +04:00
omap_revision = OMAP3630_REV_ES1_2 ;
2011-12-19 14:20:14 +04:00
cpu_rev = " 1.2 " ;
2011-09-14 05:52:15 +04:00
pr_warn ( " Warning: unknown chip type; assuming OMAP3630ES1.2 \n " ) ;
2008-12-11 04:36:30 +03:00
}
2005-11-10 17:26:51 +03:00
}
2011-12-19 14:20:15 +04:00
void __init omap4xxx_check_revision ( void )
2009-12-12 03:16:34 +03:00
{
u32 idcode ;
u16 hawkeye ;
u8 rev ;
/*
* The IC rev detection is done with hawkeye and rev .
* Note that rev does not map directly to defined processor
* revision numbers as ES1 .0 uses value 0.
*/
idcode = read_tap_reg ( OMAP_TAP_IDCODE ) ;
hawkeye = ( idcode > > 12 ) & 0xffff ;
2011-02-17 20:55:03 +03:00
rev = ( idcode > > 28 ) & 0xf ;
2009-12-12 03:16:34 +03:00
2010-09-16 17:14:46 +04:00
/*
2011-07-02 06:30:21 +04:00
* Few initial 4430 ES2 .0 samples IDCODE is same as ES1 .0
2010-09-16 17:14:46 +04:00
* Use ARM register to detect the correct ES version
*/
2011-12-13 22:46:44 +04:00
if ( ! rev & & ( hawkeye ! = 0xb94e ) & & ( hawkeye ! = 0xb975 ) ) {
2010-09-16 17:14:46 +04:00
idcode = read_cpuid ( CPUID_ID ) ;
rev = ( idcode & 0xf ) - 1 ;
}
switch ( hawkeye ) {
case 0xb852 :
switch ( rev ) {
case 0 :
omap_revision = OMAP4430_REV_ES1_0 ;
break ;
case 1 :
2011-02-17 20:55:03 +03:00
default :
2010-09-16 17:14:46 +04:00
omap_revision = OMAP4430_REV_ES2_0 ;
2011-02-17 20:55:03 +03:00
}
break ;
case 0xb95c :
switch ( rev ) {
case 3 :
omap_revision = OMAP4430_REV_ES2_1 ;
2010-09-16 17:14:46 +04:00
break ;
2011-02-17 20:55:03 +03:00
case 4 :
omap_revision = OMAP4430_REV_ES2_2 ;
2011-12-13 22:46:44 +04:00
break ;
case 6 :
default :
omap_revision = OMAP4430_REV_ES2_3 ;
2011-02-17 20:55:03 +03:00
}
break ;
2011-07-02 06:30:21 +04:00
case 0xb94e :
switch ( rev ) {
case 0 :
omap_revision = OMAP4460_REV_ES1_0 ;
break ;
2012-05-09 20:45:02 +04:00
case 2 :
default :
omap_revision = OMAP4460_REV_ES1_1 ;
break ;
2011-07-02 06:30:21 +04:00
}
break ;
2011-12-13 22:46:44 +04:00
case 0xb975 :
switch ( rev ) {
case 0 :
default :
omap_revision = OMAP4470_REV_ES1_0 ;
break ;
}
break ;
2010-09-16 17:14:46 +04:00
default :
2011-02-17 20:55:03 +03:00
/* Unknown default to latest silicon rev as default */
2011-12-13 22:46:44 +04:00
omap_revision = OMAP4430_REV_ES2_3 ;
2009-12-12 03:16:34 +03:00
}
2011-02-17 20:55:03 +03:00
pr_info ( " OMAP%04x ES%d.%d \n " , omap_rev ( ) > > 16 ,
( ( omap_rev ( ) > > 12 ) & 0xf ) , ( ( omap_rev ( ) > > 8 ) & 0xf ) ) ;
2009-12-12 03:16:34 +03:00
}
2008-12-11 04:36:30 +03:00
/*
* Set up things for map_io and processor detection later on . Gets called
* pretty much first thing from board init . For multi - omap , this gets
* cpu_is_omapxxxx ( ) working accurately enough for map_io . Then we ' ll try to
* detect the exact revision later on in omap2_detect_revision ( ) once map_io
* is done .
*/
2008-10-06 16:49:16 +04:00
void __init omap2_set_globals_tap ( struct omap_globals * omap2_globals )
{
2008-12-11 04:36:31 +03:00
omap_revision = omap2_globals - > class ;
2008-10-06 16:49:16 +04:00
tap_base = omap2_globals - > tap ;
2008-12-11 04:36:30 +03:00
if ( cpu_is_omap34xx ( ) )
2008-10-06 16:49:16 +04:00
tap_prod_id = 0x0210 ;
else
tap_prod_id = 0x0208 ;
}