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 29 enum { 30 THRESHOLD_INDEX_0, 31 THRESHOLD_INDEX_1, 32 THRESHOLD_INDEX_COUNT, 33 }; 34 35 static const u32 __initconst cpu_process_speedos[][CPU_PROCESS_CORNERS] = { 36 {2190, UINT_MAX}, 37 {0, UINT_MAX}, 38 }; 39 40 static const u32 __initconst gpu_process_speedos[][GPU_PROCESS_CORNERS] = { 41 {1965, UINT_MAX}, 42 {0, UINT_MAX}, 43 }; 44 45 static const u32 __initconst soc_process_speedos[][SOC_PROCESS_CORNERS] = { 46 {2101, UINT_MAX}, 47 {0, UINT_MAX}, 48 }; 49 50 static 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 102 void __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