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/bug.h> 18 #include <linux/device.h> 19 #include <linux/kernel.h> 20 21 #include <soc/tegra/fuse.h> 22 23 #include "fuse.h" 24 25 #define SOC_PROCESS_CORNERS 2 26 #define CPU_PROCESS_CORNERS 2 27 28 enum { 29 THRESHOLD_INDEX_0, 30 THRESHOLD_INDEX_1, 31 THRESHOLD_INDEX_COUNT, 32 }; 33 34 static const u32 __initconst soc_process_speedos[][SOC_PROCESS_CORNERS] = { 35 {1123, UINT_MAX}, 36 {0, UINT_MAX}, 37 }; 38 39 static const u32 __initconst cpu_process_speedos[][CPU_PROCESS_CORNERS] = { 40 {1695, UINT_MAX}, 41 {0, UINT_MAX}, 42 }; 43 44 static void __init rev_sku_to_speedo_ids(struct tegra_sku_info *sku_info, 45 int *threshold) 46 { 47 u32 tmp; 48 u32 sku = sku_info->sku_id; 49 enum tegra_revision rev = sku_info->revision; 50 51 switch (sku) { 52 case 0x00: 53 case 0x10: 54 case 0x05: 55 case 0x06: 56 sku_info->cpu_speedo_id = 1; 57 sku_info->soc_speedo_id = 0; 58 *threshold = THRESHOLD_INDEX_0; 59 break; 60 61 case 0x03: 62 case 0x04: 63 sku_info->cpu_speedo_id = 2; 64 sku_info->soc_speedo_id = 1; 65 *threshold = THRESHOLD_INDEX_1; 66 break; 67 68 default: 69 pr_err("Tegra Unknown SKU %d\n", sku); 70 sku_info->cpu_speedo_id = 0; 71 sku_info->soc_speedo_id = 0; 72 *threshold = THRESHOLD_INDEX_0; 73 break; 74 } 75 76 if (rev == TEGRA_REVISION_A01) { 77 tmp = tegra_fuse_read_early(0x270) << 1; 78 tmp |= tegra_fuse_read_early(0x26c); 79 if (!tmp) 80 sku_info->cpu_speedo_id = 0; 81 } 82 } 83 84 void __init tegra114_init_speedo_data(struct tegra_sku_info *sku_info) 85 { 86 u32 cpu_speedo_val; 87 u32 soc_speedo_val; 88 int threshold; 89 int i; 90 91 BUILD_BUG_ON(ARRAY_SIZE(cpu_process_speedos) != 92 THRESHOLD_INDEX_COUNT); 93 BUILD_BUG_ON(ARRAY_SIZE(soc_process_speedos) != 94 THRESHOLD_INDEX_COUNT); 95 96 rev_sku_to_speedo_ids(sku_info, &threshold); 97 98 cpu_speedo_val = tegra_fuse_read_early(0x12c) + 1024; 99 soc_speedo_val = tegra_fuse_read_early(0x134); 100 101 for (i = 0; i < CPU_PROCESS_CORNERS; i++) 102 if (cpu_speedo_val < cpu_process_speedos[threshold][i]) 103 break; 104 sku_info->cpu_process_id = i; 105 106 for (i = 0; i < SOC_PROCESS_CORNERS; i++) 107 if (soc_speedo_val < soc_process_speedos[threshold][i]) 108 break; 109 sku_info->soc_process_id = i; 110 } 111