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