Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * Copyright (c) 2012-2014, NVIDIA CORPORATION.  All rights reserved.
0004  */
0005 
0006 #include <linux/bug.h>
0007 #include <linux/device.h>
0008 #include <linux/kernel.h>
0009 
0010 #include <soc/tegra/fuse.h>
0011 
0012 #include "fuse.h"
0013 
0014 #define SOC_PROCESS_CORNERS 1
0015 #define CPU_PROCESS_CORNERS 6
0016 
0017 #define FUSE_SPEEDO_CALIB_0 0x14
0018 #define FUSE_PACKAGE_INFO   0XFC
0019 #define FUSE_TEST_PROG_VER  0X28
0020 
0021 #define G_SPEEDO_BIT_MINUS1 58
0022 #define G_SPEEDO_BIT_MINUS1_R   59
0023 #define G_SPEEDO_BIT_MINUS2 60
0024 #define G_SPEEDO_BIT_MINUS2_R   61
0025 #define LP_SPEEDO_BIT_MINUS1    62
0026 #define LP_SPEEDO_BIT_MINUS1_R  63
0027 #define LP_SPEEDO_BIT_MINUS2    64
0028 #define LP_SPEEDO_BIT_MINUS2_R  65
0029 
0030 enum {
0031     THRESHOLD_INDEX_0,
0032     THRESHOLD_INDEX_1,
0033     THRESHOLD_INDEX_2,
0034     THRESHOLD_INDEX_3,
0035     THRESHOLD_INDEX_4,
0036     THRESHOLD_INDEX_5,
0037     THRESHOLD_INDEX_6,
0038     THRESHOLD_INDEX_7,
0039     THRESHOLD_INDEX_8,
0040     THRESHOLD_INDEX_9,
0041     THRESHOLD_INDEX_10,
0042     THRESHOLD_INDEX_11,
0043     THRESHOLD_INDEX_COUNT,
0044 };
0045 
0046 static const u32 __initconst soc_process_speedos[][SOC_PROCESS_CORNERS] = {
0047     {180},
0048     {170},
0049     {195},
0050     {180},
0051     {168},
0052     {192},
0053     {180},
0054     {170},
0055     {195},
0056     {180},
0057     {180},
0058     {180},
0059 };
0060 
0061 static const u32 __initconst cpu_process_speedos[][CPU_PROCESS_CORNERS] = {
0062     {306, 338, 360, 376, UINT_MAX},
0063     {295, 336, 358, 375, UINT_MAX},
0064     {325, 325, 358, 375, UINT_MAX},
0065     {325, 325, 358, 375, UINT_MAX},
0066     {292, 324, 348, 364, UINT_MAX},
0067     {324, 324, 348, 364, UINT_MAX},
0068     {324, 324, 348, 364, UINT_MAX},
0069     {295, 336, 358, 375, UINT_MAX},
0070     {358, 358, 358, 358, 397, UINT_MAX},
0071     {364, 364, 364, 364, 397, UINT_MAX},
0072     {295, 336, 358, 375, 391, UINT_MAX},
0073     {295, 336, 358, 375, 391, UINT_MAX},
0074 };
0075 
0076 static int threshold_index __initdata;
0077 
0078 static void __init fuse_speedo_calib(u32 *speedo_g, u32 *speedo_lp)
0079 {
0080     u32 reg;
0081     int ate_ver;
0082     int bit_minus1;
0083     int bit_minus2;
0084 
0085     reg = tegra_fuse_read_early(FUSE_SPEEDO_CALIB_0);
0086 
0087     *speedo_lp = (reg & 0xFFFF) * 4;
0088     *speedo_g = ((reg >> 16) & 0xFFFF) * 4;
0089 
0090     ate_ver = tegra_fuse_read_early(FUSE_TEST_PROG_VER);
0091     pr_debug("Tegra ATE prog ver %d.%d\n", ate_ver/10, ate_ver%10);
0092 
0093     if (ate_ver >= 26) {
0094         bit_minus1 = tegra_fuse_read_spare(LP_SPEEDO_BIT_MINUS1);
0095         bit_minus1 |= tegra_fuse_read_spare(LP_SPEEDO_BIT_MINUS1_R);
0096         bit_minus2 = tegra_fuse_read_spare(LP_SPEEDO_BIT_MINUS2);
0097         bit_minus2 |= tegra_fuse_read_spare(LP_SPEEDO_BIT_MINUS2_R);
0098         *speedo_lp |= (bit_minus1 << 1) | bit_minus2;
0099 
0100         bit_minus1 = tegra_fuse_read_spare(G_SPEEDO_BIT_MINUS1);
0101         bit_minus1 |= tegra_fuse_read_spare(G_SPEEDO_BIT_MINUS1_R);
0102         bit_minus2 = tegra_fuse_read_spare(G_SPEEDO_BIT_MINUS2);
0103         bit_minus2 |= tegra_fuse_read_spare(G_SPEEDO_BIT_MINUS2_R);
0104         *speedo_g |= (bit_minus1 << 1) | bit_minus2;
0105     } else {
0106         *speedo_lp |= 0x3;
0107         *speedo_g |= 0x3;
0108     }
0109 }
0110 
0111 static void __init rev_sku_to_speedo_ids(struct tegra_sku_info *sku_info)
0112 {
0113     int package_id = tegra_fuse_read_early(FUSE_PACKAGE_INFO) & 0x0F;
0114 
0115     switch (sku_info->revision) {
0116     case TEGRA_REVISION_A01:
0117         sku_info->cpu_speedo_id = 0;
0118         sku_info->soc_speedo_id = 0;
0119         threshold_index = THRESHOLD_INDEX_0;
0120         break;
0121     case TEGRA_REVISION_A02:
0122     case TEGRA_REVISION_A03:
0123         switch (sku_info->sku_id) {
0124         case 0x87:
0125         case 0x82:
0126             sku_info->cpu_speedo_id = 1;
0127             sku_info->soc_speedo_id = 1;
0128             threshold_index = THRESHOLD_INDEX_1;
0129             break;
0130         case 0x81:
0131             switch (package_id) {
0132             case 1:
0133                 sku_info->cpu_speedo_id = 2;
0134                 sku_info->soc_speedo_id = 2;
0135                 threshold_index = THRESHOLD_INDEX_2;
0136                 break;
0137             case 2:
0138                 sku_info->cpu_speedo_id = 4;
0139                 sku_info->soc_speedo_id = 1;
0140                 threshold_index = THRESHOLD_INDEX_7;
0141                 break;
0142             default:
0143                 pr_err("Tegra Unknown pkg %d\n", package_id);
0144                 break;
0145             }
0146             break;
0147         case 0x80:
0148             switch (package_id) {
0149             case 1:
0150                 sku_info->cpu_speedo_id = 5;
0151                 sku_info->soc_speedo_id = 2;
0152                 threshold_index = THRESHOLD_INDEX_8;
0153                 break;
0154             case 2:
0155                 sku_info->cpu_speedo_id = 6;
0156                 sku_info->soc_speedo_id = 2;
0157                 threshold_index = THRESHOLD_INDEX_9;
0158                 break;
0159             default:
0160                 pr_err("Tegra Unknown pkg %d\n", package_id);
0161                 break;
0162             }
0163             break;
0164         case 0x83:
0165             switch (package_id) {
0166             case 1:
0167                 sku_info->cpu_speedo_id = 7;
0168                 sku_info->soc_speedo_id = 1;
0169                 threshold_index = THRESHOLD_INDEX_10;
0170                 break;
0171             case 2:
0172                 sku_info->cpu_speedo_id = 3;
0173                 sku_info->soc_speedo_id = 2;
0174                 threshold_index = THRESHOLD_INDEX_3;
0175                 break;
0176             default:
0177                 pr_err("Tegra Unknown pkg %d\n", package_id);
0178                 break;
0179             }
0180             break;
0181         case 0x8F:
0182             sku_info->cpu_speedo_id = 8;
0183             sku_info->soc_speedo_id = 1;
0184             threshold_index = THRESHOLD_INDEX_11;
0185             break;
0186         case 0x08:
0187             sku_info->cpu_speedo_id = 1;
0188             sku_info->soc_speedo_id = 1;
0189             threshold_index = THRESHOLD_INDEX_4;
0190             break;
0191         case 0x02:
0192             sku_info->cpu_speedo_id = 2;
0193             sku_info->soc_speedo_id = 2;
0194             threshold_index = THRESHOLD_INDEX_5;
0195             break;
0196         case 0x04:
0197             sku_info->cpu_speedo_id = 3;
0198             sku_info->soc_speedo_id = 2;
0199             threshold_index = THRESHOLD_INDEX_6;
0200             break;
0201         case 0:
0202             switch (package_id) {
0203             case 1:
0204                 sku_info->cpu_speedo_id = 2;
0205                 sku_info->soc_speedo_id = 2;
0206                 threshold_index = THRESHOLD_INDEX_2;
0207                 break;
0208             case 2:
0209                 sku_info->cpu_speedo_id = 3;
0210                 sku_info->soc_speedo_id = 2;
0211                 threshold_index = THRESHOLD_INDEX_3;
0212                 break;
0213             default:
0214                 pr_err("Tegra Unknown pkg %d\n", package_id);
0215                 break;
0216             }
0217             break;
0218         default:
0219             pr_warn("Tegra Unknown SKU %d\n", sku_info->sku_id);
0220             sku_info->cpu_speedo_id = 0;
0221             sku_info->soc_speedo_id = 0;
0222             threshold_index = THRESHOLD_INDEX_0;
0223             break;
0224         }
0225         break;
0226     default:
0227         pr_warn("Tegra Unknown chip rev %d\n", sku_info->revision);
0228         sku_info->cpu_speedo_id = 0;
0229         sku_info->soc_speedo_id = 0;
0230         threshold_index = THRESHOLD_INDEX_0;
0231         break;
0232     }
0233 }
0234 
0235 void __init tegra30_init_speedo_data(struct tegra_sku_info *sku_info)
0236 {
0237     u32 cpu_speedo_val;
0238     u32 soc_speedo_val;
0239     int i;
0240 
0241     BUILD_BUG_ON(ARRAY_SIZE(cpu_process_speedos) !=
0242             THRESHOLD_INDEX_COUNT);
0243     BUILD_BUG_ON(ARRAY_SIZE(soc_process_speedos) !=
0244             THRESHOLD_INDEX_COUNT);
0245 
0246 
0247     rev_sku_to_speedo_ids(sku_info);
0248     fuse_speedo_calib(&cpu_speedo_val, &soc_speedo_val);
0249     pr_debug("Tegra CPU speedo value %u\n", cpu_speedo_val);
0250     pr_debug("Tegra Core speedo value %u\n", soc_speedo_val);
0251 
0252     for (i = 0; i < CPU_PROCESS_CORNERS; i++) {
0253         if (cpu_speedo_val < cpu_process_speedos[threshold_index][i])
0254             break;
0255     }
0256     sku_info->cpu_process_id = i - 1;
0257 
0258     if (sku_info->cpu_process_id == -1) {
0259         pr_warn("Tegra CPU speedo value %3d out of range",
0260              cpu_speedo_val);
0261         sku_info->cpu_process_id = 0;
0262         sku_info->cpu_speedo_id = 1;
0263     }
0264 
0265     for (i = 0; i < SOC_PROCESS_CORNERS; i++) {
0266         if (soc_speedo_val < soc_process_speedos[threshold_index][i])
0267             break;
0268     }
0269     sku_info->soc_process_id = i - 1;
0270 
0271     if (sku_info->soc_process_id == -1) {
0272         pr_warn("Tegra SoC speedo value %3d out of range",
0273             soc_speedo_val);
0274         sku_info->soc_process_id = 0;
0275         sku_info->soc_speedo_id = 1;
0276     }
0277 }