aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorSeungwon Jeon <tgih.jun@samsung.com>2013-08-31 12:10:20 -0400
committerJames Bottomley <JBottomley@Parallels.com>2013-09-06 19:00:53 -0400
commit7d568652d3abc81a6d684d4760571a3ccb6f68d9 (patch)
tree7f8ea65eb95da32ca155c6eb5359f27d26a54555 /drivers
parent1c2623c50dfd38c823a62c57af2ca9551a861b21 (diff)
[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>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/scsi/ufs/ufshcd.c53
-rw-r--r--drivers/scsi/ufs/ufshci.h4
2 files changed, 27 insertions, 30 deletions
diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c
index 6c34f6ae8870..46b0754b4b76 100644
--- a/drivers/scsi/ufs/ufshcd.c
+++ b/drivers/scsi/ufs/ufshcd.c
@@ -56,6 +56,9 @@
56/* Expose the flag value from utp_upiu_query.value */ 56/* Expose the flag value from utp_upiu_query.value */
57#define MASK_QUERY_UPIU_FLAG_LOC 0xFF 57#define MASK_QUERY_UPIU_FLAG_LOC 0xFF
58 58
59/* Interrupt aggregation default timeout, unit: 40us */
60#define INT_AGGR_DEF_TO 0x02
61
59enum { 62enum {
60 UFSHCD_MAX_CHANNEL = 0, 63 UFSHCD_MAX_CHANNEL = 0,
61 UFSHCD_MAX_ID = 1, 64 UFSHCD_MAX_ID = 1,
@@ -78,12 +81,6 @@ enum {
78 UFSHCD_INT_CLEAR, 81 UFSHCD_INT_CLEAR,
79}; 82};
80 83
81/* Interrupt aggregation options */
82enum {
83 INT_AGGR_RESET,
84 INT_AGGR_CONFIG,
85};
86
87/* 84/*
88 * ufshcd_wait_for_register - wait for register value to change 85 * ufshcd_wait_for_register - wait for register value to change
89 * @hba - per-adapter interface 86 * @hba - per-adapter interface
@@ -290,30 +287,30 @@ static inline bool ufshcd_is_exception_event(struct utp_upiu_rsp *ucd_rsp_ptr)
290} 287}
291 288
292/** 289/**
293 * ufshcd_config_int_aggr - Configure interrupt aggregation values. 290 * ufshcd_reset_intr_aggr - Reset interrupt aggregation values.
294 * Currently there is no use case where we want to configure
295 * interrupt aggregation dynamically. So to configure interrupt
296 * aggregation, #define INT_AGGR_COUNTER_THRESHOLD_VALUE and
297 * INT_AGGR_TIMEOUT_VALUE are used.
298 * @hba: per adapter instance 291 * @hba: per adapter instance
299 * @option: Interrupt aggregation option
300 */ 292 */
301static inline void 293static inline void
302ufshcd_config_int_aggr(struct ufs_hba *hba, int option) 294ufshcd_reset_intr_aggr(struct ufs_hba *hba)
303{ 295{
304 switch (option) { 296 ufshcd_writel(hba, INT_AGGR_ENABLE |
305 case INT_AGGR_RESET: 297 INT_AGGR_COUNTER_AND_TIMER_RESET,
306 ufshcd_writel(hba, INT_AGGR_ENABLE | 298 REG_UTP_TRANSFER_REQ_INT_AGG_CONTROL);
307 INT_AGGR_COUNTER_AND_TIMER_RESET, 299}
308 REG_UTP_TRANSFER_REQ_INT_AGG_CONTROL); 300
309 break; 301/**
310 case INT_AGGR_CONFIG: 302 * ufshcd_config_intr_aggr - Configure interrupt aggregation values.
311 ufshcd_writel(hba, INT_AGGR_ENABLE | INT_AGGR_PARAM_WRITE | 303 * @hba: per adapter instance
312 INT_AGGR_COUNTER_THRESHOLD_VALUE | 304 * @cnt: Interrupt aggregation counter threshold
313 INT_AGGR_TIMEOUT_VALUE, 305 * @tmout: Interrupt aggregation timeout value
314 REG_UTP_TRANSFER_REQ_INT_AGG_CONTROL); 306 */
315 break; 307static inline void
316 } 308ufshcd_config_intr_aggr(struct ufs_hba *hba, u8 cnt, u8 tmout)
309{
310 ufshcd_writel(hba, INT_AGGR_ENABLE | INT_AGGR_PARAM_WRITE |
311 INT_AGGR_COUNTER_THLD_VAL(cnt) |
312 INT_AGGR_TIMEOUT_VAL(tmout),
313 REG_UTP_TRANSFER_REQ_INT_AGG_CONTROL);
317} 314}
318 315
319/** 316/**
@@ -1457,7 +1454,7 @@ static int ufshcd_make_hba_operational(struct ufs_hba *hba)
1457 ufshcd_enable_intr(hba, UFSHCD_ENABLE_INTRS); 1454 ufshcd_enable_intr(hba, UFSHCD_ENABLE_INTRS);
1458 1455
1459 /* Configure interrupt aggregation */ 1456 /* Configure interrupt aggregation */
1460 ufshcd_config_int_aggr(hba, INT_AGGR_CONFIG); 1457 ufshcd_config_intr_aggr(hba, hba->nutrs - 1, INT_AGGR_DEF_TO);
1461 1458
1462 /* Configure UTRL and UTMRL base address registers */ 1459 /* Configure UTRL and UTMRL base address registers */
1463 ufshcd_writel(hba, lower_32_bits(hba->utrdl_dma_addr), 1460 ufshcd_writel(hba, lower_32_bits(hba->utrdl_dma_addr),
@@ -1967,7 +1964,7 @@ static void ufshcd_transfer_req_compl(struct ufs_hba *hba)
1967 1964
1968 /* Reset interrupt aggregation counters */ 1965 /* Reset interrupt aggregation counters */
1969 if (int_aggr_reset) 1966 if (int_aggr_reset)
1970 ufshcd_config_int_aggr(hba, INT_AGGR_RESET); 1967 ufshcd_reset_intr_aggr(hba);
1971} 1968}
1972 1969
1973/** 1970/**
diff --git a/drivers/scsi/ufs/ufshci.h b/drivers/scsi/ufs/ufshci.h
index f1e1b7459107..739ae3aade0e 100644
--- a/drivers/scsi/ufs/ufshci.h
+++ b/drivers/scsi/ufs/ufshci.h
@@ -226,8 +226,8 @@ enum {
226 226
227#define MASK_UIC_COMMAND_RESULT 0xFF 227#define MASK_UIC_COMMAND_RESULT 0xFF
228 228
229#define INT_AGGR_COUNTER_THRESHOLD_VALUE (0x1F << 8) 229#define INT_AGGR_COUNTER_THLD_VAL(c) (((c) & 0x1F) << 8)
230#define INT_AGGR_TIMEOUT_VALUE (0x02) 230#define INT_AGGR_TIMEOUT_VAL(t) (((t) & 0xFF) << 0)
231 231
232/* Interrupt disable masks */ 232/* Interrupt disable masks */
233enum { 233enum {