From: Aaron Williams <awilli...@marvell.com> Import cvmx-helper-fpa.c from 2013 U-Boot. It will be used by the later added drivers to support networking on the MIPS Octeon II / III platforms.
Signed-off-by: Aaron Williams <awilli...@marvell.com> Signed-off-by: Stefan Roese <s...@denx.de> --- arch/mips/mach-octeon/cvmx-helper-fpa.c | 329 ++++++++++++++++++++++++ 1 file changed, 329 insertions(+) create mode 100644 arch/mips/mach-octeon/cvmx-helper-fpa.c diff --git a/arch/mips/mach-octeon/cvmx-helper-fpa.c b/arch/mips/mach-octeon/cvmx-helper-fpa.c new file mode 100644 index 000000000000..ba31e66579f1 --- /dev/null +++ b/arch/mips/mach-octeon/cvmx-helper-fpa.c @@ -0,0 +1,329 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2018-2022 Marvell International Ltd. + * + * Helper functions for FPA setup. + */ + +#include <errno.h> +#include <log.h> +#include <time.h> +#include <linux/delay.h> + +#include <mach/cvmx-regs.h> +#include <mach/cvmx-csr.h> +#include <mach/cvmx-bootmem.h> +#include <mach/octeon-model.h> +#include <mach/cvmx-fuse.h> +#include <mach/octeon-feature.h> +#include <mach/cvmx-qlm.h> +#include <mach/octeon_qlm.h> +#include <mach/cvmx-pcie.h> +#include <mach/cvmx-coremask.h> +#include <mach/cvmx-range.h> +#include <mach/cvmx-global-resources.h> + +#include <mach/cvmx-agl-defs.h> +#include <mach/cvmx-bgxx-defs.h> +#include <mach/cvmx-ciu-defs.h> +#include <mach/cvmx-gmxx-defs.h> +#include <mach/cvmx-gserx-defs.h> +#include <mach/cvmx-ilk-defs.h> +#include <mach/cvmx-ipd-defs.h> +#include <mach/cvmx-pcsx-defs.h> +#include <mach/cvmx-pcsxx-defs.h> +#include <mach/cvmx-pki-defs.h> +#include <mach/cvmx-pko-defs.h> +#include <mach/cvmx-xcv-defs.h> + +#include <mach/cvmx-hwpko.h> +#include <mach/cvmx-ilk.h> +#include <mach/cvmx-ipd.h> +#include <mach/cvmx-pki.h> +#include <mach/cvmx-pko3.h> +#include <mach/cvmx-pko3-queue.h> +#include <mach/cvmx-pko3-resources.h> +#include <mach/cvmx-pip.h> + +#include <mach/cvmx-helper.h> +#include <mach/cvmx-helper-board.h> +#include <mach/cvmx-helper-cfg.h> + +#include <mach/cvmx-helper-bgx.h> +#include <mach/cvmx-helper-cfg.h> +#include <mach/cvmx-helper-util.h> +#include <mach/cvmx-helper-pki.h> +#include <mach/cvmx-helper-pko.h> + +void cvmx_helper_fpa1_dump(int node) +{ + int pool_num = 0, pools_max = cvmx_fpa_get_max_pools(); + + if (node == -1) + node = cvmx_get_node_num(); + + printf("FPA pool status: pools count: %u\n", pools_max); + printf("----------------------------------------------------\n"); + printf("%5s %5s %12s %16s\n", "POOL", "Size", "Free", "Name"); + + while (pool_num < pools_max) { + int pool = pool_num++; + unsigned int sz = cvmx_fpa_get_block_size(pool); + char *s = ""; + + if (sz == 0) + continue; + if (cvmx_fpa_get_pool_owner(pool) != cvmx_get_app_id()) + s = "*"; + + printf("%5u %5u %12u %16s %1s\n", pool, sz, + cvmx_fpa_get_current_count(pool), + cvmx_fpa_get_name(pool), s); + } +} + +void cvmx_helper_fpa3_dump(unsigned int node) +{ + int lpool, laura; + unsigned int intr; + char line[128]; + + intr = csr_rd_node(node, CVMX_FPA_ERR_INT); + memset(line, '*', 80); + line[80] = '\0'; + printf("\n%s\n", line); + printf(" FPA3 on node %u: intr=%#x\n", node, intr); + printf("%s\n", line); + printf("%6s %5s %14s %14s %16s %s\n", "POOL", "Size", "Free", "", + "Name", "Intr"); + + for (lpool = 0; lpool < cvmx_fpa3_num_pools(); lpool++) { + cvmx_fpa3_pool_t pool; + cvmx_fpa_poolx_cfg_t pool_cfg; + cvmx_fpa_poolx_available_t avail_reg; + unsigned int bsz; + unsigned long long bcnt; + + pool = __cvmx_fpa3_pool(node, lpool); + pool_cfg.u64 = + csr_rd_node(pool.node, CVMX_FPA_POOLX_CFG(pool.lpool)); + bsz = pool_cfg.cn78xx.buf_size << 7; + if (bsz == 0) + continue; + avail_reg.u64 = csr_rd_node( + pool.node, CVMX_FPA_POOLX_AVAILABLE(pool.lpool)); + bcnt = avail_reg.cn78xx.count; + intr = csr_rd_node(pool.node, CVMX_FPA_POOLX_INT(pool.lpool)); + + printf("%6u %5u %14llu %14s %16s %#4x\n", lpool, bsz, bcnt, "", + cvmx_fpa3_get_pool_name(pool), intr); + } + printf("\n"); + + printf("%6s %5s %14s %14s %16s %s\n", "AURA", "POOL", "Allocated", + "Remaining", "Name", "Intr"); + + for (laura = 0; laura < cvmx_fpa3_num_auras(); laura++) { + cvmx_fpa3_gaura_t aura; + cvmx_fpa_aurax_cnt_t cnt_reg; + cvmx_fpa_aurax_cnt_limit_t limit_reg; + cvmx_fpa_aurax_pool_t aurax_pool; + unsigned long long cnt, limit, rem; + unsigned int pool; + const char *name; + + aura = __cvmx_fpa3_gaura(node, laura); + aurax_pool.u64 = + csr_rd_node(aura.node, CVMX_FPA_AURAX_POOL(aura.laura)); + pool = aurax_pool.cn78xx.pool; + if (pool == 0) + continue; + cnt_reg.u64 = + csr_rd_node(aura.node, CVMX_FPA_AURAX_CNT(aura.laura)); + limit_reg.u64 = csr_rd_node( + aura.node, CVMX_FPA_AURAX_CNT_LIMIT(aura.laura)); + cnt = cnt_reg.cn78xx.cnt; + limit = limit_reg.cn78xx.limit; + rem = limit - cnt; + name = cvmx_fpa3_get_aura_name(aura); + intr = csr_rd_node(aura.node, CVMX_FPA_AURAX_INT(aura.laura)); + + if (limit == CVMX_FPA3_AURAX_LIMIT_MAX) + printf("%6u %5u %14llu %14s %16s %#4x\n", laura, pool, + cnt, "unlimited", name, intr); + else + printf("%6u %5u %14llu %14llu %16s %#4x\n", laura, pool, + cnt, rem, name, intr); + } + printf("\n"); +} + +void cvmx_helper_fpa_dump(int node) +{ + if (node == -1) + node = cvmx_get_node_num(); + if (octeon_has_feature(OCTEON_FEATURE_FPA3)) + cvmx_helper_fpa3_dump(node); + else + cvmx_helper_fpa1_dump(node); +} + +int cvmx_helper_shutdown_fpa_pools(int node) +{ + if (octeon_has_feature(OCTEON_FEATURE_FPA3)) { + cvmx_fpa3_gaura_t aura; + cvmx_fpa3_pool_t pool; + int laura, lpool; + + for (laura = 0; laura < cvmx_fpa3_num_auras(); laura++) { + aura = __cvmx_fpa3_gaura(node, laura); + (void)cvmx_fpa3_shutdown_aura(aura); + } + + for (lpool = 0; lpool < cvmx_fpa3_num_pools(); lpool++) { + pool = __cvmx_fpa3_pool(node, lpool); + (void)cvmx_fpa3_shutdown_pool(pool); + } + } else { + int pool; + + for (pool = 0; pool < CVMX_FPA1_NUM_POOLS; pool++) { + if (cvmx_fpa_get_block_size(pool) > 0) + cvmx_fpa_shutdown_pool(pool); + } + if (!OCTEON_IS_MODEL(OCTEON_CN68XX)) + cvmx_fpa_disable(); + } + + return 0; +} + +/** + * @INTERNAL + * OBSOLETE + * + * Allocate memory for and initialize a single FPA pool. + * + * @param pool Pool to initialize + * @param buffer_size Size of buffers to allocate in bytes + * @param buffers Number of buffers to put in the pool. Zero is allowed + * @param name String name of the pool for debugging purposes + * @return Zero on success, non-zero on failure + * + * This function is only for transition, will be removed. + */ +int __cvmx_helper_initialize_fpa_pool(int pool, u64 buffer_size, u64 buffers, + const char *name) +{ + return cvmx_fpa_setup_pool(pool, name, NULL, buffer_size, buffers); +} + +/** + * @INTERNAL + * Allocate memory and initialize the FPA pools using memory + * from cvmx-bootmem. Specifying zero for the number of + * buffers will cause that FPA pool to not be setup. This is + * useful if you aren't using some of the hardware and want + * to save memory. Use cvmx_helper_initialize_fpa instead of + * this function directly. + * + * @param pip_pool Should always be CVMX_FPA_PACKET_POOL + * @param pip_size Should always be CVMX_FPA_PACKET_POOL_SIZE + * @param pip_buffers + * Number of packet buffers. + * @param wqe_pool Should always be CVMX_FPA_WQE_POOL + * @param wqe_size Should always be CVMX_FPA_WQE_POOL_SIZE + * @param wqe_entries + * Number of work queue entries + * @param pko_pool Should always be CVMX_FPA_OUTPUT_BUFFER_POOL + * @param pko_size Should always be CVMX_FPA_OUTPUT_BUFFER_POOL_SIZE + * @param pko_buffers + * PKO Command buffers. You should at minimum have two per + * each PKO queue. + * @param tim_pool Should always be CVMX_FPA_TIMER_POOL + * @param tim_size Should always be CVMX_FPA_TIMER_POOL_SIZE + * @param tim_buffers + * TIM ring buffer command queues. At least two per timer bucket + * is recommended. + * @param dfa_pool Should always be CVMX_FPA_DFA_POOL + * @param dfa_size Should always be CVMX_FPA_DFA_POOL_SIZE + * @param dfa_buffers + * DFA command buffer. A relatively small (32 for example) + * number should work. + * @return Zero on success, non-zero if out of memory + */ +static int +__cvmx_helper_initialize_fpa(int pip_pool, int pip_size, int pip_buffers, + int wqe_pool, int wqe_size, int wqe_entries, + int pko_pool, int pko_size, int pko_buffers, + int tim_pool, int tim_size, int tim_buffers, + int dfa_pool, int dfa_size, int dfa_buffers) +{ + cvmx_fpa_enable(); + if (pip_buffers > 0) { + cvmx_fpa_setup_pool(pip_pool, "PKI_POOL", NULL, pip_size, + pip_buffers); + } + /* Allocate WQE pool only if it is distinct from packet pool */ + if (wqe_entries > 0 && wqe_pool != pip_pool) { + cvmx_fpa_setup_pool(wqe_pool, "WQE_POOL", NULL, wqe_size, + wqe_entries); + } + /* cn78xx PKO allocates its own FPA pool per HW constraints */ + if (pko_buffers > 0) { + if (!octeon_has_feature(OCTEON_FEATURE_PKI)) + cvmx_fpa_setup_pool(pko_pool, "PKO_POOL", NULL, + pko_size, pko_buffers); + } + if (tim_buffers > 0) { + cvmx_fpa_setup_pool(tim_pool, "TIM_POOL", NULL, tim_size, + tim_buffers); + } + return 0; +} + +/** + * Allocate memory and initialize the FPA pools using memory + * from cvmx-bootmem. Sizes of each element in the pools is + * controlled by the cvmx-config.h header file. Specifying + * zero for any parameter will cause that FPA pool to not be + * setup. This is useful if you aren't using some of the + * hardware and want to save memory. + * + * @param packet_buffers + * Number of packet buffers to allocate + * @param work_queue_entries + * Number of work queue entries + * @param pko_buffers + * PKO Command buffers. You should at minimum have two per + * each PKO queue. + * @param tim_buffers + * TIM ring buffer command queues. At least two per timer bucket + * is recommended. + * @param dfa_buffers + * DFA command buffer. A relatively small (32 for example) + * number should work. + * @return Zero on success, non-zero if out of memory + */ +int cvmx_helper_initialize_fpa(int packet_buffers, int work_queue_entries, + int pko_buffers, int tim_buffers, + int dfa_buffers) +{ + int packet_pool = (int)cvmx_fpa_get_packet_pool(); + int wqe_pool = (int)cvmx_fpa_get_wqe_pool(); + int outputbuffer_pool = (int)cvmx_fpa_get_pko_pool(); + int timer_pool; + int dfa_pool = 0; + int rv; + + timer_pool = 0; + + rv = __cvmx_helper_initialize_fpa( + packet_pool, cvmx_fpa_get_packet_pool_block_size(), + packet_buffers, wqe_pool, cvmx_fpa_get_wqe_pool_block_size(), + work_queue_entries, outputbuffer_pool, + cvmx_fpa_get_pko_pool_block_size(), pko_buffers, timer_pool, 0, + tim_buffers, dfa_pool, 0, dfa_buffers); + + return rv; +} -- 2.35.1