root/drivers/soc/tegra/fuse/speedo-tegra30.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. fuse_speedo_calib
  2. rev_sku_to_speedo_ids
  3. tegra30_init_speedo_data

   1 // SPDX-License-Identifier: GPL-2.0-only
   2 /*
   3  * Copyright (c) 2012-2014, NVIDIA CORPORATION.  All rights reserved.
   4  */
   5 
   6 #include <linux/bug.h>
   7 #include <linux/device.h>
   8 #include <linux/kernel.h>
   9 
  10 #include <soc/tegra/fuse.h>
  11 
  12 #include "fuse.h"
  13 
  14 #define SOC_PROCESS_CORNERS     1
  15 #define CPU_PROCESS_CORNERS     6
  16 
  17 #define FUSE_SPEEDO_CALIB_0     0x14
  18 #define FUSE_PACKAGE_INFO       0XFC
  19 #define FUSE_TEST_PROG_VER      0X28
  20 
  21 #define G_SPEEDO_BIT_MINUS1     58
  22 #define G_SPEEDO_BIT_MINUS1_R   59
  23 #define G_SPEEDO_BIT_MINUS2     60
  24 #define G_SPEEDO_BIT_MINUS2_R   61
  25 #define LP_SPEEDO_BIT_MINUS1    62
  26 #define LP_SPEEDO_BIT_MINUS1_R  63
  27 #define LP_SPEEDO_BIT_MINUS2    64
  28 #define LP_SPEEDO_BIT_MINUS2_R  65
  29 
  30 enum {
  31         THRESHOLD_INDEX_0,
  32         THRESHOLD_INDEX_1,
  33         THRESHOLD_INDEX_2,
  34         THRESHOLD_INDEX_3,
  35         THRESHOLD_INDEX_4,
  36         THRESHOLD_INDEX_5,
  37         THRESHOLD_INDEX_6,
  38         THRESHOLD_INDEX_7,
  39         THRESHOLD_INDEX_8,
  40         THRESHOLD_INDEX_9,
  41         THRESHOLD_INDEX_10,
  42         THRESHOLD_INDEX_11,
  43         THRESHOLD_INDEX_COUNT,
  44 };
  45 
  46 static const u32 __initconst soc_process_speedos[][SOC_PROCESS_CORNERS] = {
  47         {180},
  48         {170},
  49         {195},
  50         {180},
  51         {168},
  52         {192},
  53         {180},
  54         {170},
  55         {195},
  56         {180},
  57         {180},
  58         {180},
  59 };
  60 
  61 static const u32 __initconst cpu_process_speedos[][CPU_PROCESS_CORNERS] = {
  62         {306, 338, 360, 376, UINT_MAX},
  63         {295, 336, 358, 375, UINT_MAX},
  64         {325, 325, 358, 375, UINT_MAX},
  65         {325, 325, 358, 375, UINT_MAX},
  66         {292, 324, 348, 364, UINT_MAX},
  67         {324, 324, 348, 364, UINT_MAX},
  68         {324, 324, 348, 364, UINT_MAX},
  69         {295, 336, 358, 375, UINT_MAX},
  70         {358, 358, 358, 358, 397, UINT_MAX},
  71         {364, 364, 364, 364, 397, UINT_MAX},
  72         {295, 336, 358, 375, 391, UINT_MAX},
  73         {295, 336, 358, 375, 391, UINT_MAX},
  74 };
  75 
  76 static int threshold_index __initdata;
  77 
  78 static void __init fuse_speedo_calib(u32 *speedo_g, u32 *speedo_lp)
  79 {
  80         u32 reg;
  81         int ate_ver;
  82         int bit_minus1;
  83         int bit_minus2;
  84 
  85         reg = tegra_fuse_read_early(FUSE_SPEEDO_CALIB_0);
  86 
  87         *speedo_lp = (reg & 0xFFFF) * 4;
  88         *speedo_g = ((reg >> 16) & 0xFFFF) * 4;
  89 
  90         ate_ver = tegra_fuse_read_early(FUSE_TEST_PROG_VER);
  91         pr_debug("Tegra ATE prog ver %d.%d\n", ate_ver/10, ate_ver%10);
  92 
  93         if (ate_ver >= 26) {
  94                 bit_minus1 = tegra_fuse_read_spare(LP_SPEEDO_BIT_MINUS1);
  95                 bit_minus1 |= tegra_fuse_read_spare(LP_SPEEDO_BIT_MINUS1_R);
  96                 bit_minus2 = tegra_fuse_read_spare(LP_SPEEDO_BIT_MINUS2);
  97                 bit_minus2 |= tegra_fuse_read_spare(LP_SPEEDO_BIT_MINUS2_R);
  98                 *speedo_lp |= (bit_minus1 << 1) | bit_minus2;
  99 
 100                 bit_minus1 = tegra_fuse_read_spare(G_SPEEDO_BIT_MINUS1);
 101                 bit_minus1 |= tegra_fuse_read_spare(G_SPEEDO_BIT_MINUS1_R);
 102                 bit_minus2 = tegra_fuse_read_spare(G_SPEEDO_BIT_MINUS2);
 103                 bit_minus2 |= tegra_fuse_read_spare(G_SPEEDO_BIT_MINUS2_R);
 104                 *speedo_g |= (bit_minus1 << 1) | bit_minus2;
 105         } else {
 106                 *speedo_lp |= 0x3;
 107                 *speedo_g |= 0x3;
 108         }
 109 }
 110 
 111 static void __init rev_sku_to_speedo_ids(struct tegra_sku_info *sku_info)
 112 {
 113         int package_id = tegra_fuse_read_early(FUSE_PACKAGE_INFO) & 0x0F;
 114 
 115         switch (sku_info->revision) {
 116         case TEGRA_REVISION_A01:
 117                 sku_info->cpu_speedo_id = 0;
 118                 sku_info->soc_speedo_id = 0;
 119                 threshold_index = THRESHOLD_INDEX_0;
 120                 break;
 121         case TEGRA_REVISION_A02:
 122         case TEGRA_REVISION_A03:
 123                 switch (sku_info->sku_id) {
 124                 case 0x87:
 125                 case 0x82:
 126                         sku_info->cpu_speedo_id = 1;
 127                         sku_info->soc_speedo_id = 1;
 128                         threshold_index = THRESHOLD_INDEX_1;
 129                         break;
 130                 case 0x81:
 131                         switch (package_id) {
 132                         case 1:
 133                                 sku_info->cpu_speedo_id = 2;
 134                                 sku_info->soc_speedo_id = 2;
 135                                 threshold_index = THRESHOLD_INDEX_2;
 136                                 break;
 137                         case 2:
 138                                 sku_info->cpu_speedo_id = 4;
 139                                 sku_info->soc_speedo_id = 1;
 140                                 threshold_index = THRESHOLD_INDEX_7;
 141                                 break;
 142                         default:
 143                                 pr_err("Tegra Unknown pkg %d\n", package_id);
 144                                 break;
 145                         }
 146                         break;
 147                 case 0x80:
 148                         switch (package_id) {
 149                         case 1:
 150                                 sku_info->cpu_speedo_id = 5;
 151                                 sku_info->soc_speedo_id = 2;
 152                                 threshold_index = THRESHOLD_INDEX_8;
 153                                 break;
 154                         case 2:
 155                                 sku_info->cpu_speedo_id = 6;
 156                                 sku_info->soc_speedo_id = 2;
 157                                 threshold_index = THRESHOLD_INDEX_9;
 158                                 break;
 159                         default:
 160                                 pr_err("Tegra Unknown pkg %d\n", package_id);
 161                                 break;
 162                         }
 163                         break;
 164                 case 0x83:
 165                         switch (package_id) {
 166                         case 1:
 167                                 sku_info->cpu_speedo_id = 7;
 168                                 sku_info->soc_speedo_id = 1;
 169                                 threshold_index = THRESHOLD_INDEX_10;
 170                                 break;
 171                         case 2:
 172                                 sku_info->cpu_speedo_id = 3;
 173                                 sku_info->soc_speedo_id = 2;
 174                                 threshold_index = THRESHOLD_INDEX_3;
 175                                 break;
 176                         default:
 177                                 pr_err("Tegra Unknown pkg %d\n", package_id);
 178                                 break;
 179                         }
 180                         break;
 181                 case 0x8F:
 182                         sku_info->cpu_speedo_id = 8;
 183                         sku_info->soc_speedo_id = 1;
 184                         threshold_index = THRESHOLD_INDEX_11;
 185                         break;
 186                 case 0x08:
 187                         sku_info->cpu_speedo_id = 1;
 188                         sku_info->soc_speedo_id = 1;
 189                         threshold_index = THRESHOLD_INDEX_4;
 190                         break;
 191                 case 0x02:
 192                         sku_info->cpu_speedo_id = 2;
 193                         sku_info->soc_speedo_id = 2;
 194                         threshold_index = THRESHOLD_INDEX_5;
 195                         break;
 196                 case 0x04:
 197                         sku_info->cpu_speedo_id = 3;
 198                         sku_info->soc_speedo_id = 2;
 199                         threshold_index = THRESHOLD_INDEX_6;
 200                         break;
 201                 case 0:
 202                         switch (package_id) {
 203                         case 1:
 204                                 sku_info->cpu_speedo_id = 2;
 205                                 sku_info->soc_speedo_id = 2;
 206                                 threshold_index = THRESHOLD_INDEX_2;
 207                                 break;
 208                         case 2:
 209                                 sku_info->cpu_speedo_id = 3;
 210                                 sku_info->soc_speedo_id = 2;
 211                                 threshold_index = THRESHOLD_INDEX_3;
 212                                 break;
 213                         default:
 214                                 pr_err("Tegra Unknown pkg %d\n", package_id);
 215                                 break;
 216                         }
 217                         break;
 218                 default:
 219                         pr_warn("Tegra Unknown SKU %d\n", sku_info->sku_id);
 220                         sku_info->cpu_speedo_id = 0;
 221                         sku_info->soc_speedo_id = 0;
 222                         threshold_index = THRESHOLD_INDEX_0;
 223                         break;
 224                 }
 225                 break;
 226         default:
 227                 pr_warn("Tegra Unknown chip rev %d\n", sku_info->revision);
 228                 sku_info->cpu_speedo_id = 0;
 229                 sku_info->soc_speedo_id = 0;
 230                 threshold_index = THRESHOLD_INDEX_0;
 231                 break;
 232         }
 233 }
 234 
 235 void __init tegra30_init_speedo_data(struct tegra_sku_info *sku_info)
 236 {
 237         u32 cpu_speedo_val;
 238         u32 soc_speedo_val;
 239         int i;
 240 
 241         BUILD_BUG_ON(ARRAY_SIZE(cpu_process_speedos) !=
 242                         THRESHOLD_INDEX_COUNT);
 243         BUILD_BUG_ON(ARRAY_SIZE(soc_process_speedos) !=
 244                         THRESHOLD_INDEX_COUNT);
 245 
 246 
 247         rev_sku_to_speedo_ids(sku_info);
 248         fuse_speedo_calib(&cpu_speedo_val, &soc_speedo_val);
 249         pr_debug("Tegra CPU speedo value %u\n", cpu_speedo_val);
 250         pr_debug("Tegra Core speedo value %u\n", soc_speedo_val);
 251 
 252         for (i = 0; i < CPU_PROCESS_CORNERS; i++) {
 253                 if (cpu_speedo_val < cpu_process_speedos[threshold_index][i])
 254                         break;
 255         }
 256         sku_info->cpu_process_id = i - 1;
 257 
 258         if (sku_info->cpu_process_id == -1) {
 259                 pr_warn("Tegra CPU speedo value %3d out of range",
 260                          cpu_speedo_val);
 261                 sku_info->cpu_process_id = 0;
 262                 sku_info->cpu_speedo_id = 1;
 263         }
 264 
 265         for (i = 0; i < SOC_PROCESS_CORNERS; i++) {
 266                 if (soc_speedo_val < soc_process_speedos[threshold_index][i])
 267                         break;
 268         }
 269         sku_info->soc_process_id = i - 1;
 270 
 271         if (sku_info->soc_process_id == -1) {
 272                 pr_warn("Tegra SoC speedo value %3d out of range",
 273                         soc_speedo_val);
 274                 sku_info->soc_process_id = 0;
 275                 sku_info->soc_speedo_id = 1;
 276         }
 277 }

/* [<][>][^][v][top][bottom][index][help] */