From 753d672212bfbb427b6e7bee64eb1e233ac45448 Mon Sep 17 00:00:00 2001 From: "jianxin.pan" Date: Wed, 5 Jul 2017 20:04:42 +0800 Subject: [PATCH] chipid: add chipid to cpuinfo PD#138714: add chipid for cpuinfo Change-Id: I95da78a07d0806638768984542b3f9886571efd7 Signed-off-by: jianxin.pan --- arch/arm64/kernel/cpuinfo.c | 14 +++++ drivers/amlogic/cpu_info/cpu_info.c | 122 ++++++++++++++++++------------------ include/linux/amlogic/cpu_version.h | 6 +- 3 files changed, 78 insertions(+), 64 deletions(-) diff --git a/arch/arm64/kernel/cpuinfo.c b/arch/arm64/kernel/cpuinfo.c index 6dbb835..798c0f2 100644 --- a/arch/arm64/kernel/cpuinfo.c +++ b/arch/arm64/kernel/cpuinfo.c @@ -33,6 +33,10 @@ #include #include #include +#ifdef CONFIG_AMLOGIC_CPU_INFO +#include +#endif + /* * In case the boot CPU is hotpluggable, we record its initial state and @@ -107,6 +111,9 @@ static int c_show(struct seq_file *m, void *v) { int i, j; bool compat = personality(current->personality) == PER_LINUX32; +#ifdef CONFIG_AMLOGIC_CPU_INFO + unsigned char chipid[CHIPID_LEN]; +#endif for_each_online_cpu(i) { struct cpuinfo_arm64 *cpuinfo = &per_cpu(cpu_data, i); @@ -157,6 +164,13 @@ static int c_show(struct seq_file *m, void *v) seq_printf(m, "CPU part\t: 0x%03x\n", MIDR_PARTNUM(midr)); seq_printf(m, "CPU revision\t: %d\n\n", MIDR_REVISION(midr)); } +#ifdef CONFIG_AMLOGIC_CPU_INFO + cpuinfo_get_chipid(chipid, CHIPID_LEN); + seq_puts(m, "Serial\t\t: "); + for (i = 0; i < 16; i++) + seq_printf(m, "%02x", chipid[i]); + seq_puts(m, "\n"); +#endif seq_printf(m, "Hardware\t: %s\n\n", "Amlogic"); return 0; diff --git a/drivers/amlogic/cpu_info/cpu_info.c b/drivers/amlogic/cpu_info/cpu_info.c index fd51341..5f4ae10 100644 --- a/drivers/amlogic/cpu_info/cpu_info.c +++ b/drivers/amlogic/cpu_info/cpu_info.c @@ -15,6 +15,9 @@ * */ +#define pr_fmt(fmt) "cpuinfo: " fmt + +#include #include #include #include @@ -33,84 +36,85 @@ #include #include #include -static int cpuinfo_func_id; -unsigned int system_serial_low0; -unsigned int system_serial_low1; -unsigned int system_serial_high0; -unsigned int system_serial_high1; +static unsigned char cpuinfo_chip_id[16] = { 0 }; -#undef pr_fmt -#define pr_fmt(fmt) "cpuinfo: " fmt -struct aml_cpu_info { - unsigned int version; - u8 chipid[12]; - unsigned int reserved[103]; -}; -static void __iomem *sharemem_output; -static struct aml_cpu_info *cpu_info_buf; -static noinline int fn_smc(u64 function_id, u64 arg0, u64 arg1, - u64 arg2) +static noinline int fn_smc(u64 function_id, + u64 arg0, + u64 arg1, + u64 arg2) { register long x0 asm("x0") = function_id; register long x1 asm("x1") = arg0; register long x2 asm("x2") = arg1; register long x3 asm("x3") = arg2; asm volatile( - __asmeq("%0", "x0") - __asmeq("%1", "x1") - __asmeq("%2", "x2") - __asmeq("%3", "x3") - "smc #0\n" + __asmeq("%0", "x0") + __asmeq("%1", "x1") + __asmeq("%2", "x2") + __asmeq("%3", "x3") + "smc #0\n" : "+r" (x0) : "r" (x1), "r" (x2), "r" (x3)); - return function_id; + return x0; } static int cpuinfo_probe(struct platform_device *pdev) { + void __iomem *shm_out; struct device_node *np = pdev->dev.of_node; - unsigned int id; - unsigned int *p = NULL; - unsigned int version = - (get_meson_cpu_version(MESON_CPU_VERSION_LVL_MAJOR) << 24) | - (get_meson_cpu_version(MESON_CPU_VERSION_LVL_MINOR) << 16) | - (get_meson_cpu_version(MESON_CPU_VERSION_LVL_PACK) << 8); - - if (!of_property_read_u32(np, "cpuinfo_cmd", &id)) - cpuinfo_func_id = id; - cpu_info_buf = kzalloc(sizeof(struct aml_cpu_info), GFP_KERNEL); - if (!cpu_info_buf) { - pr_info("No memory to alloc\n"); - return -ENOMEM; - } - sharemem_output = get_secmon_sharemem_output_base(); - if (!sharemem_output) { - pr_info("secmon share mem prepare not okay\n"); - return -ENOMEM; + int cmd, ret; + + if (of_property_read_u32(np, "cpuinfo_cmd", &cmd)) + return -EINVAL; + + shm_out = get_secmon_sharemem_output_base(); + if (!shm_out) { + pr_err("failed to allocate shared memory\n"); + return -ENOMEM; } + sharemem_mutex_lock(); - fn_smc(cpuinfo_func_id, 0, 0, 0); - memcpy((void *)cpu_info_buf, - (const void *)sharemem_output, sizeof(struct aml_cpu_info)); + ret = fn_smc(cmd, 2, 0, 0); + if (ret == 0) { + int version = *((unsigned int *)shm_out); + + if (version == 2) + memcpy((void *)&cpuinfo_chip_id[0], + (void *)shm_out + 4, + 16); + else { + /** + * Legacy 12-byte chip ID read out, transform data + * to expected order format. + */ + uint8_t *ch; + int i; + + cpuinfo_chip_id[0] = get_meson_cpu_version( + MESON_CPU_VERSION_LVL_MAJOR); + cpuinfo_chip_id[1] = get_meson_cpu_version( + MESON_CPU_VERSION_LVL_MINOR); + cpuinfo_chip_id[2] = get_meson_cpu_version( + MESON_CPU_VERSION_LVL_PACK); + cpuinfo_chip_id[3] = 0; + + /* Transform into expected order for display */ + ch = (uint8_t *)(shm_out + 4); + for (i = 0; i < 12; i++) + cpuinfo_chip_id[i + 4] = ch[11 - i]; + } + } else + ret = -EPROTO; sharemem_mutex_unlock(); -#if 0 - int i; - unsigned int *p = (unsigned int *)(cpu_info_buf->chipid); - for (i = 0; i < 12; i++) - pr_info("cpu_info_buf->chipid[%d]=%x\n", - i, cpu_info_buf->chipid[i]); -#endif - p = (unsigned int *)(cpu_info_buf->chipid); - system_serial_low0 = *p; - system_serial_low1 = *(p+1); - system_serial_high0 = *(p+2); - system_serial_high1 = version; - - pr_info("probe done\n"); - return 0; + return ret; +} + +void cpuinfo_get_chipid(unsigned char *cid, unsigned int size) +{ + memcpy(&cid[0], cpuinfo_chip_id, size); } static const struct of_device_id cpuinfo_dt_match[] = { @@ -132,5 +136,3 @@ static int __init meson_cpuinfo_init(void) return platform_driver_register(&cpuinfo_platform_driver); } module_init(meson_cpuinfo_init); - - diff --git a/include/linux/amlogic/cpu_version.h b/include/linux/amlogic/cpu_version.h index 5202c22..a4bdc71 100644 --- a/include/linux/amlogic/cpu_version.h +++ b/include/linux/amlogic/cpu_version.h @@ -32,11 +32,9 @@ #define MESON_CPU_VERSION_LVL_PACK 2 #define MESON_CPU_VERSION_LVL_MISC 3 #define MESON_CPU_VERSION_LVL_MAX MESON_CPU_VERSION_LVL_MISC -extern unsigned int system_serial_low0; -extern unsigned int system_serial_low1; -extern unsigned int system_serial_high0; -extern unsigned int system_serial_high1; +#define CHIPID_LEN 16 +void cpuinfo_get_chipid(unsigned char *cid, unsigned int size); int meson_cpu_version_init(void); #ifdef CONFIG_AMLOGIC_CPU_VERSION int get_meson_cpu_version(int level); -- 2.7.4