linux/drivers/soc/tegra/fuse/speedo-tegra124.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-only
   2/*
   3 * Copyright (c) 2013-2014, NVIDIA CORPORATION.  All rights reserved.
   4 */
   5
   6#include <linux/device.h>
   7#include <linux/kernel.h>
   8#include <linux/bug.h>
   9
  10#include <soc/tegra/fuse.h>
  11
  12#include "fuse.h"
  13
  14#define CPU_PROCESS_CORNERS     2
  15#define GPU_PROCESS_CORNERS     2
  16#define SOC_PROCESS_CORNERS     2
  17
  18#define FUSE_CPU_SPEEDO_0       0x14
  19#define FUSE_CPU_SPEEDO_1       0x2c
  20#define FUSE_CPU_SPEEDO_2       0x30
  21#define FUSE_SOC_SPEEDO_0       0x34
  22#define FUSE_SOC_SPEEDO_1       0x38
  23#define FUSE_SOC_SPEEDO_2       0x3c
  24#define FUSE_CPU_IDDQ           0x18
  25#define FUSE_SOC_IDDQ           0x40
  26#define FUSE_GPU_IDDQ           0x128
  27#define FUSE_FT_REV             0x28
  28
  29enum {
  30        THRESHOLD_INDEX_0,
  31        THRESHOLD_INDEX_1,
  32        THRESHOLD_INDEX_COUNT,
  33};
  34
  35static const u32 __initconst cpu_process_speedos[][CPU_PROCESS_CORNERS] = {
  36        {2190,  UINT_MAX},
  37        {0,     UINT_MAX},
  38};
  39
  40static const u32 __initconst gpu_process_speedos[][GPU_PROCESS_CORNERS] = {
  41        {1965,  UINT_MAX},
  42        {0,     UINT_MAX},
  43};
  44
  45static const u32 __initconst soc_process_speedos[][SOC_PROCESS_CORNERS] = {
  46        {2101,  UINT_MAX},
  47        {0,     UINT_MAX},
  48};
  49
  50static void __init rev_sku_to_speedo_ids(struct tegra_sku_info *sku_info,
  51                                         int *threshold)
  52{
  53        int sku = sku_info->sku_id;
  54
  55        /* Assign to default */
  56        sku_info->cpu_speedo_id = 0;
  57        sku_info->soc_speedo_id = 0;
  58        sku_info->gpu_speedo_id = 0;
  59        *threshold = THRESHOLD_INDEX_0;
  60
  61        switch (sku) {
  62        case 0x00: /* Eng sku */
  63        case 0x0F:
  64        case 0x23:
  65                /* Using the default */
  66                break;
  67        case 0x83:
  68                sku_info->cpu_speedo_id = 2;
  69                break;
  70
  71        case 0x1F:
  72        case 0x87:
  73        case 0x27:
  74                sku_info->cpu_speedo_id = 2;
  75                sku_info->soc_speedo_id = 0;
  76                sku_info->gpu_speedo_id = 1;
  77                *threshold = THRESHOLD_INDEX_0;
  78                break;
  79        case 0x81:
  80        case 0x21:
  81        case 0x07:
  82                sku_info->cpu_speedo_id = 1;
  83                sku_info->soc_speedo_id = 1;
  84                sku_info->gpu_speedo_id = 1;
  85                *threshold = THRESHOLD_INDEX_1;
  86                break;
  87        case 0x49:
  88        case 0x4A:
  89        case 0x48:
  90                sku_info->cpu_speedo_id = 4;
  91                sku_info->soc_speedo_id = 2;
  92                sku_info->gpu_speedo_id = 3;
  93                *threshold = THRESHOLD_INDEX_1;
  94                break;
  95        default:
  96                pr_err("Tegra Unknown SKU %d\n", sku);
  97                /* Using the default for the error case */
  98                break;
  99        }
 100}
 101
 102void __init tegra124_init_speedo_data(struct tegra_sku_info *sku_info)
 103{
 104        int i, threshold, soc_speedo_0_value;
 105
 106        BUILD_BUG_ON(ARRAY_SIZE(cpu_process_speedos) !=
 107                        THRESHOLD_INDEX_COUNT);
 108        BUILD_BUG_ON(ARRAY_SIZE(gpu_process_speedos) !=
 109                        THRESHOLD_INDEX_COUNT);
 110        BUILD_BUG_ON(ARRAY_SIZE(soc_process_speedos) !=
 111                        THRESHOLD_INDEX_COUNT);
 112
 113        sku_info->cpu_speedo_value = tegra_fuse_read_early(FUSE_CPU_SPEEDO_0);
 114        if (sku_info->cpu_speedo_value == 0) {
 115                pr_warn("Tegra Warning: Speedo value not fused.\n");
 116                WARN_ON(1);
 117                return;
 118        }
 119
 120        /* GPU Speedo is stored in CPU_SPEEDO_2 */
 121        sku_info->gpu_speedo_value = tegra_fuse_read_early(FUSE_CPU_SPEEDO_2);
 122        soc_speedo_0_value = tegra_fuse_read_early(FUSE_SOC_SPEEDO_0);
 123
 124        rev_sku_to_speedo_ids(sku_info, &threshold);
 125
 126        sku_info->cpu_iddq_value = tegra_fuse_read_early(FUSE_CPU_IDDQ);
 127
 128        for (i = 0; i < GPU_PROCESS_CORNERS; i++)
 129                if (sku_info->gpu_speedo_value <
 130                        gpu_process_speedos[threshold][i])
 131                        break;
 132        sku_info->gpu_process_id = i;
 133
 134        for (i = 0; i < CPU_PROCESS_CORNERS; i++)
 135                if (sku_info->cpu_speedo_value <
 136                        cpu_process_speedos[threshold][i])
 137                                break;
 138        sku_info->cpu_process_id = i;
 139
 140        for (i = 0; i < SOC_PROCESS_CORNERS; i++)
 141                if (soc_speedo_0_value <
 142                        soc_process_speedos[threshold][i])
 143                        break;
 144        sku_info->soc_process_id = i;
 145
 146        pr_debug("Tegra GPU Speedo ID=%d, Speedo Value=%d\n",
 147                 sku_info->gpu_speedo_id, sku_info->gpu_speedo_value);
 148}
 149