Skip to content

Commit 21bdd68

Browse files
committed
cpu: armv8: Add Cortex-A5x/A7x CPU support and enhance driver functionality
Extend the ARMv8 CPU driver with the following improvements: 1. Add compatible strings for modern ARM Cortex-A cores: - arm,cortex-a53 - arm,cortex-a55 - arm,cortex-a72 - arm,cortex-a73 - arm,cortex-a75 - arm,cortex-a76 2. Implement human-readable CPU name detection by reading the MIDR register and mapping known part numbers to descriptive names. 3. Add clock frequency reporting via the clk framework. The driver now probes for an optional clock and reports the CPU frequency in cpu_get_info() when available. 4. Implement get_vendor() callback returning "ARM" as the vendor. 5. Implement is_current() callback that compares the MPIDR register value against the device tree "reg" property to identify if this CPU device corresponds to the currently executing CPU. 6. Add private data structure to track per-CPU state including the optional clock reference. These changes enable proper CPU enumeration and information display on SoCs using Cortex-A5x and Cortex-A7x cores, which are common in modern Rockchip, NXP, and other ARM-based platforms. Change-Id: 6372f41d-a192-4117-9c1a-b5c75db2617a batch-01 Signed-off-by: Anton Burticica <mouse@ya.ru>
1 parent cb2e54d commit 21bdd68

File tree

1 file changed

+102
-25
lines changed

1 file changed

+102
-25
lines changed

drivers/cpu/armv8_cpu.c

Lines changed: 102 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -3,39 +3,106 @@
33
* Copyright 2024 9elements GmbH
44
*/
55
#include <cpu.h>
6+
#include <clk.h>
67
#include <dm.h>
78
#include <irq.h>
89
#include <acpi/acpigen.h>
910
#include <asm/armv8/cpu.h>
1011
#include <asm/io.h>
12+
#include <asm/system.h>
1113
#include <dm/acpi.h>
1214
#include <linux/bitops.h>
1315
#include <linux/printk.h>
1416
#include <linux/sizes.h>
1517

16-
static int armv8_cpu_get_desc(const struct udevice *dev, char *buf, int size)
18+
/* MIDR part numbers */
19+
#define MIDR_PARTNUM_CORTEX_A53 0xD03
20+
#define MIDR_PARTNUM_CORTEX_A72 0xD08
21+
#define MIDR_PARTNUM_CORTEX_A55 0xD05
22+
#define MIDR_PARTNUM_CORTEX_A76 0xD0B
23+
24+
struct armv8_cpu_priv {
25+
struct clk clk;
26+
bool has_clk;
27+
};
28+
29+
static const char *armv8_cpu_get_name(void)
1730
{
18-
int cpuid;
31+
u32 partnum = (read_midr() & MIDR_PARTNUM_MASK) >> MIDR_PARTNUM_SHIFT;
32+
33+
switch (partnum) {
34+
case MIDR_PARTNUM_CORTEX_A53:
35+
return "Cortex-A53";
36+
case MIDR_PARTNUM_CORTEX_A72:
37+
return "Cortex-A72";
38+
case MIDR_PARTNUM_CORTEX_A55:
39+
return "Cortex-A55";
40+
case MIDR_PARTNUM_CORTEX_A76:
41+
return "Cortex-A76";
42+
default:
43+
return "Unknown";
44+
}
45+
}
1946

20-
cpuid = (read_midr() & MIDR_PARTNUM_MASK) >> MIDR_PARTNUM_SHIFT;
47+
static int armv8_cpu_get_desc(const struct udevice *dev, char *buf, int size)
48+
{
49+
u32 partnum = (read_midr() & MIDR_PARTNUM_MASK) >> MIDR_PARTNUM_SHIFT;
2150

22-
snprintf(buf, size, "CPU MIDR %04x", cpuid);
51+
snprintf(buf, size, "ARM %s (MIDR %04x)", armv8_cpu_get_name(), partnum);
2352

24-
return 0;
53+
return 0;
2554
}
2655

27-
static int armv8_cpu_get_info(const struct udevice *dev,
28-
struct cpu_info *info)
56+
static int armv8_cpu_get_info(const struct udevice *dev, struct cpu_info *info)
2957
{
30-
info->cpu_freq = 0;
31-
info->features = BIT(CPU_FEAT_L1_CACHE) | BIT(CPU_FEAT_MMU);
58+
struct armv8_cpu_priv *priv = dev_get_priv(dev);
3259

33-
return 0;
60+
info->cpu_freq = 0;
61+
info->features = BIT(CPU_FEAT_L1_CACHE) | BIT(CPU_FEAT_MMU);
62+
63+
if (priv && priv->has_clk)
64+
info->cpu_freq = clk_get_rate(&priv->clk);
65+
66+
return 0;
3467
}
3568

3669
static int armv8_cpu_get_count(const struct udevice *dev)
3770
{
38-
return uclass_id_count(UCLASS_CPU);
71+
return uclass_id_count(UCLASS_CPU);
72+
}
73+
74+
static int armv8_cpu_get_vendor(const struct udevice *dev, char *buf, int size)
75+
{
76+
snprintf(buf, size, "ARM");
77+
return 0;
78+
}
79+
80+
static int armv8_cpu_is_current(struct udevice *dev)
81+
{
82+
u64 mpidr = read_mpidr();
83+
u64 cpu_reg;
84+
85+
/* Get reg property (MPIDR value for this CPU) */
86+
cpu_reg = dev_read_u64_default(dev, "reg", 0);
87+
if (!cpu_reg)
88+
cpu_reg = dev_read_u32_default(dev, "reg", 0);
89+
90+
/* Compare affinity fields */
91+
return (mpidr & 0xFFFFFF) == (cpu_reg & 0xFFFFFF);
92+
}
93+
94+
static int armv8_cpu_probe(struct udevice *dev)
95+
{
96+
struct armv8_cpu_priv *priv = dev_get_priv(dev);
97+
int ret;
98+
99+
priv->has_clk = false;
100+
101+
ret = clk_get_by_index(dev, 0, &priv->clk);
102+
if (!ret)
103+
priv->has_clk = true;
104+
105+
return 0;
39106
}
40107

41108
#ifdef CONFIG_ACPIGEN
@@ -130,22 +197,32 @@ struct acpi_ops armv8_cpu_acpi_ops = {
130197
};
131198
#endif
132199

133-
static const struct cpu_ops cpu_ops = {
134-
.get_count = armv8_cpu_get_count,
135-
.get_desc = armv8_cpu_get_desc,
136-
.get_info = armv8_cpu_get_info,
200+
static const struct cpu_ops armv8_cpu_ops = {
201+
.get_count = armv8_cpu_get_count,
202+
.get_desc = armv8_cpu_get_desc,
203+
.get_info = armv8_cpu_get_info,
204+
.get_vendor = armv8_cpu_get_vendor,
205+
.is_current = armv8_cpu_is_current,
137206
};
138207

139-
static const struct udevice_id cpu_ids[] = {
140-
{ .compatible = "arm,armv8" },
141-
{}
208+
static const struct udevice_id armv8_cpu_ids[] = {
209+
{ .compatible = "arm,cortex-a53" },
210+
{ .compatible = "arm,cortex-a55" },
211+
{ .compatible = "arm,cortex-a72" },
212+
{ .compatible = "arm,cortex-a73" },
213+
{ .compatible = "arm,cortex-a75" },
214+
{ .compatible = "arm,cortex-a76" },
215+
{ .compatible = "arm,armv8" },
216+
{}
142217
};
143218

144-
U_BOOT_DRIVER(arm_cpu) = {
145-
.name = "arm-cpu",
146-
.id = UCLASS_CPU,
147-
.of_match = cpu_ids,
148-
.ops = &cpu_ops,
149-
.flags = DM_FLAG_PRE_RELOC,
150-
ACPI_OPS_PTR(&armv8_cpu_acpi_ops)
219+
U_BOOT_DRIVER(armv8_cpu) = {
220+
.name = "armv8-cpu",
221+
.id = UCLASS_CPU,
222+
.of_match = armv8_cpu_ids,
223+
.ops = &armv8_cpu_ops,
224+
.probe = armv8_cpu_probe,
225+
.priv_auto = sizeof(struct armv8_cpu_priv),
226+
.flags = DM_FLAG_PRE_RELOC,
227+
ACPI_OPS_PTR(&armv8_cpu_acpi_ops)
151228
};

0 commit comments

Comments
 (0)