chipid: add chipid to cpuinfo
authorjianxin.pan <jianxin.pan@amlogic.com>
Wed, 5 Jul 2017 12:04:42 +0000 (20:04 +0800)
committerjianxin.pan <jianxin.pan@amlogic.com>
Sun, 9 Jul 2017 13:14:10 +0000 (21:14 +0800)
PD#138714: add chipid for cpuinfo

Change-Id: I95da78a07d0806638768984542b3f9886571efd7
Signed-off-by: jianxin.pan <jianxin.pan@amlogic.com>
arch/arm64/kernel/cpuinfo.c
drivers/amlogic/cpu_info/cpu_info.c
include/linux/amlogic/cpu_version.h

index 6dbb835..798c0f2 100644 (file)
 #include <linux/sched.h>
 #include <linux/smp.h>
 #include <linux/delay.h>
+#ifdef CONFIG_AMLOGIC_CPU_INFO
+#include <linux/amlogic/cpu_version.h>
+#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;
index fd51341..5f4ae10 100644 (file)
@@ -15,6 +15,9 @@
  *
  */
 
+#define pr_fmt(fmt) "cpuinfo: " fmt
+
+#include <linux/export.h>
 #include <linux/cdev.h>
 #include <linux/types.h>
 #include <linux/fs.h>
 #include <linux/of.h>
 #include <linux/of_fdt.h>
 #include <linux/amlogic/cpu_version.h>
-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);
-
-
index 5202c22..a4bdc71 100644 (file)
 #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);