Hi Anatolij, > -----Original Message----- > From: Anatolij Gustschin [mailto:ag...@denx.de] > Sent: 2018年10月18日 20:28 > To: u-boot@lists.denx.de; Peng Fan <peng....@nxp.com>; sba...@denx.de > Subject: [PATCH v6 21/34] imx8: cpu: add uclass based CPU driver > > print_cpuinfo() in board init code requires uclass CPU driver, add it to be > able to > display CPU info when CONFIG_DISPLAY_CPUINFO option is enabled. CPU node > in DT will have to include 'clocks' > and 'u-boot,dm-pre-reloc' properties for generic print_cpuinfo() to work as > expected. The driver outputs info for i.MX8QXP Rev A and Rev B CPUs. > > Signed-off-by: Anatolij Gustschin <ag...@denx.de> > Cc: Stefano Babic <sba...@denx.de> > --- > arch/arm/include/asm/arch-imx/cpu.h | 5 +- > arch/arm/mach-imx/imx8/cpu.c | 215 ++++++++++++++++++---------- > 2 files changed, 142 insertions(+), 78 deletions(-) > > diff --git a/arch/arm/include/asm/arch-imx/cpu.h > b/arch/arm/include/asm/arch-imx/cpu.h > index cf6303c3f5..2af79659d2 100644 > --- a/arch/arm/include/asm/arch-imx/cpu.h > +++ b/arch/arm/include/asm/arch-imx/cpu.h > @@ -25,6 +25,7 @@ > #define MXC_CPU_MX7S 0x71 /* dummy ID */ > #define MXC_CPU_MX7D 0x72 > #define MXC_CPU_MX8MQ 0x82 > +#define MXC_CPU_IMX8QXP_A0 0x90 /* dummy ID */ > #define MXC_CPU_IMX8QXP 0x92 /* dummy ID */ > #define MXC_CPU_MX7ULP 0xE1 /* Temporally hard code */ > #define MXC_CPU_VF610 0xF6 /* dummy ID */ > @@ -43,8 +44,8 @@ > #define CHIP_REV_2_5 0x25 > #define CHIP_REV_3_0 0x30 > > -#define CHIP_REV_A 0x0 > -#define CHIP_REV_B 0x1 > +#define CHIP_REV_A 0x0 > +#define CHIP_REV_B 0x1 > > #define BOARD_REV_1_0 0x0 > #define BOARD_REV_2_0 0x1 > diff --git a/arch/arm/mach-imx/imx8/cpu.c b/arch/arm/mach-imx/imx8/cpu.c > index da34a94a23..f093f34ca5 100644 > --- a/arch/arm/mach-imx/imx8/cpu.c > +++ b/arch/arm/mach-imx/imx8/cpu.c > @@ -5,6 +5,7 @@ > > #include <common.h> > #include <clk.h> > +#include <cpu.h> > #include <dm.h> > #include <dm/device-internal.h> > #include <dm/lists.h> > @@ -19,82 +20,6 @@ > > DECLARE_GLOBAL_DATA_PTR; > > -u32 get_cpu_rev(void) > -{ > - u32 id = 0, rev = 0; > - int ret; > - > - ret = sc_misc_get_control(-1, SC_R_SYSTEM, SC_C_ID, &id); > - if (ret) > - return 0; > - > - rev = (id >> 5) & 0xf; > - id = (id & 0x1f) + MXC_SOC_IMX8; /* Dummy ID for chip */ > - > - return (id << 12) | rev; > -} > - > -#ifdef CONFIG_DISPLAY_CPUINFO > -const char *get_imx8_type(u32 imxtype) > -{ > - switch (imxtype) { > - case MXC_CPU_IMX8QXP: > - return "8QXP"; > - default: > - return "??"; > - } > -} > - > -const char *get_imx8_rev(u32 rev) > -{ > - switch (rev) { > - case CHIP_REV_A: > - return "A"; > - case CHIP_REV_B: > - return "B"; > - default: > - return "?"; > - } > -} > - > -const char *get_core_name(void) > -{ > - if (is_cortex_a35()) > - return "A35"; > - else > - return "?"; > -} > - > -int print_cpuinfo(void) > -{ > - struct udevice *dev; > - struct clk cpu_clk; > - int ret; > - > - ret = uclass_get_device(UCLASS_CPU, 0, &dev); > - if (ret) > - return 0; > - > - ret = clk_get_by_index(dev, 0, &cpu_clk); > - if (ret) { > - dev_err(dev, "failed to clk\n"); > - return 0; > - } > - > - u32 cpurev; > - > - cpurev = get_cpu_rev(); > - > - printf("CPU: Freescale i.MX%s rev%s %s at %ld MHz\n", > - get_imx8_type((cpurev & 0xFF000) >> 12), > - get_imx8_rev((cpurev & 0xFFF)), > - get_core_name(), > - clk_get_rate(&cpu_clk) / 1000000); > - > - return 0; > -} > -#endif > - > #define BT_PASSOVER_TAG 0x504F > struct pass_over_info_t *get_pass_over_info(void) { @@ -581,3 +506,141 > @@ void imx_get_mac_from_fuse(int dev_id, unsigned char *mac) > err: > printf("%s: fuse %d, err: %d\n", __func__, word[i], ret); } > + > +#if CONFIG_IS_ENABLED(CPU) > +struct cpu_imx_platdata { > + const char *name; > + const char *rev; > + const char *type; > + u32 cpurev; > + u32 freq_mhz; > +}; > + > +u32 get_cpu_rev(void) > +{ > + u32 id = 0, rev = 0; > + int ret; > + > + ret = sc_misc_get_control(-1, SC_R_SYSTEM, SC_C_ID, &id); > + if (ret) > + return 0; > + > + rev = (id >> 5) & 0xf; > + id = (id & 0x1f) + MXC_SOC_IMX8; /* Dummy ID for chip */ > + > + return (id << 12) | rev; > +} > + > +const char *get_imx8_type(u32 imxtype) > +{ > + switch (imxtype) { > + case MXC_CPU_IMX8QXP: > + case MXC_CPU_IMX8QXP_A0: > + return "QXP"; > + default: > + return "??"; > + } > +} > + > +const char *get_imx8_rev(u32 rev) > +{ > + switch (rev) { > + case CHIP_REV_A: > + return "A"; > + case CHIP_REV_B: > + return "B"; > + default: > + return "?"; > + } > +} > + > +const char *get_core_name(void) > +{ > + if (is_cortex_a35()) > + return "A35"; > + else if (is_cortex_a53()) > + return "A53"; > + else if (is_cortex_a72()) > + return "A72"; > + else > + return "?"; > +} > + > +int cpu_imx_get_desc(struct udevice *dev, char *buf, int size) { > + struct cpu_imx_platdata *plat = dev_get_platdata(dev); > + > + if (size < 100) > + return -ENOSPC; > + > + snprintf(buf, size, "CPU: Freescale i.MX8%s Rev%s %s at %u MHz\n", > + plat->type, plat->rev, plat->name, plat->freq_mhz); > + > + return 0; > +} > + > +static int cpu_imx_get_info(struct udevice *dev, struct cpu_info *info) > +{ > + struct cpu_imx_platdata *plat = dev_get_platdata(dev); > + > + info->cpu_freq = plat->freq_mhz * 1000; > + info->features = BIT(CPU_FEAT_L1_CACHE) | BIT(CPU_FEAT_MMU); > + return 0; > +} > + > +static int cpu_imx_get_count(struct udevice *dev) { > + return 4; > +} > + > +static int cpu_imx_get_vendor(struct udevice *dev, char *buf, int > +size) { > + snprintf(buf, size, "NXP"); > + return 0; > +} > + > +static const struct cpu_ops cpu_imx8_ops = { > + .get_desc = cpu_imx_get_desc, > + .get_info = cpu_imx_get_info, > + .get_count = cpu_imx_get_count, > + .get_vendor = cpu_imx_get_vendor, > +}; > + > +static const struct udevice_id cpu_imx8_ids[] = { > + { .compatible = "arm,cortex-a35" }, > + { } > +}; > + > +static int imx8_cpu_probe(struct udevice *dev) { > + struct cpu_imx_platdata *plat = dev_get_platdata(dev); > + struct clk cpu_clk; > + u32 cpurev; > + int ret; > + > + cpurev = get_cpu_rev(); > + plat->cpurev = cpurev; > + plat->name = get_core_name(); > + plat->rev = get_imx8_rev(cpurev & 0xFFF); > + plat->type = get_imx8_type((cpurev & 0xFF000) >> 12); > + > + ret = clk_get_by_index(dev, 0, &cpu_clk); > + if (ret) { > + debug("%s: Failed to get CPU clk: %d\n", __func__, ret); > + return 0; > + } > + > + plat->freq_mhz = clk_get_rate(&cpu_clk) / 1000000; > + return 0; > +} > + > +U_BOOT_DRIVER(cpu_imx8_drv) = { > + .name = "imx8x_cpu", > + .id = UCLASS_CPU, > + .of_match = cpu_imx8_ids, > + .ops = &cpu_imx8_ops, > + .probe = imx8_cpu_probe, > + .platdata_auto_alloc_size = sizeof(struct cpu_imx_platdata), > + .flags = DM_FLAG_PRE_RELOC, > +}; > +#endif
Reviewed-by: Peng Fan <peng....@nxp.com> Thanks, Peng. > -- > 2.17.1 _______________________________________________ U-Boot mailing list U-Boot@lists.denx.de https://lists.denx.de/listinfo/u-boot