#define EFUSE_HAL_API_WRITE 1
#define EFUSE_HAL_API_USER_MAX 3
+#define AML_DATA_PROCESS (0x820000FF)
+#define AML_D_P_W_EFUSE_AMLOGIC (0x20)
+#define GXB_EFUSE_PATTERN_SIZE (0x400)
+
#define ASSIST_HW_REV 0x1f53
extern int efuseinfo_num;
ssize_t efuse_get_max(void);
ssize_t efuse_read_usr(char *buf, size_t count, loff_t *ppos);
ssize_t efuse_write_usr(char *buf, size_t count, loff_t *ppos);
+unsigned long efuse_amlogic_set(char *buf, size_t count);
#endif
}
#endif
+static ssize_t amlogic_set_store(struct class *cla,
+ struct class_attribute *attr, const char *buf, size_t count)
+{
+ int i;
+ int ret;
+ char *op = NULL;
+
+ if (count != GXB_EFUSE_PATTERN_SIZE) {
+ pr_err("efuse: bad size, only support size %d!\n",
+ GXB_EFUSE_PATTERN_SIZE);
+ return -EINVAL;
+ }
+
+ op = kzalloc((sizeof(char)*count), GFP_KERNEL);
+ if (!op) {
+ ret = -ENOMEM;
+ pr_err("efuse: failed to allocate memory!\n");
+ return ret;
+ }
+
+ memset(op, 0, count);
+ for (i = 0; i < count; i++)
+ op[i] = buf[i];
+
+ ret = efuse_amlogic_set(op, count);
+ kfree(op);
+
+ if (ret) {
+ pr_err("EFUSE pattern programming fail! ret: %d\n", ret);
+ return -EINVAL;
+ }
+
+ pr_info("EFUSE pattern programming success!\n");
+
+ return count;
+}
+
static struct class_attribute efuse_class_attrs[] = {
#ifndef EFUSE_READ_ONLY
__ATTR(usid, 0700, show_usid, store_usid),
+ __ATTR_WO(amlogic_set),
+
__ATTR_NULL
};
#endif
#include <linux/amlogic/secmon.h>
#include <linux/arm-smccc.h>
+#include <asm/cacheflush.h>
static long meson_efuse_fn_smc(struct efuse_hal_api_arg *arg)
{
return ret;
}
+unsigned long efuse_aml_sec_boot_check(unsigned long nType,
+ unsigned long pBuffer,
+ unsigned long nLength,
+ unsigned long nOption)
+{
+ struct arm_smccc_res res;
+ long sharemem_phy_base;
+
+ sharemem_phy_base = get_secmon_phy_input_base();
+ if ((!sharemem_input_base) || (!sharemem_phy_base))
+ return -1;
+
+ sharemem_mutex_lock();
+
+ memcpy((void *)sharemem_input_base,
+ (const void *)pBuffer, nLength);
+
+ __flush_dcache_area(sharemem_input_base, nLength);
+
+ asm __volatile__("" : : : "memory");
+
+ do {
+ arm_smccc_smc((unsigned long)AML_DATA_PROCESS,
+ (unsigned long)nType,
+ (unsigned long)sharemem_phy_base,
+ (unsigned long)nLength,
+ (unsigned long)nOption,
+ 0, 0, 0, &res);
+ } while (0);
+
+ sharemem_mutex_unlock();
+
+ return res.a0;
+}
+
+unsigned long efuse_amlogic_set(char *buf, size_t count)
+{
+ unsigned long ret;
+
+ set_cpus_allowed_ptr(current, cpumask_of(0));
+
+ ret = efuse_aml_sec_boot_check(AML_D_P_W_EFUSE_AMLOGIC,
+ (unsigned long)buf, (unsigned long)count, 0);
+
+ set_cpus_allowed_ptr(current, cpu_all_mask);
+
+ return ret;
+}
+
ssize_t meson_trustzone_efuse_get_max(struct efuse_hal_api_arg *arg)
{
ssize_t ret;
{
return sharemem_out_base;
}
+
+long get_secmon_phy_input_base(void)
+{
+ return phy_in_base;
+}
+long get_secmon_phy_output_base(void)
+{
+ return phy_out_base;
+}
void __iomem *get_secmon_sharemem_input_base(void);
void __iomem *get_secmon_sharemem_output_base(void);
+long get_secmon_phy_input_base(void);
+long get_secmon_phy_output_base(void);
+
void sharemem_mutex_lock(void);
void sharemem_mutex_unlock(void);