1 // SPDX-License-Identifier: GPL-2.0+
3 * Copyright 2015-2016 Freescale Semiconductor, Inc.
7 #include <linux/bitops.h>
8 #include <net/pfe_eth/pfe_eth.h>
9 #include <net/pfe_eth/pfe/pfe_hw.h>
11 static struct pe_info pe
[MAX_PE
];
14 * Initializes the PFE library.
15 * Must be called before using any of the library functions.
17 void pfe_lib_init(void)
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
;
33 for (pfe_pe_id
= TMU0_ID
; pfe_pe_id
<= TMU_MAX_ID
; pfe_pe_id
++) {
34 if (pfe_pe_id
== TMU2_ID
)
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
;
48 * Writes a buffer to PE internal memory from the host
49 * through indirect access registers.
51 * @param[in] id PE identification (CLASS0_ID, ..., TMU0_ID,
53 * @param[in] mem_access_addr DMEM destination address (must be 32bit
55 * @param[in] src Buffer source address
56 * @param[in] len Number of bytes to copy
58 static void pe_mem_memcpy_to32(int id
, u32 mem_access_addr
, const void *src
,
61 u32 offset
= 0, val
, addr
;
62 unsigned int len32
= len
>> 2;
65 addr
= mem_access_addr
| PE_MEM_ACCESS_WRITE
|
66 PE_MEM_ACCESS_BYTE_ENABLE(0, 4);
68 for (i
= 0; i
< len32
; i
++, offset
+= 4, src
+= 4) {
70 writel(cpu_to_be32(val
), pe
[id
].mem_access_wdata
);
71 writel(addr
+ offset
, pe
[id
].mem_access_addr
);
78 addr
= (mem_access_addr
| PE_MEM_ACCESS_WRITE
|
79 PE_MEM_ACCESS_BYTE_ENABLE(0, len
)) + offset
;
81 for (i
= 0; i
< len
; i
++, src
++)
82 val
|= (*(u8
*)src
) << (8 * i
);
84 writel(cpu_to_be32(val
), pe
[id
].mem_access_wdata
);
85 writel(addr
, pe
[id
].mem_access_addr
);
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,
94 * @param[in] dst DMEM destination address (must be 32bit
96 * @param[in] src Buffer source address
97 * @param[in] len Number of bytes to copy
99 static void pe_dmem_memcpy_to32(int id
, u32 dst
, const void *src
,
102 pe_mem_memcpy_to32(id
, pe
[id
].dmem_base_addr
| dst
| PE_MEM_ACCESS_DMEM
,
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,
111 * @param[in] dst PMEM destination address (must be 32bit
113 * @param[in] src Buffer source address
114 * @param[in] len Number of bytes to copy
116 static void pe_pmem_memcpy_to32(int id
, u32 dst
, const void *src
,
119 pe_mem_memcpy_to32(id
, pe
[id
].pmem_base_addr
| (dst
& (pe
[id
].pmem_size
120 - 1)) | PE_MEM_ACCESS_IMEM
, src
, len
);
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,
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).
133 u32
pe_pmem_read(int id
, u32 addr
, u8 size
)
135 u32 offset
= addr
& 0x3;
136 u32 mask
= 0xffffffff >> ((4 - size
) << 3);
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
);
143 writel(addr
, pe
[id
].mem_access_addr
);
144 val
= be32_to_cpu(readl(pe
[id
].mem_access_rdata
));
146 return (val
>> (offset
<< 3)) & mask
;
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,
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)
159 void pe_dmem_write(int id
, u32 val
, u32 addr
, u8 size
)
161 u32 offset
= addr
& 0x3;
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
);
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
);
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,
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).
181 u32
pe_dmem_read(int id
, u32 addr
, u8 size
)
183 u32 offset
= addr
& 0x3;
184 u32 mask
= 0xffffffff >> ((4 - size
) << 3);
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
);
190 writel(addr
, pe
[id
].mem_access_addr
);
192 /* Indirect access interface is byte swapping data being read */
193 val
= be32_to_cpu(readl(pe
[id
].mem_access_rdata
));
195 return (val
>> (offset
<< 3)) & mask
;
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)
207 static void class_bus_write(u32 val
, u32 addr
, u8 size
)
209 u32 offset
= addr
& 0x3;
211 writel((addr
& CLASS_BUS_ACCESS_BASE_MASK
), CLASS_BUS_ACCESS_BASE
);
213 addr
= (addr
& ~CLASS_BUS_ACCESS_BASE_MASK
) | PE_MEM_ACCESS_WRITE
|
216 writel(cpu_to_be32(val
<< (offset
<< 3)), CLASS_BUS_ACCESS_WDATA
);
217 writel(addr
, CLASS_BUS_ACCESS_ADDR
);
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
227 static u32
class_bus_read(u32 addr
, u8 size
)
229 u32 offset
= addr
& 0x3;
230 u32 mask
= 0xffffffff >> ((4 - size
) << 3);
233 writel((addr
& CLASS_BUS_ACCESS_BASE_MASK
), CLASS_BUS_ACCESS_BASE
);
235 addr
= (addr
& ~CLASS_BUS_ACCESS_BASE_MASK
) | (size
<< 24);
237 writel(addr
, CLASS_BUS_ACCESS_ADDR
);
238 val
= be32_to_cpu(readl(CLASS_BUS_ACCESS_RDATA
));
240 return (val
>> (offset
<< 3)) & mask
;
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
249 static void class_pe_lmem_memcpy_to32(u32 dst
, const void *src
,
252 u32 len32
= len
>> 2;
255 for (i
= 0; i
< len32
; i
++, src
+= 4, dst
+= 4)
256 class_bus_write(*(u32
*)src
, dst
, 4);
259 class_bus_write(*(u16
*)src
, dst
, 2);
265 class_bus_write(*(u8
*)src
, dst
, 1);
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
277 static void class_pe_lmem_memset(u32 dst
, int val
, unsigned int len
)
279 u32 len32
= len
>> 2;
282 val
= val
| (val
<< 8) | (val
<< 16) | (val
<< 24);
284 for (i
= 0; i
< len32
; i
++, dst
+= 4)
285 class_bus_write(val
, dst
, 4);
288 class_bus_write(val
, dst
, 2);
293 class_bus_write(val
, dst
, 1);
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
306 void pe_lmem_read(u32
*dst
, u32 len
, u32 offset
)
308 u32 len32
= len
>> 2;
311 for (i
= 0; i
< len32
; dst
++, i
++, offset
+= 4)
312 *dst
= class_bus_read(PE_LMEM_BASE_ADDR
+ offset
, 4);
315 *dst
= class_bus_read(PE_LMEM_BASE_ADDR
+ offset
, (len
& 0x03));
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
323 * @param[in] offset offset in bytes in the cluster memory where data are
326 void pe_lmem_write(u32
*src
, u32 len
, u32 offset
)
328 u32 len32
= len
>> 2;
331 for (i
= 0; i
< len32
; src
++, i
++, offset
+= 4)
332 class_bus_write(*src
, PE_LMEM_BASE_ADDR
+ offset
, 4);
335 class_bus_write(*src
, PE_LMEM_BASE_ADDR
+ offset
, (len
&
340 * Loads an elf section into pmem
341 * Code needs to be at least 16bit aligned and only PROGBITS sections are
344 * @param[in] id PE identification (CLASS0_ID, ..., TMU0_ID, ...,
346 * @param[in] data pointer to the elf firmware
347 * @param[in] shdr pointer to the elf section header
349 static int pe_load_pmem_section(int id
, const void *data
, Elf32_Shdr
*shdr
)
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
);
356 if (((unsigned long)(data
+ offset
) & 0x3) != (addr
& 0x3)) {
358 "%s: load address(%x) and elf file address(%lx) don't have the same alignment\n",
359 __func__
, addr
, (unsigned long)data
+ offset
);
365 printf("%s: load address(%x) is not 16bit aligned\n",
371 printf("%s: load size(%x) is not 16bit aligned\n", __func__
,
376 debug("pmem pe%d @%x len %d\n", id
, addr
, size
);
379 pe_pmem_memcpy_to32(id
, addr
, data
+ offset
, size
);
383 printf("%s: unsupported section type(%x)\n", __func__
, type
);
391 * Loads an elf section into dmem
392 * Data needs to be at least 32bit aligned, NOBITS sections are correctly
395 * @param[in] id PE identification (CLASS0_ID, ..., TMU0_ID,
397 * @param[in] data pointer to the elf firmware
398 * @param[in] shdr pointer to the elf section header
400 static int pe_load_dmem_section(int id
, const void *data
, Elf32_Shdr
*shdr
)
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;
409 if (((unsigned long)(data
+ offset
) & 0x3) != (addr
& 0x3)) {
411 "%s: load address(%x) and elf file address(%lx) don't have the same alignment\n",
412 __func__
, addr
, (unsigned long)data
+ offset
);
418 printf("%s: load address(%x) is not 32bit aligned\n",
425 debug("dmem pe%d @%x len %d\n", id
, addr
, size
);
426 pe_dmem_memcpy_to32(id
, addr
, data
+ offset
, size
);
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);
435 pe_dmem_write(id
, 0, addr
, size
& 0x3);
440 printf("%s: unsupported section type(%x)\n", __func__
, type
);
448 * Loads an elf section into DDR
449 * Data needs to be at least 32bit aligned, NOBITS sections are correctly
452 * @param[in] id PE identification (CLASS0_ID, ..., TMU0_ID,
454 * @param[in] data pointer to the elf firmware
455 * @param[in] shdr pointer to the elf section header
457 static int pe_load_ddr_section(int id
, const void *data
, Elf32_Shdr
*shdr
)
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
);
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
) {
473 "%s: load address(%x) and elf file address(%lx) rcvd\n"
475 (unsigned long)data
+ offset
);
476 if (((unsigned long)(data
+ offset
)
477 & 0x3) != (addr
& 0x3)) {
479 "%s: load address(%x) and elf file address(%lx) don't have the same alignment\n",
481 (unsigned long)data
+
489 "%s: load address(%x) is not 16bit aligned\n"
496 "%s: load length(%x) is not 16bit aligned\n"
501 memcpy((void *)DDR_PFE_TO_VIRT(addr
),
502 data
+ offset
, size
);
506 "%s: unsupported ddr section type(%x) for PE(%d)\n"
507 , __func__
, type
, id
);
512 memcpy((void *)DDR_PFE_TO_VIRT(addr
), data
+ offset
,
519 debug("ddr zero pe%d @%x len %d\n", id
, addr
, size
);
520 memset((void *)DDR_PFE_TO_VIRT(addr
), 0, size
);
525 printf("%s: unsupported section type(%x)\n", __func__
, type
);
533 * Loads an elf section into pe lmem
534 * Data needs to be at least 32bit aligned, NOBITS sections are correctly
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
541 static int pe_load_pe_lmem_section(int id
, const void *data
, Elf32_Shdr
*shdr
)
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
);
548 if (id
> CLASS_MAX_ID
) {
549 printf("%s: unsupported pe-lmem section type(%x) for PE(%d)\n",
554 if (((unsigned long)(data
+ offset
) & 0x3) != (addr
& 0x3)) {
556 "%s: load address(%x) and elf file address(%lx) don't have the same alignment\n",
557 __func__
, addr
, (unsigned long)data
+ offset
);
563 printf("%s: load address(%x) is not 32bit aligned\n",
568 debug("lmem pe%d @%x len %d\n", id
, addr
, size
);
572 class_pe_lmem_memcpy_to32(addr
, data
+ offset
, size
);
576 class_pe_lmem_memset(addr
, 0, size
);
580 printf("%s: unsupported section type(%x)\n", __func__
, type
);
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,
593 * @param[in] data pointer to the elf firmware
594 * @param[in] shdr pointer to the elf section header
596 int pe_load_elf_section(int id
, const void *data
, Elf32_Shdr
*shdr
)
598 u32 addr
= be32_to_cpu(shdr
->sh_addr
);
599 u32 size
= be32_to_cpu(shdr
->sh_size
);
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
))
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
);
612 printf("%s: unsupported memory range(%x)\n", __func__
, addr
);
617 /**************************** BMU ***************************/
619 * Resets a BMU block.
620 * @param[in] base BMU block base address
622 static inline void bmu_reset(void *base
)
624 writel(CORE_SW_RESET
, base
+ BMU_CTRL
);
626 /* Wait for self clear */
627 while (readl(base
+ BMU_CTRL
) & CORE_SW_RESET
)
632 * Enabled a BMU block.
633 * @param[in] base BMU block base address
635 void bmu_enable(void *base
)
637 writel(CORE_ENABLE
, base
+ BMU_CTRL
);
641 * Disables a BMU block.
642 * @param[in] base BMU block base address
644 static inline void bmu_disable(void *base
)
646 writel(CORE_DISABLE
, base
+ BMU_CTRL
);
650 * Sets the configuration of a BMU block.
651 * @param[in] base BMU block base address
652 * @param[in] cfg BMU configuration
654 static inline void bmu_set_config(void *base
, struct bmu_cfg
*cfg
)
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
);
660 /* Interrupts are never used */
661 writel(0x0, base
+ BMU_INT_ENABLE
);
665 * Initializes a BMU block.
666 * @param[in] base BMU block base address
667 * @param[in] cfg BMU configuration
669 void bmu_init(void *base
, struct bmu_cfg
*cfg
)
673 bmu_set_config(base
, cfg
);
678 /**************************** GPI ***************************/
680 * Resets a GPI block.
681 * @param[in] base GPI base address
683 static inline void gpi_reset(void *base
)
685 writel(CORE_SW_RESET
, base
+ GPI_CTRL
);
689 * Enables a GPI block.
690 * @param[in] base GPI base address
692 void gpi_enable(void *base
)
694 writel(CORE_ENABLE
, base
+ GPI_CTRL
);
698 * Disables a GPI block.
699 * @param[in] base GPI base address
701 void gpi_disable(void *base
)
703 writel(CORE_DISABLE
, base
+ GPI_CTRL
);
707 * Sets the configuration of a GPI block.
708 * @param[in] base GPI base address
709 * @param[in] cfg GPI configuration
711 static inline void gpi_set_config(void *base
, struct gpi_cfg
*cfg
)
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
);
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
);
734 /*Make GPI AXI transactions non-bufferable */
735 writel(0x1, base
+ GPI_AXI_CTRL
);
739 * Initializes a GPI block.
740 * @param[in] base GPI base address
741 * @param[in] cfg GPI configuration
743 void gpi_init(void *base
, struct gpi_cfg
*cfg
)
749 gpi_set_config(base
, cfg
);
752 /**************************** CLASSIFIER ***************************/
754 * Resets CLASSIFIER block.
756 static inline void class_reset(void)
758 writel(CORE_SW_RESET
, CLASS_TX_CTRL
);
762 * Enables all CLASS-PE's cores.
764 void class_enable(void)
766 writel(CORE_ENABLE
, CLASS_TX_CTRL
);
770 * Disables all CLASS-PE's cores.
772 void class_disable(void)
774 writel(CORE_DISABLE
, CLASS_TX_CTRL
);
778 * Sets the configuration of the CLASSIFIER block.
779 * @param[in] cfg CLASSIFIER configuration
781 static inline void class_set_config(struct class_cfg
*cfg
)
783 if (PLL_CLK_EN
== 0) {
784 /* Clock ratio: for 1:1 the value is 0 */
785 writel(0x0, CLASS_PE_SYS_CLK_RATIO
);
787 /* Clock ratio: for 1:2 the value is 1 */
788 writel(0x1, CLASS_PE_SYS_CLK_RATIO
);
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
);
797 writel(cfg
->route_table_baseaddr
, CLASS_ROUTE_TABLE_BASE
);
798 memset((void *)DDR_PFE_TO_VIRT(cfg
->route_table_baseaddr
), 0,
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
);
807 writel(23, CLASS_AFULL_THRES
);
808 writel(23, CLASS_TSQ_FIFO_THRES
);
810 writel(24, CLASS_MAX_BUF_CNT
);
811 writel(24, CLASS_TSQ_MAX_CNT
);
813 /*Make Class AXI transactions non-bufferable */
814 writel(0x1, CLASS_AXI_CTRL
);
816 /*Make Util AXI transactions non-bufferable */
817 /*Util is disabled in U-Boot, do it from here */
818 writel(0x1, UTIL_AXI_CTRL
);
822 * Initializes CLASSIFIER block.
823 * @param[in] cfg CLASSIFIER configuration
825 void class_init(struct class_cfg
*cfg
)
831 class_set_config(cfg
);
834 /**************************** TMU ***************************/
836 * Enables TMU-PE cores.
837 * @param[in] pe_mask TMU PE mask
839 void tmu_enable(u32 pe_mask
)
841 writel(readl(TMU_TX_CTRL
) | (pe_mask
& 0xF), TMU_TX_CTRL
);
845 * Disables TMU cores.
846 * @param[in] pe_mask TMU PE mask
848 void tmu_disable(u32 pe_mask
)
850 writel(readl(TMU_TX_CTRL
) & ~(pe_mask
& 0xF), TMU_TX_CTRL
);
854 * Initializes TMU block.
855 * @param[in] cfg TMU configuration
857 void tmu_init(struct tmu_cfg
*cfg
)
861 /* keep in soft reset */
862 writel(SW_RESET
, TMU_CTRL
);
864 /*Make Class AXI transactions non-bufferable */
865 writel(0x1, TMU_AXI_CTRL
);
867 /* enable EMAC PHY ports */
868 writel(0x3, TMU_SYS_GENERIC_CONTROL
);
870 writel(750, TMU_INQ_WATERMARK
);
872 writel(CBUS_VIRT_TO_PFE(EGPI1_BASE_ADDR
+ GPI_INQ_PKTPTR
),
874 writel(CBUS_VIRT_TO_PFE(EGPI2_BASE_ADDR
+ GPI_INQ_PKTPTR
),
877 writel(CBUS_VIRT_TO_PFE(HGPI_BASE_ADDR
+ GPI_INQ_PKTPTR
),
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
),
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
);
889 if (PLL_CLK_EN
== 0) {
890 /* Clock ratio: for 1:1 the value is 0 */
891 writel(0x0, TMU_PE_SYS_CLK_RATIO
);
893 /* Clock ratio: for 1:2 the value is 1 */
894 writel(0x1, TMU_PE_SYS_CLK_RATIO
);
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
);
901 debug("TMU_LLM_QUE_LEN %x\n", cfg
->llm_queue_len
);
902 writel(cfg
->llm_queue_len
, TMU_LLM_QUE_LEN
);
904 writel(5, TMU_TDQ_IIFG_CFG
);
905 writel(DDR_BUF_SIZE
, TMU_BMU_BUF_SIZE
);
907 writel(0x0, TMU_CTRL
);
910 writel(MEM_INIT
, TMU_CTRL
);
912 while (!(readl(TMU_CTRL
) & MEM_INIT_DONE
))
916 writel(LLM_INIT
, TMU_CTRL
);
918 while (!(readl(TMU_CTRL
) & LLM_INIT_DONE
))
921 /* set up each queue for tail drop */
922 for (phyno
= 0; phyno
< 4; phyno
++) {
925 for (q
= 0; q
< 16; q
++) {
928 writel((phyno
<< 8) | q
, TMU_TEQ_CTRL
);
929 writel(BIT(22), TMU_TEQ_QCFG
);
932 qmax
= DEFAULT_TMU3_QDEPTH
;
934 qmax
= (q
== 0) ? DEFAULT_Q0_QDEPTH
:
937 writel(qmax
<< 18, TMU_TEQ_HW_PROB_CFG2
);
938 writel(qmax
>> 14, TMU_TEQ_HW_PROB_CFG3
);
941 writel(0x05, TMU_TEQ_DISABLE_DROPCHK
);
945 /**************************** HIF ***************************/
947 * Enable hif tx DMA and interrupt
949 void hif_tx_enable(void)
951 writel(HIF_CTRL_DMA_EN
, HIF_TX_CTRL
);
955 * Disable hif tx DMA and interrupt
957 void hif_tx_disable(void)
961 writel(0, HIF_TX_CTRL
);
963 hif_int
= readl(HIF_INT_ENABLE
);
964 hif_int
&= HIF_TXPKT_INT_EN
;
965 writel(hif_int
, HIF_INT_ENABLE
);
969 * Enable hif rx DMA and interrupt
971 void hif_rx_enable(void)
973 writel((HIF_CTRL_DMA_EN
| HIF_CTRL_BDP_CH_START_WSTB
), HIF_RX_CTRL
);
977 * Disable hif rx DMA and interrupt
979 void hif_rx_disable(void)
983 writel(0, HIF_RX_CTRL
);
985 hif_int
= readl(HIF_INT_ENABLE
);
986 hif_int
&= HIF_RXPKT_INT_EN
;
987 writel(hif_int
, HIF_INT_ENABLE
);
991 * Initializes HIF copy block.
995 /* Initialize HIF registers */
996 writel(HIF_RX_POLL_CTRL_CYCLE
<< 16 | HIF_TX_POLL_CTRL_CYCLE
,
998 /* Make HIF AXI transactions non-bufferable */
999 writel(0x1, HIF_AXI_CTRL
);