1 // SPDX-License-Identifier: GPL-2.0-only
3 * Copyright (c) 2012-2014, NVIDIA CORPORATION. All rights reserved.
7 #include <linux/device.h>
8 #include <linux/kernel.h>
10 #include <soc/tegra/fuse.h>
14 #define CPU_SPEEDO_LSBIT 20
15 #define CPU_SPEEDO_MSBIT 29
16 #define CPU_SPEEDO_REDUND_LSBIT 30
17 #define CPU_SPEEDO_REDUND_MSBIT 39
18 #define CPU_SPEEDO_REDUND_OFFS (CPU_SPEEDO_REDUND_MSBIT - CPU_SPEEDO_MSBIT)
20 #define SOC_SPEEDO_LSBIT 40
21 #define SOC_SPEEDO_MSBIT 47
22 #define SOC_SPEEDO_REDUND_LSBIT 48
23 #define SOC_SPEEDO_REDUND_MSBIT 55
24 #define SOC_SPEEDO_REDUND_OFFS (SOC_SPEEDO_REDUND_MSBIT - SOC_SPEEDO_MSBIT)
28 #define PROCESS_CORNERS_NUM 4
30 #define SPEEDO_ID_SELECT_0(rev) ((rev) <= 2)
31 #define SPEEDO_ID_SELECT_1(sku) \
32 (((sku) != 20) && ((sku) != 23) && ((sku) != 24) && \
33 ((sku) != 27) && ((sku) != 28))
42 static const u32 __initconst cpu_process_speedos
[][PROCESS_CORNERS_NUM
] = {
43 {315, 366, 420, UINT_MAX
},
44 {303, 368, 419, UINT_MAX
},
45 {316, 331, 383, UINT_MAX
},
48 static const u32 __initconst soc_process_speedos
[][PROCESS_CORNERS_NUM
] = {
49 {165, 195, 224, UINT_MAX
},
50 {165, 195, 224, UINT_MAX
},
51 {165, 195, 224, UINT_MAX
},
54 void __init
tegra20_init_speedo_data(struct tegra_sku_info
*sku_info
)
60 BUILD_BUG_ON(ARRAY_SIZE(cpu_process_speedos
) != SPEEDO_ID_COUNT
);
61 BUILD_BUG_ON(ARRAY_SIZE(soc_process_speedos
) != SPEEDO_ID_COUNT
);
63 if (SPEEDO_ID_SELECT_0(sku_info
->revision
))
64 sku_info
->soc_speedo_id
= SPEEDO_ID_0
;
65 else if (SPEEDO_ID_SELECT_1(sku_info
->sku_id
))
66 sku_info
->soc_speedo_id
= SPEEDO_ID_1
;
68 sku_info
->soc_speedo_id
= SPEEDO_ID_2
;
71 for (i
= CPU_SPEEDO_MSBIT
; i
>= CPU_SPEEDO_LSBIT
; i
--) {
72 reg
= tegra_fuse_read_spare(i
) |
73 tegra_fuse_read_spare(i
+ CPU_SPEEDO_REDUND_OFFS
);
74 val
= (val
<< 1) | (reg
& 0x1);
76 val
= val
* SPEEDO_MULT
;
77 pr_debug("Tegra CPU speedo value %u\n", val
);
79 for (i
= 0; i
< (PROCESS_CORNERS_NUM
- 1); i
++) {
80 if (val
<= cpu_process_speedos
[sku_info
->soc_speedo_id
][i
])
83 sku_info
->cpu_process_id
= i
;
86 for (i
= SOC_SPEEDO_MSBIT
; i
>= SOC_SPEEDO_LSBIT
; i
--) {
87 reg
= tegra_fuse_read_spare(i
) |
88 tegra_fuse_read_spare(i
+ SOC_SPEEDO_REDUND_OFFS
);
89 val
= (val
<< 1) | (reg
& 0x1);
91 val
= val
* SPEEDO_MULT
;
92 pr_debug("Core speedo value %u\n", val
);
94 for (i
= 0; i
< (PROCESS_CORNERS_NUM
- 1); i
++) {
95 if (val
<= soc_process_speedos
[sku_info
->soc_speedo_id
][i
])
98 sku_info
->soc_process_id
= i
;