Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3)  * Copyright (C) 1997, 2001 Ralf Baechle (ralf@gnu.org),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4)  * derived from r4xx0.c by David S. Miller (davem@davemloft.net).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8) #include <linux/sched.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9) #include <linux/mm.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11) #include <asm/mipsregs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12) #include <asm/bcache.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13) #include <asm/cacheops.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14) #include <asm/page.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15) #include <asm/mmu_context.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16) #include <asm/r4kcache.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) /* Secondary cache size in bytes, if present.  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) static unsigned long scache_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21) #define SC_LINE 32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22) #define SC_PAGE (128*SC_LINE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) static inline void blast_r5000_scache(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) 	unsigned long start = INDEX_BASE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) 	unsigned long end = start + scache_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) 	while(start < end) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) 		cache_op(R5K_Page_Invalidate_S, start);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) 		start += SC_PAGE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) static void r5k_dma_cache_inv_sc(unsigned long addr, unsigned long size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) 	unsigned long end, a;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) 	/* Catch bad driver code */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) 	BUG_ON(size == 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) 	if (size >= scache_size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) 		blast_r5000_scache();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) 	/* On the R5000 secondary cache we cannot
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) 	 * invalidate less than a page at a time.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) 	 * The secondary cache is physically indexed, write-through.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) 	a = addr & ~(SC_PAGE - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) 	end = (addr + size - 1) & ~(SC_PAGE - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) 	while (a <= end) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) 		cache_op(R5K_Page_Invalidate_S, a);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) 		a += SC_PAGE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) static void r5k_sc_enable(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) 	unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) 	local_irq_save(flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) 	set_c0_config(R5K_CONF_SE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) 	blast_r5000_scache();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) 	local_irq_restore(flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) static void r5k_sc_disable(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) 	unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) 	local_irq_save(flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) 	blast_r5000_scache();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) 	clear_c0_config(R5K_CONF_SE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) 	local_irq_restore(flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) static inline int __init r5k_sc_probe(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) 	unsigned long config = read_c0_config();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) 	if (config & CONF_SC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) 	scache_size = (512 * 1024) << ((config & R5K_CONF_SS) >> 20);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) 	printk("R5000 SCACHE size %ldkB, linesize 32 bytes.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) 			scache_size >> 10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) 	return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) static struct bcache_ops r5k_sc_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) 	.bc_enable = r5k_sc_enable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) 	.bc_disable = r5k_sc_disable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) 	.bc_wback_inv = r5k_dma_cache_inv_sc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) 	.bc_inv = r5k_dma_cache_inv_sc
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) void r5k_sc_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) 	if (r5k_sc_probe()) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) 		r5k_sc_enable();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) 		bcops = &r5k_sc_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) }