// SPDX-License-Identifier: GPL-2.0-only /* * sec_debug_hw_param.c * * Copyright (c) 2019 Samsung Electronics Co., Ltd * http://www.samsung.com */ #include #include #include #include #include #include #include #include #include #include #include "sec_debug_internal.h" /* maximum size of sysfs */ #define DATA_SIZE 1024 #define LOT_STRING_LEN 5 /* function name prefix: secdbg_hprm */ #if defined(CONFIG_SAMSUNG_VST_CAL) /* from NAD related bootloader work */ static unsigned int vst_result; module_param(vst_result, unsigned int, 0440); #endif char __read_mostly *dram_size; module_param(dram_size, charp, 0440); /* this is same with androidboot.dram_info */ char __read_mostly *dram_info; module_param(dram_info, charp, 0440); static u32 chipid_reverse_value(u32 value, u32 bitcnt) { int tmp, ret = 0, i; for (i = 0; i < bitcnt; i++) { tmp = (value >> i) & 0x1; ret += tmp << ((bitcnt - 1) - i); } return ret; } static void chipid_dec_to_36(u32 in, char *p) { int mod, i; for (i = LOT_STRING_LEN - 1; i >= 1; i--) { mod = in % 36; in /= 36; p[i] = (mod < 10) ? (mod + '0') : (mod - 10 + 'A'); } p[0] = 'N'; p[LOT_STRING_LEN] = '\0'; } /* sysfs show functions */ static ssize_t secdbg_hprm_ap_info_show(struct device *dev, struct device_attribute *attr, char *buf) { ssize_t info_size = 0; int reverse_id_0 = 0; u32 tmp = 0; char lot_id[LOT_STRING_LEN + 1]; char val[32] = {0, }; reverse_id_0 = chipid_reverse_value(exynos_soc_info.lot_id, 32); tmp = (reverse_id_0 >> 11) & 0x1FFFFF; chipid_dec_to_36(tmp, lot_id); memset(val, 0, 32); get_bk_item_val_as_string("RSTCNT", val); info_size += snprintf((char *)(buf + info_size), DATA_SIZE - info_size, "\"RSTCNT\":\"%s\",", val); memset(val, 0, 32); get_bk_item_val_as_string("CHI", val); info_size += snprintf((char *)(buf + info_size), DATA_SIZE - info_size, "\"CHIPID_FAIL\":\"%s\",", val); memset(val, 0, 32); get_bk_item_val_as_string("LPI", val); info_size += snprintf((char *)(buf + info_size), DATA_SIZE - info_size, "\"LPI_TIMEOUT\":\"%s\",", val); memset(val, 0, 32); get_bk_item_val_as_string("CDI", val); info_size += snprintf((char *)(buf + info_size), DATA_SIZE - info_size, "\"CODE_DIFF\":\"%s\",", val); memset(val, 0, 32); get_bk_item_val_as_string("BIN", val); info_size += snprintf((char *)(buf + info_size), DATA_SIZE - info_size, "\"BIN\":\"%s\",", val); info_size += snprintf((char *)(buf + info_size), DATA_SIZE - info_size, "\"ASB\":\"%d\",", id_get_asb_ver()); info_size += snprintf((char *)(buf + info_size), DATA_SIZE - info_size, "\"PSITE\":\"%d\",", id_get_product_line()); info_size += snprintf((char *)(buf + info_size), DATA_SIZE - info_size, "\"LOT_ID\":\"%s\",", lot_id); #if defined(CONFIG_SAMSUNG_VST_CAL) info_size += snprintf((char *)(buf + info_size), DATA_SIZE - info_size, "\"VST_RESULT\":\"%d\",", vst_result); info_size += snprintf((char *)(buf + info_size), DATA_SIZE - info_size, "\"VST_ADJUST\":\"%d\",", volt_vst_cal_bdata); #endif return info_size; } static ssize_t secdbg_hprm_ddr_info_show(struct device *dev, struct device_attribute *attr, char *buf) { ssize_t info_size = 0; info_size += snprintf((char *)(buf), DATA_SIZE, "\"DDRV\":\"%s\"", dram_info); return info_size; } static ssize_t secdbg_hprm_extra_info_show(struct device *dev, struct device_attribute *attr, char *buf) { ssize_t info_size = 0; secdbg_exin_get_extra_info_A(buf); info_size = strlen(buf); return info_size; } static ssize_t secdbg_hprm_extrb_info_show(struct device *dev, struct device_attribute *attr, char *buf) { ssize_t info_size = 0; secdbg_exin_get_extra_info_B(buf); info_size = strlen(buf); return info_size; } static ssize_t secdbg_hprm_extrc_info_show(struct device *dev, struct device_attribute *attr, char *buf) { ssize_t info_size = 0; secdbg_exin_get_extra_info_C(buf); info_size = strlen(buf); return info_size; } static ssize_t secdbg_hprm_extrm_info_show(struct device *dev, struct device_attribute *attr, char *buf) { ssize_t info_size = 0; secdbg_exin_get_extra_info_M(buf); info_size = strlen(buf); return info_size; } static ssize_t secdbg_hprm_extrf_info_show(struct device *dev, struct device_attribute *attr, char *buf) { ssize_t info_size = 0; secdbg_exin_get_extra_info_F(buf); info_size = strlen(buf); return info_size; } static ssize_t secdbg_hprm_extrt_info_show(struct device *dev, struct device_attribute *attr, char *buf) { ssize_t info_size = 0; secdbg_exin_get_extra_info_T(buf); info_size = strlen(buf); return info_size; } static ssize_t secdbg_hprm_thermal_info_show(struct device *dev, struct device_attribute *attr, char *buf) { ssize_t info_size = 0; return info_size; } static DEVICE_ATTR(ap_info, 0440, secdbg_hprm_ap_info_show, NULL); static DEVICE_ATTR(ddr_info, 0440, secdbg_hprm_ddr_info_show, NULL); static DEVICE_ATTR(extra_info, 0440, secdbg_hprm_extra_info_show, NULL); static DEVICE_ATTR(extrb_info, 0440, secdbg_hprm_extrb_info_show, NULL); static DEVICE_ATTR(extrc_info, 0440, secdbg_hprm_extrc_info_show, NULL); static DEVICE_ATTR(extrm_info, 0440, secdbg_hprm_extrm_info_show, NULL); static DEVICE_ATTR(extrf_info, 0440, secdbg_hprm_extrf_info_show, NULL); static DEVICE_ATTR(extrt_info, 0440, secdbg_hprm_extrt_info_show, NULL); static DEVICE_ATTR(thermal_info, 0440, secdbg_hprm_thermal_info_show, NULL); static struct attribute *secdbg_hprm_attributes[] = { &dev_attr_ap_info.attr, &dev_attr_ddr_info.attr, &dev_attr_extra_info.attr, &dev_attr_extrb_info.attr, &dev_attr_extrc_info.attr, &dev_attr_extrm_info.attr, &dev_attr_extrf_info.attr, &dev_attr_extrt_info.attr, &dev_attr_thermal_info.attr, NULL, }; static struct attribute_group secdbg_hprm_attr_group = { .attrs = secdbg_hprm_attributes, }; static void secdbg_hprm_set_hw_exin(void) { secdbg_exin_set_hwid(id_get_asb_ver(), id_get_product_line(), dram_info); } static int __init secdbg_hw_param_init(void) { int ret = 0; struct device *dev; pr_info("%s: start\n", __func__); pr_info("%s: from cmdline: dram_size: %s\n", __func__, dram_size); pr_info("%s: from cmdline: dram_info: %s\n", __func__, dram_info); secdbg_hprm_set_hw_exin(); dev = sec_device_create(NULL, "sec_hw_param"); ret = sysfs_create_group(&dev->kobj, &secdbg_hprm_attr_group); if (ret) pr_err("%s : could not create sysfs noden", __func__); return 0; } module_init(secdbg_hw_param_init); MODULE_DESCRIPTION("Samsung Debug HW Parameter driver"); MODULE_LICENSE("GPL v2");