1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0-or-later
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun * Copyright (C) 2006-2010 Freescale Semiconductor, Inc. All rights reserved.
4*4882a593Smuzhiyun *
5*4882a593Smuzhiyun * Authors: Shlomi Gridish <gridish@freescale.com>
6*4882a593Smuzhiyun * Li Yang <leoli@freescale.com>
7*4882a593Smuzhiyun * Based on cpm2_common.c from Dan Malek (dmalek@jlc.net)
8*4882a593Smuzhiyun *
9*4882a593Smuzhiyun * Description:
10*4882a593Smuzhiyun * General Purpose functions for the global management of the
11*4882a593Smuzhiyun * QUICC Engine (QE).
12*4882a593Smuzhiyun */
13*4882a593Smuzhiyun #include <linux/bitmap.h>
14*4882a593Smuzhiyun #include <linux/errno.h>
15*4882a593Smuzhiyun #include <linux/sched.h>
16*4882a593Smuzhiyun #include <linux/kernel.h>
17*4882a593Smuzhiyun #include <linux/param.h>
18*4882a593Smuzhiyun #include <linux/string.h>
19*4882a593Smuzhiyun #include <linux/spinlock.h>
20*4882a593Smuzhiyun #include <linux/mm.h>
21*4882a593Smuzhiyun #include <linux/interrupt.h>
22*4882a593Smuzhiyun #include <linux/module.h>
23*4882a593Smuzhiyun #include <linux/delay.h>
24*4882a593Smuzhiyun #include <linux/ioport.h>
25*4882a593Smuzhiyun #include <linux/iopoll.h>
26*4882a593Smuzhiyun #include <linux/crc32.h>
27*4882a593Smuzhiyun #include <linux/mod_devicetable.h>
28*4882a593Smuzhiyun #include <linux/of_platform.h>
29*4882a593Smuzhiyun #include <soc/fsl/qe/immap_qe.h>
30*4882a593Smuzhiyun #include <soc/fsl/qe/qe.h>
31*4882a593Smuzhiyun
32*4882a593Smuzhiyun static void qe_snums_init(void);
33*4882a593Smuzhiyun static int qe_sdma_init(void);
34*4882a593Smuzhiyun
35*4882a593Smuzhiyun static DEFINE_SPINLOCK(qe_lock);
36*4882a593Smuzhiyun DEFINE_SPINLOCK(cmxgcr_lock);
37*4882a593Smuzhiyun EXPORT_SYMBOL(cmxgcr_lock);
38*4882a593Smuzhiyun
39*4882a593Smuzhiyun /* We allocate this here because it is used almost exclusively for
40*4882a593Smuzhiyun * the communication processor devices.
41*4882a593Smuzhiyun */
42*4882a593Smuzhiyun struct qe_immap __iomem *qe_immr;
43*4882a593Smuzhiyun EXPORT_SYMBOL(qe_immr);
44*4882a593Smuzhiyun
45*4882a593Smuzhiyun static u8 snums[QE_NUM_OF_SNUM]; /* Dynamically allocated SNUMs */
46*4882a593Smuzhiyun static DECLARE_BITMAP(snum_state, QE_NUM_OF_SNUM);
47*4882a593Smuzhiyun static unsigned int qe_num_of_snum;
48*4882a593Smuzhiyun
49*4882a593Smuzhiyun static phys_addr_t qebase = -1;
50*4882a593Smuzhiyun
qe_get_device_node(void)51*4882a593Smuzhiyun static struct device_node *qe_get_device_node(void)
52*4882a593Smuzhiyun {
53*4882a593Smuzhiyun struct device_node *qe;
54*4882a593Smuzhiyun
55*4882a593Smuzhiyun /*
56*4882a593Smuzhiyun * Newer device trees have an "fsl,qe" compatible property for the QE
57*4882a593Smuzhiyun * node, but we still need to support older device trees.
58*4882a593Smuzhiyun */
59*4882a593Smuzhiyun qe = of_find_compatible_node(NULL, NULL, "fsl,qe");
60*4882a593Smuzhiyun if (qe)
61*4882a593Smuzhiyun return qe;
62*4882a593Smuzhiyun return of_find_node_by_type(NULL, "qe");
63*4882a593Smuzhiyun }
64*4882a593Smuzhiyun
get_qe_base(void)65*4882a593Smuzhiyun static phys_addr_t get_qe_base(void)
66*4882a593Smuzhiyun {
67*4882a593Smuzhiyun struct device_node *qe;
68*4882a593Smuzhiyun int ret;
69*4882a593Smuzhiyun struct resource res;
70*4882a593Smuzhiyun
71*4882a593Smuzhiyun if (qebase != -1)
72*4882a593Smuzhiyun return qebase;
73*4882a593Smuzhiyun
74*4882a593Smuzhiyun qe = qe_get_device_node();
75*4882a593Smuzhiyun if (!qe)
76*4882a593Smuzhiyun return qebase;
77*4882a593Smuzhiyun
78*4882a593Smuzhiyun ret = of_address_to_resource(qe, 0, &res);
79*4882a593Smuzhiyun if (!ret)
80*4882a593Smuzhiyun qebase = res.start;
81*4882a593Smuzhiyun of_node_put(qe);
82*4882a593Smuzhiyun
83*4882a593Smuzhiyun return qebase;
84*4882a593Smuzhiyun }
85*4882a593Smuzhiyun
qe_reset(void)86*4882a593Smuzhiyun void qe_reset(void)
87*4882a593Smuzhiyun {
88*4882a593Smuzhiyun if (qe_immr == NULL)
89*4882a593Smuzhiyun qe_immr = ioremap(get_qe_base(), QE_IMMAP_SIZE);
90*4882a593Smuzhiyun
91*4882a593Smuzhiyun qe_snums_init();
92*4882a593Smuzhiyun
93*4882a593Smuzhiyun qe_issue_cmd(QE_RESET, QE_CR_SUBBLOCK_INVALID,
94*4882a593Smuzhiyun QE_CR_PROTOCOL_UNSPECIFIED, 0);
95*4882a593Smuzhiyun
96*4882a593Smuzhiyun /* Reclaim the MURAM memory for our use. */
97*4882a593Smuzhiyun qe_muram_init();
98*4882a593Smuzhiyun
99*4882a593Smuzhiyun if (qe_sdma_init())
100*4882a593Smuzhiyun panic("sdma init failed!");
101*4882a593Smuzhiyun }
102*4882a593Smuzhiyun
qe_issue_cmd(u32 cmd,u32 device,u8 mcn_protocol,u32 cmd_input)103*4882a593Smuzhiyun int qe_issue_cmd(u32 cmd, u32 device, u8 mcn_protocol, u32 cmd_input)
104*4882a593Smuzhiyun {
105*4882a593Smuzhiyun unsigned long flags;
106*4882a593Smuzhiyun u8 mcn_shift = 0, dev_shift = 0;
107*4882a593Smuzhiyun u32 val;
108*4882a593Smuzhiyun int ret;
109*4882a593Smuzhiyun
110*4882a593Smuzhiyun spin_lock_irqsave(&qe_lock, flags);
111*4882a593Smuzhiyun if (cmd == QE_RESET) {
112*4882a593Smuzhiyun qe_iowrite32be((u32)(cmd | QE_CR_FLG), &qe_immr->cp.cecr);
113*4882a593Smuzhiyun } else {
114*4882a593Smuzhiyun if (cmd == QE_ASSIGN_PAGE) {
115*4882a593Smuzhiyun /* Here device is the SNUM, not sub-block */
116*4882a593Smuzhiyun dev_shift = QE_CR_SNUM_SHIFT;
117*4882a593Smuzhiyun } else if (cmd == QE_ASSIGN_RISC) {
118*4882a593Smuzhiyun /* Here device is the SNUM, and mcnProtocol is
119*4882a593Smuzhiyun * e_QeCmdRiscAssignment value */
120*4882a593Smuzhiyun dev_shift = QE_CR_SNUM_SHIFT;
121*4882a593Smuzhiyun mcn_shift = QE_CR_MCN_RISC_ASSIGN_SHIFT;
122*4882a593Smuzhiyun } else {
123*4882a593Smuzhiyun if (device == QE_CR_SUBBLOCK_USB)
124*4882a593Smuzhiyun mcn_shift = QE_CR_MCN_USB_SHIFT;
125*4882a593Smuzhiyun else
126*4882a593Smuzhiyun mcn_shift = QE_CR_MCN_NORMAL_SHIFT;
127*4882a593Smuzhiyun }
128*4882a593Smuzhiyun
129*4882a593Smuzhiyun qe_iowrite32be(cmd_input, &qe_immr->cp.cecdr);
130*4882a593Smuzhiyun qe_iowrite32be((cmd | QE_CR_FLG | ((u32)device << dev_shift) | (u32)mcn_protocol << mcn_shift),
131*4882a593Smuzhiyun &qe_immr->cp.cecr);
132*4882a593Smuzhiyun }
133*4882a593Smuzhiyun
134*4882a593Smuzhiyun /* wait for the QE_CR_FLG to clear */
135*4882a593Smuzhiyun ret = readx_poll_timeout_atomic(qe_ioread32be, &qe_immr->cp.cecr, val,
136*4882a593Smuzhiyun (val & QE_CR_FLG) == 0, 0, 100);
137*4882a593Smuzhiyun /* On timeout, ret is -ETIMEDOUT, otherwise it will be 0. */
138*4882a593Smuzhiyun spin_unlock_irqrestore(&qe_lock, flags);
139*4882a593Smuzhiyun
140*4882a593Smuzhiyun return ret == 0;
141*4882a593Smuzhiyun }
142*4882a593Smuzhiyun EXPORT_SYMBOL(qe_issue_cmd);
143*4882a593Smuzhiyun
144*4882a593Smuzhiyun /* Set a baud rate generator. This needs lots of work. There are
145*4882a593Smuzhiyun * 16 BRGs, which can be connected to the QE channels or output
146*4882a593Smuzhiyun * as clocks. The BRGs are in two different block of internal
147*4882a593Smuzhiyun * memory mapped space.
148*4882a593Smuzhiyun * The BRG clock is the QE clock divided by 2.
149*4882a593Smuzhiyun * It was set up long ago during the initial boot phase and is
150*4882a593Smuzhiyun * is given to us.
151*4882a593Smuzhiyun * Baud rate clocks are zero-based in the driver code (as that maps
152*4882a593Smuzhiyun * to port numbers). Documentation uses 1-based numbering.
153*4882a593Smuzhiyun */
154*4882a593Smuzhiyun static unsigned int brg_clk = 0;
155*4882a593Smuzhiyun
156*4882a593Smuzhiyun #define CLK_GRAN (1000)
157*4882a593Smuzhiyun #define CLK_GRAN_LIMIT (5)
158*4882a593Smuzhiyun
qe_get_brg_clk(void)159*4882a593Smuzhiyun unsigned int qe_get_brg_clk(void)
160*4882a593Smuzhiyun {
161*4882a593Smuzhiyun struct device_node *qe;
162*4882a593Smuzhiyun u32 brg;
163*4882a593Smuzhiyun unsigned int mod;
164*4882a593Smuzhiyun
165*4882a593Smuzhiyun if (brg_clk)
166*4882a593Smuzhiyun return brg_clk;
167*4882a593Smuzhiyun
168*4882a593Smuzhiyun qe = qe_get_device_node();
169*4882a593Smuzhiyun if (!qe)
170*4882a593Smuzhiyun return brg_clk;
171*4882a593Smuzhiyun
172*4882a593Smuzhiyun if (!of_property_read_u32(qe, "brg-frequency", &brg))
173*4882a593Smuzhiyun brg_clk = brg;
174*4882a593Smuzhiyun
175*4882a593Smuzhiyun of_node_put(qe);
176*4882a593Smuzhiyun
177*4882a593Smuzhiyun /* round this if near to a multiple of CLK_GRAN */
178*4882a593Smuzhiyun mod = brg_clk % CLK_GRAN;
179*4882a593Smuzhiyun if (mod) {
180*4882a593Smuzhiyun if (mod < CLK_GRAN_LIMIT)
181*4882a593Smuzhiyun brg_clk -= mod;
182*4882a593Smuzhiyun else if (mod > (CLK_GRAN - CLK_GRAN_LIMIT))
183*4882a593Smuzhiyun brg_clk += CLK_GRAN - mod;
184*4882a593Smuzhiyun }
185*4882a593Smuzhiyun
186*4882a593Smuzhiyun return brg_clk;
187*4882a593Smuzhiyun }
188*4882a593Smuzhiyun EXPORT_SYMBOL(qe_get_brg_clk);
189*4882a593Smuzhiyun
190*4882a593Smuzhiyun #define PVR_VER_836x 0x8083
191*4882a593Smuzhiyun #define PVR_VER_832x 0x8084
192*4882a593Smuzhiyun
qe_general4_errata(void)193*4882a593Smuzhiyun static bool qe_general4_errata(void)
194*4882a593Smuzhiyun {
195*4882a593Smuzhiyun #ifdef CONFIG_PPC32
196*4882a593Smuzhiyun return pvr_version_is(PVR_VER_836x) || pvr_version_is(PVR_VER_832x);
197*4882a593Smuzhiyun #endif
198*4882a593Smuzhiyun return false;
199*4882a593Smuzhiyun }
200*4882a593Smuzhiyun
201*4882a593Smuzhiyun /* Program the BRG to the given sampling rate and multiplier
202*4882a593Smuzhiyun *
203*4882a593Smuzhiyun * @brg: the BRG, QE_BRG1 - QE_BRG16
204*4882a593Smuzhiyun * @rate: the desired sampling rate
205*4882a593Smuzhiyun * @multiplier: corresponds to the value programmed in GUMR_L[RDCR] or
206*4882a593Smuzhiyun * GUMR_L[TDCR]. E.g., if this BRG is the RX clock, and GUMR_L[RDCR]=01,
207*4882a593Smuzhiyun * then 'multiplier' should be 8.
208*4882a593Smuzhiyun */
qe_setbrg(enum qe_clock brg,unsigned int rate,unsigned int multiplier)209*4882a593Smuzhiyun int qe_setbrg(enum qe_clock brg, unsigned int rate, unsigned int multiplier)
210*4882a593Smuzhiyun {
211*4882a593Smuzhiyun u32 divisor, tempval;
212*4882a593Smuzhiyun u32 div16 = 0;
213*4882a593Smuzhiyun
214*4882a593Smuzhiyun if ((brg < QE_BRG1) || (brg > QE_BRG16))
215*4882a593Smuzhiyun return -EINVAL;
216*4882a593Smuzhiyun
217*4882a593Smuzhiyun divisor = qe_get_brg_clk() / (rate * multiplier);
218*4882a593Smuzhiyun
219*4882a593Smuzhiyun if (divisor > QE_BRGC_DIVISOR_MAX + 1) {
220*4882a593Smuzhiyun div16 = QE_BRGC_DIV16;
221*4882a593Smuzhiyun divisor /= 16;
222*4882a593Smuzhiyun }
223*4882a593Smuzhiyun
224*4882a593Smuzhiyun /* Errata QE_General4, which affects some MPC832x and MPC836x SOCs, says
225*4882a593Smuzhiyun that the BRG divisor must be even if you're not using divide-by-16
226*4882a593Smuzhiyun mode. */
227*4882a593Smuzhiyun if (qe_general4_errata())
228*4882a593Smuzhiyun if (!div16 && (divisor & 1) && (divisor > 3))
229*4882a593Smuzhiyun divisor++;
230*4882a593Smuzhiyun
231*4882a593Smuzhiyun tempval = ((divisor - 1) << QE_BRGC_DIVISOR_SHIFT) |
232*4882a593Smuzhiyun QE_BRGC_ENABLE | div16;
233*4882a593Smuzhiyun
234*4882a593Smuzhiyun qe_iowrite32be(tempval, &qe_immr->brg.brgc[brg - QE_BRG1]);
235*4882a593Smuzhiyun
236*4882a593Smuzhiyun return 0;
237*4882a593Smuzhiyun }
238*4882a593Smuzhiyun EXPORT_SYMBOL(qe_setbrg);
239*4882a593Smuzhiyun
240*4882a593Smuzhiyun /* Convert a string to a QE clock source enum
241*4882a593Smuzhiyun *
242*4882a593Smuzhiyun * This function takes a string, typically from a property in the device
243*4882a593Smuzhiyun * tree, and returns the corresponding "enum qe_clock" value.
244*4882a593Smuzhiyun */
qe_clock_source(const char * source)245*4882a593Smuzhiyun enum qe_clock qe_clock_source(const char *source)
246*4882a593Smuzhiyun {
247*4882a593Smuzhiyun unsigned int i;
248*4882a593Smuzhiyun
249*4882a593Smuzhiyun if (strcasecmp(source, "none") == 0)
250*4882a593Smuzhiyun return QE_CLK_NONE;
251*4882a593Smuzhiyun
252*4882a593Smuzhiyun if (strcmp(source, "tsync_pin") == 0)
253*4882a593Smuzhiyun return QE_TSYNC_PIN;
254*4882a593Smuzhiyun
255*4882a593Smuzhiyun if (strcmp(source, "rsync_pin") == 0)
256*4882a593Smuzhiyun return QE_RSYNC_PIN;
257*4882a593Smuzhiyun
258*4882a593Smuzhiyun if (strncasecmp(source, "brg", 3) == 0) {
259*4882a593Smuzhiyun i = simple_strtoul(source + 3, NULL, 10);
260*4882a593Smuzhiyun if ((i >= 1) && (i <= 16))
261*4882a593Smuzhiyun return (QE_BRG1 - 1) + i;
262*4882a593Smuzhiyun else
263*4882a593Smuzhiyun return QE_CLK_DUMMY;
264*4882a593Smuzhiyun }
265*4882a593Smuzhiyun
266*4882a593Smuzhiyun if (strncasecmp(source, "clk", 3) == 0) {
267*4882a593Smuzhiyun i = simple_strtoul(source + 3, NULL, 10);
268*4882a593Smuzhiyun if ((i >= 1) && (i <= 24))
269*4882a593Smuzhiyun return (QE_CLK1 - 1) + i;
270*4882a593Smuzhiyun else
271*4882a593Smuzhiyun return QE_CLK_DUMMY;
272*4882a593Smuzhiyun }
273*4882a593Smuzhiyun
274*4882a593Smuzhiyun return QE_CLK_DUMMY;
275*4882a593Smuzhiyun }
276*4882a593Smuzhiyun EXPORT_SYMBOL(qe_clock_source);
277*4882a593Smuzhiyun
278*4882a593Smuzhiyun /* Initialize SNUMs (thread serial numbers) according to
279*4882a593Smuzhiyun * QE Module Control chapter, SNUM table
280*4882a593Smuzhiyun */
qe_snums_init(void)281*4882a593Smuzhiyun static void qe_snums_init(void)
282*4882a593Smuzhiyun {
283*4882a593Smuzhiyun static const u8 snum_init_76[] = {
284*4882a593Smuzhiyun 0x04, 0x05, 0x0C, 0x0D, 0x14, 0x15, 0x1C, 0x1D,
285*4882a593Smuzhiyun 0x24, 0x25, 0x2C, 0x2D, 0x34, 0x35, 0x88, 0x89,
286*4882a593Smuzhiyun 0x98, 0x99, 0xA8, 0xA9, 0xB8, 0xB9, 0xC8, 0xC9,
287*4882a593Smuzhiyun 0xD8, 0xD9, 0xE8, 0xE9, 0x44, 0x45, 0x4C, 0x4D,
288*4882a593Smuzhiyun 0x54, 0x55, 0x5C, 0x5D, 0x64, 0x65, 0x6C, 0x6D,
289*4882a593Smuzhiyun 0x74, 0x75, 0x7C, 0x7D, 0x84, 0x85, 0x8C, 0x8D,
290*4882a593Smuzhiyun 0x94, 0x95, 0x9C, 0x9D, 0xA4, 0xA5, 0xAC, 0xAD,
291*4882a593Smuzhiyun 0xB4, 0xB5, 0xBC, 0xBD, 0xC4, 0xC5, 0xCC, 0xCD,
292*4882a593Smuzhiyun 0xD4, 0xD5, 0xDC, 0xDD, 0xE4, 0xE5, 0xEC, 0xED,
293*4882a593Smuzhiyun 0xF4, 0xF5, 0xFC, 0xFD,
294*4882a593Smuzhiyun };
295*4882a593Smuzhiyun static const u8 snum_init_46[] = {
296*4882a593Smuzhiyun 0x04, 0x05, 0x0C, 0x0D, 0x14, 0x15, 0x1C, 0x1D,
297*4882a593Smuzhiyun 0x24, 0x25, 0x2C, 0x2D, 0x34, 0x35, 0x88, 0x89,
298*4882a593Smuzhiyun 0x98, 0x99, 0xA8, 0xA9, 0xB8, 0xB9, 0xC8, 0xC9,
299*4882a593Smuzhiyun 0xD8, 0xD9, 0xE8, 0xE9, 0x08, 0x09, 0x18, 0x19,
300*4882a593Smuzhiyun 0x28, 0x29, 0x38, 0x39, 0x48, 0x49, 0x58, 0x59,
301*4882a593Smuzhiyun 0x68, 0x69, 0x78, 0x79, 0x80, 0x81,
302*4882a593Smuzhiyun };
303*4882a593Smuzhiyun struct device_node *qe;
304*4882a593Smuzhiyun const u8 *snum_init;
305*4882a593Smuzhiyun int i;
306*4882a593Smuzhiyun
307*4882a593Smuzhiyun bitmap_zero(snum_state, QE_NUM_OF_SNUM);
308*4882a593Smuzhiyun qe_num_of_snum = 28; /* The default number of snum for threads is 28 */
309*4882a593Smuzhiyun qe = qe_get_device_node();
310*4882a593Smuzhiyun if (qe) {
311*4882a593Smuzhiyun i = of_property_read_variable_u8_array(qe, "fsl,qe-snums",
312*4882a593Smuzhiyun snums, 1, QE_NUM_OF_SNUM);
313*4882a593Smuzhiyun if (i > 0) {
314*4882a593Smuzhiyun of_node_put(qe);
315*4882a593Smuzhiyun qe_num_of_snum = i;
316*4882a593Smuzhiyun return;
317*4882a593Smuzhiyun }
318*4882a593Smuzhiyun /*
319*4882a593Smuzhiyun * Fall back to legacy binding of using the value of
320*4882a593Smuzhiyun * fsl,qe-num-snums to choose one of the static arrays
321*4882a593Smuzhiyun * above.
322*4882a593Smuzhiyun */
323*4882a593Smuzhiyun of_property_read_u32(qe, "fsl,qe-num-snums", &qe_num_of_snum);
324*4882a593Smuzhiyun of_node_put(qe);
325*4882a593Smuzhiyun }
326*4882a593Smuzhiyun
327*4882a593Smuzhiyun if (qe_num_of_snum == 76) {
328*4882a593Smuzhiyun snum_init = snum_init_76;
329*4882a593Smuzhiyun } else if (qe_num_of_snum == 28 || qe_num_of_snum == 46) {
330*4882a593Smuzhiyun snum_init = snum_init_46;
331*4882a593Smuzhiyun } else {
332*4882a593Smuzhiyun pr_err("QE: unsupported value of fsl,qe-num-snums: %u\n", qe_num_of_snum);
333*4882a593Smuzhiyun return;
334*4882a593Smuzhiyun }
335*4882a593Smuzhiyun memcpy(snums, snum_init, qe_num_of_snum);
336*4882a593Smuzhiyun }
337*4882a593Smuzhiyun
qe_get_snum(void)338*4882a593Smuzhiyun int qe_get_snum(void)
339*4882a593Smuzhiyun {
340*4882a593Smuzhiyun unsigned long flags;
341*4882a593Smuzhiyun int snum = -EBUSY;
342*4882a593Smuzhiyun int i;
343*4882a593Smuzhiyun
344*4882a593Smuzhiyun spin_lock_irqsave(&qe_lock, flags);
345*4882a593Smuzhiyun i = find_first_zero_bit(snum_state, qe_num_of_snum);
346*4882a593Smuzhiyun if (i < qe_num_of_snum) {
347*4882a593Smuzhiyun set_bit(i, snum_state);
348*4882a593Smuzhiyun snum = snums[i];
349*4882a593Smuzhiyun }
350*4882a593Smuzhiyun spin_unlock_irqrestore(&qe_lock, flags);
351*4882a593Smuzhiyun
352*4882a593Smuzhiyun return snum;
353*4882a593Smuzhiyun }
354*4882a593Smuzhiyun EXPORT_SYMBOL(qe_get_snum);
355*4882a593Smuzhiyun
qe_put_snum(u8 snum)356*4882a593Smuzhiyun void qe_put_snum(u8 snum)
357*4882a593Smuzhiyun {
358*4882a593Smuzhiyun const u8 *p = memchr(snums, snum, qe_num_of_snum);
359*4882a593Smuzhiyun
360*4882a593Smuzhiyun if (p)
361*4882a593Smuzhiyun clear_bit(p - snums, snum_state);
362*4882a593Smuzhiyun }
363*4882a593Smuzhiyun EXPORT_SYMBOL(qe_put_snum);
364*4882a593Smuzhiyun
qe_sdma_init(void)365*4882a593Smuzhiyun static int qe_sdma_init(void)
366*4882a593Smuzhiyun {
367*4882a593Smuzhiyun struct sdma __iomem *sdma = &qe_immr->sdma;
368*4882a593Smuzhiyun static s32 sdma_buf_offset = -ENOMEM;
369*4882a593Smuzhiyun
370*4882a593Smuzhiyun /* allocate 2 internal temporary buffers (512 bytes size each) for
371*4882a593Smuzhiyun * the SDMA */
372*4882a593Smuzhiyun if (sdma_buf_offset < 0) {
373*4882a593Smuzhiyun sdma_buf_offset = qe_muram_alloc(512 * 2, 4096);
374*4882a593Smuzhiyun if (sdma_buf_offset < 0)
375*4882a593Smuzhiyun return -ENOMEM;
376*4882a593Smuzhiyun }
377*4882a593Smuzhiyun
378*4882a593Smuzhiyun qe_iowrite32be((u32)sdma_buf_offset & QE_SDEBCR_BA_MASK,
379*4882a593Smuzhiyun &sdma->sdebcr);
380*4882a593Smuzhiyun qe_iowrite32be((QE_SDMR_GLB_1_MSK | (0x1 << QE_SDMR_CEN_SHIFT)),
381*4882a593Smuzhiyun &sdma->sdmr);
382*4882a593Smuzhiyun
383*4882a593Smuzhiyun return 0;
384*4882a593Smuzhiyun }
385*4882a593Smuzhiyun
386*4882a593Smuzhiyun /* The maximum number of RISCs we support */
387*4882a593Smuzhiyun #define MAX_QE_RISC 4
388*4882a593Smuzhiyun
389*4882a593Smuzhiyun /* Firmware information stored here for qe_get_firmware_info() */
390*4882a593Smuzhiyun static struct qe_firmware_info qe_firmware_info;
391*4882a593Smuzhiyun
392*4882a593Smuzhiyun /*
393*4882a593Smuzhiyun * Set to 1 if QE firmware has been uploaded, and therefore
394*4882a593Smuzhiyun * qe_firmware_info contains valid data.
395*4882a593Smuzhiyun */
396*4882a593Smuzhiyun static int qe_firmware_uploaded;
397*4882a593Smuzhiyun
398*4882a593Smuzhiyun /*
399*4882a593Smuzhiyun * Upload a QE microcode
400*4882a593Smuzhiyun *
401*4882a593Smuzhiyun * This function is a worker function for qe_upload_firmware(). It does
402*4882a593Smuzhiyun * the actual uploading of the microcode.
403*4882a593Smuzhiyun */
qe_upload_microcode(const void * base,const struct qe_microcode * ucode)404*4882a593Smuzhiyun static void qe_upload_microcode(const void *base,
405*4882a593Smuzhiyun const struct qe_microcode *ucode)
406*4882a593Smuzhiyun {
407*4882a593Smuzhiyun const __be32 *code = base + be32_to_cpu(ucode->code_offset);
408*4882a593Smuzhiyun unsigned int i;
409*4882a593Smuzhiyun
410*4882a593Smuzhiyun if (ucode->major || ucode->minor || ucode->revision)
411*4882a593Smuzhiyun printk(KERN_INFO "qe-firmware: "
412*4882a593Smuzhiyun "uploading microcode '%s' version %u.%u.%u\n",
413*4882a593Smuzhiyun ucode->id, ucode->major, ucode->minor, ucode->revision);
414*4882a593Smuzhiyun else
415*4882a593Smuzhiyun printk(KERN_INFO "qe-firmware: "
416*4882a593Smuzhiyun "uploading microcode '%s'\n", ucode->id);
417*4882a593Smuzhiyun
418*4882a593Smuzhiyun /* Use auto-increment */
419*4882a593Smuzhiyun qe_iowrite32be(be32_to_cpu(ucode->iram_offset) | QE_IRAM_IADD_AIE | QE_IRAM_IADD_BADDR,
420*4882a593Smuzhiyun &qe_immr->iram.iadd);
421*4882a593Smuzhiyun
422*4882a593Smuzhiyun for (i = 0; i < be32_to_cpu(ucode->count); i++)
423*4882a593Smuzhiyun qe_iowrite32be(be32_to_cpu(code[i]), &qe_immr->iram.idata);
424*4882a593Smuzhiyun
425*4882a593Smuzhiyun /* Set I-RAM Ready Register */
426*4882a593Smuzhiyun qe_iowrite32be(QE_IRAM_READY, &qe_immr->iram.iready);
427*4882a593Smuzhiyun }
428*4882a593Smuzhiyun
429*4882a593Smuzhiyun /*
430*4882a593Smuzhiyun * Upload a microcode to the I-RAM at a specific address.
431*4882a593Smuzhiyun *
432*4882a593Smuzhiyun * See Documentation/powerpc/qe_firmware.rst for information on QE microcode
433*4882a593Smuzhiyun * uploading.
434*4882a593Smuzhiyun *
435*4882a593Smuzhiyun * Currently, only version 1 is supported, so the 'version' field must be
436*4882a593Smuzhiyun * set to 1.
437*4882a593Smuzhiyun *
438*4882a593Smuzhiyun * The SOC model and revision are not validated, they are only displayed for
439*4882a593Smuzhiyun * informational purposes.
440*4882a593Smuzhiyun *
441*4882a593Smuzhiyun * 'calc_size' is the calculated size, in bytes, of the firmware structure and
442*4882a593Smuzhiyun * all of the microcode structures, minus the CRC.
443*4882a593Smuzhiyun *
444*4882a593Smuzhiyun * 'length' is the size that the structure says it is, including the CRC.
445*4882a593Smuzhiyun */
qe_upload_firmware(const struct qe_firmware * firmware)446*4882a593Smuzhiyun int qe_upload_firmware(const struct qe_firmware *firmware)
447*4882a593Smuzhiyun {
448*4882a593Smuzhiyun unsigned int i;
449*4882a593Smuzhiyun unsigned int j;
450*4882a593Smuzhiyun u32 crc;
451*4882a593Smuzhiyun size_t calc_size;
452*4882a593Smuzhiyun size_t length;
453*4882a593Smuzhiyun const struct qe_header *hdr;
454*4882a593Smuzhiyun
455*4882a593Smuzhiyun if (!firmware) {
456*4882a593Smuzhiyun printk(KERN_ERR "qe-firmware: invalid pointer\n");
457*4882a593Smuzhiyun return -EINVAL;
458*4882a593Smuzhiyun }
459*4882a593Smuzhiyun
460*4882a593Smuzhiyun hdr = &firmware->header;
461*4882a593Smuzhiyun length = be32_to_cpu(hdr->length);
462*4882a593Smuzhiyun
463*4882a593Smuzhiyun /* Check the magic */
464*4882a593Smuzhiyun if ((hdr->magic[0] != 'Q') || (hdr->magic[1] != 'E') ||
465*4882a593Smuzhiyun (hdr->magic[2] != 'F')) {
466*4882a593Smuzhiyun printk(KERN_ERR "qe-firmware: not a microcode\n");
467*4882a593Smuzhiyun return -EPERM;
468*4882a593Smuzhiyun }
469*4882a593Smuzhiyun
470*4882a593Smuzhiyun /* Check the version */
471*4882a593Smuzhiyun if (hdr->version != 1) {
472*4882a593Smuzhiyun printk(KERN_ERR "qe-firmware: unsupported version\n");
473*4882a593Smuzhiyun return -EPERM;
474*4882a593Smuzhiyun }
475*4882a593Smuzhiyun
476*4882a593Smuzhiyun /* Validate some of the fields */
477*4882a593Smuzhiyun if ((firmware->count < 1) || (firmware->count > MAX_QE_RISC)) {
478*4882a593Smuzhiyun printk(KERN_ERR "qe-firmware: invalid data\n");
479*4882a593Smuzhiyun return -EINVAL;
480*4882a593Smuzhiyun }
481*4882a593Smuzhiyun
482*4882a593Smuzhiyun /* Validate the length and check if there's a CRC */
483*4882a593Smuzhiyun calc_size = struct_size(firmware, microcode, firmware->count);
484*4882a593Smuzhiyun
485*4882a593Smuzhiyun for (i = 0; i < firmware->count; i++)
486*4882a593Smuzhiyun /*
487*4882a593Smuzhiyun * For situations where the second RISC uses the same microcode
488*4882a593Smuzhiyun * as the first, the 'code_offset' and 'count' fields will be
489*4882a593Smuzhiyun * zero, so it's okay to add those.
490*4882a593Smuzhiyun */
491*4882a593Smuzhiyun calc_size += sizeof(__be32) *
492*4882a593Smuzhiyun be32_to_cpu(firmware->microcode[i].count);
493*4882a593Smuzhiyun
494*4882a593Smuzhiyun /* Validate the length */
495*4882a593Smuzhiyun if (length != calc_size + sizeof(__be32)) {
496*4882a593Smuzhiyun printk(KERN_ERR "qe-firmware: invalid length\n");
497*4882a593Smuzhiyun return -EPERM;
498*4882a593Smuzhiyun }
499*4882a593Smuzhiyun
500*4882a593Smuzhiyun /* Validate the CRC */
501*4882a593Smuzhiyun crc = be32_to_cpu(*(__be32 *)((void *)firmware + calc_size));
502*4882a593Smuzhiyun if (crc != crc32(0, firmware, calc_size)) {
503*4882a593Smuzhiyun printk(KERN_ERR "qe-firmware: firmware CRC is invalid\n");
504*4882a593Smuzhiyun return -EIO;
505*4882a593Smuzhiyun }
506*4882a593Smuzhiyun
507*4882a593Smuzhiyun /*
508*4882a593Smuzhiyun * If the microcode calls for it, split the I-RAM.
509*4882a593Smuzhiyun */
510*4882a593Smuzhiyun if (!firmware->split)
511*4882a593Smuzhiyun qe_setbits_be16(&qe_immr->cp.cercr, QE_CP_CERCR_CIR);
512*4882a593Smuzhiyun
513*4882a593Smuzhiyun if (firmware->soc.model)
514*4882a593Smuzhiyun printk(KERN_INFO
515*4882a593Smuzhiyun "qe-firmware: firmware '%s' for %u V%u.%u\n",
516*4882a593Smuzhiyun firmware->id, be16_to_cpu(firmware->soc.model),
517*4882a593Smuzhiyun firmware->soc.major, firmware->soc.minor);
518*4882a593Smuzhiyun else
519*4882a593Smuzhiyun printk(KERN_INFO "qe-firmware: firmware '%s'\n",
520*4882a593Smuzhiyun firmware->id);
521*4882a593Smuzhiyun
522*4882a593Smuzhiyun /*
523*4882a593Smuzhiyun * The QE only supports one microcode per RISC, so clear out all the
524*4882a593Smuzhiyun * saved microcode information and put in the new.
525*4882a593Smuzhiyun */
526*4882a593Smuzhiyun memset(&qe_firmware_info, 0, sizeof(qe_firmware_info));
527*4882a593Smuzhiyun strlcpy(qe_firmware_info.id, firmware->id, sizeof(qe_firmware_info.id));
528*4882a593Smuzhiyun qe_firmware_info.extended_modes = be64_to_cpu(firmware->extended_modes);
529*4882a593Smuzhiyun memcpy(qe_firmware_info.vtraps, firmware->vtraps,
530*4882a593Smuzhiyun sizeof(firmware->vtraps));
531*4882a593Smuzhiyun
532*4882a593Smuzhiyun /* Loop through each microcode. */
533*4882a593Smuzhiyun for (i = 0; i < firmware->count; i++) {
534*4882a593Smuzhiyun const struct qe_microcode *ucode = &firmware->microcode[i];
535*4882a593Smuzhiyun
536*4882a593Smuzhiyun /* Upload a microcode if it's present */
537*4882a593Smuzhiyun if (ucode->code_offset)
538*4882a593Smuzhiyun qe_upload_microcode(firmware, ucode);
539*4882a593Smuzhiyun
540*4882a593Smuzhiyun /* Program the traps for this processor */
541*4882a593Smuzhiyun for (j = 0; j < 16; j++) {
542*4882a593Smuzhiyun u32 trap = be32_to_cpu(ucode->traps[j]);
543*4882a593Smuzhiyun
544*4882a593Smuzhiyun if (trap)
545*4882a593Smuzhiyun qe_iowrite32be(trap,
546*4882a593Smuzhiyun &qe_immr->rsp[i].tibcr[j]);
547*4882a593Smuzhiyun }
548*4882a593Smuzhiyun
549*4882a593Smuzhiyun /* Enable traps */
550*4882a593Smuzhiyun qe_iowrite32be(be32_to_cpu(ucode->eccr),
551*4882a593Smuzhiyun &qe_immr->rsp[i].eccr);
552*4882a593Smuzhiyun }
553*4882a593Smuzhiyun
554*4882a593Smuzhiyun qe_firmware_uploaded = 1;
555*4882a593Smuzhiyun
556*4882a593Smuzhiyun return 0;
557*4882a593Smuzhiyun }
558*4882a593Smuzhiyun EXPORT_SYMBOL(qe_upload_firmware);
559*4882a593Smuzhiyun
560*4882a593Smuzhiyun /*
561*4882a593Smuzhiyun * Get info on the currently-loaded firmware
562*4882a593Smuzhiyun *
563*4882a593Smuzhiyun * This function also checks the device tree to see if the boot loader has
564*4882a593Smuzhiyun * uploaded a firmware already.
565*4882a593Smuzhiyun */
qe_get_firmware_info(void)566*4882a593Smuzhiyun struct qe_firmware_info *qe_get_firmware_info(void)
567*4882a593Smuzhiyun {
568*4882a593Smuzhiyun static int initialized;
569*4882a593Smuzhiyun struct device_node *qe;
570*4882a593Smuzhiyun struct device_node *fw = NULL;
571*4882a593Smuzhiyun const char *sprop;
572*4882a593Smuzhiyun
573*4882a593Smuzhiyun /*
574*4882a593Smuzhiyun * If we haven't checked yet, and a driver hasn't uploaded a firmware
575*4882a593Smuzhiyun * yet, then check the device tree for information.
576*4882a593Smuzhiyun */
577*4882a593Smuzhiyun if (qe_firmware_uploaded)
578*4882a593Smuzhiyun return &qe_firmware_info;
579*4882a593Smuzhiyun
580*4882a593Smuzhiyun if (initialized)
581*4882a593Smuzhiyun return NULL;
582*4882a593Smuzhiyun
583*4882a593Smuzhiyun initialized = 1;
584*4882a593Smuzhiyun
585*4882a593Smuzhiyun qe = qe_get_device_node();
586*4882a593Smuzhiyun if (!qe)
587*4882a593Smuzhiyun return NULL;
588*4882a593Smuzhiyun
589*4882a593Smuzhiyun /* Find the 'firmware' child node */
590*4882a593Smuzhiyun fw = of_get_child_by_name(qe, "firmware");
591*4882a593Smuzhiyun of_node_put(qe);
592*4882a593Smuzhiyun
593*4882a593Smuzhiyun /* Did we find the 'firmware' node? */
594*4882a593Smuzhiyun if (!fw)
595*4882a593Smuzhiyun return NULL;
596*4882a593Smuzhiyun
597*4882a593Smuzhiyun qe_firmware_uploaded = 1;
598*4882a593Smuzhiyun
599*4882a593Smuzhiyun /* Copy the data into qe_firmware_info*/
600*4882a593Smuzhiyun sprop = of_get_property(fw, "id", NULL);
601*4882a593Smuzhiyun if (sprop)
602*4882a593Smuzhiyun strlcpy(qe_firmware_info.id, sprop,
603*4882a593Smuzhiyun sizeof(qe_firmware_info.id));
604*4882a593Smuzhiyun
605*4882a593Smuzhiyun of_property_read_u64(fw, "extended-modes",
606*4882a593Smuzhiyun &qe_firmware_info.extended_modes);
607*4882a593Smuzhiyun
608*4882a593Smuzhiyun of_property_read_u32_array(fw, "virtual-traps", qe_firmware_info.vtraps,
609*4882a593Smuzhiyun ARRAY_SIZE(qe_firmware_info.vtraps));
610*4882a593Smuzhiyun
611*4882a593Smuzhiyun of_node_put(fw);
612*4882a593Smuzhiyun
613*4882a593Smuzhiyun return &qe_firmware_info;
614*4882a593Smuzhiyun }
615*4882a593Smuzhiyun EXPORT_SYMBOL(qe_get_firmware_info);
616*4882a593Smuzhiyun
qe_get_num_of_risc(void)617*4882a593Smuzhiyun unsigned int qe_get_num_of_risc(void)
618*4882a593Smuzhiyun {
619*4882a593Smuzhiyun struct device_node *qe;
620*4882a593Smuzhiyun unsigned int num_of_risc = 0;
621*4882a593Smuzhiyun
622*4882a593Smuzhiyun qe = qe_get_device_node();
623*4882a593Smuzhiyun if (!qe)
624*4882a593Smuzhiyun return num_of_risc;
625*4882a593Smuzhiyun
626*4882a593Smuzhiyun of_property_read_u32(qe, "fsl,qe-num-riscs", &num_of_risc);
627*4882a593Smuzhiyun
628*4882a593Smuzhiyun of_node_put(qe);
629*4882a593Smuzhiyun
630*4882a593Smuzhiyun return num_of_risc;
631*4882a593Smuzhiyun }
632*4882a593Smuzhiyun EXPORT_SYMBOL(qe_get_num_of_risc);
633*4882a593Smuzhiyun
qe_get_num_of_snums(void)634*4882a593Smuzhiyun unsigned int qe_get_num_of_snums(void)
635*4882a593Smuzhiyun {
636*4882a593Smuzhiyun return qe_num_of_snum;
637*4882a593Smuzhiyun }
638*4882a593Smuzhiyun EXPORT_SYMBOL(qe_get_num_of_snums);
639*4882a593Smuzhiyun
qe_init(void)640*4882a593Smuzhiyun static int __init qe_init(void)
641*4882a593Smuzhiyun {
642*4882a593Smuzhiyun struct device_node *np;
643*4882a593Smuzhiyun
644*4882a593Smuzhiyun np = of_find_compatible_node(NULL, NULL, "fsl,qe");
645*4882a593Smuzhiyun if (!np)
646*4882a593Smuzhiyun return -ENODEV;
647*4882a593Smuzhiyun qe_reset();
648*4882a593Smuzhiyun of_node_put(np);
649*4882a593Smuzhiyun return 0;
650*4882a593Smuzhiyun }
651*4882a593Smuzhiyun subsys_initcall(qe_init);
652*4882a593Smuzhiyun
653*4882a593Smuzhiyun #if defined(CONFIG_SUSPEND) && defined(CONFIG_PPC_85xx)
qe_resume(struct platform_device * ofdev)654*4882a593Smuzhiyun static int qe_resume(struct platform_device *ofdev)
655*4882a593Smuzhiyun {
656*4882a593Smuzhiyun if (!qe_alive_during_sleep())
657*4882a593Smuzhiyun qe_reset();
658*4882a593Smuzhiyun return 0;
659*4882a593Smuzhiyun }
660*4882a593Smuzhiyun
qe_probe(struct platform_device * ofdev)661*4882a593Smuzhiyun static int qe_probe(struct platform_device *ofdev)
662*4882a593Smuzhiyun {
663*4882a593Smuzhiyun return 0;
664*4882a593Smuzhiyun }
665*4882a593Smuzhiyun
666*4882a593Smuzhiyun static const struct of_device_id qe_ids[] = {
667*4882a593Smuzhiyun { .compatible = "fsl,qe", },
668*4882a593Smuzhiyun { },
669*4882a593Smuzhiyun };
670*4882a593Smuzhiyun
671*4882a593Smuzhiyun static struct platform_driver qe_driver = {
672*4882a593Smuzhiyun .driver = {
673*4882a593Smuzhiyun .name = "fsl-qe",
674*4882a593Smuzhiyun .of_match_table = qe_ids,
675*4882a593Smuzhiyun },
676*4882a593Smuzhiyun .probe = qe_probe,
677*4882a593Smuzhiyun .resume = qe_resume,
678*4882a593Smuzhiyun };
679*4882a593Smuzhiyun
680*4882a593Smuzhiyun builtin_platform_driver(qe_driver);
681*4882a593Smuzhiyun #endif /* defined(CONFIG_SUSPEND) && defined(CONFIG_PPC_85xx) */
682