^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Copyright (c) 2013-2014, NVIDIA CORPORATION. All rights reserved.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) #include <linux/bug.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) #include <linux/device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <soc/tegra/fuse.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include "fuse.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #define SOC_PROCESS_CORNERS 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #define CPU_PROCESS_CORNERS 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) enum {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) THRESHOLD_INDEX_0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) THRESHOLD_INDEX_1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) THRESHOLD_INDEX_COUNT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) static const u32 __initconst soc_process_speedos[][SOC_PROCESS_CORNERS] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) {1123, UINT_MAX},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) {0, UINT_MAX},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) static const u32 __initconst cpu_process_speedos[][CPU_PROCESS_CORNERS] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) {1695, UINT_MAX},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) {0, UINT_MAX},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) static void __init rev_sku_to_speedo_ids(struct tegra_sku_info *sku_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) int *threshold)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) u32 tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) u32 sku = sku_info->sku_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) enum tegra_revision rev = sku_info->revision;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) switch (sku) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) case 0x00:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) case 0x10:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) case 0x05:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) case 0x06:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) sku_info->cpu_speedo_id = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) sku_info->soc_speedo_id = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) *threshold = THRESHOLD_INDEX_0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) case 0x03:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) case 0x04:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) sku_info->cpu_speedo_id = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) sku_info->soc_speedo_id = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) *threshold = THRESHOLD_INDEX_1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) pr_err("Tegra Unknown SKU %d\n", sku);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) sku_info->cpu_speedo_id = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) sku_info->soc_speedo_id = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) *threshold = THRESHOLD_INDEX_0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) if (rev == TEGRA_REVISION_A01) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) tmp = tegra_fuse_read_early(0x270) << 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) tmp |= tegra_fuse_read_early(0x26c);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) if (!tmp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) sku_info->cpu_speedo_id = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) void __init tegra114_init_speedo_data(struct tegra_sku_info *sku_info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) u32 cpu_speedo_val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) u32 soc_speedo_val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) int threshold;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) BUILD_BUG_ON(ARRAY_SIZE(cpu_process_speedos) !=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) THRESHOLD_INDEX_COUNT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) BUILD_BUG_ON(ARRAY_SIZE(soc_process_speedos) !=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) THRESHOLD_INDEX_COUNT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) rev_sku_to_speedo_ids(sku_info, &threshold);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) cpu_speedo_val = tegra_fuse_read_early(0x12c) + 1024;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) soc_speedo_val = tegra_fuse_read_early(0x134);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) for (i = 0; i < CPU_PROCESS_CORNERS; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) if (cpu_speedo_val < cpu_process_speedos[threshold][i])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) sku_info->cpu_process_id = i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) for (i = 0; i < SOC_PROCESS_CORNERS; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) if (soc_speedo_val < soc_process_speedos[threshold][i])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) sku_info->soc_process_id = i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) }