blob: 417df7e19281b3189da4e0a27369815cabdacb31 [file] [log] [blame]
Thomas Gleixner2874c5f2019-05-27 08:55:01 +02001// SPDX-License-Identifier: GPL-2.0-or-later
Li Yang98658532006-10-03 23:10:46 -05002/*
Yang Li8a56e1e2012-11-01 18:53:42 +00003 * Copyright (C) 2006-2010 Freescale Semiconductor, Inc. All rights reserved.
Li Yang98658532006-10-03 23:10:46 -05004 *
5 * Authors: Shlomi Gridish <gridish@freescale.com>
6 * Li Yang <leoli@freescale.com>
7 * Based on cpm2_common.c from Dan Malek (dmalek@jlc.net)
8 *
9 * Description:
10 * General Purpose functions for the global management of the
11 * QUICC Engine (QE).
Li Yang98658532006-10-03 23:10:46 -050012 */
Rasmus Villemoes875f2aa2019-05-13 11:14:56 +000013#include <linux/bitmap.h>
Li Yang98658532006-10-03 23:10:46 -050014#include <linux/errno.h>
15#include <linux/sched.h>
16#include <linux/kernel.h>
17#include <linux/param.h>
18#include <linux/string.h>
Anton Vorontsov09a3fba2008-11-11 18:31:39 +030019#include <linux/spinlock.h>
Li Yang98658532006-10-03 23:10:46 -050020#include <linux/mm.h>
21#include <linux/interrupt.h>
Li Yang98658532006-10-03 23:10:46 -050022#include <linux/module.h>
23#include <linux/delay.h>
24#include <linux/ioport.h>
Timur Tabibc556ba2008-01-08 10:30:58 -060025#include <linux/crc32.h>
Anton Vorontsovfdfde242009-09-16 01:43:55 +040026#include <linux/mod_devicetable.h>
27#include <linux/of_platform.h>
Li Yang98658532006-10-03 23:10:46 -050028#include <asm/irq.h>
29#include <asm/page.h>
30#include <asm/pgtable.h>
Zhao Qiang7aa1aa62015-11-30 10:48:57 +080031#include <soc/fsl/qe/immap_qe.h>
32#include <soc/fsl/qe/qe.h>
Li Yang98658532006-10-03 23:10:46 -050033#include <asm/prom.h>
34#include <asm/rheap.h>
35
36static void qe_snums_init(void);
Li Yang98658532006-10-03 23:10:46 -050037static int qe_sdma_init(void);
38
39static DEFINE_SPINLOCK(qe_lock);
Anton Vorontsov09a3fba2008-11-11 18:31:39 +030040DEFINE_SPINLOCK(cmxgcr_lock);
41EXPORT_SYMBOL(cmxgcr_lock);
Li Yang98658532006-10-03 23:10:46 -050042
Li Yang98658532006-10-03 23:10:46 -050043/* We allocate this here because it is used almost exclusively for
44 * the communication processor devices.
45 */
Anton Vorontsov0b51b022008-03-11 20:24:13 +030046struct qe_immap __iomem *qe_immr;
Li Yang98658532006-10-03 23:10:46 -050047EXPORT_SYMBOL(qe_immr);
48
Rasmus Villemoes875f2aa2019-05-13 11:14:56 +000049static u8 snums[QE_NUM_OF_SNUM]; /* Dynamically allocated SNUMs */
50static DECLARE_BITMAP(snum_state, QE_NUM_OF_SNUM);
Haiying Wang98ca77a2009-05-01 15:40:48 -040051static unsigned int qe_num_of_snum;
Li Yang98658532006-10-03 23:10:46 -050052
53static phys_addr_t qebase = -1;
54
Rasmus Villemoesd7fc5962019-05-13 11:14:57 +000055static struct device_node *qe_get_device_node(void)
56{
57 struct device_node *qe;
58
59 /*
60 * Newer device trees have an "fsl,qe" compatible property for the QE
61 * node, but we still need to support older device trees.
62 */
63 qe = of_find_compatible_node(NULL, NULL, "fsl,qe");
64 if (qe)
65 return qe;
66 return of_find_node_by_type(NULL, "qe");
67}
68
Christophe Leroyb54ea822017-02-07 10:05:11 +010069static phys_addr_t get_qe_base(void)
Li Yang98658532006-10-03 23:10:46 -050070{
71 struct device_node *qe;
Zhao Qiang50669432016-09-23 10:20:31 +080072 int ret;
73 struct resource res;
Li Yang98658532006-10-03 23:10:46 -050074
75 if (qebase != -1)
76 return qebase;
77
Rasmus Villemoesd7fc5962019-05-13 11:14:57 +000078 qe = qe_get_device_node();
79 if (!qe)
80 return qebase;
Anton Vorontsova2dd70a2008-01-24 18:39:59 +030081
Zhao Qiang50669432016-09-23 10:20:31 +080082 ret = of_address_to_resource(qe, 0, &res);
83 if (!ret)
84 qebase = res.start;
Anton Vorontsova2dd70a2008-01-24 18:39:59 +030085 of_node_put(qe);
Li Yang98658532006-10-03 23:10:46 -050086
87 return qebase;
88}
89
Anton Vorontsov0c7b87b2009-09-16 01:43:52 +040090void qe_reset(void)
Li Yang98658532006-10-03 23:10:46 -050091{
92 if (qe_immr == NULL)
93 qe_immr = ioremap(get_qe_base(), QE_IMMAP_SIZE);
94
95 qe_snums_init();
96
97 qe_issue_cmd(QE_RESET, QE_CR_SUBBLOCK_INVALID,
98 QE_CR_PROTOCOL_UNSPECIFIED, 0);
99
100 /* Reclaim the MURAM memory for our use. */
101 qe_muram_init();
102
103 if (qe_sdma_init())
104 panic("sdma init failed!");
105}
106
107int qe_issue_cmd(u32 cmd, u32 device, u8 mcn_protocol, u32 cmd_input)
108{
109 unsigned long flags;
110 u8 mcn_shift = 0, dev_shift = 0;
Timur Tabif49156ea2009-05-26 10:21:42 -0500111 u32 ret;
Li Yang98658532006-10-03 23:10:46 -0500112
113 spin_lock_irqsave(&qe_lock, flags);
114 if (cmd == QE_RESET) {
115 out_be32(&qe_immr->cp.cecr, (u32) (cmd | QE_CR_FLG));
116 } else {
117 if (cmd == QE_ASSIGN_PAGE) {
118 /* Here device is the SNUM, not sub-block */
119 dev_shift = QE_CR_SNUM_SHIFT;
120 } else if (cmd == QE_ASSIGN_RISC) {
121 /* Here device is the SNUM, and mcnProtocol is
122 * e_QeCmdRiscAssignment value */
123 dev_shift = QE_CR_SNUM_SHIFT;
124 mcn_shift = QE_CR_MCN_RISC_ASSIGN_SHIFT;
125 } else {
126 if (device == QE_CR_SUBBLOCK_USB)
127 mcn_shift = QE_CR_MCN_USB_SHIFT;
128 else
129 mcn_shift = QE_CR_MCN_NORMAL_SHIFT;
130 }
131
Timur Tabi302439d2006-10-31 17:53:42 +0800132 out_be32(&qe_immr->cp.cecdr, cmd_input);
Li Yang98658532006-10-03 23:10:46 -0500133 out_be32(&qe_immr->cp.cecr,
134 (cmd | QE_CR_FLG | ((u32) device << dev_shift) | (u32)
135 mcn_protocol << mcn_shift));
136 }
137
138 /* wait for the QE_CR_FLG to clear */
Timur Tabif49156ea2009-05-26 10:21:42 -0500139 ret = spin_event_timeout((in_be32(&qe_immr->cp.cecr) & QE_CR_FLG) == 0,
140 100, 0);
141 /* On timeout (e.g. failure), the expression will be false (ret == 0),
142 otherwise it will be true (ret == 1). */
Li Yang98658532006-10-03 23:10:46 -0500143 spin_unlock_irqrestore(&qe_lock, flags);
144
Timur Tabif49156ea2009-05-26 10:21:42 -0500145 return ret == 1;
Li Yang98658532006-10-03 23:10:46 -0500146}
147EXPORT_SYMBOL(qe_issue_cmd);
148
149/* Set a baud rate generator. This needs lots of work. There are
150 * 16 BRGs, which can be connected to the QE channels or output
151 * as clocks. The BRGs are in two different block of internal
152 * memory mapped space.
Timur Tabi6b0b5942007-10-03 11:34:59 -0500153 * The BRG clock is the QE clock divided by 2.
Li Yang98658532006-10-03 23:10:46 -0500154 * It was set up long ago during the initial boot phase and is
155 * is given to us.
156 * Baud rate clocks are zero-based in the driver code (as that maps
157 * to port numbers). Documentation uses 1-based numbering.
158 */
159static unsigned int brg_clk = 0;
160
Valentin Longchamp2ccf80b2017-02-17 11:29:45 +0100161#define CLK_GRAN (1000)
162#define CLK_GRAN_LIMIT (5)
163
Anton Vorontsov7f0a6fc2008-03-11 20:24:24 +0300164unsigned int qe_get_brg_clk(void)
Li Yang98658532006-10-03 23:10:46 -0500165{
166 struct device_node *qe;
Andy Fleming7e1cc9c2008-05-07 13:19:44 -0500167 int size;
Anton Vorontsova2dd70a2008-01-24 18:39:59 +0300168 const u32 *prop;
Valentin Longchamp2ccf80b2017-02-17 11:29:45 +0100169 unsigned int mod;
Anton Vorontsova2dd70a2008-01-24 18:39:59 +0300170
Li Yang98658532006-10-03 23:10:46 -0500171 if (brg_clk)
172 return brg_clk;
173
Rasmus Villemoesd7fc5962019-05-13 11:14:57 +0000174 qe = qe_get_device_node();
175 if (!qe)
176 return brg_clk;
Anton Vorontsova2dd70a2008-01-24 18:39:59 +0300177
178 prop = of_get_property(qe, "brg-frequency", &size);
Anton Vorontsovd8985fd2008-02-04 16:46:17 +0300179 if (prop && size == sizeof(*prop))
180 brg_clk = *prop;
Anton Vorontsova2dd70a2008-01-24 18:39:59 +0300181
Anton Vorontsova2dd70a2008-01-24 18:39:59 +0300182 of_node_put(qe);
183
Valentin Longchamp2ccf80b2017-02-17 11:29:45 +0100184 /* round this if near to a multiple of CLK_GRAN */
185 mod = brg_clk % CLK_GRAN;
186 if (mod) {
187 if (mod < CLK_GRAN_LIMIT)
188 brg_clk -= mod;
189 else if (mod > (CLK_GRAN - CLK_GRAN_LIMIT))
190 brg_clk += CLK_GRAN - mod;
191 }
192
Li Yang98658532006-10-03 23:10:46 -0500193 return brg_clk;
194}
Anton Vorontsov7f0a6fc2008-03-11 20:24:24 +0300195EXPORT_SYMBOL(qe_get_brg_clk);
Li Yang98658532006-10-03 23:10:46 -0500196
Valentin Longchampe5c5c8d2017-02-17 11:29:46 +0100197#define PVR_VER_836x 0x8083
198#define PVR_VER_832x 0x8084
199
Timur Tabi6b0b5942007-10-03 11:34:59 -0500200/* Program the BRG to the given sampling rate and multiplier
201 *
Timur Tabi7264ec42007-11-29 17:26:30 -0600202 * @brg: the BRG, QE_BRG1 - QE_BRG16
Timur Tabi6b0b5942007-10-03 11:34:59 -0500203 * @rate: the desired sampling rate
204 * @multiplier: corresponds to the value programmed in GUMR_L[RDCR] or
205 * GUMR_L[TDCR]. E.g., if this BRG is the RX clock, and GUMR_L[RDCR]=01,
206 * then 'multiplier' should be 8.
Li Yang98658532006-10-03 23:10:46 -0500207 */
Timur Tabi7264ec42007-11-29 17:26:30 -0600208int qe_setbrg(enum qe_clock brg, unsigned int rate, unsigned int multiplier)
Li Yang98658532006-10-03 23:10:46 -0500209{
Li Yang98658532006-10-03 23:10:46 -0500210 u32 divisor, tempval;
Timur Tabi6b0b5942007-10-03 11:34:59 -0500211 u32 div16 = 0;
Li Yang98658532006-10-03 23:10:46 -0500212
Timur Tabi7264ec42007-11-29 17:26:30 -0600213 if ((brg < QE_BRG1) || (brg > QE_BRG16))
214 return -EINVAL;
215
Anton Vorontsov7f0a6fc2008-03-11 20:24:24 +0300216 divisor = qe_get_brg_clk() / (rate * multiplier);
Li Yang98658532006-10-03 23:10:46 -0500217
Li Yang98658532006-10-03 23:10:46 -0500218 if (divisor > QE_BRGC_DIVISOR_MAX + 1) {
Timur Tabi6b0b5942007-10-03 11:34:59 -0500219 div16 = QE_BRGC_DIV16;
Li Yang98658532006-10-03 23:10:46 -0500220 divisor /= 16;
221 }
222
Timur Tabi6b0b5942007-10-03 11:34:59 -0500223 /* Errata QE_General4, which affects some MPC832x and MPC836x SOCs, says
224 that the BRG divisor must be even if you're not using divide-by-16
225 mode. */
Valentin Longchampe5c5c8d2017-02-17 11:29:46 +0100226 if (pvr_version_is(PVR_VER_836x) || pvr_version_is(PVR_VER_832x))
227 if (!div16 && (divisor & 1) && (divisor > 3))
228 divisor++;
Li Yang98658532006-10-03 23:10:46 -0500229
Timur Tabi6b0b5942007-10-03 11:34:59 -0500230 tempval = ((divisor - 1) << QE_BRGC_DIVISOR_SHIFT) |
231 QE_BRGC_ENABLE | div16;
232
Timur Tabi7264ec42007-11-29 17:26:30 -0600233 out_be32(&qe_immr->brg.brgc[brg - QE_BRG1], tempval);
234
235 return 0;
Li Yang98658532006-10-03 23:10:46 -0500236}
Timur Tabi7264ec42007-11-29 17:26:30 -0600237EXPORT_SYMBOL(qe_setbrg);
Li Yang98658532006-10-03 23:10:46 -0500238
Timur Tabi174b0da2007-12-03 15:17:58 -0600239/* Convert a string to a QE clock source enum
240 *
241 * This function takes a string, typically from a property in the device
242 * tree, and returns the corresponding "enum qe_clock" value.
243*/
244enum qe_clock qe_clock_source(const char *source)
245{
246 unsigned int i;
247
248 if (strcasecmp(source, "none") == 0)
249 return QE_CLK_NONE;
250
Zhao Qiang68f047e2016-06-06 14:29:58 +0800251 if (strcmp(source, "tsync_pin") == 0)
252 return QE_TSYNC_PIN;
253
254 if (strcmp(source, "rsync_pin") == 0)
255 return QE_RSYNC_PIN;
256
Timur Tabi174b0da2007-12-03 15:17:58 -0600257 if (strncasecmp(source, "brg", 3) == 0) {
258 i = simple_strtoul(source + 3, NULL, 10);
259 if ((i >= 1) && (i <= 16))
260 return (QE_BRG1 - 1) + i;
261 else
262 return QE_CLK_DUMMY;
263 }
264
265 if (strncasecmp(source, "clk", 3) == 0) {
266 i = simple_strtoul(source + 3, NULL, 10);
267 if ((i >= 1) && (i <= 24))
268 return (QE_CLK1 - 1) + i;
269 else
270 return QE_CLK_DUMMY;
271 }
272
273 return QE_CLK_DUMMY;
274}
275EXPORT_SYMBOL(qe_clock_source);
276
Li Yang98658532006-10-03 23:10:46 -0500277/* Initialize SNUMs (thread serial numbers) according to
278 * QE Module Control chapter, SNUM table
279 */
280static void qe_snums_init(void)
281{
Dave Liufa1b42b2010-01-12 00:04:03 +0000282 static const u8 snum_init_76[] = {
283 0x04, 0x05, 0x0C, 0x0D, 0x14, 0x15, 0x1C, 0x1D,
284 0x24, 0x25, 0x2C, 0x2D, 0x34, 0x35, 0x88, 0x89,
285 0x98, 0x99, 0xA8, 0xA9, 0xB8, 0xB9, 0xC8, 0xC9,
286 0xD8, 0xD9, 0xE8, 0xE9, 0x44, 0x45, 0x4C, 0x4D,
287 0x54, 0x55, 0x5C, 0x5D, 0x64, 0x65, 0x6C, 0x6D,
288 0x74, 0x75, 0x7C, 0x7D, 0x84, 0x85, 0x8C, 0x8D,
289 0x94, 0x95, 0x9C, 0x9D, 0xA4, 0xA5, 0xAC, 0xAD,
290 0xB4, 0xB5, 0xBC, 0xBD, 0xC4, 0xC5, 0xCC, 0xCD,
291 0xD4, 0xD5, 0xDC, 0xDD, 0xE4, 0xE5, 0xEC, 0xED,
292 0xF4, 0xF5, 0xFC, 0xFD,
293 };
294 static const u8 snum_init_46[] = {
Li Yang98658532006-10-03 23:10:46 -0500295 0x04, 0x05, 0x0C, 0x0D, 0x14, 0x15, 0x1C, 0x1D,
296 0x24, 0x25, 0x2C, 0x2D, 0x34, 0x35, 0x88, 0x89,
297 0x98, 0x99, 0xA8, 0xA9, 0xB8, 0xB9, 0xC8, 0xC9,
Haiying Wang98ca77a2009-05-01 15:40:48 -0400298 0xD8, 0xD9, 0xE8, 0xE9, 0x08, 0x09, 0x18, 0x19,
299 0x28, 0x29, 0x38, 0x39, 0x48, 0x49, 0x58, 0x59,
300 0x68, 0x69, 0x78, 0x79, 0x80, 0x81,
Li Yang98658532006-10-03 23:10:46 -0500301 };
Rasmus Villemoes5cfca892019-05-13 11:15:00 +0000302 struct device_node *qe;
Rasmus Villemoesf03de742019-05-13 11:14:54 +0000303 const u8 *snum_init;
Rasmus Villemoes5cfca892019-05-13 11:15:00 +0000304 int i;
Li Yang98658532006-10-03 23:10:46 -0500305
Rasmus Villemoes5cfca892019-05-13 11:15:00 +0000306 bitmap_zero(snum_state, QE_NUM_OF_SNUM);
Rasmus Villemoes21560062019-05-13 11:15:01 +0000307 qe_num_of_snum = 28; /* The default number of snum for threads is 28 */
Rasmus Villemoes5cfca892019-05-13 11:15:00 +0000308 qe = qe_get_device_node();
309 if (qe) {
310 i = of_property_read_variable_u8_array(qe, "fsl,qe-snums",
311 snums, 1, QE_NUM_OF_SNUM);
Rasmus Villemoes5cfca892019-05-13 11:15:00 +0000312 if (i > 0) {
Rasmus Villemoes21560062019-05-13 11:15:01 +0000313 of_node_put(qe);
Rasmus Villemoes5cfca892019-05-13 11:15:00 +0000314 qe_num_of_snum = i;
315 return;
316 }
Rasmus Villemoes21560062019-05-13 11:15:01 +0000317 /*
318 * Fall back to legacy binding of using the value of
319 * fsl,qe-num-snums to choose one of the static arrays
320 * above.
321 */
322 of_property_read_u32(qe, "fsl,qe-num-snums", &qe_num_of_snum);
323 of_node_put(qe);
Li Yang98658532006-10-03 23:10:46 -0500324 }
Li Yang98658532006-10-03 23:10:46 -0500325
Rasmus Villemoes21560062019-05-13 11:15:01 +0000326 if (qe_num_of_snum == 76) {
Li Yang98658532006-10-03 23:10:46 -0500327 snum_init = snum_init_76;
Rasmus Villemoes21560062019-05-13 11:15:01 +0000328 } else if (qe_num_of_snum == 28 || qe_num_of_snum == 46) {
Li Yang98658532006-10-03 23:10:46 -0500329 snum_init = snum_init_46;
Rasmus Villemoes21560062019-05-13 11:15:01 +0000330 } else {
331 pr_err("QE: unsupported value of fsl,qe-num-snums: %u\n", qe_num_of_snum);
332 return;
333 }
Rasmus Villemoes875f2aa2019-05-13 11:14:56 +0000334 memcpy(snums, snum_init, qe_num_of_snum);
Li Yang98658532006-10-03 23:10:46 -0500335}
336
337int qe_get_snum(void)
338{
339 unsigned long flags;
340 int snum = -EBUSY;
341 int i;
342
343 spin_lock_irqsave(&qe_lock, flags);
Rasmus Villemoes875f2aa2019-05-13 11:14:56 +0000344 i = find_first_zero_bit(snum_state, qe_num_of_snum);
345 if (i < qe_num_of_snum) {
346 set_bit(i, snum_state);
347 snum = snums[i];
Li Yang98658532006-10-03 23:10:46 -0500348 }
349 spin_unlock_irqrestore(&qe_lock, flags);
350
351 return snum;
352}
353EXPORT_SYMBOL(qe_get_snum);
354
355void qe_put_snum(u8 snum)
356{
Rasmus Villemoes875f2aa2019-05-13 11:14:56 +0000357 const u8 *p = memchr(snums, snum, qe_num_of_snum);
Li Yang98658532006-10-03 23:10:46 -0500358
Rasmus Villemoes875f2aa2019-05-13 11:14:56 +0000359 if (p)
360 clear_bit(p - snums, snum_state);
Li Yang98658532006-10-03 23:10:46 -0500361}
362EXPORT_SYMBOL(qe_put_snum);
363
364static int qe_sdma_init(void)
365{
Andy Fleming7e1cc9c2008-05-07 13:19:44 -0500366 struct sdma __iomem *sdma = &qe_immr->sdma;
Anton Vorontsov0c7b87b2009-09-16 01:43:52 +0400367 static unsigned long sdma_buf_offset = (unsigned long)-ENOMEM;
Li Yang98658532006-10-03 23:10:46 -0500368
369 if (!sdma)
370 return -ENODEV;
371
372 /* allocate 2 internal temporary buffers (512 bytes size each) for
373 * the SDMA */
Anton Vorontsov0c7b87b2009-09-16 01:43:52 +0400374 if (IS_ERR_VALUE(sdma_buf_offset)) {
375 sdma_buf_offset = qe_muram_alloc(512 * 2, 4096);
376 if (IS_ERR_VALUE(sdma_buf_offset))
377 return -ENOMEM;
378 }
Li Yang98658532006-10-03 23:10:46 -0500379
Timur Tabi4c356302007-05-08 14:46:36 -0500380 out_be32(&sdma->sdebcr, (u32) sdma_buf_offset & QE_SDEBCR_BA_MASK);
Chuck Meade7f013bc2007-03-27 10:46:10 -0400381 out_be32(&sdma->sdmr, (QE_SDMR_GLB_1_MSK |
382 (0x1 << QE_SDMR_CEN_SHIFT)));
Li Yang98658532006-10-03 23:10:46 -0500383
384 return 0;
385}
386
Timur Tabibc556ba2008-01-08 10:30:58 -0600387/* The maximum number of RISCs we support */
Anton Vorontsov98eaa092009-08-27 21:30:11 +0400388#define MAX_QE_RISC 4
Timur Tabibc556ba2008-01-08 10:30:58 -0600389
390/* Firmware information stored here for qe_get_firmware_info() */
391static struct qe_firmware_info qe_firmware_info;
392
393/*
394 * Set to 1 if QE firmware has been uploaded, and therefore
395 * qe_firmware_info contains valid data.
396 */
397static int qe_firmware_uploaded;
398
399/*
400 * Upload a QE microcode
401 *
402 * This function is a worker function for qe_upload_firmware(). It does
403 * the actual uploading of the microcode.
404 */
405static void qe_upload_microcode(const void *base,
406 const struct qe_microcode *ucode)
407{
408 const __be32 *code = base + be32_to_cpu(ucode->code_offset);
409 unsigned int i;
410
411 if (ucode->major || ucode->minor || ucode->revision)
412 printk(KERN_INFO "qe-firmware: "
413 "uploading microcode '%s' version %u.%u.%u\n",
414 ucode->id, ucode->major, ucode->minor, ucode->revision);
415 else
416 printk(KERN_INFO "qe-firmware: "
417 "uploading microcode '%s'\n", ucode->id);
418
419 /* Use auto-increment */
420 out_be32(&qe_immr->iram.iadd, be32_to_cpu(ucode->iram_offset) |
421 QE_IRAM_IADD_AIE | QE_IRAM_IADD_BADDR);
422
423 for (i = 0; i < be32_to_cpu(ucode->count); i++)
424 out_be32(&qe_immr->iram.idata, be32_to_cpu(code[i]));
Kokoris, Ioannise65650e2011-11-11 17:05:11 +0100425
426 /* Set I-RAM Ready Register */
427 out_be32(&qe_immr->iram.iready, be32_to_cpu(QE_IRAM_READY));
Timur Tabibc556ba2008-01-08 10:30:58 -0600428}
429
430/*
431 * Upload a microcode to the I-RAM at a specific address.
432 *
Mauro Carvalho Chehab4d2e26a2019-04-10 08:32:42 -0300433 * See Documentation/powerpc/qe_firmware.rst for information on QE microcode
Timur Tabibc556ba2008-01-08 10:30:58 -0600434 * uploading.
435 *
436 * Currently, only version 1 is supported, so the 'version' field must be
437 * set to 1.
438 *
439 * The SOC model and revision are not validated, they are only displayed for
440 * informational purposes.
441 *
442 * 'calc_size' is the calculated size, in bytes, of the firmware structure and
443 * all of the microcode structures, minus the CRC.
444 *
445 * 'length' is the size that the structure says it is, including the CRC.
446 */
447int qe_upload_firmware(const struct qe_firmware *firmware)
448{
449 unsigned int i;
450 unsigned int j;
451 u32 crc;
452 size_t calc_size = sizeof(struct qe_firmware);
453 size_t length;
454 const struct qe_header *hdr;
455
456 if (!firmware) {
457 printk(KERN_ERR "qe-firmware: invalid pointer\n");
458 return -EINVAL;
459 }
460
461 hdr = &firmware->header;
462 length = be32_to_cpu(hdr->length);
463
464 /* Check the magic */
465 if ((hdr->magic[0] != 'Q') || (hdr->magic[1] != 'E') ||
466 (hdr->magic[2] != 'F')) {
467 printk(KERN_ERR "qe-firmware: not a microcode\n");
468 return -EPERM;
469 }
470
471 /* Check the version */
472 if (hdr->version != 1) {
473 printk(KERN_ERR "qe-firmware: unsupported version\n");
474 return -EPERM;
475 }
476
477 /* Validate some of the fields */
Timur Tabi6f913162008-03-03 11:11:30 -0600478 if ((firmware->count < 1) || (firmware->count > MAX_QE_RISC)) {
Timur Tabibc556ba2008-01-08 10:30:58 -0600479 printk(KERN_ERR "qe-firmware: invalid data\n");
480 return -EINVAL;
481 }
482
483 /* Validate the length and check if there's a CRC */
484 calc_size += (firmware->count - 1) * sizeof(struct qe_microcode);
485
486 for (i = 0; i < firmware->count; i++)
487 /*
488 * For situations where the second RISC uses the same microcode
489 * as the first, the 'code_offset' and 'count' fields will be
490 * zero, so it's okay to add those.
491 */
492 calc_size += sizeof(__be32) *
493 be32_to_cpu(firmware->microcode[i].count);
494
495 /* Validate the length */
496 if (length != calc_size + sizeof(__be32)) {
497 printk(KERN_ERR "qe-firmware: invalid length\n");
498 return -EPERM;
499 }
500
501 /* Validate the CRC */
502 crc = be32_to_cpu(*(__be32 *)((void *)firmware + calc_size));
503 if (crc != crc32(0, firmware, calc_size)) {
504 printk(KERN_ERR "qe-firmware: firmware CRC is invalid\n");
505 return -EIO;
506 }
507
508 /*
509 * If the microcode calls for it, split the I-RAM.
510 */
511 if (!firmware->split)
512 setbits16(&qe_immr->cp.cercr, QE_CP_CERCR_CIR);
513
514 if (firmware->soc.model)
515 printk(KERN_INFO
516 "qe-firmware: firmware '%s' for %u V%u.%u\n",
517 firmware->id, be16_to_cpu(firmware->soc.model),
518 firmware->soc.major, firmware->soc.minor);
519 else
520 printk(KERN_INFO "qe-firmware: firmware '%s'\n",
521 firmware->id);
522
523 /*
524 * The QE only supports one microcode per RISC, so clear out all the
525 * saved microcode information and put in the new.
526 */
527 memset(&qe_firmware_info, 0, sizeof(qe_firmware_info));
Rickard Strandqvist5db43122014-07-26 23:26:51 +0200528 strlcpy(qe_firmware_info.id, firmware->id, sizeof(qe_firmware_info.id));
Timur Tabibc556ba2008-01-08 10:30:58 -0600529 qe_firmware_info.extended_modes = firmware->extended_modes;
530 memcpy(qe_firmware_info.vtraps, firmware->vtraps,
531 sizeof(firmware->vtraps));
532
533 /* Loop through each microcode. */
534 for (i = 0; i < firmware->count; i++) {
535 const struct qe_microcode *ucode = &firmware->microcode[i];
536
537 /* Upload a microcode if it's present */
538 if (ucode->code_offset)
539 qe_upload_microcode(firmware, ucode);
540
541 /* Program the traps for this processor */
542 for (j = 0; j < 16; j++) {
543 u32 trap = be32_to_cpu(ucode->traps[j]);
544
545 if (trap)
546 out_be32(&qe_immr->rsp[i].tibcr[j], trap);
547 }
548
549 /* Enable traps */
550 out_be32(&qe_immr->rsp[i].eccr, be32_to_cpu(ucode->eccr));
551 }
552
553 qe_firmware_uploaded = 1;
554
555 return 0;
556}
557EXPORT_SYMBOL(qe_upload_firmware);
558
559/*
560 * Get info on the currently-loaded firmware
561 *
562 * This function also checks the device tree to see if the boot loader has
563 * uploaded a firmware already.
564 */
565struct qe_firmware_info *qe_get_firmware_info(void)
566{
567 static int initialized;
568 struct property *prop;
569 struct device_node *qe;
570 struct device_node *fw = NULL;
571 const char *sprop;
572 unsigned int i;
573
574 /*
575 * If we haven't checked yet, and a driver hasn't uploaded a firmware
576 * yet, then check the device tree for information.
577 */
Ionut Nicu86f4e5d2008-03-07 19:27:59 +0200578 if (qe_firmware_uploaded)
579 return &qe_firmware_info;
580
581 if (initialized)
Timur Tabibc556ba2008-01-08 10:30:58 -0600582 return NULL;
583
584 initialized = 1;
585
Rasmus Villemoesd7fc5962019-05-13 11:14:57 +0000586 qe = qe_get_device_node();
587 if (!qe)
588 return NULL;
Timur Tabibc556ba2008-01-08 10:30:58 -0600589
590 /* Find the 'firmware' child node */
Rob Herringf55f6122018-08-29 15:04:25 -0500591 fw = of_get_child_by_name(qe, "firmware");
Timur Tabibc556ba2008-01-08 10:30:58 -0600592 of_node_put(qe);
593
594 /* Did we find the 'firmware' node? */
595 if (!fw)
596 return NULL;
597
598 qe_firmware_uploaded = 1;
599
600 /* Copy the data into qe_firmware_info*/
601 sprop = of_get_property(fw, "id", NULL);
602 if (sprop)
Rickard Strandqvist5db43122014-07-26 23:26:51 +0200603 strlcpy(qe_firmware_info.id, sprop,
604 sizeof(qe_firmware_info.id));
Timur Tabibc556ba2008-01-08 10:30:58 -0600605
606 prop = of_find_property(fw, "extended-modes", NULL);
607 if (prop && (prop->length == sizeof(u64))) {
608 const u64 *iprop = prop->value;
609
610 qe_firmware_info.extended_modes = *iprop;
611 }
612
613 prop = of_find_property(fw, "virtual-traps", NULL);
614 if (prop && (prop->length == 32)) {
615 const u32 *iprop = prop->value;
616
617 for (i = 0; i < ARRAY_SIZE(qe_firmware_info.vtraps); i++)
618 qe_firmware_info.vtraps[i] = iprop[i];
619 }
620
621 of_node_put(fw);
622
623 return &qe_firmware_info;
624}
625EXPORT_SYMBOL(qe_get_firmware_info);
626
Haiying Wang06c44352009-05-01 15:40:47 -0400627unsigned int qe_get_num_of_risc(void)
628{
629 struct device_node *qe;
630 int size;
631 unsigned int num_of_risc = 0;
632 const u32 *prop;
633
Rasmus Villemoesd7fc5962019-05-13 11:14:57 +0000634 qe = qe_get_device_node();
635 if (!qe)
636 return num_of_risc;
Haiying Wang06c44352009-05-01 15:40:47 -0400637
638 prop = of_get_property(qe, "fsl,qe-num-riscs", &size);
639 if (prop && size == sizeof(*prop))
640 num_of_risc = *prop;
641
642 of_node_put(qe);
643
644 return num_of_risc;
645}
646EXPORT_SYMBOL(qe_get_num_of_risc);
647
Haiying Wang98ca77a2009-05-01 15:40:48 -0400648unsigned int qe_get_num_of_snums(void)
649{
Rasmus Villemoes21560062019-05-13 11:15:01 +0000650 return qe_num_of_snum;
Haiying Wang98ca77a2009-05-01 15:40:48 -0400651}
652EXPORT_SYMBOL(qe_get_num_of_snums);
Anton Vorontsovfdfde242009-09-16 01:43:55 +0400653
Zhao Qiang302c0592015-11-30 10:48:56 +0800654static int __init qe_init(void)
655{
656 struct device_node *np;
657
658 np = of_find_compatible_node(NULL, NULL, "fsl,qe");
659 if (!np)
660 return -ENODEV;
661 qe_reset();
662 of_node_put(np);
663 return 0;
664}
665subsys_initcall(qe_init);
666
Anton Vorontsovfdfde242009-09-16 01:43:55 +0400667#if defined(CONFIG_SUSPEND) && defined(CONFIG_PPC_85xx)
Grant Likelya454dc52010-07-22 15:52:34 -0600668static int qe_resume(struct platform_device *ofdev)
Anton Vorontsovfdfde242009-09-16 01:43:55 +0400669{
670 if (!qe_alive_during_sleep())
671 qe_reset();
672 return 0;
673}
674
Grant Likely00006122011-02-22 19:59:54 -0700675static int qe_probe(struct platform_device *ofdev)
Anton Vorontsovfdfde242009-09-16 01:43:55 +0400676{
677 return 0;
678}
679
680static const struct of_device_id qe_ids[] = {
681 { .compatible = "fsl,qe", },
682 { },
683};
684
Grant Likely00006122011-02-22 19:59:54 -0700685static struct platform_driver qe_driver = {
Grant Likely40182942010-04-13 16:13:02 -0700686 .driver = {
687 .name = "fsl-qe",
Grant Likely40182942010-04-13 16:13:02 -0700688 .of_match_table = qe_ids,
689 },
Anton Vorontsovfdfde242009-09-16 01:43:55 +0400690 .probe = qe_probe,
691 .resume = qe_resume,
692};
693
Geliang Tangc9492b42016-11-23 23:04:21 +0800694builtin_platform_driver(qe_driver);
Anton Vorontsovfdfde242009-09-16 01:43:55 +0400695#endif /* defined(CONFIG_SUSPEND) && defined(CONFIG_PPC_85xx) */