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