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