diff options
author | Seungwon Jeon <tgih.jun@samsung.com> | 2013-08-31 12:10:20 -0400 |
---|---|---|
committer | James Bottomley <JBottomley@Parallels.com> | 2013-09-06 19:00:53 -0400 |
commit | 7d568652d3abc81a6d684d4760571a3ccb6f68d9 (patch) | |
tree | 7f8ea65eb95da32ca155c6eb5359f27d26a54555 /drivers/scsi | |
parent | 1c2623c50dfd38c823a62c57af2ca9551a861b21 (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/scsi')
-rw-r--r-- | drivers/scsi/ufs/ufshcd.c | 53 | ||||
-rw-r--r-- | drivers/scsi/ufs/ufshci.h | 4 |
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 | |||
59 | enum { | 62 | enum { |
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 */ | ||
82 | enum { | ||
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 | */ |
301 | static inline void | 293 | static inline void |
302 | ufshcd_config_int_aggr(struct ufs_hba *hba, int option) | 294 | ufshcd_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; | 307 | static inline void |
316 | } | 308 | ufshcd_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 */ |
233 | enum { | 233 | enum { |