Skip to content

Commit cf7da86

Browse files
committed
cpufreq: Fix m1n1 stage 1 bugs
Old stage1 did cpufreq init and didn't do it right. Undo the damage in stage2. Signed-off-by: Hector Martin <[email protected]>
1 parent 9b944c5 commit cf7da86

3 files changed

Lines changed: 54 additions & 17 deletions

File tree

src/cpufreq.c

Lines changed: 51 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
#include "cpufreq.h"
44
#include "adt.h"
5+
#include "firmware.h"
56
#include "soc.h"
67
#include "utils.h"
78

@@ -10,6 +11,8 @@
1011

1112
#define CLUSTER_PSTATE_BUSY BIT(31)
1213
#define CLUSTER_PSTATE_SET BIT(25)
14+
#define CLUSTER_PSTATE_UNK BIT(20)
15+
#define CLUSTER_PSTATE_DESIRED2 GENMASK(16, 12)
1316
#define CLUSTER_PSTATE_DESIRED1 GENMASK(4, 0)
1417

1518
#define CLUSTER_CONFIG_ENABLE BIT(63)
@@ -55,6 +58,24 @@ int cpufreq_init_cluster(const struct cluster_t *cluster)
5558
return 0;
5659
}
5760

61+
void cpufreq_fixup_cluster(const struct cluster_t *cluster)
62+
{
63+
u64 val = read64(cluster->base + CLUSTER_PSTATE);
64+
65+
// Older versions of m1n1 stage 1 erroneously cleared CLUSTER_PSTATE_UNK, so put it back for
66+
// firmwares it supported (don't touch anything newer, which includes newer devices).
67+
// Also clear the CLUSTER_PSTATE_DESIRED2 field since it doesn't seem to do anything, and isn't
68+
// used on newer chips.
69+
if (os_firmware.version != V_UNKNOWN && os_firmware.version <= V13_3) {
70+
if (!(val & CLUSTER_PSTATE_UNK) || (val & CLUSTER_PSTATE_DESIRED2)) {
71+
val |= CLUSTER_PSTATE_UNK;
72+
val &= ~CLUSTER_PSTATE_DESIRED2;
73+
printf("cpufreq: Correcting setting for cluster %s\n", cluster->name);
74+
write64(cluster->base + CLUSTER_PSTATE, val);
75+
}
76+
}
77+
}
78+
5879
static const struct cluster_t t8103_clusters[] = {
5980
{"ECPU", 0x210e20000, false, 5},
6081
{"PCPU", 0x211e20000, true, 7},
@@ -91,34 +112,35 @@ static const struct cluster_t t6020_clusters[] = {
91112
{},
92113
};
93114

94-
int cpufreq_init(void)
115+
const struct cluster_t *cpufreq_get_clusters(void)
95116
{
96-
printf("cpufreq: Initializing clusters\n");
97-
98-
const struct cluster_t *cluster;
99-
100117
switch (chip_id) {
101118
case T8103:
102-
cluster = t8103_clusters;
103-
break;
119+
return t8103_clusters;
104120
case T6000:
105121
case T6001:
106-
cluster = t6000_clusters;
107-
break;
122+
return t6000_clusters;
108123
case T6002:
109-
cluster = t6002_clusters;
110-
break;
124+
return t6002_clusters;
125+
case T8112:
126+
return t8112_clusters;
111127
case T6020:
112128
case T6021:
113-
cluster = t6020_clusters;
114-
break;
115-
case T8112:
116-
cluster = t8112_clusters;
117-
break;
129+
return t6020_clusters;
118130
default:
119131
printf("cpufreq: Chip 0x%x is unsupported\n", chip_id);
120-
return -1;
132+
return NULL;
121133
}
134+
}
135+
136+
int cpufreq_init(void)
137+
{
138+
printf("cpufreq: Initializing clusters\n");
139+
140+
const struct cluster_t *cluster = cpufreq_get_clusters();
141+
142+
if (!cluster)
143+
return -1;
122144

123145
bool err = false;
124146
while (cluster->base) {
@@ -127,3 +149,15 @@ int cpufreq_init(void)
127149

128150
return err ? -1 : 0;
129151
}
152+
153+
void cpufreq_fixup(void)
154+
{
155+
const struct cluster_t *cluster = cpufreq_get_clusters();
156+
157+
if (!cluster)
158+
return;
159+
160+
while (cluster->base) {
161+
cpufreq_fixup_cluster(cluster++);
162+
}
163+
}

src/cpufreq.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,6 @@
44
#define CPUFREQ_H
55

66
int cpufreq_init(void);
7+
void cpufreq_fixup(void);
78

89
#endif

src/main.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77

88
#include "adt.h"
99
#include "aic.h"
10+
#include "cpufreq.h"
1011
#include "display.h"
1112
#include "exception.h"
1213
#include "fb.h"
@@ -166,6 +167,7 @@ void m1n1_main(void)
166167
#endif
167168
#endif
168169

170+
cpufreq_fixup();
169171
sep_init();
170172
#endif
171173

0 commit comments

Comments
 (0)