xref: /openbmc/u-boot/drivers/qe/qe.c (revision 88919ff7)
1 /*
2  * Copyright (C) 2006-2009 Freescale Semiconductor, Inc.
3  *
4  * Dave Liu <daveliu@freescale.com>
5  * based on source code of Shlomi Gridish
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License as
9  * published by the Free Software Foundation; either version 2 of
10  * the License, or (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
20  * MA 02111-1307 USA
21  */
22 
23 #include "common.h"
24 #include <command.h>
25 #include "asm/errno.h"
26 #include "asm/io.h"
27 #include "asm/immap_qe.h"
28 #include "qe.h"
29 
30 qe_map_t		*qe_immr = NULL;
31 static qe_snum_t	snums[QE_NUM_OF_SNUM];
32 
33 DECLARE_GLOBAL_DATA_PTR;
34 
35 void qe_issue_cmd(uint cmd, uint sbc, u8 mcn, u32 cmd_data)
36 {
37 	u32 cecr;
38 
39 	if (cmd == QE_RESET) {
40 		out_be32(&qe_immr->cp.cecr,(u32) (cmd | QE_CR_FLG));
41 	} else {
42 		out_be32(&qe_immr->cp.cecdr, cmd_data);
43 		out_be32(&qe_immr->cp.cecr, (sbc | QE_CR_FLG |
44 			 ((u32) mcn<<QE_CR_PROTOCOL_SHIFT) | cmd));
45 	}
46 	/* Wait for the QE_CR_FLG to clear */
47 	do {
48 		cecr = in_be32(&qe_immr->cp.cecr);
49 	} while (cecr & QE_CR_FLG);
50 
51 	return;
52 }
53 
54 uint qe_muram_alloc(uint size, uint align)
55 {
56 	uint	retloc;
57 	uint	align_mask, off;
58 	uint	savebase;
59 
60 	align_mask = align - 1;
61 	savebase = gd->mp_alloc_base;
62 
63 	if ((off = (gd->mp_alloc_base & align_mask)) != 0)
64 		gd->mp_alloc_base += (align - off);
65 
66 	if ((off = size & align_mask) != 0)
67 		size += (align - off);
68 
69 	if ((gd->mp_alloc_base + size) >= gd->mp_alloc_top) {
70 		gd->mp_alloc_base = savebase;
71 		printf("%s: ran out of ram.\n",  __FUNCTION__);
72 	}
73 
74 	retloc = gd->mp_alloc_base;
75 	gd->mp_alloc_base += size;
76 
77 	memset((void *)&qe_immr->muram[retloc], 0, size);
78 
79 	__asm__ __volatile__("sync");
80 
81 	return retloc;
82 }
83 
84 void *qe_muram_addr(uint offset)
85 {
86 	return (void *)&qe_immr->muram[offset];
87 }
88 
89 static void qe_sdma_init(void)
90 {
91 	volatile sdma_t	*p;
92 	uint		sdma_buffer_base;
93 
94 	p = (volatile sdma_t *)&qe_immr->sdma;
95 
96 	/* All of DMA transaction in bus 1 */
97 	out_be32(&p->sdaqr, 0);
98 	out_be32(&p->sdaqmr, 0);
99 
100 	/* Allocate 2KB temporary buffer for sdma */
101 	sdma_buffer_base = qe_muram_alloc(2048, 4096);
102 	out_be32(&p->sdwbcr, sdma_buffer_base & QE_SDEBCR_BA_MASK);
103 
104 	/* Clear sdma status */
105 	out_be32(&p->sdsr, 0x03000000);
106 
107 	/* Enable global mode on bus 1, and 2KB buffer size */
108 	out_be32(&p->sdmr, QE_SDMR_GLB_1_MSK | (0x3 << QE_SDMR_CEN_SHIFT));
109 }
110 
111 /* This table is a list of the serial numbers of the Threads, taken from the
112  * "SNUM Table" chart in the QE Reference Manual. The order is not important,
113  * we just need to know what the SNUMs are for the threads.
114  */
115 static u8 thread_snum[] = {
116 /* Evthreads 16-29 are not supported in MPC8309 */
117 #if !defined(CONFIG_MPC8309)
118 	0x04, 0x05, 0x0c, 0x0d,
119 	0x14, 0x15, 0x1c, 0x1d,
120 	0x24, 0x25, 0x2c, 0x2d,
121 	0x34, 0x35,
122 #endif
123 	0x88, 0x89, 0x98, 0x99,
124 	0xa8, 0xa9, 0xb8, 0xb9,
125 	0xc8, 0xc9, 0xd8, 0xd9,
126 	0xe8, 0xe9, 0x08, 0x09,
127 	0x18, 0x19, 0x28, 0x29,
128 	0x38, 0x39, 0x48, 0x49,
129 	0x58, 0x59, 0x68, 0x69,
130 	0x78, 0x79, 0x80, 0x81
131 };
132 
133 static void qe_snums_init(void)
134 {
135 	int	i;
136 
137 	for (i = 0; i < QE_NUM_OF_SNUM; i++) {
138 		snums[i].state = QE_SNUM_STATE_FREE;
139 		snums[i].num   = thread_snum[i];
140 	}
141 }
142 
143 int qe_get_snum(void)
144 {
145 	int	snum = -EBUSY;
146 	int	i;
147 
148 	for (i = 0; i < QE_NUM_OF_SNUM; i++) {
149 		if (snums[i].state == QE_SNUM_STATE_FREE) {
150 			snums[i].state = QE_SNUM_STATE_USED;
151 			snum = snums[i].num;
152 			break;
153 		}
154 	}
155 
156 	return snum;
157 }
158 
159 void qe_put_snum(u8 snum)
160 {
161 	int	i;
162 
163 	for (i = 0; i < QE_NUM_OF_SNUM; i++) {
164 		if (snums[i].num == snum) {
165 			snums[i].state = QE_SNUM_STATE_FREE;
166 			break;
167 		}
168 	}
169 }
170 
171 void qe_init(uint qe_base)
172 {
173 	/* Init the QE IMMR base */
174 	qe_immr = (qe_map_t *)qe_base;
175 
176 #ifdef CONFIG_SYS_QE_FMAN_FW_IN_NOR
177 	/*
178 	 * Upload microcode to IRAM for those SOCs which do not have ROM in QE.
179 	 */
180 	qe_upload_firmware((const void *)CONFIG_SYS_QE_FMAN_FW_ADDR);
181 
182 	/* enable the microcode in IRAM */
183 	out_be32(&qe_immr->iram.iready,QE_IRAM_READY);
184 #endif
185 
186 	gd->mp_alloc_base = QE_DATAONLY_BASE;
187 	gd->mp_alloc_top = gd->mp_alloc_base + QE_DATAONLY_SIZE;
188 
189 	qe_sdma_init();
190 	qe_snums_init();
191 }
192 
193 void qe_reset(void)
194 {
195 	qe_issue_cmd(QE_RESET, QE_CR_SUBBLOCK_INVALID,
196 			 (u8) QE_CR_PROTOCOL_UNSPECIFIED, 0);
197 }
198 
199 void qe_assign_page(uint snum, uint para_ram_base)
200 {
201 	u32	cecr;
202 
203 	out_be32(&qe_immr->cp.cecdr, para_ram_base);
204 	out_be32(&qe_immr->cp.cecr, ((u32) snum<<QE_CR_ASSIGN_PAGE_SNUM_SHIFT)
205 					 | QE_CR_FLG | QE_ASSIGN_PAGE);
206 
207 	/* Wait for the QE_CR_FLG to clear */
208 	do {
209 		cecr = in_be32(&qe_immr->cp.cecr);
210 	} while (cecr & QE_CR_FLG );
211 
212 	return;
213 }
214 
215 /*
216  * brg: 0~15 as BRG1~BRG16
217    rate: baud rate
218  * BRG input clock comes from the BRGCLK (internal clock generated from
219    the QE clock, it is one-half of the QE clock), If need the clock source
220    from CLKn pin, we have te change the function.
221  */
222 
223 #define BRG_CLK		(gd->brg_clk)
224 
225 int qe_set_brg(uint brg, uint rate)
226 {
227 	volatile uint	*bp;
228 	u32		divisor;
229 	int		div16 = 0;
230 
231 	if (brg >= QE_NUM_OF_BRGS)
232 		return -EINVAL;
233 	bp = (uint *)&qe_immr->brg.brgc1;
234 	bp += brg;
235 
236 	divisor = (BRG_CLK / rate);
237 	if (divisor > QE_BRGC_DIVISOR_MAX + 1) {
238 		div16 = 1;
239 		divisor /= 16;
240 	}
241 
242 	*bp = ((divisor - 1) << QE_BRGC_DIVISOR_SHIFT) | QE_BRGC_ENABLE;
243 	__asm__ __volatile__("sync");
244 
245 	if (div16) {
246 		*bp |= QE_BRGC_DIV16;
247 		__asm__ __volatile__("sync");
248 	}
249 
250 	return 0;
251 }
252 
253 /* Set ethernet MII clock master
254 */
255 int qe_set_mii_clk_src(int ucc_num)
256 {
257 	u32	cmxgcr;
258 
259 	/* check if the UCC number is in range. */
260 	if ((ucc_num > UCC_MAX_NUM - 1) || (ucc_num < 0)) {
261 		printf("%s: ucc num not in ranges\n", __FUNCTION__);
262 		return -EINVAL;
263 	}
264 
265 	cmxgcr = in_be32(&qe_immr->qmx.cmxgcr);
266 	cmxgcr &= ~QE_CMXGCR_MII_ENET_MNG_MASK;
267 	cmxgcr |= (ucc_num <<QE_CMXGCR_MII_ENET_MNG_SHIFT);
268 	out_be32(&qe_immr->qmx.cmxgcr, cmxgcr);
269 
270 	return 0;
271 }
272 
273 /* Firmware information stored here for qe_get_firmware_info() */
274 static struct qe_firmware_info qe_firmware_info;
275 
276 /*
277  * Set to 1 if QE firmware has been uploaded, and therefore
278  * qe_firmware_info contains valid data.
279  */
280 static int qe_firmware_uploaded;
281 
282 /*
283  * Upload a QE microcode
284  *
285  * This function is a worker function for qe_upload_firmware().  It does
286  * the actual uploading of the microcode.
287  */
288 static void qe_upload_microcode(const void *base,
289 	const struct qe_microcode *ucode)
290 {
291 	const u32 *code = base + be32_to_cpu(ucode->code_offset);
292 	unsigned int i;
293 
294 	if (ucode->major || ucode->minor || ucode->revision)
295 		printf("QE: uploading microcode '%s' version %u.%u.%u\n",
296 			ucode->id, ucode->major, ucode->minor, ucode->revision);
297 	else
298 		printf("QE: uploading microcode '%s'\n", ucode->id);
299 
300 	/* Use auto-increment */
301 	out_be32(&qe_immr->iram.iadd, be32_to_cpu(ucode->iram_offset) |
302 		QE_IRAM_IADD_AIE | QE_IRAM_IADD_BADDR);
303 
304 	for (i = 0; i < be32_to_cpu(ucode->count); i++)
305 		out_be32(&qe_immr->iram.idata, be32_to_cpu(code[i]));
306 }
307 
308 /*
309  * Upload a microcode to the I-RAM at a specific address.
310  *
311  * See docs/README.qe_firmware for information on QE microcode uploading.
312  *
313  * Currently, only version 1 is supported, so the 'version' field must be
314  * set to 1.
315  *
316  * The SOC model and revision are not validated, they are only displayed for
317  * informational purposes.
318  *
319  * 'calc_size' is the calculated size, in bytes, of the firmware structure and
320  * all of the microcode structures, minus the CRC.
321  *
322  * 'length' is the size that the structure says it is, including the CRC.
323  */
324 int qe_upload_firmware(const struct qe_firmware *firmware)
325 {
326 	unsigned int i;
327 	unsigned int j;
328 	u32 crc;
329 	size_t calc_size = sizeof(struct qe_firmware);
330 	size_t length;
331 	const struct qe_header *hdr;
332 
333 	if (!firmware) {
334 		printf("Invalid address\n");
335 		return -EINVAL;
336 	}
337 
338 	hdr = &firmware->header;
339 	length = be32_to_cpu(hdr->length);
340 
341 	/* Check the magic */
342 	if ((hdr->magic[0] != 'Q') || (hdr->magic[1] != 'E') ||
343 	    (hdr->magic[2] != 'F')) {
344 		printf("Not a microcode\n");
345 		return -EPERM;
346 	}
347 
348 	/* Check the version */
349 	if (hdr->version != 1) {
350 		printf("Unsupported version\n");
351 		return -EPERM;
352 	}
353 
354 	/* Validate some of the fields */
355 	if ((firmware->count < 1) || (firmware->count > MAX_QE_RISC)) {
356 		printf("Invalid data\n");
357 		return -EINVAL;
358 	}
359 
360 	/* Validate the length and check if there's a CRC */
361 	calc_size += (firmware->count - 1) * sizeof(struct qe_microcode);
362 
363 	for (i = 0; i < firmware->count; i++)
364 		/*
365 		 * For situations where the second RISC uses the same microcode
366 		 * as the first, the 'code_offset' and 'count' fields will be
367 		 * zero, so it's okay to add those.
368 		 */
369 		calc_size += sizeof(u32) *
370 			be32_to_cpu(firmware->microcode[i].count);
371 
372 	/* Validate the length */
373 	if (length != calc_size + sizeof(u32)) {
374 		printf("Invalid length\n");
375 		return -EPERM;
376 	}
377 
378 	/*
379 	 * Validate the CRC.  We would normally call crc32_no_comp(), but that
380 	 * function isn't available unless you turn on JFFS support.
381 	 */
382 	crc = be32_to_cpu(*(u32 *)((void *)firmware + calc_size));
383 	if (crc != (crc32(-1, (const void *) firmware, calc_size) ^ -1)) {
384 		printf("Firmware CRC is invalid\n");
385 		return -EIO;
386 	}
387 
388 	/*
389 	 * If the microcode calls for it, split the I-RAM.
390 	 */
391 	if (!firmware->split) {
392 		out_be16(&qe_immr->cp.cercr,
393 			in_be16(&qe_immr->cp.cercr) | QE_CP_CERCR_CIR);
394 	}
395 
396 	if (firmware->soc.model)
397 		printf("Firmware '%s' for %u V%u.%u\n",
398 			firmware->id, be16_to_cpu(firmware->soc.model),
399 			firmware->soc.major, firmware->soc.minor);
400 	else
401 		printf("Firmware '%s'\n", firmware->id);
402 
403 	/*
404 	 * The QE only supports one microcode per RISC, so clear out all the
405 	 * saved microcode information and put in the new.
406 	 */
407 	memset(&qe_firmware_info, 0, sizeof(qe_firmware_info));
408 	strcpy(qe_firmware_info.id, (char *)firmware->id);
409 	qe_firmware_info.extended_modes = firmware->extended_modes;
410 	memcpy(qe_firmware_info.vtraps, firmware->vtraps,
411 		sizeof(firmware->vtraps));
412 	qe_firmware_uploaded = 1;
413 
414 	/* Loop through each microcode. */
415 	for (i = 0; i < firmware->count; i++) {
416 		const struct qe_microcode *ucode = &firmware->microcode[i];
417 
418 		/* Upload a microcode if it's present */
419 		if (ucode->code_offset)
420 			qe_upload_microcode(firmware, ucode);
421 
422 		/* Program the traps for this processor */
423 		for (j = 0; j < 16; j++) {
424 			u32 trap = be32_to_cpu(ucode->traps[j]);
425 
426 			if (trap)
427 				out_be32(&qe_immr->rsp[i].tibcr[j], trap);
428 		}
429 
430 		/* Enable traps */
431 		out_be32(&qe_immr->rsp[i].eccr, be32_to_cpu(ucode->eccr));
432 	}
433 
434 	return 0;
435 }
436 
437 struct qe_firmware_info *qe_get_firmware_info(void)
438 {
439 	return qe_firmware_uploaded ? &qe_firmware_info : NULL;
440 }
441 
442 static int qe_cmd(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
443 {
444 	ulong addr;
445 
446 	if (argc < 3)
447 		return cmd_usage(cmdtp);
448 
449 	if (strcmp(argv[1], "fw") == 0) {
450 		addr = simple_strtoul(argv[2], NULL, 16);
451 
452 		if (!addr) {
453 			printf("Invalid address\n");
454 			return -EINVAL;
455 		}
456 
457 		/*
458 		 * If a length was supplied, compare that with the 'length'
459 		 * field.
460 		 */
461 
462 		if (argc > 3) {
463 			ulong length = simple_strtoul(argv[3], NULL, 16);
464 			struct qe_firmware *firmware = (void *) addr;
465 
466 			if (length != be32_to_cpu(firmware->header.length)) {
467 				printf("Length mismatch\n");
468 				return -EINVAL;
469 			}
470 		}
471 
472 		return qe_upload_firmware((const struct qe_firmware *) addr);
473 	}
474 
475 	return cmd_usage(cmdtp);
476 }
477 
478 U_BOOT_CMD(
479 	qe, 4, 0, qe_cmd,
480 	"QUICC Engine commands",
481 	"fw <addr> [<length>] - Upload firmware binary at address <addr> to "
482 		"the QE,\n"
483 	"\twith optional length <length> verification."
484 );
485