#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
{
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);
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;
*
*/
+#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[] = {
return platform_driver_register(&cpuinfo_platform_driver);
}
module_init(meson_cpuinfo_init);
-
-