105b405d5SPeter Spreadborough /* SPDX-License-Identifier: BSD-3-Clause 2*e6e8f03eSRandy Schacher * Copyright(c) 2019-2023 Broadcom 305b405d5SPeter Spreadborough * All rights reserved. 405b405d5SPeter Spreadborough */ 505b405d5SPeter Spreadborough 605b405d5SPeter Spreadborough #ifndef _DPOOL_H_ 705b405d5SPeter Spreadborough #define _DPOOL_H_ 805b405d5SPeter Spreadborough 905b405d5SPeter Spreadborough #include <stdint.h> 1005b405d5SPeter Spreadborough #include <stdlib.h> 1105b405d5SPeter Spreadborough 1205b405d5SPeter Spreadborough #define DP_MAX_FREE_SIZE 0x8000 /* 32K */ 1305b405d5SPeter Spreadborough 1405b405d5SPeter Spreadborough #define DP_INVALID_INDEX 0xffffffff 1505b405d5SPeter Spreadborough 1605b405d5SPeter Spreadborough #define DP_FLAGS_START 0x80000000 1705b405d5SPeter Spreadborough #define DP_IS_START(flags) ((flags) & DP_FLAGS_START) 1805b405d5SPeter Spreadborough 1905b405d5SPeter Spreadborough #define DP_FLAGS_SIZE_SHIFT 0 2005b405d5SPeter Spreadborough #define DP_FLAGS_SIZE_MASK 0x07 2105b405d5SPeter Spreadborough 2205b405d5SPeter Spreadborough #define DP_FLAGS_SIZE(flags) (((flags) >> DP_FLAGS_SIZE_SHIFT) & DP_FLAGS_SIZE_MASK) 2305b405d5SPeter Spreadborough 2405b405d5SPeter Spreadborough #define DP_IS_FREE(flags) (((flags) & DP_FLAGS_SIZE_MASK) == 0) 2505b405d5SPeter Spreadborough #define DP_IS_USED(flags) ((flags) & DP_FLAGS_SIZE_MASK) 2605b405d5SPeter Spreadborough 2705b405d5SPeter Spreadborough #define DP_DEFRAG_NONE 0x0 2805b405d5SPeter Spreadborough #define DP_DEFRAG_ALL 0x1 2905b405d5SPeter Spreadborough #define DP_DEFRAG_TO_FIT 0x2 3005b405d5SPeter Spreadborough 3105b405d5SPeter Spreadborough /** 3205b405d5SPeter Spreadborough * Free list entry 3305b405d5SPeter Spreadborough * 3405b405d5SPeter Spreadborough * Each entry includes an index in to the dpool entry array 3505b405d5SPeter Spreadborough * and the size of dpool array entry. 3605b405d5SPeter Spreadborough */ 3705b405d5SPeter Spreadborough struct dpool_free_list_entry { 3805b405d5SPeter Spreadborough /* 3905b405d5SPeter Spreadborough * Index in to dpool entry array 4005b405d5SPeter Spreadborough */ 4105b405d5SPeter Spreadborough uint32_t index; 4205b405d5SPeter Spreadborough /* 4305b405d5SPeter Spreadborough * The size of the entry in the dpool entry array 4405b405d5SPeter Spreadborough */ 4505b405d5SPeter Spreadborough uint32_t size; 4605b405d5SPeter Spreadborough }; 4705b405d5SPeter Spreadborough 4805b405d5SPeter Spreadborough /** 4905b405d5SPeter Spreadborough * Free list 5005b405d5SPeter Spreadborough * 5105b405d5SPeter Spreadborough * Used internally to record free entries in the dpool entry array. 5205b405d5SPeter Spreadborough * Each entry represents a single or multiple contiguous entries 5305b405d5SPeter Spreadborough * in the dpool entry array. 5405b405d5SPeter Spreadborough * 5505b405d5SPeter Spreadborough * Used only during the defrag operation. 5605b405d5SPeter Spreadborough */ 5705b405d5SPeter Spreadborough struct dpool_free_list { 5805b405d5SPeter Spreadborough /* 5905b405d5SPeter Spreadborough * Number of entries in the free list 6005b405d5SPeter Spreadborough */ 6105b405d5SPeter Spreadborough uint32_t size; 6205b405d5SPeter Spreadborough /* 6305b405d5SPeter Spreadborough * List of unused entries in the dpool entry array 6405b405d5SPeter Spreadborough */ 6505b405d5SPeter Spreadborough struct dpool_free_list_entry entry[DP_MAX_FREE_SIZE]; 6605b405d5SPeter Spreadborough }; 6705b405d5SPeter Spreadborough 6805b405d5SPeter Spreadborough /** 6905b405d5SPeter Spreadborough * Adjacent list entry 7005b405d5SPeter Spreadborough * 7105b405d5SPeter Spreadborough * Each entry includes and index in to the dpool entry array, 7205b405d5SPeter Spreadborough * the size of the entry and the counts of free entries to the 7305b405d5SPeter Spreadborough * right and left off that entry. 7405b405d5SPeter Spreadborough */ 7505b405d5SPeter Spreadborough struct dpool_adj_list_entry { 7605b405d5SPeter Spreadborough /* 7705b405d5SPeter Spreadborough * Index in to dpool entry array 7805b405d5SPeter Spreadborough */ 7905b405d5SPeter Spreadborough uint32_t index; 8005b405d5SPeter Spreadborough /* 8105b405d5SPeter Spreadborough * The size of the entry in the dpool entry array 8205b405d5SPeter Spreadborough */ 8305b405d5SPeter Spreadborough uint32_t size; 8405b405d5SPeter Spreadborough /* 8505b405d5SPeter Spreadborough * Number of free entries directly to the left of 8605b405d5SPeter Spreadborough * this entry 8705b405d5SPeter Spreadborough */ 8805b405d5SPeter Spreadborough uint32_t left; 8905b405d5SPeter Spreadborough /* 9005b405d5SPeter Spreadborough * Number of free entries directly to the right of 9105b405d5SPeter Spreadborough * this entry 9205b405d5SPeter Spreadborough */ 9305b405d5SPeter Spreadborough uint32_t right; 9405b405d5SPeter Spreadborough }; 9505b405d5SPeter Spreadborough 9605b405d5SPeter Spreadborough /** 9705b405d5SPeter Spreadborough * Adjacent list 9805b405d5SPeter Spreadborough * 9905b405d5SPeter Spreadborough * A list of references to entries in the dpool entry array that 10005b405d5SPeter Spreadborough * have free entries to the left and right. Since we pack to the 1011993b267SShahaji Bhosle * left entries will always have a non zero left out. 10205b405d5SPeter Spreadborough * 10305b405d5SPeter Spreadborough * Used only during the defrag operation. 10405b405d5SPeter Spreadborough */ 10505b405d5SPeter Spreadborough struct dpool_adj_list { 10605b405d5SPeter Spreadborough /* 10705b405d5SPeter Spreadborough * Number of entries in the adj list 10805b405d5SPeter Spreadborough */ 10905b405d5SPeter Spreadborough uint32_t size; 11005b405d5SPeter Spreadborough /* 11105b405d5SPeter Spreadborough * List of entries in the dpool entry array that have 11205b405d5SPeter Spreadborough * free entries directly to their left and right. 11305b405d5SPeter Spreadborough */ 11405b405d5SPeter Spreadborough struct dpool_adj_list_entry entry[DP_MAX_FREE_SIZE]; 11505b405d5SPeter Spreadborough }; 11605b405d5SPeter Spreadborough 11705b405d5SPeter Spreadborough /** 11805b405d5SPeter Spreadborough * Dpool entry 11905b405d5SPeter Spreadborough * 12005b405d5SPeter Spreadborough * Each entry includes flags and the FW index. 12105b405d5SPeter Spreadborough */ 12205b405d5SPeter Spreadborough struct dpool_entry { 12305b405d5SPeter Spreadborough uint32_t flags; 12405b405d5SPeter Spreadborough uint32_t index; 12505b405d5SPeter Spreadborough uint64_t entry_data; 12605b405d5SPeter Spreadborough }; 12705b405d5SPeter Spreadborough 12805b405d5SPeter Spreadborough /** 12905b405d5SPeter Spreadborough * Dpool 13005b405d5SPeter Spreadborough * 13105b405d5SPeter Spreadborough * Used to manage resource pool. Includes the start FW index, the 13205b405d5SPeter Spreadborough * size of the entry array and the entry array it's self. 13305b405d5SPeter Spreadborough */ 13405b405d5SPeter Spreadborough struct dpool { 13505b405d5SPeter Spreadborough uint32_t start_index; 13605b405d5SPeter Spreadborough uint32_t size; 13705b405d5SPeter Spreadborough uint8_t max_alloc_size; 13805b405d5SPeter Spreadborough void *user_data; 13905b405d5SPeter Spreadborough int (*move_callback)(void *user_data, 14005b405d5SPeter Spreadborough uint64_t entry_data, 14105b405d5SPeter Spreadborough uint32_t new_index); 14205b405d5SPeter Spreadborough struct dpool_entry *entry; 14305b405d5SPeter Spreadborough }; 14405b405d5SPeter Spreadborough 14505b405d5SPeter Spreadborough /** 14605b405d5SPeter Spreadborough * dpool_init 14705b405d5SPeter Spreadborough * 14805b405d5SPeter Spreadborough * Initialize the dpool 14905b405d5SPeter Spreadborough * 15005b405d5SPeter Spreadborough * [in] dpool 15105b405d5SPeter Spreadborough * Pointer to a dpool structure that includes an entry field 15205b405d5SPeter Spreadborough * that points to the entry array. The user is responsible for 15305b405d5SPeter Spreadborough * allocating memory for the dpool struct and the entry array. 15405b405d5SPeter Spreadborough * 15505b405d5SPeter Spreadborough * [in] start_index 15605b405d5SPeter Spreadborough * The base index to use. 15705b405d5SPeter Spreadborough * 15805b405d5SPeter Spreadborough * [in] size 15905b405d5SPeter Spreadborough * The number of entries 16005b405d5SPeter Spreadborough * 16105b405d5SPeter Spreadborough * [in] max_alloc_size 16205b405d5SPeter Spreadborough * The number of entries 16305b405d5SPeter Spreadborough * 16405b405d5SPeter Spreadborough * [in] user_data 16505b405d5SPeter Spreadborough * Pointer to user data. Will be passed in callbacks. 16605b405d5SPeter Spreadborough * 16705b405d5SPeter Spreadborough * [in] move_callback 16805b405d5SPeter Spreadborough * Pointer to move EM entry callback. 16905b405d5SPeter Spreadborough * 17005b405d5SPeter Spreadborough * Return 17105b405d5SPeter Spreadborough * - 0 on success 17205b405d5SPeter Spreadborough * - -1 on failure 17305b405d5SPeter Spreadborough * 17405b405d5SPeter Spreadborough */ 17505b405d5SPeter Spreadborough int dpool_init(struct dpool *dpool, 17605b405d5SPeter Spreadborough uint32_t start_index, 17705b405d5SPeter Spreadborough uint32_t size, 17805b405d5SPeter Spreadborough uint8_t max_alloc_size, 17905b405d5SPeter Spreadborough void *user_data, 18005b405d5SPeter Spreadborough int (*move_callback)(void *, uint64_t, uint32_t)); 18105b405d5SPeter Spreadborough 18205b405d5SPeter Spreadborough /** 18305b405d5SPeter Spreadborough * dpool_alloc 18405b405d5SPeter Spreadborough * 18505b405d5SPeter Spreadborough * Request a FW index of size and if necessary de-fragment the dpool 18605b405d5SPeter Spreadborough * array. 18705b405d5SPeter Spreadborough * 18805b405d5SPeter Spreadborough * [i] dpool 18905b405d5SPeter Spreadborough * The dpool 19005b405d5SPeter Spreadborough * 19105b405d5SPeter Spreadborough * [i] size 19205b405d5SPeter Spreadborough * The size of the requested allocation. 19305b405d5SPeter Spreadborough * 19405b405d5SPeter Spreadborough * [i] defrag 19505b405d5SPeter Spreadborough * Operation to apply when there is insufficient space: 19605b405d5SPeter Spreadborough * 19705b405d5SPeter Spreadborough * DP_DEFRAG_NONE (0x0) - Don't do anything. 19805b405d5SPeter Spreadborough * DP_DEFRAG_ALL (0x1) - Defrag until there is nothing left 19905b405d5SPeter Spreadborough * to defrag. 20005b405d5SPeter Spreadborough * DP_DEFRAG_TO_FIT (0x2) - Defrag until there is just enough space 20105b405d5SPeter Spreadborough * to insert the requested allocation. 20205b405d5SPeter Spreadborough * 20305b405d5SPeter Spreadborough * Return 20405b405d5SPeter Spreadborough * - FW index on success 20505b405d5SPeter Spreadborough * - DP_INVALID_INDEX on failure 20605b405d5SPeter Spreadborough * 20705b405d5SPeter Spreadborough */ 20805b405d5SPeter Spreadborough uint32_t dpool_alloc(struct dpool *dpool, 20905b405d5SPeter Spreadborough uint32_t size, 21005b405d5SPeter Spreadborough uint8_t defrag); 21105b405d5SPeter Spreadborough 21205b405d5SPeter Spreadborough /** 21305b405d5SPeter Spreadborough * dpool_set_entry_data 21405b405d5SPeter Spreadborough * 21505b405d5SPeter Spreadborough * Set the entry data field. This will be passed to callbacks. 21605b405d5SPeter Spreadborough * 21705b405d5SPeter Spreadborough * [i] dpool 21805b405d5SPeter Spreadborough * The dpool 21905b405d5SPeter Spreadborough * 22005b405d5SPeter Spreadborough * [i] index 22105b405d5SPeter Spreadborough * FW index 22205b405d5SPeter Spreadborough * 22305b405d5SPeter Spreadborough * [i] entry_data 22405b405d5SPeter Spreadborough * Entry data value 22505b405d5SPeter Spreadborough * 22605b405d5SPeter Spreadborough * Return 22705b405d5SPeter Spreadborough * - FW index on success 22805b405d5SPeter Spreadborough * - DP_INVALID_INDEX on failure 22905b405d5SPeter Spreadborough * 23005b405d5SPeter Spreadborough */ 23105b405d5SPeter Spreadborough int dpool_set_entry_data(struct dpool *dpool, 23205b405d5SPeter Spreadborough uint32_t index, 23305b405d5SPeter Spreadborough uint64_t entry_data); 23405b405d5SPeter Spreadborough 23505b405d5SPeter Spreadborough /** 23605b405d5SPeter Spreadborough * dpool_free 23705b405d5SPeter Spreadborough * 23805b405d5SPeter Spreadborough * Free allocated entry. The is responsible for the dpool and dpool 23905b405d5SPeter Spreadborough * entry array memory. 24005b405d5SPeter Spreadborough * 24105b405d5SPeter Spreadborough * [in] dpool 24205b405d5SPeter Spreadborough * The pool 24305b405d5SPeter Spreadborough * 24405b405d5SPeter Spreadborough * [in] index 24505b405d5SPeter Spreadborough * FW index to free up. 24605b405d5SPeter Spreadborough * 24705b405d5SPeter Spreadborough * Result 24805b405d5SPeter Spreadborough * - 0 on success 24905b405d5SPeter Spreadborough * - -1 on failure 25005b405d5SPeter Spreadborough * 25105b405d5SPeter Spreadborough */ 25205b405d5SPeter Spreadborough int dpool_free(struct dpool *dpool, 25305b405d5SPeter Spreadborough uint32_t index); 25405b405d5SPeter Spreadborough 25505b405d5SPeter Spreadborough /** 25605b405d5SPeter Spreadborough * dpool_free_all 25705b405d5SPeter Spreadborough * 25805b405d5SPeter Spreadborough * Free all entries. 25905b405d5SPeter Spreadborough * 26005b405d5SPeter Spreadborough * [in] dpool 26105b405d5SPeter Spreadborough * The pool 26205b405d5SPeter Spreadborough * 26305b405d5SPeter Spreadborough * Result 26405b405d5SPeter Spreadborough * - 0 on success 26505b405d5SPeter Spreadborough * - -1 on failure 26605b405d5SPeter Spreadborough * 26705b405d5SPeter Spreadborough */ 26805b405d5SPeter Spreadborough void dpool_free_all(struct dpool *dpool); 26905b405d5SPeter Spreadborough 27005b405d5SPeter Spreadborough /** 27105b405d5SPeter Spreadborough * dpool_dump 27205b405d5SPeter Spreadborough * 27305b405d5SPeter Spreadborough * Debug/util function to dump the dpool array. 27405b405d5SPeter Spreadborough * 27505b405d5SPeter Spreadborough * [in] dpool 27605b405d5SPeter Spreadborough * The pool 27705b405d5SPeter Spreadborough * 27805b405d5SPeter Spreadborough */ 27905b405d5SPeter Spreadborough void dpool_dump(struct dpool *dpool); 28005b405d5SPeter Spreadborough 28105b405d5SPeter Spreadborough /** 28205b405d5SPeter Spreadborough * dpool_defrag 28305b405d5SPeter Spreadborough * 2841993b267SShahaji Bhosle * De-fragment the dpool array and apply the specified defrag strategy. 28505b405d5SPeter Spreadborough * 28605b405d5SPeter Spreadborough * [in] dpool 28705b405d5SPeter Spreadborough * The dpool 28805b405d5SPeter Spreadborough * 28905b405d5SPeter Spreadborough * [in] entry_size 2901993b267SShahaji Bhosle * If using the DP_DEFRAG_TO_FIT strategy defrag will stop when there's 29105b405d5SPeter Spreadborough * at least entry_size space available. 29205b405d5SPeter Spreadborough * 29305b405d5SPeter Spreadborough * [i] defrag 2941993b267SShahaji Bhosle * Defrag strategy: 29505b405d5SPeter Spreadborough * 29605b405d5SPeter Spreadborough * DP_DEFRAG_ALL (0x1) - Defrag until there is nothing left 29705b405d5SPeter Spreadborough * to defrag. 29805b405d5SPeter Spreadborough * DP_DEFRAG_TO_FIT (0x2) - Defrag until there is just enough space 29905b405d5SPeter Spreadborough * to insert the requested allocation. 30005b405d5SPeter Spreadborough * 30105b405d5SPeter Spreadborough * Return 30205b405d5SPeter Spreadborough * < 0 - on failure 30305b405d5SPeter Spreadborough * > 0 - The size of the largest free space 30405b405d5SPeter Spreadborough */ 30505b405d5SPeter Spreadborough int dpool_defrag(struct dpool *dpool, 30605b405d5SPeter Spreadborough uint32_t entry_size, 30705b405d5SPeter Spreadborough uint8_t defrag); 30805b405d5SPeter Spreadborough #endif /* _DPOOL_H_ */ 309