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.
Unified · Split
| @@ -19,6 +19,7 @@ · 18 unmodified lines | ||
| 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 | |
| @@ -29,6 +30,7 @@ · 4 unmodified lines | ||
| 29 | 30 | #define TF_CPU_PM_S1 0xffffffe4 |
| 30 | 31 | #define TF_CPU_PM_S1_NOFLUSH_L2 0xffffffe7 |
| 31 | 32 | |
| 33 | +static unsigned long tf_idle_mode = TF_PM_MODE_NONE; | |
| 32 | 34 | static unsigned long cpu_boot_addr; |
| 33 | 35 | |
| 34 | 36 | static void tf_generic_smc(u32 type, u32 arg1, u32 arg2) |
| @@ -85,25 +87,40 @@ static int tf_prepare_idle(unsigned long mode) · 50 unmodified lines | ||
| 85 | 87 | cpu_boot_addr); |
| 86 | 88 | break; |
| 87 | 89 | |
| 90 | + case TF_PM_MODE_NONE: | |
| 91 | + break; | |
| 92 | + | |
| 88 | 93 | default: |
| 89 | 94 | return -EINVAL; |
| 90 | 95 | } |
| 91 | 96 | |
| 97 | + tf_idle_mode = mode; | |
| 98 | + | |
| 92 | 99 | return 0; |
| 93 | 100 | } |
| 94 | 101 | |
| 95 | 102 | #ifdef CONFIG_CACHE_L2X0 |
| 96 | 103 | static void tf_cache_write_sec(unsigned long val, unsigned int reg) |
| 97 | 104 | { |
| 98 | − u32 l2x0_way_mask = 0xff; | |
| 105 | + u32 enable_op, l2x0_way_mask = 0xff; | |
| 99 | 106 | |
| 100 | 107 | switch (reg) { |
| 101 | 108 | case L2X0_CTRL: |
| 102 | 109 | if (l2x0_saved_regs.aux_ctrl & L310_AUX_CTRL_ASSOCIATIVITY_16) |
| 103 | 110 | l2x0_way_mask = 0xffff; |
| 104 | 111 | |
| 112 | + switch (tf_idle_mode) { | |
| 113 | + case TF_PM_MODE_LP2: | |
| 114 | + enable_op = TF_CACHE_REENABLE; | |
| 115 | + break; | |
| 116 | + | |
| 117 | + default: | |
| 118 | + enable_op = TF_CACHE_ENABLE; | |
| 119 | + break; | |
| 120 | + } | |
| 121 | + | |
| 105 | 122 | if (val == L2X0_CTRL_EN) |
| 106 | − tf_generic_smc(TF_CACHE_MAINT, TF_CACHE_ENABLE, | |
| 123 | + tf_generic_smc(TF_CACHE_MAINT, enable_op, | |
| 107 | 124 | l2x0_saved_regs.aux_ctrl); |
| 108 | 125 | else |
| 109 | 126 | tf_generic_smc(TF_CACHE_MAINT, TF_CACHE_DISABLE, |
| @@ -32,6 +32,7 @@ · 31 unmodified lines | ||
| 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; |