aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/memory
diff options
context:
space:
mode:
authorAneesh V <aneesh@ti.com>2012-04-27 08:24:07 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2012-05-02 13:56:30 -0400
commit68b4aee35d1fb8399068aa6e6c908584690d0b06 (patch)
tree8ab447cf4a83d0fa6020663c96d440e3dbfd331e /drivers/memory
parenta93de288aad3b046935d626065d4bcbb7d93b093 (diff)
memory: emif: add interrupt and temperature handling
Add an ISR for EMIF that: 1. reports details of access errors 2. takes action on thermal events Also clear all interrupts on shut-down. Pending IRQs may casue problems during warm-reset. Temperature handling: EMIF can be configured to poll the temperature level of an LPDDR2 device from the MR4 mode register in the device. EMIF generates an interrupt whenever it identifies a temperature level change between two consecutive pollings. Some of the timing parameters need to be de-rated at high temperatures. The interrupt handler takes care of doing this and also takes care of going back to nominal settings when temperature falls back to nominal levels. Signed-off-by: Aneesh V <aneesh@ti.com> Reviewed-by: Santosh Shilimkar <santosh.shilimkar@ti.com> Reviewed-by: Benoit Cousson <b-cousson@ti.com> [santosh.shilimkar@ti.com: Moved to drivers/memory from drivers/misc] Signed-off-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.c211
1 files changed, 209 insertions, 2 deletions
diff --git a/drivers/memory/emif.c b/drivers/memory/emif.c
index bd116eb8c738..a8dcf3515573 100644
--- a/drivers/memory/emif.c
+++ b/drivers/memory/emif.c
@@ -545,6 +545,42 @@ static u32 get_pwr_mgmt_ctrl(u32 freq, struct emif_data *emif, u32 ip_rev)
545} 545}
546 546
547/* 547/*
548 * Get the temperature level of the EMIF instance:
549 * Reads the MR4 register of attached SDRAM parts to find out the temperature
550 * level. If there are two parts attached(one on each CS), then the temperature
551 * level for the EMIF instance is the higher of the two temperatures.
552 */
553static void get_temperature_level(struct emif_data *emif)
554{
555 u32 temp, temperature_level;
556 void __iomem *base;
557
558 base = emif->base;
559
560 /* Read mode register 4 */
561 writel(DDR_MR4, base + EMIF_LPDDR2_MODE_REG_CONFIG);
562 temperature_level = readl(base + EMIF_LPDDR2_MODE_REG_DATA);
563 temperature_level = (temperature_level & MR4_SDRAM_REF_RATE_MASK) >>
564 MR4_SDRAM_REF_RATE_SHIFT;
565
566 if (emif->plat_data->device_info->cs1_used) {
567 writel(DDR_MR4 | CS_MASK, base + EMIF_LPDDR2_MODE_REG_CONFIG);
568 temp = readl(base + EMIF_LPDDR2_MODE_REG_DATA);
569 temp = (temp & MR4_SDRAM_REF_RATE_MASK)
570 >> MR4_SDRAM_REF_RATE_SHIFT;
571 temperature_level = max(temp, temperature_level);
572 }
573
574 /* treat everything less than nominal(3) in MR4 as nominal */
575 if (unlikely(temperature_level < SDRAM_TEMP_NOMINAL))
576 temperature_level = SDRAM_TEMP_NOMINAL;
577
578 /* if we get reserved value in MR4 persist with the existing value */
579 if (likely(temperature_level != SDRAM_TEMP_RESERVED_4))
580 emif->temperature_level = temperature_level;
581}
582
583/*
548 * Program EMIF shadow registers that are not dependent on temperature 584 * Program EMIF shadow registers that are not dependent on temperature
549 * or voltage 585 * or voltage
550 */ 586 */
@@ -627,6 +663,158 @@ out:
627 writel(ref_ctrl, base + EMIF_SDRAM_REFRESH_CTRL_SHDW); 663 writel(ref_ctrl, base + EMIF_SDRAM_REFRESH_CTRL_SHDW);
628} 664}
629 665
666static irqreturn_t handle_temp_alert(void __iomem *base, struct emif_data *emif)
667{
668 u32 old_temp_level;
669 irqreturn_t ret = IRQ_HANDLED;
670
671 spin_lock_irqsave(&emif_lock, irq_state);
672 old_temp_level = emif->temperature_level;
673 get_temperature_level(emif);
674
675 if (unlikely(emif->temperature_level == old_temp_level)) {
676 goto out;
677 } else if (!emif->curr_regs) {
678 dev_err(emif->dev, "temperature alert before registers are calculated, not de-rating timings\n");
679 goto out;
680 }
681
682 if (emif->temperature_level < old_temp_level ||
683 emif->temperature_level == SDRAM_TEMP_VERY_HIGH_SHUTDOWN) {
684 /*
685 * Temperature coming down - defer handling to thread OR
686 * Temperature far too high - do kernel_power_off() from
687 * thread context
688 */
689 ret = IRQ_WAKE_THREAD;
690 } else {
691 /* Temperature is going up - handle immediately */
692 setup_temperature_sensitive_regs(emif, emif->curr_regs);
693 do_freq_update();
694 }
695
696out:
697 spin_unlock_irqrestore(&emif_lock, irq_state);
698 return ret;
699}
700
701static irqreturn_t emif_interrupt_handler(int irq, void *dev_id)
702{
703 u32 interrupts;
704 struct emif_data *emif = dev_id;
705 void __iomem *base = emif->base;
706 struct device *dev = emif->dev;
707 irqreturn_t ret = IRQ_HANDLED;
708
709 /* Save the status and clear it */
710 interrupts = readl(base + EMIF_SYSTEM_OCP_INTERRUPT_STATUS);
711 writel(interrupts, base + EMIF_SYSTEM_OCP_INTERRUPT_STATUS);
712
713 /*
714 * Handle temperature alert
715 * Temperature alert should be same for all ports
716 * So, it's enough to process it only for one of the ports
717 */
718 if (interrupts & TA_SYS_MASK)
719 ret = handle_temp_alert(base, emif);
720
721 if (interrupts & ERR_SYS_MASK)
722 dev_err(dev, "Access error from SYS port - %x\n", interrupts);
723
724 if (emif->plat_data->hw_caps & EMIF_HW_CAPS_LL_INTERFACE) {
725 /* Save the status and clear it */
726 interrupts = readl(base + EMIF_LL_OCP_INTERRUPT_STATUS);
727 writel(interrupts, base + EMIF_LL_OCP_INTERRUPT_STATUS);
728
729 if (interrupts & ERR_LL_MASK)
730 dev_err(dev, "Access error from LL port - %x\n",
731 interrupts);
732 }
733
734 return ret;
735}
736
737static irqreturn_t emif_threaded_isr(int irq, void *dev_id)
738{
739 struct emif_data *emif = dev_id;
740
741 if (emif->temperature_level == SDRAM_TEMP_VERY_HIGH_SHUTDOWN) {
742 dev_emerg(emif->dev, "SDRAM temperature exceeds operating limit.. Needs shut down!!!\n");
743 kernel_power_off();
744 return IRQ_HANDLED;
745 }
746
747 spin_lock_irqsave(&emif_lock, irq_state);
748
749 if (emif->curr_regs) {
750 setup_temperature_sensitive_regs(emif, emif->curr_regs);
751 do_freq_update();
752 } else {
753 dev_err(emif->dev, "temperature alert before registers are calculated, not de-rating timings\n");
754 }
755
756 spin_unlock_irqrestore(&emif_lock, irq_state);
757
758 return IRQ_HANDLED;
759}
760
761static void clear_all_interrupts(struct emif_data *emif)
762{
763 void __iomem *base = emif->base;
764
765 writel(readl(base + EMIF_SYSTEM_OCP_INTERRUPT_STATUS),
766 base + EMIF_SYSTEM_OCP_INTERRUPT_STATUS);
767 if (emif->plat_data->hw_caps & EMIF_HW_CAPS_LL_INTERFACE)
768 writel(readl(base + EMIF_LL_OCP_INTERRUPT_STATUS),
769 base + EMIF_LL_OCP_INTERRUPT_STATUS);
770}
771
772static void disable_and_clear_all_interrupts(struct emif_data *emif)
773{
774 void __iomem *base = emif->base;
775
776 /* Disable all interrupts */
777 writel(readl(base + EMIF_SYSTEM_OCP_INTERRUPT_ENABLE_SET),
778 base + EMIF_SYSTEM_OCP_INTERRUPT_ENABLE_CLEAR);
779 if (emif->plat_data->hw_caps & EMIF_HW_CAPS_LL_INTERFACE)
780 writel(readl(base + EMIF_LL_OCP_INTERRUPT_ENABLE_SET),
781 base + EMIF_LL_OCP_INTERRUPT_ENABLE_CLEAR);
782
783 /* Clear all interrupts */
784 clear_all_interrupts(emif);
785}
786
787static int __init_or_module setup_interrupts(struct emif_data *emif, u32 irq)
788{
789 u32 interrupts, type;
790 void __iomem *base = emif->base;
791
792 type = emif->plat_data->device_info->type;
793
794 clear_all_interrupts(emif);
795
796 /* Enable interrupts for SYS interface */
797 interrupts = EN_ERR_SYS_MASK;
798 if (type == DDR_TYPE_LPDDR2_S2 || type == DDR_TYPE_LPDDR2_S4)
799 interrupts |= EN_TA_SYS_MASK;
800 writel(interrupts, base + EMIF_SYSTEM_OCP_INTERRUPT_ENABLE_SET);
801
802 /* Enable interrupts for LL interface */
803 if (emif->plat_data->hw_caps & EMIF_HW_CAPS_LL_INTERFACE) {
804 /* TA need not be enabled for LL */
805 interrupts = EN_ERR_LL_MASK;
806 writel(interrupts, base + EMIF_LL_OCP_INTERRUPT_ENABLE_SET);
807 }
808
809 /* setup IRQ handlers */
810 return devm_request_threaded_irq(emif->dev, irq,
811 emif_interrupt_handler,
812 emif_threaded_isr,
813 0, dev_name(emif->dev),
814 emif);
815
816}
817
630static void get_default_timings(struct emif_data *emif) 818static void get_default_timings(struct emif_data *emif)
631{ 819{
632 struct emif_platform_data *pd = emif->plat_data; 820 struct emif_platform_data *pd = emif->plat_data;
@@ -803,6 +991,7 @@ static int __init_or_module emif_probe(struct platform_device *pdev)
803{ 991{
804 struct emif_data *emif; 992 struct emif_data *emif;
805 struct resource *res; 993 struct resource *res;
994 int irq;
806 995
807 emif = get_device_details(pdev); 996 emif = get_device_details(pdev);
808 if (!emif) { 997 if (!emif) {
@@ -831,6 +1020,16 @@ static int __init_or_module emif_probe(struct platform_device *pdev)
831 goto error; 1020 goto error;
832 } 1021 }
833 1022
1023 irq = platform_get_irq(pdev, 0);
1024 if (irq < 0) {
1025 dev_err(emif->dev, "%s: error getting IRQ resource - %d\n",
1026 __func__, irq);
1027 goto error;
1028 }
1029
1030 disable_and_clear_all_interrupts(emif);
1031 setup_interrupts(emif, irq);
1032
834 /* One-time actions taken on probing the first device */ 1033 /* One-time actions taken on probing the first device */
835 if (!emif1) { 1034 if (!emif1) {
836 emif1 = emif; 1035 emif1 = emif;
@@ -843,14 +1042,21 @@ static int __init_or_module emif_probe(struct platform_device *pdev)
843 */ 1042 */
844 } 1043 }
845 1044
846 dev_info(&pdev->dev, "%s: device configured with addr = %p\n", 1045 dev_info(&pdev->dev, "%s: device configured with addr = %p and IRQ%d\n",
847 __func__, emif->base); 1046 __func__, emif->base, irq);
848 1047
849 return 0; 1048 return 0;
850error: 1049error:
851 return -ENODEV; 1050 return -ENODEV;
852} 1051}
853 1052
1053static void emif_shutdown(struct platform_device *pdev)
1054{
1055 struct emif_data *emif = platform_get_drvdata(pdev);
1056
1057 disable_and_clear_all_interrupts(emif);
1058}
1059
854static int get_emif_reg_values(struct emif_data *emif, u32 freq, 1060static int get_emif_reg_values(struct emif_data *emif, u32 freq,
855 struct emif_regs *regs) 1061 struct emif_regs *regs)
856{ 1062{
@@ -1154,6 +1360,7 @@ static void __attribute__((unused)) freq_post_notify_handling(void)
1154} 1360}
1155 1361
1156static struct platform_driver emif_driver = { 1362static struct platform_driver emif_driver = {
1363 .shutdown = emif_shutdown,
1157 .driver = { 1364 .driver = {
1158 .name = "emif", 1365 .name = "emif",
1159 }, 1366 },