hpb: disable HPB feature for 4G ram

Remark:
parse share memory get ram size to distinguish if is 4G ram
if yes, disable HPB feature(Due to 4G ram size is too
senstive for camera).

Change-Id: Icb8575dec742c248586e11bf4ebcc0d2bbac0d9e
Signed-off-by: fuxm1 <fuxm1@motorola.com>
Reviewed-on: https://gerrit.mot.com/1939239
SME-Granted: SME Approvals Granted
Reviewed-by: Huosheng Liao <liaohs@motorola.com>
SLTApproved: Slta Waiver
Tested-by: Jira Key
Submit-Approved: Jira Key
This commit is contained in:
fuxm1 2021-05-04 23:39:32 +08:00 • committed by Xiaojun Ji
commit e6157fa890
3 changed files with 146 additions and 21 deletions

View file

@ -212,7 +212,8 @@ static int ufsf_read_dev_desc(struct ufsf_feature *ufsf, u8 selector)
#if defined(CONFIG_UFSHPB)
ufshpb_get_dev_info(ufsf, desc_buf);
if (IS_RAM_SIZE_GREATER_THAN_4G(ram_size))
ufshpb_get_dev_info(ufsf, desc_buf);
#endif
#if defined(CONFIG_UFSTW)
ufstw_get_dev_info(ufsf, desc_buf);
@ -231,7 +232,7 @@ static int ufsf_read_geo_desc(struct ufsf_feature *ufsf, u8 selector)
return ret;
#if defined(CONFIG_UFSHPB)
if (ufshpb_get_state(ufsf) == HPB_NEED_INIT)
if ((ufshpb_get_state(ufsf) == HPB_NEED_INIT) && IS_RAM_SIZE_GREATER_THAN_4G(ram_size))
ufshpb_get_geo_info(ufsf, geo_buf);
#endif
@ -259,7 +260,7 @@ static void ufsf_read_unit_desc(struct ufsf_feature *ufsf, int lun, u8 selector)
return;
#if defined(CONFIG_UFSHPB)
if (ufshpb_get_state(ufsf) == HPB_NEED_INIT)
if ((ufshpb_get_state(ufsf) == HPB_NEED_INIT) && IS_RAM_SIZE_GREATER_THAN_4G(ram_size))
ufshpb_get_lu_info(ufsf, lun, unit_buf);
#endif
@ -531,7 +532,7 @@ inline void ufsf_slave_configure(struct ufsf_feature *ufsf,
ufsf->slave_conf_cnt, ufsf->num_lu);
#if defined(CONFIG_UFSHPB)
if (ufsf->num_lu == ufsf->slave_conf_cnt) {
if (ufsf->num_lu == ufsf->slave_conf_cnt && IS_RAM_SIZE_GREATER_THAN_4G(ram_size)) {
if (ufshpb_get_state(ufsf) == HPB_NEED_INIT) {
INFO_MSG("wakeup ufshpb_init_handler");
wake_up(&ufsf->hpb_wait);
@ -546,7 +547,7 @@ inline void ufsf_prep_fn(struct ufsf_feature *ufsf,
{
#if defined(CONFIG_UFSHPB)
if (ufshpb_get_state(ufsf) == HPB_PRESENT &&
ufsf->issue_ioctl == false)
ufsf->issue_ioctl == false && IS_RAM_SIZE_GREATER_THAN_4G(ram_size))
ufshpb_prep_fn(ufsf, lrbp);
#endif
@ -569,10 +570,12 @@ inline void ufsf_reset_lu(struct ufsf_feature *ufsf)
inline void ufsf_reset_host(struct ufsf_feature *ufsf)
{
#if defined(CONFIG_UFSHPB)
INFO_MSG("run reset_host.. hpb_state(%d) -> HPB_RESET",
ufshpb_get_state(ufsf));
if (ufshpb_get_state(ufsf) == HPB_PRESENT)
ufshpb_reset_host(ufsf);
if (IS_RAM_SIZE_GREATER_THAN_4G(ram_size)) {
INFO_MSG("run reset_host.. hpb_state(%d) -> HPB_RESET",
ufshpb_get_state(ufsf));
if (ufshpb_get_state(ufsf) == HPB_PRESENT)
ufshpb_reset_host(ufsf);
}
#endif
#if defined(CONFIG_UFSTW)
@ -586,7 +589,7 @@ inline void ufsf_reset_host(struct ufsf_feature *ufsf)
inline void ufsf_init(struct ufsf_feature *ufsf)
{
#if defined(CONFIG_UFSHPB)
if (ufshpb_get_state(ufsf) == HPB_NEED_INIT) {
if ((ufshpb_get_state(ufsf) == HPB_NEED_INIT) && IS_RAM_SIZE_GREATER_THAN_4G(ram_size)) {
INFO_MSG("init start.. hpb_state (%d)", HPB_NEED_INIT);
schedule_work(&ufsf->hpb_init_work);
}
@ -601,7 +604,7 @@ inline void ufsf_init(struct ufsf_feature *ufsf)
inline void ufsf_reset(struct ufsf_feature *ufsf)
{
#if defined(CONFIG_UFSHPB)
if (ufshpb_get_state(ufsf) == HPB_RESET) {
if ((ufshpb_get_state(ufsf) == HPB_RESET) && IS_RAM_SIZE_GREATER_THAN_4G(ram_size)) {
INFO_MSG("reset start.. hpb_state %d", HPB_RESET);
ufshpb_reset(ufsf);
}
@ -620,7 +623,7 @@ inline void ufsf_reset(struct ufsf_feature *ufsf)
inline void ufsf_remove(struct ufsf_feature *ufsf)
{
#if defined(CONFIG_UFSHPB)
if (ufshpb_get_state(ufsf) == HPB_PRESENT)
if ((ufshpb_get_state(ufsf) == HPB_PRESENT) && IS_RAM_SIZE_GREATER_THAN_4G(ram_size))
ufshpb_remove(ufsf, HPB_NEED_INIT);
#endif
@ -635,9 +638,13 @@ inline void ufsf_set_init_state(struct ufsf_feature *ufsf)
ufsf->slave_conf_cnt = 0;
ufsf->issue_ioctl = false;
#if defined(CONFIG_UFSHPB)
ufshpb_set_state(ufsf, HPB_NEED_INIT);
INIT_WORK(&ufsf->hpb_init_work, ufshpb_init_handler);
init_waitqueue_head(&ufsf->hpb_wait);
if (IS_RAM_SIZE_GREATER_THAN_4G(ram_size)) {
INFO_MSG("enable HPB feature, init start!");
INFO_MSG("ram size is %d", ram_size);
ufshpb_set_state(ufsf, HPB_NEED_INIT);
INIT_WORK(&ufsf->hpb_init_work, ufshpb_init_handler);
init_waitqueue_head(&ufsf->hpb_wait);
}
#endif
#if defined(CONFIG_UFSTW)
ufstw_set_state(ufsf, TW_NEED_INIT);
@ -652,7 +659,7 @@ inline void ufsf_suspend(struct ufsf_feature *ufsf)
* in this case, ufshpb state already had been changed to SUSPEND state.
* so, we will not call ufshpb_suspend.
*/
if (ufshpb_get_state(ufsf) == HPB_PRESENT)
if ((ufshpb_get_state(ufsf) == HPB_PRESENT) && IS_RAM_SIZE_GREATER_THAN_4G(ram_size))
ufshpb_suspend(ufsf);
#endif
}
@ -660,8 +667,9 @@ inline void ufsf_suspend(struct ufsf_feature *ufsf)
inline void ufsf_resume(struct ufsf_feature *ufsf)
{
#if defined(CONFIG_UFSHPB)
if (ufshpb_get_state(ufsf) == HPB_SUSPEND ||
ufshpb_get_state(ufsf) == HPB_PRESENT) {
if ((ufshpb_get_state(ufsf) == HPB_SUSPEND ||
ufshpb_get_state(ufsf) == HPB_PRESENT) &&
IS_RAM_SIZE_GREATER_THAN_4G(ram_size)) {
if (ufshpb_get_state(ufsf) == HPB_PRESENT)
WARN_MSG("warning.. hpb state PRESENT in resuming");
ufshpb_resume(ufsf);

View file

@ -55,6 +55,36 @@
#define CREATE_TRACE_POINTS
#include <trace/events/ufs.h>
#if defined(CONFIG_SCSI_SKHPB) || defined(CONFIG_UFSHPB)
#include <linux/of.h>
#include <linux/of_platform.h>
#include <linux/version.h>
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,14,0)
#include <linux/soc/qcom/smem.h>
#define SMEM_SDRAM_INFO 135
#else
#include <soc/qcom/smsm.h>
#define SMEM_SDRAM_INFO SMEM_ID_VENDOR1
#endif
struct {
unsigned int mr5;
unsigned int mr6;
unsigned int mr7;
unsigned int mr8;
unsigned int ramsize;
} *smem_ddr_info;
struct storage_info {
char type[16]; /* UFS or eMMC */
char size[16]; /* size in GB */
char card_manufacturer[32];
char product_name[32]; /* model ID */
char firmware_version[32];
};
unsigned int ram_size;
#endif
#define UFSHCD_ENABLE_INTRS (UTP_TRANSFER_REQ_COMPL |\
UTP_TASK_REQ_COMPL |\
UFSHCD_ERROR_MASK)
@ -303,6 +333,10 @@ static struct ufs_dev_fix ufs_fixups[] = {
END_FIX
};
#if defined(CONFIG_SCSI_SKHPB) || defined(CONFIG_UFSHPB)
static int get_dram_info(struct ufs_hba *hba);
static int get_storage_info(struct ufs_hba *hba);
#endif
static irqreturn_t ufshcd_tmc_handler(struct ufs_hba *hba);
static void ufshcd_async_scan(void *data, async_cookie_t cookie);
static int ufshcd_reset_and_restore(struct ufs_hba *hba);
@ -9782,13 +9816,18 @@ int ufshcd_init(struct ufs_hba *hba, void __iomem *mmio_base, unsigned int irq)
*/
ufshcd_set_ufs_dev_active(hba);
#if defined(CONFIG_UFSHPB) || defined(CONFIG_SCSI_SKHPB)
get_storage_info(hba);
get_dram_info(hba);
#endif
#if defined(CONFIG_UFSFEATURE)
if (is_support_hpb_200_device(storage_mfrid)){
if (is_support_hpb_200_device(storage_mfrid)) {
ufsf_set_init_state(&hba->ufsf);
}
#endif
#if defined(CONFIG_SCSI_SKHPB)
if (is_support_hpb_100_device(storage_mfrid)){
if (is_support_hpb_100_device(storage_mfrid) && IS_RAM_SIZE_GREATER_THAN_4G(ram_size)) {
/* initialize hpb structures */
ufshcd_init_hpb(hba);
}
@ -9816,6 +9855,81 @@ static int __init storage_mfrid_setup(char *str)
return 1;
}
__setup("storage_mfrid=",storage_mfrid_setup);
#if defined(CONFIG_SCSI_SKHPB) || defined(CONFIG_UFSHPB)
static int get_storage_info(struct ufs_hba *hba)
{
int ret = 0;
struct property *p;
struct device_node *n;
struct storage_info *info;
unsigned int mfrid;
n = of_find_node_by_path("/chosen/mmi,storage");
if (n == NULL) {
ret = 1;
goto err;
}
info = kzalloc(sizeof(struct storage_info), GFP_KERNEL);
if (!info) {
dev_err(hba->dev,"%s: failed to allocate space for mmi_storage_info\n",
__func__);
ret = 1;
goto err;
}
for_each_property_of_node(n, p) {
if (!strcmp(p->name, "type") && p->value)
strlcpy(info->type, (char *)p->value, sizeof(info->type));
if (!strcmp(p->name, "size") && p->value)
strlcpy(info->size, (char *)p->value, sizeof(info->size));
if (!strcmp(p->name, "manufacturer") && p->value)
strlcpy(info->card_manufacturer, (char *)p->value, sizeof(info->card_manufacturer));
if (!strcmp(p->name, "product") && p->value)
strlcpy(info->product_name, (char *)p->value, sizeof(info->product_name));
if (!strcmp(p->name, "firmware") && p->value)
strlcpy(info->firmware_version, (char *)p->value, sizeof(info->firmware_version));
}
of_node_put(n);
mfrid = simple_strtol(info->card_manufacturer, NULL, 16);
dev_info(hba->dev, "manufacturer parsed from choosen is %s\n",mfrid);
err:
return ret;
}
static int get_dram_info(struct ufs_hba *hba)
{
int ret = -1;
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,14,0)
ssize_t ddr_info_size = 0;
smem_ddr_info = qcom_smem_get(QCOM_SMEM_HOST_ANY,
SMEM_SDRAM_INFO,
&ddr_info_size);
if(smem_ddr_info) {
if(ddr_info_size < sizeof(*smem_ddr_info)) {
dev_err(hba->dev,"%s: Invalid SMEM size, cannot get RAM info\n", __func__);
goto err;
}
}
#endif
if (smem_ddr_info == NULL) {
dev_err(hba->dev,"%s: failed to access RAM info in SMEM\n", __func__);
goto err;
}
ram_size = (smem_ddr_info->ramsize / 1024);
dev_info(hba->dev, "ram_size parsed from SMEM is %d\n",ram_size);
return ram_size;
err:
return ret;
}
#endif
EXPORT_SYMBOL_GPL(ufshcd_init);
MODULE_AUTHOR("Santosh Yaragnavi <santosh.sy@samsung.com>");

View file

@ -89,7 +89,10 @@ extern unsigned int storage_mfrid;
#define IS_SAMSUNG_DEVICE(mfrid) (UFS_VENDOR_SAMSUNG == (mfrid))
#define IS_SKHYNIX_DEVICE(mfrid) (UFS_VENDOR_SKHYNIX == (mfrid))
#define IS_MICRON_DEVICE(mfrid) (UFS_VENDOR_MICRON == (mfrid))
#if defined(CONFIG_SCSI_SKHPB) || defined(CONFIG_UFSHPB)
extern unsigned int ram_size;
#define IS_RAM_SIZE_GREATER_THAN_4G(ram_size) (ram_size > 4)
#endif
struct ufs_hba;
enum dev_cmd_type {