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