arm: tegra: Enable MC early ACK and scoreboard
Scott Williams [Fri, 18 Mar 2011 20:38:02 +0000 (13:38 -0700)]
Bug 791803

Original-Change-Id: I25be461cccd6e14618d8b43fd0738e9abfbe4432
Reviewed-on: http://git-master/r/23584
Reviewed-by: Scott Williams <scwilliams@nvidia.com>
Tested-by: Scott Williams <scwilliams@nvidia.com>
Original-Change-Id: I6bb5dcfbf48323919529c6271ea7696ecc413bb2

Rebase-Id: R3308cf0a852ee2bf0e2adb3de17cebc81e48c71c

arch/arm/mach-tegra/common-t3.c
arch/arm/mach-tegra/pm-t3.c
arch/arm/mach-tegra/pm.c
arch/arm/mach-tegra/pm.h
arch/arm/mach-tegra/tegra3_emc.h

index b2b9a0b..d539300 100644 (file)
@@ -28,6 +28,8 @@
 #include <mach/iomap.h>
 #include <mach/irqs.h>
 
+#include "tegra3_emc.h"
+
 #define MC_INT_STATUS                  0x0
 #define MC_INT_MASK                    0x4
 #define MC_INT_DECERR_EMEM             (1<<6)
@@ -185,12 +187,21 @@ out:
 
 void __init tegra_mc_init(void)
 {
+       void __iomem *mc = IO_ADDRESS(TEGRA_MC_BASE);
+       u32 reg;
+
+       reg = 0x0A7F1010;
+       writel(reg, mc + MC_RESERVED_RSV);
+
+       reg = readl(mc + MC_EMEM_ARB_OVERRIDE);
+       reg |= 3;
+       writel(reg, mc + MC_EMEM_ARB_OVERRIDE);
+
        if (request_irq(INT_MC_GENERAL, tegra_mc_error_isr, 0,
                        "mc_status", NULL)) {
                pr_err("%s: unable to register MC error interrupt\n", __func__);
        } else {
-               void __iomem *mc = IO_ADDRESS(TEGRA_MC_BASE);
-               u32 reg = MC_INT_DECERR_EMEM | MC_INT_SECURITY_VIOLATION |
+               reg = MC_INT_DECERR_EMEM | MC_INT_SECURITY_VIOLATION |
                                MC_INT_INVALID_SMMU_PAGE;
                writel(reg, mc + MC_INT_MASK);
        }
index c005e67..1c57a01 100644 (file)
@@ -27,6 +27,7 @@
 #include "clock.h"
 #include "gpio-names.h"
 #include "pm.h"
+#include "tegra3_emc.h"
 
 #define CAR_CCLK_BURST_POLICY \
        (IO_ADDRESS(TEGRA_CLK_RESET_BASE) + 0x20)
@@ -335,3 +336,20 @@ int tegra_cluster_control(unsigned int us, unsigned int flags)
 
        return 0;
 }
+
+static u32 mc_reserved_rsv;
+static u32 mc_emem_arb_override;
+
+void tegra_lp0_suspend_mc(void)
+{
+       void __iomem *mc = IO_ADDRESS(TEGRA_MC_BASE);
+       mc_reserved_rsv = readl(mc + MC_RESERVED_RSV);
+       mc_emem_arb_override = readl(mc + MC_EMEM_ARB_OVERRIDE);
+}
+
+void tegra_lp0_resume_mc(void)
+{
+       void __iomem *mc = IO_ADDRESS(TEGRA_MC_BASE);
+       writel(mc_reserved_rsv, mc + MC_RESERVED_RSV);
+       writel(mc_emem_arb_override, mc + MC_EMEM_ARB_OVERRIDE);
+}
index f548f9b..8fb1d86 100644 (file)
@@ -694,6 +694,9 @@ static int tegra_suspend_enter(suspend_state_t state)
        cpu_pm_enter();
        cpu_complex_pm_enter();
 
+       if (mode == TEGRA_SUSPEND_LP0)
+               tegra_lp0_suspend_mc();
+
        suspend_cpu_complex();
        flush_cache_all();
        outer_flush_all();
@@ -705,6 +708,10 @@ static int tegra_suspend_enter(suspend_state_t state)
                tegra_sleep_core(PLAT_PHYS_OFFSET - PAGE_OFFSET);
 
        tegra_init_cache();
+
+       if (mode == TEGRA_SUSPEND_LP0)
+               tegra_lp0_resume_mc();
+
        restore_cpu_complex();
 
        cpu_complex_pm_exit();
index e39fda0..b03a0f4 100644 (file)
@@ -76,7 +76,7 @@ void __init tegra_init_suspend(struct tegra_suspend_platform_data *plat);
 
 void tegra_idle_lp2(void);
 
-#if defined(CONFIG_TEGRA_AUTO_HOTPLUG) && defined(CONFIG_ARCH_TEGRA_3x_SOC)
+#if defined(CONFIG_TEGRA_AUTO_HOTPLUG) && !defined(CONFIG_ARCH_TEGRA_2x_SOC)
 int tegra_auto_hotplug_init(void);
 void tegra_auto_hotplug_exit(void);
 void tegra_auto_hotplug_governor(unsigned int cpu_freq);
@@ -110,6 +110,8 @@ static inline unsigned int is_lp_cluster(void)
 { return 0; }
 static inline unsigned long tegra_get_lpcpu_max_rate(void)
 { return 0; }
+#define tegra_lp0_suspend_mc() do {} while(0)
+#define tegra_lp0_resume_mc() do {} while(0)
 #else
 #define INSTRUMENT_CLUSTER_SWITCH 1    /* Should be zero for shipping code */
 #define DEBUG_CLUSTER_SWITCH 1         /* Should be zero for shipping code */
@@ -130,6 +132,8 @@ static inline unsigned int is_lp_cluster(void)
        return (reg & 1); /* 0 == G, 1 == LP*/
 }
 unsigned long tegra_get_lpcpu_max_rate(void);
+void tegra_lp0_suspend_mc(void);
+void tegra_lp0_resume_mc(void);
 #endif
 
 #if DEBUG_CLUSTER_SWITCH
index f92d254..c55214e 100644 (file)
@@ -225,5 +225,7 @@ enum {
 #define MC_EMEM_ARB_MISC0                      0xd8
 #define MC_EMEM_ARB_MISC0_EMC_SAME_FREQ                (0x1 << 27)
 #define MC_EMEM_ARB_RING1_THROTTLE             0xe0
+#define MC_EMEM_ARB_OVERRIDE                   0xe8
+#define MC_RESERVED_RSV                                0x3fc
 
 #endif