1 /* 2 * Copyright (C) 2018 Marvell International Ltd. 3 * 4 * SPDX-License-Identifier: BSD-3-Clause 5 * https://spdx.org/licenses 6 */ 7 8 /* LLC driver is the Last Level Cache (L3C) driver 9 * for Marvell SoCs in AP806, AP807, and AP810 10 */ 11 12 #include <assert.h> 13 14 #include <arch_helpers.h> 15 #include <drivers/marvell/cache_llc.h> 16 #include <drivers/marvell/ccu.h> 17 #include <lib/mmio.h> 18 19 #include <mvebu_def.h> 20 21 #define CCU_HTC_CR(ap_index) (MVEBU_CCU_BASE(ap_index) + 0x200) 22 #define CCU_SET_POC_OFFSET 5 23 24 extern void ca72_l2_enable_unique_clean(void); 25 26 void llc_cache_sync(int ap_index) 27 { 28 mmio_write_32(LLC_SYNC(ap_index), 0); 29 /* Atomic write, no need to wait */ 30 } 31 32 void llc_flush_all(int ap_index) 33 { 34 mmio_write_32(L2X0_CLEAN_INV_WAY(ap_index), LLC_WAY_MASK); 35 llc_cache_sync(ap_index); 36 } 37 38 void llc_clean_all(int ap_index) 39 { 40 mmio_write_32(L2X0_CLEAN_WAY(ap_index), LLC_WAY_MASK); 41 llc_cache_sync(ap_index); 42 } 43 44 void llc_inv_all(int ap_index) 45 { 46 mmio_write_32(L2X0_INV_WAY(ap_index), LLC_WAY_MASK); 47 llc_cache_sync(ap_index); 48 } 49 50 void llc_disable(int ap_index) 51 { 52 llc_flush_all(ap_index); 53 mmio_write_32(LLC_CTRL(ap_index), 0); 54 dsbishst(); 55 } 56 57 void llc_enable(int ap_index, int excl_mode) 58 { 59 uint32_t val; 60 61 dsbsy(); 62 llc_inv_all(ap_index); 63 dsbsy(); 64 65 val = LLC_CTRL_EN; 66 if (excl_mode) 67 val |= LLC_EXCLUSIVE_EN; 68 69 mmio_write_32(LLC_CTRL(ap_index), val); 70 dsbsy(); 71 } 72 73 int llc_is_exclusive(int ap_index) 74 { 75 uint32_t reg; 76 77 reg = mmio_read_32(LLC_CTRL(ap_index)); 78 79 if ((reg & (LLC_CTRL_EN | LLC_EXCLUSIVE_EN)) == 80 (LLC_CTRL_EN | LLC_EXCLUSIVE_EN)) 81 return 1; 82 83 return 0; 84 } 85 86 void llc_runtime_enable(int ap_index) 87 { 88 uint32_t reg; 89 90 reg = mmio_read_32(LLC_CTRL(ap_index)); 91 if (reg & LLC_CTRL_EN) 92 return; 93 94 INFO("Enabling LLC\n"); 95 96 /* 97 * Enable L2 UniqueClean evictions with data 98 * Note: this configuration assumes that LLC is configured 99 * in exclusive mode. 100 * Later on in the code this assumption will be validated 101 */ 102 ca72_l2_enable_unique_clean(); 103 llc_enable(ap_index, 1); 104 105 /* Set point of coherency to DDR. 106 * This is required by units which have SW cache coherency 107 */ 108 reg = mmio_read_32(CCU_HTC_CR(ap_index)); 109 reg |= (0x1 << CCU_SET_POC_OFFSET); 110 mmio_write_32(CCU_HTC_CR(ap_index), reg); 111 } 112