efuse: support EFUSE pattern burning

PD#168568: G12A need to support EFUSE burning

1.add child node amlogic_set in efuse
2.node amlogic_set support EFUSE pattern burning

Change-Id: Ie20a8b61678e351cf32418879d4b40228e1d365f
Signed-off-by: Zhongfu Luo <zhongfu.luo@amlogic.com>
This commit is contained in:
Zhongfu Luo
2018-07-12 14:50:48 +08:00
parent a3f21fe9fb
commit 797ca58e55
5 changed files with 106 additions and 0 deletions

View File

@@ -46,6 +46,10 @@
#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;
@@ -97,6 +101,7 @@ extern struct clk *efuse_clk;
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

View File

@@ -483,6 +483,43 @@ static ssize_t userdata_write(struct class *cla,
}
#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
@@ -502,6 +539,8 @@ static struct class_attribute efuse_class_attrs[] = {
__ATTR(usid, 0700, show_usid, store_usid),
__ATTR_WO(amlogic_set),
__ATTR_NULL
};

View File

@@ -31,6 +31,7 @@
#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)
{
@@ -83,6 +84,55 @@ int meson_trustzone_efuse(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;

View File

@@ -148,3 +148,12 @@ void __iomem *get_secmon_sharemem_output_base(void)
{
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;
}

View File

@@ -20,6 +20,9 @@
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);