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