xref: /OK3568_Linux_fs/kernel/drivers/soc/fsl/qe/qe.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
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