diff options
author | Krishna Reddy <vdumpa@nvidia.com> | 2012-08-13 12:37:32 -0700 |
---|---|---|
committer | Simone Willett <swillett@nvidia.com> | 2012-08-15 17:12:57 -0700 |
commit | 361f7676aaecfd0157b89f0e106f59fcc229a839 (patch) | |
tree | f66e0c369bacdea5bc789dc9a77da9b42485cb2e /arch/arm | |
parent | 028042d5cc554c41a7b5f00fc2b20dce997fcc43 (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.h | 31 | ||||
-rw-r--r-- | arch/arm/mach-tegra/la_priv_common.h | 71 | ||||
-rw-r--r-- | arch/arm/mach-tegra/latency_allowance.c | 346 | ||||
-rw-r--r-- | arch/arm/mach-tegra/tegra3_la_priv.h | 226 |
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_ */ |