1ee5b26fdSAndre Przywara /* 2ee5b26fdSAndre Przywara * Copyright (c) 2024, ARM Limited. All rights reserved. 3ee5b26fdSAndre Przywara * 4ee5b26fdSAndre Przywara * SPDX-License-Identifier: BSD-3-Clause 5ee5b26fdSAndre Przywara * 6ee5b26fdSAndre Przywara * Amend the device tree to adjust the L2 cache size, which is different 7ee5b26fdSAndre Przywara * between the revisions of the H616 chips: earlier versions have 256 KB of L2, 8ee5b26fdSAndre Przywara * later versions 1 MB. 9ee5b26fdSAndre Przywara * Read the cache ID registers and adjust the size and number of sets entries 10ee5b26fdSAndre Przywara * in the L2 cache DT node. 11ee5b26fdSAndre Przywara */ 12ee5b26fdSAndre Przywara 13ee5b26fdSAndre Przywara #include <common/fdt_wrappers.h> 14ee5b26fdSAndre Przywara #include <lib/utils_def.h> 15ee5b26fdSAndre Przywara #include <libfdt.h> 16ee5b26fdSAndre Przywara 17ee5b26fdSAndre Przywara #define CACHE_L1D 0x0 18ee5b26fdSAndre Przywara #define CACHE_L1I 0x1 19ee5b26fdSAndre Przywara #define CACHE_L2U 0x2 20ee5b26fdSAndre Przywara 21ee5b26fdSAndre Przywara #define CCSIDR_SETS_SHIFT 13 22ee5b26fdSAndre Przywara #define CCSIDR_SETS_MASK GENMASK(14, 0) 23ee5b26fdSAndre Przywara #define CCSIDR_ASSOC_SHIFT 3 24ee5b26fdSAndre Przywara #define CCSIDR_ASSOC_MASK GENMASK(9, 0) 25ee5b26fdSAndre Przywara #define CCSIDR_LSIZE_SHIFT 0 26ee5b26fdSAndre Przywara #define CCSIDR_LSIZE_MASK GENMASK(2, 0) 27ee5b26fdSAndre Przywara 28ee5b26fdSAndre Przywara static uint32_t armv8_get_ccsidr(unsigned int sel) 29ee5b26fdSAndre Przywara { 30ee5b26fdSAndre Przywara uint32_t reg; 31ee5b26fdSAndre Przywara 32ee5b26fdSAndre Przywara __asm__ volatile ("msr CSSELR_EL1, %0\n" :: "r" (sel)); 33ee5b26fdSAndre Przywara __asm__ volatile ("mrs %0, CCSIDR_EL1\n" : "=r" (reg)); 34ee5b26fdSAndre Przywara 35ee5b26fdSAndre Przywara return reg; 36ee5b26fdSAndre Przywara } 37ee5b26fdSAndre Przywara 38ee5b26fdSAndre Przywara void sunxi_soc_fdt_fixup(void *dtb) 39ee5b26fdSAndre Przywara { 40ee5b26fdSAndre Przywara int node = fdt_path_offset(dtb, "/cpus/cpu@0"); 41ee5b26fdSAndre Przywara uint32_t phandle, ccsidr, cell; 42ee5b26fdSAndre Przywara int sets, line_size, assoc; 43ee5b26fdSAndre Przywara int ret; 44ee5b26fdSAndre Przywara 45ee5b26fdSAndre Przywara if (node < 0) { 46ee5b26fdSAndre Przywara return; 47ee5b26fdSAndre Przywara } 48ee5b26fdSAndre Przywara 49ee5b26fdSAndre Przywara ret = fdt_read_uint32(dtb, node, "next-level-cache", &phandle); 50ee5b26fdSAndre Przywara if (ret != 0) { 51ee5b26fdSAndre Przywara return; 52ee5b26fdSAndre Przywara } 53ee5b26fdSAndre Przywara 54ee5b26fdSAndre Przywara node = fdt_node_offset_by_phandle(dtb, phandle); 55*7300a4d1SAndre Przywara if (node < 0) { 56ee5b26fdSAndre Przywara return; 57ee5b26fdSAndre Przywara } 58ee5b26fdSAndre Przywara 59ee5b26fdSAndre Przywara ccsidr = armv8_get_ccsidr(CACHE_L2U); 60ee5b26fdSAndre Przywara sets = ((ccsidr >> CCSIDR_SETS_SHIFT) & CCSIDR_SETS_MASK) + 1; 61ee5b26fdSAndre Przywara line_size = 16U << ((ccsidr >> CCSIDR_LSIZE_SHIFT) & CCSIDR_LSIZE_MASK); 62ee5b26fdSAndre Przywara assoc = ((ccsidr >> CCSIDR_ASSOC_SHIFT) & CCSIDR_ASSOC_MASK) + 1; 63ee5b26fdSAndre Przywara 64ee5b26fdSAndre Przywara cell = cpu_to_fdt32(sets); 65ee5b26fdSAndre Przywara fdt_setprop(dtb, node, "cache-sets", &cell, sizeof(cell)); 66ee5b26fdSAndre Przywara 67ee5b26fdSAndre Przywara cell = cpu_to_fdt32(line_size); 68ee5b26fdSAndre Przywara fdt_setprop(dtb, node, "cache-line-size", &cell, sizeof(cell)); 69ee5b26fdSAndre Przywara 70ee5b26fdSAndre Przywara cell = cpu_to_fdt32(sets * assoc * line_size); 71ee5b26fdSAndre Przywara fdt_setprop(dtb, node, "cache-size", &cell, sizeof(cell)); 72ee5b26fdSAndre Przywara } 73