aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/memory
diff options
context:
space:
mode:
authorNishanth Menon <nm@ti.com>2013-03-16 02:16:43 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2013-03-25 16:18:12 -0400
commit25aaacd2834233bbfa2b7ec697bfce42707e35b7 (patch)
treeb8352a0f79151e2255c5c9736fbcdf604bf9895d /drivers/memory
parent9ea03dec380208bfee015b25f253c2f58aba0071 (diff)
memory: emif: handle overflow for timing for LP mode
In case the custom timings provide values which overflow the maximum possible field value, warn and use maximum permissible value. Signed-off-by: Nishanth Menon <nm@ti.com> Signed-off-by: Lokesh Vutla <lokeshvutla@ti.com> Acked-by: Santosh Shilimkar <santosh.shilimkar@ti.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/memory')
-rw-r--r--drivers/memory/emif.c36
1 files changed, 28 insertions, 8 deletions
diff --git a/drivers/memory/emif.c b/drivers/memory/emif.c
index bda11ebb25cd..249222905c94 100644
--- a/drivers/memory/emif.c
+++ b/drivers/memory/emif.c
@@ -715,6 +715,8 @@ static u32 get_pwr_mgmt_ctrl(u32 freq, struct emif_data *emif, u32 ip_rev)
715 u32 timeout_perf = EMIF_LP_MODE_TIMEOUT_PERFORMANCE; 715 u32 timeout_perf = EMIF_LP_MODE_TIMEOUT_PERFORMANCE;
716 u32 timeout_pwr = EMIF_LP_MODE_TIMEOUT_POWER; 716 u32 timeout_pwr = EMIF_LP_MODE_TIMEOUT_POWER;
717 u32 freq_threshold = EMIF_LP_MODE_FREQ_THRESHOLD; 717 u32 freq_threshold = EMIF_LP_MODE_FREQ_THRESHOLD;
718 u32 mask;
719 u8 shift;
718 720
719 struct emif_custom_configs *cust_cfgs = emif->plat_data->custom_configs; 721 struct emif_custom_configs *cust_cfgs = emif->plat_data->custom_configs;
720 722
@@ -743,27 +745,45 @@ static u32 get_pwr_mgmt_ctrl(u32 freq, struct emif_data *emif, u32 ip_rev)
743 745
744 switch (lpmode) { 746 switch (lpmode) {
745 case EMIF_LP_MODE_CLOCK_STOP: 747 case EMIF_LP_MODE_CLOCK_STOP:
746 pwr_mgmt_ctrl = (timeout << CS_TIM_SHIFT) | 748 shift = CS_TIM_SHIFT;
747 SR_TIM_MASK | PD_TIM_MASK; 749 mask = CS_TIM_MASK;
748 break; 750 break;
749 case EMIF_LP_MODE_SELF_REFRESH: 751 case EMIF_LP_MODE_SELF_REFRESH:
750 /* Workaround for errata i735 */ 752 /* Workaround for errata i735 */
751 if (timeout < 6) 753 if (timeout < 6)
752 timeout = 6; 754 timeout = 6;
753 755
754 pwr_mgmt_ctrl = (timeout << SR_TIM_SHIFT) | 756 shift = SR_TIM_SHIFT;
755 CS_TIM_MASK | PD_TIM_MASK; 757 mask = SR_TIM_MASK;
756 break; 758 break;
757 case EMIF_LP_MODE_PWR_DN: 759 case EMIF_LP_MODE_PWR_DN:
758 pwr_mgmt_ctrl = (timeout << PD_TIM_SHIFT) | 760 shift = PD_TIM_SHIFT;
759 CS_TIM_MASK | SR_TIM_MASK; 761 mask = PD_TIM_MASK;
760 break; 762 break;
761 case EMIF_LP_MODE_DISABLE: 763 case EMIF_LP_MODE_DISABLE:
762 default: 764 default:
763 pwr_mgmt_ctrl = CS_TIM_MASK | 765 mask = 0;
764 PD_TIM_MASK | SR_TIM_MASK; 766 shift = 0;
767 break;
768 }
769 /* Round to maximum in case of overflow, BUT warn! */
770 if (lpmode != EMIF_LP_MODE_DISABLE && timeout > mask >> shift) {
771 pr_err("TIMEOUT Overflow - lpmode=%d perf=%d pwr=%d freq=%d\n",
772 lpmode,
773 timeout_perf,
774 timeout_pwr,
775 freq_threshold);
776 WARN(1, "timeout=0x%02x greater than 0x%02x. Using max\n",
777 timeout, mask >> shift);
778 timeout = mask >> shift;
765 } 779 }
766 780
781 /* Setup required timing */
782 pwr_mgmt_ctrl = (timeout << shift) & mask;
783 /* setup a default mask for rest of the modes */
784 pwr_mgmt_ctrl |= (SR_TIM_MASK | CS_TIM_MASK | PD_TIM_MASK) &
785 ~mask;
786
767 /* No CS_TIM in EMIF_4D5 */ 787 /* No CS_TIM in EMIF_4D5 */
768 if (ip_rev == EMIF_4D5) 788 if (ip_rev == EMIF_4D5)
769 pwr_mgmt_ctrl &= ~CS_TIM_MASK; 789 pwr_mgmt_ctrl &= ~CS_TIM_MASK;