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, cpu_speedo_0_value, soc_speedo_0_value;
 105        int cpu_iddq_value, gpu_iddq_value, soc_iddq_value;
 106
 107        BUILD_BUG_ON(ARRAY_SIZE(cpu_process_speedos) !=
 108                        THRESHOLD_INDEX_COUNT);
 109        BUILD_BUG_ON(ARRAY_SIZE(gpu_process_speedos) !=
 110                        THRESHOLD_INDEX_COUNT);
 111        BUILD_BUG_ON(ARRAY_SIZE(soc_process_speedos) !=
 112                        THRESHOLD_INDEX_COUNT);
 113
 114        cpu_speedo_0_value = tegra_fuse_read_early(FUSE_CPU_SPEEDO_0);
 115
 116        /* GPU Speedo is stored in CPU_SPEEDO_2 */
 117        sku_info->gpu_speedo_value = tegra_fuse_read_early(FUSE_CPU_SPEEDO_2);
 118
 119        soc_speedo_0_value = tegra_fuse_read_early(FUSE_SOC_SPEEDO_0);
 120
 121        cpu_iddq_value = tegra_fuse_read_early(FUSE_CPU_IDDQ);
 122        soc_iddq_value = tegra_fuse_read_early(FUSE_SOC_IDDQ);
 123        gpu_iddq_value = tegra_fuse_read_early(FUSE_GPU_IDDQ);
 124
 125        sku_info->cpu_speedo_value = cpu_speedo_0_value;
 126
 127        if (sku_info->cpu_speedo_value == 0) {
 128                pr_warn("Tegra Warning: Speedo value not fused.\n");
 129                WARN_ON(1);
 130                return;
 131        }
 132
 133        rev_sku_to_speedo_ids(sku_info, &threshold);
 134
 135        sku_info->cpu_iddq_value = tegra_fuse_read_early(FUSE_CPU_IDDQ);
 136
 137        for (i = 0; i < GPU_PROCESS_CORNERS; i++)
 138                if (sku_info->gpu_speedo_value <
 139                        gpu_process_speedos[threshold][i])
 140                        break;
 141        sku_info->gpu_process_id = i;
 142
 143        for (i = 0; i < CPU_PROCESS_CORNERS; i++)
 144                if (sku_info->cpu_speedo_value <
 145                        cpu_process_speedos[threshold][i])
 146                                break;
 147        sku_info->cpu_process_id = i;
 148
 149        for (i = 0; i < SOC_PROCESS_CORNERS; i++)
 150                if (soc_speedo_0_value <
 151                        soc_process_speedos[threshold][i])
 152                        break;
 153        sku_info->soc_process_id = i;
 154
 155        pr_debug("Tegra GPU Speedo ID=%d, Speedo Value=%d\n",
 156                 sku_info->gpu_speedo_id, sku_info->gpu_speedo_value);
 157}
 158