summaryrefslogtreecommitdiff
path: root/arch/arm
diff options
context:
space:
mode:
authorKrishna Reddy <vdumpa@nvidia.com>2012-08-13 12:37:32 -0700
committerSimone Willett <swillett@nvidia.com>2012-08-15 17:12:57 -0700
commit361f7676aaecfd0157b89f0e106f59fcc229a839 (patch)
treef66e0c369bacdea5bc789dc9a77da9b42485cb2e /arch/arm
parent028042d5cc554c41a7b5f00fc2b20dce997fcc43 (diff)
arm: tegra: la: refactor la code.
This is necessary to support future tegra SOC's. Change-Id: I2f6ce328e30a6895dce16d82c4097291339155cd Signed-off-by: Krishna Reddy <vdumpa@nvidia.com> Reviewed-on: http://git-master/r/123146 Reviewed-by: Automatic_Commit_Validation_User Reviewed-by: Jon Mayo <jmayo@nvidia.com> Reviewed-by: Mark Stadler <mastadler@nvidia.com> GVS: Gerrit_Virtual_Submit
Diffstat (limited to 'arch/arm')
-rw-r--r--arch/arm/mach-tegra/include/mach/latency_allowance.h31
-rw-r--r--arch/arm/mach-tegra/la_priv_common.h71
-rw-r--r--arch/arm/mach-tegra/latency_allowance.c346
-rw-r--r--arch/arm/mach-tegra/tegra3_la_priv.h226
4 files changed, 368 insertions, 306 deletions
diff --git a/arch/arm/mach-tegra/include/mach/latency_allowance.h b/arch/arm/mach-tegra/include/mach/latency_allowance.h
index 8644075a88b3..5ebc6f03b810 100644
--- a/arch/arm/mach-tegra/include/mach/latency_allowance.h
+++ b/arch/arm/mach-tegra/include/mach/latency_allowance.h
@@ -18,19 +18,19 @@
#define _MACH_TEGRA_LATENCY_ALLOWANCE_H_
enum tegra_la_id {
- TEGRA_LA_AFIR = 0,
- TEGRA_LA_AFIW,
+ TEGRA_LA_AFIR = 0, /* T30 specific */
+ TEGRA_LA_AFIW, /* T30 specific */
TEGRA_LA_AVPC_ARM7R,
TEGRA_LA_AVPC_ARM7W,
TEGRA_LA_DISPLAY_0A,
TEGRA_LA_DISPLAY_0B,
TEGRA_LA_DISPLAY_0C,
- TEGRA_LA_DISPLAY_1B,
+ TEGRA_LA_DISPLAY_1B, /* T30 specific */
TEGRA_LA_DISPLAY_HC,
TEGRA_LA_DISPLAY_0AB,
TEGRA_LA_DISPLAY_0BB,
TEGRA_LA_DISPLAY_0CB,
- TEGRA_LA_DISPLAY_1BB,
+ TEGRA_LA_DISPLAY_1BB, /* T30 specific */
TEGRA_LA_DISPLAY_HCB,
TEGRA_LA_EPPUP,
TEGRA_LA_EPPU,
@@ -50,27 +50,27 @@ enum tegra_la_id {
TEGRA_LA_MPCOREW,
TEGRA_LA_MPCORE_LPR,
TEGRA_LA_MPCORE_LPW,
- TEGRA_LA_MPE_UNIFBR,
- TEGRA_LA_MPE_IPRED,
- TEGRA_LA_MPE_AMEMRD,
- TEGRA_LA_MPE_CSRD,
- TEGRA_LA_MPE_UNIFBW,
- TEGRA_LA_MPE_CSWR,
+ TEGRA_LA_MPE_UNIFBR, /* T30 specific */
+ TEGRA_LA_MPE_IPRED, /* T30 specific */
+ TEGRA_LA_MPE_AMEMRD, /* T30 specific */
+ TEGRA_LA_MPE_CSRD, /* T30 specific */
+ TEGRA_LA_MPE_UNIFBW, /* T30 specific */
+ TEGRA_LA_MPE_CSWR, /* T30 specific */
TEGRA_LA_FDCDRD,
TEGRA_LA_IDXSRD,
TEGRA_LA_TEXSRD,
TEGRA_LA_FDCDWR,
TEGRA_LA_FDCDRD2,
- TEGRA_LA_IDXSRD2,
- TEGRA_LA_TEXSRD2,
+ TEGRA_LA_IDXSRD2, /* T30 specific */
+ TEGRA_LA_TEXSRD2, /* T30 specific */
TEGRA_LA_FDCDWR2,
TEGRA_LA_PPCS_AHBDMAR,
TEGRA_LA_PPCS_AHBSLVR,
TEGRA_LA_PPCS_AHBDMAW,
TEGRA_LA_PPCS_AHBSLVW,
TEGRA_LA_PTCR,
- TEGRA_LA_SATAR,
- TEGRA_LA_SATAW,
+ TEGRA_LA_SATAR, /* T30 specific */
+ TEGRA_LA_SATAW, /* T30 specific */
TEGRA_LA_VDE_BSEVR,
TEGRA_LA_VDE_MBER,
TEGRA_LA_VDE_MCER,
@@ -79,11 +79,12 @@ enum tegra_la_id {
TEGRA_LA_VDE_DBGW,
TEGRA_LA_VDE_MBEW,
TEGRA_LA_VDE_TPMW,
- TEGRA_LA_VI_RUV,
+ TEGRA_LA_VI_RUV, /* T30 specific */
TEGRA_LA_VI_WSB,
TEGRA_LA_VI_WU,
TEGRA_LA_VI_WV,
TEGRA_LA_VI_WY,
+
TEGRA_LA_MAX_ID
};
diff --git a/arch/arm/mach-tegra/la_priv_common.h b/arch/arm/mach-tegra/la_priv_common.h
new file mode 100644
index 000000000000..5b487e5970c5
--- /dev/null
+++ b/arch/arm/mach-tegra/la_priv_common.h
@@ -0,0 +1,71 @@
+/*
+ * arch/arm/mach-tegra/la_priv_common.h
+ *
+ * Copyright (C) 2012 NVIDIA Corporation.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#ifndef _MACH_TEGRA_LA_PRIV_H_
+#define _MACH_TEGRA_LA_PRIV_H_
+
+/* maximum valid value for latency allowance */
+#define MC_LA_MAX_VALUE 255
+
+#define MC_RA(r) \
+ ((u32)IO_ADDRESS(TEGRA_MC_BASE) + (MC_##r))
+#define RA(r) \
+ ((u32)IO_ADDRESS(TEGRA_MC_BASE) + (MC_LA_##r))
+
+#define MASK(x) \
+ ((0xFFFFFFFFUL >> (31 - (1 ? x) + (0 ? x))) << (0 ? x))
+#define SHIFT(x) \
+ (0 ? x)
+#define ID(id) \
+ TEGRA_LA_##id
+
+#define LA_INFO(f, e, a, r, id, ss) \
+{f, e, RA(a), MASK(r), SHIFT(r), ID(id), __stringify(id), ss}
+
+struct la_client_info {
+ unsigned int fifo_size_in_atoms;
+ unsigned int expiration_in_ns; /* worst case expiration value */
+ unsigned long reg_addr;
+ unsigned long mask;
+ unsigned long shift;
+ enum tegra_la_id id;
+ char *name;
+ bool scaling_supported;
+};
+
+struct la_scaling_info {
+ unsigned int threshold_low;
+ unsigned int threshold_mid;
+ unsigned int threshold_high;
+ int scaling_ref_count;
+ int actual_la_to_set;
+ int la_set;
+};
+
+struct la_scaling_reg_info {
+ enum tegra_la_id id;
+ unsigned int tl_reg_addr;
+ unsigned int tl_mask;
+ unsigned int tl_shift;
+ unsigned int tm_reg_addr;
+ unsigned int tm_mask;
+ unsigned int tm_shift;
+ unsigned int th_reg_addr;
+ unsigned int th_mask;
+ unsigned int th_shift;
+};
+
+#endif /* _MACH_TEGRA_LA_PRIV_H_ */
diff --git a/arch/arm/mach-tegra/latency_allowance.c b/arch/arm/mach-tegra/latency_allowance.c
index f8e5ce579200..d481882ce713 100644
--- a/arch/arm/mach-tegra/latency_allowance.c
+++ b/arch/arm/mach-tegra/latency_allowance.c
@@ -29,68 +29,8 @@
#include <mach/iomap.h>
#include <mach/io.h>
#include <mach/latency_allowance.h>
-
-#define MC_ARB_OVERRIDE 0xe8
-#define GLOBAL_LATENCY_SCALING_ENABLE_BIT 7
-
-#define MC_LA_AFI_0 0x2e0
-#define MC_LA_AVPC_ARM7_0 0x2e4
-#define MC_LA_DC_0 0x2e8
-#define MC_LA_DC_1 0x2ec
-#define MC_LA_DC_2 0x2f0
-#define MC_LA_DCB_0 0x2f4
-#define MC_LA_DCB_1 0x2f8
-#define MC_LA_DCB_2 0x2fc
-#define MC_LA_EPP_0 0x300
-#define MC_LA_EPP_1 0x304
-#define MC_LA_G2_0 0x308
-#define MC_LA_G2_1 0x30c
-#define MC_LA_HC_0 0x310
-#define MC_LA_HC_1 0x314
-#define MC_LA_HDA_0 0x318
-#define MC_LA_ISP_0 0x31C
-#define MC_LA_MPCORE_0 0x320
-#define MC_LA_MPCORELP_0 0x324
-#define MC_LA_MPE_0 0x328
-#define MC_LA_MPE_1 0x32c
-#define MC_LA_MPE_2 0x330
-#define MC_LA_NV_0 0x334
-#define MC_LA_NV_1 0x338
-#define MC_LA_NV2_0 0x33c
-#define MC_LA_NV2_1 0x340
-#define MC_LA_PPCS_0 0x344
-#define MC_LA_PPCS_1 0x348
-#define MC_LA_PTC_0 0x34c
-#define MC_LA_SATA_0 0x350
-#define MC_LA_VDE_0 0x354
-#define MC_LA_VDE_1 0x358
-#define MC_LA_VDE_2 0x35c
-#define MC_LA_VDE_3 0x360
-#define MC_LA_VI_0 0x364
-#define MC_LA_VI_1 0x368
-#define MC_LA_VI_2 0x36c
-
-#define DS_DISP_MCCIF_DISPLAY0A_HYST (0x481 * 4)
-#define DS_DISP_MCCIF_DISPLAY0B_HYST (0x482 * 4)
-#define DS_DISP_MCCIF_DISPLAY0C_HYST (0x483 * 4)
-#define DS_DISP_MCCIF_DISPLAY1B_HYST (0x484 * 4)
-
-#define DS_DISP_MCCIF_DISPLAY0AB_HYST (0x481 * 4)
-#define DS_DISP_MCCIF_DISPLAY0BB_HYST (0x482 * 4)
-#define DS_DISP_MCCIF_DISPLAY0CB_HYST (0x483 * 4)
-#define DS_DISP_MCCIF_DISPLAY1BB_HYST (0x484 * 4)
-
-#define VI_MCCIF_VIWSB_HYST (0x9a * 4)
-#define VI_MCCIF_VIWU_HYST (0x9b * 4)
-#define VI_MCCIF_VIWV_HYST (0x9c * 4)
-#define VI_MCCIF_VIWY_HYST (0x9d * 4)
-
-#define VI_TIMEOUT_WOCAL_VI (0x70 * 4)
-#define VI_RESERVE_3 (0x97 * 4)
-#define VI_RESERVE_4 (0x98 * 4)
-
-/* maximum valid value for latency allowance */
-#define MC_LA_MAX_VALUE 255
+#include "la_priv_common.h"
+#include "tegra3_la_priv.h"
#define ENABLE_LA_DEBUG 0
#define TEST_LA_CODE 0
@@ -104,209 +44,18 @@
#define HACK_LA_FIFO 1
static struct dentry *latency_debug_dir;
-
-struct la_client_info {
- unsigned int fifo_size_in_atoms;
- unsigned int expiration_in_ns; /* worst case expiration value */
- unsigned long reg_addr;
- unsigned long mask;
- unsigned long shift;
- enum tegra_la_id id;
- char *name;
- bool scaling_supported;
-};
-
static DEFINE_SPINLOCK(safety_lock);
-
-static const int ns_per_tick = 30;
-/* fifo atom size in bytes for non-fdc clients*/
-static const int normal_atom_size = 16;
-/* fifo atom size in bytes for fdc clients*/
-static const int fdc_atom_size = 32;
-
-#define MC_RA(r) \
- ((u32)IO_ADDRESS(TEGRA_MC_BASE) + (MC_##r))
-#define RA(r) \
- ((u32)IO_ADDRESS(TEGRA_MC_BASE) + (MC_LA_##r))
-
-#define MASK(x) \
- ((0xFFFFFFFFUL >> (31 - (1 ? x) + (0 ? x))) << (0 ? x))
-#define SHIFT(x) \
- (0 ? x)
-#define ID(id) \
- TEGRA_LA_##id
-
-#define LA_INFO(f, e, a, r, id, ss) \
-{f, e, RA(a), MASK(r), SHIFT(r), ID(id), __stringify(id), ss}
-
-/*
- * The rule for getting the fifo_size_in_atoms is:
- * 1.If REORDER_DEPTH exists, use it(default is overridden).
- * 2.Else if (write_client) use RFIFO_DEPTH.
- * 3.Else (read client) use RDFIFO_DEPTH.
- * Refer to project.h file.
- */
-struct la_client_info la_info[] = {
- LA_INFO(32, 150, AFI_0, 7 : 0, AFIR, false),
- LA_INFO(32, 150, AFI_0, 23 : 16, AFIW, false),
- LA_INFO(2, 150, AVPC_ARM7_0, 7 : 0, AVPC_ARM7R, false),
- LA_INFO(2, 150, AVPC_ARM7_0, 23 : 16, AVPC_ARM7W, false),
- LA_INFO(128, 1050, DC_0, 7 : 0, DISPLAY_0A, true),
- LA_INFO(64, 1050, DC_0, 23 : 16, DISPLAY_0B, true),
- LA_INFO(128, 1050, DC_1, 7 : 0, DISPLAY_0C, true),
- LA_INFO(64, 1050, DC_1, 23 : 16, DISPLAY_1B, true),
- LA_INFO(2, 1050, DC_2, 7 : 0, DISPLAY_HC, false),
- LA_INFO(128, 1050, DCB_0, 7 : 0, DISPLAY_0AB, true),
- LA_INFO(64, 1050, DCB_0, 23 : 16, DISPLAY_0BB, true),
- LA_INFO(128, 1050, DCB_1, 7 : 0, DISPLAY_0CB, true),
- LA_INFO(64, 1050, DCB_1, 23 : 16, DISPLAY_1BB, true),
- LA_INFO(2, 1050, DCB_2, 7 : 0, DISPLAY_HCB, false),
- LA_INFO(8, 150, EPP_0, 7 : 0, EPPUP, false),
- LA_INFO(64, 150, EPP_0, 23 : 16, EPPU, false),
- LA_INFO(64, 150, EPP_1, 7 : 0, EPPV, false),
- LA_INFO(64, 150, EPP_1, 23 : 16, EPPY, false),
- LA_INFO(64, 150, G2_0, 7 : 0, G2PR, false),
- LA_INFO(64, 150, G2_0, 23 : 16, G2SR, false),
- LA_INFO(48, 150, G2_1, 7 : 0, G2DR, false),
- LA_INFO(128, 150, G2_1, 23 : 16, G2DW, false),
- LA_INFO(16, 150, HC_0, 7 : 0, HOST1X_DMAR, false),
- LA_INFO(8, 150, HC_0, 23 : 16, HOST1XR, false),
- LA_INFO(32, 150, HC_1, 7 : 0, HOST1XW, false),
- LA_INFO(16, 150, HDA_0, 7 : 0, HDAR, false),
- LA_INFO(16, 150, HDA_0, 23 : 16, HDAW, false),
- LA_INFO(64, 150, ISP_0, 7 : 0, ISPW, false),
- LA_INFO(14, 150, MPCORE_0, 7 : 0, MPCORER, false),
- LA_INFO(24, 150, MPCORE_0, 23 : 16, MPCOREW, false),
- LA_INFO(14, 150, MPCORELP_0, 7 : 0, MPCORE_LPR, false),
- LA_INFO(24, 150, MPCORELP_0, 23 : 16, MPCORE_LPW, false),
- LA_INFO(8, 150, MPE_0, 7 : 0, MPE_UNIFBR, false),
- LA_INFO(2, 150, MPE_0, 23 : 16, MPE_IPRED, false),
- LA_INFO(64, 150, MPE_1, 7 : 0, MPE_AMEMRD, false),
- LA_INFO(8, 150, MPE_1, 23 : 16, MPE_CSRD, false),
- LA_INFO(8, 150, MPE_2, 7 : 0, MPE_UNIFBW, false),
- LA_INFO(8, 150, MPE_2, 23 : 16, MPE_CSWR, false),
- LA_INFO(48, 150, NV_0, 7 : 0, FDCDRD, false),
- LA_INFO(64, 150, NV_0, 23 : 16, IDXSRD, false),
- LA_INFO(64, 150, NV_1, 7 : 0, TEXSRD, false),
- LA_INFO(48, 150, NV_1, 23 : 16, FDCDWR, false),
- LA_INFO(48, 150, NV2_0, 7 : 0, FDCDRD2, false),
- LA_INFO(64, 150, NV2_0, 23 : 16, IDXSRD2, false),
- LA_INFO(64, 150, NV2_1, 7 : 0, TEXSRD2, false),
- LA_INFO(48, 150, NV2_1, 23 : 16, FDCDWR2, false),
- LA_INFO(2, 150, PPCS_0, 7 : 0, PPCS_AHBDMAR, false),
- LA_INFO(8, 150, PPCS_0, 23 : 16, PPCS_AHBSLVR, false),
- LA_INFO(2, 150, PPCS_1, 7 : 0, PPCS_AHBDMAW, false),
- LA_INFO(4, 150, PPCS_1, 23 : 16, PPCS_AHBSLVW, false),
- LA_INFO(2, 150, PTC_0, 7 : 0, PTCR, false),
- LA_INFO(32, 150, SATA_0, 7 : 0, SATAR, false),
- LA_INFO(32, 150, SATA_0, 23 : 16, SATAW, false),
- LA_INFO(8, 150, VDE_0, 7 : 0, VDE_BSEVR, false),
- LA_INFO(4, 150, VDE_0, 23 : 16, VDE_MBER, false),
- LA_INFO(16, 150, VDE_1, 7 : 0, VDE_MCER, false),
- LA_INFO(16, 150, VDE_1, 23 : 16, VDE_TPER, false),
- LA_INFO(4, 150, VDE_2, 7 : 0, VDE_BSEVW, false),
- LA_INFO(16, 150, VDE_2, 23 : 16, VDE_DBGW, false),
- LA_INFO(2, 150, VDE_3, 7 : 0, VDE_MBEW, false),
- LA_INFO(16, 150, VDE_3, 23 : 16, VDE_TPMW, false),
- LA_INFO(8, 1050, VI_0, 7 : 0, VI_RUV, false),
- LA_INFO(64, 1050, VI_0, 23 : 16, VI_WSB, true),
- LA_INFO(64, 1050, VI_1, 7 : 0, VI_WU, true),
- LA_INFO(64, 1050, VI_1, 23 : 16, VI_WV, true),
- LA_INFO(64, 1050, VI_2, 7 : 0, VI_WY, true),
-
-/* end of list. */
- LA_INFO(0, 0, AFI_0, 0 : 0, MAX_ID, false)
-};
-
-struct la_scaling_info {
- unsigned int threshold_low;
- unsigned int threshold_mid;
- unsigned int threshold_high;
- int scaling_ref_count;
- int actual_la_to_set;
- int la_set;
-};
-
-struct la_scaling_reg_info {
- enum tegra_la_id id;
- unsigned int tl_reg_addr;
- unsigned int tl_mask;
- unsigned int tl_shift;
- unsigned int tm_reg_addr;
- unsigned int tm_mask;
- unsigned int tm_shift;
- unsigned int th_reg_addr;
- unsigned int th_mask;
- unsigned int th_shift;
-};
-
-#define DISP1_RA(r) \
- ((u32)IO_ADDRESS(TEGRA_DISPLAY_BASE) + DS_DISP_MCCIF_##r##_HYST)
-#define DISP2_RA(r) \
- ((u32)IO_ADDRESS(TEGRA_DISPLAY2_BASE) + DS_DISP_MCCIF_##r##_HYST)
-
-#define DISP_SCALING_REG_INFO(id, r, ra) \
- { \
- ID(id), \
- ra(r), MASK(15 : 8), SHIFT(15 : 8), \
- ra(r), MASK(23 : 16), SHIFT(15 : 8), \
- ra(r), MASK(7 : 0), SHIFT(15 : 8) \
- }
-
-struct la_scaling_reg_info disp_info[] = {
- DISP_SCALING_REG_INFO(DISPLAY_0A, DISPLAY0A, DISP1_RA),
- DISP_SCALING_REG_INFO(DISPLAY_0B, DISPLAY0B, DISP1_RA),
- DISP_SCALING_REG_INFO(DISPLAY_0C, DISPLAY0C, DISP1_RA),
- DISP_SCALING_REG_INFO(DISPLAY_1B, DISPLAY1B, DISP1_RA),
- DISP_SCALING_REG_INFO(MAX_ID, DISPLAY1B, DISP1_RA), /*dummy entry*/
- DISP_SCALING_REG_INFO(DISPLAY_0AB, DISPLAY0AB, DISP2_RA),
- DISP_SCALING_REG_INFO(DISPLAY_0BB, DISPLAY0BB, DISP2_RA),
- DISP_SCALING_REG_INFO(DISPLAY_0CB, DISPLAY0CB, DISP2_RA),
- DISP_SCALING_REG_INFO(DISPLAY_1BB, DISPLAY1BB, DISP2_RA),
-};
-
-#define VI_TH_RA(r) \
- ((u32)IO_ADDRESS(TEGRA_VI_BASE) + VI_MCCIF_##r##_HYST)
-#define VI_TM_RA(r) \
- ((u32)IO_ADDRESS(TEGRA_VI_BASE) + VI_TIMEOUT_WOCAL_VI)
-#define VI_TL_RA(r) \
- ((u32)IO_ADDRESS(TEGRA_VI_BASE) + VI_RESERVE_##r)
-
-struct la_scaling_reg_info vi_info[] = {
- {
- ID(VI_WSB),
- VI_TL_RA(4), MASK(7 : 0), SHIFT(7 : 0),
- VI_TM_RA(0), MASK(7 : 0), SHIFT(7 : 0),
- VI_TH_RA(VIWSB), MASK(7 : 0), SHIFT(7 : 0)
- },
- {
- ID(VI_WU),
- VI_TL_RA(3), MASK(15 : 8), SHIFT(15 : 8),
- VI_TM_RA(0), MASK(15 : 8), SHIFT(15 : 8),
- VI_TH_RA(VIWU), MASK(7 : 0), SHIFT(7 : 0)
- },
- {
- ID(VI_WV),
- VI_TL_RA(3), MASK(7 : 0), SHIFT(7 : 0),
- VI_TM_RA(0), MASK(23 : 16), SHIFT(23 : 16),
- VI_TH_RA(VIWV), MASK(7 : 0), SHIFT(7 : 0)
- },
- {
- ID(VI_WY),
- VI_TL_RA(4), MASK(15 : 8), SHIFT(15 : 8),
- VI_TM_RA(0), MASK(31 : 24), SHIFT(31 : 24),
- VI_TH_RA(VIWY), MASK(7 : 0), SHIFT(7 : 0)
- }
-};
-
+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 { \
- if (id >= TEGRA_LA_MAX_ID) \
+ if (id >= TEGRA_LA_MAX_ID || id_to_index[id] == 0xFFFF) { \
+ pr_err("%s: invalid Id=%d", __func__, id); \
return -EINVAL; \
- BUG_ON(la_info[id].id != id); \
+ } \
+ BUG_ON(la_info_array[id_to_index[id]].id != id); \
} while (0)
#define VALIDATE_BW(bw_in_mbps) \
@@ -330,20 +79,22 @@ static void set_thresholds(struct la_scaling_reg_info *info,
unsigned int thresh_mid;
unsigned int thresh_high;
int la_set;
+ int idx = id_to_index[id];
- reg_read = readl(la_info[id].reg_addr);
- la_set = (reg_read & la_info[id].mask) >> la_info[id].shift;
+ reg_read = readl(la_info_array[idx].reg_addr);
+ la_set = (reg_read & la_info_array[idx].mask) >>
+ la_info_array[idx].shift;
/* la should be set before enabling scaling. */
- BUG_ON(la_set != scaling_info[id].la_set);
+ BUG_ON(la_set != scaling_info[idx].la_set);
- thresh_low = (scaling_info[id].threshold_low * la_set) / 100;
- thresh_mid = (scaling_info[id].threshold_mid * la_set) / 100;
- thresh_high = (scaling_info[id].threshold_high * la_set) / 100;
+ thresh_low = (scaling_info[idx].threshold_low * la_set) / 100;
+ thresh_mid = (scaling_info[idx].threshold_mid * la_set) / 100;
+ thresh_high = (scaling_info[idx].threshold_high * la_set) / 100;
la_debug("%s: la_set=%d, thresh_low=%d(%d%%), thresh_mid=%d(%d%%),"
" thresh_high=%d(%d%%) ", __func__, la_set,
- thresh_low, scaling_info[id].threshold_low,
- thresh_mid, scaling_info[id].threshold_mid,
- thresh_high, scaling_info[id].threshold_high);
+ thresh_low, scaling_info[idx].threshold_low,
+ thresh_mid, scaling_info[idx].threshold_mid,
+ thresh_high, scaling_info[idx].threshold_high);
reg_read = readl(info->tl_reg_addr);
reg_write = (reg_read & ~info->tl_mask) |
@@ -391,14 +142,12 @@ int tegra_set_latency_allowance(enum tegra_la_id id,
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);
- if (id == ID(FDCDRD) || id == ID(FDCDWR) ||
- id == ID(FDCDRD2) || id == ID(FDCDWR2))
- bytes_per_atom = fdc_atom_size;
- ci = &la_info[id];
+ ci = &la_info_array[idx];
fifo_size_in_atoms = ci->fifo_size_in_atoms;
#if HACK_LA_FIFO
@@ -416,18 +165,18 @@ int tegra_set_latency_allowance(enum tegra_la_id id,
la_to_set = ideal_la - (ci->expiration_in_ns/ns_per_tick) - 1;
}
- la_debug("\n%s:id=%d,bw=%dmbps, la_to_set=%d",
- __func__, id, bandwidth_in_mbps, la_to_set);
+ 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[id].actual_la_to_set = 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[id].la_set = la_to_set;
+ 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);
@@ -450,21 +199,22 @@ int tegra_enable_latency_scaling(enum tegra_la_id id,
{
unsigned long reg;
unsigned long scaling_enable_reg = MC_RA(ARB_OVERRIDE);
+ int idx = id_to_index[id];
VALIDATE_ID(id);
VALIDATE_THRESHOLDS(threshold_low, threshold_mid, threshold_high);
- if (la_info[id].scaling_supported == false)
+ if (la_info_array[idx].scaling_supported == false)
goto exit;
spin_lock(&safety_lock);
la_debug("\n%s: id=%d, tl=%d, tm=%d, th=%d", __func__,
id, threshold_low, threshold_mid, threshold_high);
- scaling_info[id].threshold_low = threshold_low;
- scaling_info[id].threshold_mid = threshold_mid;
- scaling_info[id].threshold_high = threshold_high;
- scaling_info[id].scaling_ref_count++;
+ scaling_info[idx].threshold_low = threshold_low;
+ scaling_info[idx].threshold_mid = threshold_mid;
+ scaling_info[idx].threshold_high = threshold_high;
+ scaling_info[idx].scaling_ref_count++;
if (id >= ID(DISPLAY_0A) && id <= ID(DISPLAY_1BB))
set_disp_latency_thresholds(id);
@@ -485,17 +235,18 @@ void tegra_disable_latency_scaling(enum tegra_la_id id)
{
unsigned long reg;
unsigned long scaling_enable_reg = MC_RA(ARB_OVERRIDE);
+ int idx;
- if (id >= TEGRA_LA_MAX_ID)
- return;
- BUG_ON(la_info[id].id != id);
+ BUG_ON(id >= TEGRA_LA_MAX_ID);
+ idx = id_to_index[id];
+ BUG_ON(la_info_array[idx].id != id);
- if (la_info[id].scaling_supported == false)
+ if (la_info_array[idx].scaling_supported == false)
return;
spin_lock(&safety_lock);
la_debug("\n%s: id=%d", __func__, id);
- scaling_info[id].scaling_ref_count--;
- BUG_ON(scaling_info[id].scaling_ref_count < 0);
+ scaling_info[idx].scaling_ref_count--;
+ BUG_ON(scaling_info[idx].scaling_ref_count < 0);
if (!--la_scaling_enable_count) {
reg = readl(scaling_enable_reg);
@@ -512,13 +263,13 @@ static int la_regs_show(struct seq_file *s, void *unused)
unsigned long la;
/* iterate the list, but don't print MAX_ID */
- for (i = 0; i < ARRAY_SIZE(la_info) - 1; i++) {
- la = (readl(la_info[i].reg_addr) & la_info[i].mask)
- >> la_info[i].shift;
- seq_printf(s, "%-16s: %4lu\n", la_info[i].name, la);
+ for (i = 0; i < ARRAY_SIZE(la_info_array) - 1; i++) {
+ la = (readl(la_info_array[i].reg_addr) & la_info_array[i].mask)
+ >> la_info_array[i].shift;
+ seq_printf(s, "%-16s: %4lu\n", la_info_array[i].name, la);
}
- return 0;
+ return 0;
}
static int dbg_la_regs_open(struct inode *inode, struct file *file)
@@ -550,7 +301,13 @@ late_initcall(tegra_latency_allowance_debugfs_init);
static int __init tegra_latency_allowance_init(void)
{
+ unsigned int i;
+
la_scaling_enable_count = 0;
+ memset(&id_to_index[0], 0xFF, sizeof(id_to_index));
+
+ for (i = 0; i < ARRAY_SIZE(la_info_array); i++)
+ id_to_index[la_info_array[i].id] = i;
tegra_set_latency_allowance(TEGRA_LA_G2PR, 20);
tegra_set_latency_allowance(TEGRA_LA_G2SR, 20);
@@ -562,12 +319,19 @@ static int __init tegra_latency_allowance_init(void)
core_initcall(tegra_latency_allowance_init);
#if TEST_LA_CODE
+#define PRINT_ID_IDX_MAPPING 0
static int __init test_la(void)
{
+ int i;
int err;
enum tegra_la_id id = 0;
int repeat_count = 5;
+#if PRINT_ID_IDX_MAPPING
+ for (i = 0; i < ID(MAX_ID); i++)
+ pr_info("ID=0x%x, Idx=0x%x", i, id_to_index[i]);
+#endif
+
do {
for (id = 0; id < TEGRA_LA_MAX_ID; id++) {
err = tegra_set_latency_allowance(id, 200);
diff --git a/arch/arm/mach-tegra/tegra3_la_priv.h b/arch/arm/mach-tegra/tegra3_la_priv.h
new file mode 100644
index 000000000000..7f3fa7c46931
--- /dev/null
+++ b/arch/arm/mach-tegra/tegra3_la_priv.h
@@ -0,0 +1,226 @@
+/*
+ * arch/arm/mach-tegra/tegra3_la_priv.h
+ *
+ * Copyright (C) 2012, NVIDIA CORPORATION. All rights reserved.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#ifndef _MACH_TEGRA_TEGRA3_LA_PRIV_H_
+#define _MACH_TEGRA_TEGRA3_LA_PRIV_H_
+
+#if defined(CONFIG_ARCH_TEGRA_3x_SOC)
+
+#define MC_LA_AFI_0 0x2e0
+#define MC_LA_AVPC_ARM7_0 0x2e4
+#define MC_LA_DC_0 0x2e8
+#define MC_LA_DC_1 0x2ec
+#define MC_LA_DC_2 0x2f0
+#define MC_LA_DCB_0 0x2f4
+#define MC_LA_DCB_1 0x2f8
+#define MC_LA_DCB_2 0x2fc
+#define MC_LA_EPP_0 0x300
+#define MC_LA_EPP_1 0x304
+#define MC_LA_G2_0 0x308
+#define MC_LA_G2_1 0x30c
+#define MC_LA_HC_0 0x310
+#define MC_LA_HC_1 0x314
+#define MC_LA_HDA_0 0x318
+#define MC_LA_ISP_0 0x31C
+#define MC_LA_MPCORE_0 0x320
+#define MC_LA_MPCORELP_0 0x324
+#define MC_LA_MPE_0 0x328
+#define MC_LA_MPE_1 0x32c
+#define MC_LA_MPE_2 0x330
+#define MC_LA_NV_0 0x334
+#define MC_LA_NV_1 0x338
+#define MC_LA_NV2_0 0x33c
+#define MC_LA_NV2_1 0x340
+#define MC_LA_PPCS_0 0x344
+#define MC_LA_PPCS_1 0x348
+#define MC_LA_PTC_0 0x34c
+#define MC_LA_SATA_0 0x350
+#define MC_LA_VDE_0 0x354
+#define MC_LA_VDE_1 0x358
+#define MC_LA_VDE_2 0x35c
+#define MC_LA_VDE_3 0x360
+#define MC_LA_VI_0 0x364
+#define MC_LA_VI_1 0x368
+#define MC_LA_VI_2 0x36c
+
+#define MC_ARB_OVERRIDE 0xe8
+#define GLOBAL_LATENCY_SCALING_ENABLE_BIT 7
+
+#define DS_DISP_MCCIF_DISPLAY0A_HYST (0x481 * 4)
+#define DS_DISP_MCCIF_DISPLAY0B_HYST (0x482 * 4)
+#define DS_DISP_MCCIF_DISPLAY0C_HYST (0x483 * 4)
+#define DS_DISP_MCCIF_DISPLAY1B_HYST (0x484 * 4)
+
+#define DS_DISP_MCCIF_DISPLAY0AB_HYST (0x481 * 4)
+#define DS_DISP_MCCIF_DISPLAY0BB_HYST (0x482 * 4)
+#define DS_DISP_MCCIF_DISPLAY0CB_HYST (0x483 * 4)
+#define DS_DISP_MCCIF_DISPLAY1BB_HYST (0x484 * 4)
+
+#define VI_MCCIF_VIWSB_HYST (0x9a * 4)
+#define VI_MCCIF_VIWU_HYST (0x9b * 4)
+#define VI_MCCIF_VIWV_HYST (0x9c * 4)
+#define VI_MCCIF_VIWY_HYST (0x9d * 4)
+
+#define VI_TIMEOUT_WOCAL_VI (0x70 * 4)
+#define VI_RESERVE_3 (0x97 * 4)
+#define VI_RESERVE_4 (0x98 * 4)
+
+/*
+ * The rule for getting the fifo_size_in_atoms is:
+ * 1.If REORDER_DEPTH exists, use it(default is overridden).
+ * 2.Else if (write_client) use RFIFO_DEPTH.
+ * 3.Else (read client) use RDFIFO_DEPTH.
+ * Multiply the value by 2 for wide clients.
+ * A client is wide, if CMW is larger than MW.
+ * Refer to project.h file.
+ */
+struct la_client_info la_info_array[] = {
+ LA_INFO(32, 150, AFI_0, 7 : 0, AFIR, false),
+ LA_INFO(32, 150, AFI_0, 23 : 16, AFIW, false),
+ LA_INFO(2, 150, AVPC_ARM7_0, 7 : 0, AVPC_ARM7R, false),
+ LA_INFO(2, 150, AVPC_ARM7_0, 23 : 16, AVPC_ARM7W, false),
+ LA_INFO(128, 1050, DC_0, 7 : 0, DISPLAY_0A, true),
+ LA_INFO(64, 1050, DC_0, 23 : 16, DISPLAY_0B, true),
+ LA_INFO(128, 1050, DC_1, 7 : 0, DISPLAY_0C, true),
+ LA_INFO(64, 1050, DC_1, 23 : 16, DISPLAY_1B, true),
+ LA_INFO(2, 1050, DC_2, 7 : 0, DISPLAY_HC, false),
+ LA_INFO(128, 1050, DCB_0, 7 : 0, DISPLAY_0AB, true),
+ LA_INFO(64, 1050, DCB_0, 23 : 16, DISPLAY_0BB, true),
+ LA_INFO(128, 1050, DCB_1, 7 : 0, DISPLAY_0CB, true),
+ LA_INFO(64, 1050, DCB_1, 23 : 16, DISPLAY_1BB, true),
+ LA_INFO(2, 1050, DCB_2, 7 : 0, DISPLAY_HCB, false),
+ LA_INFO(8, 150, EPP_0, 7 : 0, EPPUP, false),
+ LA_INFO(64, 150, EPP_0, 23 : 16, EPPU, false),
+ LA_INFO(64, 150, EPP_1, 7 : 0, EPPV, false),
+ LA_INFO(64, 150, EPP_1, 23 : 16, EPPY, false),
+ LA_INFO(64, 150, G2_0, 7 : 0, G2PR, false),
+ LA_INFO(64, 150, G2_0, 23 : 16, G2SR, false),
+ LA_INFO(48, 150, G2_1, 7 : 0, G2DR, false),
+ LA_INFO(128, 150, G2_1, 23 : 16, G2DW, false),
+ LA_INFO(16, 150, HC_0, 7 : 0, HOST1X_DMAR, false),
+ LA_INFO(8, 150, HC_0, 23 : 16, HOST1XR, false),
+ LA_INFO(32, 150, HC_1, 7 : 0, HOST1XW, false),
+ LA_INFO(16, 150, HDA_0, 7 : 0, HDAR, false),
+ LA_INFO(16, 150, HDA_0, 23 : 16, HDAW, false),
+ LA_INFO(64, 150, ISP_0, 7 : 0, ISPW, false),
+ LA_INFO(14, 150, MPCORE_0, 7 : 0, MPCORER, false),
+ LA_INFO(24, 150, MPCORE_0, 23 : 16, MPCOREW, false),
+ LA_INFO(14, 150, MPCORELP_0, 7 : 0, MPCORE_LPR, false),
+ LA_INFO(24, 150, MPCORELP_0, 23 : 16, MPCORE_LPW, false),
+ LA_INFO(8, 150, MPE_0, 7 : 0, MPE_UNIFBR, false),
+ LA_INFO(2, 150, MPE_0, 23 : 16, MPE_IPRED, false),
+ LA_INFO(64, 150, MPE_1, 7 : 0, MPE_AMEMRD, false),
+ LA_INFO(8, 150, MPE_1, 23 : 16, MPE_CSRD, false),
+ LA_INFO(8, 150, MPE_2, 7 : 0, MPE_UNIFBW, false),
+ LA_INFO(8, 150, MPE_2, 23 : 16, MPE_CSWR, false),
+ LA_INFO(96, 150, NV_0, 7 : 0, FDCDRD, false),
+ LA_INFO(64, 150, NV_0, 23 : 16, IDXSRD, false),
+ LA_INFO(64, 150, NV_1, 7 : 0, TEXSRD, false),
+ LA_INFO(96, 150, NV_1, 23 : 16, FDCDWR, false),
+ LA_INFO(96, 150, NV2_0, 7 : 0, FDCDRD2, false),
+ LA_INFO(64, 150, NV2_0, 23 : 16, IDXSRD2, false),
+ LA_INFO(64, 150, NV2_1, 7 : 0, TEXSRD2, false),
+ LA_INFO(96, 150, NV2_1, 23 : 16, FDCDWR2, false),
+ LA_INFO(2, 150, PPCS_0, 7 : 0, PPCS_AHBDMAR, false),
+ LA_INFO(8, 150, PPCS_0, 23 : 16, PPCS_AHBSLVR, false),
+ LA_INFO(2, 150, PPCS_1, 7 : 0, PPCS_AHBDMAW, false),
+ LA_INFO(4, 150, PPCS_1, 23 : 16, PPCS_AHBSLVW, false),
+ LA_INFO(2, 150, PTC_0, 7 : 0, PTCR, false),
+ LA_INFO(32, 150, SATA_0, 7 : 0, SATAR, false),
+ LA_INFO(32, 150, SATA_0, 23 : 16, SATAW, false),
+ LA_INFO(8, 150, VDE_0, 7 : 0, VDE_BSEVR, false),
+ LA_INFO(4, 150, VDE_0, 23 : 16, VDE_MBER, false),
+ LA_INFO(16, 150, VDE_1, 7 : 0, VDE_MCER, false),
+ LA_INFO(16, 150, VDE_1, 23 : 16, VDE_TPER, false),
+ LA_INFO(4, 150, VDE_2, 7 : 0, VDE_BSEVW, false),
+ LA_INFO(16, 150, VDE_2, 23 : 16, VDE_DBGW, false),
+ LA_INFO(2, 150, VDE_3, 7 : 0, VDE_MBEW, false),
+ LA_INFO(16, 150, VDE_3, 23 : 16, VDE_TPMW, false),
+ LA_INFO(8, 1050, VI_0, 7 : 0, VI_RUV, false),
+ LA_INFO(64, 1050, VI_0, 23 : 16, VI_WSB, true),
+ LA_INFO(64, 1050, VI_1, 7 : 0, VI_WU, true),
+ LA_INFO(64, 1050, VI_1, 23 : 16, VI_WV, true),
+ LA_INFO(64, 1050, VI_2, 7 : 0, VI_WY, true),
+
+/* end of list. */
+ LA_INFO(0, 0, AFI_0, 0 : 0, MAX_ID, false)
+};
+
+#define DISP1_RA(r) \
+ ((u32)IO_ADDRESS(TEGRA_DISPLAY_BASE) + DS_DISP_MCCIF_##r##_HYST)
+#define DISP2_RA(r) \
+ ((u32)IO_ADDRESS(TEGRA_DISPLAY2_BASE) + DS_DISP_MCCIF_##r##_HYST)
+
+#define DISP_SCALING_REG_INFO(id, r, ra) \
+ { \
+ ID(id), \
+ ra(r), MASK(15 : 8), SHIFT(15 : 8), \
+ ra(r), MASK(23 : 16), SHIFT(15 : 8), \
+ ra(r), MASK(7 : 0), SHIFT(15 : 8) \
+ }
+
+struct la_scaling_reg_info disp_info[] = {
+ DISP_SCALING_REG_INFO(DISPLAY_0A, DISPLAY0A, DISP1_RA),
+ DISP_SCALING_REG_INFO(DISPLAY_0B, DISPLAY0B, DISP1_RA),
+ DISP_SCALING_REG_INFO(DISPLAY_0C, DISPLAY0C, DISP1_RA),
+ DISP_SCALING_REG_INFO(DISPLAY_1B, DISPLAY1B, DISP1_RA),
+ DISP_SCALING_REG_INFO(MAX_ID, DISPLAY1B, DISP1_RA), /*dummy entry*/
+ DISP_SCALING_REG_INFO(DISPLAY_0AB, DISPLAY0AB, DISP2_RA),
+ DISP_SCALING_REG_INFO(DISPLAY_0BB, DISPLAY0BB, DISP2_RA),
+ DISP_SCALING_REG_INFO(DISPLAY_0CB, DISPLAY0CB, DISP2_RA),
+ DISP_SCALING_REG_INFO(DISPLAY_1BB, DISPLAY1BB, DISP2_RA),
+};
+
+#define VI_TH_RA(r) \
+ ((u32)IO_ADDRESS(TEGRA_VI_BASE) + VI_MCCIF_##r##_HYST)
+#define VI_TM_RA(r) \
+ ((u32)IO_ADDRESS(TEGRA_VI_BASE) + VI_TIMEOUT_WOCAL_VI)
+#define VI_TL_RA(r) \
+ ((u32)IO_ADDRESS(TEGRA_VI_BASE) + VI_RESERVE_##r)
+
+struct la_scaling_reg_info vi_info[] = {
+ {
+ ID(VI_WSB),
+ VI_TL_RA(4), MASK(7 : 0), SHIFT(7 : 0),
+ VI_TM_RA(0), MASK(7 : 0), SHIFT(7 : 0),
+ VI_TH_RA(VIWSB), MASK(7 : 0), SHIFT(7 : 0)
+ },
+ {
+ ID(VI_WU),
+ VI_TL_RA(3), MASK(15 : 8), SHIFT(15 : 8),
+ VI_TM_RA(0), MASK(15 : 8), SHIFT(15 : 8),
+ VI_TH_RA(VIWU), MASK(7 : 0), SHIFT(7 : 0)
+ },
+ {
+ ID(VI_WV),
+ VI_TL_RA(3), MASK(7 : 0), SHIFT(7 : 0),
+ VI_TM_RA(0), MASK(23 : 16), SHIFT(23 : 16),
+ VI_TH_RA(VIWV), MASK(7 : 0), SHIFT(7 : 0)
+ },
+ {
+ ID(VI_WY),
+ VI_TL_RA(4), MASK(15 : 8), SHIFT(15 : 8),
+ VI_TM_RA(0), MASK(31 : 24), SHIFT(31 : 24),
+ VI_TH_RA(VIWY), MASK(7 : 0), SHIFT(7 : 0)
+ }
+};
+
+static const int ns_per_tick = 30;
+/* Tegra3 MC atom size in bytes */
+static const int normal_atom_size = 16;
+#endif
+
+#endif /* _MACH_TEGRA_TEGRA3_LA_PRIV_H_ */