blob: dbb77232e262a4dea6d33386d4b6384634caac96 [file] [log] [blame]
Aaron Williams17c7ad22020-08-20 07:21:57 +02001/* SPDX-License-Identifier: GPL-2.0+ */
2/*
3 * Copyright (C) 2020 Stefan Roese <sr@denx.de>
4 */
5
6#ifndef __CVMX_REGS_H__
7#define __CVMX_REGS_H__
8
9#include <linux/bitfield.h>
10#include <linux/bitops.h>
11#include <linux/io.h>
Stefan Roese1a035f82020-12-11 17:05:56 +010012#include <mach/cvmx-address.h>
Aaron Williams17c7ad22020-08-20 07:21:57 +020013
14/* General defines */
15#define CVMX_MAX_CORES 48
16/* Maximum # of bits to define core in node */
17#define CVMX_NODE_NO_SHIFT 7
18#define CVMX_NODE_BITS 2 /* Number of bits to define a node */
19#define CVMX_MAX_NODES (1 << CVMX_NODE_BITS)
20#define CVMX_NODE_MASK (CVMX_MAX_NODES - 1)
21#define CVMX_NODE_IO_SHIFT 36
22#define CVMX_NODE_MEM_SHIFT 40
23#define CVMX_NODE_IO_MASK ((u64)CVMX_NODE_MASK << CVMX_NODE_IO_SHIFT)
24
25#define CVMX_MIPS_MAX_CORE_BITS 10 /* Maximum # of bits to define cores */
26#define CVMX_MIPS_MAX_CORES (1 << CVMX_MIPS_MAX_CORE_BITS)
27
28#define MAX_CORE_TADS 8
29
Aaron Williams17c7ad22020-08-20 07:21:57 +020030#define CASTPTR(type, v) ((type *)(long)(v))
Stefan Roese1a035f82020-12-11 17:05:56 +010031#define CAST64(v) ((long long)(long)(v))
Aaron Williams17c7ad22020-08-20 07:21:57 +020032
33/* Regs */
Aaron Williams17c7ad22020-08-20 07:21:57 +020034#define CVMX_CIU3_NMI 0x0001010000000160ULL
Aaron Williams17c7ad22020-08-20 07:21:57 +020035
36#define CVMX_MIO_BOOT_LOC_CFGX(x) (0x0001180000000080ULL + ((x) & 1) * 8)
Stefan Roese1a035f82020-12-11 17:05:56 +010037#define MIO_BOOT_LOC_CFG_BASE GENMASK_ULL(27, 3)
38#define MIO_BOOT_LOC_CFG_EN BIT_ULL(31)
Aaron Williams17c7ad22020-08-20 07:21:57 +020039
40#define CVMX_MIO_BOOT_LOC_ADR 0x0001180000000090ULL
Stefan Roese1a035f82020-12-11 17:05:56 +010041#define MIO_BOOT_LOC_ADR_ADR GENMASK_ULL(7, 3)
Aaron Williams17c7ad22020-08-20 07:21:57 +020042
43#define CVMX_MIO_BOOT_LOC_DAT 0x0001180000000098ULL
44
45#define CVMX_MIO_FUS_DAT2 0x0001180000001410ULL
Stefan Roese1a035f82020-12-11 17:05:56 +010046#define MIO_FUS_DAT2_NOCRYPTO BIT_ULL(26)
47#define MIO_FUS_DAT2_NOMUL BIT_ULL(27)
48#define MIO_FUS_DAT2_DORM_CRYPTO BIT_ULL(34)
Aaron Williams17c7ad22020-08-20 07:21:57 +020049
50#define CVMX_MIO_FUS_RCMD 0x0001180000001500ULL
Stefan Roese1a035f82020-12-11 17:05:56 +010051#define MIO_FUS_RCMD_ADDR GENMASK_ULL(7, 0)
52#define MIO_FUS_RCMD_PEND BIT_ULL(12)
53#define MIO_FUS_RCMD_DAT GENMASK_ULL(23, 16)
Aaron Williams17c7ad22020-08-20 07:21:57 +020054
55#define CVMX_RNM_CTL_STATUS 0x0001180040000000ULL
Stefan Roese1a035f82020-12-11 17:05:56 +010056#define RNM_CTL_STATUS_EER_VAL BIT_ULL(9)
57
58#define CVMX_IOBDMA_ORDERED_IO_ADDR 0xffffffffffffa200ull
Aaron Williams17c7ad22020-08-20 07:21:57 +020059
60/* turn the variable name into a string */
61#define CVMX_TMP_STR(x) CVMX_TMP_STR2(x)
62#define CVMX_TMP_STR2(x) #x
63
Stefan Roese1a035f82020-12-11 17:05:56 +010064#define CVMX_RDHWR(result, regstr) \
65 asm volatile("rdhwr %[rt],$" CVMX_TMP_STR(regstr) : [rt] "=d"(result))
Aaron Williams17c7ad22020-08-20 07:21:57 +020066#define CVMX_RDHWRNV(result, regstr) \
Stefan Roese1a035f82020-12-11 17:05:56 +010067 asm("rdhwr %[rt],$" CVMX_TMP_STR(regstr) : [rt] "=d"(result))
68#define CVMX_POP(result, input) \
69 asm("pop %[rd],%[rs]" : [rd] "=d"(result) : [rs] "d"(input))
70
Stefan Roese3629d8b2021-04-07 09:12:27 +020071#define CVMX_SYNC asm volatile("sync\n" : : : "memory")
Stefan Roese1a035f82020-12-11 17:05:56 +010072#define CVMX_SYNCW asm volatile("syncw\nsyncw\n" : : : "memory")
73#define CVMX_SYNCS asm volatile("syncs\n" : : : "memory")
74#define CVMX_SYNCWS asm volatile("syncws\n" : : : "memory")
75
76#define CVMX_CACHE_LINE_SIZE 128 // In bytes
77#define CVMX_CACHE_LINE_MASK (CVMX_CACHE_LINE_SIZE - 1) // In bytes
78#define CVMX_CACHE_LINE_ALIGNED __aligned(CVMX_CACHE_LINE_SIZE)
79
80#define CVMX_SYNCIOBDMA asm volatile("synciobdma" : : : "memory")
81
82#define CVMX_MF_CHORD(dest) CVMX_RDHWR(dest, 30)
Aaron Williams17c7ad22020-08-20 07:21:57 +020083
Stefan Roese1a035f82020-12-11 17:05:56 +010084/*
85 * The macros cvmx_likely and cvmx_unlikely use the
86 * __builtin_expect GCC operation to control branch
87 * probabilities for a conditional. For example, an "if"
88 * statement in the code that will almost always be
89 * executed should be written as "if (cvmx_likely(...))".
90 * If the "else" section of an if statement is more
91 * probable, use "if (cvmx_unlikey(...))".
92 */
93#define cvmx_likely(x) __builtin_expect(!!(x), 1)
94#define cvmx_unlikely(x) __builtin_expect(!!(x), 0)
95
96#define CVMX_WAIT_FOR_FIELD64(address, type, field, op, value, to_us) \
97 ({ \
98 int result; \
99 do { \
100 u64 done = get_timer(0); \
101 type c; \
102 while (1) { \
103 c.u64 = csr_rd(address); \
104 if ((c.s.field)op(value)) { \
105 result = 0; \
106 break; \
107 } else if (get_timer(done) > ((to_us) / 1000)) { \
108 result = -1; \
109 break; \
110 } else \
111 udelay(100); \
112 } \
113 } while (0); \
114 result; \
115 })
116
117#define CVMX_WAIT_FOR_FIELD64_NODE(node, address, type, field, op, value, to_us) \
118 ({ \
119 int result; \
120 do { \
121 u64 done = get_timer(0); \
122 type c; \
123 while (1) { \
124 c.u64 = csr_rd(address); \
125 if ((c.s.field)op(value)) { \
126 result = 0; \
127 break; \
128 } else if (get_timer(done) > ((to_us) / 1000)) { \
129 result = -1; \
130 break; \
131 } else \
132 udelay(100); \
133 } \
134 } while (0); \
135 result; \
136 })
Aaron Williams17c7ad22020-08-20 07:21:57 +0200137
138/* ToDo: Currently only node = 0 supported */
Stefan Roese1a035f82020-12-11 17:05:56 +0100139#define cvmx_get_node_num() 0
140
Aaron Williams17c7ad22020-08-20 07:21:57 +0200141static inline u64 csr_rd_node(int node, u64 addr)
142{
143 void __iomem *base;
144
145 base = ioremap_nocache(addr, 0x100);
146 return ioread64(base);
147}
148
Stefan Roese1a035f82020-12-11 17:05:56 +0100149static inline u32 csr_rd32_node(int node, u64 addr)
150{
151 void __iomem *base;
152
153 base = ioremap_nocache(addr, 0x100);
154 return ioread32(base);
155}
156
Aaron Williams17c7ad22020-08-20 07:21:57 +0200157static inline u64 csr_rd(u64 addr)
158{
159 return csr_rd_node(0, addr);
160}
161
Stefan Roese1a035f82020-12-11 17:05:56 +0100162static inline u32 csr_rd32(u64 addr)
163{
164 return csr_rd32_node(0, addr);
165}
166
Aaron Williams17c7ad22020-08-20 07:21:57 +0200167static inline void csr_wr_node(int node, u64 addr, u64 val)
168{
169 void __iomem *base;
170
171 base = ioremap_nocache(addr, 0x100);
172 iowrite64(val, base);
173}
174
Stefan Roese1a035f82020-12-11 17:05:56 +0100175static inline void csr_wr32_node(int node, u64 addr, u32 val)
176{
177 void __iomem *base;
178
179 base = ioremap_nocache(addr, 0x100);
180 iowrite32(val, base);
181}
182
Aaron Williams17c7ad22020-08-20 07:21:57 +0200183static inline void csr_wr(u64 addr, u64 val)
184{
185 csr_wr_node(0, addr, val);
186}
187
Stefan Roese1a035f82020-12-11 17:05:56 +0100188static inline void csr_wr32(u64 addr, u32 val)
189{
190 csr_wr32_node(0, addr, val);
191}
192
Aaron Williams17c7ad22020-08-20 07:21:57 +0200193/*
194 * We need to use the volatile access here, otherwise the IO accessor
195 * functions might swap the bytes
196 */
197static inline u64 cvmx_read64_uint64(u64 addr)
198{
199 return *(volatile u64 *)addr;
200}
201
Stefan Roese1a035f82020-12-11 17:05:56 +0100202static inline s64 cvmx_read64_int64(u64 addr)
203{
204 return *(volatile s64 *)addr;
205}
206
Aaron Williams17c7ad22020-08-20 07:21:57 +0200207static inline void cvmx_write64_uint64(u64 addr, u64 val)
208{
209 *(volatile u64 *)addr = val;
210}
211
Stefan Roese1a035f82020-12-11 17:05:56 +0100212static inline void cvmx_write64_int64(u64 addr, s64 val)
213{
214 *(volatile s64 *)addr = val;
215}
216
Aaron Williams17c7ad22020-08-20 07:21:57 +0200217static inline u32 cvmx_read64_uint32(u64 addr)
218{
219 return *(volatile u32 *)addr;
220}
221
Stefan Roese1a035f82020-12-11 17:05:56 +0100222static inline s32 cvmx_read64_int32(u64 addr)
223{
224 return *(volatile s32 *)addr;
225}
226
Aaron Williams17c7ad22020-08-20 07:21:57 +0200227static inline void cvmx_write64_uint32(u64 addr, u32 val)
228{
229 *(volatile u32 *)addr = val;
230}
231
Stefan Roese1a035f82020-12-11 17:05:56 +0100232static inline void cvmx_write64_int32(u64 addr, s32 val)
233{
234 *(volatile s32 *)addr = val;
235}
236
237static inline void cvmx_write64_int16(u64 addr, s16 val)
238{
239 *(volatile s16 *)addr = val;
240}
241
242static inline void cvmx_write64_uint16(u64 addr, u16 val)
243{
244 *(volatile u16 *)addr = val;
245}
246
247static inline void cvmx_write64_int8(u64 addr, int8_t val)
248{
249 *(volatile int8_t *)addr = val;
250}
251
252static inline void cvmx_write64_uint8(u64 addr, u8 val)
253{
254 *(volatile u8 *)addr = val;
255}
256
257static inline s16 cvmx_read64_int16(u64 addr)
258{
259 return *(volatile s16 *)addr;
260}
261
262static inline u16 cvmx_read64_uint16(u64 addr)
263{
264 return *(volatile u16 *)addr;
265}
266
267static inline int8_t cvmx_read64_int8(u64 addr)
268{
269 return *(volatile int8_t *)addr;
270}
271
272static inline u8 cvmx_read64_uint8(u64 addr)
273{
274 return *(volatile u8 *)addr;
275}
276
277static inline void cvmx_send_single(u64 data)
278{
279 cvmx_write64_uint64(CVMX_IOBDMA_ORDERED_IO_ADDR, data);
280}
281
282/**
283 * Perform a 64-bit write to an IO address
284 *
285 * @param io_addr I/O address to write to
286 * @param val 64-bit value to write
287 */
288static inline void cvmx_write_io(u64 io_addr, u64 val)
289{
290 cvmx_write64_uint64(io_addr, val);
291}
292
293/**
294 * Builds a memory address for I/O based on the Major and Sub DID.
295 *
296 * @param major_did 5 bit major did
297 * @param sub_did 3 bit sub did
Heinrich Schuchardt47b4c022022-01-19 18:05:50 +0100298 * Return: I/O base address
Stefan Roese1a035f82020-12-11 17:05:56 +0100299 */
300static inline u64 cvmx_build_io_address(u64 major_did, u64 sub_did)
301{
302 return ((0x1ull << 48) | (major_did << 43) | (sub_did << 40));
303}
304
305/**
306 * Builds a bit mask given the required size in bits.
307 *
308 * @param bits Number of bits in the mask
Heinrich Schuchardt47b4c022022-01-19 18:05:50 +0100309 * Return: The mask
Stefan Roese1a035f82020-12-11 17:05:56 +0100310 */
311static inline u64 cvmx_build_mask(u64 bits)
312{
313 if (bits == 64)
314 return -1;
315
316 return ~((~0x0ull) << bits);
317}
318
319/**
320 * Extract bits out of a number
321 *
322 * @param input Number to extract from
323 * @param lsb Starting bit, least significant (0-63)
324 * @param width Width in bits (1-64)
325 *
Heinrich Schuchardt47b4c022022-01-19 18:05:50 +0100326 * Return: Extracted number
Stefan Roese1a035f82020-12-11 17:05:56 +0100327 */
328static inline u64 cvmx_bit_extract(u64 input, int lsb, int width)
329{
330 u64 result = input >> lsb;
331
332 result &= cvmx_build_mask(width);
333
334 return result;
335}
336
337/**
338 * Perform mask and shift to place the supplied value into
339 * the supplied bit rage.
340 *
341 * Example: cvmx_build_bits(39,24,value)
342 * <pre>
343 * 6 5 4 3 3 2 1
344 * 3 5 7 9 1 3 5 7 0
345 * +-------+-------+-------+-------+-------+-------+-------+------+
346 * 000000000000000000000000___________value000000000000000000000000
347 * </pre>
348 *
349 * @param high_bit Highest bit value can occupy (inclusive) 0-63
350 * @param low_bit Lowest bit value can occupy inclusive 0-high_bit
351 * @param value Value to use
Heinrich Schuchardt47b4c022022-01-19 18:05:50 +0100352 * Return: Value masked and shifted
Stefan Roese1a035f82020-12-11 17:05:56 +0100353 */
354static inline u64 cvmx_build_bits(u64 high_bit, u64 low_bit, u64 value)
355{
356 return ((value & cvmx_build_mask(high_bit - low_bit + 1)) << low_bit);
357}
358
359static inline u64 cvmx_mask_to_localaddr(u64 addr)
360{
361 return (addr & 0xffffffffff);
362}
363
364static inline u64 cvmx_addr_on_node(u64 node, u64 addr)
365{
366 return (node << 40) | cvmx_mask_to_localaddr(addr);
367}
368
Aaron Williams17c7ad22020-08-20 07:21:57 +0200369static inline void *cvmx_phys_to_ptr(u64 addr)
370{
371 return (void *)CKSEG0ADDR(addr);
372}
373
374static inline u64 cvmx_ptr_to_phys(void *ptr)
375{
376 return virt_to_phys(ptr);
377}
378
379/**
380 * Number of the Core on which the program is currently running.
381 *
Heinrich Schuchardt47b4c022022-01-19 18:05:50 +0100382 * Return: core number
Aaron Williams17c7ad22020-08-20 07:21:57 +0200383 */
384static inline unsigned int cvmx_get_core_num(void)
385{
386 unsigned int core_num;
387
388 CVMX_RDHWRNV(core_num, 0);
389 return core_num;
390}
391
Stefan Roese1a035f82020-12-11 17:05:56 +0100392/**
393 * Node-local number of the core on which the program is currently running.
394 *
Heinrich Schuchardt47b4c022022-01-19 18:05:50 +0100395 * Return: core number on local node
Stefan Roese1a035f82020-12-11 17:05:56 +0100396 */
397static inline unsigned int cvmx_get_local_core_num(void)
398{
399 unsigned int core_num, core_mask;
400
401 CVMX_RDHWRNV(core_num, 0);
402 /* note that MAX_CORES may not be power of 2 */
403 core_mask = (1 << CVMX_NODE_NO_SHIFT) - 1;
404
405 return core_num & core_mask;
406}
407
408/**
409 * Returns the number of bits set in the provided value.
410 * Simple wrapper for POP instruction.
411 *
412 * @param val 32 bit value to count set bits in
413 *
Heinrich Schuchardt47b4c022022-01-19 18:05:50 +0100414 * Return: Number of bits set
Stefan Roese1a035f82020-12-11 17:05:56 +0100415 */
416static inline u32 cvmx_pop(u32 val)
417{
418 u32 pop;
419
420 CVMX_POP(pop, val);
421
422 return pop;
423}
424
425#define cvmx_read_csr_node(node, addr) csr_rd(addr)
426#define cvmx_write_csr_node(node, addr, val) csr_wr(addr, val)
427
428#define cvmx_printf printf
429#define cvmx_vprintf vprintf
430
431#if defined(DEBUG)
432void cvmx_warn(const char *format, ...) __printf(1, 2);
433#else
434void cvmx_warn(const char *format, ...);
435#endif
436
437#define cvmx_warn_if(expression, format, ...) \
438 if (expression) \
439 cvmx_warn(format, ##__VA_ARGS__)
440
Aaron Williams17c7ad22020-08-20 07:21:57 +0200441#endif /* __CVMX_REGS_H__ */