2019-06-04 10:11:33 +02:00
// SPDX-License-Identifier: GPL-2.0-only
2005-11-10 14:26:51 +00: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 09:55:03 -08:00
* Copyright ( C ) 2009 - 11 Texas Instruments
2009-05-28 14:16:04 -07:00
* Added OMAP4 support - Santosh Shilimkar < santosh . shilimkar @ ti . com >
2005-11-10 14:26:51 +00:00
*/
# include <linux/module.h>
# include <linux/kernel.h>
# include <linux/init.h>
2008-09-06 12:10:45 +01:00
# include <linux/io.h>
2013-09-05 09:29:18 +02:00
# include <linux/random.h>
2013-02-14 13:55:24 +02:00
# include <linux/slab.h>
# ifdef CONFIG_SOC_BUS
# include <linux/sys_soc.h>
# endif
2005-11-10 14:26:51 +00:00
2008-08-10 18:08:10 +01:00
# include <asm/cputype.h>
2005-11-10 14:26:51 +00:00
2011-11-10 22:45:17 +01:00
# include "common.h"
2006-12-06 17:14:05 -08:00
2012-09-19 10:33:40 -07:00
# include "id.h"
2010-08-02 14:21:41 +03:00
2012-08-31 10:59:07 -07:00
# include "soc.h"
2010-10-08 11:40:20 -06:00
# include "control.h"
2012-11-14 12:10:37 -08:00
# define OMAP4_SILICON_TYPE_STANDARD 0x01
# define OMAP4_SILICON_TYPE_PERFORMANCE 0x02
2013-02-14 13:55:23 +02:00
# define OMAP_SOC_MAX_NAME_LENGTH 16
2008-12-10 17:36:31 -08:00
static unsigned int omap_revision ;
2013-02-14 13:55:23 +02:00
static char soc_name [ OMAP_SOC_MAX_NAME_LENGTH ] ;
static char soc_rev [ OMAP_SOC_MAX_NAME_LENGTH ] ;
2011-07-02 08:00:22 +05:30
u32 omap_features ;
2008-12-10 17:36:31 -08:00
unsigned int omap_rev ( void )
{
return omap_revision ;
}
EXPORT_SYMBOL ( omap_rev ) ;
2008-07-03 12:24:45 +03:00
2009-06-23 13:30:23 +03:00
int omap_type ( void )
{
2015-02-09 16:17:38 +02:00
static u32 val = OMAP2_DEVICETYPE_MASK ;
if ( val < OMAP2_DEVICETYPE_MASK )
return val ;
2009-06-23 13:30:23 +03:00
2015-10-14 11:13:08 +05:30
if ( soc_is_omap24xx ( ) ) {
2009-06-23 13:30:23 +03:00
val = omap_ctrl_readl ( OMAP24XX_CONTROL_STATUS ) ;
2015-10-14 11:13:08 +05:30
} else if ( soc_is_ti81xx ( ) ) {
2015-01-14 17:37:15 -08:00
val = omap_ctrl_readl ( TI81XX_CONTROL_STATUS ) ;
2013-05-27 20:06:33 +05:30
} else if ( soc_is_am33xx ( ) | | soc_is_am43xx ( ) ) {
2012-03-05 16:11:01 -08:00
val = omap_ctrl_readl ( AM33XX_CONTROL_STATUS ) ;
2015-10-14 11:13:08 +05:30
} else if ( soc_is_omap34xx ( ) ) {
2009-06-23 13:30:23 +03:00
val = omap_ctrl_readl ( OMAP343X_CONTROL_STATUS ) ;
2015-10-14 11:13:08 +05:30
} else if ( soc_is_omap44xx ( ) ) {
2010-09-27 14:02:58 -06:00
val = omap_ctrl_readl ( OMAP4_CTRL_MODULE_CORE_STATUS ) ;
2013-02-06 20:25:40 +05:30
} else if ( soc_is_omap54xx ( ) | | soc_is_dra7xx ( ) ) {
2012-04-19 17:42:19 +05:30
val = omap_ctrl_readl ( OMAP5XXX_CONTROL_STATUS ) ;
val & = OMAP5_DEVICETYPE_MASK ;
val > > = 6 ;
goto out ;
2009-11-22 10:11:24 -08:00
} else {
2009-06-23 13:30:23 +03: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-10 17:36:30 -08:00
/*----------------------------------------------------------------------------*/
2008-07-03 12:24:45 +03:00
2008-12-10 17:36:30 -08: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 12:24:45 +03:00
2011-03-12 22:50:54 +00: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
2014-04-15 20:37:46 +03:00
# define read_tap_reg(reg) readl_relaxed(tap_base + (reg))
2008-07-03 12:24:45 +03:00
2008-12-10 17:36:30 -08:00
struct omap_id {
u16 hawkeye ; /* Silicon type (Hawkeye id) */
u8 dev ; /* Device type from production_id reg */
2008-12-10 17:36:31 -08:00
u32 type ; /* Combined type id copied to omap_revision */
2008-12-10 17:36:30 -08:00
} ;
2008-07-03 12:24:45 +03:00
2008-12-10 17:36:30 -08: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 12:24:45 +03:00
2008-12-10 17:36:30 -08:00
static void __iomem * tap_base ;
static u16 tap_prod_id ;
2005-11-10 14:26:51 +00:00
2010-08-02 14:21:41 +03:00
void omap_get_die_id ( struct omap_die_id * odi )
{
2015-10-14 11:13:08 +05:30
if ( soc_is_omap44xx ( ) | | soc_is_omap54xx ( ) | | soc_is_dra7xx ( ) ) {
2011-03-12 22:50:54 +00:00
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 14:21:41 +03: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 ) ;
}
2013-09-05 09:29:18 +02:00
static int __init omap_feed_randpool ( void )
{
struct omap_die_id odi ;
/* Throw the die ID into the entropy pool at boot */
omap_get_die_id ( & odi ) ;
add_device_randomness ( & odi , sizeof ( odi ) ) ;
return 0 ;
}
omap_device_initcall ( omap_feed_randpool ) ;
2011-12-19 15:50:15 +05:30
void __init omap2xxx_check_revision ( void )
2005-11-10 14:26:51 +00:00
{
int i , j ;
2008-12-10 17:36:30 -08:00
u32 idcode , prod_id ;
2005-11-10 14:26:51 +00:00
u16 hawkeye ;
2008-12-10 17:36:30 -08:00
u8 dev_type , rev ;
2010-08-02 14:21:41 +03:00
struct omap_die_id odi ;
2005-11-10 14:26:51 +00:00
idcode = read_tap_reg ( OMAP_TAP_IDCODE ) ;
2008-10-06 15:49:16 +03:00
prod_id = read_tap_reg ( tap_prod_id ) ;
2005-11-10 14:26:51 +00:00
hawkeye = ( idcode > > 12 ) & 0xffff ;
rev = ( idcode > > 28 ) & 0x0f ;
dev_type = ( prod_id > > 16 ) & 0x0f ;
2010-08-02 14:21:41 +03:00
omap_get_die_id ( & odi ) ;
2005-11-10 14:26:51 +00:00
2008-07-03 12:24:45 +03: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 14:21:41 +03:00
pr_debug ( " OMAP_TAP_DIE_ID_0: 0x%08x \n " , odi . id_0 ) ;
2008-07-03 12:24:45 +03:00
pr_debug ( " OMAP_TAP_DIE_ID_1: 0x%08x DEV_REV: %i \n " ,
2010-08-02 14:21:41 +03: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 12:24:45 +03:00
pr_debug ( " OMAP_TAP_PROD_ID_0: 0x%08x DEV_TYPE: %i \n " ,
prod_id , dev_type ) ;
2005-11-10 14:26:51 +00: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 ) ) {
2012-07-26 00:54:26 -06:00
pr_err ( " Unknown OMAP device type. Handling it as OMAP%04x \n " ,
omap_ids [ i ] . type > > 16 ) ;
2005-11-10 14:26:51 +00:00
j = i ;
}
2013-02-14 13:55:23 +02:00
sprintf ( soc_name , " OMAP%04x " , omap_rev ( ) > > 16 ) ;
sprintf ( soc_rev , " ES%x " , ( omap_rev ( ) > > 12 ) & 0xf ) ;
pr_info ( " %s " , soc_name ) ;
2008-12-10 17:36:31 -08:00
if ( ( omap_rev ( ) > > 8 ) & 0x0f )
2018-11-19 21:46:41 +02:00
pr_cont ( " %s " , soc_rev ) ;
pr_cont ( " \n " ) ;
2008-12-10 17:36:30 -08:00
}
2011-12-19 15:50:14 +05:30
# define OMAP3_SHOW_FEATURE(feat) \
if ( omap3_has_ # # feat ( ) ) \
2016-11-07 14:52:39 -07:00
n + = scnprintf ( buf + n , sizeof ( buf ) - n , # feat " " ) ;
2011-12-19 15:50:14 +05:30
static void __init omap3_cpuinfo ( void )
{
const char * cpu_name ;
2016-11-07 14:52:39 -07:00
char buf [ 64 ] ;
int n = 0 ;
memset ( buf , 0 , sizeof ( buf ) ) ;
2011-12-19 15:50:14 +05:30
/*
* 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 .
*/
2015-10-14 11:13:08 +05:30
if ( soc_is_omap3630 ( ) ) {
2017-01-20 10:44:01 -06:00
if ( omap3_has_iva ( ) & & omap3_has_sgx ( ) ) {
cpu_name = ( omap3_has_isp ( ) ) ? " OMAP3630/DM3730 " : " OMAP3621 " ;
} else if ( omap3_has_iva ( ) ) {
cpu_name = " DM3725 " ;
} else if ( omap3_has_sgx ( ) ) {
cpu_name = " OMAP3615/AM3715 " ;
} else {
cpu_name = ( omap3_has_isp ( ) ) ? " AM3703 " : " OMAP3611 " ;
}
2012-04-30 16:37:10 -07:00
} else if ( soc_is_am35xx ( ) ) {
2011-12-19 15:50:14 +05:30
cpu_name = ( omap3_has_sgx ( ) ) ? " AM3517 " : " AM3505 " ;
2015-10-14 11:13:08 +05:30
} else if ( soc_is_ti816x ( ) ) {
2011-12-19 15:50:14 +05:30
cpu_name = " TI816X " ;
2012-07-05 08:05:15 -07:00
} else if ( soc_is_am335x ( ) ) {
2011-12-19 15:50:14 +05:30
cpu_name = " AM335X " ;
2013-05-27 20:06:01 +05:30
} else if ( soc_is_am437x ( ) ) {
cpu_name = " AM437x " ;
2015-10-14 11:13:08 +05:30
} else if ( soc_is_ti814x ( ) ) {
2011-12-19 15:50:14 +05:30
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 " ;
}
2016-11-07 14:52:39 -07:00
scnprintf ( soc_name , sizeof ( soc_name ) , " %s " , cpu_name ) ;
2013-02-14 13:55:23 +02:00
2011-12-19 15:50:14 +05:30
/* Print verbose information */
2016-11-07 14:52:39 -07:00
n + = scnprintf ( buf , sizeof ( buf ) - n , " %s %s ( " , soc_name , soc_rev ) ;
2011-12-19 15:50:14 +05:30
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 ) ;
2016-11-07 14:52:39 -07:00
if ( * ( buf + n - 1 ) = = ' ' )
n - - ;
n + = scnprintf ( buf + n , sizeof ( buf ) - n , " ) \n " ) ;
pr_info ( " %s " , buf ) ;
2011-12-19 15:50:14 +05:30
}
2009-11-22 10:10:53 -08:00
# define OMAP3_CHECK_FEATURE(status,feat) \
if ( ( ( status & OMAP3_ # # feat # # _MASK ) \
> > OMAP3_ # # feat # # _SHIFT ) ! = FEAT_ # # feat # # _NONE ) { \
2011-07-02 08:00:22 +05:30
omap_features | = OMAP3_HAS_ # # feat ; \
2009-11-22 10:10:53 -08:00
}
2011-12-19 15:50:15 +05:30
void __init omap3xxx_check_features ( void )
2009-11-22 10:10:53 -08:00
{
u32 status ;
2011-07-02 08:00:22 +05:30
omap_features = 0 ;
2009-11-22 10:10:53 -08: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 ) ;
2015-10-14 11:13:08 +05:30
if ( soc_is_omap3630 ( ) )
2011-07-02 08:00:22 +05:30
omap_features | = OMAP3_HAS_192MHZ_CLK ;
2015-10-14 11:13:08 +05:30
if ( soc_is_omap3430 ( ) | | soc_is_omap3630 ( ) )
2011-07-02 08:00:22 +05:30
omap_features | = OMAP3_HAS_IO_WAKEUP ;
2015-10-14 11:13:08 +05:30
if ( soc_is_omap3630 ( ) | | omap_rev ( ) = = OMAP3430_REV_ES3_1 | |
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-06 17:18:45 -06:00
omap_rev ( ) = = OMAP3430_REV_ES3_1_2 )
omap_features | = OMAP3_HAS_IO_CHAIN_CTRL ;
2009-11-22 10:10:53 -08:00
2011-07-02 08:00:22 +05:30
omap_features | = OMAP3_HAS_SDRC ;
2011-02-16 08:31:39 -08:00
2012-04-30 16:57:09 -07:00
/*
* am35x fixups :
* - The am35x Chip ID register has bits 12 , 7 : 5 , and 3 : 2 marked as
* reserved and therefore return 0 when read . Unfortunately ,
* OMAP3_CHECK_FEATURE ( ) will interpret some of those zeroes to
* mean that a feature is present even though it isn ' t so clear
* the incorrectly set feature bits .
*/
if ( soc_is_am35xx ( ) )
omap_features & = ~ ( OMAP3_HAS_IVA | OMAP3_HAS_ISP ) ;
2009-11-22 10:10:53 -08:00
/*
* TODO : Get additional info ( where applicable )
* e . g . Size of L2 cache .
*/
2011-12-19 15:50:15 +05:30
omap3_cpuinfo ( ) ;
2009-11-22 10:10:53 -08:00
}
2011-12-19 15:50:15 +05:30
void __init omap4xxx_check_features ( void )
2011-07-02 08:00:22 +05:30
{
u32 si_type ;
2012-11-14 12:10:37 -08:00
si_type =
( read_tap_reg ( OMAP4_CTRL_MODULE_CORE_STD_FUSE_PROD_ID_1 ) > > 16 ) & 0x03 ;
2011-07-02 08:00:22 +05:30
2012-11-14 12:10:37 -08:00
if ( si_type = = OMAP4_SILICON_TYPE_PERFORMANCE )
omap_features = OMAP4_HAS_PERF_SILICON ;
2011-07-02 08:00:22 +05:30
}
2011-12-19 15:50:15 +05:30
void __init ti81xx_check_features ( void )
2011-02-16 08:31:39 -08:00
{
2011-07-02 08:00:22 +05:30
omap_features = OMAP3_HAS_NEON ;
2011-12-19 15:50:15 +05:30
omap3_cpuinfo ( ) ;
2011-02-16 08:31:39 -08:00
}
2013-05-17 15:43:41 +05:30
void __init am33xx_check_features ( void )
{
u32 status ;
omap_features = OMAP3_HAS_NEON ;
status = omap_ctrl_readl ( AM33XX_DEV_FEATURE ) ;
if ( status & AM33XX_SGX_MASK )
omap_features | = OMAP3_HAS_SGX ;
omap3_cpuinfo ( ) ;
}
2011-12-19 15:50:15 +05:30
void __init omap3xxx_check_revision ( void )
2008-12-10 17:36:30 -08:00
{
2013-02-14 13:55:23 +02:00
const char * cpu_rev ;
2008-12-10 17:36:30 -08: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 .
*/
2013-01-30 17:38:21 +01:00
cpuid = read_cpuid_id ( ) ;
2008-12-10 17:36:30 -08:00
if ( ( ( ( cpuid > > 4 ) & 0xfff ) = = 0xc08 ) & & ( ( cpuid & 0xf ) = = 0x0 ) ) {
2008-12-10 17:36:31 -08:00
omap_revision = OMAP3430_REV_ES1_0 ;
2011-12-19 15:50:14 +05:30
cpu_rev = " 1.0 " ;
2009-11-22 10:10:54 -08:00
return ;
2008-12-10 17:36:30 -08: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 12:24:45 +03:00
2009-11-22 10:10:56 -08:00
switch ( hawkeye ) {
case 0xb7ae :
/* Handle 34xx/35xx devices */
2008-12-10 17:36:30 -08:00
switch ( rev ) {
2009-11-22 10:10:54 -08:00
case 0 : /* Take care of early samples */
case 1 :
2008-12-10 17:36:31 -08:00
omap_revision = OMAP3430_REV_ES2_0 ;
2011-12-19 15:50:14 +05:30
cpu_rev = " 2.0 " ;
2008-12-10 17:36:30 -08:00
break ;
case 2 :
2008-12-10 17:36:31 -08:00
omap_revision = OMAP3430_REV_ES2_1 ;
2011-12-19 15:50:14 +05:30
cpu_rev = " 2.1 " ;
2008-12-10 17:36:30 -08:00
break ;
case 3 :
2008-12-10 17:36:31 -08:00
omap_revision = OMAP3430_REV_ES3_0 ;
2011-12-19 15:50:14 +05:30
cpu_rev = " 3.0 " ;
2008-12-10 17:36:30 -08:00
break ;
2009-01-29 08:57:16 -08:00
case 4 :
2010-01-19 15:40:26 -08:00
omap_revision = OMAP3430_REV_ES3_1 ;
2011-12-19 15:50:14 +05:30
cpu_rev = " 3.1 " ;
2010-01-19 15:40:26 -08:00
break ;
case 7 :
2009-11-22 10:11:24 -08:00
/* FALLTHROUGH */
2008-12-10 17:36:30 -08:00
default :
/* Use the latest known revision as default */
2010-01-19 15:40:26 -08:00
omap_revision = OMAP3430_REV_ES3_1_2 ;
2011-12-19 15:50:14 +05:30
cpu_rev = " 3.1.2 " ;
2008-12-10 17:36:30 -08:00
}
2009-11-22 10:10:56 -08:00
break ;
2009-11-22 10:10:58 -08:00
case 0xb868 :
2011-09-13 19:52:13 -06:00
/*
* Handle OMAP / AM 3505 / 3517 devices
2009-11-22 10:10:58 -08:00
*
2011-09-13 19:52:13 -06:00
* Set the device to be OMAP3517 here . Actual device
2009-11-22 10:10:58 -08:00
* is identified later based on the features .
*/
2011-09-13 19:52:14 -06:00
switch ( rev ) {
case 0 :
2012-04-30 16:37:10 -07:00
omap_revision = AM35XX_REV_ES1_0 ;
2011-12-19 15:50:14 +05:30
cpu_rev = " 1.0 " ;
2011-09-13 19:52:14 -06:00
break ;
case 1 :
/* FALLTHROUGH */
default :
2012-04-30 16:37:10 -07:00
omap_revision = AM35XX_REV_ES1_1 ;
2011-12-19 15:50:14 +05:30
cpu_rev = " 1.1 " ;
2011-09-13 19:52:14 -06:00
}
2009-11-22 10:10:58 -08:00
break ;
2009-11-22 10:11:24 -08:00
case 0xb891 :
2010-08-03 19:59:24 +00:00
/* Handle 36xx devices */
switch ( rev ) {
case 0 : /* Take care of early samples */
omap_revision = OMAP3630_REV_ES1_0 ;
2011-12-19 15:50:14 +05:30
cpu_rev = " 1.0 " ;
2010-08-03 19:59:24 +00:00
break ;
case 1 :
omap_revision = OMAP3630_REV_ES1_1 ;
2011-12-19 15:50:14 +05:30
cpu_rev = " 1.1 " ;
2010-08-03 19:59:24 +00:00
break ;
case 2 :
2011-09-13 19:52:15 -06:00
/* FALLTHROUGH */
2010-08-03 19:59:24 +00:00
default :
2011-09-13 19:52:15 -06:00
omap_revision = OMAP3630_REV_ES1_2 ;
2011-12-19 15:50:14 +05:30
cpu_rev = " 1.2 " ;
2010-08-03 19:59:24 +00:00
}
2010-08-16 09:21:19 +03:00
break ;
2011-02-16 08:31:39 -08:00
case 0xb81e :
switch ( rev ) {
case 0 :
omap_revision = TI8168_REV_ES1_0 ;
2011-12-19 15:50:14 +05:30
cpu_rev = " 1.0 " ;
2011-02-16 08:31:39 -08:00
break ;
case 1 :
2011-09-13 19:52:15 -06:00
omap_revision = TI8168_REV_ES1_1 ;
2011-12-19 15:50:14 +05:30
cpu_rev = " 1.1 " ;
2011-09-13 19:52:15 -06:00
break ;
2013-05-30 14:21:01 +04:00
case 2 :
omap_revision = TI8168_REV_ES2_0 ;
cpu_rev = " 2.0 " ;
break ;
case 3 :
/* FALLTHROUGH */
default :
omap_revision = TI8168_REV_ES2_1 ;
cpu_rev = " 2.1 " ;
2011-02-16 08:31:39 -08:00
}
break ;
2011-12-13 10:46:43 -08:00
case 0xb944 :
2013-02-01 15:58:22 +05:30
switch ( rev ) {
case 0 :
omap_revision = AM335X_REV_ES1_0 ;
cpu_rev = " 1.0 " ;
break ;
case 1 :
omap_revision = AM335X_REV_ES2_0 ;
cpu_rev = " 2.0 " ;
break ;
2013-05-08 16:48:02 -07:00
case 2 :
/* FALLTHROUGH */
default :
omap_revision = AM335X_REV_ES2_1 ;
cpu_rev = " 2.1 " ;
break ;
2013-02-01 15:58:22 +05:30
}
2012-01-23 13:26:47 +05:30
break ;
2013-05-27 20:06:01 +05:30
case 0xb98c :
2014-02-07 15:51:24 +05:30
switch ( rev ) {
case 0 :
omap_revision = AM437X_REV_ES1_0 ;
cpu_rev = " 1.0 " ;
break ;
case 1 :
omap_revision = AM437X_REV_ES1_1 ;
cpu_rev = " 1.1 " ;
break ;
2014-11-28 09:02:07 +05:30
case 2 :
/* FALLTHROUGH */
default :
omap_revision = AM437X_REV_ES1_2 ;
cpu_rev = " 1.2 " ;
break ;
2014-02-07 15:51:24 +05:30
}
2013-05-27 20:06:01 +05:30
break ;
2011-12-13 10:46:45 -08:00
case 0xb8f2 :
2015-12-22 15:39:29 -08:00
case 0xb968 :
2011-12-13 10:46:45 -08:00
switch ( rev ) {
case 0 :
/* FALLTHROUGH */
case 1 :
omap_revision = TI8148_REV_ES1_0 ;
2011-12-19 15:50:14 +05:30
cpu_rev = " 1.0 " ;
2011-12-13 10:46:45 -08:00
break ;
case 2 :
omap_revision = TI8148_REV_ES2_0 ;
2011-12-19 15:50:14 +05:30
cpu_rev = " 2.0 " ;
2011-12-13 10:46:45 -08:00
break ;
case 3 :
/* FALLTHROUGH */
default :
omap_revision = TI8148_REV_ES2_1 ;
2011-12-19 15:50:14 +05:30
cpu_rev = " 2.1 " ;
2011-12-13 10:46:45 -08:00
break ;
}
2011-12-13 10:46:43 -08:00
break ;
2009-11-22 10:10:56 -08:00
default :
2011-09-13 19:52:15 -06:00
/* Unknown default to latest silicon rev as default */
2011-09-13 19:52:15 -06:00
omap_revision = OMAP3630_REV_ES1_2 ;
2011-12-19 15:50:14 +05:30
cpu_rev = " 1.2 " ;
2015-12-22 15:39:29 -08:00
pr_warn ( " Warning: unknown chip type: hawkeye %04x, assuming OMAP3630ES1.2 \n " ,
hawkeye ) ;
2008-12-10 17:36:30 -08:00
}
2013-02-14 13:55:23 +02:00
sprintf ( soc_rev , " ES%s " , cpu_rev ) ;
2005-11-10 14:26:51 +00:00
}
2011-12-19 15:50:15 +05:30
void __init omap4xxx_check_revision ( void )
2009-12-11 16:16:34 -08: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 09:55:03 -08:00
rev = ( idcode > > 28 ) & 0xf ;
2009-12-11 16:16:34 -08:00
2010-09-16 18:44:46 +05:30
/*
2011-07-02 08:00:21 +05:30
* Few initial 4430 ES2 .0 samples IDCODE is same as ES1 .0
2010-09-16 18:44:46 +05:30
* Use ARM register to detect the correct ES version
*/
2011-12-13 10:46:44 -08:00
if ( ! rev & & ( hawkeye ! = 0xb94e ) & & ( hawkeye ! = 0xb975 ) ) {
2013-01-30 17:38:21 +01:00
idcode = read_cpuid_id ( ) ;
2010-09-16 18:44:46 +05:30
rev = ( idcode & 0xf ) - 1 ;
}
switch ( hawkeye ) {
case 0xb852 :
switch ( rev ) {
case 0 :
omap_revision = OMAP4430_REV_ES1_0 ;
break ;
case 1 :
2011-02-17 09:55:03 -08:00
default :
2010-09-16 18:44:46 +05:30
omap_revision = OMAP4430_REV_ES2_0 ;
2011-02-17 09:55:03 -08:00
}
break ;
case 0xb95c :
switch ( rev ) {
case 3 :
omap_revision = OMAP4430_REV_ES2_1 ;
2010-09-16 18:44:46 +05:30
break ;
2011-02-17 09:55:03 -08:00
case 4 :
omap_revision = OMAP4430_REV_ES2_2 ;
2011-12-13 10:46:44 -08:00
break ;
case 6 :
default :
omap_revision = OMAP4430_REV_ES2_3 ;
2011-02-17 09:55:03 -08:00
}
break ;
2011-07-02 08:00:21 +05:30
case 0xb94e :
switch ( rev ) {
case 0 :
omap_revision = OMAP4460_REV_ES1_0 ;
break ;
2012-05-09 09:45:02 -07:00
case 2 :
default :
omap_revision = OMAP4460_REV_ES1_1 ;
break ;
2011-07-02 08:00:21 +05:30
}
break ;
2011-12-13 10:46:44 -08:00
case 0xb975 :
switch ( rev ) {
case 0 :
default :
omap_revision = OMAP4470_REV_ES1_0 ;
break ;
}
break ;
2010-09-16 18:44:46 +05:30
default :
2011-02-17 09:55:03 -08:00
/* Unknown default to latest silicon rev as default */
2011-12-13 10:46:44 -08:00
omap_revision = OMAP4430_REV_ES2_3 ;
2009-12-11 16:16:34 -08:00
}
2013-02-14 13:55:23 +02:00
sprintf ( soc_name , " OMAP%04x " , omap_rev ( ) > > 16 ) ;
sprintf ( soc_rev , " ES%d.%d " , ( omap_rev ( ) > > 12 ) & 0xf ,
( omap_rev ( ) > > 8 ) & 0xf ) ;
pr_info ( " %s %s \n " , soc_name , soc_rev ) ;
2009-12-11 16:16:34 -08:00
}
2012-04-19 17:42:19 +05:30
void __init omap5xxx_check_revision ( void )
{
u32 idcode ;
u16 hawkeye ;
u8 rev ;
idcode = read_tap_reg ( OMAP_TAP_IDCODE ) ;
hawkeye = ( idcode > > 12 ) & 0xffff ;
rev = ( idcode > > 28 ) & 0xff ;
switch ( hawkeye ) {
case 0xb942 :
switch ( rev ) {
case 0 :
2013-09-18 09:05:42 -05:00
/* No support for ES1.0 Test chip */
BUG ( ) ;
2013-01-07 19:29:46 +05:30
case 1 :
default :
omap_revision = OMAP5430_REV_ES2_0 ;
2012-04-19 17:42:19 +05:30
}
break ;
case 0xb998 :
switch ( rev ) {
case 0 :
2013-09-18 09:05:42 -05:00
/* No support for ES1.0 Test chip */
BUG ( ) ;
2013-01-07 19:29:46 +05:30
case 1 :
default :
omap_revision = OMAP5432_REV_ES2_0 ;
2012-04-19 17:42:19 +05:30
}
break ;
default :
/* Unknown default to latest silicon rev as default*/
2013-01-07 19:29:46 +05:30
omap_revision = OMAP5430_REV_ES2_0 ;
2012-04-19 17:42:19 +05:30
}
2013-02-14 13:55:23 +02:00
sprintf ( soc_name , " OMAP%04x " , omap_rev ( ) > > 16 ) ;
sprintf ( soc_rev , " ES%d.0 " , ( omap_rev ( ) > > 12 ) & 0xf ) ;
pr_info ( " %s %s \n " , soc_name , soc_rev ) ;
2012-04-19 17:42:19 +05:30
}
2014-05-19 10:27:11 -05:00
void __init dra7xxx_check_revision ( void )
{
u32 idcode ;
u16 hawkeye ;
2017-12-18 11:50:01 +05:30
u8 rev , package ;
struct omap_die_id odi ;
2014-05-19 10:27:11 -05:00
2017-12-18 11:50:01 +05:30
omap_get_die_id ( & odi ) ;
package = ( odi . id_2 > > 16 ) & 0x3 ;
2014-05-19 10:27:11 -05:00
idcode = read_tap_reg ( OMAP_TAP_IDCODE ) ;
hawkeye = ( idcode > > 12 ) & 0xffff ;
rev = ( idcode > > 28 ) & 0xff ;
switch ( hawkeye ) {
2017-08-12 09:35:59 +05:30
case 0xbb50 :
switch ( rev ) {
case 0 :
default :
2017-12-18 11:50:01 +05:30
switch ( package ) {
case 0x2 :
omap_revision = DRA762_ABZ_REV_ES1_0 ;
break ;
case 0x3 :
omap_revision = DRA762_ACD_REV_ES1_0 ;
break ;
default :
omap_revision = DRA762_REV_ES1_0 ;
break ;
}
2017-08-12 09:35:59 +05:30
break ;
}
break ;
2014-05-19 10:27:11 -05:00
case 0xb990 :
switch ( rev ) {
case 0 :
omap_revision = DRA752_REV_ES1_0 ;
break ;
case 1 :
omap_revision = DRA752_REV_ES1_1 ;
2015-09-01 13:59:25 -07:00
break ;
case 2 :
default :
omap_revision = DRA752_REV_ES2_0 ;
break ;
2014-05-19 10:27:11 -05:00
}
break ;
2014-05-29 14:05:50 -05:00
case 0xb9bc :
switch ( rev ) {
case 0 :
omap_revision = DRA722_REV_ES1_0 ;
break ;
2016-03-09 14:56:31 -06:00
case 1 :
omap_revision = DRA722_REV_ES2_0 ;
2014-05-29 14:05:50 -05:00
break ;
2017-08-30 21:40:29 -05:00
case 2 :
default :
omap_revision = DRA722_REV_ES2_1 ;
break ;
2014-05-29 14:05:50 -05:00
}
break ;
2014-05-19 10:27:11 -05:00
default :
/* Unknown default to latest silicon rev as default*/
2014-08-25 16:15:34 -07:00
pr_warn ( " %s: unknown idcode=0x%08x (hawkeye=0x%08x,rev=0x%x) \n " ,
2014-05-19 10:27:11 -05:00
__func__ , idcode , hawkeye , rev ) ;
2015-09-01 13:59:25 -07:00
omap_revision = DRA752_REV_ES2_0 ;
2014-05-19 10:27:11 -05:00
}
sprintf ( soc_name , " DRA%03x " , omap_rev ( ) > > 16 ) ;
sprintf ( soc_rev , " ES%d.%d " , ( omap_rev ( ) > > 12 ) & 0xf ,
( omap_rev ( ) > > 8 ) & 0xf ) ;
pr_info ( " %s %s \n " , soc_name , soc_rev ) ;
}
2008-12-10 17:36:30 -08: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 .
*/
2012-10-29 20:50:21 -06:00
void __init omap2_set_globals_tap ( u32 class , void __iomem * tap )
2008-10-06 15:49:16 +03:00
{
2012-10-29 20:50:21 -06:00
omap_revision = class ;
tap_base = tap ;
2008-10-06 15:49:16 +03:00
2012-10-29 20:50:21 -06:00
/* XXX What is this intended to do? */
2015-10-14 11:13:08 +05:30
if ( soc_is_omap34xx ( ) )
2008-10-06 15:49:16 +03:00
tap_prod_id = 0x0210 ;
else
tap_prod_id = 0x0208 ;
}
2013-02-14 13:55:24 +02:00
# ifdef CONFIG_SOC_BUS
2013-06-06 15:24:38 +02:00
static const char * const omap_types [ ] = {
2013-02-14 13:55:24 +02:00
[ OMAP2_DEVICE_TYPE_TEST ] = " TST " ,
[ OMAP2_DEVICE_TYPE_EMU ] = " EMU " ,
[ OMAP2_DEVICE_TYPE_SEC ] = " HS " ,
[ OMAP2_DEVICE_TYPE_GP ] = " GP " ,
[ OMAP2_DEVICE_TYPE_BAD ] = " BAD " ,
} ;
static const char * __init omap_get_family ( void )
{
2015-10-14 11:13:08 +05:30
if ( soc_is_omap24xx ( ) )
2013-02-14 13:55:24 +02:00
return kasprintf ( GFP_KERNEL , " OMAP2 " ) ;
2015-10-14 11:13:08 +05:30
else if ( soc_is_omap34xx ( ) )
2013-02-14 13:55:24 +02:00
return kasprintf ( GFP_KERNEL , " OMAP3 " ) ;
2015-10-14 11:13:08 +05:30
else if ( soc_is_omap44xx ( ) )
2013-02-14 13:55:24 +02:00
return kasprintf ( GFP_KERNEL , " OMAP4 " ) ;
else if ( soc_is_omap54xx ( ) )
return kasprintf ( GFP_KERNEL , " OMAP5 " ) ;
2015-03-11 18:38:38 -05:00
else if ( soc_is_am33xx ( ) | | soc_is_am335x ( ) )
return kasprintf ( GFP_KERNEL , " AM33xx " ) ;
2014-02-07 15:51:25 +05:30
else if ( soc_is_am43xx ( ) )
return kasprintf ( GFP_KERNEL , " AM43xx " ) ;
2014-05-19 10:27:11 -05:00
else if ( soc_is_dra7xx ( ) )
return kasprintf ( GFP_KERNEL , " DRA7 " ) ;
2013-02-14 13:55:24 +02:00
else
return kasprintf ( GFP_KERNEL , " Unknown " ) ;
}
static ssize_t omap_get_type ( struct device * dev ,
struct device_attribute * attr ,
char * buf )
{
return sprintf ( buf , " %s \n " , omap_types [ omap_type ( ) ] ) ;
}
static struct device_attribute omap_soc_attr =
__ATTR ( type , S_IRUGO , omap_get_type , NULL ) ;
void __init omap_soc_device_init ( void )
{
struct device * parent ;
struct soc_device * soc_dev ;
struct soc_device_attribute * soc_dev_attr ;
soc_dev_attr = kzalloc ( sizeof ( * soc_dev_attr ) , GFP_KERNEL ) ;
if ( ! soc_dev_attr )
return ;
soc_dev_attr - > machine = soc_name ;
soc_dev_attr - > family = omap_get_family ( ) ;
soc_dev_attr - > revision = soc_rev ;
soc_dev = soc_device_register ( soc_dev_attr ) ;
2013-05-09 08:27:25 -07:00
if ( IS_ERR ( soc_dev ) ) {
2013-02-14 13:55:24 +02:00
kfree ( soc_dev_attr ) ;
return ;
}
parent = soc_device_to_device ( soc_dev ) ;
2013-05-09 08:27:25 -07:00
device_create_file ( parent , & omap_soc_attr ) ;
2013-02-14 13:55:24 +02:00
}
# endif /* CONFIG_SOC_BUS */