Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

firmware: tf: Different way of L2 cache enabling after LP2 suspend

ASUS TF300T device may not work properly if firmware is asked to fully
re-initialize L2 cache after resume from LP2 suspend. The downstream
kernel of TF300T uses different opcode to enable cache after resuming
from LP2, this opcode also works fine on Nexus 7 and Ouya devices.
Supposedly, this may be needed by an older firmware versions.

Reported-by: Michał Mirosław <mirq-linux@rere.qmqm.pl>
Tested-by: Michał Mirosław <mirq-linux@rere.qmqm.pl>
Tested-by: Jasper Korten <jja2000@gmail.com>
Tested-by: David Heidelberg <david@ixit.cz>
Tested-by: Peter Geis <pgwipeout@gmail.com>
Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
Signed-off-by: Thierry Reding <treding@nvidia.com>

authored by

Dmitry Osipenko and committed by
Thierry Reding
b720aaa3 d70f5e54

+20 -2
+19 -2
drivers/firmware/trusted_foundations.c
··· 19 19 20 20 #define TF_CACHE_ENABLE 1 21 21 #define TF_CACHE_DISABLE 2 22 + #define TF_CACHE_REENABLE 4 22 23 23 24 #define TF_SET_CPU_BOOT_ADDR_SMC 0xfffff200 24 25 ··· 30 29 #define TF_CPU_PM_S1 0xffffffe4 31 30 #define TF_CPU_PM_S1_NOFLUSH_L2 0xffffffe7 32 31 32 + static unsigned long tf_idle_mode = TF_PM_MODE_NONE; 33 33 static unsigned long cpu_boot_addr; 34 34 35 35 static void tf_generic_smc(u32 type, u32 arg1, u32 arg2) ··· 87 85 cpu_boot_addr); 88 86 break; 89 87 88 + case TF_PM_MODE_NONE: 89 + break; 90 + 90 91 default: 91 92 return -EINVAL; 92 93 } 94 + 95 + tf_idle_mode = mode; 93 96 94 97 return 0; 95 98 } ··· 102 95 #ifdef CONFIG_CACHE_L2X0 103 96 static void tf_cache_write_sec(unsigned long val, unsigned int reg) 104 97 { 105 - u32 l2x0_way_mask = 0xff; 98 + u32 enable_op, l2x0_way_mask = 0xff; 106 99 107 100 switch (reg) { 108 101 case L2X0_CTRL: 109 102 if (l2x0_saved_regs.aux_ctrl & L310_AUX_CTRL_ASSOCIATIVITY_16) 110 103 l2x0_way_mask = 0xffff; 111 104 105 + switch (tf_idle_mode) { 106 + case TF_PM_MODE_LP2: 107 + enable_op = TF_CACHE_REENABLE; 108 + break; 109 + 110 + default: 111 + enable_op = TF_CACHE_ENABLE; 112 + break; 113 + } 114 + 112 115 if (val == L2X0_CTRL_EN) 113 - tf_generic_smc(TF_CACHE_MAINT, TF_CACHE_ENABLE, 116 + tf_generic_smc(TF_CACHE_MAINT, enable_op, 114 117 l2x0_saved_regs.aux_ctrl); 115 118 else 116 119 tf_generic_smc(TF_CACHE_MAINT, TF_CACHE_DISABLE,
+1
include/linux/firmware/trusted_foundations.h
··· 32 32 #define TF_PM_MODE_LP1_NO_MC_CLK 2 33 33 #define TF_PM_MODE_LP2 3 34 34 #define TF_PM_MODE_LP2_NOFLUSH_L2 4 35 + #define TF_PM_MODE_NONE 5 35 36 36 37 struct trusted_foundations_platform_data { 37 38 unsigned int version_major;