diff options
-rw-r--r-- | arch/arm/mach-tegra/latency_allowance.c | 169 |
1 files changed, 169 insertions, 0 deletions
diff --git a/arch/arm/mach-tegra/latency_allowance.c b/arch/arm/mach-tegra/latency_allowance.c index e3f0199d91e8..9b35a07eddc4 100644 --- a/arch/arm/mach-tegra/latency_allowance.c +++ b/arch/arm/mach-tegra/latency_allowance.c @@ -23,11 +23,13 @@ #include <linux/spinlock_types.h> #include <linux/spinlock.h> #include <linux/stringify.h> +#include <linux/clk.h> #include <asm/bug.h> #include <asm/io.h> #include <asm/string.h> #include <mach/iomap.h> #include <mach/io.h> +#include <mach/clk.h> #include <mach/latency_allowance.h> #include "la_priv_common.h" #include "tegra3_la_priv.h" @@ -44,6 +46,105 @@ /* Bug 995270 */ #define HACK_LA_FIFO 1 +/* Hack program PTSA */ +#if defined (CONFIG_ARCH_TEGRA_11x_SOC) +#define HACK_PROGRAM_PTSA 1 +#else +#define HACK_PROGRAM_PTSA 0 +#endif + +#if HACK_PROGRAM_PTSA +#define MC_DIS_PTSA_RATE_0 0x41c +#define MC_DIS_PTSA_MIN_0 0x420 +#define MC_DIS_PTSA_MAX_0 0x424 +#define MC_DISB_PTSA_RATE_0 0x428 +#define MC_DISB_PTSA_MIN_0 0x42c +#define MC_DISB_PTSA_MAX_0 0x430 +#define MC_VE_PTSA_RATE_0 0x434 +#define MC_VE_PTSA_MIN_0 0x438 +#define MC_VE_PTSA_MAX_0 0x43c +#define MC_RING2_PTSA_RATE_0 0x440 +#define MC_RING2_PTSA_MIN_0 0x444 +#define MC_RING2_PTSA_MAX_0 0x448 +#define MC_MLL_MPCORER_PTSA_RATE_0 0x44c +#define MC_MLL_MPCORER_PTSA_MIN_0 0x450 +#define MC_MLL_MPCORER_PTSA_MAX_0 0x454 +#define MC_SMMU_SMMU_PTSA_RATE_0 0x458 +#define MC_SMMU_SMMU_PTSA_MIN_0 0x45c +#define MC_SMMU_SMMU_PTSA_MAX_0 0x460 +#define MC_R0_DIS_PTSA_RATE_0 0x464 +#define MC_R0_DIS_PTSA_MIN_0 0x468 +#define MC_R0_DIS_PTSA_MAX_0 0x46c +#define MC_R0_DISB_PTSA_RATE_0 0x470 +#define MC_R0_DISB_PTSA_MIN_0 0x474 +#define MC_R0_DISB_PTSA_MAX_0 0x478 +#define MC_RING1_PTSA_RATE_0 0x47c +#define MC_RING1_PTSA_MIN_0 0x480 +#define MC_RING1_PTSA_MAX_0 0x484 + +#define MC_DIS_EXTRA_SNAP_LEVELS_0 0x2ac +#define MC_HEG_EXTRA_SNAP_LEVELS_0 0x2b0 +#define MC_EMEM_ARB_MISC0_0 0x0d8 +#define MC_PTSA_GRANT_DECREMENT_0 0x960 + +#define BASE_EMC_FREQ_MHZ 500 +#define MAX_CAMERA_BW_MHZ 528 + +static unsigned int get_ptsa_rate(unsigned int bw) +{ + /* 16 = 2 channels * 2 ddr * 4 bytes */ + unsigned int base_memory_bw = 16 * BASE_EMC_FREQ_MHZ; + unsigned int rate = 281 * bw / base_memory_bw; + if (rate > 255) + rate = 255; + return rate; +} + +static unsigned int disp_bw_array[10]; + +static void update_display_ptsa_rate(void) +{ + unsigned int num_active = (disp_bw_array[0] != 0) + + (disp_bw_array[1] != 0) + + (disp_bw_array[2] != 0); + unsigned int num_activeb = (disp_bw_array[5] != 0) + + (disp_bw_array[6] != 0) + + (disp_bw_array[7] != 0); + unsigned int max_bw = disp_bw_array[0]; + unsigned int max_bwb = disp_bw_array[5]; + unsigned int rate_dis; + unsigned int rate_disb; + unsigned long ring1_rate; + + max_bw = max(disp_bw_array[0], disp_bw_array[1]); + max_bw = max(max_bw, disp_bw_array[2]); + + max_bwb = max(disp_bw_array[5], disp_bw_array[6]); + max_bwb = max(max_bwb, disp_bw_array[7]); + + rate_dis = get_ptsa_rate(num_active * max_bw); + rate_disb = get_ptsa_rate(num_activeb * max_bwb); + + writel(rate_dis, MC_RA(DIS_PTSA_RATE_0)); + writel(rate_disb, MC_RA(DISB_PTSA_RATE_0)); + + + ring1_rate = readl(MC_RA(DIS_PTSA_RATE_0)) + + readl(MC_RA(DISB_PTSA_RATE_0)) + + readl(MC_RA(VE_PTSA_RATE_0)) + + readl(MC_RA(RING2_PTSA_RATE_0)); + la_debug("max_bw=0x%x, max_bwb=0x%x, num_active=0x%x, num_activeb=0x%x," + "0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x ", + max_bw, max_bwb, num_active, num_activeb, disp_bw_array[0],disp_bw_array[1], + disp_bw_array[2],disp_bw_array[5],disp_bw_array[6],disp_bw_array[7]); + la_debug("dis=0x%x, disb=0x%x, ve=0x%x, rng2=0x%x, rng1=0x%lx", + readl(MC_RA(DIS_PTSA_RATE_0)), readl(MC_RA(DISB_PTSA_RATE_0)), + readl(MC_RA(VE_PTSA_RATE_0)), readl(MC_RA(RING2_PTSA_RATE_0)), ring1_rate); + writel(ring1_rate / 2, MC_RA(RING1_PTSA_RATE_0)); +} + +#endif + static struct dentry *latency_debug_dir; static DEFINE_SPINLOCK(safety_lock); static unsigned short id_to_index[ID(MAX_ID) + 1]; @@ -109,6 +210,12 @@ int tegra_set_latency_allowance(enum tegra_la_id id, ci = &la_info_array[idx]; fifo_size_in_atoms = ci->fifo_size_in_atoms; +#if HACK_PROGRAM_PTSA + if (id >= TEGRA_LA_DISPLAY_0A && id <= TEGRA_LA_DISPLAY_HCB) { + disp_bw_array[id - TEGRA_LA_DISPLAY_0A] = bandwidth_in_mbps; + update_display_ptsa_rate(); + } +#endif #if HACK_LA_FIFO /* pretend that our FIFO is only as deep as the lowest fullness * we expect to see */ @@ -346,6 +453,11 @@ late_initcall(tegra_latency_allowance_debugfs_init); static int __init tegra_latency_allowance_init(void) { unsigned int i; + struct clk *emc_clk __attribute__((unused)); + unsigned long emc_freq __attribute__((unused)); + unsigned long same_freq __attribute__((unused)); + unsigned long grant_dec __attribute__((unused)); + unsigned long ring1_rate __attribute__((unused)); la_scaling_enable_count = 0; memset(&id_to_index[0], 0xFF, sizeof(id_to_index)); @@ -363,6 +475,63 @@ static int __init tegra_latency_allowance_init(void) tegra_set_latency_allowance(TEGRA_LA_G2DR, 20); tegra_set_latency_allowance(TEGRA_LA_G2DW, 20); #endif + +#if HACK_PROGRAM_PTSA + emc_clk = clk_get(NULL, "emc"); + la_debug("**** emc clk_rate=%luMHz", clk_get_rate(emc_clk)/1000000); + + emc_freq = clk_get_rate(emc_clk); + emc_freq /= 1000000; + /* Compute initial value for grant dec */ + same_freq = readl(MC_RA(EMEM_ARB_MISC0_0)); + same_freq = same_freq >> 27 & 1; + grant_dec = 256 * (same_freq ? 2 : 1) * emc_freq; + if (grant_dec > 511) + grant_dec = 511; + writel(grant_dec, MC_RA(PTSA_GRANT_DECREMENT_0)); + + writel(0x3d, MC_RA(DIS_PTSA_MIN_0)); + writel(0x14, MC_RA(DIS_PTSA_MAX_0)); + + writel(0x3d, MC_RA(DISB_PTSA_MIN_0)); + writel(0x14, MC_RA(DISB_PTSA_MAX_0)); + + writel(get_ptsa_rate(MAX_CAMERA_BW_MHZ), MC_RA(VE_PTSA_RATE_0)); + writel(0x3d, MC_RA(VE_PTSA_MIN_0)); + writel(0x14, MC_RA(VE_PTSA_MAX_0)); + + writel(0x01, MC_RA(RING2_PTSA_RATE_0)); + writel(0x3f, MC_RA(RING2_PTSA_MIN_0)); + writel(0x05, MC_RA(RING2_PTSA_MAX_0)); + + writel(38 * emc_freq / BASE_EMC_FREQ_MHZ, + MC_RA(MLL_MPCORER_PTSA_RATE_0)); + writel(0x3f, MC_RA(MLL_MPCORER_PTSA_MIN_0)); + writel(0x05, MC_RA(MLL_MPCORER_PTSA_MAX_0)); + + writel(0x01, MC_RA(SMMU_SMMU_PTSA_RATE_0)); + writel(0x01, MC_RA(SMMU_SMMU_PTSA_MIN_0)); + writel(0x01, MC_RA(SMMU_SMMU_PTSA_MAX_0)); + + writel(0x00, MC_RA(R0_DIS_PTSA_RATE_0)); + writel(0x3f, MC_RA(R0_DIS_PTSA_MIN_0)); + writel(0x3f, MC_RA(R0_DIS_PTSA_MAX_0)); + + writel(0x00, MC_RA(R0_DISB_PTSA_RATE_0)); + writel(0x3f, MC_RA(R0_DISB_PTSA_MIN_0)); + writel(0x3f, MC_RA(R0_DISB_PTSA_MAX_0)); + + ring1_rate = readl(MC_RA(DIS_PTSA_RATE_0)) + + readl(MC_RA(DISB_PTSA_RATE_0)) + + readl(MC_RA(VE_PTSA_RATE_0)) + + readl(MC_RA(RING2_PTSA_RATE_0)); + writel(ring1_rate / 2, MC_RA(RING1_PTSA_RATE_0)); + writel(0x36, MC_RA(RING1_PTSA_MIN_0)); + writel(0x1f, MC_RA(RING1_PTSA_MAX_0)); + + writel(0x00, MC_RA(DIS_EXTRA_SNAP_LEVELS_0)); + writel(0x03, MC_RA(HEG_EXTRA_SNAP_LEVELS_0)); +#endif return 0; } |