/* SPDX-License-Identifier: LGPL-2.1-only OR BSD-3-Clause */
/******************************************************************************
 *
 * This file is provided under a dual license.  When you use or
 * distribute this software, you may choose to be licensed under
 * version 2.1 of the GNU Lesser General Public License
 * ("LGPLv2.1 License") or BSD License.
 *
 * LGPLv2.1 License
 *
 * Copyright(C) 2019 MediaTek Inc.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of version 2.1 of the GNU Lesser General Public
 * License as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 * See https://www.gnu.org/licenses/old-licenses/lgpl-2.1.html for more
 * details.
 *
 * BSD LICENSE
 *
 * Copyright(C) 2019 MediaTek Inc.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 *  * Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *  * Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *  * Neither the name of the copyright holder nor the names of its
 *    contributors may be used to endorse or promote products derived
 *    from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 *****************************************************************************/

#ifndef _MT53_DLMALLOC_H_
#define _MT53_DLMALLOC_H_

//==========================================================================
//
//      dlmalloc.h
//
//      Interface to the port of Doug Lea's malloc implementation
//
//==========================================================================

// init memory pool
// return true on success
extern int
MT53_GPU_dlmem_init(void* base, int size);

// get some memory, return NULL if none available
extern void*
MT53_GPU_dlmalloc(int size);

extern void*
MT53_GPU_dlcalloc(int nmemb, int size);

// resize existing allocation, if oldsize is non-NULL, previous
// allocation size is placed into it. If previous size not available,
// it is set to 0. NB previous allocation size may have been rounded up.
// Occasionally the allocation can be adjusted *backwards* as well as,
// or instead of forwards, therefore the address of the resized
// allocation is returned, or NULL if no resizing was possible.
// Note that this differs from ::realloc() in that no attempt is
// made to call malloc() if resizing is not possible - that is left
// to higher layers. The data is copied from old to new though.
// The effects of alloc_ptr==NULL or newsize==0 are undefined
extern void*
MT53_GPU_dlresize_alloc(void* alloc_ptr, int newsize, int* oldsize);

extern void*
MT53_GPU_dlrealloc(void* ptr, int size);

// free the memory back to the pool
// returns true on success
extern int
MT53_GPU_dlfree(void* ptr);

typedef struct MT53_GPU_mempool_status
{
    const unsigned char *arenabase;     // base address of entire pool
    int   arenasize;                    // total size of entire pool
    int   freeblocks;                   // number of chunks free for use
    int   totalallocated;               // total allocated space in bytes
    int   totalfree;                    // total space in bytes not in use
    int   blocksize;                    // block size if fixed block
    int   maxfree;                      // size of largest unused block
    char  waiting;                      // are there any threads waiting for memory?
    const unsigned char *origbase;      // address of original region used when pool
                                        // created
    int   origsize;                     // size of original region used when pool
                                        // created

    // maxoverhead is the *maximum* per-allocation overhead imposed by
    // the allocator implementation. Note: this is rarely the typical
    // overhead which often depends on the size of the allocation requested.
    // It includes overhead due to alignment constraints. For example, if
    // maxfree and maxoverhead are available for this allocator, then an
    // allocation request of (maxfree-maxoverhead) bytes must always succeed
    // Unless maxoverhead is set to -1 of course, in which case the allocator
    // does not support reporting this information.
    char    maxoverhead;
}mt_mempool_status;

// Flags to pass to mem_get_status() methods to tell it which stat(s) is/are
// being requested

typedef struct {
	unsigned int	physicalAddr;		/**< physical address of surface pool base */
	unsigned int	virtualAddr;		/**< virtual address of surface pool base */
	unsigned int	startOffset;		/**< the end of allocated layers (surface pool start with zero offset.) */
	unsigned int	size;				/**< size of surface pool (in bytes). It is not from startOffset but zero offset which means base point of surface pool. */
	unsigned short	byteOffsetAlign;	/**< bytes alignment constraint for the offset value of each surface allocation */
	unsigned short	bytePitchAlign;		/**< bytes alignment constraint for the surface's pitch value */
} MT53_HOA_GX_SURFACE_POOL_INFO_T;



#define MT53_GPU_MEMPOOL_STAT_ARENABASE       (1<<0)
#define MT53_GPU_MEMPOOL_STAT_ARENASIZE       (1<<1)
#define MT53_GPU_MEMPOOL_STAT_FREEBLOCKS      (1<<2)
#define MT53_GPU_MEMPOOL_STAT_TOTALALLOCATED  (1<<3)
#define MT53_GPU_MEMPOOL_STAT_TOTALFREE       (1<<4)
#define MT53_GPU_MEMPOOL_STAT_BLOCKSIZE       (1<<5)
#define MT53_GPU_MEMPOOL_STAT_MAXFREE         (1<<6)
#define MT53_GPU_MEMPOOL_STAT_WAITING         (1<<7)
#define MT53_GPU_MEMPOOL_STAT_ORIGBASE        (1<<9)
#define MT53_GPU_MEMPOOL_STAT_ORIGSIZE        (1<<10)
#define MT53_GPU_MEMPOOL_STAT_MAXOVERHEAD     (1<<11)
#define MT53_GPU_MEMPOOL_STAT_ALL             0xfff

// Get memory pool status
// flags is a bitmask of requested fields to fill in. The flags are
// defined in common.hxx
extern void
MT53_GPU_dlmem_get_status(unsigned int flags, struct MT53_GPU_mempool_status* status);

/*

#include <stdlib.h>

extern struct mallinfo
mallinfo(void);

*/

#endif // ifndef _DLMALLOC_H_

// EOF dlmalloc.h
