| /* Copyright (c) 2012, The Linux Foundation. All rights reserved. |
| * |
| * This program is free software; you can redistribute it and/or modify |
| * it under the terms of the GNU General Public License version 2 and |
| * only version 2 as published by the Free Software Foundation. |
| * |
| * 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. |
| */ |
| |
| #include <asm/hardware/cache-l2x0.h> |
| |
| /* Add 300 NOPs after 'wfi' for 8x25 target */ |
| .macro DELAY_8x25, rept |
| #ifdef CONFIG_ARCH_MSM8625 |
| .rept \rept |
| nop |
| .endr |
| #endif |
| .endm |
| |
| /* Switch between smp_to_amp/amp_to_smp configuration */ |
| .macro SET_SMP_COHERENCY, on = 0 |
| ldr r0, =target_type |
| ldr r0, [r0] |
| mov r1, #TARGET_IS_8625 |
| cmp r0, r1 |
| bne skip\@ |
| mrc p15, 0, r0, c1, c0, 1 /* read ACTLR register */ |
| .if \on |
| orr r0, r0, #(1 << 6) /* Set the SMP bit in ACTLR */ |
| .else |
| bic r0, r0, #(1 << 6) /* Clear the SMP bit */ |
| .endif |
| mcr p15, 0, r0, c1, c0, 1 /* write ACTLR register */ |
| isb |
| skip\@: |
| .endm |
| |
| /* |
| * Enable the "L2" cache, not require to restore the controller registers |
| */ |
| .macro ENABLE_8x25_L2 |
| ldr r0, =target_type |
| ldr r0, [r0] |
| mov r1, #TARGET_IS_8625 |
| cmp r0, r1 |
| bne skip_enable\@ |
| ldr r0, =apps_power_collapse |
| ldr r0, [r0] |
| cmp r0, #POWER_COLLAPSED |
| bne skip_enable\@ |
| ldr r0, =l2x0_base_addr |
| ldr r0, [r0] |
| mov r1, #0x1 |
| str r1, [r0, #L2X0_CTRL] |
| dmb |
| skip_enable\@: |
| .endm |
| |
| /* |
| * Perform the required operation |
| * operation: type of operation on l2 cache (e.g: clean&inv or inv) |
| * l2_enable: enable or disable |
| */ |
| .macro DO_CACHE_OPERATION, operation, l2_enable |
| ldr r2, =l2x0_base_addr |
| ldr r2, [r2] |
| ldr r0, =0xffff |
| str r0, [r2, #\operation] |
| wait\@: |
| ldr r0, [r2, #\operation] |
| ldr r1, =0xffff |
| ands r0, r0, r1 |
| bne wait\@ |
| l2x_sync\@: |
| mov r0, #0x0 |
| str r0, [r2, #L2X0_CACHE_SYNC] |
| sync\@: |
| ldr r0, [r2, #L2X0_CACHE_SYNC] |
| ands r0, r0, #0x1 |
| bne sync\@ |
| mov r1, #\l2_enable |
| str r1, [r2, #L2X0_CTRL] |
| .endm |
| |
| /* |
| * Clean and invalidate the L2 cache. |
| * 1. Check the target type |
| * 2. Check whether we are coming from PC are not |
| * 3. Save 'aux', 'data latency', & 'prefetch ctlr' registers |
| * 4. Start L2 clean & invalidation operation |
| * 5. Disable the L2 cache |
| */ |
| .macro SUSPEND_8x25_L2 |
| ldr r0, =target_type |
| ldr r0, [r0] |
| mov r1, #TARGET_IS_8625 |
| cmp r0, r1 |
| bne skip_suspend\@ |
| ldr r0, =apps_power_collapse |
| ldr r0, [r0] |
| cmp r0, #POWER_COLLAPSED |
| bne skip_suspend\@ |
| ldr r0, =l2x0_saved_ctrl_reg_val |
| ldr r1, =l2x0_base_addr |
| ldr r1, [r1] |
| ldr r2, [r1, #L2X0_AUX_CTRL] |
| str r2, [r0, #0x0] /* store aux_ctlr reg value */ |
| ldr r2, [r1, #L2X0_DATA_LATENCY_CTRL] |
| str r2, [r0, #0x4] /* store data latency reg value */ |
| ldr r2, [r1, #L2X0_PREFETCH_CTRL] |
| str r2, [r0, #0x8] /* store prefetch_ctlr reg value */ |
| DO_CACHE_OPERATION L2X0_CLEAN_INV_WAY OFF |
| dmb |
| skip_suspend\@: |
| .endm |
| |
| /* |
| * Coming back from a successful PC |
| * 1. Check the target type |
| * 2. Check whether we are going to PC are not |
| * 3. Disable the L2 cache |
| * 4. Restore 'aux', 'data latency', & 'prefetch ctlr' reg |
| * 5. Invalidate the cache |
| * 6. Enable the L2 cache |
| */ |
| .macro RESUME_8x25_L2 |
| ldr r0, =target_type |
| ldr r0, [r0] |
| mov r1, #TARGET_IS_8625 |
| cmp r0, r1 |
| bne skip_resume\@ |
| ldr r0, =apps_power_collapse |
| ldr r0, [r0] |
| cmp r0, #POWER_COLLAPSED |
| bne skip_resume\@ |
| ldr r1, =l2x0_base_addr |
| ldr r1, [r1] |
| mov r0, #0x0 |
| str r0, [r1, #L2X0_CTRL] |
| ldr r0, =l2x0_saved_ctrl_reg_val |
| ldr r2, [r0, #0x0] |
| str r2, [r1, #L2X0_AUX_CTRL] /* restore aux_ctlr reg value */ |
| ldr r2, [r0, #0x4] |
| str r2, [r1, #L2X0_DATA_LATENCY_CTRL] |
| ldr r2, [r0, #0x8] |
| str r2, [r1, #L2X0_PREFETCH_CTRL] |
| DO_CACHE_OPERATION L2X0_INV_WAY ON |
| skip_resume\@: |
| .endm |