xref: /linux/drivers/soc/tegra/fuse/speedo-tegra124.c (revision 48c1c40ab40cb087b992e7b77518c3a2926743cc)
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * Copyright (c) 2013-2014, NVIDIA CORPORATION.  All rights reserved.
4  */
5 
6 #include <linux/device.h>
7 #include <linux/kernel.h>
8 #include <linux/bug.h>
9 
10 #include <soc/tegra/fuse.h>
11 
12 #include "fuse.h"
13 
14 #define CPU_PROCESS_CORNERS	2
15 #define GPU_PROCESS_CORNERS	2
16 #define SOC_PROCESS_CORNERS	2
17 
18 #define FUSE_CPU_SPEEDO_0	0x14
19 #define FUSE_CPU_SPEEDO_1	0x2c
20 #define FUSE_CPU_SPEEDO_2	0x30
21 #define FUSE_SOC_SPEEDO_0	0x34
22 #define FUSE_SOC_SPEEDO_1	0x38
23 #define FUSE_SOC_SPEEDO_2	0x3c
24 #define FUSE_CPU_IDDQ		0x18
25 #define FUSE_SOC_IDDQ		0x40
26 #define FUSE_GPU_IDDQ		0x128
27 #define FUSE_FT_REV		0x28
28 
29 enum {
30 	THRESHOLD_INDEX_0,
31 	THRESHOLD_INDEX_1,
32 	THRESHOLD_INDEX_COUNT,
33 };
34 
35 static const u32 __initconst cpu_process_speedos[][CPU_PROCESS_CORNERS] = {
36 	{2190,	UINT_MAX},
37 	{0,	UINT_MAX},
38 };
39 
40 static const u32 __initconst gpu_process_speedos[][GPU_PROCESS_CORNERS] = {
41 	{1965,	UINT_MAX},
42 	{0,	UINT_MAX},
43 };
44 
45 static const u32 __initconst soc_process_speedos[][SOC_PROCESS_CORNERS] = {
46 	{2101,	UINT_MAX},
47 	{0,	UINT_MAX},
48 };
49 
50 static void __init rev_sku_to_speedo_ids(struct tegra_sku_info *sku_info,
51 					 int *threshold)
52 {
53 	int sku = sku_info->sku_id;
54 
55 	/* Assign to default */
56 	sku_info->cpu_speedo_id = 0;
57 	sku_info->soc_speedo_id = 0;
58 	sku_info->gpu_speedo_id = 0;
59 	*threshold = THRESHOLD_INDEX_0;
60 
61 	switch (sku) {
62 	case 0x00: /* Eng sku */
63 	case 0x0F:
64 	case 0x23:
65 		/* Using the default */
66 		break;
67 	case 0x83:
68 		sku_info->cpu_speedo_id = 2;
69 		break;
70 
71 	case 0x1F:
72 	case 0x87:
73 	case 0x27:
74 		sku_info->cpu_speedo_id = 2;
75 		sku_info->soc_speedo_id = 0;
76 		sku_info->gpu_speedo_id = 1;
77 		*threshold = THRESHOLD_INDEX_0;
78 		break;
79 	case 0x81:
80 	case 0x21:
81 	case 0x07:
82 		sku_info->cpu_speedo_id = 1;
83 		sku_info->soc_speedo_id = 1;
84 		sku_info->gpu_speedo_id = 1;
85 		*threshold = THRESHOLD_INDEX_1;
86 		break;
87 	case 0x49:
88 	case 0x4A:
89 	case 0x48:
90 		sku_info->cpu_speedo_id = 4;
91 		sku_info->soc_speedo_id = 2;
92 		sku_info->gpu_speedo_id = 3;
93 		*threshold = THRESHOLD_INDEX_1;
94 		break;
95 	default:
96 		pr_err("Tegra Unknown SKU %d\n", sku);
97 		/* Using the default for the error case */
98 		break;
99 	}
100 }
101 
102 void __init tegra124_init_speedo_data(struct tegra_sku_info *sku_info)
103 {
104 	int i, threshold, soc_speedo_0_value;
105 
106 	BUILD_BUG_ON(ARRAY_SIZE(cpu_process_speedos) !=
107 			THRESHOLD_INDEX_COUNT);
108 	BUILD_BUG_ON(ARRAY_SIZE(gpu_process_speedos) !=
109 			THRESHOLD_INDEX_COUNT);
110 	BUILD_BUG_ON(ARRAY_SIZE(soc_process_speedos) !=
111 			THRESHOLD_INDEX_COUNT);
112 
113 	sku_info->cpu_speedo_value = tegra_fuse_read_early(FUSE_CPU_SPEEDO_0);
114 	if (sku_info->cpu_speedo_value == 0) {
115 		pr_warn("Tegra Warning: Speedo value not fused.\n");
116 		WARN_ON(1);
117 		return;
118 	}
119 
120 	/* GPU Speedo is stored in CPU_SPEEDO_2 */
121 	sku_info->gpu_speedo_value = tegra_fuse_read_early(FUSE_CPU_SPEEDO_2);
122 	soc_speedo_0_value = tegra_fuse_read_early(FUSE_SOC_SPEEDO_0);
123 
124 	rev_sku_to_speedo_ids(sku_info, &threshold);
125 
126 	sku_info->cpu_iddq_value = tegra_fuse_read_early(FUSE_CPU_IDDQ);
127 
128 	for (i = 0; i < GPU_PROCESS_CORNERS; i++)
129 		if (sku_info->gpu_speedo_value <
130 			gpu_process_speedos[threshold][i])
131 			break;
132 	sku_info->gpu_process_id = i;
133 
134 	for (i = 0; i < CPU_PROCESS_CORNERS; i++)
135 		if (sku_info->cpu_speedo_value <
136 			cpu_process_speedos[threshold][i])
137 				break;
138 	sku_info->cpu_process_id = i;
139 
140 	for (i = 0; i < SOC_PROCESS_CORNERS; i++)
141 		if (soc_speedo_0_value <
142 			soc_process_speedos[threshold][i])
143 			break;
144 	sku_info->soc_process_id = i;
145 
146 	pr_debug("Tegra GPU Speedo ID=%d, Speedo Value=%d\n",
147 		 sku_info->gpu_speedo_id, sku_info->gpu_speedo_value);
148 }
149