arm: tegra: la: Add config option for latency allowance scaling
Krishna Reddy [Fri, 7 Sep 2012 00:41:24 +0000 (17:41 -0700)]
Change-Id: I90d7fd87e774e04f8d671dfcec5f1833871c7ef9
Signed-off-by: Krishna Reddy <vdumpa@nvidia.com>
Reviewed-on: http://git-master/r/130403
Reviewed-by: Simone Willett <swillett@nvidia.com>
Tested-by: Simone Willett <swillett@nvidia.com>

Rebase-Id: Re780070ae179523c97dd833555dc9f1bceead353

arch/arm/mach-tegra/Kconfig
arch/arm/mach-tegra/include/mach/latency_allowance.h
arch/arm/mach-tegra/latency_allowance.c

index cab4fe7..a96d105 100644 (file)
@@ -78,6 +78,7 @@ config ARCH_TEGRA_3x_SOC
        select PL310_ERRATA_769419 if CACHE_L2X0
        select REPORT_PRESENT_CPUS if TEGRA_AUTO_HOTPLUG
        select TEGRA_LATENCY_ALLOWANCE if !TEGRA_FPGA_PLATFORM
+       select TEGRA_LATENCY_ALLOWANCE_SCALING if !TEGRA_FPGA_PLATFORM
        select TEGRA_LP2_CPU_TIMER if HAVE_ARM_TWD && !TEGRA_RAIL_OFF_MULTIPLE_CPUS
        select USB_ARCH_HAS_EHCI if USB_SUPPORT
        select USB_ULPI if USB_PHY
@@ -420,6 +421,7 @@ config TEGRA_LP1_950
        depends on ARCH_TEGRA_3x_SOC
        help
                Enable support for LP1 Core voltage to set to lowest
+
 config TEGRA_LATENCY_ALLOWANCE
        bool "Allow memory clients to configure latency allowance"
        help
@@ -429,4 +431,13 @@ config TEGRA_LATENCY_ALLOWANCE
          memory client can wait before it is served.
          Enabling this option allows memory clients configure the
          latency allowance as per their bandwidth requirement.
+
+config TEGRA_LATENCY_ALLOWANCE_SCALING
+       bool "Enable latency allowance scaling"
+       depends on TEGRA_LATENCY_ALLOWANCE
+       help
+         Enables latency allowance scaling, which enables scaling
+         programmed latency allowance values based on fifo threshold levels
+         set for for display and vi hardware.
+
 endif
index aaab168..25df115 100644 (file)
@@ -95,6 +95,19 @@ static inline int tegra_set_latency_allowance(enum tegra_la_id id,
        return 0;
 }
 
+static inline void tegra_latency_allowance_update_tick_length(
+                                               unsigned int new_ns_per_tick)
+{
+       return;
+}
+#else
+int tegra_set_latency_allowance(enum tegra_la_id id,
+                               unsigned int bandwidth_in_mbps);
+
+void tegra_latency_allowance_update_tick_length(unsigned int new_ns_per_tick);
+#endif
+
+#if !defined(CONFIG_TEGRA_LATENCY_ALLOWANCE_SCALING)
 static inline int tegra_enable_latency_scaling(enum tegra_la_id id,
                                                unsigned int threshold_low,
                                                unsigned int threshold_mid,
@@ -106,23 +119,13 @@ static inline int tegra_enable_latency_scaling(enum tegra_la_id id,
 static inline void tegra_disable_latency_scaling(enum tegra_la_id id)
 {
 }
-
-static inline void tegra_latency_allowance_update_tick_length(
-                                               unsigned int new_ns_per_tick)
-{
-       return;
-}
 #else
-int tegra_set_latency_allowance(enum tegra_la_id id,
-                               unsigned int bandwidth_in_mbps);
-
 int tegra_enable_latency_scaling(enum tegra_la_id id,
                                    unsigned int threshold_low,
                                    unsigned int threshold_mid,
                                    unsigned int threshold_high);
 
 void tegra_disable_latency_scaling(enum tegra_la_id id);
-void tegra_latency_allowance_update_tick_length(unsigned int new_ns_per_tick);
 #endif
 
 #endif /* _MACH_TEGRA_LATENCY_ALLOWANCE_H_ */
index 3d5d444..50051e4 100644 (file)
 /* Bug 995270 */
 #define HACK_LA_FIFO 1
 
-#if !defined(CONFIG_ARCH_TEGRA_2x_SOC)
-static DEFINE_SPINLOCK(safety_lock);
 static struct dentry *latency_debug_dir;
-static int la_scaling_enable_count;
+static DEFINE_SPINLOCK(safety_lock);
 static unsigned short id_to_index[ID(MAX_ID) + 1];
 static struct la_scaling_info scaling_info[TEGRA_LA_MAX_ID];
+static int la_scaling_enable_count;
 
 #define VALIDATE_ID(id) \
        do { \
@@ -75,6 +74,62 @@ static struct la_scaling_info scaling_info[TEGRA_LA_MAX_ID];
                        return -EINVAL; \
        } while (0)
 
+/* Sets latency allowance based on clients memory bandwitdh requirement.
+ * Bandwidth passed is in mega bytes per second.
+ */
+int tegra_set_latency_allowance(enum tegra_la_id id,
+                               unsigned int bandwidth_in_mbps)
+{
+       int ideal_la;
+       int la_to_set;
+       unsigned long reg_read;
+       unsigned long reg_write;
+       unsigned int fifo_size_in_atoms;
+       int bytes_per_atom = normal_atom_size;
+       const int fifo_scale = 4;               /* 25% of the FIFO */
+       struct la_client_info *ci;
+       int idx = id_to_index[id];
+
+       VALIDATE_ID(id);
+       VALIDATE_BW(bandwidth_in_mbps);
+
+       ci = &la_info_array[idx];
+       fifo_size_in_atoms = ci->fifo_size_in_atoms;
+
+#if HACK_LA_FIFO
+       /* pretend that our FIFO is only as deep as the lowest fullness
+        * we expect to see */
+       if (id >= ID(DISPLAY_0A) && id <= ID(DISPLAY_HCB))
+               fifo_size_in_atoms /= fifo_scale;
+#endif
+
+       if (bandwidth_in_mbps == 0) {
+               la_to_set = MC_LA_MAX_VALUE;
+       } else {
+               ideal_la = (fifo_size_in_atoms * bytes_per_atom * 1000) /
+                          (bandwidth_in_mbps * ns_per_tick);
+               la_to_set = ideal_la - (ci->expiration_in_ns/ns_per_tick) - 1;
+       }
+
+       la_debug("\n%s:id=%d,idx=%d, bw=%dmbps, la_to_set=%d",
+               __func__, id, idx, bandwidth_in_mbps, la_to_set);
+       la_to_set = (la_to_set < 0) ? 0 : la_to_set;
+       la_to_set = (la_to_set > MC_LA_MAX_VALUE) ? MC_LA_MAX_VALUE : la_to_set;
+       scaling_info[idx].actual_la_to_set = la_to_set;
+
+       spin_lock(&safety_lock);
+       reg_read = readl(ci->reg_addr);
+       reg_write = (reg_read & ~ci->mask) |
+                       (la_to_set << ci->shift);
+       writel(reg_write, ci->reg_addr);
+       scaling_info[idx].la_set = la_to_set;
+       la_debug("reg_addr=0x%x, read=0x%x, write=0x%x",
+               (u32)ci->reg_addr, (u32)reg_read, (u32)reg_write);
+       spin_unlock(&safety_lock);
+       return 0;
+}
+
+#if defined(CONFIG_TEGRA_LATENCY_ALLOWANCE_SCALING)
 static void set_thresholds(struct la_scaling_reg_info *info,
                            enum tegra_la_id id)
 {
@@ -133,61 +188,6 @@ static void set_vi_latency_thresholds(enum tegra_la_id id)
        set_thresholds(&vi_info[id - ID(VI_WSB)], id);
 }
 
-/* Sets latency allowance based on clients memory bandwitdh requirement.
- * Bandwidth passed is in mega bytes per second.
- */
-int tegra_set_latency_allowance(enum tegra_la_id id,
-                               unsigned int bandwidth_in_mbps)
-{
-       int ideal_la;
-       int la_to_set;
-       unsigned long reg_read;
-       unsigned long reg_write;
-       unsigned int fifo_size_in_atoms;
-       int bytes_per_atom = normal_atom_size;
-       const int fifo_scale = 4;               /* 25% of the FIFO */
-       struct la_client_info *ci;
-       int idx = id_to_index[id];
-
-       VALIDATE_ID(id);
-       VALIDATE_BW(bandwidth_in_mbps);
-
-       ci = &la_info_array[idx];
-       fifo_size_in_atoms = ci->fifo_size_in_atoms;
-
-#if HACK_LA_FIFO
-       /* pretend that our FIFO is only as deep as the lowest fullness
-        * we expect to see */
-       if (id >= ID(DISPLAY_0A) && id <= ID(DISPLAY_HCB))
-               fifo_size_in_atoms /= fifo_scale;
-#endif
-
-       if (bandwidth_in_mbps == 0) {
-               la_to_set = MC_LA_MAX_VALUE;
-       } else {
-               ideal_la = (fifo_size_in_atoms * bytes_per_atom * 1000) /
-                          (bandwidth_in_mbps * ns_per_tick);
-               la_to_set = ideal_la - (ci->expiration_in_ns/ns_per_tick) - 1;
-       }
-
-       la_debug("\n%s:id=%d,idx=%d, bw=%dmbps, la_to_set=%d",
-               __func__, id, idx, bandwidth_in_mbps, la_to_set);
-       la_to_set = (la_to_set < 0) ? 0 : la_to_set;
-       la_to_set = (la_to_set > MC_LA_MAX_VALUE) ? MC_LA_MAX_VALUE : la_to_set;
-       scaling_info[idx].actual_la_to_set = la_to_set;
-
-       spin_lock(&safety_lock);
-       reg_read = readl(ci->reg_addr);
-       reg_write = (reg_read & ~ci->mask) |
-                       (la_to_set << ci->shift);
-       writel(reg_write, ci->reg_addr);
-       scaling_info[idx].la_set = la_to_set;
-       la_debug("reg_addr=0x%x, read=0x%x, write=0x%x",
-               (u32)ci->reg_addr, (u32)reg_read, (u32)reg_write);
-       spin_unlock(&safety_lock);
-       return 0;
-}
-
 /* Thresholds for scaling are specified in % of fifo freeness.
  * If threshold_low is specified as 20%, it means when the fifo free
  * between 0 to 20%, use la as programmed_la.
@@ -261,6 +261,7 @@ void tegra_disable_latency_scaling(enum tegra_la_id id)
        }
        spin_unlock(&safety_lock);
 }
+#endif
 
 void tegra_latency_allowance_update_tick_length(unsigned int new_ns_per_tick)
 {
@@ -404,4 +405,3 @@ static int __init test_la(void)
 
 late_initcall(test_la);
 #endif
-#endif