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