blob: 24f802beffb951ef407a65377ba0f86f2331f1da [file] [log] [blame]
Konrad Eisele5213a782009-08-17 00:13:29 +00001/*
2 * Copyright (C) 2004 Konrad Eisele (eiselekd@web.de,konrad@gaisler.com) Gaisler Research
3 * Copyright (C) 2004 Stefan Holst (mail@s-holst.de) Uni-Stuttgart
4 * Copyright (C) 2009 Daniel Hellstrom (daniel@gaisler.com) Aeroflex Gaisler AB
5 * Copyright (C) 2009 Konrad Eisele (konrad@gaisler.com) Aeroflex Gaisler AB
6 */
7
8#ifndef LEON_H_INCLUDE
9#define LEON_H_INCLUDE
10
11#ifdef CONFIG_SPARC_LEON
12
Konrad Eisele5213a782009-08-17 00:13:29 +000013/* mmu register access, ASI_LEON_MMUREGS */
14#define LEON_CNR_CTRL 0x000
15#define LEON_CNR_CTXP 0x100
16#define LEON_CNR_CTX 0x200
17#define LEON_CNR_F 0x300
18#define LEON_CNR_FADDR 0x400
19
20#define LEON_CNR_CTX_NCTX 256 /*number of MMU ctx */
21
22#define LEON_CNR_CTRL_TLBDIS 0x80000000
23
24#define LEON_MMUTLB_ENT_MAX 64
25
26/*
27 * diagnostic access from mmutlb.vhd:
28 * 0: pte address
29 * 4: pte
30 * 8: additional flags
31 */
32#define LEON_DIAGF_LVL 0x3
33#define LEON_DIAGF_WR 0x8
34#define LEON_DIAGF_WR_SHIFT 3
35#define LEON_DIAGF_HIT 0x10
36#define LEON_DIAGF_HIT_SHIFT 4
37#define LEON_DIAGF_CTX 0x1fe0
38#define LEON_DIAGF_CTX_SHIFT 5
39#define LEON_DIAGF_VALID 0x2000
40#define LEON_DIAGF_VALID_SHIFT 13
41
Konrad Eisele5213a782009-08-17 00:13:29 +000042/* irq masks */
43#define LEON_HARD_INT(x) (1 << (x)) /* irq 0-15 */
44#define LEON_IRQMASK_R 0x0000fffe /* bit 15- 1 of lregs.irqmask */
45#define LEON_IRQPRIO_R 0xfffe0000 /* bit 31-17 of lregs.irqmask */
46
Konrad Eisele5213a782009-08-17 00:13:29 +000047#define LEON_MCFG2_SRAMDIS 0x00002000
48#define LEON_MCFG2_SDRAMEN 0x00004000
49#define LEON_MCFG2_SRAMBANKSZ 0x00001e00 /* [12-9] */
50#define LEON_MCFG2_SRAMBANKSZ_SHIFT 9
51#define LEON_MCFG2_SDRAMBANKSZ 0x03800000 /* [25-23] */
52#define LEON_MCFG2_SDRAMBANKSZ_SHIFT 23
53
54#define LEON_TCNT0_MASK 0x7fffff
55
Konrad Eisele5213a782009-08-17 00:13:29 +000056
57#define ASI_LEON3_SYSCTRL 0x02
58#define ASI_LEON3_SYSCTRL_ICFG 0x08
59#define ASI_LEON3_SYSCTRL_DCFG 0x0c
60#define ASI_LEON3_SYSCTRL_CFG_SNOOPING (1 << 27)
61#define ASI_LEON3_SYSCTRL_CFG_SSIZE(c) (1 << ((c >> 20) & 0xf))
62
63#ifndef __ASSEMBLY__
64
65/* do a virtual address read without cache */
66static inline unsigned long leon_readnobuffer_reg(unsigned long paddr)
67{
68 unsigned long retval;
69 __asm__ __volatile__("lda [%1] %2, %0\n\t" :
70 "=r"(retval) : "r"(paddr), "i"(ASI_LEON_NOCACHE));
71 return retval;
72}
73
74/* do a physical address bypass write, i.e. for 0x80000000 */
75static inline void leon_store_reg(unsigned long paddr, unsigned long value)
76{
77 __asm__ __volatile__("sta %0, [%1] %2\n\t" : : "r"(value), "r"(paddr),
78 "i"(ASI_LEON_BYPASS) : "memory");
79}
80
81/* do a physical address bypass load, i.e. for 0x80000000 */
82static inline unsigned long leon_load_reg(unsigned long paddr)
83{
84 unsigned long retval;
85 __asm__ __volatile__("lda [%1] %2, %0\n\t" :
86 "=r"(retval) : "r"(paddr), "i"(ASI_LEON_BYPASS));
87 return retval;
88}
89
Kristoffer Glembo4309e562009-11-15 23:51:06 +000090static inline void leon_srmmu_disabletlb(void)
Konrad Eisele5213a782009-08-17 00:13:29 +000091{
92 unsigned int retval;
93 __asm__ __volatile__("lda [%%g0] %2, %0\n\t" : "=r"(retval) : "r"(0),
94 "i"(ASI_LEON_MMUREGS));
95 retval |= LEON_CNR_CTRL_TLBDIS;
96 __asm__ __volatile__("sta %0, [%%g0] %2\n\t" : : "r"(retval), "r"(0),
97 "i"(ASI_LEON_MMUREGS) : "memory");
98}
99
Kristoffer Glembo4309e562009-11-15 23:51:06 +0000100static inline void leon_srmmu_enabletlb(void)
Konrad Eisele5213a782009-08-17 00:13:29 +0000101{
102 unsigned int retval;
103 __asm__ __volatile__("lda [%%g0] %2, %0\n\t" : "=r"(retval) : "r"(0),
104 "i"(ASI_LEON_MMUREGS));
105 retval = retval & ~LEON_CNR_CTRL_TLBDIS;
106 __asm__ __volatile__("sta %0, [%%g0] %2\n\t" : : "r"(retval), "r"(0),
107 "i"(ASI_LEON_MMUREGS) : "memory");
108}
109
110/* macro access for leon_load_reg() and leon_store_reg() */
111#define LEON3_BYPASS_LOAD_PA(x) (leon_load_reg((unsigned long)(x)))
112#define LEON3_BYPASS_STORE_PA(x, v) (leon_store_reg((unsigned long)(x), (unsigned long)(v)))
113#define LEON3_BYPASS_ANDIN_PA(x, v) LEON3_BYPASS_STORE_PA(x, LEON3_BYPASS_LOAD_PA(x) & v)
114#define LEON3_BYPASS_ORIN_PA(x, v) LEON3_BYPASS_STORE_PA(x, LEON3_BYPASS_LOAD_PA(x) | v)
115#define LEON_BYPASS_LOAD_PA(x) leon_load_reg((unsigned long)(x))
116#define LEON_BYPASS_STORE_PA(x, v) leon_store_reg((unsigned long)(x), (unsigned long)(v))
117#define LEON_REGLOAD_PA(x) leon_load_reg((unsigned long)(x)+LEON_PREGS)
118#define LEON_REGSTORE_PA(x, v) leon_store_reg((unsigned long)(x)+LEON_PREGS, (unsigned long)(v))
119#define LEON_REGSTORE_OR_PA(x, v) LEON_REGSTORE_PA(x, LEON_REGLOAD_PA(x) | (unsigned long)(v))
120#define LEON_REGSTORE_AND_PA(x, v) LEON_REGSTORE_PA(x, LEON_REGLOAD_PA(x) & (unsigned long)(v))
121
122/* macro access for leon_readnobuffer_reg() */
123#define LEON_BYPASSCACHE_LOAD_VA(x) leon_readnobuffer_reg((unsigned long)(x))
124
Konrad Eisele5213a782009-08-17 00:13:29 +0000125extern void leon_init(void);
126extern void leon_switch_mm(void);
127extern void leon_init_IRQ(void);
128
129extern unsigned long last_valid_pfn;
130
Kristoffer Glembo4309e562009-11-15 23:51:06 +0000131static inline unsigned long sparc_leon3_get_dcachecfg(void)
Konrad Eisele5213a782009-08-17 00:13:29 +0000132{
133 unsigned int retval;
134 __asm__ __volatile__("lda [%1] %2, %0\n\t" :
135 "=r"(retval) :
136 "r"(ASI_LEON3_SYSCTRL_DCFG),
137 "i"(ASI_LEON3_SYSCTRL));
138 return retval;
139}
140
141/* enable snooping */
Kristoffer Glembo4309e562009-11-15 23:51:06 +0000142static inline void sparc_leon3_enable_snooping(void)
Konrad Eisele5213a782009-08-17 00:13:29 +0000143{
144 __asm__ __volatile__ ("lda [%%g0] 2, %%l1\n\t"
145 "set 0x800000, %%l2\n\t"
146 "or %%l2, %%l1, %%l2\n\t"
147 "sta %%l2, [%%g0] 2\n\t" : : : "l1", "l2");
148};
149
Kristoffer Glembo4309e562009-11-15 23:51:06 +0000150static inline int sparc_leon3_snooping_enabled(void)
151{
152 u32 cctrl;
153 __asm__ __volatile__("lda [%%g0] 2, %0\n\t" : "=r"(cctrl));
154 return (cctrl >> 23) & 1;
155};
156
157static inline void sparc_leon3_disable_cache(void)
Konrad Eisele5213a782009-08-17 00:13:29 +0000158{
159 __asm__ __volatile__ ("lda [%%g0] 2, %%l1\n\t"
160 "set 0x00000f, %%l2\n\t"
161 "andn %%l2, %%l1, %%l2\n\t"
162 "sta %%l2, [%%g0] 2\n\t" : : : "l1", "l2");
163};
164
Daniel Hellstrome2305e32011-01-04 01:41:30 +0000165static inline unsigned long sparc_leon3_asr17(void)
166{
167 u32 asr17;
168 __asm__ __volatile__ ("rd %%asr17, %0\n\t" : "=r"(asr17));
169 return asr17;
170};
171
172static inline int sparc_leon3_cpuid(void)
173{
174 return sparc_leon3_asr17() >> 28;
175}
176
Konrad Eisele5213a782009-08-17 00:13:29 +0000177#endif /*!__ASSEMBLY__*/
178
179#ifdef CONFIG_SMP
Daniel Hellstrom1ca0c802011-05-02 00:08:52 +0000180# define LEON3_IRQ_IPI_DEFAULT 13
Daniel Hellstrom2cf95302011-04-19 23:41:23 +0000181# define LEON3_IRQ_TICKER (leon3_ticker_irq)
Konrad Eisele5213a782009-08-17 00:13:29 +0000182# define LEON3_IRQ_CROSS_CALL 15
183#endif
184
185#if defined(PAGE_SIZE_LEON_8K)
186#define LEON_PAGE_SIZE_LEON 1
187#elif defined(PAGE_SIZE_LEON_16K)
188#define LEON_PAGE_SIZE_LEON 2)
189#else
190#define LEON_PAGE_SIZE_LEON 0
191#endif
192
193#if LEON_PAGE_SIZE_LEON == 0
194/* [ 8, 6, 6 ] + 12 */
195#define LEON_PGD_SH 24
196#define LEON_PGD_M 0xff
197#define LEON_PMD_SH 18
198#define LEON_PMD_SH_V (LEON_PGD_SH-2)
199#define LEON_PMD_M 0x3f
200#define LEON_PTE_SH 12
201#define LEON_PTE_M 0x3f
202#elif LEON_PAGE_SIZE_LEON == 1
203/* [ 7, 6, 6 ] + 13 */
204#define LEON_PGD_SH 25
205#define LEON_PGD_M 0x7f
206#define LEON_PMD_SH 19
207#define LEON_PMD_SH_V (LEON_PGD_SH-1)
208#define LEON_PMD_M 0x3f
209#define LEON_PTE_SH 13
210#define LEON_PTE_M 0x3f
211#elif LEON_PAGE_SIZE_LEON == 2
212/* [ 6, 6, 6 ] + 14 */
213#define LEON_PGD_SH 26
214#define LEON_PGD_M 0x3f
215#define LEON_PMD_SH 20
216#define LEON_PMD_SH_V (LEON_PGD_SH-0)
217#define LEON_PMD_M 0x3f
218#define LEON_PTE_SH 14
219#define LEON_PTE_M 0x3f
220#elif LEON_PAGE_SIZE_LEON == 3
221/* [ 4, 7, 6 ] + 15 */
222#define LEON_PGD_SH 28
223#define LEON_PGD_M 0x0f
224#define LEON_PMD_SH 21
225#define LEON_PMD_SH_V (LEON_PGD_SH-0)
226#define LEON_PMD_M 0x7f
227#define LEON_PTE_SH 15
228#define LEON_PTE_M 0x3f
229#else
230#error cannot determine LEON_PAGE_SIZE_LEON
231#endif
232
233#define PAGE_MIN_SHIFT (12)
234#define PAGE_MIN_SIZE (1UL << PAGE_MIN_SHIFT)
235
236#define LEON3_XCCR_SETS_MASK 0x07000000UL
237#define LEON3_XCCR_SSIZE_MASK 0x00f00000UL
238
239#define LEON2_CCR_DSETS_MASK 0x03000000UL
240#define LEON2_CFG_SSIZE_MASK 0x00007000UL
241
242#ifndef __ASSEMBLY__
Sam Ravnborgf6678d32012-05-19 20:02:48 +0000243struct vm_area_struct;
244
Konrad Eisele5213a782009-08-17 00:13:29 +0000245extern unsigned long srmmu_swprobe(unsigned long vaddr, unsigned long *paddr);
246extern void leon_flush_icache_all(void);
247extern void leon_flush_dcache_all(void);
248extern void leon_flush_cache_all(void);
249extern void leon_flush_tlb_all(void);
250extern int leon_flush_during_switch;
251extern int leon_flush_needed(void);
Konrad Eisele5213a782009-08-17 00:13:29 +0000252extern void leon_flush_pcache_all(struct vm_area_struct *vma, unsigned long page);
253
254/* struct that hold LEON3 cache configuration registers */
255struct leon3_cacheregs {
256 unsigned long ccr; /* 0x00 - Cache Control Register */
257 unsigned long iccr; /* 0x08 - Instruction Cache Configuration Register */
258 unsigned long dccr; /* 0x0c - Data Cache Configuration Register */
259};
260
261/* struct that hold LEON2 cache configuration register
262 * & configuration register
263 */
264struct leon2_cacheregs {
265 unsigned long ccr, cfg;
266};
267
268#ifdef __KERNEL__
269
270#include <linux/interrupt.h>
271
272struct device_node;
Daniel Hellstrom4c6773c2011-04-19 23:41:22 +0000273extern unsigned int leon_build_device_irq(unsigned int real_irq,
274 irq_flow_handler_t flow_handler,
275 const char *name, int do_ack);
Daniel Hellstrom5d07b782011-05-23 21:04:48 +0000276extern void leon_update_virq_handling(unsigned int virq,
277 irq_flow_handler_t flow_handler,
278 const char *name, int do_ack);
Tkhai Kirill62f08282012-04-04 21:49:26 +0200279extern void leon_init_timers(void);
Konrad Eisele5213a782009-08-17 00:13:29 +0000280extern void leon_trans_init(struct device_node *dp);
281extern void leon_node_init(struct device_node *dp, struct device_node ***nextp);
Konrad Eisele5213a782009-08-17 00:13:29 +0000282extern void init_leon(void);
283extern void poke_leonsparc(void);
284extern void leon3_getCacheRegs(struct leon3_cacheregs *regs);
Daniel Hellstrom2cf95302011-04-19 23:41:23 +0000285extern int leon3_ticker_irq;
Konrad Eisele5213a782009-08-17 00:13:29 +0000286
Konrad Eisele84017072009-08-31 22:08:13 +0000287#ifdef CONFIG_SMP
288extern int leon_smp_nrcpus(void);
289extern void leon_clear_profile_irq(int cpu);
290extern void leon_smp_done(void);
291extern void leon_boot_cpus(void);
292extern int leon_boot_one_cpu(int i);
293void leon_init_smp(void);
Konrad Eisele84017072009-08-31 22:08:13 +0000294extern void cpu_idle(void);
295extern void init_IRQ(void);
296extern void cpu_panic(void);
297extern int __leon_processor_id(void);
298void leon_enable_irq_cpu(unsigned int irq_nr, unsigned int cpu);
Daniel Hellstrom2cf95302011-04-19 23:41:23 +0000299extern irqreturn_t leon_percpu_timer_interrupt(int irq, void *unused);
Konrad Eisele84017072009-08-31 22:08:13 +0000300
Daniel Hellstrom2cf95302011-04-19 23:41:23 +0000301extern unsigned int real_irq_entry[];
Daniel Hellstrom1ca0c802011-05-02 00:08:52 +0000302extern unsigned int smpleon_ipi[];
Konrad Eisele84017072009-08-31 22:08:13 +0000303extern unsigned int patchme_maybe_smp_msg[];
Konrad Eisele84017072009-08-31 22:08:13 +0000304extern unsigned int t_nmi[], linux_trap_ipi15_leon[];
305extern unsigned int linux_trap_ipi15_sun4m[];
Daniel Hellstrom1ca0c802011-05-02 00:08:52 +0000306extern int leon_ipi_irq;
Konrad Eisele84017072009-08-31 22:08:13 +0000307
308#endif /* CONFIG_SMP */
309
Konrad Eisele5213a782009-08-17 00:13:29 +0000310#endif /* __KERNEL__ */
311
312#endif /* __ASSEMBLY__ */
313
314/* macros used in leon_mm.c */
315#define PFN(x) ((x) >> PAGE_SHIFT)
316#define _pfn_valid(pfn) ((pfn < last_valid_pfn) && (pfn >= PFN(phys_base)))
317#define _SRMMU_PTE_PMASK_LEON 0xffffffff
318
319#else /* defined(CONFIG_SPARC_LEON) */
320
321/* nop definitions for !LEON case */
322#define leon_init() do {} while (0)
323#define leon_switch_mm() do {} while (0)
324#define leon_init_IRQ() do {} while (0)
325#define init_leon() do {} while (0)
Konrad Eisele84017072009-08-31 22:08:13 +0000326#define leon_smp_done() do {} while (0)
327#define leon_boot_cpus() do {} while (0)
328#define leon_boot_one_cpu(i) 1
329#define leon_init_smp() do {} while (0)
Konrad Eisele5213a782009-08-17 00:13:29 +0000330
331#endif /* !defined(CONFIG_SPARC_LEON) */
332
333#endif