1// SPDX-License-Identifier: GPL-2.0 2/* 3 * Copyright (C) 2021 SiFive 4 */ 5 6#include <cache.h> 7#include <dm.h> 8#include <asm/io.h> 9#include <dm/device.h> 10#include <linux/bitfield.h> 11 12#define SIFIVE_CCACHE_CONFIG 0x000 13#define SIFIVE_CCACHE_CONFIG_WAYS GENMASK(15, 8) 14 15#define SIFIVE_CCACHE_WAY_ENABLE 0x008 16 17struct sifive_ccache { 18 void __iomem *base; 19}; 20 21static int sifive_ccache_enable(struct udevice *dev) 22{ 23 struct sifive_ccache *priv = dev_get_priv(dev); 24 u32 config; 25 u32 ways; 26 27 /* Enable all ways of composable cache */ 28 config = readl(priv->base + SIFIVE_CCACHE_CONFIG); 29 ways = FIELD_GET(SIFIVE_CCACHE_CONFIG_WAYS, config); 30 31 writel(ways - 1, priv->base + SIFIVE_CCACHE_WAY_ENABLE); 32 33 return 0; 34} 35 36static int sifive_ccache_get_info(struct udevice *dev, struct cache_info *info) 37{ 38 struct sifive_ccache *priv = dev_get_priv(dev); 39 40 info->base = (uintptr_t)priv->base; 41 42 return 0; 43} 44 45static const struct cache_ops sifive_ccache_ops = { 46 .enable = sifive_ccache_enable, 47 .get_info = sifive_ccache_get_info, 48}; 49 50static int sifive_ccache_probe(struct udevice *dev) 51{ 52 struct sifive_ccache *priv = dev_get_priv(dev); 53 54 priv->base = dev_read_addr_ptr(dev); 55 if (!priv->base) 56 return -EINVAL; 57 58 return 0; 59} 60 61static const struct udevice_id sifive_ccache_ids[] = { 62 { .compatible = "sifive,fu540-c000-ccache" }, 63 { .compatible = "sifive,fu740-c000-ccache" }, 64 { .compatible = "sifive,ccache0" }, 65 {} 66}; 67 68U_BOOT_DRIVER(sifive_ccache) = { 69 .name = "sifive_ccache", 70 .id = UCLASS_CACHE, 71 .of_match = sifive_ccache_ids, 72 .probe = sifive_ccache_probe, 73 .priv_auto = sizeof(struct sifive_ccache), 74 .ops = &sifive_ccache_ops, 75}; 76