xref: /openbmc/u-boot/drivers/net/pfe_eth/pfe_hw.c (revision b0af1044)
1 /*
2  * Copyright 2015-2016 Freescale Semiconductor, Inc.
3  * Copyright 2017 NXP
4  *
5  * SPDX-License-Identifier:GPL-2.0+
6  */
7 #include <net/pfe_eth/pfe_eth.h>
8 #include <net/pfe_eth/pfe/pfe_hw.h>
9 
10 static struct pe_info pe[MAX_PE];
11 
12 /*
13  * Initializes the PFE library.
14  * Must be called before using any of the library functions.
15  */
16 void pfe_lib_init(void)
17 {
18 	int pfe_pe_id;
19 
20 	for (pfe_pe_id = CLASS0_ID; pfe_pe_id <= CLASS_MAX_ID; pfe_pe_id++) {
21 		pe[pfe_pe_id].dmem_base_addr =
22 			(u32)CLASS_DMEM_BASE_ADDR(pfe_pe_id);
23 		pe[pfe_pe_id].pmem_base_addr =
24 			(u32)CLASS_IMEM_BASE_ADDR(pfe_pe_id);
25 		pe[pfe_pe_id].pmem_size = (u32)CLASS_IMEM_SIZE;
26 		pe[pfe_pe_id].mem_access_wdata =
27 			(void *)CLASS_MEM_ACCESS_WDATA;
28 		pe[pfe_pe_id].mem_access_addr = (void *)CLASS_MEM_ACCESS_ADDR;
29 		pe[pfe_pe_id].mem_access_rdata = (void *)CLASS_MEM_ACCESS_RDATA;
30 	}
31 
32 	for (pfe_pe_id = TMU0_ID; pfe_pe_id <= TMU_MAX_ID; pfe_pe_id++) {
33 		if (pfe_pe_id == TMU2_ID)
34 			continue;
35 		pe[pfe_pe_id].dmem_base_addr =
36 			(u32)TMU_DMEM_BASE_ADDR(pfe_pe_id - TMU0_ID);
37 		pe[pfe_pe_id].pmem_base_addr =
38 			(u32)TMU_IMEM_BASE_ADDR(pfe_pe_id - TMU0_ID);
39 		pe[pfe_pe_id].pmem_size = (u32)TMU_IMEM_SIZE;
40 		pe[pfe_pe_id].mem_access_wdata = (void *)TMU_MEM_ACCESS_WDATA;
41 		pe[pfe_pe_id].mem_access_addr = (void *)TMU_MEM_ACCESS_ADDR;
42 		pe[pfe_pe_id].mem_access_rdata = (void *)TMU_MEM_ACCESS_RDATA;
43 	}
44 }
45 
46 /*
47  * Writes a buffer to PE internal memory from the host
48  * through indirect access registers.
49  *
50  * @param[in] id	       PE identification (CLASS0_ID, ..., TMU0_ID,
51  *				..., UTIL_ID)
52  * @param[in] mem_access_addr	DMEM destination address (must be 32bit
53  *				aligned)
54  * @param[in] src		Buffer source address
55  * @param[in] len		Number of bytes to copy
56  */
57 static void pe_mem_memcpy_to32(int id, u32 mem_access_addr, const void *src,
58 			       unsigned int len)
59 {
60 	u32 offset = 0, val, addr;
61 	unsigned int len32 = len >> 2;
62 	int i;
63 
64 	addr = mem_access_addr | PE_MEM_ACCESS_WRITE |
65 		PE_MEM_ACCESS_BYTE_ENABLE(0, 4);
66 
67 	for (i = 0; i < len32; i++, offset += 4, src += 4) {
68 		val = *(u32 *)src;
69 		writel(cpu_to_be32(val), pe[id].mem_access_wdata);
70 		writel(addr + offset, pe[id].mem_access_addr);
71 	}
72 
73 	len = (len & 0x3);
74 	if (len) {
75 		val = 0;
76 
77 		addr = (mem_access_addr | PE_MEM_ACCESS_WRITE |
78 			PE_MEM_ACCESS_BYTE_ENABLE(0, len)) + offset;
79 
80 		for (i = 0; i < len; i++, src++)
81 			val |= (*(u8 *)src) << (8 * i);
82 
83 		writel(cpu_to_be32(val), pe[id].mem_access_wdata);
84 		writel(addr, pe[id].mem_access_addr);
85 	}
86 }
87 
88 /*
89  * Writes a buffer to PE internal data memory (DMEM) from the host
90  * through indirect access registers.
91  * @param[in] id	PE identification (CLASS0_ID, ..., TMU0_ID,
92  *			..., UTIL_ID)
93  * @param[in] dst	DMEM destination address (must be 32bit
94  *			aligned)
95  * @param[in] src	Buffer source address
96  * @param[in] len	Number of bytes to copy
97  */
98 static void pe_dmem_memcpy_to32(int id, u32 dst, const void *src,
99 				unsigned int len)
100 {
101 	pe_mem_memcpy_to32(id, pe[id].dmem_base_addr | dst | PE_MEM_ACCESS_DMEM,
102 			   src, len);
103 }
104 
105 /*
106  * Writes a buffer to PE internal program memory (PMEM) from the host
107  * through indirect access registers.
108  * @param[in] id	PE identification (CLASS0_ID, ..., TMU0_ID,
109  *			..., TMU3_ID)
110  * @param[in] dst	PMEM destination address (must be 32bit
111  *			aligned)
112  * @param[in] src	Buffer source address
113  * @param[in] len	Number of bytes to copy
114  */
115 static void pe_pmem_memcpy_to32(int id, u32 dst, const void *src,
116 				unsigned int len)
117 {
118 	pe_mem_memcpy_to32(id, pe[id].pmem_base_addr | (dst & (pe[id].pmem_size
119 				- 1)) | PE_MEM_ACCESS_IMEM, src, len);
120 }
121 
122 /*
123  * Reads PE internal program memory (IMEM) from the host
124  * through indirect access registers.
125  * @param[in] id		PE identification (CLASS0_ID, ..., TMU0_ID,
126  *				..., TMU3_ID)
127  * @param[in] addr		PMEM read address (must be aligned on size)
128  * @param[in] size		Number of bytes to read (maximum 4, must not
129  *				cross 32bit boundaries)
130  * @return			the data read (in PE endianness, i.e BE).
131  */
132 u32 pe_pmem_read(int id, u32 addr, u8 size)
133 {
134 	u32 offset = addr & 0x3;
135 	u32 mask = 0xffffffff >> ((4 - size) << 3);
136 	u32 val;
137 
138 	addr = pe[id].pmem_base_addr | ((addr & ~0x3) & (pe[id].pmem_size - 1))
139 		| PE_MEM_ACCESS_READ | PE_MEM_ACCESS_IMEM |
140 		PE_MEM_ACCESS_BYTE_ENABLE(offset, size);
141 
142 	writel(addr, pe[id].mem_access_addr);
143 	val = be32_to_cpu(readl(pe[id].mem_access_rdata));
144 
145 	return (val >> (offset << 3)) & mask;
146 }
147 
148 /*
149  * Writes PE internal data memory (DMEM) from the host
150  * through indirect access registers.
151  * @param[in] id	PE identification (CLASS0_ID, ..., TMU0_ID,
152  *			..., UTIL_ID)
153  * @param[in] val	Value to write (in PE endianness, i.e BE)
154  * @param[in] addr	DMEM write address (must be aligned on size)
155  * @param[in] size	Number of bytes to write (maximum 4, must not
156  *			cross 32bit boundaries)
157  */
158 void pe_dmem_write(int id, u32 val, u32 addr, u8 size)
159 {
160 	u32 offset = addr & 0x3;
161 
162 	addr = pe[id].dmem_base_addr | (addr & ~0x3) | PE_MEM_ACCESS_WRITE |
163 		PE_MEM_ACCESS_DMEM | PE_MEM_ACCESS_BYTE_ENABLE(offset, size);
164 
165 	/* Indirect access interface is byte swapping data being written */
166 	writel(cpu_to_be32(val << (offset << 3)), pe[id].mem_access_wdata);
167 	writel(addr, pe[id].mem_access_addr);
168 }
169 
170 /*
171  * Reads PE internal data memory (DMEM) from the host
172  * through indirect access registers.
173  * @param[in] id		PE identification (CLASS0_ID, ..., TMU0_ID,
174  *				..., UTIL_ID)
175  * @param[in] addr		DMEM read address (must be aligned on size)
176  * @param[in] size		Number of bytes to read (maximum 4, must not
177  *				cross 32bit boundaries)
178  * @return			the data read (in PE endianness, i.e BE).
179  */
180 u32 pe_dmem_read(int id, u32 addr, u8 size)
181 {
182 	u32 offset = addr & 0x3;
183 	u32 mask = 0xffffffff >> ((4 - size) << 3);
184 	u32 val;
185 
186 	addr = pe[id].dmem_base_addr | (addr & ~0x3) | PE_MEM_ACCESS_READ |
187 		PE_MEM_ACCESS_DMEM | PE_MEM_ACCESS_BYTE_ENABLE(offset, size);
188 
189 	writel(addr, pe[id].mem_access_addr);
190 
191 	/* Indirect access interface is byte swapping data being read */
192 	val = be32_to_cpu(readl(pe[id].mem_access_rdata));
193 
194 	return (val >> (offset << 3)) & mask;
195 }
196 
197 /*
198  * This function is used to write to CLASS internal bus peripherals (ccu,
199  * pe-lem) from the host
200  * through indirect access registers.
201  * @param[in]	val	value to write
202  * @param[in]	addr	Address to write to (must be aligned on size)
203  * @param[in]	size	Number of bytes to write (1, 2 or 4)
204  *
205  */
206 static void class_bus_write(u32 val, u32 addr, u8 size)
207 {
208 	u32 offset = addr & 0x3;
209 
210 	writel((addr & CLASS_BUS_ACCESS_BASE_MASK), CLASS_BUS_ACCESS_BASE);
211 
212 	addr = (addr & ~CLASS_BUS_ACCESS_BASE_MASK) | PE_MEM_ACCESS_WRITE |
213 		(size << 24);
214 
215 	writel(cpu_to_be32(val << (offset << 3)), CLASS_BUS_ACCESS_WDATA);
216 	writel(addr, CLASS_BUS_ACCESS_ADDR);
217 }
218 
219 /*
220  * Reads from CLASS internal bus peripherals (ccu, pe-lem) from the host
221  * through indirect access registers.
222  * @param[in] addr	Address to read from (must be aligned on size)
223  * @param[in] size	Number of bytes to read (1, 2 or 4)
224  * @return		the read data
225  */
226 static u32 class_bus_read(u32 addr, u8 size)
227 {
228 	u32 offset = addr & 0x3;
229 	u32 mask = 0xffffffff >> ((4 - size) << 3);
230 	u32 val;
231 
232 	writel((addr & CLASS_BUS_ACCESS_BASE_MASK), CLASS_BUS_ACCESS_BASE);
233 
234 	addr = (addr & ~CLASS_BUS_ACCESS_BASE_MASK) | (size << 24);
235 
236 	writel(addr, CLASS_BUS_ACCESS_ADDR);
237 	val = be32_to_cpu(readl(CLASS_BUS_ACCESS_RDATA));
238 
239 	return (val >> (offset << 3)) & mask;
240 }
241 
242 /*
243  * Writes data to the cluster memory (PE_LMEM)
244  * @param[in] dst	PE LMEM destination address (must be 32bit aligned)
245  * @param[in] src	Buffer source address
246  * @param[in] len	Number of bytes to copy
247  */
248 static void class_pe_lmem_memcpy_to32(u32 dst, const void *src,
249 				      unsigned int len)
250 {
251 	u32 len32 = len >> 2;
252 	int i;
253 
254 	for (i = 0; i < len32; i++, src += 4, dst += 4)
255 		class_bus_write(*(u32 *)src, dst, 4);
256 
257 	if (len & 0x2) {
258 		class_bus_write(*(u16 *)src, dst, 2);
259 		src += 2;
260 		dst += 2;
261 	}
262 
263 	if (len & 0x1) {
264 		class_bus_write(*(u8 *)src, dst, 1);
265 		src++;
266 		dst++;
267 	}
268 }
269 
270 /*
271  * Writes value to the cluster memory (PE_LMEM)
272  * @param[in] dst	PE LMEM destination address (must be 32bit aligned)
273  * @param[in] val	Value to write
274  * @param[in] len	Number of bytes to write
275  */
276 static void class_pe_lmem_memset(u32 dst, int val, unsigned int len)
277 {
278 	u32 len32 = len >> 2;
279 	int i;
280 
281 	val = val | (val << 8) | (val << 16) | (val << 24);
282 
283 	for (i = 0; i < len32; i++, dst += 4)
284 		class_bus_write(val, dst, 4);
285 
286 	if (len & 0x2) {
287 		class_bus_write(val, dst, 2);
288 		dst += 2;
289 	}
290 
291 	if (len & 0x1) {
292 		class_bus_write(val, dst, 1);
293 		dst++;
294 	}
295 }
296 
297 /*
298  * Reads data from the cluster memory (PE_LMEM)
299  * @param[out] dst	pointer to the source buffer data are copied to
300  * @param[in] len	length in bytes of the amount of data to read
301  *			from cluster memory
302  * @param[in] offset	offset in bytes in the cluster memory where data are
303  *			read from
304  */
305 void pe_lmem_read(u32 *dst, u32 len, u32 offset)
306 {
307 	u32 len32 = len >> 2;
308 	int i = 0;
309 
310 	for (i = 0; i < len32; dst++, i++, offset += 4)
311 		*dst = class_bus_read(PE_LMEM_BASE_ADDR + offset, 4);
312 
313 	if (len & 0x03)
314 		*dst = class_bus_read(PE_LMEM_BASE_ADDR + offset, (len & 0x03));
315 }
316 
317 /*
318  * Writes data to the cluster memory (PE_LMEM)
319  * @param[in] src	pointer to the source buffer data are copied from
320  * @param[in] len	length in bytes of the amount of data to write to the
321  *				cluster memory
322  * @param[in] offset	offset in bytes in the cluster memory where data are
323  *				written to
324  */
325 void pe_lmem_write(u32 *src, u32 len, u32 offset)
326 {
327 	u32 len32 = len >> 2;
328 	int i = 0;
329 
330 	for (i = 0; i < len32; src++, i++, offset += 4)
331 		class_bus_write(*src, PE_LMEM_BASE_ADDR + offset, 4);
332 
333 	if (len & 0x03)
334 		class_bus_write(*src, PE_LMEM_BASE_ADDR + offset, (len &
335 					0x03));
336 }
337 
338 /*
339  * Loads an elf section into pmem
340  * Code needs to be at least 16bit aligned and only PROGBITS sections are
341  * supported
342  *
343  * @param[in] id	PE identification (CLASS0_ID, ..., TMU0_ID, ...,
344  *					TMU3_ID)
345  * @param[in] data	pointer to the elf firmware
346  * @param[in] shdr	pointer to the elf section header
347  */
348 static int pe_load_pmem_section(int id, const void *data, Elf32_Shdr *shdr)
349 {
350 	u32 offset = be32_to_cpu(shdr->sh_offset);
351 	u32 addr = be32_to_cpu(shdr->sh_addr);
352 	u32 size = be32_to_cpu(shdr->sh_size);
353 	u32 type = be32_to_cpu(shdr->sh_type);
354 
355 	if (((unsigned long)(data + offset) & 0x3) != (addr & 0x3)) {
356 		printf(
357 			"%s: load address(%x) and elf file address(%lx) don't have the same alignment\n",
358 			__func__, addr, (unsigned long)data + offset);
359 
360 		return -1;
361 	}
362 
363 	if (addr & 0x1) {
364 		printf("%s: load address(%x) is not 16bit aligned\n",
365 		       __func__, addr);
366 		return -1;
367 	}
368 
369 	if (size & 0x1) {
370 		printf("%s: load size(%x) is not 16bit aligned\n", __func__,
371 		       size);
372 		return -1;
373 	}
374 
375 		debug("pmem pe%d @%x len %d\n", id, addr, size);
376 	switch (type) {
377 	case SHT_PROGBITS:
378 		pe_pmem_memcpy_to32(id, addr, data + offset, size);
379 		break;
380 
381 	default:
382 		printf("%s: unsupported section type(%x)\n", __func__, type);
383 		return -1;
384 	}
385 
386 	return 0;
387 }
388 
389 /*
390  * Loads an elf section into dmem
391  * Data needs to be at least 32bit aligned, NOBITS sections are correctly
392  * initialized to 0
393  *
394  * @param[in] id	PE identification (CLASS0_ID, ..., TMU0_ID,
395  *			..., UTIL_ID)
396  * @param[in] data	pointer to the elf firmware
397  * @param[in] shdr	pointer to the elf section header
398  */
399 static int pe_load_dmem_section(int id, const void *data, Elf32_Shdr *shdr)
400 {
401 	u32 offset = be32_to_cpu(shdr->sh_offset);
402 	u32 addr = be32_to_cpu(shdr->sh_addr);
403 	u32 size = be32_to_cpu(shdr->sh_size);
404 	u32 type = be32_to_cpu(shdr->sh_type);
405 	u32 size32 = size >> 2;
406 	int i;
407 
408 	if (((unsigned long)(data + offset) & 0x3) != (addr & 0x3)) {
409 		printf(
410 			"%s: load address(%x) and elf file address(%lx) don't have the same alignment\n",
411 			__func__, addr, (unsigned long)data + offset);
412 
413 		return -1;
414 	}
415 
416 	if (addr & 0x3) {
417 		printf("%s: load address(%x) is not 32bit aligned\n",
418 		       __func__, addr);
419 		return -1;
420 	}
421 
422 	switch (type) {
423 	case SHT_PROGBITS:
424 		debug("dmem pe%d @%x len %d\n", id, addr, size);
425 		pe_dmem_memcpy_to32(id, addr, data + offset, size);
426 		break;
427 
428 	case SHT_NOBITS:
429 		debug("dmem zero pe%d @%x len %d\n", id, addr, size);
430 		for (i = 0; i < size32; i++, addr += 4)
431 			pe_dmem_write(id, 0, addr, 4);
432 
433 		if (size & 0x3)
434 			pe_dmem_write(id, 0, addr, size & 0x3);
435 
436 		break;
437 
438 	default:
439 		printf("%s: unsupported section type(%x)\n", __func__, type);
440 		return -1;
441 	}
442 
443 	return 0;
444 }
445 
446 /*
447  * Loads an elf section into DDR
448  * Data needs to be at least 32bit aligned, NOBITS sections are correctly
449  *		initialized to 0
450  *
451  * @param[in] id	PE identification (CLASS0_ID, ..., TMU0_ID,
452  *			..., UTIL_ID)
453  * @param[in] data	pointer to the elf firmware
454  * @param[in] shdr	pointer to the elf section header
455  */
456 static int pe_load_ddr_section(int id, const void *data, Elf32_Shdr *shdr)
457 {
458 	u32 offset = be32_to_cpu(shdr->sh_offset);
459 	u32 addr = be32_to_cpu(shdr->sh_addr);
460 	u32 size = be32_to_cpu(shdr->sh_size);
461 	u32 type = be32_to_cpu(shdr->sh_type);
462 	u32 flags = be32_to_cpu(shdr->sh_flags);
463 
464 	switch (type) {
465 	case SHT_PROGBITS:
466 		debug("ddr  pe%d @%x len %d\n", id, addr, size);
467 		if (flags & SHF_EXECINSTR) {
468 			if (id <= CLASS_MAX_ID) {
469 				/* DO the loading only once in DDR */
470 				if (id == CLASS0_ID) {
471 					debug(
472 						"%s: load address(%x) and elf file address(%lx) rcvd\n"
473 						, __func__, addr,
474 						(unsigned long)data + offset);
475 					if (((unsigned long)(data + offset)
476 						& 0x3) != (addr & 0x3)) {
477 						printf(
478 							"%s: load address(%x) and elf file address(%lx) don't have the same alignment\n",
479 							__func__, addr,
480 							(unsigned long)data +
481 							offset);
482 
483 						return -1;
484 					}
485 
486 					if (addr & 0x1) {
487 						printf(
488 							"%s: load address(%x) is not 16bit aligned\n"
489 							, __func__, addr);
490 						return -1;
491 					}
492 
493 					if (size & 0x1) {
494 						printf(
495 							"%s: load length(%x) is not 16bit aligned\n"
496 							, __func__, size);
497 						return -1;
498 					}
499 
500 					memcpy((void *)DDR_PFE_TO_VIRT(addr),
501 					       data + offset, size);
502 				}
503 			} else {
504 				printf(
505 					"%s: unsupported ddr section type(%x) for PE(%d)\n"
506 					, __func__, type, id);
507 				return -1;
508 			}
509 
510 		} else {
511 			memcpy((void *)DDR_PFE_TO_VIRT(addr), data + offset,
512 			       size);
513 		}
514 
515 		break;
516 
517 	case SHT_NOBITS:
518 		debug("ddr zero pe%d @%x len %d\n", id, addr, size);
519 		memset((void *)DDR_PFE_TO_VIRT(addr), 0, size);
520 
521 		break;
522 
523 	default:
524 		printf("%s: unsupported section type(%x)\n", __func__, type);
525 		return -1;
526 	}
527 
528 	return 0;
529 }
530 
531 /*
532  * Loads an elf section into pe lmem
533  * Data needs to be at least 32bit aligned, NOBITS sections are correctly
534  * initialized to 0
535  *
536  * @param[in] id	PE identification (CLASS0_ID,..., CLASS5_ID)
537  * @param[in] data	pointer to the elf firmware
538  * @param[in] shdr	pointer to the elf section header
539  */
540 static int pe_load_pe_lmem_section(int id, const void *data, Elf32_Shdr *shdr)
541 {
542 	u32 offset = be32_to_cpu(shdr->sh_offset);
543 	u32 addr = be32_to_cpu(shdr->sh_addr);
544 	u32 size = be32_to_cpu(shdr->sh_size);
545 	u32 type = be32_to_cpu(shdr->sh_type);
546 
547 	if (id > CLASS_MAX_ID) {
548 		printf("%s: unsupported pe-lmem section type(%x) for PE(%d)\n",
549 		       __func__, type, id);
550 		return -1;
551 	}
552 
553 	if (((unsigned long)(data + offset) & 0x3) != (addr & 0x3)) {
554 		printf(
555 			"%s: load address(%x) and elf file address(%lx) don't have the same alignment\n",
556 			__func__, addr, (unsigned long)data + offset);
557 
558 		return -1;
559 	}
560 
561 	if (addr & 0x3) {
562 		printf("%s: load address(%x) is not 32bit aligned\n",
563 		       __func__, addr);
564 		return -1;
565 	}
566 
567 	debug("lmem  pe%d @%x len %d\n", id, addr, size);
568 
569 	switch (type) {
570 	case SHT_PROGBITS:
571 		class_pe_lmem_memcpy_to32(addr, data + offset, size);
572 		break;
573 
574 	case SHT_NOBITS:
575 		class_pe_lmem_memset(addr, 0, size);
576 		break;
577 
578 	default:
579 		printf("%s: unsupported section type(%x)\n", __func__, type);
580 		return -1;
581 	}
582 
583 	return 0;
584 }
585 
586 /*
587  * Loads an elf section into a PE
588  * For now only supports loading a section to dmem (all PE's), pmem (class and
589  * tmu PE's), DDDR (util PE code)
590  * @param[in] id PE identification (CLASS0_ID, ..., TMU0_ID,
591  * ..., UTIL_ID)
592  * @param[in] data	pointer to the elf firmware
593  * @param[in] shdr	pointer to the elf section header
594  */
595 int pe_load_elf_section(int id, const void *data, Elf32_Shdr *shdr)
596 {
597 	u32 addr = be32_to_cpu(shdr->sh_addr);
598 	u32 size = be32_to_cpu(shdr->sh_size);
599 
600 	if (IS_DMEM(addr, size))
601 		return pe_load_dmem_section(id, data, shdr);
602 	else if (IS_PMEM(addr, size))
603 		return pe_load_pmem_section(id, data, shdr);
604 	else if (IS_PFE_LMEM(addr, size))
605 		return 0;
606 	else if (IS_PHYS_DDR(addr, size))
607 		return pe_load_ddr_section(id, data, shdr);
608 	else if (IS_PE_LMEM(addr, size))
609 		return pe_load_pe_lmem_section(id, data, shdr);
610 
611 	printf("%s: unsupported memory range(%x)\n", __func__, addr);
612 
613 	return 0;
614 }
615 
616 /**************************** BMU ***************************/
617 /*
618  * Resets a BMU block.
619  * @param[in] base	BMU block base address
620  */
621 static inline void bmu_reset(void *base)
622 {
623 	writel(CORE_SW_RESET, base + BMU_CTRL);
624 
625 	/* Wait for self clear */
626 	while (readl(base + BMU_CTRL) & CORE_SW_RESET)
627 		;
628 }
629 
630 /*
631  * Enabled a BMU block.
632  * @param[in] base	BMU block base address
633  */
634 void bmu_enable(void *base)
635 {
636 	writel(CORE_ENABLE, base + BMU_CTRL);
637 }
638 
639 /*
640  * Disables a BMU block.
641  * @param[in] base	BMU block base address
642  */
643 static inline void bmu_disable(void *base)
644 {
645 	writel(CORE_DISABLE, base + BMU_CTRL);
646 }
647 
648 /*
649  * Sets the configuration of a BMU block.
650  * @param[in] base	BMU block base address
651  * @param[in] cfg	BMU configuration
652  */
653 static inline void bmu_set_config(void *base, struct bmu_cfg *cfg)
654 {
655 	writel(cfg->baseaddr, base + BMU_UCAST_BASE_ADDR);
656 	writel(cfg->count & 0xffff, base + BMU_UCAST_CONFIG);
657 	writel(cfg->size & 0xffff, base + BMU_BUF_SIZE);
658 
659 	/* Interrupts are never used */
660 	writel(0x0, base + BMU_INT_ENABLE);
661 }
662 
663 /*
664  * Initializes a BMU block.
665  * @param[in] base	BMU block base address
666  * @param[in] cfg	BMU configuration
667  */
668 void bmu_init(void *base, struct bmu_cfg *cfg)
669 {
670 	bmu_disable(base);
671 
672 	bmu_set_config(base, cfg);
673 
674 	bmu_reset(base);
675 }
676 
677 /**************************** GPI ***************************/
678 /*
679  * Resets a GPI block.
680  * @param[in] base	GPI base address
681  */
682 static inline void gpi_reset(void *base)
683 {
684 	writel(CORE_SW_RESET, base + GPI_CTRL);
685 }
686 
687 /*
688  * Enables a GPI block.
689  * @param[in] base	GPI base address
690  */
691 void gpi_enable(void *base)
692 {
693 	writel(CORE_ENABLE, base + GPI_CTRL);
694 }
695 
696 /*
697  * Disables a GPI block.
698  * @param[in] base	GPI base address
699  */
700 void gpi_disable(void *base)
701 {
702 	writel(CORE_DISABLE, base + GPI_CTRL);
703 }
704 
705 /*
706  * Sets the configuration of a GPI block.
707  * @param[in] base	GPI base address
708  * @param[in] cfg	GPI configuration
709  */
710 static inline void gpi_set_config(void *base, struct gpi_cfg *cfg)
711 {
712 	writel(CBUS_VIRT_TO_PFE(BMU1_BASE_ADDR + BMU_ALLOC_CTRL), base
713 	       + GPI_LMEM_ALLOC_ADDR);
714 	writel(CBUS_VIRT_TO_PFE(BMU1_BASE_ADDR + BMU_FREE_CTRL), base
715 	       + GPI_LMEM_FREE_ADDR);
716 	writel(CBUS_VIRT_TO_PFE(BMU2_BASE_ADDR + BMU_ALLOC_CTRL), base
717 	       + GPI_DDR_ALLOC_ADDR);
718 	writel(CBUS_VIRT_TO_PFE(BMU2_BASE_ADDR + BMU_FREE_CTRL), base
719 	       + GPI_DDR_FREE_ADDR);
720 	writel(CBUS_VIRT_TO_PFE(CLASS_INQ_PKTPTR), base + GPI_CLASS_ADDR);
721 	writel(DDR_HDR_SIZE, base + GPI_DDR_DATA_OFFSET);
722 	writel(LMEM_HDR_SIZE, base + GPI_LMEM_DATA_OFFSET);
723 	writel(0, base + GPI_LMEM_SEC_BUF_DATA_OFFSET);
724 	writel(0, base + GPI_DDR_SEC_BUF_DATA_OFFSET);
725 	writel((DDR_HDR_SIZE << 16) | LMEM_HDR_SIZE, base + GPI_HDR_SIZE);
726 	writel((DDR_BUF_SIZE << 16) | LMEM_BUF_SIZE, base + GPI_BUF_SIZE);
727 
728 	writel(((cfg->lmem_rtry_cnt << 16) | (GPI_DDR_BUF_EN << 1) |
729 		GPI_LMEM_BUF_EN), base + GPI_RX_CONFIG);
730 	writel(cfg->tmlf_txthres, base + GPI_TMLF_TX);
731 	writel(cfg->aseq_len, base + GPI_DTX_ASEQ);
732 
733 	/*Make GPI AXI transactions non-bufferable */
734 	writel(0x1, base + GPI_AXI_CTRL);
735 }
736 
737 /*
738  * Initializes a GPI block.
739  * @param[in] base	GPI base address
740  * @param[in] cfg	GPI configuration
741  */
742 void gpi_init(void *base, struct gpi_cfg *cfg)
743 {
744 	gpi_reset(base);
745 
746 	gpi_disable(base);
747 
748 	gpi_set_config(base, cfg);
749 }
750 
751 /**************************** CLASSIFIER ***************************/
752 /*
753  * Resets CLASSIFIER block.
754  */
755 static inline void class_reset(void)
756 {
757 	writel(CORE_SW_RESET, CLASS_TX_CTRL);
758 }
759 
760 /*
761  * Enables all CLASS-PE's cores.
762  */
763 void class_enable(void)
764 {
765 	writel(CORE_ENABLE, CLASS_TX_CTRL);
766 }
767 
768 /*
769  * Disables all CLASS-PE's cores.
770  */
771 void class_disable(void)
772 {
773 	writel(CORE_DISABLE, CLASS_TX_CTRL);
774 }
775 
776 /*
777  * Sets the configuration of the CLASSIFIER block.
778  * @param[in] cfg	CLASSIFIER configuration
779  */
780 static inline void class_set_config(struct class_cfg *cfg)
781 {
782 	if (PLL_CLK_EN == 0) {
783 		/* Clock ratio: for 1:1 the value is 0 */
784 		writel(0x0, CLASS_PE_SYS_CLK_RATIO);
785 	} else {
786 		/* Clock ratio: for 1:2 the value is 1 */
787 		writel(0x1, CLASS_PE_SYS_CLK_RATIO);
788 	}
789 	writel((DDR_HDR_SIZE << 16) | LMEM_HDR_SIZE, CLASS_HDR_SIZE);
790 	writel(LMEM_BUF_SIZE, CLASS_LMEM_BUF_SIZE);
791 	writel(CLASS_ROUTE_ENTRY_SIZE(CLASS_ROUTE_SIZE) |
792 		CLASS_ROUTE_HASH_SIZE(cfg->route_table_hash_bits),
793 		CLASS_ROUTE_HASH_ENTRY_SIZE);
794 	writel(HASH_CRC_PORT_IP | QB2BUS_LE, CLASS_ROUTE_MULTI);
795 
796 	writel(cfg->route_table_baseaddr, CLASS_ROUTE_TABLE_BASE);
797 	memset((void *)DDR_PFE_TO_VIRT(cfg->route_table_baseaddr), 0,
798 	       ROUTE_TABLE_SIZE);
799 
800 	writel(CLASS_PE0_RO_DM_ADDR0_VAL, CLASS_PE0_RO_DM_ADDR0);
801 	writel(CLASS_PE0_RO_DM_ADDR1_VAL, CLASS_PE0_RO_DM_ADDR1);
802 	writel(CLASS_PE0_QB_DM_ADDR0_VAL, CLASS_PE0_QB_DM_ADDR0);
803 	writel(CLASS_PE0_QB_DM_ADDR1_VAL, CLASS_PE0_QB_DM_ADDR1);
804 	writel(CBUS_VIRT_TO_PFE(TMU_PHY_INQ_PKTPTR), CLASS_TM_INQ_ADDR);
805 
806 	writel(23, CLASS_AFULL_THRES);
807 	writel(23, CLASS_TSQ_FIFO_THRES);
808 
809 	writel(24, CLASS_MAX_BUF_CNT);
810 	writel(24, CLASS_TSQ_MAX_CNT);
811 
812 	/*Make Class AXI transactions non-bufferable */
813 	writel(0x1, CLASS_AXI_CTRL);
814 
815 	/*Make Util AXI transactions non-bufferable */
816 	/*Util is disabled in U-boot, do it from here */
817 	writel(0x1, UTIL_AXI_CTRL);
818 }
819 
820 /*
821  * Initializes CLASSIFIER block.
822  * @param[in] cfg	CLASSIFIER configuration
823  */
824 void class_init(struct class_cfg *cfg)
825 {
826 	class_reset();
827 
828 	class_disable();
829 
830 	class_set_config(cfg);
831 }
832 
833 /**************************** TMU ***************************/
834 /*
835  * Enables TMU-PE cores.
836  * @param[in] pe_mask	TMU PE mask
837  */
838 void tmu_enable(u32 pe_mask)
839 {
840 	writel(readl(TMU_TX_CTRL) | (pe_mask & 0xF), TMU_TX_CTRL);
841 }
842 
843 /*
844  * Disables TMU cores.
845  * @param[in] pe_mask	TMU PE mask
846  */
847 void tmu_disable(u32 pe_mask)
848 {
849 	writel(readl(TMU_TX_CTRL) & ~(pe_mask & 0xF), TMU_TX_CTRL);
850 }
851 
852 /*
853  * Initializes TMU block.
854  * @param[in] cfg	TMU configuration
855  */
856 void tmu_init(struct tmu_cfg *cfg)
857 {
858 	int q, phyno;
859 
860 	/* keep in soft reset */
861 	writel(SW_RESET, TMU_CTRL);
862 
863 	/*Make Class AXI transactions non-bufferable */
864 	writel(0x1, TMU_AXI_CTRL);
865 
866 	/* enable EMAC PHY ports */
867 	writel(0x3, TMU_SYS_GENERIC_CONTROL);
868 
869 	writel(750, TMU_INQ_WATERMARK);
870 
871 	writel(CBUS_VIRT_TO_PFE(EGPI1_BASE_ADDR + GPI_INQ_PKTPTR),
872 	       TMU_PHY0_INQ_ADDR);
873 	writel(CBUS_VIRT_TO_PFE(EGPI2_BASE_ADDR + GPI_INQ_PKTPTR),
874 	       TMU_PHY1_INQ_ADDR);
875 
876 	writel(CBUS_VIRT_TO_PFE(HGPI_BASE_ADDR + GPI_INQ_PKTPTR),
877 	       TMU_PHY3_INQ_ADDR);
878 	writel(CBUS_VIRT_TO_PFE(HIF_NOCPY_RX_INQ0_PKTPTR), TMU_PHY4_INQ_ADDR);
879 	writel(CBUS_VIRT_TO_PFE(UTIL_INQ_PKTPTR), TMU_PHY5_INQ_ADDR);
880 	writel(CBUS_VIRT_TO_PFE(BMU2_BASE_ADDR + BMU_FREE_CTRL),
881 	       TMU_BMU_INQ_ADDR);
882 
883 	/* enabling all 10 schedulers [9:0] of each TDQ  */
884 	writel(0x3FF, TMU_TDQ0_SCH_CTRL);
885 	writel(0x3FF, TMU_TDQ1_SCH_CTRL);
886 	writel(0x3FF, TMU_TDQ3_SCH_CTRL);
887 
888 	if (PLL_CLK_EN == 0) {
889 		/* Clock ratio: for 1:1 the value is 0 */
890 		writel(0x0, TMU_PE_SYS_CLK_RATIO);
891 	} else {
892 		/* Clock ratio: for 1:2 the value is 1 */
893 		writel(0x1, TMU_PE_SYS_CLK_RATIO);
894 	}
895 
896 	/* Extra packet pointers will be stored from this address onwards */
897 	debug("TMU_LLM_BASE_ADDR %x\n", cfg->llm_base_addr);
898 	writel(cfg->llm_base_addr, TMU_LLM_BASE_ADDR);
899 
900 	debug("TMU_LLM_QUE_LEN %x\n", cfg->llm_queue_len);
901 	writel(cfg->llm_queue_len,	TMU_LLM_QUE_LEN);
902 
903 	writel(5, TMU_TDQ_IIFG_CFG);
904 	writel(DDR_BUF_SIZE, TMU_BMU_BUF_SIZE);
905 
906 	writel(0x0, TMU_CTRL);
907 
908 	/* MEM init */
909 	writel(MEM_INIT, TMU_CTRL);
910 
911 	while (!(readl(TMU_CTRL) & MEM_INIT_DONE))
912 		;
913 
914 	/* LLM init */
915 	writel(LLM_INIT, TMU_CTRL);
916 
917 	while (!(readl(TMU_CTRL) & LLM_INIT_DONE))
918 		;
919 
920 	/* set up each queue for tail drop */
921 	for (phyno = 0; phyno < 4; phyno++) {
922 		if (phyno == 2)
923 			continue;
924 		for (q = 0; q < 16; q++) {
925 			u32 qmax;
926 
927 			writel((phyno << 8) | q, TMU_TEQ_CTRL);
928 			writel(BIT(22), TMU_TEQ_QCFG);
929 
930 			if (phyno == 3)
931 				qmax = DEFAULT_TMU3_QDEPTH;
932 			else
933 				qmax = (q == 0) ? DEFAULT_Q0_QDEPTH :
934 					DEFAULT_MAX_QDEPTH;
935 
936 			writel(qmax << 18, TMU_TEQ_HW_PROB_CFG2);
937 			writel(qmax >> 14, TMU_TEQ_HW_PROB_CFG3);
938 		}
939 	}
940 	writel(0x05, TMU_TEQ_DISABLE_DROPCHK);
941 	writel(0, TMU_CTRL);
942 }
943 
944 /**************************** HIF ***************************/
945 /*
946  * Enable hif tx DMA and interrupt
947  */
948 void hif_tx_enable(void)
949 {
950 	writel(HIF_CTRL_DMA_EN, HIF_TX_CTRL);
951 }
952 
953 /*
954  * Disable hif tx DMA and interrupt
955  */
956 void hif_tx_disable(void)
957 {
958 	u32 hif_int;
959 
960 	writel(0, HIF_TX_CTRL);
961 
962 	hif_int = readl(HIF_INT_ENABLE);
963 	hif_int &= HIF_TXPKT_INT_EN;
964 	writel(hif_int, HIF_INT_ENABLE);
965 }
966 
967 /*
968  * Enable hif rx DMA and interrupt
969  */
970 void hif_rx_enable(void)
971 {
972 	writel((HIF_CTRL_DMA_EN | HIF_CTRL_BDP_CH_START_WSTB), HIF_RX_CTRL);
973 }
974 
975 /*
976  * Disable hif rx DMA and interrupt
977  */
978 void hif_rx_disable(void)
979 {
980 	u32 hif_int;
981 
982 	writel(0, HIF_RX_CTRL);
983 
984 	hif_int = readl(HIF_INT_ENABLE);
985 	hif_int &= HIF_RXPKT_INT_EN;
986 	writel(hif_int, HIF_INT_ENABLE);
987 }
988 
989 /*
990  * Initializes HIF copy block.
991  */
992 void hif_init(void)
993 {
994 	/* Initialize HIF registers */
995 	writel(HIF_RX_POLL_CTRL_CYCLE << 16 | HIF_TX_POLL_CTRL_CYCLE,
996 	       HIF_POLL_CTRL);
997 	/* Make HIF AXI transactions non-bufferable */
998 	writel(0x1, HIF_AXI_CTRL);
999 }
1000