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);