linux/drivers/soc/tegra/fuse/speedo-tegra124.c
<<
>>
Prefs
   1/*
   2 * Copyright (c) 2013-2014, NVIDIA CORPORATION.  All rights reserved.
   3 *
   4 * This program is free software; you can redistribute it and/or modify it
   5 * under the terms and conditions of the GNU General Public License,
   6 * version 2, as published by the Free Software Foundation.
   7 *
   8 * This program is distributed in the hope it will be useful, but WITHOUT
   9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  10 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
  11 * more details.
  12 *
  13 * You should have received a copy of the GNU General Public License
  14 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  15 */
  16
  17#include <linux/device.h>
  18#include <linux/kernel.h>
  19#include <linux/bug.h>
  20
  21#include <soc/tegra/fuse.h>
  22
  23#include "fuse.h"
  24
  25#define CPU_PROCESS_CORNERS     2
  26#define GPU_PROCESS_CORNERS     2
  27#define SOC_PROCESS_CORNERS     2
  28
  29#define FUSE_CPU_SPEEDO_0       0x14
  30#define FUSE_CPU_SPEEDO_1       0x2c
  31#define FUSE_CPU_SPEEDO_2       0x30
  32#define FUSE_SOC_SPEEDO_0       0x34
  33#define FUSE_SOC_SPEEDO_1       0x38
  34#define FUSE_SOC_SPEEDO_2       0x3c
  35#define FUSE_CPU_IDDQ           0x18
  36#define FUSE_SOC_IDDQ           0x40
  37#define FUSE_GPU_IDDQ           0x128
  38#define FUSE_FT_REV             0x28
  39
  40enum {
  41        THRESHOLD_INDEX_0,
  42        THRESHOLD_INDEX_1,
  43        THRESHOLD_INDEX_COUNT,
  44};
  45
  46static const u32 __initconst cpu_process_speedos[][CPU_PROCESS_CORNERS] = {
  47        {2190,  UINT_MAX},
  48        {0,     UINT_MAX},
  49};
  50
  51static const u32 __initconst gpu_process_speedos[][GPU_PROCESS_CORNERS] = {
  52        {1965,  UINT_MAX},
  53        {0,     UINT_MAX},
  54};
  55
  56static const u32 __initconst soc_process_speedos[][SOC_PROCESS_CORNERS] = {
  57        {2101,  UINT_MAX},
  58        {0,     UINT_MAX},
  59};
  60
  61static void __init rev_sku_to_speedo_ids(struct tegra_sku_info *sku_info,
  62                                         int *threshold)
  63{
  64        int sku = sku_info->sku_id;
  65
  66        /* Assign to default */
  67        sku_info->cpu_speedo_id = 0;
  68        sku_info->soc_speedo_id = 0;
  69        sku_info->gpu_speedo_id = 0;
  70        *threshold = THRESHOLD_INDEX_0;
  71
  72        switch (sku) {
  73        case 0x00: /* Eng sku */
  74        case 0x0F:
  75        case 0x23:
  76                /* Using the default */
  77                break;
  78        case 0x83:
  79                sku_info->cpu_speedo_id = 2;
  80                break;
  81
  82        case 0x1F:
  83        case 0x87:
  84        case 0x27:
  85                sku_info->cpu_speedo_id = 2;
  86                sku_info->soc_speedo_id = 0;
  87                sku_info->gpu_speedo_id = 1;
  88                *threshold = THRESHOLD_INDEX_0;
  89                break;
  90        case 0x81:
  91        case 0x21:
  92        case 0x07:
  93                sku_info->cpu_speedo_id = 1;
  94                sku_info->soc_speedo_id = 1;
  95                sku_info->gpu_speedo_id = 1;
  96                *threshold = THRESHOLD_INDEX_1;
  97                break;
  98        case 0x49:
  99        case 0x4A:
 100        case 0x48:
 101                sku_info->cpu_speedo_id = 4;
 102                sku_info->soc_speedo_id = 2;
 103                sku_info->gpu_speedo_id = 3;
 104                *threshold = THRESHOLD_INDEX_1;
 105                break;
 106        default:
 107                pr_err("Tegra Unknown SKU %d\n", sku);
 108                /* Using the default for the error case */
 109                break;
 110        }
 111}
 112
 113void __init tegra124_init_speedo_data(struct tegra_sku_info *sku_info)
 114{
 115        int i, threshold, cpu_speedo_0_value, soc_speedo_0_value;
 116        int cpu_iddq_value, gpu_iddq_value, soc_iddq_value;
 117
 118        BUILD_BUG_ON(ARRAY_SIZE(cpu_process_speedos) !=
 119                        THRESHOLD_INDEX_COUNT);
 120        BUILD_BUG_ON(ARRAY_SIZE(gpu_process_speedos) !=
 121                        THRESHOLD_INDEX_COUNT);
 122        BUILD_BUG_ON(ARRAY_SIZE(soc_process_speedos) !=
 123                        THRESHOLD_INDEX_COUNT);
 124
 125        cpu_speedo_0_value = tegra_fuse_read_early(FUSE_CPU_SPEEDO_0);
 126
 127        /* GPU Speedo is stored in CPU_SPEEDO_2 */
 128        sku_info->gpu_speedo_value = tegra_fuse_read_early(FUSE_CPU_SPEEDO_2);
 129
 130        soc_speedo_0_value = tegra_fuse_read_early(FUSE_SOC_SPEEDO_0);
 131
 132        cpu_iddq_value = tegra_fuse_read_early(FUSE_CPU_IDDQ);
 133        soc_iddq_value = tegra_fuse_read_early(FUSE_SOC_IDDQ);
 134        gpu_iddq_value = tegra_fuse_read_early(FUSE_GPU_IDDQ);
 135
 136        sku_info->cpu_speedo_value = cpu_speedo_0_value;
 137
 138        if (sku_info->cpu_speedo_value == 0) {
 139                pr_warn("Tegra Warning: Speedo value not fused.\n");
 140                WARN_ON(1);
 141                return;
 142        }
 143
 144        rev_sku_to_speedo_ids(sku_info, &threshold);
 145
 146        sku_info->cpu_iddq_value = tegra_fuse_read_early(FUSE_CPU_IDDQ);
 147
 148        for (i = 0; i < GPU_PROCESS_CORNERS; i++)
 149                if (sku_info->gpu_speedo_value <
 150                        gpu_process_speedos[threshold][i])
 151                        break;
 152        sku_info->gpu_process_id = i;
 153
 154        for (i = 0; i < CPU_PROCESS_CORNERS; i++)
 155                if (sku_info->cpu_speedo_value <
 156                        cpu_process_speedos[threshold][i])
 157                                break;
 158        sku_info->cpu_process_id = i;
 159
 160        for (i = 0; i < SOC_PROCESS_CORNERS; i++)
 161                if (soc_speedo_0_value <
 162                        soc_process_speedos[threshold][i])
 163                        break;
 164        sku_info->soc_process_id = i;
 165
 166        pr_debug("Tegra GPU Speedo ID=%d, Speedo Value=%d\n",
 167                 sku_info->gpu_speedo_id, sku_info->gpu_speedo_value);
 168}
 169