1783c8f4cSPeter De Schrijver /* 2783c8f4cSPeter De Schrijver * Copyright (c) 2012-2014, NVIDIA CORPORATION. All rights reserved. 3783c8f4cSPeter De Schrijver * 4783c8f4cSPeter De Schrijver * This program is free software; you can redistribute it and/or modify it 5783c8f4cSPeter De Schrijver * under the terms and conditions of the GNU General Public License, 6783c8f4cSPeter De Schrijver * version 2, as published by the Free Software Foundation. 7783c8f4cSPeter De Schrijver * 8783c8f4cSPeter De Schrijver * This program is distributed in the hope it will be useful, but WITHOUT 9783c8f4cSPeter De Schrijver * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 10783c8f4cSPeter De Schrijver * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 11783c8f4cSPeter De Schrijver * more details. 12783c8f4cSPeter De Schrijver * 13783c8f4cSPeter De Schrijver * You should have received a copy of the GNU General Public License 14783c8f4cSPeter De Schrijver * along with this program. If not, see <http://www.gnu.org/licenses/>. 15783c8f4cSPeter De Schrijver */ 16783c8f4cSPeter De Schrijver 17783c8f4cSPeter De Schrijver #include <linux/bug.h> 18783c8f4cSPeter De Schrijver #include <linux/device.h> 19783c8f4cSPeter De Schrijver #include <linux/kernel.h> 20783c8f4cSPeter De Schrijver 21783c8f4cSPeter De Schrijver #include <soc/tegra/fuse.h> 22783c8f4cSPeter De Schrijver 23783c8f4cSPeter De Schrijver #include "fuse.h" 24783c8f4cSPeter De Schrijver 25783c8f4cSPeter De Schrijver #define CPU_SPEEDO_LSBIT 20 26783c8f4cSPeter De Schrijver #define CPU_SPEEDO_MSBIT 29 27783c8f4cSPeter De Schrijver #define CPU_SPEEDO_REDUND_LSBIT 30 28783c8f4cSPeter De Schrijver #define CPU_SPEEDO_REDUND_MSBIT 39 29783c8f4cSPeter De Schrijver #define CPU_SPEEDO_REDUND_OFFS (CPU_SPEEDO_REDUND_MSBIT - CPU_SPEEDO_MSBIT) 30783c8f4cSPeter De Schrijver 31*03b3f4c8SThierry Reding #define SOC_SPEEDO_LSBIT 40 32*03b3f4c8SThierry Reding #define SOC_SPEEDO_MSBIT 47 33*03b3f4c8SThierry Reding #define SOC_SPEEDO_REDUND_LSBIT 48 34*03b3f4c8SThierry Reding #define SOC_SPEEDO_REDUND_MSBIT 55 35*03b3f4c8SThierry Reding #define SOC_SPEEDO_REDUND_OFFS (SOC_SPEEDO_REDUND_MSBIT - SOC_SPEEDO_MSBIT) 36783c8f4cSPeter De Schrijver 37783c8f4cSPeter De Schrijver #define SPEEDO_MULT 4 38783c8f4cSPeter De Schrijver 39783c8f4cSPeter De Schrijver #define PROCESS_CORNERS_NUM 4 40783c8f4cSPeter De Schrijver 41783c8f4cSPeter De Schrijver #define SPEEDO_ID_SELECT_0(rev) ((rev) <= 2) 42783c8f4cSPeter De Schrijver #define SPEEDO_ID_SELECT_1(sku) \ 43783c8f4cSPeter De Schrijver (((sku) != 20) && ((sku) != 23) && ((sku) != 24) && \ 44783c8f4cSPeter De Schrijver ((sku) != 27) && ((sku) != 28)) 45783c8f4cSPeter De Schrijver 46783c8f4cSPeter De Schrijver enum { 47783c8f4cSPeter De Schrijver SPEEDO_ID_0, 48783c8f4cSPeter De Schrijver SPEEDO_ID_1, 49783c8f4cSPeter De Schrijver SPEEDO_ID_2, 50783c8f4cSPeter De Schrijver SPEEDO_ID_COUNT, 51783c8f4cSPeter De Schrijver }; 52783c8f4cSPeter De Schrijver 53783c8f4cSPeter De Schrijver static const u32 __initconst cpu_process_speedos[][PROCESS_CORNERS_NUM] = { 54783c8f4cSPeter De Schrijver {315, 366, 420, UINT_MAX}, 55783c8f4cSPeter De Schrijver {303, 368, 419, UINT_MAX}, 56783c8f4cSPeter De Schrijver {316, 331, 383, UINT_MAX}, 57783c8f4cSPeter De Schrijver }; 58783c8f4cSPeter De Schrijver 59*03b3f4c8SThierry Reding static const u32 __initconst soc_process_speedos[][PROCESS_CORNERS_NUM] = { 60783c8f4cSPeter De Schrijver {165, 195, 224, UINT_MAX}, 61783c8f4cSPeter De Schrijver {165, 195, 224, UINT_MAX}, 62783c8f4cSPeter De Schrijver {165, 195, 224, UINT_MAX}, 63783c8f4cSPeter De Schrijver }; 64783c8f4cSPeter De Schrijver 65783c8f4cSPeter De Schrijver void __init tegra20_init_speedo_data(struct tegra_sku_info *sku_info) 66783c8f4cSPeter De Schrijver { 67783c8f4cSPeter De Schrijver u32 reg; 68783c8f4cSPeter De Schrijver u32 val; 69783c8f4cSPeter De Schrijver int i; 70783c8f4cSPeter De Schrijver 71783c8f4cSPeter De Schrijver BUILD_BUG_ON(ARRAY_SIZE(cpu_process_speedos) != SPEEDO_ID_COUNT); 72*03b3f4c8SThierry Reding BUILD_BUG_ON(ARRAY_SIZE(soc_process_speedos) != SPEEDO_ID_COUNT); 73783c8f4cSPeter De Schrijver 74783c8f4cSPeter De Schrijver if (SPEEDO_ID_SELECT_0(sku_info->revision)) 75783c8f4cSPeter De Schrijver sku_info->soc_speedo_id = SPEEDO_ID_0; 76783c8f4cSPeter De Schrijver else if (SPEEDO_ID_SELECT_1(sku_info->sku_id)) 77783c8f4cSPeter De Schrijver sku_info->soc_speedo_id = SPEEDO_ID_1; 78783c8f4cSPeter De Schrijver else 79783c8f4cSPeter De Schrijver sku_info->soc_speedo_id = SPEEDO_ID_2; 80783c8f4cSPeter De Schrijver 81783c8f4cSPeter De Schrijver val = 0; 82783c8f4cSPeter De Schrijver for (i = CPU_SPEEDO_MSBIT; i >= CPU_SPEEDO_LSBIT; i--) { 837e939de1SThierry Reding reg = tegra_fuse_read_spare(i) | 847e939de1SThierry Reding tegra_fuse_read_spare(i + CPU_SPEEDO_REDUND_OFFS); 85783c8f4cSPeter De Schrijver val = (val << 1) | (reg & 0x1); 86783c8f4cSPeter De Schrijver } 87783c8f4cSPeter De Schrijver val = val * SPEEDO_MULT; 88783c8f4cSPeter De Schrijver pr_debug("Tegra CPU speedo value %u\n", val); 89783c8f4cSPeter De Schrijver 90783c8f4cSPeter De Schrijver for (i = 0; i < (PROCESS_CORNERS_NUM - 1); i++) { 91783c8f4cSPeter De Schrijver if (val <= cpu_process_speedos[sku_info->soc_speedo_id][i]) 92783c8f4cSPeter De Schrijver break; 93783c8f4cSPeter De Schrijver } 94783c8f4cSPeter De Schrijver sku_info->cpu_process_id = i; 95783c8f4cSPeter De Schrijver 96783c8f4cSPeter De Schrijver val = 0; 97*03b3f4c8SThierry Reding for (i = SOC_SPEEDO_MSBIT; i >= SOC_SPEEDO_LSBIT; i--) { 987e939de1SThierry Reding reg = tegra_fuse_read_spare(i) | 99*03b3f4c8SThierry Reding tegra_fuse_read_spare(i + SOC_SPEEDO_REDUND_OFFS); 100783c8f4cSPeter De Schrijver val = (val << 1) | (reg & 0x1); 101783c8f4cSPeter De Schrijver } 102783c8f4cSPeter De Schrijver val = val * SPEEDO_MULT; 103783c8f4cSPeter De Schrijver pr_debug("Core speedo value %u\n", val); 104783c8f4cSPeter De Schrijver 105783c8f4cSPeter De Schrijver for (i = 0; i < (PROCESS_CORNERS_NUM - 1); i++) { 106*03b3f4c8SThierry Reding if (val <= soc_process_speedos[sku_info->soc_speedo_id][i]) 107783c8f4cSPeter De Schrijver break; 108783c8f4cSPeter De Schrijver } 109*03b3f4c8SThierry Reding sku_info->soc_process_id = i; 110783c8f4cSPeter De Schrijver } 111