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