2010-06-23 15:49:17 -07:00
/*
* arch / arm / mach - tegra / fuse . c
*
* Copyright ( C ) 2010 Google , Inc .
*
* Author :
* Colin Cross < ccross @ android . com >
*
* This software is licensed under the terms of the GNU General Public
* License version 2 , as published by the Free Software Foundation , and
* may be copied , distributed , and modified under those terms .
*
* 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 .
*
*/
# include <linux/kernel.h>
# include <linux/io.h>
# include <mach/iomap.h>
# include "fuse.h"
2011-10-13 00:14:08 -07:00
# include "apbio.h"
2010-06-23 15:49:17 -07:00
# define FUSE_UID_LOW 0x108
# define FUSE_UID_HIGH 0x10c
# define FUSE_SKU_INFO 0x110
# define FUSE_SPARE_BIT 0x200
2011-10-13 00:31:20 -07:00
int tegra_sku_id ;
int tegra_cpu_process_id ;
int tegra_core_process_id ;
2012-02-10 01:47:41 +02:00
static int tegra_chip_id ;
2011-10-13 00:31:20 -07:00
enum tegra_revision tegra_revision ;
2011-10-17 16:39:24 -07:00
/* The BCT to use at boot is specified by board straps that can be read
* through a APB misc register and decoded . 2 bits , i . e . 4 possible BCTs .
*/
int tegra_bct_strapping ;
# define STRAP_OPT 0x008
# define GMI_AD0 (1 << 4)
# define GMI_AD1 (1 << 5)
# define RAM_ID_MASK (GMI_AD0 | GMI_AD1)
# define RAM_CODE_SHIFT 4
2011-10-13 00:31:20 -07:00
static const char * tegra_revision_name [ TEGRA_REVISION_MAX ] = {
[ TEGRA_REVISION_UNKNOWN ] = " unknown " ,
[ TEGRA_REVISION_A01 ] = " A01 " ,
[ TEGRA_REVISION_A02 ] = " A02 " ,
[ TEGRA_REVISION_A03 ] = " A03 " ,
[ TEGRA_REVISION_A03p ] = " A03 prime " ,
[ TEGRA_REVISION_A04 ] = " A04 " ,
} ;
2011-10-13 00:14:08 -07:00
static inline u32 tegra_fuse_readl ( unsigned long offset )
2010-06-23 15:49:17 -07:00
{
2011-10-13 00:14:08 -07:00
return tegra_apb_readl ( TEGRA_FUSE_BASE + offset ) ;
2010-06-23 15:49:17 -07:00
}
2011-10-13 00:31:20 -07:00
static inline bool get_spare_fuse ( int bit )
{
return tegra_fuse_readl ( FUSE_SPARE_BIT + bit * 4 ) ;
}
2012-02-10 01:47:41 +02:00
static enum tegra_revision tegra_get_revision ( u32 id )
2011-10-13 00:31:20 -07:00
{
u32 minor_rev = ( id > > 16 ) & 0xf ;
switch ( minor_rev ) {
case 1 :
return TEGRA_REVISION_A01 ;
case 2 :
return TEGRA_REVISION_A02 ;
case 3 :
2012-02-10 01:47:41 +02:00
if ( tegra_chip_id = = TEGRA20 & &
( get_spare_fuse ( 18 ) | | get_spare_fuse ( 19 ) ) )
2011-10-13 00:31:20 -07:00
return TEGRA_REVISION_A03p ;
else
return TEGRA_REVISION_A03 ;
case 4 :
return TEGRA_REVISION_A04 ;
default :
return TEGRA_REVISION_UNKNOWN ;
}
}
2010-06-23 15:49:17 -07:00
void tegra_init_fuse ( void )
{
2012-02-10 01:47:41 +02:00
u32 id ;
2010-06-23 15:49:17 -07:00
u32 reg = readl ( IO_TO_VIRT ( TEGRA_CLK_RESET_BASE + 0x48 ) ) ;
reg | = 1 < < 28 ;
writel ( reg , IO_TO_VIRT ( TEGRA_CLK_RESET_BASE + 0x48 ) ) ;
2011-10-13 00:31:20 -07:00
reg = tegra_fuse_readl ( FUSE_SKU_INFO ) ;
tegra_sku_id = reg & 0xFF ;
reg = tegra_fuse_readl ( FUSE_SPARE_BIT ) ;
tegra_cpu_process_id = ( reg > > 6 ) & 3 ;
reg = tegra_fuse_readl ( FUSE_SPARE_BIT ) ;
tegra_core_process_id = ( reg > > 12 ) & 3 ;
2011-10-17 16:39:24 -07:00
reg = tegra_apb_readl ( TEGRA_APB_MISC_BASE + STRAP_OPT ) ;
tegra_bct_strapping = ( reg & RAM_ID_MASK ) > > RAM_CODE_SHIFT ;
2012-02-10 01:47:41 +02:00
id = readl_relaxed ( IO_ADDRESS ( TEGRA_APB_MISC_BASE ) + 0x804 ) ;
tegra_chip_id = ( id > > 8 ) & 0xff ;
tegra_revision = tegra_get_revision ( id ) ;
2011-10-13 00:31:20 -07:00
pr_info ( " Tegra Revision: %s SKU: %d CPU Process: %d Core Process: %d \n " ,
2012-02-10 01:47:41 +02:00
tegra_revision_name [ tegra_revision ] ,
2011-10-13 00:31:20 -07:00
tegra_sku_id , tegra_cpu_process_id ,
tegra_core_process_id ) ;
2010-06-23 15:49:17 -07:00
}
unsigned long long tegra_chip_uid ( void )
{
unsigned long long lo , hi ;
2011-10-13 00:14:08 -07:00
lo = tegra_fuse_readl ( FUSE_UID_LOW ) ;
hi = tegra_fuse_readl ( FUSE_UID_HIGH ) ;
2010-06-23 15:49:17 -07:00
return ( hi < < 32ull ) | lo ;
}