[SCSI] ufs: fix the setting interrupt aggregation counter
IACTH(Interrupt aggregation counter threshold) value is allowed up to 0x1F and current setting value is the maximum. This value is related with NUTRS(max:0x20) of HCI's capability. Considering HCI controller doesn't support the maximum, IACTH setting should be adjusted with possible value. For that, existing 'ufshcd_config_int_aggr' is split into two part [reset, configure]. Signed-off-by: Seungwon Jeon <tgih.jun@samsung.com> Reviewed-by: Subhash Jadavani <subhashj@codeaurora.org> Tested-by: Yaniv Gardi <ygardi@codeaurora.org> Signed-off-by: Santosh Y <santoshsy@gmail.com> Signed-off-by: James Bottomley <JBottomley@Parallels.com>
This commit is contained in:
Родитель
1c2623c50d
Коммит
7d568652d3
|
@ -56,6 +56,9 @@
|
||||||
/* Expose the flag value from utp_upiu_query.value */
|
/* Expose the flag value from utp_upiu_query.value */
|
||||||
#define MASK_QUERY_UPIU_FLAG_LOC 0xFF
|
#define MASK_QUERY_UPIU_FLAG_LOC 0xFF
|
||||||
|
|
||||||
|
/* Interrupt aggregation default timeout, unit: 40us */
|
||||||
|
#define INT_AGGR_DEF_TO 0x02
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
UFSHCD_MAX_CHANNEL = 0,
|
UFSHCD_MAX_CHANNEL = 0,
|
||||||
UFSHCD_MAX_ID = 1,
|
UFSHCD_MAX_ID = 1,
|
||||||
|
@ -78,12 +81,6 @@ enum {
|
||||||
UFSHCD_INT_CLEAR,
|
UFSHCD_INT_CLEAR,
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Interrupt aggregation options */
|
|
||||||
enum {
|
|
||||||
INT_AGGR_RESET,
|
|
||||||
INT_AGGR_CONFIG,
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* ufshcd_wait_for_register - wait for register value to change
|
* ufshcd_wait_for_register - wait for register value to change
|
||||||
* @hba - per-adapter interface
|
* @hba - per-adapter interface
|
||||||
|
@ -290,30 +287,30 @@ static inline bool ufshcd_is_exception_event(struct utp_upiu_rsp *ucd_rsp_ptr)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ufshcd_config_int_aggr - Configure interrupt aggregation values.
|
* ufshcd_reset_intr_aggr - Reset interrupt aggregation values.
|
||||||
* Currently there is no use case where we want to configure
|
|
||||||
* interrupt aggregation dynamically. So to configure interrupt
|
|
||||||
* aggregation, #define INT_AGGR_COUNTER_THRESHOLD_VALUE and
|
|
||||||
* INT_AGGR_TIMEOUT_VALUE are used.
|
|
||||||
* @hba: per adapter instance
|
* @hba: per adapter instance
|
||||||
* @option: Interrupt aggregation option
|
|
||||||
*/
|
*/
|
||||||
static inline void
|
static inline void
|
||||||
ufshcd_config_int_aggr(struct ufs_hba *hba, int option)
|
ufshcd_reset_intr_aggr(struct ufs_hba *hba)
|
||||||
{
|
{
|
||||||
switch (option) {
|
|
||||||
case INT_AGGR_RESET:
|
|
||||||
ufshcd_writel(hba, INT_AGGR_ENABLE |
|
ufshcd_writel(hba, INT_AGGR_ENABLE |
|
||||||
INT_AGGR_COUNTER_AND_TIMER_RESET,
|
INT_AGGR_COUNTER_AND_TIMER_RESET,
|
||||||
REG_UTP_TRANSFER_REQ_INT_AGG_CONTROL);
|
REG_UTP_TRANSFER_REQ_INT_AGG_CONTROL);
|
||||||
break;
|
|
||||||
case INT_AGGR_CONFIG:
|
|
||||||
ufshcd_writel(hba, INT_AGGR_ENABLE | INT_AGGR_PARAM_WRITE |
|
|
||||||
INT_AGGR_COUNTER_THRESHOLD_VALUE |
|
|
||||||
INT_AGGR_TIMEOUT_VALUE,
|
|
||||||
REG_UTP_TRANSFER_REQ_INT_AGG_CONTROL);
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ufshcd_config_intr_aggr - Configure interrupt aggregation values.
|
||||||
|
* @hba: per adapter instance
|
||||||
|
* @cnt: Interrupt aggregation counter threshold
|
||||||
|
* @tmout: Interrupt aggregation timeout value
|
||||||
|
*/
|
||||||
|
static inline void
|
||||||
|
ufshcd_config_intr_aggr(struct ufs_hba *hba, u8 cnt, u8 tmout)
|
||||||
|
{
|
||||||
|
ufshcd_writel(hba, INT_AGGR_ENABLE | INT_AGGR_PARAM_WRITE |
|
||||||
|
INT_AGGR_COUNTER_THLD_VAL(cnt) |
|
||||||
|
INT_AGGR_TIMEOUT_VAL(tmout),
|
||||||
|
REG_UTP_TRANSFER_REQ_INT_AGG_CONTROL);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1457,7 +1454,7 @@ static int ufshcd_make_hba_operational(struct ufs_hba *hba)
|
||||||
ufshcd_enable_intr(hba, UFSHCD_ENABLE_INTRS);
|
ufshcd_enable_intr(hba, UFSHCD_ENABLE_INTRS);
|
||||||
|
|
||||||
/* Configure interrupt aggregation */
|
/* Configure interrupt aggregation */
|
||||||
ufshcd_config_int_aggr(hba, INT_AGGR_CONFIG);
|
ufshcd_config_intr_aggr(hba, hba->nutrs - 1, INT_AGGR_DEF_TO);
|
||||||
|
|
||||||
/* Configure UTRL and UTMRL base address registers */
|
/* Configure UTRL and UTMRL base address registers */
|
||||||
ufshcd_writel(hba, lower_32_bits(hba->utrdl_dma_addr),
|
ufshcd_writel(hba, lower_32_bits(hba->utrdl_dma_addr),
|
||||||
|
@ -1967,7 +1964,7 @@ static void ufshcd_transfer_req_compl(struct ufs_hba *hba)
|
||||||
|
|
||||||
/* Reset interrupt aggregation counters */
|
/* Reset interrupt aggregation counters */
|
||||||
if (int_aggr_reset)
|
if (int_aggr_reset)
|
||||||
ufshcd_config_int_aggr(hba, INT_AGGR_RESET);
|
ufshcd_reset_intr_aggr(hba);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -226,8 +226,8 @@ enum {
|
||||||
|
|
||||||
#define MASK_UIC_COMMAND_RESULT 0xFF
|
#define MASK_UIC_COMMAND_RESULT 0xFF
|
||||||
|
|
||||||
#define INT_AGGR_COUNTER_THRESHOLD_VALUE (0x1F << 8)
|
#define INT_AGGR_COUNTER_THLD_VAL(c) (((c) & 0x1F) << 8)
|
||||||
#define INT_AGGR_TIMEOUT_VALUE (0x02)
|
#define INT_AGGR_TIMEOUT_VAL(t) (((t) & 0xFF) << 0)
|
||||||
|
|
||||||
/* Interrupt disable masks */
|
/* Interrupt disable masks */
|
||||||
enum {
|
enum {
|
||||||
|
|
Загрузка…
Ссылка в новой задаче