xref: /linux/arch/openrisc/kernel/cacheinfo.c (revision ec0c2d5359e2f288d75d98465829d31c6d26da47)
1*4e6d24a3SSahil Siddiq // SPDX-License-Identifier: GPL-2.0-or-later
2*4e6d24a3SSahil Siddiq /*
3*4e6d24a3SSahil Siddiq  * OpenRISC cacheinfo support
4*4e6d24a3SSahil Siddiq  *
5*4e6d24a3SSahil Siddiq  * Based on work done for MIPS and LoongArch. All original copyrights
6*4e6d24a3SSahil Siddiq  * apply as per the original source declaration.
7*4e6d24a3SSahil Siddiq  *
8*4e6d24a3SSahil Siddiq  * OpenRISC implementation:
9*4e6d24a3SSahil Siddiq  * Copyright (C) 2025 Sahil Siddiq <sahilcdq@proton.me>
10*4e6d24a3SSahil Siddiq  */
11*4e6d24a3SSahil Siddiq 
12*4e6d24a3SSahil Siddiq #include <linux/cacheinfo.h>
13*4e6d24a3SSahil Siddiq #include <asm/cpuinfo.h>
14*4e6d24a3SSahil Siddiq #include <asm/spr.h>
15*4e6d24a3SSahil Siddiq #include <asm/spr_defs.h>
16*4e6d24a3SSahil Siddiq 
ci_leaf_init(struct cacheinfo * this_leaf,enum cache_type type,unsigned int level,struct cache_desc * cache,int cpu)17*4e6d24a3SSahil Siddiq static inline void ci_leaf_init(struct cacheinfo *this_leaf, enum cache_type type,
18*4e6d24a3SSahil Siddiq 				unsigned int level, struct cache_desc *cache, int cpu)
19*4e6d24a3SSahil Siddiq {
20*4e6d24a3SSahil Siddiq 	this_leaf->type = type;
21*4e6d24a3SSahil Siddiq 	this_leaf->level = level;
22*4e6d24a3SSahil Siddiq 	this_leaf->coherency_line_size = cache->block_size;
23*4e6d24a3SSahil Siddiq 	this_leaf->number_of_sets = cache->sets;
24*4e6d24a3SSahil Siddiq 	this_leaf->ways_of_associativity = cache->ways;
25*4e6d24a3SSahil Siddiq 	this_leaf->size = cache->size;
26*4e6d24a3SSahil Siddiq 	cpumask_set_cpu(cpu, &this_leaf->shared_cpu_map);
27*4e6d24a3SSahil Siddiq }
28*4e6d24a3SSahil Siddiq 
init_cache_level(unsigned int cpu)29*4e6d24a3SSahil Siddiq int init_cache_level(unsigned int cpu)
30*4e6d24a3SSahil Siddiq {
31*4e6d24a3SSahil Siddiq 	struct cpuinfo_or1k *cpuinfo = &cpuinfo_or1k[smp_processor_id()];
32*4e6d24a3SSahil Siddiq 	struct cpu_cacheinfo *this_cpu_ci = get_cpu_cacheinfo(cpu);
33*4e6d24a3SSahil Siddiq 	int leaves = 0, levels = 0;
34*4e6d24a3SSahil Siddiq 	unsigned long upr = mfspr(SPR_UPR);
35*4e6d24a3SSahil Siddiq 	unsigned long iccfgr, dccfgr;
36*4e6d24a3SSahil Siddiq 
37*4e6d24a3SSahil Siddiq 	if (!(upr & SPR_UPR_UP)) {
38*4e6d24a3SSahil Siddiq 		printk(KERN_INFO
39*4e6d24a3SSahil Siddiq 		       "-- no UPR register... unable to detect configuration\n");
40*4e6d24a3SSahil Siddiq 		return -ENOENT;
41*4e6d24a3SSahil Siddiq 	}
42*4e6d24a3SSahil Siddiq 
43*4e6d24a3SSahil Siddiq 	if (cpu_cache_is_present(SPR_UPR_DCP)) {
44*4e6d24a3SSahil Siddiq 		dccfgr = mfspr(SPR_DCCFGR);
45*4e6d24a3SSahil Siddiq 		cpuinfo->dcache.ways = 1 << (dccfgr & SPR_DCCFGR_NCW);
46*4e6d24a3SSahil Siddiq 		cpuinfo->dcache.sets = 1 << ((dccfgr & SPR_DCCFGR_NCS) >> 3);
47*4e6d24a3SSahil Siddiq 		cpuinfo->dcache.block_size = 16 << ((dccfgr & SPR_DCCFGR_CBS) >> 7);
48*4e6d24a3SSahil Siddiq 		cpuinfo->dcache.size =
49*4e6d24a3SSahil Siddiq 		    cpuinfo->dcache.sets * cpuinfo->dcache.ways * cpuinfo->dcache.block_size;
50*4e6d24a3SSahil Siddiq 		leaves += 1;
51*4e6d24a3SSahil Siddiq 		printk(KERN_INFO
52*4e6d24a3SSahil Siddiq 		       "-- dcache: %d bytes total, %d bytes/line, %d set(s), %d way(s)\n",
53*4e6d24a3SSahil Siddiq 		       cpuinfo->dcache.size, cpuinfo->dcache.block_size,
54*4e6d24a3SSahil Siddiq 		       cpuinfo->dcache.sets, cpuinfo->dcache.ways);
55*4e6d24a3SSahil Siddiq 	} else
56*4e6d24a3SSahil Siddiq 		printk(KERN_INFO "-- dcache disabled\n");
57*4e6d24a3SSahil Siddiq 
58*4e6d24a3SSahil Siddiq 	if (cpu_cache_is_present(SPR_UPR_ICP)) {
59*4e6d24a3SSahil Siddiq 		iccfgr = mfspr(SPR_ICCFGR);
60*4e6d24a3SSahil Siddiq 		cpuinfo->icache.ways = 1 << (iccfgr & SPR_ICCFGR_NCW);
61*4e6d24a3SSahil Siddiq 		cpuinfo->icache.sets = 1 << ((iccfgr & SPR_ICCFGR_NCS) >> 3);
62*4e6d24a3SSahil Siddiq 		cpuinfo->icache.block_size = 16 << ((iccfgr & SPR_ICCFGR_CBS) >> 7);
63*4e6d24a3SSahil Siddiq 		cpuinfo->icache.size =
64*4e6d24a3SSahil Siddiq 		    cpuinfo->icache.sets * cpuinfo->icache.ways * cpuinfo->icache.block_size;
65*4e6d24a3SSahil Siddiq 		leaves += 1;
66*4e6d24a3SSahil Siddiq 		printk(KERN_INFO
67*4e6d24a3SSahil Siddiq 		       "-- icache: %d bytes total, %d bytes/line, %d set(s), %d way(s)\n",
68*4e6d24a3SSahil Siddiq 		       cpuinfo->icache.size, cpuinfo->icache.block_size,
69*4e6d24a3SSahil Siddiq 		       cpuinfo->icache.sets, cpuinfo->icache.ways);
70*4e6d24a3SSahil Siddiq 	} else
71*4e6d24a3SSahil Siddiq 		printk(KERN_INFO "-- icache disabled\n");
72*4e6d24a3SSahil Siddiq 
73*4e6d24a3SSahil Siddiq 	if (!leaves)
74*4e6d24a3SSahil Siddiq 		return -ENOENT;
75*4e6d24a3SSahil Siddiq 
76*4e6d24a3SSahil Siddiq 	levels = 1;
77*4e6d24a3SSahil Siddiq 
78*4e6d24a3SSahil Siddiq 	this_cpu_ci->num_leaves = leaves;
79*4e6d24a3SSahil Siddiq 	this_cpu_ci->num_levels = levels;
80*4e6d24a3SSahil Siddiq 
81*4e6d24a3SSahil Siddiq 	return 0;
82*4e6d24a3SSahil Siddiq }
83*4e6d24a3SSahil Siddiq 
populate_cache_leaves(unsigned int cpu)84*4e6d24a3SSahil Siddiq int populate_cache_leaves(unsigned int cpu)
85*4e6d24a3SSahil Siddiq {
86*4e6d24a3SSahil Siddiq 	struct cpuinfo_or1k *cpuinfo = &cpuinfo_or1k[smp_processor_id()];
87*4e6d24a3SSahil Siddiq 	struct cpu_cacheinfo *this_cpu_ci = get_cpu_cacheinfo(cpu);
88*4e6d24a3SSahil Siddiq 	struct cacheinfo *this_leaf = this_cpu_ci->info_list;
89*4e6d24a3SSahil Siddiq 	int level = 1;
90*4e6d24a3SSahil Siddiq 
91*4e6d24a3SSahil Siddiq 	if (cpu_cache_is_present(SPR_UPR_DCP)) {
92*4e6d24a3SSahil Siddiq 		ci_leaf_init(this_leaf, CACHE_TYPE_DATA, level, &cpuinfo->dcache, cpu);
93*4e6d24a3SSahil Siddiq 		this_leaf->attributes = ((mfspr(SPR_DCCFGR) & SPR_DCCFGR_CWS) >> 8) ?
94*4e6d24a3SSahil Siddiq 					CACHE_WRITE_BACK : CACHE_WRITE_THROUGH;
95*4e6d24a3SSahil Siddiq 		this_leaf++;
96*4e6d24a3SSahil Siddiq 	}
97*4e6d24a3SSahil Siddiq 
98*4e6d24a3SSahil Siddiq 	if (cpu_cache_is_present(SPR_UPR_ICP))
99*4e6d24a3SSahil Siddiq 		ci_leaf_init(this_leaf, CACHE_TYPE_INST, level, &cpuinfo->icache, cpu);
100*4e6d24a3SSahil Siddiq 
101*4e6d24a3SSahil Siddiq 	this_cpu_ci->cpu_map_populated = true;
102*4e6d24a3SSahil Siddiq 
103*4e6d24a3SSahil Siddiq 	return 0;
104*4e6d24a3SSahil Siddiq }
105