HPB Introduction

一. HPB Overview

      HPB全称为Host Performance Booster, 是利用手机内存缓存UFS Devices 主控(这里指的是Ufs Device Controller, 比如群联/慧荣等厂商的Ufs,控制运行FTL程序代码)的L2P表,来提升读性能,尤其是长时间使用后的随机读性能。

      HPB技术是Jedec UFS3.1加入的Feature, 用来提升随机读性能,其实这个技术在无缓存的SSD上很常见。

二. 手机HPB方案介绍

      目前Qcom/MTK/Sprd都开发了支持Ufs Host IP的手机芯片,现在用户越来越多的用户重视手机平时使用的流畅性,流畅性又和随机读有很大联系,所以支持HPB能提高竞争力。

      以下以高通平台来举例:

  Qcom Ufs Hos和Ufs Devices进行Probe匹配:

/**
 * ufshcd_probe_hba - probe hba to detect device and initialize
 * @hba: per-adapter instance
 *
 * Execute link-startup and verify device initialization
 */
static int ufshcd_probe_hba(struct ufs_hba *hba)
{
    ufsf_device_check(hba);
}

 检查Ufs Devices Descriptor/Geometry Descriptor/Unit Descriptor 涉及HPB的 属性

void ufsf_device_check(struct ufs_hba *hba)
{
	struct ufsf_feature *ufsf = &hba->ufsf;
	int ret, lun;
	u32 status;

	ufsf->slave_conf_cnt = 0;

	ufsf->hba = hba;

	ufshcd_query_attr(ufsf->hba, UPIU_QUERY_OPCODE_READ_ATTR,
			  QUERY_ATTR_IDN_SUP_VENDOR_OPTIONS, 0, 0, &status);
	INIT_INFO("UFS FEATURE SELECTOR Dev %d - D/D %d", status,
		  UFSFEATURE_SELECTOR);

	ret = ufsf_read_dev_desc(ufsf, UFSFEATURE_SELECTOR);
	if (ret)
		return;

	ret = ufsf_read_geo_desc(ufsf, UFSFEATURE_SELECTOR);
	if (ret)
		return;

	seq_scan_lu(lun) {
		ret = ufsf_read_unit_desc(ufsf, lun, UFSFEATURE_SELECTOR);
		if (ret == -ENOMEM)
			goto out_free_mem;
	}
	/* huangjianan@TECH.Storage.UFS, 2019/12/09, Add for UFS+ RUS */
	create_ufsplus_ctrl_proc(ufsf);

	return;
out_free_mem:
#if defined(CONFIG_UFSHPB)
	/* yujinghua@TECH.Storage.UFS, 2019/12/31, set the ufsf->ufshpb_lup[lun] as NULL after kfree*/
	seq_scan_lu(lun) {
		kfree(ufsf->ufshpb_lup[lun]);
		ufsf->ufshpb_lup[lun] = NULL;
	}

	/* don't call init handler */
	ufsf->ufshpb_state = HPB_FAILED;
#endif
#if defined(CONFIG_UFSTW)
	/* yujinghua@TECH.Storage.UFS, 2019/12/31, set the ufsf->tw_lup[lun] as NULL after kfree*/
	seq_scan_lu(lun) {
		kfree(ufsf->tw_lup[lun]);
		ufsf->tw_lup[lun] = NULL;
	}

	ufsf->tw_dev_info.tw_device = false;
	atomic_set(&ufsf->tw_state, TW_FAILED);
#endif
	return;
}

 获取Device Descriptor配置,如果Devices Descriptor中0x1F bit[7]置1,说明支持HPB Feature.

void ufshpb_get_dev_info(struct ufshpb_dev_info *hpb_dev_info, u8 *desc_buf)
{
	int ret;

	hpb_dev_info->hpb_device = false;

	if (desc_buf[DEVICE_DESC_PARAM_UFS_FEAT] & UFS_FEATURE_SUPPORT_HPB_BIT)
		INIT_INFO("bUFSFeaturesSupport: HPB is set");
	else {
		INIT_INFO("bUFSFeaturesSupport: HPB not support");
		return;
	}

	hpb_dev_info->hpb_ver = LI_EN_16(desc_buf + DEVICE_DESC_PARAM_HPB_VER);

	ret = ufshpb_version_check(hpb_dev_info);
	if (!ret)
		hpb_dev_info->hpb_device = true;
}

static inline int ufshpb_version_check(struct ufshpb_dev_info *hpb_dev_info)
{
	INIT_INFO("Support HPB Spec : Driver = %.4X  Device = %.4X",
		  UFSHPB_VER, hpb_dev_info->hpb_ver);

	INIT_INFO("HPB Driver Version : %.4X", UFSHPB_DD_VER);

	if (hpb_dev_info->hpb_ver != UFSHPB_VER) {
		ERR_MSG("ERROR: HPB Spec Version mismatch. So HPB disabled.");
		return -ENODEV;
	}
	return 0;
}

#define UFSHPB_VER				0x0200
#define UFS_FEATURE_SUPPORT_HPB_BIT		0x80


/* Device descriptor parameters offsets in bytes*/
enum device_desc_param {
	DEVICE_DESC_PARAM_LEN			= 0x0,
	DEVICE_DESC_PARAM_TYPE			= 0x1,
	DEVICE_DESC_PARAM_DEVICE_TYPE		= 0x2,
	DEVICE_DESC_PARAM_DEVICE_CLASS		= 0x3,
	DEVICE_DESC_PARAM_DEVICE_SUB_CLASS	= 0x4,
	DEVICE_DESC_PARAM_PRTCL			= 0x5,
	DEVICE_DESC_PARAM_NUM_LU		= 0x6,
	DEVICE_DESC_PARAM_NUM_WLU		= 0x7,
	DEVICE_DESC_PARAM_BOOT_ENBL		= 0x8,
	DEVICE_DESC_PARAM_DESC_ACCSS_ENBL	= 0x9,
	DEVICE_DESC_PARAM_INIT_PWR_MODE		= 0xA,
	DEVICE_DESC_PARAM_HIGH_PR_LUN		= 0xB,
	DEVICE_DESC_PARAM_SEC_RMV_TYPE		= 0xC,
	DEVICE_DESC_PARAM_SEC_LU		= 0xD,
	DEVICE_DESC_PARAM_BKOP_TERM_LT		= 0xE,
	DEVICE_DESC_PARAM_ACTVE_ICC_LVL		= 0xF,
	DEVICE_DESC_PARAM_SPEC_VER		= 0x10,
	DEVICE_DESC_PARAM_MANF_DATE		= 0x12,
	DEVICE_DESC_PARAM_MANF_NAME		= 0x14,
	DEVICE_DESC_PARAM_PRDCT_NAME		= 0x15,
	DEVICE_DESC_PARAM_SN			= 0x16,
	DEVICE_DESC_PARAM_OEM_ID		= 0x17,
	DEVICE_DESC_PARAM_MANF_ID		= 0x18,
	DEVICE_DESC_PARAM_UD_OFFSET		= 0x1A,
	DEVICE_DESC_PARAM_UD_LEN		= 0x1B,
	DEVICE_DESC_PARAM_RTT_CAP		= 0x1C,
	DEVICE_DESC_PARAM_FRQ_RTC		= 0x1D,
	DEVICE_DESC_PARAM_UFS_FEAT		= 0x1F,
	DEVICE_DESC_PARAM_FFU_TMT		= 0x20,
	DEVICE_DESC_PARAM_Q_DPTH		= 0x21,
	DEVICE_DESC_PARAM_DEV_VER		= 0x22,
	DEVICE_DESC_PARAM_NUM_SEC_WPA		= 0x24,
	DEVICE_DESC_PARAM_PSA_MAX_DATA		= 0x25,
	DEVICE_DESC_PARAM_PSA_TMT		= 0x29,
	DEVICE_DESC_PARAM_PRDCT_REV		= 0x2A,
#ifdef VENDOR_EDIT
/* Hank.liu@TECH.PLAT.Storage, 2019-10-31, add UFS+ hpb and tw driver*/
#if defined(CONFIG_UFSHPB)
	DEVICE_DESC_PARAM_HPB_VER		= 0x40,
#endif
#endif
	DEVICE_DESC_PARAM_EXT_UFS_FEATURE_SUP	= 0x4F,
#ifdef VENDOR_EDIT
#if defined(CONFIG_UFSTW)
	DEVICE_DESC_PARAM_TW_RETURN_TO_USER	= 0x53,
	DEVICE_DESC_PARAM_TW_BUF_TYPE		= 0x54,
	DEVICE_DESC_PARAM_TW_VER		= 0x55,
#endif
#endif
	DEVICE_DESC_PARAM_WB_US_RED_EN		= 0x53,
	DEVICE_DESC_PARAM_WB_TYPE		= 0x54,
	DEVICE_DESC_PARAM_WB_SHARED_ALLOC_UNITS = 0x55,
};

 获取Geometry Descriptor关于HPB Feature的配置,获取的信息有:

(1)HPB Number Lun: 支持HPB Feature的Lun的数量

(2)HPB Region Size

(3)HPB SubRegion Size

(4)HPB Devices Max Active regions

static int ufsf_read_geo_desc(struct ufsf_feature *ufsf, u8 selector)
{
	u8 geo_buf[UFSF_QUERY_DESC_GEOMETRY_MAX_SIZE];
	int ret;

	ret = ufsf_read_desc(ufsf->hba, QUERY_DESC_IDN_GEOMETRY, 0, selector,
			     geo_buf, UFSF_QUERY_DESC_GEOMETRY_MAX_SIZE);
	if (ret)
		return ret;

#if defined(CONFIG_UFSHPB)
	if (ufsf->hpb_dev_info.hpb_device)
		ufshpb_get_geo_info(&ufsf->hpb_dev_info, geo_buf);
#endif

#if defined(CONFIG_UFSTW)
	if (ufsf->tw_dev_info.tw_device)
		ufstw_get_geo_info(&ufsf->tw_dev_info, geo_buf);
#endif
	return 0;
}

void ufshpb_get_geo_info(struct ufshpb_dev_info *hpb_dev_info, u8 *geo_buf)
{
	hpb_dev_info->hpb_number_lu = geo_buf[GEOMETRY_DESC_HPB_NUMBER_LU];
	if (hpb_dev_info->hpb_number_lu == 0) {
		ERR_MSG("Don't have a lu for hpb.");
		hpb_dev_info->hpb_device = false;
		return;
	}

	hpb_dev_info->hpb_rgn_size = geo_buf[GEOMETRY_DESC_HPB_REGION_SIZE];
	hpb_dev_info->hpb_srgn_size = geo_buf[GEOMETRY_DESC_HPB_SUBREGION_SIZE];
	hpb_dev_info->hpb_device_max_active_rgns =
		LI_EN_16(geo_buf + GEOMETRY_DESC_HPB_DEVICE_MAX_ACTIVE_REGIONS);

	INIT_INFO("[48] bHPBRegionSiz %u", hpb_dev_info->hpb_rgn_size);
	INIT_INFO("[49] bHPBNumberLU %u", hpb_dev_info->hpb_number_lu);
	INIT_INFO("[4A] bHPBSubRegionSize %u", hpb_dev_info->hpb_srgn_size);
	INIT_INFO("[4B:4C] wDeviceMaxActiveHPBRegions %u",
		  hpb_dev_info->hpb_device_max_active_rgns);

	ufshpb_init_constant();
}

static void ufshpb_init_constant(void)
{
	sects_per_blk_shift = ffs(BLOCK) - ffs(SECTOR);
	INIT_INFO("sects_per_blk_shift: %u %u", sects_per_blk_shift,
		  ffs(SECTORS_PER_BLOCK) - 1);

	bits_per_dword_shift = ffs(BITS_PER_DWORD) - 1;
	bits_per_dword_mask = BITS_PER_DWORD - 1;
	INIT_INFO("bits_per_dword %u shift %u mask 0x%X", BITS_PER_DWORD,
		  bits_per_dword_shift, bits_per_dword_mask);

	bits_per_byte_shift = ffs(BITS_PER_BYTE) - 1;
	INIT_INFO("bits_per_byte %u shift %u", BITS_PER_BYTE,
		  bits_per_byte_shift);
}

 

      

  • 3
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值