1361 lines
54 KiB
C
Executable File
1361 lines
54 KiB
C
Executable File
/* sec_nad.c
|
|
*
|
|
* Copyright (c) 2012 Samsung Electronics Co., Ltd
|
|
* http://www.samsung.com
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify it
|
|
* under the terms of the GNU General Public License as published by the
|
|
* Free Software Foundation; either version 2 of the License, or (at your
|
|
* option) any later version.
|
|
*
|
|
*/
|
|
|
|
#include <linux/device.h>
|
|
#include <linux/module.h>
|
|
#include <linux/sec_class.h>
|
|
#include <linux/sec_nad.h>
|
|
#include <linux/fs.h>
|
|
|
|
#define NAD_PRINT(format, ...) printk("[NAD] " format, ##__VA_ARGS__)
|
|
#define NAD_DEBUG
|
|
|
|
#if defined(CONFIG_SEC_FACTORY)
|
|
static void sec_nad_param_update(struct work_struct *work)
|
|
{
|
|
int ret = -1;
|
|
struct file *fp;
|
|
struct sec_nad_param *param_data =
|
|
container_of(work, struct sec_nad_param, sec_nad_work);
|
|
|
|
NAD_PRINT("%s: set param at %s\n", __func__, param_data->state ? "write" : "read");
|
|
|
|
fp = filp_open(NAD_PARAM_NAME, O_RDWR | O_SYNC, 0);
|
|
if (IS_ERR(fp)) {
|
|
pr_err("%s: filp_open error %ld\n", __func__, PTR_ERR(fp));
|
|
|
|
/* Rerun workqueue when nad_refer read fail */
|
|
if (param_data->retry_cnt > param_data->curr_cnt) {
|
|
NAD_PRINT("retry count : %d\n", param_data->curr_cnt++);
|
|
schedule_delayed_work(&sec_nad_param_data.sec_nad_delay_work, HZ * 1);
|
|
}
|
|
return;
|
|
}
|
|
ret = fp->f_op->llseek(fp, -param_data->offset, SEEK_END);
|
|
if (ret < 0) {
|
|
pr_err("%s: llseek error %d!\n", __func__, ret);
|
|
goto close_fp_out;
|
|
}
|
|
|
|
switch (param_data->state) {
|
|
case NAD_PARAM_WRITE:
|
|
ret = vfs_write(fp, (char *)&sec_nad_env, sizeof(struct nad_env), &(fp->f_pos));
|
|
|
|
if (ret < 0)
|
|
pr_err("%s: write error! %d\n", __func__, ret);
|
|
|
|
#ifdef NAD_DEBUG
|
|
NAD_PRINT(
|
|
"NAD factory : %s\n"
|
|
"NAD result : %s\n"
|
|
"NAD data : 0x%x\n"
|
|
"NAD ACAT : %s\n"
|
|
"NAD ACAT result : %s\n"
|
|
"NAD ACAT data : 0x%x\n"
|
|
"NAD ACAT loop count : %d\n"
|
|
"NAD ACAT real count : %d\n"
|
|
"NAD DRAM test need : %s\n"
|
|
"NAD DRAM test result : 0x%x\n"
|
|
"NAD DRAM test fail data : 0x%x\n"
|
|
"NAD DRAM test fail address : 0x%08lx\n"
|
|
"NAD status : %d\n"
|
|
"NAD ACAT skip fail : %d\n"
|
|
"NAD unlimited loop : %d\n", sec_nad_env.nad_factory,
|
|
sec_nad_env.nad_result,
|
|
sec_nad_env.nad_data,
|
|
sec_nad_env.nad_acat,
|
|
sec_nad_env.nad_acat_result,
|
|
sec_nad_env.nad_acat_data,
|
|
sec_nad_env.nad_acat_loop_count,
|
|
sec_nad_env.nad_acat_real_count,
|
|
sec_nad_env.nad_dram_test_need,
|
|
sec_nad_env.nad_dram_test_result,
|
|
sec_nad_env.nad_dram_fail_data,
|
|
sec_nad_env.nad_dram_fail_address,
|
|
sec_nad_env.current_nad_status,
|
|
sec_nad_env.nad_acat_skip_fail,
|
|
sec_nad_env.unlimited_loop);
|
|
|
|
#endif
|
|
break;
|
|
case NAD_PARAM_READ:
|
|
ret = vfs_read(fp, (char *)&sec_nad_env, sizeof(struct nad_env), &(fp->f_pos));
|
|
|
|
if (ret < 0)
|
|
pr_err("%s: read error! %d\n", __func__, ret);
|
|
#ifdef NAD_DEBUG
|
|
NAD_PRINT(
|
|
"NAD factory : %s\n"
|
|
"NAD result : %s\n"
|
|
"NAD data : 0x%x\n"
|
|
"NAD ACAT : %s\n"
|
|
"NAD ACAT result : %s\n"
|
|
"NAD ACAT data : 0x%x\n"
|
|
"NAD ACAT loop count : %d\n"
|
|
"NAD ACAT real count : %d\n"
|
|
"NAD DRAM test need : %s\n"
|
|
"NAD DRAM test result : 0x%x\n"
|
|
"NAD DRAM test fail data : 0x%x\n"
|
|
"NAD DRAM test fail address : 0x%08lx\n"
|
|
"NAD status : %d\n"
|
|
"NAD ACAT skip fail : %d\n"
|
|
"NAD unlimited loop : %d\n", sec_nad_env.nad_factory,
|
|
sec_nad_env.nad_result,
|
|
sec_nad_env.nad_data,
|
|
sec_nad_env.nad_acat,
|
|
sec_nad_env.nad_acat_result,
|
|
sec_nad_env.nad_acat_data,
|
|
sec_nad_env.nad_acat_loop_count,
|
|
sec_nad_env.nad_acat_real_count,
|
|
sec_nad_env.nad_dram_test_need,
|
|
sec_nad_env.nad_dram_test_result,
|
|
sec_nad_env.nad_dram_fail_data,
|
|
sec_nad_env.nad_dram_fail_address,
|
|
sec_nad_env.current_nad_status,
|
|
sec_nad_env.nad_acat_skip_fail,
|
|
sec_nad_env.unlimited_loop);
|
|
|
|
#endif
|
|
break;
|
|
}
|
|
close_fp_out:
|
|
if (fp)
|
|
filp_close(fp, NULL);
|
|
|
|
NAD_PRINT("%s: exit %d\n", __func__, ret);
|
|
return;
|
|
}
|
|
|
|
int sec_set_nad_param(int val)
|
|
{
|
|
int ret = -1;
|
|
|
|
mutex_lock(&sec_nad_param_lock);
|
|
|
|
switch (val) {
|
|
case NAD_PARAM_WRITE:
|
|
case NAD_PARAM_READ:
|
|
goto set_param;
|
|
default:
|
|
goto unlock_out;
|
|
}
|
|
|
|
set_param:
|
|
sec_nad_param_data.state = val;
|
|
schedule_work(&sec_nad_param_data.sec_nad_work);
|
|
|
|
/* how to determine to return success or fail ? */
|
|
ret = 0;
|
|
unlock_out:
|
|
mutex_unlock(&sec_nad_param_lock);
|
|
return ret;
|
|
}
|
|
|
|
static void sec_nad_init_update(struct work_struct *work)
|
|
{
|
|
int ret = -1;
|
|
|
|
NAD_PRINT("%s\n", __func__);
|
|
|
|
ret = sec_set_nad_param(NAD_PARAM_READ);
|
|
if (ret < 0)
|
|
pr_err("%s: read error! %d\n", __func__, ret);
|
|
|
|
}
|
|
|
|
#if defined(CONFIG_SEC_SUPPORT_VST)
|
|
static int get_vst_adjust(void)
|
|
{
|
|
int i = 0;
|
|
int bit = 1;
|
|
int tmp = 0;
|
|
int crc = 0;
|
|
int vst_adjust;
|
|
|
|
vst_adjust = sec_nad_env.vst_info.vst_adjust;
|
|
|
|
NAD_PRINT("vst_adjust : 0x%x\n", vst_adjust);
|
|
|
|
/* check crc */
|
|
crc = vst_adjust & 0x3;
|
|
vst_adjust = vst_adjust >> 2;
|
|
|
|
for (i = 0; i < 30; i++) {
|
|
if (bit & vst_adjust)
|
|
tmp++;
|
|
bit = bit << 1;
|
|
}
|
|
|
|
tmp = (tmp % 4);
|
|
if (tmp != 0)
|
|
tmp = 4 - tmp;
|
|
|
|
NAD_PRINT(" crc = %d, tmp = %d\n", crc, tmp);
|
|
|
|
if (crc != tmp)
|
|
return 0;
|
|
else
|
|
return vst_adjust & NAD_VST_ADJUST_MASK;
|
|
}
|
|
|
|
static int get_vst_result(void)
|
|
{
|
|
int vst_result;
|
|
|
|
vst_result = sec_nad_env.vst_info.vst_result;
|
|
|
|
NAD_PRINT("vst_result : 0x%x\n", vst_result);
|
|
|
|
/* check magic number */
|
|
if (((vst_result >> 8) & NAD_VST_MAGIC_MASK) == NAD_VST_MAGIC_NUM)
|
|
return ((vst_result >> 2) & NAD_VST_RESULT_MASK);
|
|
else
|
|
return 0;
|
|
}
|
|
#endif
|
|
|
|
static ssize_t show_nad_stat(struct device *dev,
|
|
struct device_attribute *attr,
|
|
char *buf)
|
|
{
|
|
NAD_PRINT("%s\n", __func__);
|
|
|
|
#if defined(CONFIG_SEC_SUPPORT_SECOND_NAD)
|
|
#if defined(CONFIG_SEC_NAD_HPM)
|
|
if (!strncasecmp(sec_nad_env.nad_result, "FAIL", 4) && !strncasecmp(sec_nad_env.nad_second_result, "FAIL", 4)) {
|
|
/* Both of NAD were failed. */
|
|
return sprintf(buf, "NG_3.1_L_0x%x_0x%x_0x%x_0x%x,IT(%d),MT(%d),"
|
|
"HPM_BIG_L%d(%d),HPM_BIG_L%d(%d),HPM_BIG_L%d(%d),HPM_BIG_L%d(%d),HPM_BIG_L%d(%d),HPM_BIG_L%d(%d),"
|
|
"HPM_BIG_L%d(%d),HPM_BIG_L%d(%d),HPM_BIG_L%d(%d),"
|
|
"HPM_LIT_L%d(%d),HPM_LIT_L%d(%d),HPM_LIT_L%d(%d),HPM_LIT_L%d(%d),HPM_LIT_L%d(%d),HPM_LIT_L%d(%d),"
|
|
"HPM_G3D_L%d(%d),HPM_G3D_L%d(%d),HPM_G3D_L%d(%d),HPM_G3D_L%d(%d),"
|
|
"HPM_MIF_L%d(%d),HPM_MIF_L%d(%d),HPM_MIF_L%d(%d),HPM_MIF_L%d(%d),HPM_MIF_L%d(%d),HPM_MIF_L%d(%d),"
|
|
"HPM_MIF_L%d(%d),HPM_MIF_L%d(%d),"
|
|
"HPM_INVALID(%d),HPM_PASS_FAIL(%d),"
|
|
"LOTID(%s),TBL_VER(%d),BIG_G(%d),LIT_G(%d),G3D_G(%d),MIF_G(%d),"
|
|
"HPM_BIG_DATA(%d;%d_%d_%d_%d_%d;%d_%d_%d_%d_%d;%d_%d_%d_%d_%d;%d_%d_%d_%d_%d;"
|
|
"%d_%d_%d_%d_%d;%d_%d_%d_%d_%d;%d_%d_%d_%d_%d;%d_%d_%d_%d_%d;%d_%d_%d_%d_%d),"
|
|
"HPM_LIT_DATA(%d;%d_%d_%d_%d_%d;%d_%d_%d_%d_%d;%d_%d_%d_%d_%d;%d_%d_%d_%d_%d;"
|
|
"%d_%d_%d_%d_%d;%d_%d_%d_%d_%d),"
|
|
"HPM_G3D_DATA(%d;%d_%d_%d_%d_%d;%d_%d_%d_%d_%d;%d_%d_%d_%d_%d;%d_%d_%d_%d_%d),"
|
|
"HPM_MIF_DATA(%d;%d_%d_%d_%d_%d;%d_%d_%d_%d_%d;%d_%d_%d_%d_%d;%d_%d_%d_%d_%d;"
|
|
"%d_%d_%d_%d_%d;%d_%d_%d_%d_%d;%d_%d_%d_%d_%d;%d_%d_%d_%d_%d),"
|
|
"DAS(%s),BLOCK(%s),"
|
|
"FN(%s_%s_%d_%s),FD(0x%08llx_0x%08llx_0x%08llx),"
|
|
#if defined(CONFIG_SEC_SUPPORT_VST)
|
|
"FNS(%s_%s_%d_%s),FDS(0x%08llx_0x%08llx_0x%08llx),VRES(%d),VADJ(%d),FRES(%d)\n",
|
|
#else
|
|
"FNS(%s_%s_%d_%s),FDS(0x%08llx_0x%08llx_0x%08llx)\n",
|
|
#endif
|
|
sec_nad_env.nad_data,
|
|
sec_nad_env.nad_inform2_data,
|
|
sec_nad_env.nad_second_data,
|
|
sec_nad_env.nad_second_inform2_data,
|
|
sec_nad_env.nad_init_temperature,
|
|
sec_nad_env.max_temperature,
|
|
/* Start HPM */
|
|
sec_nad_env.nad_hpm_info.hpm_info[0].hpm_level_info[0].level,
|
|
sec_nad_env.hpm_min_diff_level_big[0],
|
|
sec_nad_env.nad_hpm_info.hpm_info[0].hpm_level_info[1].level,
|
|
sec_nad_env.hpm_min_diff_level_big[1],
|
|
sec_nad_env.nad_hpm_info.hpm_info[0].hpm_level_info[2].level,
|
|
sec_nad_env.hpm_min_diff_level_big[2],
|
|
sec_nad_env.nad_hpm_info.hpm_info[0].hpm_level_info[3].level,
|
|
sec_nad_env.hpm_min_diff_level_big[3],
|
|
sec_nad_env.nad_hpm_info.hpm_info[0].hpm_level_info[4].level,
|
|
sec_nad_env.hpm_min_diff_level_big[4],
|
|
sec_nad_env.nad_hpm_info.hpm_info[0].hpm_level_info[5].level,
|
|
sec_nad_env.hpm_min_diff_level_big[5],
|
|
sec_nad_env.nad_hpm_info.hpm_info[0].hpm_level_info[6].level,
|
|
sec_nad_env.hpm_min_diff_level_big[6],
|
|
sec_nad_env.nad_hpm_info.hpm_info[0].hpm_level_info[7].level,
|
|
sec_nad_env.hpm_min_diff_level_big[7],
|
|
sec_nad_env.nad_hpm_info.hpm_info[0].hpm_level_info[8].level,
|
|
sec_nad_env.hpm_min_diff_level_big[8],
|
|
|
|
sec_nad_env.nad_hpm_info.hpm_info[1].hpm_level_info[0].level,
|
|
sec_nad_env.hpm_min_diff_level_lit[0],
|
|
sec_nad_env.nad_hpm_info.hpm_info[1].hpm_level_info[1].level,
|
|
sec_nad_env.hpm_min_diff_level_lit[1],
|
|
sec_nad_env.nad_hpm_info.hpm_info[1].hpm_level_info[2].level,
|
|
sec_nad_env.hpm_min_diff_level_lit[2],
|
|
sec_nad_env.nad_hpm_info.hpm_info[1].hpm_level_info[3].level,
|
|
sec_nad_env.hpm_min_diff_level_lit[3],
|
|
sec_nad_env.nad_hpm_info.hpm_info[1].hpm_level_info[4].level,
|
|
sec_nad_env.hpm_min_diff_level_lit[4],
|
|
sec_nad_env.nad_hpm_info.hpm_info[1].hpm_level_info[5].level,
|
|
sec_nad_env.hpm_min_diff_level_lit[5],
|
|
|
|
sec_nad_env.nad_hpm_info.hpm_info[2].hpm_level_info[0].level,
|
|
sec_nad_env.hpm_min_diff_level_g3d[0],
|
|
sec_nad_env.nad_hpm_info.hpm_info[2].hpm_level_info[1].level,
|
|
sec_nad_env.hpm_min_diff_level_g3d[1],
|
|
sec_nad_env.nad_hpm_info.hpm_info[2].hpm_level_info[2].level,
|
|
sec_nad_env.hpm_min_diff_level_g3d[2],
|
|
sec_nad_env.nad_hpm_info.hpm_info[2].hpm_level_info[3].level,
|
|
sec_nad_env.hpm_min_diff_level_g3d[3],
|
|
|
|
sec_nad_env.nad_hpm_info.hpm_info[3].hpm_level_info[0].level,
|
|
sec_nad_env.hpm_min_diff_level_mif[0],
|
|
sec_nad_env.nad_hpm_info.hpm_info[3].hpm_level_info[1].level,
|
|
sec_nad_env.hpm_min_diff_level_mif[1],
|
|
sec_nad_env.nad_hpm_info.hpm_info[3].hpm_level_info[2].level,
|
|
sec_nad_env.hpm_min_diff_level_mif[2],
|
|
sec_nad_env.nad_hpm_info.hpm_info[3].hpm_level_info[3].level,
|
|
sec_nad_env.hpm_min_diff_level_mif[3],
|
|
sec_nad_env.nad_hpm_info.hpm_info[3].hpm_level_info[4].level,
|
|
sec_nad_env.hpm_min_diff_level_mif[4],
|
|
sec_nad_env.nad_hpm_info.hpm_info[3].hpm_level_info[5].level,
|
|
sec_nad_env.hpm_min_diff_level_mif[5],
|
|
sec_nad_env.nad_hpm_info.hpm_info[3].hpm_level_info[6].level,
|
|
sec_nad_env.hpm_min_diff_level_mif[6],
|
|
sec_nad_env.nad_hpm_info.hpm_info[3].hpm_level_info[7].level,
|
|
sec_nad_env.hpm_min_diff_level_mif[7],
|
|
|
|
sec_nad_env.nad_hpm_info.hpm_invalid,
|
|
sec_nad_env.nad_hpm_info.device_pass_fail,
|
|
sec_nad_env.nad_hpm_info.LotID,
|
|
sec_nad_env.nad_hpm_info.asv_table_ver,
|
|
sec_nad_env.nad_hpm_info.big_grp,
|
|
sec_nad_env.nad_hpm_info.lit_grp,
|
|
sec_nad_env.nad_hpm_info.g3d_grp,
|
|
sec_nad_env.nad_hpm_info.mif_grp,
|
|
// BIG
|
|
sec_nad_env.nad_hpm_info.hpm_info[0].block_pass_fail,
|
|
sec_nad_env.nad_hpm_info.hpm_info[0].hpm_level_info[0].level,
|
|
sec_nad_env.nad_hpm_info.hpm_info[0].hpm_level_info[0].fused_hpm,
|
|
sec_nad_env.nad_hpm_info.hpm_info[0].hpm_level_info[0].pba_hpm_ave,
|
|
sec_nad_env.nad_hpm_info.hpm_info[0].hpm_level_info[0].pba_hpm_var,
|
|
sec_nad_env.nad_hpm_info.hpm_info[0].hpm_level_info[0].pba_hpm_min,
|
|
|
|
sec_nad_env.nad_hpm_info.hpm_info[0].hpm_level_info[1].level,
|
|
sec_nad_env.nad_hpm_info.hpm_info[0].hpm_level_info[1].fused_hpm,
|
|
sec_nad_env.nad_hpm_info.hpm_info[0].hpm_level_info[1].pba_hpm_ave,
|
|
sec_nad_env.nad_hpm_info.hpm_info[0].hpm_level_info[1].pba_hpm_var,
|
|
sec_nad_env.nad_hpm_info.hpm_info[0].hpm_level_info[1].pba_hpm_min,
|
|
|
|
sec_nad_env.nad_hpm_info.hpm_info[0].hpm_level_info[2].level,
|
|
sec_nad_env.nad_hpm_info.hpm_info[0].hpm_level_info[2].fused_hpm,
|
|
sec_nad_env.nad_hpm_info.hpm_info[0].hpm_level_info[2].pba_hpm_ave,
|
|
sec_nad_env.nad_hpm_info.hpm_info[0].hpm_level_info[2].pba_hpm_var,
|
|
sec_nad_env.nad_hpm_info.hpm_info[0].hpm_level_info[2].pba_hpm_min,
|
|
|
|
sec_nad_env.nad_hpm_info.hpm_info[0].hpm_level_info[3].level,
|
|
sec_nad_env.nad_hpm_info.hpm_info[0].hpm_level_info[3].fused_hpm,
|
|
sec_nad_env.nad_hpm_info.hpm_info[0].hpm_level_info[3].pba_hpm_ave,
|
|
sec_nad_env.nad_hpm_info.hpm_info[0].hpm_level_info[3].pba_hpm_var,
|
|
sec_nad_env.nad_hpm_info.hpm_info[0].hpm_level_info[3].pba_hpm_min,
|
|
|
|
sec_nad_env.nad_hpm_info.hpm_info[0].hpm_level_info[4].level,
|
|
sec_nad_env.nad_hpm_info.hpm_info[0].hpm_level_info[4].fused_hpm,
|
|
sec_nad_env.nad_hpm_info.hpm_info[0].hpm_level_info[4].pba_hpm_ave,
|
|
sec_nad_env.nad_hpm_info.hpm_info[0].hpm_level_info[4].pba_hpm_var,
|
|
sec_nad_env.nad_hpm_info.hpm_info[0].hpm_level_info[4].pba_hpm_min,
|
|
|
|
sec_nad_env.nad_hpm_info.hpm_info[0].hpm_level_info[5].level,
|
|
sec_nad_env.nad_hpm_info.hpm_info[0].hpm_level_info[5].fused_hpm,
|
|
sec_nad_env.nad_hpm_info.hpm_info[0].hpm_level_info[5].pba_hpm_ave,
|
|
sec_nad_env.nad_hpm_info.hpm_info[0].hpm_level_info[5].pba_hpm_var,
|
|
sec_nad_env.nad_hpm_info.hpm_info[0].hpm_level_info[5].pba_hpm_min,
|
|
|
|
sec_nad_env.nad_hpm_info.hpm_info[0].hpm_level_info[6].level,
|
|
sec_nad_env.nad_hpm_info.hpm_info[0].hpm_level_info[6].fused_hpm,
|
|
sec_nad_env.nad_hpm_info.hpm_info[0].hpm_level_info[6].pba_hpm_ave,
|
|
sec_nad_env.nad_hpm_info.hpm_info[0].hpm_level_info[6].pba_hpm_var,
|
|
sec_nad_env.nad_hpm_info.hpm_info[0].hpm_level_info[6].pba_hpm_min,
|
|
|
|
sec_nad_env.nad_hpm_info.hpm_info[0].hpm_level_info[7].level,
|
|
sec_nad_env.nad_hpm_info.hpm_info[0].hpm_level_info[7].fused_hpm,
|
|
sec_nad_env.nad_hpm_info.hpm_info[0].hpm_level_info[7].pba_hpm_ave,
|
|
sec_nad_env.nad_hpm_info.hpm_info[0].hpm_level_info[7].pba_hpm_var,
|
|
sec_nad_env.nad_hpm_info.hpm_info[0].hpm_level_info[7].pba_hpm_min,
|
|
|
|
sec_nad_env.nad_hpm_info.hpm_info[0].hpm_level_info[8].level,
|
|
sec_nad_env.nad_hpm_info.hpm_info[0].hpm_level_info[8].fused_hpm,
|
|
sec_nad_env.nad_hpm_info.hpm_info[0].hpm_level_info[8].pba_hpm_ave,
|
|
sec_nad_env.nad_hpm_info.hpm_info[0].hpm_level_info[8].pba_hpm_var,
|
|
sec_nad_env.nad_hpm_info.hpm_info[0].hpm_level_info[8].pba_hpm_min,
|
|
// Little
|
|
sec_nad_env.nad_hpm_info.hpm_info[1].block_pass_fail,
|
|
sec_nad_env.nad_hpm_info.hpm_info[1].hpm_level_info[0].level,
|
|
sec_nad_env.nad_hpm_info.hpm_info[1].hpm_level_info[0].fused_hpm,
|
|
sec_nad_env.nad_hpm_info.hpm_info[1].hpm_level_info[0].pba_hpm_ave,
|
|
sec_nad_env.nad_hpm_info.hpm_info[1].hpm_level_info[0].pba_hpm_var,
|
|
sec_nad_env.nad_hpm_info.hpm_info[1].hpm_level_info[0].pba_hpm_min,
|
|
|
|
sec_nad_env.nad_hpm_info.hpm_info[1].hpm_level_info[1].level,
|
|
sec_nad_env.nad_hpm_info.hpm_info[1].hpm_level_info[1].fused_hpm,
|
|
sec_nad_env.nad_hpm_info.hpm_info[1].hpm_level_info[1].pba_hpm_ave,
|
|
sec_nad_env.nad_hpm_info.hpm_info[1].hpm_level_info[1].pba_hpm_var,
|
|
sec_nad_env.nad_hpm_info.hpm_info[1].hpm_level_info[1].pba_hpm_min,
|
|
|
|
sec_nad_env.nad_hpm_info.hpm_info[1].hpm_level_info[2].level,
|
|
sec_nad_env.nad_hpm_info.hpm_info[1].hpm_level_info[2].fused_hpm,
|
|
sec_nad_env.nad_hpm_info.hpm_info[1].hpm_level_info[2].pba_hpm_ave,
|
|
sec_nad_env.nad_hpm_info.hpm_info[1].hpm_level_info[2].pba_hpm_var,
|
|
sec_nad_env.nad_hpm_info.hpm_info[1].hpm_level_info[2].pba_hpm_min,
|
|
|
|
sec_nad_env.nad_hpm_info.hpm_info[1].hpm_level_info[3].level,
|
|
sec_nad_env.nad_hpm_info.hpm_info[1].hpm_level_info[3].fused_hpm,
|
|
sec_nad_env.nad_hpm_info.hpm_info[1].hpm_level_info[3].pba_hpm_ave,
|
|
sec_nad_env.nad_hpm_info.hpm_info[1].hpm_level_info[3].pba_hpm_var,
|
|
sec_nad_env.nad_hpm_info.hpm_info[1].hpm_level_info[3].pba_hpm_min,
|
|
|
|
sec_nad_env.nad_hpm_info.hpm_info[1].hpm_level_info[4].level,
|
|
sec_nad_env.nad_hpm_info.hpm_info[1].hpm_level_info[4].fused_hpm,
|
|
sec_nad_env.nad_hpm_info.hpm_info[1].hpm_level_info[4].pba_hpm_ave,
|
|
sec_nad_env.nad_hpm_info.hpm_info[1].hpm_level_info[4].pba_hpm_var,
|
|
sec_nad_env.nad_hpm_info.hpm_info[1].hpm_level_info[4].pba_hpm_min,
|
|
|
|
sec_nad_env.nad_hpm_info.hpm_info[1].hpm_level_info[5].level,
|
|
sec_nad_env.nad_hpm_info.hpm_info[1].hpm_level_info[5].fused_hpm,
|
|
sec_nad_env.nad_hpm_info.hpm_info[1].hpm_level_info[5].pba_hpm_ave,
|
|
sec_nad_env.nad_hpm_info.hpm_info[1].hpm_level_info[5].pba_hpm_var,
|
|
sec_nad_env.nad_hpm_info.hpm_info[1].hpm_level_info[5].pba_hpm_min,
|
|
//G3D
|
|
sec_nad_env.nad_hpm_info.hpm_info[2].block_pass_fail,
|
|
sec_nad_env.nad_hpm_info.hpm_info[2].hpm_level_info[0].level,
|
|
sec_nad_env.nad_hpm_info.hpm_info[2].hpm_level_info[0].fused_hpm,
|
|
sec_nad_env.nad_hpm_info.hpm_info[2].hpm_level_info[0].pba_hpm_ave,
|
|
sec_nad_env.nad_hpm_info.hpm_info[2].hpm_level_info[0].pba_hpm_var,
|
|
sec_nad_env.nad_hpm_info.hpm_info[2].hpm_level_info[0].pba_hpm_min,
|
|
|
|
sec_nad_env.nad_hpm_info.hpm_info[2].hpm_level_info[1].level,
|
|
sec_nad_env.nad_hpm_info.hpm_info[2].hpm_level_info[1].fused_hpm,
|
|
sec_nad_env.nad_hpm_info.hpm_info[2].hpm_level_info[1].pba_hpm_ave,
|
|
sec_nad_env.nad_hpm_info.hpm_info[2].hpm_level_info[1].pba_hpm_var,
|
|
sec_nad_env.nad_hpm_info.hpm_info[2].hpm_level_info[1].pba_hpm_min,
|
|
|
|
sec_nad_env.nad_hpm_info.hpm_info[2].hpm_level_info[2].level,
|
|
sec_nad_env.nad_hpm_info.hpm_info[2].hpm_level_info[2].fused_hpm,
|
|
sec_nad_env.nad_hpm_info.hpm_info[2].hpm_level_info[2].pba_hpm_ave,
|
|
sec_nad_env.nad_hpm_info.hpm_info[2].hpm_level_info[2].pba_hpm_var,
|
|
sec_nad_env.nad_hpm_info.hpm_info[2].hpm_level_info[2].pba_hpm_min,
|
|
|
|
sec_nad_env.nad_hpm_info.hpm_info[2].hpm_level_info[3].level,
|
|
sec_nad_env.nad_hpm_info.hpm_info[2].hpm_level_info[3].fused_hpm,
|
|
sec_nad_env.nad_hpm_info.hpm_info[2].hpm_level_info[3].pba_hpm_ave,
|
|
sec_nad_env.nad_hpm_info.hpm_info[2].hpm_level_info[3].pba_hpm_var,
|
|
sec_nad_env.nad_hpm_info.hpm_info[2].hpm_level_info[3].pba_hpm_min,
|
|
//MIF
|
|
sec_nad_env.nad_hpm_info.hpm_info[3].block_pass_fail,
|
|
sec_nad_env.nad_hpm_info.hpm_info[3].hpm_level_info[0].level,
|
|
sec_nad_env.nad_hpm_info.hpm_info[3].hpm_level_info[0].fused_hpm,
|
|
sec_nad_env.nad_hpm_info.hpm_info[3].hpm_level_info[0].pba_hpm_ave,
|
|
sec_nad_env.nad_hpm_info.hpm_info[3].hpm_level_info[0].pba_hpm_var,
|
|
sec_nad_env.nad_hpm_info.hpm_info[3].hpm_level_info[0].pba_hpm_min,
|
|
|
|
sec_nad_env.nad_hpm_info.hpm_info[3].hpm_level_info[1].level,
|
|
sec_nad_env.nad_hpm_info.hpm_info[3].hpm_level_info[1].fused_hpm,
|
|
sec_nad_env.nad_hpm_info.hpm_info[3].hpm_level_info[1].pba_hpm_ave,
|
|
sec_nad_env.nad_hpm_info.hpm_info[3].hpm_level_info[1].pba_hpm_var,
|
|
sec_nad_env.nad_hpm_info.hpm_info[3].hpm_level_info[1].pba_hpm_min,
|
|
|
|
sec_nad_env.nad_hpm_info.hpm_info[3].hpm_level_info[2].level,
|
|
sec_nad_env.nad_hpm_info.hpm_info[3].hpm_level_info[2].fused_hpm,
|
|
sec_nad_env.nad_hpm_info.hpm_info[3].hpm_level_info[2].pba_hpm_ave,
|
|
sec_nad_env.nad_hpm_info.hpm_info[3].hpm_level_info[2].pba_hpm_var,
|
|
sec_nad_env.nad_hpm_info.hpm_info[3].hpm_level_info[2].pba_hpm_min,
|
|
|
|
sec_nad_env.nad_hpm_info.hpm_info[3].hpm_level_info[3].level,
|
|
sec_nad_env.nad_hpm_info.hpm_info[3].hpm_level_info[3].fused_hpm,
|
|
sec_nad_env.nad_hpm_info.hpm_info[3].hpm_level_info[3].pba_hpm_ave,
|
|
sec_nad_env.nad_hpm_info.hpm_info[3].hpm_level_info[3].pba_hpm_var,
|
|
sec_nad_env.nad_hpm_info.hpm_info[3].hpm_level_info[3].pba_hpm_min,
|
|
|
|
sec_nad_env.nad_hpm_info.hpm_info[3].hpm_level_info[4].level,
|
|
sec_nad_env.nad_hpm_info.hpm_info[3].hpm_level_info[4].fused_hpm,
|
|
sec_nad_env.nad_hpm_info.hpm_info[3].hpm_level_info[4].pba_hpm_ave,
|
|
sec_nad_env.nad_hpm_info.hpm_info[3].hpm_level_info[4].pba_hpm_var,
|
|
sec_nad_env.nad_hpm_info.hpm_info[3].hpm_level_info[4].pba_hpm_min,
|
|
|
|
sec_nad_env.nad_hpm_info.hpm_info[3].hpm_level_info[5].level,
|
|
sec_nad_env.nad_hpm_info.hpm_info[3].hpm_level_info[5].fused_hpm,
|
|
sec_nad_env.nad_hpm_info.hpm_info[3].hpm_level_info[5].pba_hpm_ave,
|
|
sec_nad_env.nad_hpm_info.hpm_info[3].hpm_level_info[5].pba_hpm_var,
|
|
sec_nad_env.nad_hpm_info.hpm_info[3].hpm_level_info[5].pba_hpm_min,
|
|
|
|
sec_nad_env.nad_hpm_info.hpm_info[3].hpm_level_info[6].level,
|
|
sec_nad_env.nad_hpm_info.hpm_info[3].hpm_level_info[6].fused_hpm,
|
|
sec_nad_env.nad_hpm_info.hpm_info[3].hpm_level_info[6].pba_hpm_ave,
|
|
sec_nad_env.nad_hpm_info.hpm_info[3].hpm_level_info[6].pba_hpm_var,
|
|
sec_nad_env.nad_hpm_info.hpm_info[3].hpm_level_info[6].pba_hpm_min,
|
|
|
|
sec_nad_env.nad_hpm_info.hpm_info[3].hpm_level_info[7].level,
|
|
sec_nad_env.nad_hpm_info.hpm_info[3].hpm_level_info[7].fused_hpm,
|
|
sec_nad_env.nad_hpm_info.hpm_info[3].hpm_level_info[7].pba_hpm_ave,
|
|
sec_nad_env.nad_hpm_info.hpm_info[3].hpm_level_info[7].pba_hpm_var,
|
|
sec_nad_env.nad_hpm_info.hpm_info[3].hpm_level_info[7].pba_hpm_min,
|
|
/* End of HPM */
|
|
sec_nad_env.nad_second_fail_info.das_string,
|
|
sec_nad_env.nad_second_fail_info.block_string,
|
|
sec_nad_env.nad_fail_info.das_string,
|
|
sec_nad_env.nad_fail_info.block_string,
|
|
sec_nad_env.nad_fail_info.level,
|
|
sec_nad_env.nad_fail_info.vector_string,
|
|
sec_nad_env.nad_dram_fail_information.nad_dram_fail_info[0].target_addr,
|
|
sec_nad_env.nad_dram_fail_information.nad_dram_fail_info[0].read_val,
|
|
sec_nad_env.nad_dram_fail_information.nad_dram_fail_info[0].expected_val,
|
|
sec_nad_env.nad_second_fail_info.das_string,
|
|
sec_nad_env.nad_second_fail_info.block_string,
|
|
sec_nad_env.nad_second_fail_info.level,
|
|
sec_nad_env.nad_second_fail_info.vector_string,
|
|
sec_nad_env.nad_second_dram_fail_information.nad_dram_fail_info[0].target_addr,
|
|
sec_nad_env.nad_second_dram_fail_information.nad_dram_fail_info[0].read_val,
|
|
#if defined(CONFIG_SEC_SUPPORT_VST)
|
|
sec_nad_env.nad_second_dram_fail_information.nad_dram_fail_info[0].expected_val,
|
|
/* VST */
|
|
get_vst_result(), get_vst_adjust(), sec_nad_env.vst_info.vst_f_res);
|
|
#else
|
|
sec_nad_env.nad_second_dram_fail_information.nad_dram_fail_info[0].expected_val);
|
|
#endif
|
|
} else {
|
|
return sprintf(buf, "OK_3.1_L_0x%x_0x%x_0x%x_0x%x,IT(%d),MT(%d),"
|
|
"HPM_BIG_L%d(%d),HPM_BIG_L%d(%d),HPM_BIG_L%d(%d),HPM_BIG_L%d(%d),HPM_BIG_L%d(%d),HPM_BIG_L%d(%d),"
|
|
"HPM_BIG_L%d(%d),HPM_BIG_L%d(%d),HPM_BIG_L%d(%d),"
|
|
"HPM_LIT_L%d(%d),HPM_LIT_L%d(%d),HPM_LIT_L%d(%d),HPM_LIT_L%d(%d),HPM_LIT_L%d(%d),HPM_LIT_L%d(%d),"
|
|
"HPM_G3D_L%d(%d),HPM_G3D_L%d(%d),HPM_G3D_L%d(%d),HPM_G3D_L%d(%d),"
|
|
"HPM_MIF_L%d(%d),HPM_MIF_L%d(%d),HPM_MIF_L%d(%d),HPM_MIF_L%d(%d),HPM_MIF_L%d(%d),HPM_MIF_L%d(%d),"
|
|
"HPM_MIF_L%d(%d),HPM_MIF_L%d(%d),"
|
|
"HPM_INVALID(%d),HPM_PASS_FAIL(%d),"
|
|
"LOTID(%s),TBL_VER(%d),BIG_G(%d),LIT_G(%d),G3D_G(%d),MIF_G(%d),"
|
|
"HPM_BIG_DATA(%d;%d_%d_%d_%d_%d;%d_%d_%d_%d_%d;%d_%d_%d_%d_%d;%d_%d_%d_%d_%d;"
|
|
"%d_%d_%d_%d_%d;%d_%d_%d_%d_%d;%d_%d_%d_%d_%d;%d_%d_%d_%d_%d;%d_%d_%d_%d_%d),"
|
|
"HPM_LIT_DATA(%d;%d_%d_%d_%d_%d;%d_%d_%d_%d_%d;%d_%d_%d_%d_%d;%d_%d_%d_%d_%d;"
|
|
"%d_%d_%d_%d_%d;%d_%d_%d_%d_%d),"
|
|
"HPM_G3D_DATA(%d;%d_%d_%d_%d_%d;%d_%d_%d_%d_%d;%d_%d_%d_%d_%d;%d_%d_%d_%d_%d),"
|
|
"HPM_MIF_DATA(%d;%d_%d_%d_%d_%d;%d_%d_%d_%d_%d;%d_%d_%d_%d_%d;%d_%d_%d_%d_%d;"
|
|
"%d_%d_%d_%d_%d;%d_%d_%d_%d_%d;%d_%d_%d_%d_%d;%d_%d_%d_%d_%d),"
|
|
#if defined(CONFIG_SEC_SUPPORT_VST)
|
|
"OT(0x%x),TN(%d),VRES(%d),VADJ(%d),FRES(%d)\n",
|
|
#else
|
|
"OT(0x%x),TN(%d)\n",
|
|
#endif
|
|
sec_nad_env.nad_data,
|
|
sec_nad_env.nad_inform2_data,
|
|
sec_nad_env.nad_second_data,
|
|
sec_nad_env.nad_second_inform2_data,
|
|
sec_nad_env.nad_init_temperature,
|
|
sec_nad_env.max_temperature,
|
|
/* Start HPM */
|
|
sec_nad_env.nad_hpm_info.hpm_info[0].hpm_level_info[0].level,
|
|
sec_nad_env.hpm_min_diff_level_big[0],
|
|
sec_nad_env.nad_hpm_info.hpm_info[0].hpm_level_info[1].level,
|
|
sec_nad_env.hpm_min_diff_level_big[1],
|
|
sec_nad_env.nad_hpm_info.hpm_info[0].hpm_level_info[2].level,
|
|
sec_nad_env.hpm_min_diff_level_big[2],
|
|
sec_nad_env.nad_hpm_info.hpm_info[0].hpm_level_info[3].level,
|
|
sec_nad_env.hpm_min_diff_level_big[3],
|
|
sec_nad_env.nad_hpm_info.hpm_info[0].hpm_level_info[4].level,
|
|
sec_nad_env.hpm_min_diff_level_big[4],
|
|
sec_nad_env.nad_hpm_info.hpm_info[0].hpm_level_info[5].level,
|
|
sec_nad_env.hpm_min_diff_level_big[5],
|
|
sec_nad_env.nad_hpm_info.hpm_info[0].hpm_level_info[6].level,
|
|
sec_nad_env.hpm_min_diff_level_big[6],
|
|
sec_nad_env.nad_hpm_info.hpm_info[0].hpm_level_info[7].level,
|
|
sec_nad_env.hpm_min_diff_level_big[7],
|
|
sec_nad_env.nad_hpm_info.hpm_info[0].hpm_level_info[8].level,
|
|
sec_nad_env.hpm_min_diff_level_big[8],
|
|
|
|
sec_nad_env.nad_hpm_info.hpm_info[1].hpm_level_info[0].level,
|
|
sec_nad_env.hpm_min_diff_level_lit[0],
|
|
sec_nad_env.nad_hpm_info.hpm_info[1].hpm_level_info[1].level,
|
|
sec_nad_env.hpm_min_diff_level_lit[1],
|
|
sec_nad_env.nad_hpm_info.hpm_info[1].hpm_level_info[2].level,
|
|
sec_nad_env.hpm_min_diff_level_lit[2],
|
|
sec_nad_env.nad_hpm_info.hpm_info[1].hpm_level_info[3].level,
|
|
sec_nad_env.hpm_min_diff_level_lit[3],
|
|
sec_nad_env.nad_hpm_info.hpm_info[1].hpm_level_info[4].level,
|
|
sec_nad_env.hpm_min_diff_level_lit[4],
|
|
sec_nad_env.nad_hpm_info.hpm_info[1].hpm_level_info[5].level,
|
|
sec_nad_env.hpm_min_diff_level_lit[5],
|
|
|
|
sec_nad_env.nad_hpm_info.hpm_info[2].hpm_level_info[0].level,
|
|
sec_nad_env.hpm_min_diff_level_g3d[0],
|
|
sec_nad_env.nad_hpm_info.hpm_info[2].hpm_level_info[1].level,
|
|
sec_nad_env.hpm_min_diff_level_g3d[1],
|
|
sec_nad_env.nad_hpm_info.hpm_info[2].hpm_level_info[2].level,
|
|
sec_nad_env.hpm_min_diff_level_g3d[2],
|
|
sec_nad_env.nad_hpm_info.hpm_info[2].hpm_level_info[3].level,
|
|
sec_nad_env.hpm_min_diff_level_g3d[3],
|
|
|
|
sec_nad_env.nad_hpm_info.hpm_info[3].hpm_level_info[0].level,
|
|
sec_nad_env.hpm_min_diff_level_mif[0],
|
|
sec_nad_env.nad_hpm_info.hpm_info[3].hpm_level_info[1].level,
|
|
sec_nad_env.hpm_min_diff_level_mif[1],
|
|
sec_nad_env.nad_hpm_info.hpm_info[3].hpm_level_info[2].level,
|
|
sec_nad_env.hpm_min_diff_level_mif[2],
|
|
sec_nad_env.nad_hpm_info.hpm_info[3].hpm_level_info[3].level,
|
|
sec_nad_env.hpm_min_diff_level_mif[3],
|
|
sec_nad_env.nad_hpm_info.hpm_info[3].hpm_level_info[4].level,
|
|
sec_nad_env.hpm_min_diff_level_mif[4],
|
|
sec_nad_env.nad_hpm_info.hpm_info[3].hpm_level_info[5].level,
|
|
sec_nad_env.hpm_min_diff_level_mif[5],
|
|
sec_nad_env.nad_hpm_info.hpm_info[3].hpm_level_info[6].level,
|
|
sec_nad_env.hpm_min_diff_level_mif[6],
|
|
sec_nad_env.nad_hpm_info.hpm_info[3].hpm_level_info[7].level,
|
|
sec_nad_env.hpm_min_diff_level_mif[7],
|
|
|
|
sec_nad_env.nad_hpm_info.hpm_invalid,
|
|
sec_nad_env.nad_hpm_info.device_pass_fail,
|
|
sec_nad_env.nad_hpm_info.LotID,
|
|
sec_nad_env.nad_hpm_info.asv_table_ver,
|
|
sec_nad_env.nad_hpm_info.big_grp,
|
|
sec_nad_env.nad_hpm_info.lit_grp,
|
|
sec_nad_env.nad_hpm_info.g3d_grp,
|
|
sec_nad_env.nad_hpm_info.mif_grp,
|
|
// BIG
|
|
sec_nad_env.nad_hpm_info.hpm_info[0].block_pass_fail,
|
|
sec_nad_env.nad_hpm_info.hpm_info[0].hpm_level_info[0].level,
|
|
sec_nad_env.nad_hpm_info.hpm_info[0].hpm_level_info[0].fused_hpm,
|
|
sec_nad_env.nad_hpm_info.hpm_info[0].hpm_level_info[0].pba_hpm_ave,
|
|
sec_nad_env.nad_hpm_info.hpm_info[0].hpm_level_info[0].pba_hpm_var,
|
|
sec_nad_env.nad_hpm_info.hpm_info[0].hpm_level_info[0].pba_hpm_min,
|
|
|
|
sec_nad_env.nad_hpm_info.hpm_info[0].hpm_level_info[1].level,
|
|
sec_nad_env.nad_hpm_info.hpm_info[0].hpm_level_info[1].fused_hpm,
|
|
sec_nad_env.nad_hpm_info.hpm_info[0].hpm_level_info[1].pba_hpm_ave,
|
|
sec_nad_env.nad_hpm_info.hpm_info[0].hpm_level_info[1].pba_hpm_var,
|
|
sec_nad_env.nad_hpm_info.hpm_info[0].hpm_level_info[1].pba_hpm_min,
|
|
|
|
sec_nad_env.nad_hpm_info.hpm_info[0].hpm_level_info[2].level,
|
|
sec_nad_env.nad_hpm_info.hpm_info[0].hpm_level_info[2].fused_hpm,
|
|
sec_nad_env.nad_hpm_info.hpm_info[0].hpm_level_info[2].pba_hpm_ave,
|
|
sec_nad_env.nad_hpm_info.hpm_info[0].hpm_level_info[2].pba_hpm_var,
|
|
sec_nad_env.nad_hpm_info.hpm_info[0].hpm_level_info[2].pba_hpm_min,
|
|
|
|
sec_nad_env.nad_hpm_info.hpm_info[0].hpm_level_info[3].level,
|
|
sec_nad_env.nad_hpm_info.hpm_info[0].hpm_level_info[3].fused_hpm,
|
|
sec_nad_env.nad_hpm_info.hpm_info[0].hpm_level_info[3].pba_hpm_ave,
|
|
sec_nad_env.nad_hpm_info.hpm_info[0].hpm_level_info[3].pba_hpm_var,
|
|
sec_nad_env.nad_hpm_info.hpm_info[0].hpm_level_info[3].pba_hpm_min,
|
|
|
|
sec_nad_env.nad_hpm_info.hpm_info[0].hpm_level_info[4].level,
|
|
sec_nad_env.nad_hpm_info.hpm_info[0].hpm_level_info[4].fused_hpm,
|
|
sec_nad_env.nad_hpm_info.hpm_info[0].hpm_level_info[4].pba_hpm_ave,
|
|
sec_nad_env.nad_hpm_info.hpm_info[0].hpm_level_info[4].pba_hpm_var,
|
|
sec_nad_env.nad_hpm_info.hpm_info[0].hpm_level_info[4].pba_hpm_min,
|
|
|
|
sec_nad_env.nad_hpm_info.hpm_info[0].hpm_level_info[5].level,
|
|
sec_nad_env.nad_hpm_info.hpm_info[0].hpm_level_info[5].fused_hpm,
|
|
sec_nad_env.nad_hpm_info.hpm_info[0].hpm_level_info[5].pba_hpm_ave,
|
|
sec_nad_env.nad_hpm_info.hpm_info[0].hpm_level_info[5].pba_hpm_var,
|
|
sec_nad_env.nad_hpm_info.hpm_info[0].hpm_level_info[5].pba_hpm_min,
|
|
|
|
sec_nad_env.nad_hpm_info.hpm_info[0].hpm_level_info[6].level,
|
|
sec_nad_env.nad_hpm_info.hpm_info[0].hpm_level_info[6].fused_hpm,
|
|
sec_nad_env.nad_hpm_info.hpm_info[0].hpm_level_info[6].pba_hpm_ave,
|
|
sec_nad_env.nad_hpm_info.hpm_info[0].hpm_level_info[6].pba_hpm_var,
|
|
sec_nad_env.nad_hpm_info.hpm_info[0].hpm_level_info[6].pba_hpm_min,
|
|
|
|
sec_nad_env.nad_hpm_info.hpm_info[0].hpm_level_info[7].level,
|
|
sec_nad_env.nad_hpm_info.hpm_info[0].hpm_level_info[7].fused_hpm,
|
|
sec_nad_env.nad_hpm_info.hpm_info[0].hpm_level_info[7].pba_hpm_ave,
|
|
sec_nad_env.nad_hpm_info.hpm_info[0].hpm_level_info[7].pba_hpm_var,
|
|
sec_nad_env.nad_hpm_info.hpm_info[0].hpm_level_info[7].pba_hpm_min,
|
|
|
|
sec_nad_env.nad_hpm_info.hpm_info[0].hpm_level_info[8].level,
|
|
sec_nad_env.nad_hpm_info.hpm_info[0].hpm_level_info[8].fused_hpm,
|
|
sec_nad_env.nad_hpm_info.hpm_info[0].hpm_level_info[8].pba_hpm_ave,
|
|
sec_nad_env.nad_hpm_info.hpm_info[0].hpm_level_info[8].pba_hpm_var,
|
|
sec_nad_env.nad_hpm_info.hpm_info[0].hpm_level_info[8].pba_hpm_min,
|
|
// Little
|
|
sec_nad_env.nad_hpm_info.hpm_info[1].block_pass_fail,
|
|
sec_nad_env.nad_hpm_info.hpm_info[1].hpm_level_info[0].level,
|
|
sec_nad_env.nad_hpm_info.hpm_info[1].hpm_level_info[0].fused_hpm,
|
|
sec_nad_env.nad_hpm_info.hpm_info[1].hpm_level_info[0].pba_hpm_ave,
|
|
sec_nad_env.nad_hpm_info.hpm_info[1].hpm_level_info[0].pba_hpm_var,
|
|
sec_nad_env.nad_hpm_info.hpm_info[1].hpm_level_info[0].pba_hpm_min,
|
|
|
|
sec_nad_env.nad_hpm_info.hpm_info[1].hpm_level_info[1].level,
|
|
sec_nad_env.nad_hpm_info.hpm_info[1].hpm_level_info[1].fused_hpm,
|
|
sec_nad_env.nad_hpm_info.hpm_info[1].hpm_level_info[1].pba_hpm_ave,
|
|
sec_nad_env.nad_hpm_info.hpm_info[1].hpm_level_info[1].pba_hpm_var,
|
|
sec_nad_env.nad_hpm_info.hpm_info[1].hpm_level_info[1].pba_hpm_min,
|
|
|
|
sec_nad_env.nad_hpm_info.hpm_info[1].hpm_level_info[2].level,
|
|
sec_nad_env.nad_hpm_info.hpm_info[1].hpm_level_info[2].fused_hpm,
|
|
sec_nad_env.nad_hpm_info.hpm_info[1].hpm_level_info[2].pba_hpm_ave,
|
|
sec_nad_env.nad_hpm_info.hpm_info[1].hpm_level_info[2].pba_hpm_var,
|
|
sec_nad_env.nad_hpm_info.hpm_info[1].hpm_level_info[2].pba_hpm_min,
|
|
|
|
sec_nad_env.nad_hpm_info.hpm_info[1].hpm_level_info[3].level,
|
|
sec_nad_env.nad_hpm_info.hpm_info[1].hpm_level_info[3].fused_hpm,
|
|
sec_nad_env.nad_hpm_info.hpm_info[1].hpm_level_info[3].pba_hpm_ave,
|
|
sec_nad_env.nad_hpm_info.hpm_info[1].hpm_level_info[3].pba_hpm_var,
|
|
sec_nad_env.nad_hpm_info.hpm_info[1].hpm_level_info[3].pba_hpm_min,
|
|
|
|
sec_nad_env.nad_hpm_info.hpm_info[1].hpm_level_info[4].level,
|
|
sec_nad_env.nad_hpm_info.hpm_info[1].hpm_level_info[4].fused_hpm,
|
|
sec_nad_env.nad_hpm_info.hpm_info[1].hpm_level_info[4].pba_hpm_ave,
|
|
sec_nad_env.nad_hpm_info.hpm_info[1].hpm_level_info[4].pba_hpm_var,
|
|
sec_nad_env.nad_hpm_info.hpm_info[1].hpm_level_info[4].pba_hpm_min,
|
|
|
|
sec_nad_env.nad_hpm_info.hpm_info[1].hpm_level_info[5].level,
|
|
sec_nad_env.nad_hpm_info.hpm_info[1].hpm_level_info[5].fused_hpm,
|
|
sec_nad_env.nad_hpm_info.hpm_info[1].hpm_level_info[5].pba_hpm_ave,
|
|
sec_nad_env.nad_hpm_info.hpm_info[1].hpm_level_info[5].pba_hpm_var,
|
|
sec_nad_env.nad_hpm_info.hpm_info[1].hpm_level_info[5].pba_hpm_min,
|
|
//G3D
|
|
sec_nad_env.nad_hpm_info.hpm_info[2].block_pass_fail,
|
|
sec_nad_env.nad_hpm_info.hpm_info[2].hpm_level_info[0].level,
|
|
sec_nad_env.nad_hpm_info.hpm_info[2].hpm_level_info[0].fused_hpm,
|
|
sec_nad_env.nad_hpm_info.hpm_info[2].hpm_level_info[0].pba_hpm_ave,
|
|
sec_nad_env.nad_hpm_info.hpm_info[2].hpm_level_info[0].pba_hpm_var,
|
|
sec_nad_env.nad_hpm_info.hpm_info[2].hpm_level_info[0].pba_hpm_min,
|
|
|
|
sec_nad_env.nad_hpm_info.hpm_info[2].hpm_level_info[1].level,
|
|
sec_nad_env.nad_hpm_info.hpm_info[2].hpm_level_info[1].fused_hpm,
|
|
sec_nad_env.nad_hpm_info.hpm_info[2].hpm_level_info[1].pba_hpm_ave,
|
|
sec_nad_env.nad_hpm_info.hpm_info[2].hpm_level_info[1].pba_hpm_var,
|
|
sec_nad_env.nad_hpm_info.hpm_info[2].hpm_level_info[1].pba_hpm_min,
|
|
|
|
sec_nad_env.nad_hpm_info.hpm_info[2].hpm_level_info[2].level,
|
|
sec_nad_env.nad_hpm_info.hpm_info[2].hpm_level_info[2].fused_hpm,
|
|
sec_nad_env.nad_hpm_info.hpm_info[2].hpm_level_info[2].pba_hpm_ave,
|
|
sec_nad_env.nad_hpm_info.hpm_info[2].hpm_level_info[2].pba_hpm_var,
|
|
sec_nad_env.nad_hpm_info.hpm_info[2].hpm_level_info[2].pba_hpm_min,
|
|
|
|
sec_nad_env.nad_hpm_info.hpm_info[2].hpm_level_info[3].level,
|
|
sec_nad_env.nad_hpm_info.hpm_info[2].hpm_level_info[3].fused_hpm,
|
|
sec_nad_env.nad_hpm_info.hpm_info[2].hpm_level_info[3].pba_hpm_ave,
|
|
sec_nad_env.nad_hpm_info.hpm_info[2].hpm_level_info[3].pba_hpm_var,
|
|
sec_nad_env.nad_hpm_info.hpm_info[2].hpm_level_info[3].pba_hpm_min,
|
|
//MIF
|
|
sec_nad_env.nad_hpm_info.hpm_info[3].block_pass_fail,
|
|
sec_nad_env.nad_hpm_info.hpm_info[3].hpm_level_info[0].level,
|
|
sec_nad_env.nad_hpm_info.hpm_info[3].hpm_level_info[0].fused_hpm,
|
|
sec_nad_env.nad_hpm_info.hpm_info[3].hpm_level_info[0].pba_hpm_ave,
|
|
sec_nad_env.nad_hpm_info.hpm_info[3].hpm_level_info[0].pba_hpm_var,
|
|
sec_nad_env.nad_hpm_info.hpm_info[3].hpm_level_info[0].pba_hpm_min,
|
|
|
|
sec_nad_env.nad_hpm_info.hpm_info[3].hpm_level_info[1].level,
|
|
sec_nad_env.nad_hpm_info.hpm_info[3].hpm_level_info[1].fused_hpm,
|
|
sec_nad_env.nad_hpm_info.hpm_info[3].hpm_level_info[1].pba_hpm_ave,
|
|
sec_nad_env.nad_hpm_info.hpm_info[3].hpm_level_info[1].pba_hpm_var,
|
|
sec_nad_env.nad_hpm_info.hpm_info[3].hpm_level_info[1].pba_hpm_min,
|
|
|
|
sec_nad_env.nad_hpm_info.hpm_info[3].hpm_level_info[2].level,
|
|
sec_nad_env.nad_hpm_info.hpm_info[3].hpm_level_info[2].fused_hpm,
|
|
sec_nad_env.nad_hpm_info.hpm_info[3].hpm_level_info[2].pba_hpm_ave,
|
|
sec_nad_env.nad_hpm_info.hpm_info[3].hpm_level_info[2].pba_hpm_var,
|
|
sec_nad_env.nad_hpm_info.hpm_info[3].hpm_level_info[2].pba_hpm_min,
|
|
|
|
sec_nad_env.nad_hpm_info.hpm_info[3].hpm_level_info[3].level,
|
|
sec_nad_env.nad_hpm_info.hpm_info[3].hpm_level_info[3].fused_hpm,
|
|
sec_nad_env.nad_hpm_info.hpm_info[3].hpm_level_info[3].pba_hpm_ave,
|
|
sec_nad_env.nad_hpm_info.hpm_info[3].hpm_level_info[3].pba_hpm_var,
|
|
sec_nad_env.nad_hpm_info.hpm_info[3].hpm_level_info[3].pba_hpm_min,
|
|
|
|
sec_nad_env.nad_hpm_info.hpm_info[3].hpm_level_info[4].level,
|
|
sec_nad_env.nad_hpm_info.hpm_info[3].hpm_level_info[4].fused_hpm,
|
|
sec_nad_env.nad_hpm_info.hpm_info[3].hpm_level_info[4].pba_hpm_ave,
|
|
sec_nad_env.nad_hpm_info.hpm_info[3].hpm_level_info[4].pba_hpm_var,
|
|
sec_nad_env.nad_hpm_info.hpm_info[3].hpm_level_info[4].pba_hpm_min,
|
|
|
|
sec_nad_env.nad_hpm_info.hpm_info[3].hpm_level_info[5].level,
|
|
sec_nad_env.nad_hpm_info.hpm_info[3].hpm_level_info[5].fused_hpm,
|
|
sec_nad_env.nad_hpm_info.hpm_info[3].hpm_level_info[5].pba_hpm_ave,
|
|
sec_nad_env.nad_hpm_info.hpm_info[3].hpm_level_info[5].pba_hpm_var,
|
|
sec_nad_env.nad_hpm_info.hpm_info[3].hpm_level_info[5].pba_hpm_min,
|
|
|
|
sec_nad_env.nad_hpm_info.hpm_info[3].hpm_level_info[6].level,
|
|
sec_nad_env.nad_hpm_info.hpm_info[3].hpm_level_info[6].fused_hpm,
|
|
sec_nad_env.nad_hpm_info.hpm_info[3].hpm_level_info[6].pba_hpm_ave,
|
|
sec_nad_env.nad_hpm_info.hpm_info[3].hpm_level_info[6].pba_hpm_var,
|
|
sec_nad_env.nad_hpm_info.hpm_info[3].hpm_level_info[6].pba_hpm_min,
|
|
|
|
sec_nad_env.nad_hpm_info.hpm_info[3].hpm_level_info[7].level,
|
|
sec_nad_env.nad_hpm_info.hpm_info[3].hpm_level_info[7].fused_hpm,
|
|
sec_nad_env.nad_hpm_info.hpm_info[3].hpm_level_info[7].pba_hpm_ave,
|
|
sec_nad_env.nad_hpm_info.hpm_info[3].hpm_level_info[7].pba_hpm_var,
|
|
sec_nad_env.nad_hpm_info.hpm_info[3].hpm_level_info[7].pba_hpm_min,
|
|
/* End of HPM */
|
|
sec_nad_env.nad_inform3_data,
|
|
#if defined(CONFIG_SEC_SUPPORT_VST)
|
|
sec_nad_env.nad_inform3_data & 0xFF,
|
|
/* VST */
|
|
get_vst_result(), get_vst_adjust(), sec_nad_env.vst_info.vst_f_res);
|
|
#else
|
|
sec_nad_env.nad_inform3_data & 0xFF);
|
|
#endif
|
|
|
|
}
|
|
#else
|
|
if (!strncasecmp(sec_nad_env.nad_result, "FAIL", 4) && !strncasecmp(sec_nad_env.nad_second_result, "FAIL", 4)) {
|
|
/* Both of NAD were failed. */
|
|
return sprintf(buf,
|
|
"NG_3.1_L_0x%x_0x%x_0x%x_0x%x,IT(%d),MT(%d),DAS(%s),BLOCK(%s),"
|
|
"FN(%s_%s_%d_%s),FD(0x%08llx_0x%08llx_0x%08llx),"
|
|
#if defined(CONFIG_SEC_SUPPORT_VST)
|
|
"FNS(%s_%s_%d_%s),FDS(0x%08llx_0x%08llx_0x%08llx),VRES(%d),VADJ(%d),FRES(%d)\n",
|
|
#else
|
|
"FNS(%s_%s_%d_%s),FDS(0x%08llx_0x%08llx_0x%08llx)\n",
|
|
#endif
|
|
sec_nad_env.nad_data,
|
|
sec_nad_env.nad_inform2_data,
|
|
sec_nad_env.nad_second_data,
|
|
sec_nad_env.nad_second_inform2_data,
|
|
sec_nad_env.nad_init_temperature,
|
|
sec_nad_env.max_temperature,
|
|
sec_nad_env.nad_second_fail_info.das_string,
|
|
sec_nad_env.nad_second_fail_info.block_string,
|
|
sec_nad_env.nad_fail_info.das_string,
|
|
sec_nad_env.nad_fail_info.block_string,
|
|
sec_nad_env.nad_fail_info.level,
|
|
sec_nad_env.nad_fail_info.vector_string,
|
|
sec_nad_env.nad_dram_fail_information.nad_dram_fail_info[0].target_addr,
|
|
sec_nad_env.nad_dram_fail_information.nad_dram_fail_info[0].read_val,
|
|
sec_nad_env.nad_dram_fail_information.nad_dram_fail_info[0].expected_val,
|
|
sec_nad_env.nad_second_fail_info.das_string,
|
|
sec_nad_env.nad_second_fail_info.block_string,
|
|
sec_nad_env.nad_second_fail_info.level,
|
|
sec_nad_env.nad_second_fail_info.vector_string,
|
|
sec_nad_env.nad_second_dram_fail_information.nad_dram_fail_info[0].target_addr,
|
|
sec_nad_env.nad_second_dram_fail_information.nad_dram_fail_info[0].read_val,
|
|
#if defined(CONFIG_SEC_SUPPORT_VST)
|
|
sec_nad_env.nad_second_dram_fail_information.nad_dram_fail_info[0].expected_val,
|
|
/* VST */
|
|
get_vst_result(), get_vst_adjust(), sec_nad_env.vst_info.vst_f_res);
|
|
#else
|
|
sec_nad_env.nad_second_dram_fail_information.nad_dram_fail_info[0].expected_val);
|
|
#endif
|
|
} else {
|
|
return sprintf(buf, "OK_3.1_L_0x%x_0x%x_0x%x_0x%x,IT(%d),MT(%d),OT(0x%x),"
|
|
#if defined(CONFIG_SEC_SUPPORT_VST)
|
|
"TN(%d),VRES(%d),VADJ(%d),FRES(%d)\n",
|
|
#else
|
|
"TN(%d)\n",
|
|
#endif
|
|
sec_nad_env.nad_data,
|
|
sec_nad_env.nad_inform2_data,
|
|
sec_nad_env.nad_second_data,
|
|
sec_nad_env.nad_second_inform2_data,
|
|
sec_nad_env.nad_init_temperature,
|
|
sec_nad_env.max_temperature,
|
|
sec_nad_env.nad_inform3_data,
|
|
#if defined(CONFIG_SEC_SUPPORT_VST)
|
|
sec_nad_env.nad_inform3_data & 0xFF,
|
|
/* VST */
|
|
get_vst_result(), get_vst_adjust(), sec_nad_env.vst_info.vst_f_res);
|
|
#else
|
|
sec_nad_env.nad_inform3_data & 0xFF);
|
|
#endif
|
|
}
|
|
#endif
|
|
#else
|
|
if (!strncasecmp(sec_nad_env.nad_result, "FAIL", 4))
|
|
return sprintf(buf, "NG_2.0_0x%x,T(%d)\n", sec_nad_env.nad_data, sec_nad_env.max_temperature);
|
|
else
|
|
return sprintf(buf, "OK_2.0_0x%x,T(%d)\n", sec_nad_env.nad_data, sec_nad_env.max_temperature);
|
|
#endif
|
|
}
|
|
static DEVICE_ATTR(nad_stat, S_IRUGO, show_nad_stat, NULL);
|
|
|
|
static ssize_t store_nad_erase(struct device *dev,
|
|
struct device_attribute *attr,
|
|
const char *buf, size_t count)
|
|
{
|
|
int ret = -1;
|
|
|
|
if (!strncmp(buf, "erase", 5)) {
|
|
strncpy(sec_nad_env.nad_factory, "GAP", 3);
|
|
#if defined(CONFIG_SEC_SUPPORT_SECOND_NAD)
|
|
strncpy(sec_nad_env.nad_second, "DUMM", 4);
|
|
#endif
|
|
#if defined(CONFIG_SEC_NAD_HPM)
|
|
/* Initialize NAD HPM data */
|
|
memset(&sec_nad_env.nad_hpm_info, 0, sizeof(nad_hpm));
|
|
memset(&sec_nad_env.hpm_min_diff_level_big, 0, sizeof(sec_nad_env.hpm_min_diff_level_big));
|
|
memset(&sec_nad_env.hpm_min_diff_level_lit, 0, sizeof(sec_nad_env.hpm_min_diff_level_lit));
|
|
memset(&sec_nad_env.hpm_min_diff_level_g3d, 0, sizeof(sec_nad_env.hpm_min_diff_level_g3d));
|
|
memset(&sec_nad_env.hpm_min_diff_level_mif, 0, sizeof(sec_nad_env.hpm_min_diff_level_mif));
|
|
#endif
|
|
#if defined(CONFIG_SEC_NAD_API)
|
|
sec_nad_env.nad_api_status = 0;
|
|
#endif
|
|
ret = sec_set_nad_param(NAD_PARAM_WRITE);
|
|
if (ret < 0)
|
|
pr_err("%s: write error! %d\n", __func__, ret);
|
|
|
|
return count;
|
|
} else
|
|
return count;
|
|
}
|
|
|
|
static ssize_t show_nad_erase(struct device *dev,
|
|
struct device_attribute *attr,
|
|
char *buf)
|
|
{
|
|
NAD_PRINT("%s\n", __func__);
|
|
|
|
if (!strncmp(sec_nad_env.nad_factory, "GAP", 3))
|
|
return sprintf(buf, "OK\n");
|
|
else
|
|
return sprintf(buf, "NG\n");
|
|
}
|
|
|
|
static DEVICE_ATTR(nad_erase, S_IRUGO | S_IWUSR, show_nad_erase, store_nad_erase);
|
|
|
|
static ssize_t show_nad_acat(struct device *dev,
|
|
struct device_attribute *attr,
|
|
char *buf)
|
|
{
|
|
NAD_PRINT("%s\n", __func__);
|
|
|
|
#if defined(CONFIG_SEC_SUPPORT_SECOND_NAD)
|
|
#if defined(CONFIG_SEC_NAD_HPM)
|
|
/* Check status if ACAT NAD was excuted */
|
|
if (sec_nad_env.current_nad_status >= NAD_ACAT_FLAG) {
|
|
if (!strncasecmp(sec_nad_env.nad_acat_result, "FAIL", 4) && !strncasecmp(sec_nad_env.nad_acat_second_result, "FAIL", 4)) {
|
|
return sprintf(buf, "NG_3.0_L_0x%x_0x%x_0x%x_0x%x,%d,%d,HPM(NULL),%s,%s,"
|
|
"FN(%s_%s_%d_%s),FD(0x%08llx_0x%08llx_0x%08llx),"
|
|
"FNS(%s_%s_%d_%s),FDS(0x%08llx_0x%08llx_0x%08llx)\n",
|
|
sec_nad_env.nad_acat_data,
|
|
sec_nad_env.nad_acat_inform2_data,
|
|
sec_nad_env.nad_acat_second_data,
|
|
sec_nad_env.nad_acat_second_inform2_data,
|
|
sec_nad_env.nad_acat_init_temperature,
|
|
sec_nad_env.nad_acat_max_temperature,
|
|
sec_nad_env.nad_acat_second_fail_info.das_string,
|
|
sec_nad_env.nad_acat_second_fail_info.block_string,
|
|
sec_nad_env.nad_acat_fail_info.das_string,
|
|
sec_nad_env.nad_acat_fail_info.block_string,
|
|
sec_nad_env.nad_acat_fail_info.level,
|
|
sec_nad_env.nad_acat_fail_info.vector_string,
|
|
sec_nad_env.nad_acat_dram_fail_information.nad_dram_fail_info[0].target_addr,
|
|
sec_nad_env.nad_acat_dram_fail_information.nad_dram_fail_info[0].read_val,
|
|
sec_nad_env.nad_acat_dram_fail_information.nad_dram_fail_info[0].expected_val,
|
|
sec_nad_env.nad_acat_second_fail_info.das_string,
|
|
sec_nad_env.nad_acat_second_fail_info.block_string,
|
|
sec_nad_env.nad_acat_second_fail_info.level,
|
|
sec_nad_env.nad_acat_second_fail_info.vector_string,
|
|
sec_nad_env.nad_acat_second_dram_fail_information.nad_dram_fail_info[0].target_addr,
|
|
sec_nad_env.nad_acat_second_dram_fail_information.nad_dram_fail_info[0].read_val,
|
|
sec_nad_env.nad_acat_second_dram_fail_information.nad_dram_fail_info[0].expected_val);
|
|
} else {
|
|
return sprintf(buf, "OK_3.0_L_0x%x_0x%x_0x%x_0x%x,%d,%d,HPM(NULL),OT(0x%x)\n",
|
|
sec_nad_env.nad_acat_data,
|
|
sec_nad_env.nad_acat_inform2_data,
|
|
sec_nad_env.nad_acat_second_data,
|
|
sec_nad_env.nad_acat_second_inform2_data,
|
|
sec_nad_env.nad_acat_init_temperature,
|
|
sec_nad_env.nad_acat_max_temperature,
|
|
sec_nad_env.nad_acat_inform3_data);
|
|
}
|
|
} else
|
|
return sprintf(buf, "NO_3.0_L_NADTEST\n");
|
|
#else
|
|
/* Check status if ACAT NAD was excuted */
|
|
if (sec_nad_env.current_nad_status >= NAD_ACAT_FLAG) {
|
|
if (!strncasecmp(sec_nad_env.nad_acat_result, "FAIL", 4) && !strncasecmp(sec_nad_env.nad_acat_second_result, "FAIL", 4)) {
|
|
return sprintf(buf, "NG_3.0_L_0x%x_0x%x_0x%x_0x%x,%d,%d,HPM(NULL),%s,%s,"
|
|
"FN(%s_%s_%d_%s),FD(0x%08llx_0x%08llx_0x%08llx),"
|
|
"FNS(%s_%s_%d_%s),FDS(0x%08llx_0x%08llx_0x%08llx)\n",
|
|
sec_nad_env.nad_acat_data,
|
|
sec_nad_env.nad_acat_inform2_data,
|
|
sec_nad_env.nad_acat_second_data,
|
|
sec_nad_env.nad_acat_second_inform2_data,
|
|
sec_nad_env.nad_acat_init_temperature,
|
|
sec_nad_env.nad_acat_max_temperature,
|
|
sec_nad_env.nad_acat_second_fail_info.das_string,
|
|
sec_nad_env.nad_acat_second_fail_info.block_string,
|
|
sec_nad_env.nad_acat_fail_info.das_string,
|
|
sec_nad_env.nad_acat_fail_info.block_string,
|
|
sec_nad_env.nad_acat_fail_info.level,
|
|
sec_nad_env.nad_acat_fail_info.vector_string,
|
|
sec_nad_env.nad_acat_dram_fail_information.nad_dram_fail_info[0].target_addr,
|
|
sec_nad_env.nad_acat_dram_fail_information.nad_dram_fail_info[0].read_val,
|
|
sec_nad_env.nad_acat_dram_fail_information.nad_dram_fail_info[0].expected_val,
|
|
sec_nad_env.nad_acat_second_fail_info.das_string,
|
|
sec_nad_env.nad_acat_second_fail_info.block_string,
|
|
sec_nad_env.nad_acat_second_fail_info.level,
|
|
sec_nad_env.nad_acat_second_fail_info.vector_string,
|
|
sec_nad_env.nad_acat_second_dram_fail_information.nad_dram_fail_info[0].target_addr,
|
|
sec_nad_env.nad_acat_second_dram_fail_information.nad_dram_fail_info[0].read_val,
|
|
sec_nad_env.nad_acat_second_dram_fail_information.nad_dram_fail_info[0].expected_val);
|
|
} else {
|
|
return sprintf(buf, "OK_3.0_L_0x%x_0x%x_0x%x_0x%x,%d,%d,HPM(NULL),OT(0x%x)\n",
|
|
sec_nad_env.nad_acat_data,
|
|
sec_nad_env.nad_acat_inform2_data,
|
|
sec_nad_env.nad_acat_second_data,
|
|
sec_nad_env.nad_acat_second_inform2_data,
|
|
sec_nad_env.nad_acat_init_temperature,
|
|
sec_nad_env.nad_acat_max_temperature,
|
|
sec_nad_env.nad_acat_inform3_data);
|
|
}
|
|
} else
|
|
return sprintf(buf, "NO_3.0_L_NADTEST\n");
|
|
#endif
|
|
#else
|
|
/* Check status if ACAT NAD was excuted */
|
|
if (sec_nad_env.current_nad_status == NAD_ACAT_FLAG) {
|
|
if (!strncasecmp(sec_nad_env.nad_acat_result, "FAIL", 4))
|
|
return sprintf(buf, "NG_ACAT_0x%x,T(%d)\n", sec_nad_env.nad_acat_data, sec_nad_env.nad_acat_max_temperature);
|
|
else
|
|
return sprintf(buf, "OK_ACAT_0x%x,T(%d)\n", sec_nad_env.nad_acat_data, sec_nad_env.nad_acat_max_temperature);
|
|
} else
|
|
return sprintf(buf, "NO_ACAT_NADTEST\n");
|
|
#endif
|
|
}
|
|
|
|
static ssize_t store_nad_acat(struct device *dev,
|
|
struct device_attribute *attr,
|
|
const char *buf, size_t count)
|
|
{
|
|
int ret = -1;
|
|
int idx = 0;
|
|
char temp[NAD_BUFF_SIZE*3];
|
|
char nad_cmd[NAD_CMD_LIST][NAD_BUFF_SIZE];
|
|
char *nad_ptr, *string;
|
|
unsigned int len = 0;
|
|
|
|
NAD_PRINT("buf : %s count : %d\n", buf, (int)count);
|
|
|
|
if ((int)count < NAD_BUFF_SIZE)
|
|
return -EINVAL;
|
|
|
|
/* Copy buf to nad temp */
|
|
len = (unsigned int)min(count, sizeof(temp) - 1);
|
|
strncpy(temp, buf, len);
|
|
temp[len] = '\0';
|
|
string = temp;
|
|
|
|
while (idx < NAD_CMD_LIST) {
|
|
nad_ptr = strsep(&string, ",");
|
|
if (nad_ptr == NULL || strlen(nad_ptr) >= NAD_BUFF_SIZE) {
|
|
NAD_PRINT(" %s: invalid input\n",__func__);
|
|
return -EINVAL;
|
|
}
|
|
strcpy(nad_cmd[idx++], nad_ptr);
|
|
}
|
|
|
|
/*
|
|
* ACAT NAD Write Data format
|
|
*
|
|
* nad_acat,20,0 : ACAT Loop test (20 cycles)
|
|
* nad_acat,20,1 : ACAT Loop & DRAM test (20 cycles & 1 DRAM test)
|
|
* nad_acat,0,1 : ACAT DRAM test (1 DRAM test)
|
|
*
|
|
*/
|
|
if (!strncmp(buf, "nad_acat", 8)) {
|
|
/* Get NAD loop count */
|
|
ret = sscanf(nad_cmd[1], "%d\n", &sec_nad_env.nad_acat_loop_count);
|
|
if (ret != 1)
|
|
return -EINVAL;
|
|
|
|
/* case 1 : ACAT NAD */
|
|
if (sec_nad_env.nad_acat_loop_count > 0) {
|
|
NAD_PRINT("ACAT NAD test command.\n");
|
|
|
|
strncpy(sec_nad_env.nad_acat, "ACAT", 4);
|
|
#if defined(CONFIG_SEC_SUPPORT_SECOND_NAD)
|
|
strncpy(sec_nad_env.nad_acat_second, "DUMM", 4);
|
|
sec_nad_env.nad_acat_second_running_count = 0;
|
|
sec_nad_env.acat_fail_retry_count = 0;
|
|
sec_nad_env.nad_acat_real_count = 0;
|
|
#endif
|
|
sec_nad_env.nad_acat_data = 0;
|
|
sec_nad_env.nad_acat_real_count = 0;
|
|
sec_nad_env.current_nad_status = 0;
|
|
sec_nad_env.nad_acat_skip_fail = 0;
|
|
sec_nad_env.unlimited_loop = 0;
|
|
sec_nad_env.max_temperature = 0;
|
|
sec_nad_env.nad_acat_max_temperature = 0;
|
|
}
|
|
|
|
/* case 2 : DRAM test */
|
|
if (!strncmp(nad_cmd[2], "1", 1)) {
|
|
NAD_PRINT("DRAM test command.\n");
|
|
|
|
strncpy(sec_nad_env.nad_dram_test_need, "DRAM", 4);
|
|
sec_nad_env.nad_dram_test_result = 0;
|
|
sec_nad_env.nad_dram_fail_data = 0;
|
|
sec_nad_env.nad_dram_fail_address = 0;
|
|
} else
|
|
strncpy(sec_nad_env.nad_dram_test_need, "DONE", 4);
|
|
|
|
ret = sec_set_nad_param(NAD_PARAM_WRITE);
|
|
if (ret < 0) {
|
|
pr_err("%s: write error! %d\n", __func__, ret);
|
|
goto err_out;
|
|
}
|
|
|
|
return count;
|
|
} else
|
|
return count;
|
|
err_out:
|
|
return ret;
|
|
}
|
|
|
|
static DEVICE_ATTR(nad_acat, S_IRUGO | S_IWUSR, show_nad_acat, store_nad_acat);
|
|
|
|
static ssize_t show_nad_dram(struct device *dev,
|
|
struct device_attribute *attr,
|
|
char *buf)
|
|
{
|
|
NAD_PRINT("%s\n", __func__);
|
|
|
|
if (sec_nad_env.nad_dram_test_result == NAD_DRAM_TEST_FAIL)
|
|
return sprintf(buf, "NG_DRAM_0x%08lx,0x%x\n",
|
|
sec_nad_env.nad_dram_fail_address,
|
|
sec_nad_env.nad_dram_fail_data);
|
|
else if (sec_nad_env.nad_dram_test_result == NAD_DRAM_TEST_PASS)
|
|
return sprintf(buf, "OK_DRAM\n");
|
|
else
|
|
return sprintf(buf, "NO_DRAMTEST\n");
|
|
}
|
|
static DEVICE_ATTR(nad_dram, S_IRUGO, show_nad_dram, NULL);
|
|
|
|
static ssize_t show_nad_all(struct device *dev,
|
|
struct device_attribute *attr,
|
|
char *buf)
|
|
{
|
|
return sprintf(buf,
|
|
"NAD factory : %s\n"
|
|
"NAD result : %s\n"
|
|
"NAD data : 0x%x\n"
|
|
"NAD ACAT : %s\n"
|
|
"NAD ACAT result : %s\n"
|
|
"NAD ACAT data : 0x%x\n"
|
|
"NAD ACAT loop count : %d\n"
|
|
"NAD ACAT real count : %d\n"
|
|
"NAD DRAM test need : %s\n"
|
|
"NAD DRAM test result : 0x%x\n"
|
|
"NAD DRAM test fail data : 0x%x\n"
|
|
"NAD DRAM test fail address : 0x%08lx\n"
|
|
"NAD status : %d\n"
|
|
"NAD ACAT skip fail : %d\n"
|
|
"NAD unlimited loop : %d\n", sec_nad_env.nad_factory,
|
|
sec_nad_env.nad_result,
|
|
sec_nad_env.nad_data,
|
|
sec_nad_env.nad_acat,
|
|
sec_nad_env.nad_acat_result,
|
|
sec_nad_env.nad_acat_data,
|
|
sec_nad_env.nad_acat_loop_count,
|
|
sec_nad_env.nad_acat_real_count,
|
|
sec_nad_env.nad_dram_test_need,
|
|
sec_nad_env.nad_dram_test_result,
|
|
sec_nad_env.nad_dram_fail_data,
|
|
sec_nad_env.nad_dram_fail_address,
|
|
sec_nad_env.current_nad_status,
|
|
sec_nad_env.nad_acat_skip_fail,
|
|
sec_nad_env.unlimited_loop);
|
|
}
|
|
static DEVICE_ATTR(nad_all, S_IRUGO, show_nad_all, NULL);
|
|
|
|
static ssize_t show_nad_support(struct device *dev,
|
|
struct device_attribute *attr,
|
|
char *buf)
|
|
{
|
|
NAD_PRINT("%s\n", __func__);
|
|
|
|
if (sec_nad_env.nad_support == NAD_SUPPORT_FLAG)
|
|
return sprintf(buf, "SUPPORT\n");
|
|
else
|
|
return sprintf(buf, "NOT_SUPPORT\n");
|
|
}
|
|
static DEVICE_ATTR(nad_support, S_IRUGO, show_nad_support, NULL);
|
|
|
|
|
|
static ssize_t show_nad_version(struct device *dev,
|
|
struct device_attribute *attr,
|
|
char *buf)
|
|
{
|
|
unsigned int nad_project_index;
|
|
unsigned int nad_project_index2;
|
|
unsigned int nad_fw_version;
|
|
char chipset_name[12];
|
|
|
|
nad_project_index = (sec_nad_env.nad_data >> 28) & 0xF;
|
|
nad_project_index2 = (sec_nad_env.nad_inform2_data >> 29) & 0xF;
|
|
nad_fw_version = ((sec_nad_env.nad_data<<4) >> 28) & 0xF;
|
|
|
|
memset(chipset_name, 0x0, sizeof(chipset_name));
|
|
NAD_PRINT("%s\n", __func__);
|
|
|
|
if(sec_nad_env.nad_data != 0)
|
|
{
|
|
if(nad_project_index == EXYNOS7885) {
|
|
if(nad_project_index2 == 0) {
|
|
strcpy(chipset_name, "EXYNOS7885");
|
|
}
|
|
else if (nad_project_index2 == 1) {
|
|
strcpy(chipset_name, "EXYNOS7884");
|
|
}
|
|
else if (nad_project_index2 == 2)
|
|
{
|
|
strcpy(chipset_name, "EXYNOS7883");
|
|
}
|
|
}
|
|
else
|
|
{
|
|
strcpy(chipset_name, nad_chipset_name[nad_project_index]);
|
|
}
|
|
return sprintf(buf,"NAD_%s_Ver.0x%x\n", chipset_name, nad_fw_version);
|
|
|
|
}
|
|
else
|
|
return sprintf(buf,"NAD_NO_INFORMATION\n");
|
|
|
|
}
|
|
static DEVICE_ATTR(nad_version, S_IRUGO, show_nad_version, NULL);
|
|
|
|
#if defined(CONFIG_SEC_NAD_API)
|
|
static void make_result_data_to_string(void)
|
|
{
|
|
int i = 0;
|
|
|
|
NAD_PRINT("%s : api total count(%d)\n", __func__, sec_nad_env.nad_api_total_count);
|
|
|
|
/* Make result string if array is empty */
|
|
if (!strlen(nad_api_result_string)) {
|
|
for (i = 0; i < sec_nad_env.nad_api_total_count; i++) {
|
|
NAD_PRINT("%s : name(%s) result(%d)\n", __func__,
|
|
sec_nad_env.nad_api_info[i].name, sec_nad_env.nad_api_info[i].result);
|
|
/* Failed gpio test */
|
|
if (sec_nad_env.nad_api_info[i].result) {
|
|
strcat(nad_api_result_string, sec_nad_env.nad_api_info[i].name);
|
|
strcat(nad_api_result_string, ",");
|
|
}
|
|
}
|
|
nad_api_result_string[strlen(nad_api_result_string)-1] = '\0';
|
|
}
|
|
}
|
|
|
|
static ssize_t show_nad_api(struct device *dev,
|
|
struct device_attribute *attr,
|
|
char *buf)
|
|
{
|
|
NAD_PRINT("%s\n", __func__);
|
|
|
|
/* Check nad api running status */
|
|
if (sec_nad_env.nad_api_status == MAGIC_NAD_API_SUCCESS) {
|
|
if (sec_nad_env.nad_api_magic == MAGIC_NAD_API_SUCCESS)
|
|
return sprintf(buf, "OK_%d\n", sec_nad_env.nad_api_total_count);
|
|
else {
|
|
make_result_data_to_string();
|
|
return sprintf(buf, "NG_%d,%s\n", sec_nad_env.nad_api_total_count, nad_api_result_string);
|
|
}
|
|
} else
|
|
return sprintf(buf, "NONE\n");
|
|
}
|
|
static DEVICE_ATTR(nad_api, S_IRUGO, show_nad_api, NULL);
|
|
#endif
|
|
#endif
|
|
|
|
static int __init sec_nad_init(void)
|
|
{
|
|
int ret = 0;
|
|
#if defined(CONFIG_SEC_FACTORY)
|
|
struct device *sec_nad;
|
|
|
|
NAD_PRINT("%s\n", __func__);
|
|
|
|
/* Skip nad init when device goes to lp charging */
|
|
if (lpcharge)
|
|
return ret;
|
|
|
|
sec_nad = sec_device_create(NULL, "sec_nad");
|
|
|
|
if (IS_ERR(sec_nad)) {
|
|
pr_err("%s Failed to create device(sec_nad)!\n", __func__);
|
|
return PTR_ERR(sec_nad);
|
|
}
|
|
|
|
ret = device_create_file(sec_nad, &dev_attr_nad_stat);
|
|
if (ret) {
|
|
pr_err("%s: Failed to create device file\n", __func__);
|
|
goto err_create_nad_sysfs;
|
|
}
|
|
|
|
ret = device_create_file(sec_nad, &dev_attr_nad_erase);
|
|
if (ret) {
|
|
pr_err("%s: Failed to create device file\n", __func__);
|
|
goto err_create_nad_sysfs;
|
|
}
|
|
|
|
ret = device_create_file(sec_nad, &dev_attr_nad_acat);
|
|
if (ret) {
|
|
pr_err("%s: Failed to create device file\n", __func__);
|
|
goto err_create_nad_sysfs;
|
|
}
|
|
|
|
ret = device_create_file(sec_nad, &dev_attr_nad_dram);
|
|
if (ret) {
|
|
pr_err("%s: Failed to create device file\n", __func__);
|
|
goto err_create_nad_sysfs;
|
|
}
|
|
|
|
ret = device_create_file(sec_nad, &dev_attr_nad_all);
|
|
if (ret) {
|
|
pr_err("%s: Failed to create device file\n", __func__);
|
|
goto err_create_nad_sysfs;
|
|
}
|
|
|
|
ret = device_create_file(sec_nad, &dev_attr_nad_support);
|
|
if (ret) {
|
|
pr_err("%s: Failed to create device file\n", __func__);
|
|
goto err_create_nad_sysfs;
|
|
}
|
|
|
|
#if defined(CONFIG_SEC_NAD_API)
|
|
ret = device_create_file(sec_nad, &dev_attr_nad_api);
|
|
if (ret) {
|
|
pr_err("%s: Failed to create device file\n", __func__);
|
|
goto err_create_nad_sysfs;
|
|
}
|
|
#endif
|
|
|
|
|
|
ret = device_create_file(sec_nad, &dev_attr_nad_version);
|
|
if (ret) {
|
|
pr_err("%s: Failed to create device file\n", __func__);
|
|
goto err_create_nad_sysfs;
|
|
}
|
|
|
|
/* Initialize nad param struct */
|
|
sec_nad_param_data.offset = NAD_ENV_OFFSET;
|
|
sec_nad_param_data.state = NAD_PARAM_EMPTY;
|
|
sec_nad_param_data.retry_cnt = NAD_RETRY_COUNT;
|
|
sec_nad_param_data.curr_cnt = 0;
|
|
|
|
INIT_WORK(&sec_nad_param_data.sec_nad_work, sec_nad_param_update);
|
|
INIT_DELAYED_WORK(&sec_nad_param_data.sec_nad_delay_work, sec_nad_init_update);
|
|
|
|
#if defined(CONFIG_SEC_NAD_MANUAL_PARAM_READTIME)
|
|
schedule_delayed_work(&sec_nad_param_data.sec_nad_delay_work, HZ * CONFIG_SEC_NAD_MANUAL_PARAM_READTIME);
|
|
#else
|
|
schedule_delayed_work(&sec_nad_param_data.sec_nad_delay_work, HZ * 10);
|
|
#endif
|
|
|
|
return 0;
|
|
err_create_nad_sysfs:
|
|
sec_device_destroy(sec_nad->devt);
|
|
return ret;
|
|
#else
|
|
return ret;
|
|
#endif
|
|
}
|
|
|
|
static void __exit sec_nad_exit(void)
|
|
{
|
|
#if defined(CONFIG_SEC_FACTORY)
|
|
cancel_work_sync(&sec_nad_param_data.sec_nad_work);
|
|
cancel_delayed_work(&sec_nad_param_data.sec_nad_delay_work);
|
|
NAD_PRINT("%s: exit\n", __func__);
|
|
#endif
|
|
}
|
|
|
|
module_init(sec_nad_init);
|
|
module_exit(sec_nad_exit);
|