xref: /openbmc/u-boot/drivers/qe/qe.c (revision a89c33db)
1 /*
2  * Copyright (C) 2006 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 static u8 thread_snum[QE_NUM_OF_SNUM] = {
112 	0x04, 0x05, 0x0c, 0x0d,
113 	0x14, 0x15, 0x1c, 0x1d,
114 	0x24, 0x25, 0x2c, 0x2d,
115 	0x34, 0x35, 0x88, 0x89,
116 	0x98, 0x99, 0xa8, 0xa9,
117 	0xb8, 0xb9, 0xc8, 0xc9,
118 	0xd8, 0xd9, 0xe8, 0xe9
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_FW_ADDR
165 	/*
166 	 * Upload microcode to IRAM for those SOCs which do not have ROM in QE.
167 	 */
168 	qe_upload_firmware((const struct qe_firmware *) 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->mp_alloc_base = QE_DATAONLY_BASE;
175 	gd->mp_alloc_top = gd->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->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 /* The maximum number of RISCs we support */
262 #define MAX_QE_RISC     2
263 
264 /* Firmware information stored here for qe_get_firmware_info() */
265 static struct qe_firmware_info qe_firmware_info;
266 
267 /*
268  * Set to 1 if QE firmware has been uploaded, and therefore
269  * qe_firmware_info contains valid data.
270  */
271 static int qe_firmware_uploaded;
272 
273 /*
274  * Upload a QE microcode
275  *
276  * This function is a worker function for qe_upload_firmware().  It does
277  * the actual uploading of the microcode.
278  */
279 static void qe_upload_microcode(const void *base,
280 	const struct qe_microcode *ucode)
281 {
282 	const u32 *code = base + be32_to_cpu(ucode->code_offset);
283 	unsigned int i;
284 
285 	if (ucode->major || ucode->minor || ucode->revision)
286 		printf("QE: uploading microcode '%s' version %u.%u.%u\n",
287 			ucode->id, ucode->major, ucode->minor, ucode->revision);
288 	else
289 		printf("QE: uploading microcode '%s'\n", ucode->id);
290 
291 	/* Use auto-increment */
292 	out_be32(&qe_immr->iram.iadd, be32_to_cpu(ucode->iram_offset) |
293 		QE_IRAM_IADD_AIE | QE_IRAM_IADD_BADDR);
294 
295 	for (i = 0; i < be32_to_cpu(ucode->count); i++)
296 		out_be32(&qe_immr->iram.idata, be32_to_cpu(code[i]));
297 }
298 
299 /*
300  * Upload a microcode to the I-RAM at a specific address.
301  *
302  * See docs/README.qe_firmware for information on QE microcode uploading.
303  *
304  * Currently, only version 1 is supported, so the 'version' field must be
305  * set to 1.
306  *
307  * The SOC model and revision are not validated, they are only displayed for
308  * informational purposes.
309  *
310  * 'calc_size' is the calculated size, in bytes, of the firmware structure and
311  * all of the microcode structures, minus the CRC.
312  *
313  * 'length' is the size that the structure says it is, including the CRC.
314  */
315 int qe_upload_firmware(const struct qe_firmware *firmware)
316 {
317 	unsigned int i;
318 	unsigned int j;
319 	u32 crc;
320 	size_t calc_size = sizeof(struct qe_firmware);
321 	size_t length;
322 	const struct qe_header *hdr;
323 
324 	if (!firmware) {
325 		printf("Invalid address\n");
326 		return -EINVAL;
327 	}
328 
329 	hdr = &firmware->header;
330 	length = be32_to_cpu(hdr->length);
331 
332 	/* Check the magic */
333 	if ((hdr->magic[0] != 'Q') || (hdr->magic[1] != 'E') ||
334 	    (hdr->magic[2] != 'F')) {
335 		printf("Not a microcode\n");
336 		return -EPERM;
337 	}
338 
339 	/* Check the version */
340 	if (hdr->version != 1) {
341 		printf("Unsupported version\n");
342 		return -EPERM;
343 	}
344 
345 	/* Validate some of the fields */
346 	if ((firmware->count < 1) || (firmware->count > MAX_QE_RISC)) {
347 		printf("Invalid data\n");
348 		return -EINVAL;
349 	}
350 
351 	/* Validate the length and check if there's a CRC */
352 	calc_size += (firmware->count - 1) * sizeof(struct qe_microcode);
353 
354 	for (i = 0; i < firmware->count; i++)
355 		/*
356 		 * For situations where the second RISC uses the same microcode
357 		 * as the first, the 'code_offset' and 'count' fields will be
358 		 * zero, so it's okay to add those.
359 		 */
360 		calc_size += sizeof(u32) *
361 			be32_to_cpu(firmware->microcode[i].count);
362 
363 	/* Validate the length */
364 	if (length != calc_size + sizeof(u32)) {
365 		printf("Invalid length\n");
366 		return -EPERM;
367 	}
368 
369 	/*
370 	 * Validate the CRC.  We would normally call crc32_no_comp(), but that
371 	 * function isn't available unless you turn on JFFS support.
372 	 */
373 	crc = be32_to_cpu(*(u32 *)((void *)firmware + calc_size));
374 	if (crc != (crc32(-1, (const void *) firmware, calc_size) ^ -1)) {
375 		printf("Firmware CRC is invalid\n");
376 		return -EIO;
377 	}
378 
379 	/*
380 	 * If the microcode calls for it, split the I-RAM.
381 	 */
382 	if (!firmware->split) {
383 		out_be16(&qe_immr->cp.cercr,
384 			in_be16(&qe_immr->cp.cercr) | QE_CP_CERCR_CIR);
385 	}
386 
387 	if (firmware->soc.model)
388 		printf("Firmware '%s' for %u V%u.%u\n",
389 			firmware->id, be16_to_cpu(firmware->soc.model),
390 			firmware->soc.major, firmware->soc.minor);
391 	else
392 		printf("Firmware '%s'\n", firmware->id);
393 
394 	/*
395 	 * The QE only supports one microcode per RISC, so clear out all the
396 	 * saved microcode information and put in the new.
397 	 */
398 	memset(&qe_firmware_info, 0, sizeof(qe_firmware_info));
399 	strcpy(qe_firmware_info.id, (char *)firmware->id);
400 	qe_firmware_info.extended_modes = firmware->extended_modes;
401 	memcpy(qe_firmware_info.vtraps, firmware->vtraps,
402 		sizeof(firmware->vtraps));
403 	qe_firmware_uploaded = 1;
404 
405 	/* Loop through each microcode. */
406 	for (i = 0; i < firmware->count; i++) {
407 		const struct qe_microcode *ucode = &firmware->microcode[i];
408 
409 		/* Upload a microcode if it's present */
410 		if (ucode->code_offset)
411 			qe_upload_microcode(firmware, ucode);
412 
413 		/* Program the traps for this processor */
414 		for (j = 0; j < 16; j++) {
415 			u32 trap = be32_to_cpu(ucode->traps[j]);
416 
417 			if (trap)
418 				out_be32(&qe_immr->rsp[i].tibcr[j], trap);
419 		}
420 
421 		/* Enable traps */
422 		out_be32(&qe_immr->rsp[i].eccr, be32_to_cpu(ucode->eccr));
423 	}
424 
425 	return 0;
426 }
427 
428 struct qe_firmware_info *qe_get_firmware_info(void)
429 {
430 	return qe_firmware_uploaded ? &qe_firmware_info : NULL;
431 }
432 
433 static int qe_cmd(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
434 {
435 	ulong addr;
436 
437 	if (argc < 3) {
438 		cmd_usage(cmdtp);
439 		return 1;
440 	}
441 
442 	if (strcmp(argv[1], "fw") == 0) {
443 		addr = simple_strtoul(argv[2], NULL, 16);
444 
445 		if (!addr) {
446 			printf("Invalid address\n");
447 			return -EINVAL;
448 		}
449 
450 		/*
451 		 * If a length was supplied, compare that with the 'length'
452 		 * field.
453 		 */
454 
455 		if (argc > 3) {
456 			ulong length = simple_strtoul(argv[3], NULL, 16);
457 			struct qe_firmware *firmware = (void *) addr;
458 
459 			if (length != be32_to_cpu(firmware->header.length)) {
460 				printf("Length mismatch\n");
461 				return -EINVAL;
462 			}
463 		}
464 
465 		return qe_upload_firmware((const struct qe_firmware *) addr);
466 	}
467 
468 	cmd_usage(cmdtp);
469 	return 1;
470 }
471 
472 U_BOOT_CMD(
473 	qe, 4, 0, qe_cmd,
474 	"QUICC Engine commands",
475 	"fw <addr> [<length>] - Upload firmware binary at address <addr> to "
476 		"the QE,\n"
477 	"\twith optional length <length> verification."
478 );
479