2019-05-28 10:10:04 -07:00
// SPDX-License-Identifier: GPL-2.0-only
2013-03-18 19:17:34 +08:00
/*
2014-06-12 18:36:37 +03:00
* Copyright ( c ) 2013 - 2014 , NVIDIA CORPORATION . All rights reserved .
2013-03-18 19:17:34 +08:00
*/
# include <linux/bug.h>
2014-06-12 18:36:37 +03:00
# include <linux/device.h>
2014-07-11 09:44:49 +02:00
# include <linux/kernel.h>
2013-03-18 19:17:34 +08:00
2014-06-12 18:36:36 +03:00
# include <soc/tegra/fuse.h>
2013-03-18 19:17:34 +08:00
# include "fuse.h"
2015-03-23 14:44:08 +01:00
# define SOC_PROCESS_CORNERS 2
2014-06-12 18:36:37 +03:00
# define CPU_PROCESS_CORNERS 2
2013-03-18 19:17:34 +08:00
enum {
THRESHOLD_INDEX_0 ,
THRESHOLD_INDEX_1 ,
THRESHOLD_INDEX_COUNT ,
} ;
2015-03-23 14:44:08 +01:00
static const u32 __initconst soc_process_speedos [ ] [ SOC_PROCESS_CORNERS ] = {
2013-03-18 19:17:34 +08:00
{ 1123 , UINT_MAX } ,
{ 0 , UINT_MAX } ,
} ;
2014-06-12 18:36:37 +03:00
static const u32 __initconst cpu_process_speedos [ ] [ CPU_PROCESS_CORNERS ] = {
2013-03-18 19:17:34 +08:00
{ 1695 , UINT_MAX } ,
{ 0 , UINT_MAX } ,
} ;
2014-06-12 18:36:37 +03:00
static void __init rev_sku_to_speedo_ids ( struct tegra_sku_info * sku_info ,
int * threshold )
2013-03-18 19:17:34 +08:00
{
u32 tmp ;
2014-06-12 18:36:37 +03:00
u32 sku = sku_info - > sku_id ;
enum tegra_revision rev = sku_info - > revision ;
2013-03-18 19:17:34 +08:00
switch ( sku ) {
case 0x00 :
case 0x10 :
case 0x05 :
case 0x06 :
2014-06-12 18:36:37 +03:00
sku_info - > cpu_speedo_id = 1 ;
sku_info - > soc_speedo_id = 0 ;
2013-03-18 19:17:34 +08:00
* threshold = THRESHOLD_INDEX_0 ;
break ;
case 0x03 :
case 0x04 :
2014-06-12 18:36:37 +03:00
sku_info - > cpu_speedo_id = 2 ;
sku_info - > soc_speedo_id = 1 ;
2013-03-18 19:17:34 +08:00
* threshold = THRESHOLD_INDEX_1 ;
break ;
default :
2014-06-12 18:36:37 +03:00
pr_err ( " Tegra Unknown SKU %d \n " , sku ) ;
sku_info - > cpu_speedo_id = 0 ;
sku_info - > soc_speedo_id = 0 ;
2013-03-18 19:17:34 +08:00
* threshold = THRESHOLD_INDEX_0 ;
break ;
}
if ( rev = = TEGRA_REVISION_A01 ) {
2015-04-29 16:54:04 +02:00
tmp = tegra_fuse_read_early ( 0x270 ) < < 1 ;
tmp | = tegra_fuse_read_early ( 0x26c ) ;
2013-03-18 19:17:34 +08:00
if ( ! tmp )
2014-06-12 18:36:37 +03:00
sku_info - > cpu_speedo_id = 0 ;
2013-03-18 19:17:34 +08:00
}
}
2014-06-12 18:36:37 +03:00
void __init tegra114_init_speedo_data ( struct tegra_sku_info * sku_info )
2013-03-18 19:17:34 +08:00
{
u32 cpu_speedo_val ;
2015-03-23 14:44:08 +01:00
u32 soc_speedo_val ;
2013-03-18 19:17:34 +08:00
int threshold ;
int i ;
BUILD_BUG_ON ( ARRAY_SIZE ( cpu_process_speedos ) ! =
THRESHOLD_INDEX_COUNT ) ;
2015-03-23 14:44:08 +01:00
BUILD_BUG_ON ( ARRAY_SIZE ( soc_process_speedos ) ! =
2013-03-18 19:17:34 +08:00
THRESHOLD_INDEX_COUNT ) ;
2014-06-12 18:36:37 +03:00
rev_sku_to_speedo_ids ( sku_info , & threshold ) ;
2013-03-18 19:17:34 +08:00
2015-04-29 16:54:04 +02:00
cpu_speedo_val = tegra_fuse_read_early ( 0x12c ) + 1024 ;
2015-03-23 14:44:08 +01:00
soc_speedo_val = tegra_fuse_read_early ( 0x134 ) ;
2013-03-18 19:17:34 +08:00
2014-06-12 18:36:37 +03:00
for ( i = 0 ; i < CPU_PROCESS_CORNERS ; i + + )
2013-03-18 19:17:34 +08:00
if ( cpu_speedo_val < cpu_process_speedos [ threshold ] [ i ] )
break ;
2014-06-12 18:36:37 +03:00
sku_info - > cpu_process_id = i ;
2013-03-18 19:17:34 +08:00
2015-03-23 14:44:08 +01:00
for ( i = 0 ; i < SOC_PROCESS_CORNERS ; i + + )
if ( soc_speedo_val < soc_process_speedos [ threshold ] [ i ] )
2013-03-18 19:17:34 +08:00
break ;
2015-03-23 14:44:08 +01:00
sku_info - > soc_process_id = i ;
2013-03-18 19:17:34 +08:00
}