]>
Commit | Line | Data |
---|---|---|
a2a55e51 PK |
1 | /* |
2 | * Copyright (C) 2014 Freescale Semiconductor | |
3 | * | |
4 | * SPDX-License-Identifier: GPL-2.0+ | |
5 | */ | |
6 | ||
7 | /* Perform extra checking */ | |
8 | #include <common.h> | |
9 | #include <errno.h> | |
10 | #include <asm/io.h> | |
11 | #include <linux/types.h> | |
cd8aefc0 | 12 | #include <asm/atomic.h> |
a2a55e51 | 13 | #include <malloc.h> |
8e62f1ee | 14 | #include <asm/arch/soc.h> |
a2a55e51 PK |
15 | #include <fsl-mc/fsl_qbman_base.h> |
16 | ||
17 | #define QBMAN_CHECKING | |
18 | ||
19 | /* Any time there is a register interface which we poll on, this provides a | |
20 | * "break after x iterations" scheme for it. It's handy for debugging, eg. | |
21 | * where you don't want millions of lines of log output from a polling loop | |
22 | * that won't, because such things tend to drown out the earlier log output | |
23 | * that might explain what caused the problem. (NB: put ";" after each macro!) | |
24 | * TODO: we should probably remove this once we're done sanitising the | |
25 | * simulator... | |
26 | */ | |
27 | #define DBG_POLL_START(loopvar) (loopvar = 10) | |
28 | #define DBG_POLL_CHECK(loopvar) \ | |
29 | do {if (!(loopvar--)) BUG_ON(NULL == "DBG_POLL_CHECK"); } while (0) | |
30 | ||
31 | /* For CCSR or portal-CINH registers that contain fields at arbitrary offsets | |
32 | * and widths, these macro-generated encode/decode/isolate/remove inlines can | |
33 | * be used. | |
34 | * | |
35 | * Eg. to "d"ecode a 14-bit field out of a register (into a "uint16_t" type), | |
36 | * where the field is located 3 bits "up" from the least-significant bit of the | |
37 | * register (ie. the field location within the 32-bit register corresponds to a | |
38 | * mask of 0x0001fff8), you would do; | |
39 | * uint16_t field = d32_uint16_t(3, 14, reg_value); | |
40 | * | |
41 | * Or to "e"ncode a 1-bit boolean value (input type is "int", zero is FALSE, | |
42 | * non-zero is TRUE, so must convert all non-zero inputs to 1, hence the "!!" | |
43 | * operator) into a register at bit location 0x00080000 (19 bits "in" from the | |
44 | * LS bit), do; | |
45 | * reg_value |= e32_int(19, 1, !!field); | |
46 | * | |
47 | * If you wish to read-modify-write a register, such that you leave the 14-bit | |
48 | * field as-is but have all other fields set to zero, then "i"solate the 14-bit | |
49 | * value using; | |
50 | * reg_value = i32_uint16_t(3, 14, reg_value); | |
51 | * | |
52 | * Alternatively, you could "r"emove the 1-bit boolean field (setting it to | |
53 | * zero) but leaving all other fields as-is; | |
54 | * reg_val = r32_int(19, 1, reg_value); | |
55 | * | |
56 | */ | |
57 | #define MAKE_MASK32(width) (width == 32 ? 0xffffffff : \ | |
58 | (uint32_t)((1 << width) - 1)) | |
59 | #define DECLARE_CODEC32(t) \ | |
60 | static inline uint32_t e32_##t(uint32_t lsoffset, uint32_t width, t val) \ | |
61 | { \ | |
62 | BUG_ON(width > (sizeof(t) * 8)); \ | |
63 | return ((uint32_t)val & MAKE_MASK32(width)) << lsoffset; \ | |
64 | } \ | |
65 | static inline t d32_##t(uint32_t lsoffset, uint32_t width, uint32_t val) \ | |
66 | { \ | |
67 | BUG_ON(width > (sizeof(t) * 8)); \ | |
68 | return (t)((val >> lsoffset) & MAKE_MASK32(width)); \ | |
69 | } \ | |
70 | static inline uint32_t i32_##t(uint32_t lsoffset, uint32_t width, \ | |
71 | uint32_t val) \ | |
72 | { \ | |
73 | BUG_ON(width > (sizeof(t) * 8)); \ | |
74 | return e32_##t(lsoffset, width, d32_##t(lsoffset, width, val)); \ | |
75 | } \ | |
76 | static inline uint32_t r32_##t(uint32_t lsoffset, uint32_t width, \ | |
77 | uint32_t val) \ | |
78 | { \ | |
79 | BUG_ON(width > (sizeof(t) * 8)); \ | |
80 | return ~(MAKE_MASK32(width) << lsoffset) & val; \ | |
81 | } | |
82 | DECLARE_CODEC32(uint32_t) | |
83 | DECLARE_CODEC32(uint16_t) | |
84 | DECLARE_CODEC32(uint8_t) | |
85 | DECLARE_CODEC32(int) | |
86 | ||
87 | /*********************/ | |
88 | /* Debugging assists */ | |
89 | /*********************/ | |
90 | ||
91 | static inline void __hexdump(unsigned long start, unsigned long end, | |
92 | unsigned long p, size_t sz, const unsigned char *c) | |
93 | { | |
94 | while (start < end) { | |
95 | unsigned int pos = 0; | |
96 | char buf[64]; | |
97 | int nl = 0; | |
98 | ||
99 | pos += sprintf(buf + pos, "%08lx: ", start); | |
100 | do { | |
101 | if ((start < p) || (start >= (p + sz))) | |
102 | pos += sprintf(buf + pos, ".."); | |
103 | else | |
104 | pos += sprintf(buf + pos, "%02x", *(c++)); | |
105 | if (!(++start & 15)) { | |
106 | buf[pos++] = '\n'; | |
107 | nl = 1; | |
108 | } else { | |
109 | nl = 0; | |
110 | if (!(start & 1)) | |
111 | buf[pos++] = ' '; | |
112 | if (!(start & 3)) | |
113 | buf[pos++] = ' '; | |
114 | } | |
115 | } while (start & 15); | |
116 | if (!nl) | |
117 | buf[pos++] = '\n'; | |
118 | buf[pos] = '\0'; | |
119 | debug("%s", buf); | |
120 | } | |
121 | } | |
122 | static inline void hexdump(const void *ptr, size_t sz) | |
123 | { | |
124 | unsigned long p = (unsigned long)ptr; | |
125 | unsigned long start = p & ~(unsigned long)15; | |
126 | unsigned long end = (p + sz + 15) & ~(unsigned long)15; | |
127 | const unsigned char *c = ptr; | |
128 | ||
129 | __hexdump(start, end, p, sz, c); | |
130 | } | |
131 | ||
132 | #if defined(__BIG_ENDIAN) | |
133 | #define DQRR_TOK_OFFSET 0 | |
134 | #else | |
135 | #define DQRR_TOK_OFFSET 24 | |
136 | #endif | |
137 | ||
138 | /* Similarly-named functions */ | |
139 | #define upper32(a) upper_32_bits(a) | |
140 | #define lower32(a) lower_32_bits(a) | |
141 | ||
142 | /****************/ | |
143 | /* arch assists */ | |
144 | /****************/ | |
145 | ||
146 | static inline void dcbz(void *ptr) | |
147 | { | |
148 | uint32_t *p = ptr; | |
149 | BUG_ON((unsigned long)ptr & 63); | |
150 | p[0] = 0; | |
151 | p[1] = 0; | |
152 | p[2] = 0; | |
153 | p[3] = 0; | |
154 | p[4] = 0; | |
155 | p[5] = 0; | |
156 | p[6] = 0; | |
157 | p[7] = 0; | |
158 | p[8] = 0; | |
159 | p[9] = 0; | |
160 | p[10] = 0; | |
161 | p[11] = 0; | |
162 | p[12] = 0; | |
163 | p[13] = 0; | |
164 | p[14] = 0; | |
165 | p[15] = 0; | |
166 | } | |
167 | ||
168 | #define lwsync() | |
169 | ||
8e62f1ee PJ |
170 | void qbman_version(u32 *major, u32 *minor) |
171 | { | |
172 | u32 svr_dev_id; | |
173 | ||
174 | /* | |
175 | * LS2080A SoC and its personalities has qbman cotroller version 4.0 | |
176 | * New SoCs like LS2088A, LS1088A has qbman conroller version 4.1 | |
177 | */ | |
a8f33034 W |
178 | svr_dev_id = get_svr(); |
179 | if (IS_SVR_DEV(svr_dev_id, SVR_DEV(SVR_LS2080A))) { | |
8e62f1ee PJ |
180 | *major = 4; |
181 | *minor = 0; | |
182 | } else { | |
183 | *major = 4; | |
184 | *minor = 1; | |
185 | } | |
186 | } | |
187 | ||
a2a55e51 | 188 | #include "qbman_sys.h" |