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 CPU_SPEEDO_LSBIT        20
0015 #define CPU_SPEEDO_MSBIT        29
0016 #define CPU_SPEEDO_REDUND_LSBIT     30
0017 #define CPU_SPEEDO_REDUND_MSBIT     39
0018 #define CPU_SPEEDO_REDUND_OFFS  (CPU_SPEEDO_REDUND_MSBIT - CPU_SPEEDO_MSBIT)
0019 
0020 #define SOC_SPEEDO_LSBIT        40
0021 #define SOC_SPEEDO_MSBIT        47
0022 #define SOC_SPEEDO_REDUND_LSBIT     48
0023 #define SOC_SPEEDO_REDUND_MSBIT     55
0024 #define SOC_SPEEDO_REDUND_OFFS  (SOC_SPEEDO_REDUND_MSBIT - SOC_SPEEDO_MSBIT)
0025 
0026 #define SPEEDO_MULT         4
0027 
0028 #define PROCESS_CORNERS_NUM     4
0029 
0030 #define SPEEDO_ID_SELECT_0(rev)     ((rev) <= 2)
0031 #define SPEEDO_ID_SELECT_1(sku)     \
0032     (((sku) != 20) && ((sku) != 23) && ((sku) != 24) && \
0033      ((sku) != 27) && ((sku) != 28))
0034 
0035 enum {
0036     SPEEDO_ID_0,
0037     SPEEDO_ID_1,
0038     SPEEDO_ID_2,
0039     SPEEDO_ID_COUNT,
0040 };
0041 
0042 static const u32 __initconst cpu_process_speedos[][PROCESS_CORNERS_NUM] = {
0043     {315, 366, 420, UINT_MAX},
0044     {303, 368, 419, UINT_MAX},
0045     {316, 331, 383, UINT_MAX},
0046 };
0047 
0048 static const u32 __initconst soc_process_speedos[][PROCESS_CORNERS_NUM] = {
0049     {165, 195, 224, UINT_MAX},
0050     {165, 195, 224, UINT_MAX},
0051     {165, 195, 224, UINT_MAX},
0052 };
0053 
0054 void __init tegra20_init_speedo_data(struct tegra_sku_info *sku_info)
0055 {
0056     u32 reg;
0057     u32 val;
0058     int i;
0059 
0060     BUILD_BUG_ON(ARRAY_SIZE(cpu_process_speedos) != SPEEDO_ID_COUNT);
0061     BUILD_BUG_ON(ARRAY_SIZE(soc_process_speedos) != SPEEDO_ID_COUNT);
0062 
0063     if (SPEEDO_ID_SELECT_0(sku_info->revision))
0064         sku_info->soc_speedo_id = SPEEDO_ID_0;
0065     else if (SPEEDO_ID_SELECT_1(sku_info->sku_id))
0066         sku_info->soc_speedo_id = SPEEDO_ID_1;
0067     else
0068         sku_info->soc_speedo_id = SPEEDO_ID_2;
0069 
0070     val = 0;
0071     for (i = CPU_SPEEDO_MSBIT; i >= CPU_SPEEDO_LSBIT; i--) {
0072         reg = tegra_fuse_read_spare(i) |
0073             tegra_fuse_read_spare(i + CPU_SPEEDO_REDUND_OFFS);
0074         val = (val << 1) | (reg & 0x1);
0075     }
0076     val = val * SPEEDO_MULT;
0077     pr_debug("Tegra CPU speedo value %u\n", val);
0078 
0079     for (i = 0; i < (PROCESS_CORNERS_NUM - 1); i++) {
0080         if (val <= cpu_process_speedos[sku_info->soc_speedo_id][i])
0081             break;
0082     }
0083     sku_info->cpu_process_id = i;
0084 
0085     val = 0;
0086     for (i = SOC_SPEEDO_MSBIT; i >= SOC_SPEEDO_LSBIT; i--) {
0087         reg = tegra_fuse_read_spare(i) |
0088             tegra_fuse_read_spare(i + SOC_SPEEDO_REDUND_OFFS);
0089         val = (val << 1) | (reg & 0x1);
0090     }
0091     val = val * SPEEDO_MULT;
0092     pr_debug("Core speedo value %u\n", val);
0093 
0094     for (i = 0; i < (PROCESS_CORNERS_NUM - 1); i++) {
0095         if (val <= soc_process_speedos[sku_info->soc_speedo_id][i])
0096             break;
0097     }
0098     sku_info->soc_process_id = i;
0099 }