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