diff --git a/drivers/marvell/cache_llc.c b/drivers/marvell/cache_llc.c new file mode 100644 index 0000000..e13e6ce --- /dev/null +++ b/drivers/marvell/cache_llc.c @@ -0,0 +1,109 @@ +/* + * Copyright (C) 2018 Marvell International Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + * https://spdx.org/licenses + */ + +/* LLC driver is the Last Level Cache (L3C) driver + * for Marvell SoCs in AP806, AP807, and AP810 + */ + +#include +#include +#include +#include +#include +#include + +#define CCU_HTC_CR(ap_index) (MVEBU_CCU_BASE(ap_index) + 0x200) +#define CCU_SET_POC_OFFSET 5 + +extern void ca72_l2_enable_unique_clean(void); + +void llc_cache_sync(int ap_index) +{ + mmio_write_32(LLC_SYNC(ap_index), 0); + /* Atomic write, no need to wait */ +} + +void llc_flush_all(int ap_index) +{ + mmio_write_32(L2X0_CLEAN_INV_WAY(ap_index), LLC_WAY_MASK); + llc_cache_sync(ap_index); +} + +void llc_clean_all(int ap_index) +{ + mmio_write_32(L2X0_CLEAN_WAY(ap_index), LLC_WAY_MASK); + llc_cache_sync(ap_index); +} + +void llc_inv_all(int ap_index) +{ + mmio_write_32(L2X0_INV_WAY(ap_index), LLC_WAY_MASK); + llc_cache_sync(ap_index); +} + +void llc_disable(int ap_index) +{ + llc_flush_all(ap_index); + mmio_write_32(LLC_CTRL(ap_index), 0); + dsbishst(); +} + +void llc_enable(int ap_index, int excl_mode) +{ + uint32_t val; + + dsbsy(); + llc_inv_all(ap_index); + dsbsy(); + + val = LLC_CTRL_EN; + if (excl_mode) + val |= LLC_EXCLUSIVE_EN; + + mmio_write_32(LLC_CTRL(ap_index), val); + dsbsy(); +} + +int llc_is_exclusive(int ap_index) +{ + uint32_t reg; + + reg = mmio_read_32(LLC_CTRL(ap_index)); + + if ((reg & (LLC_CTRL_EN | LLC_EXCLUSIVE_EN)) == + (LLC_CTRL_EN | LLC_EXCLUSIVE_EN)) + return 1; + + return 0; +} + +void llc_runtime_enable(int ap_index) +{ + uint32_t reg; + + reg = mmio_read_32(LLC_CTRL(ap_index)); + if (reg & LLC_CTRL_EN) + return; + + INFO("Enabling LLC\n"); + + /* + * Enable L2 UniqueClean evictions with data + * Note: this configuration assumes that LLC is configured + * in exclusive mode. + * Later on in the code this assumption will be validated + */ + ca72_l2_enable_unique_clean(); + llc_enable(ap_index, 1); + + /* Set point of coherency to DDR. + * This is required by units which have SW cache coherency + */ + reg = mmio_read_32(CCU_HTC_CR(ap_index)); + reg |= (0x1 << CCU_SET_POC_OFFSET); + mmio_write_32(CCU_HTC_CR(ap_index), reg); +} diff --git a/include/drivers/marvell/cache_llc.h b/include/drivers/marvell/cache_llc.h new file mode 100644 index 0000000..9e41793 --- /dev/null +++ b/include/drivers/marvell/cache_llc.h @@ -0,0 +1,42 @@ +/* + * Copyright (C) 2018 Marvell International Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + * https://spdx.org/licenses + */ + +/* LLC driver is the Last Level Cache (L3C) driver + * for Marvell SoCs in AP806, AP807, and AP810 + */ + +#ifndef _CACHE_LLC_H_ +#define _CACHE_LLC_H_ + +#define LLC_CTRL(ap) (MVEBU_LLC_BASE(ap) + 0x100) +#define LLC_SYNC(ap) (MVEBU_LLC_BASE(ap) + 0x700) +#define L2X0_INV_WAY(ap) (MVEBU_LLC_BASE(ap) + 0x77C) +#define L2X0_CLEAN_WAY(ap) (MVEBU_LLC_BASE(ap) + 0x7BC) +#define L2X0_CLEAN_INV_WAY(ap) (MVEBU_LLC_BASE(ap) + 0x7FC) +#define LLC_TC0_LOCK(ap) (MVEBU_LLC_BASE(ap) + 0x920) + +#define MASTER_LLC_CTRL LLC_CTRL(MVEBU_AP0) +#define MASTER_L2X0_INV_WAY L2X0_INV_WAY(MVEBU_AP0) +#define MASTER_LLC_TC0_LOCK LLC_TC0_LOCK(MVEBU_AP0) + +#define LLC_CTRL_EN 1 +#define LLC_EXCLUSIVE_EN 0x100 +#define LLC_WAY_MASK 0xFFFFFFFF + +#ifndef __ASSEMBLY__ +void llc_cache_sync(int ap_index); +void llc_flush_all(int ap_index); +void llc_clean_all(int ap_index); +void llc_inv_all(int ap_index); +void llc_disable(int ap_index); +void llc_enable(int ap_index, int excl_mode); +int llc_is_exclusive(int ap_index); +void llc_runtime_enable(int ap_index); +#endif + +#endif /* _CACHE_LLC_H_ */ +