Commit 8e857916 authored by Soby Mathew's avatar Soby Mathew
Browse files

Add support for level specific cache maintenance operations

This patch adds level specific cache maintenance functions
to cache_helpers.S. The new functions 'dcsw_op_levelx',
where '1 <= x <= 3', allow to perform cache maintenance by
set/way for that particular level of cache.  With this patch,
functions to support cache maintenance upto level 3 have
been implemented since it is the highest cache level for
most ARM SoCs.

These functions are now utilized in CPU specific power down
sequences to implement them as mandated by processor specific
technical reference manual.

Change-Id: Icd90ce6b51cff5a12863bcda01b93601417fd45c
parent 0f4b0634
...@@ -35,6 +35,9 @@ ...@@ -35,6 +35,9 @@
.globl inv_dcache_range .globl inv_dcache_range
.globl dcsw_op_louis .globl dcsw_op_louis
.globl dcsw_op_all .globl dcsw_op_all
.globl dcsw_op_level1
.globl dcsw_op_level2
.globl dcsw_op_level3
/* ------------------------------------------ /* ------------------------------------------
* Clean+Invalidate from base address till * Clean+Invalidate from base address till
...@@ -81,6 +84,7 @@ inv_loop: ...@@ -81,6 +84,7 @@ inv_loop:
* x0: The operation type (0-2), as defined in arch.h * x0: The operation type (0-2), as defined in arch.h
* x3: The last cache level to operate on * x3: The last cache level to operate on
* x9: clidr_el1 * x9: clidr_el1
* x10: The cache level to begin operation from
* and will carry out the operation on each data cache from level 0 * and will carry out the operation on each data cache from level 0
* to the level in x3 in sequence * to the level in x3 in sequence
* *
...@@ -93,12 +97,12 @@ inv_loop: ...@@ -93,12 +97,12 @@ inv_loop:
mrs x9, clidr_el1 mrs x9, clidr_el1
ubfx x3, x9, \shift, \fw ubfx x3, x9, \shift, \fw
lsl x3, x3, \ls lsl x3, x3, \ls
mov x10, xzr
b do_dcsw_op b do_dcsw_op
.endm .endm
func do_dcsw_op func do_dcsw_op
cbz x3, exit cbz x3, exit
mov x10, xzr
adr x14, dcsw_loop_table // compute inner loop address adr x14, dcsw_loop_table // compute inner loop address
add x14, x14, x0, lsl #5 // inner loop is 8x32-bit instructions add x14, x14, x0, lsl #5 // inner loop is 8x32-bit instructions
mov x0, x9 mov x0, x9
...@@ -163,3 +167,45 @@ func dcsw_op_louis ...@@ -163,3 +167,45 @@ func dcsw_op_louis
func dcsw_op_all func dcsw_op_all
dcsw_op #LOC_SHIFT, #CLIDR_FIELD_WIDTH, #LEVEL_SHIFT dcsw_op #LOC_SHIFT, #CLIDR_FIELD_WIDTH, #LEVEL_SHIFT
/* ---------------------------------------------------------------
* Helper macro for data cache operations by set/way for the
* level specified
* ---------------------------------------------------------------
*/
.macro dcsw_op_level level
mrs x9, clidr_el1
mov x3, \level
sub x10, x3, #2
b do_dcsw_op
.endm
/* ---------------------------------------------------------------
* Data cache operations by set/way for level 1 cache
*
* The main function, do_dcsw_op requires:
* x0: The operation type (0-2), as defined in arch.h
* ---------------------------------------------------------------
*/
func dcsw_op_level1
dcsw_op_level #(1 << LEVEL_SHIFT)
/* ---------------------------------------------------------------
* Data cache operations by set/way for level 2 cache
*
* The main function, do_dcsw_op requires:
* x0: The operation type (0-2), as defined in arch.h
* ---------------------------------------------------------------
*/
func dcsw_op_level2
dcsw_op_level #(2 << LEVEL_SHIFT)
/* ---------------------------------------------------------------
* Data cache operations by set/way for level 3 cache
*
* The main function, do_dcsw_op requires:
* x0: The operation type (0-2), as defined in arch.h
* ---------------------------------------------------------------
*/
func dcsw_op_level3
dcsw_op_level #(3 << LEVEL_SHIFT)
...@@ -77,11 +77,11 @@ func cortex_a53_core_pwr_dwn ...@@ -77,11 +77,11 @@ func cortex_a53_core_pwr_dwn
bl cortex_a53_disable_dcache bl cortex_a53_disable_dcache
/* --------------------------------------------- /* ---------------------------------------------
* Flush L1 cache to PoU. * Flush L1 caches.
* --------------------------------------------- * ---------------------------------------------
*/ */
mov x0, #DCCISW mov x0, #DCCISW
bl dcsw_op_louis bl dcsw_op_level1
/* --------------------------------------------- /* ---------------------------------------------
* Come out of intra cluster coherency * Come out of intra cluster coherency
...@@ -99,6 +99,13 @@ func cortex_a53_cluster_pwr_dwn ...@@ -99,6 +99,13 @@ func cortex_a53_cluster_pwr_dwn
*/ */
bl cortex_a53_disable_dcache bl cortex_a53_disable_dcache
/* ---------------------------------------------
* Flush L1 caches.
* ---------------------------------------------
*/
mov x0, #DCCISW
bl dcsw_op_level1
/* --------------------------------------------- /* ---------------------------------------------
* Disable the optional ACP. * Disable the optional ACP.
* --------------------------------------------- * ---------------------------------------------
...@@ -106,11 +113,11 @@ func cortex_a53_cluster_pwr_dwn ...@@ -106,11 +113,11 @@ func cortex_a53_cluster_pwr_dwn
bl plat_disable_acp bl plat_disable_acp
/* --------------------------------------------- /* ---------------------------------------------
* Flush L1 and L2 caches to PoC. * Flush L2 caches.
* --------------------------------------------- * ---------------------------------------------
*/ */
mov x0, #DCCISW mov x0, #DCCISW
bl dcsw_op_all bl dcsw_op_level2
/* --------------------------------------------- /* ---------------------------------------------
* Come out of intra cluster coherency * Come out of intra cluster coherency
......
...@@ -134,11 +134,11 @@ func cortex_a57_core_pwr_dwn ...@@ -134,11 +134,11 @@ func cortex_a57_core_pwr_dwn
bl cortex_a57_disable_l2_prefetch bl cortex_a57_disable_l2_prefetch
/* --------------------------------------------- /* ---------------------------------------------
* Flush L1 cache to PoU. * Flush L1 caches.
* --------------------------------------------- * ---------------------------------------------
*/ */
mov x0, #DCCISW mov x0, #DCCISW
bl dcsw_op_louis bl dcsw_op_level1
/* --------------------------------------------- /* ---------------------------------------------
* Come out of intra cluster coherency * Come out of intra cluster coherency
...@@ -168,18 +168,25 @@ func cortex_a57_cluster_pwr_dwn ...@@ -168,18 +168,25 @@ func cortex_a57_cluster_pwr_dwn
*/ */
bl cortex_a57_disable_l2_prefetch bl cortex_a57_disable_l2_prefetch
/* -------------------------------------------------
* Flush the L1 caches.
* -------------------------------------------------
*/
mov x0, #DCCISW
bl dcsw_op_level1
/* --------------------------------------------- /* ---------------------------------------------
* Disable the optional ACP. * Disable the optional ACP.
* --------------------------------------------- * ---------------------------------------------
*/ */
bl plat_disable_acp bl plat_disable_acp
/* --------------------------------------------- /* -------------------------------------------------
* Flush L1 and L2 caches to PoC. * Flush the L2 caches.
* --------------------------------------------- * -------------------------------------------------
*/ */
mov x0, #DCCISW mov x0, #DCCISW
bl dcsw_op_all bl dcsw_op_level2
/* --------------------------------------------- /* ---------------------------------------------
* Come out of intra cluster coherency * Come out of intra cluster coherency
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment