~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/arch/mips/kernel/spram.c

Version: ~ [ linux-6.11-rc3 ] ~ [ linux-6.10.4 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.45 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.104 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.164 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.223 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.281 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.319 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.9 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 // SPDX-License-Identifier: GPL-2.0-or-later
  2 /*
  3  * MIPS SPRAM support
  4  *
  5  * Copyright (C) 2007, 2008 MIPS Technologies, Inc.
  6  */
  7 #include <linux/kernel.h>
  8 #include <linux/ptrace.h>
  9 #include <linux/stddef.h>
 10 
 11 #include <asm/fpu.h>
 12 #include <asm/mipsregs.h>
 13 #include <asm/r4kcache.h>
 14 #include <asm/hazards.h>
 15 #include <asm/spram.h>
 16 
 17 /*
 18  * These definitions are correct for the 24K/34K/74K SPRAM sample
 19  * implementation. The 4KS interpreted the tags differently...
 20  */
 21 #define SPRAM_TAG0_ENABLE       0x00000080
 22 #define SPRAM_TAG0_PA_MASK      0xfffff000
 23 #define SPRAM_TAG1_SIZE_MASK    0xfffff000
 24 
 25 #define SPRAM_TAG_STRIDE        8
 26 
 27 #define ERRCTL_SPRAM            (1 << 28)
 28 
 29 /* errctl access */
 30 #define read_c0_errctl(x) read_c0_ecc(x)
 31 #define write_c0_errctl(x) write_c0_ecc(x)
 32 
 33 /*
 34  * Different semantics to the set_c0_* function built by __BUILD_SET_C0
 35  */
 36 static unsigned int bis_c0_errctl(unsigned int set)
 37 {
 38         unsigned int res;
 39         res = read_c0_errctl();
 40         write_c0_errctl(res | set);
 41         return res;
 42 }
 43 
 44 static void ispram_store_tag(unsigned int offset, unsigned int data)
 45 {
 46         unsigned int errctl;
 47 
 48         /* enable SPRAM tag access */
 49         errctl = bis_c0_errctl(ERRCTL_SPRAM);
 50         ehb();
 51 
 52         write_c0_taglo(data);
 53         ehb();
 54 
 55         cache_op(Index_Store_Tag_I, CKSEG0|offset);
 56         ehb();
 57 
 58         write_c0_errctl(errctl);
 59         ehb();
 60 }
 61 
 62 
 63 static unsigned int ispram_load_tag(unsigned int offset)
 64 {
 65         unsigned int data;
 66         unsigned int errctl;
 67 
 68         /* enable SPRAM tag access */
 69         errctl = bis_c0_errctl(ERRCTL_SPRAM);
 70         ehb();
 71         cache_op(Index_Load_Tag_I, CKSEG0 | offset);
 72         ehb();
 73         data = read_c0_taglo();
 74         ehb();
 75         write_c0_errctl(errctl);
 76         ehb();
 77 
 78         return data;
 79 }
 80 
 81 static void dspram_store_tag(unsigned int offset, unsigned int data)
 82 {
 83         unsigned int errctl;
 84 
 85         /* enable SPRAM tag access */
 86         errctl = bis_c0_errctl(ERRCTL_SPRAM);
 87         ehb();
 88         write_c0_dtaglo(data);
 89         ehb();
 90         cache_op(Index_Store_Tag_D, CKSEG0 | offset);
 91         ehb();
 92         write_c0_errctl(errctl);
 93         ehb();
 94 }
 95 
 96 
 97 static unsigned int dspram_load_tag(unsigned int offset)
 98 {
 99         unsigned int data;
100         unsigned int errctl;
101 
102         errctl = bis_c0_errctl(ERRCTL_SPRAM);
103         ehb();
104         cache_op(Index_Load_Tag_D, CKSEG0 | offset);
105         ehb();
106         data = read_c0_dtaglo();
107         ehb();
108         write_c0_errctl(errctl);
109         ehb();
110 
111         return data;
112 }
113 
114 static void probe_spram(char *type,
115             unsigned int base,
116             unsigned int (*read)(unsigned int),
117             void (*write)(unsigned int, unsigned int))
118 {
119         unsigned int firstsize = 0, lastsize = 0;
120         unsigned int firstpa = 0, lastpa = 0, pa = 0;
121         unsigned int offset = 0;
122         unsigned int size, tag0, tag1;
123         unsigned int enabled;
124         int i;
125 
126         /*
127          * The limit is arbitrary but avoids the loop running away if
128          * the SPRAM tags are implemented differently
129          */
130 
131         for (i = 0; i < 8; i++) {
132                 tag0 = read(offset);
133                 tag1 = read(offset+SPRAM_TAG_STRIDE);
134                 pr_debug("DBG %s%d: tag0=%08x tag1=%08x\n",
135                          type, i, tag0, tag1);
136 
137                 size = tag1 & SPRAM_TAG1_SIZE_MASK;
138 
139                 if (size == 0)
140                         break;
141 
142                 if (i != 0) {
143                         /* tags may repeat... */
144                         if ((pa == firstpa && size == firstsize) ||
145                             (pa == lastpa && size == lastsize))
146                                 break;
147                 }
148 
149                 /* Align base with size */
150                 base = (base + size - 1) & ~(size-1);
151 
152                 /* reprogram the base address base address and enable */
153                 tag0 = (base & SPRAM_TAG0_PA_MASK) | SPRAM_TAG0_ENABLE;
154                 write(offset, tag0);
155 
156                 base += size;
157 
158                 /* reread the tag */
159                 tag0 = read(offset);
160                 pa = tag0 & SPRAM_TAG0_PA_MASK;
161                 enabled = tag0 & SPRAM_TAG0_ENABLE;
162 
163                 if (i == 0) {
164                         firstpa = pa;
165                         firstsize = size;
166                 }
167 
168                 lastpa = pa;
169                 lastsize = size;
170 
171                 if (strcmp(type, "DSPRAM") == 0) {
172                         unsigned int *vp = (unsigned int *)(CKSEG1 | pa);
173                         unsigned int v;
174 #define TDAT    0x5a5aa5a5
175                         vp[0] = TDAT;
176                         vp[1] = ~TDAT;
177 
178                         mb();
179 
180                         v = vp[0];
181                         if (v != TDAT)
182                                 printk(KERN_ERR "vp=%p wrote=%08x got=%08x\n",
183                                        vp, TDAT, v);
184                         v = vp[1];
185                         if (v != ~TDAT)
186                                 printk(KERN_ERR "vp=%p wrote=%08x got=%08x\n",
187                                        vp+1, ~TDAT, v);
188                 }
189 
190                 pr_info("%s%d: PA=%08x,Size=%08x%s\n",
191                         type, i, pa, size, enabled ? ",enabled" : "");
192                 offset += 2 * SPRAM_TAG_STRIDE;
193         }
194 }
195 void spram_config(void)
196 {
197         unsigned int config0;
198 
199         switch (current_cpu_type()) {
200         case CPU_24K:
201         case CPU_34K:
202         case CPU_74K:
203         case CPU_1004K:
204         case CPU_1074K:
205         case CPU_INTERAPTIV:
206         case CPU_PROAPTIV:
207         case CPU_P5600:
208         case CPU_QEMU_GENERIC:
209         case CPU_I6400:
210         case CPU_P6600:
211                 config0 = read_c0_config();
212                 /* FIXME: addresses are Malta specific */
213                 if (config0 & MIPS_CONF_ISP) {
214                         probe_spram("ISPRAM", 0x1c000000,
215                                     &ispram_load_tag, &ispram_store_tag);
216                 }
217                 if (config0 & MIPS_CONF_DSP)
218                         probe_spram("DSPRAM", 0x1c100000,
219                                     &dspram_load_tag, &dspram_store_tag);
220         }
221 }
222 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php