diff options
Diffstat (limited to 'arch/arm/mach-tegra/fuse.c')
| -rw-r--r-- | arch/arm/mach-tegra/fuse.c | 52 | 
1 files changed, 39 insertions, 13 deletions
| diff --git a/arch/arm/mach-tegra/fuse.c b/arch/arm/mach-tegra/fuse.c index 0b7db174a5de..8121742711fe 100644 --- a/arch/arm/mach-tegra/fuse.c +++ b/arch/arm/mach-tegra/fuse.c @@ -21,22 +21,28 @@  #include <linux/io.h>  #include <linux/export.h> -#include <mach/iomap.h> -  #include "fuse.h" +#include "iomap.h"  #include "apbio.h"  #define FUSE_UID_LOW		0x108  #define FUSE_UID_HIGH		0x10c  #define FUSE_SKU_INFO		0x110 -#define FUSE_SPARE_BIT		0x200 + +#define TEGRA20_FUSE_SPARE_BIT		0x200 +#define TEGRA30_FUSE_SPARE_BIT		0x244  int tegra_sku_id;  int tegra_cpu_process_id;  int tegra_core_process_id;  int tegra_chip_id; +int tegra_cpu_speedo_id;		/* only exist in Tegra30 and later */ +int tegra_soc_speedo_id;  enum tegra_revision tegra_revision; +static int tegra_fuse_spare_bit; +static void (*tegra_init_speedo_data)(void); +  /* 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.   */ @@ -57,14 +63,14 @@ static const char *tegra_revision_name[TEGRA_REVISION_MAX] = {  	[TEGRA_REVISION_A04]     = "A04",  }; -static inline u32 tegra_fuse_readl(unsigned long offset) +u32 tegra_fuse_readl(unsigned long offset)  {  	return tegra_apb_readl(TEGRA_FUSE_BASE + offset);  } -static inline bool get_spare_fuse(int bit) +bool tegra_spare_fuse(int bit)  { -	return tegra_fuse_readl(FUSE_SPARE_BIT + bit * 4); +	return tegra_fuse_readl(tegra_fuse_spare_bit + bit * 4);  }  static enum tegra_revision tegra_get_revision(u32 id) @@ -78,7 +84,7 @@ static enum tegra_revision tegra_get_revision(u32 id)  		return TEGRA_REVISION_A02;  	case 3:  		if (tegra_chip_id == TEGRA20 && -			(get_spare_fuse(18) || get_spare_fuse(19))) +			(tegra_spare_fuse(18) || tegra_spare_fuse(19)))  			return TEGRA_REVISION_A03p;  		else  			return TEGRA_REVISION_A03; @@ -89,6 +95,16 @@ static enum tegra_revision tegra_get_revision(u32 id)  	}  } +static void tegra_get_process_id(void) +{ +	u32 reg; + +	reg = tegra_fuse_readl(tegra_fuse_spare_bit); +	tegra_cpu_process_id = (reg >> 6) & 3; +	reg = tegra_fuse_readl(tegra_fuse_spare_bit); +	tegra_core_process_id = (reg >> 12) & 3; +} +  void tegra_init_fuse(void)  {  	u32 id; @@ -100,19 +116,29 @@ void tegra_init_fuse(void)  	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; -  	reg = tegra_apb_readl(TEGRA_APB_MISC_BASE + STRAP_OPT);  	tegra_bct_strapping = (reg & RAM_ID_MASK) >> RAM_CODE_SHIFT;  	id = readl_relaxed(IO_ADDRESS(TEGRA_APB_MISC_BASE) + 0x804);  	tegra_chip_id = (id >> 8) & 0xff; +	switch (tegra_chip_id) { +	case TEGRA20: +		tegra_fuse_spare_bit = TEGRA20_FUSE_SPARE_BIT; +		tegra_init_speedo_data = &tegra20_init_speedo_data; +		break; +	case TEGRA30: +		tegra_fuse_spare_bit = TEGRA30_FUSE_SPARE_BIT; +		tegra_init_speedo_data = &tegra30_init_speedo_data; +		break; +	default: +		pr_warn("Tegra: unknown chip id %d\n", tegra_chip_id); +		tegra_fuse_spare_bit = TEGRA20_FUSE_SPARE_BIT; +		tegra_init_speedo_data = &tegra_get_process_id; +	} +  	tegra_revision = tegra_get_revision(id); +	tegra_init_speedo_data();  	pr_info("Tegra Revision: %s SKU: %d CPU Process: %d Core Process: %d\n",  		tegra_revision_name[tegra_revision], |