linux/drivers/scsi/ufs/ufshpb.h
<<
>>
Prefs
   1/* SPDX-License-Identifier: GPL-2.0 */
   2/*
   3 * Universal Flash Storage Host Performance Booster
   4 *
   5 * Copyright (C) 2017-2021 Samsung Electronics Co., Ltd.
   6 *
   7 * Authors:
   8 *      Yongmyung Lee <ymhungry.lee@samsung.com>
   9 *      Jinyoung Choi <j-young.choi@samsung.com>
  10 */
  11
  12#ifndef _UFSHPB_H_
  13#define _UFSHPB_H_
  14
  15/* hpb response UPIU macro */
  16#define HPB_RSP_NONE                            0x0
  17#define HPB_RSP_REQ_REGION_UPDATE               0x1
  18#define HPB_RSP_DEV_RESET                       0x2
  19#define MAX_ACTIVE_NUM                          2
  20#define MAX_INACTIVE_NUM                        2
  21#define DEV_DATA_SEG_LEN                        0x14
  22#define DEV_SENSE_SEG_LEN                       0x12
  23#define DEV_DES_TYPE                            0x80
  24#define DEV_ADDITIONAL_LEN                      0x10
  25
  26/* hpb map & entries macro */
  27#define HPB_RGN_SIZE_UNIT                       512
  28#define HPB_ENTRY_BLOCK_SIZE                    4096
  29#define HPB_ENTRY_SIZE                          0x8
  30#define PINNED_NOT_SET                          U32_MAX
  31
  32/* hpb support chunk size */
  33#define HPB_LEGACY_CHUNK_HIGH                   1
  34#define HPB_MULTI_CHUNK_LOW                     7
  35#define HPB_MULTI_CHUNK_HIGH                    255
  36
  37/* hpb vender defined opcode */
  38#define UFSHPB_READ                             0xF8
  39#define UFSHPB_READ_BUFFER                      0xF9
  40#define UFSHPB_READ_BUFFER_ID                   0x01
  41#define UFSHPB_WRITE_BUFFER                     0xFA
  42#define UFSHPB_WRITE_BUFFER_INACT_SINGLE_ID     0x01
  43#define UFSHPB_WRITE_BUFFER_PREFETCH_ID         0x02
  44#define UFSHPB_WRITE_BUFFER_INACT_ALL_ID        0x03
  45#define HPB_WRITE_BUFFER_CMD_LENGTH             10
  46#define MAX_HPB_READ_ID                         0x7F
  47#define HPB_READ_BUFFER_CMD_LENGTH              10
  48#define LU_ENABLED_HPB_FUNC                     0x02
  49
  50#define HPB_RESET_REQ_RETRIES                   10
  51#define HPB_MAP_REQ_RETRIES                     5
  52#define HPB_REQUEUE_TIME_MS                     0
  53
  54#define HPB_SUPPORT_VERSION                     0x200
  55#define HPB_SUPPORT_LEGACY_VERSION              0x100
  56
  57enum UFSHPB_MODE {
  58        HPB_HOST_CONTROL,
  59        HPB_DEVICE_CONTROL,
  60};
  61
  62enum UFSHPB_STATE {
  63        HPB_INIT = 0,
  64        HPB_PRESENT = 1,
  65        HPB_SUSPEND,
  66        HPB_FAILED,
  67        HPB_RESET,
  68};
  69
  70enum HPB_RGN_STATE {
  71        HPB_RGN_INACTIVE,
  72        HPB_RGN_ACTIVE,
  73        /* pinned regions are always active */
  74        HPB_RGN_PINNED,
  75};
  76
  77enum HPB_SRGN_STATE {
  78        HPB_SRGN_UNUSED,
  79        HPB_SRGN_INVALID,
  80        HPB_SRGN_VALID,
  81        HPB_SRGN_ISSUED,
  82};
  83
  84/**
  85 * struct ufshpb_lu_info - UFSHPB logical unit related info
  86 * @num_blocks: the number of logical block
  87 * @pinned_start: the start region number of pinned region
  88 * @num_pinned: the number of pinned regions
  89 * @max_active_rgns: maximum number of active regions
  90 */
  91struct ufshpb_lu_info {
  92        int num_blocks;
  93        int pinned_start;
  94        int num_pinned;
  95        int max_active_rgns;
  96};
  97
  98struct ufshpb_map_ctx {
  99        struct page **m_page;
 100        unsigned long *ppn_dirty;
 101};
 102
 103struct ufshpb_subregion {
 104        struct ufshpb_map_ctx *mctx;
 105        enum HPB_SRGN_STATE srgn_state;
 106        int rgn_idx;
 107        int srgn_idx;
 108        bool is_last;
 109
 110        /* subregion reads - for host mode */
 111        unsigned int reads;
 112
 113        /* below information is used by rsp_list */
 114        struct list_head list_act_srgn;
 115};
 116
 117struct ufshpb_region {
 118        struct ufshpb_lu *hpb;
 119        struct ufshpb_subregion *srgn_tbl;
 120        enum HPB_RGN_STATE rgn_state;
 121        int rgn_idx;
 122        int srgn_cnt;
 123
 124        /* below information is used by rsp_list */
 125        struct list_head list_inact_rgn;
 126
 127        /* below information is used by lru */
 128        struct list_head list_lru_rgn;
 129        unsigned long rgn_flags;
 130#define RGN_FLAG_DIRTY 0
 131#define RGN_FLAG_UPDATE 1
 132
 133        /* region reads - for host mode */
 134        spinlock_t rgn_lock;
 135        unsigned int reads;
 136        /* region "cold" timer - for host mode */
 137        ktime_t read_timeout;
 138        unsigned int read_timeout_expiries;
 139        struct list_head list_expired_rgn;
 140};
 141
 142#define for_each_sub_region(rgn, i, srgn)                               \
 143        for ((i) = 0;                                                   \
 144             ((i) < (rgn)->srgn_cnt) && ((srgn) = &(rgn)->srgn_tbl[i]); \
 145             (i)++)
 146
 147/**
 148 * struct ufshpb_req - HPB related request structure (write/read buffer)
 149 * @req: block layer request structure
 150 * @bio: bio for this request
 151 * @hpb: ufshpb_lu structure that related to
 152 * @list_req: ufshpb_req mempool list
 153 * @sense: store its sense data
 154 * @mctx: L2P map information
 155 * @rgn_idx: target region index
 156 * @srgn_idx: target sub-region index
 157 * @lun: target logical unit number
 158 * @m_page: L2P map information data for pre-request
 159 * @len: length of host-side cached L2P map in m_page
 160 * @lpn: start LPN of L2P map in m_page
 161 */
 162struct ufshpb_req {
 163        struct request *req;
 164        struct bio *bio;
 165        struct ufshpb_lu *hpb;
 166        struct list_head list_req;
 167        union {
 168                struct {
 169                        struct ufshpb_map_ctx *mctx;
 170                        unsigned int rgn_idx;
 171                        unsigned int srgn_idx;
 172                        unsigned int lun;
 173                } rb;
 174                struct {
 175                        struct page *m_page;
 176                        unsigned int len;
 177                        unsigned long lpn;
 178                } wb;
 179        };
 180};
 181
 182struct victim_select_info {
 183        struct list_head lh_lru_rgn; /* LRU list of regions */
 184        int max_lru_active_cnt; /* supported hpb #region - pinned #region */
 185        atomic_t active_cnt;
 186};
 187
 188/**
 189 * ufshpb_params - ufs hpb parameters
 190 * @requeue_timeout_ms - requeue threshold of wb command (0x2)
 191 * @activation_thld - min reads [IOs] to activate/update a region
 192 * @normalization_factor - shift right the region's reads
 193 * @eviction_thld_enter - min reads [IOs] for the entering region in eviction
 194 * @eviction_thld_exit - max reads [IOs] for the exiting region in eviction
 195 * @read_timeout_ms - timeout [ms] from the last read IO to the region
 196 * @read_timeout_expiries - amount of allowable timeout expireis
 197 * @timeout_polling_interval_ms - frequency in which timeouts are checked
 198 * @inflight_map_req - number of inflight map requests
 199 */
 200struct ufshpb_params {
 201        unsigned int requeue_timeout_ms;
 202        unsigned int activation_thld;
 203        unsigned int normalization_factor;
 204        unsigned int eviction_thld_enter;
 205        unsigned int eviction_thld_exit;
 206        unsigned int read_timeout_ms;
 207        unsigned int read_timeout_expiries;
 208        unsigned int timeout_polling_interval_ms;
 209        unsigned int inflight_map_req;
 210};
 211
 212struct ufshpb_stats {
 213        u64 hit_cnt;
 214        u64 miss_cnt;
 215        u64 rb_noti_cnt;
 216        u64 rb_active_cnt;
 217        u64 rb_inactive_cnt;
 218        u64 map_req_cnt;
 219        u64 pre_req_cnt;
 220        u64 umap_req_cnt;
 221};
 222
 223struct ufshpb_lu {
 224        int lun;
 225        struct scsi_device *sdev_ufs_lu;
 226
 227        spinlock_t rgn_state_lock; /* for protect rgn/srgn state */
 228        struct ufshpb_region *rgn_tbl;
 229
 230        atomic_t hpb_state;
 231
 232        spinlock_t rsp_list_lock;
 233        struct list_head lh_act_srgn; /* hold rsp_list_lock */
 234        struct list_head lh_inact_rgn; /* hold rsp_list_lock */
 235
 236        /* pre request information */
 237        struct ufshpb_req *pre_req;
 238        int num_inflight_pre_req;
 239        int throttle_pre_req;
 240        int num_inflight_map_req; /* hold param_lock */
 241        spinlock_t param_lock;
 242
 243        struct list_head lh_pre_req_free;
 244        int pre_req_max_tr_len;
 245
 246        /* cached L2P map management worker */
 247        struct work_struct map_work;
 248
 249        /* for selecting victim */
 250        struct victim_select_info lru_info;
 251        struct work_struct ufshpb_normalization_work;
 252        struct delayed_work ufshpb_read_to_work;
 253        unsigned long work_data_bits;
 254#define TIMEOUT_WORK_RUNNING 0
 255
 256        /* pinned region information */
 257        u32 lu_pinned_start;
 258        u32 lu_pinned_end;
 259
 260        /* HPB related configuration */
 261        u32 rgns_per_lu;
 262        u32 srgns_per_lu;
 263        u32 last_srgn_entries;
 264        int srgns_per_rgn;
 265        u32 srgn_mem_size;
 266        u32 entries_per_rgn_mask;
 267        u32 entries_per_rgn_shift;
 268        u32 entries_per_srgn;
 269        u32 entries_per_srgn_mask;
 270        u32 entries_per_srgn_shift;
 271        u32 pages_per_srgn;
 272
 273        bool is_hcm;
 274
 275        struct ufshpb_stats stats;
 276        struct ufshpb_params params;
 277
 278        struct kmem_cache *map_req_cache;
 279        struct kmem_cache *m_page_cache;
 280
 281        struct list_head list_hpb_lu;
 282};
 283
 284struct ufs_hba;
 285struct ufshcd_lrb;
 286
 287#ifndef CONFIG_SCSI_UFS_HPB
 288static int ufshpb_prep(struct ufs_hba *hba, struct ufshcd_lrb *lrbp) { return 0; }
 289static void ufshpb_rsp_upiu(struct ufs_hba *hba, struct ufshcd_lrb *lrbp) {}
 290static void ufshpb_resume(struct ufs_hba *hba) {}
 291static void ufshpb_suspend(struct ufs_hba *hba) {}
 292static void ufshpb_reset(struct ufs_hba *hba) {}
 293static void ufshpb_reset_host(struct ufs_hba *hba) {}
 294static void ufshpb_init(struct ufs_hba *hba) {}
 295static void ufshpb_init_hpb_lu(struct ufs_hba *hba, struct scsi_device *sdev) {}
 296static void ufshpb_destroy_lu(struct ufs_hba *hba, struct scsi_device *sdev) {}
 297static void ufshpb_remove(struct ufs_hba *hba) {}
 298static bool ufshpb_is_allowed(struct ufs_hba *hba) { return false; }
 299static void ufshpb_get_geo_info(struct ufs_hba *hba, u8 *geo_buf) {}
 300static void ufshpb_get_dev_info(struct ufs_hba *hba, u8 *desc_buf) {}
 301static bool ufshpb_is_legacy(struct ufs_hba *hba) { return false; }
 302#else
 303int ufshpb_prep(struct ufs_hba *hba, struct ufshcd_lrb *lrbp);
 304void ufshpb_rsp_upiu(struct ufs_hba *hba, struct ufshcd_lrb *lrbp);
 305void ufshpb_resume(struct ufs_hba *hba);
 306void ufshpb_suspend(struct ufs_hba *hba);
 307void ufshpb_reset(struct ufs_hba *hba);
 308void ufshpb_reset_host(struct ufs_hba *hba);
 309void ufshpb_init(struct ufs_hba *hba);
 310void ufshpb_init_hpb_lu(struct ufs_hba *hba, struct scsi_device *sdev);
 311void ufshpb_destroy_lu(struct ufs_hba *hba, struct scsi_device *sdev);
 312void ufshpb_remove(struct ufs_hba *hba);
 313bool ufshpb_is_allowed(struct ufs_hba *hba);
 314void ufshpb_get_geo_info(struct ufs_hba *hba, u8 *geo_buf);
 315void ufshpb_get_dev_info(struct ufs_hba *hba, u8 *desc_buf);
 316bool ufshpb_is_legacy(struct ufs_hba *hba);
 317extern struct attribute_group ufs_sysfs_hpb_stat_group;
 318extern struct attribute_group ufs_sysfs_hpb_param_group;
 319#endif
 320
 321#endif /* End of Header */
 322