Add RP2 support for dma_capable
This places the VM heap in PSRAM by default. audio_dma now directly allocates its buffers to ensure they are dma_capable.
This commit is contained in:
parent
63815c5f45
commit
abb3e9351b
9 changed files with 45 additions and 45 deletions
|
|
@ -324,8 +324,12 @@ void port_free(void *ptr) {
|
|||
heap_caps_free(ptr);
|
||||
}
|
||||
|
||||
void *port_realloc(void *ptr, size_t size) {
|
||||
return heap_caps_realloc(ptr, size, MALLOC_CAP_8BIT);
|
||||
void *port_realloc(void *ptr, size_t size, bool dma_capable) {
|
||||
size_t caps = MALLOC_CAP_8BIT;
|
||||
if (dma_capable) {
|
||||
caps |= MALLOC_CAP_DMA;
|
||||
}
|
||||
return heap_caps_realloc(ptr, size, caps);
|
||||
}
|
||||
|
||||
size_t port_heap_get_largest_free_size(void) {
|
||||
|
|
|
|||
|
|
@ -227,12 +227,7 @@ audio_dma_result audio_dma_setup_playback(
|
|||
max_buffer_length /= dma->sample_spacing;
|
||||
}
|
||||
|
||||
dma->buffer[0] = (uint8_t *)m_realloc(dma->buffer[0],
|
||||
#if MICROPY_MALLOC_USES_ALLOCATED_SIZE
|
||||
dma->buffer_length[0], // Old size
|
||||
#endif
|
||||
max_buffer_length);
|
||||
|
||||
dma->buffer[0] = (uint8_t *)port_realloc(dma->buffer[0], max_buffer_length, true);
|
||||
dma->buffer_length[0] = max_buffer_length;
|
||||
|
||||
if (dma->buffer[0] == NULL) {
|
||||
|
|
@ -240,12 +235,7 @@ audio_dma_result audio_dma_setup_playback(
|
|||
}
|
||||
|
||||
if (!single_buffer) {
|
||||
dma->buffer[1] = (uint8_t *)m_realloc(dma->buffer[1],
|
||||
#if MICROPY_MALLOC_USES_ALLOCATED_SIZE
|
||||
dma->buffer_length[1], // Old size
|
||||
#endif
|
||||
max_buffer_length);
|
||||
|
||||
dma->buffer[1] = (uint8_t *)port_realloc(dma->buffer[1], max_buffer_length, true);
|
||||
dma->buffer_length[1] = max_buffer_length;
|
||||
|
||||
if (dma->buffer[1] == NULL) {
|
||||
|
|
@ -439,21 +429,11 @@ void audio_dma_init(audio_dma_t *dma) {
|
|||
}
|
||||
|
||||
void audio_dma_deinit(audio_dma_t *dma) {
|
||||
#if MICROPY_MALLOC_USES_ALLOCATED_SIZE
|
||||
m_free(dma->buffer[0], dma->buffer_length[0]);
|
||||
#else
|
||||
m_free(dma->buffer[0]);
|
||||
#endif
|
||||
|
||||
port_free(dma->buffer[0]);
|
||||
dma->buffer[0] = NULL;
|
||||
dma->buffer_length[0] = 0;
|
||||
|
||||
#if MICROPY_MALLOC_USES_ALLOCATED_SIZE
|
||||
m_free(dma->buffer[1], dma->buffer_length[1]);
|
||||
#else
|
||||
m_free(dma->buffer[1]);
|
||||
#endif
|
||||
|
||||
port_free(dma->buffer[1]);
|
||||
dma->buffer[1] = NULL;
|
||||
dma->buffer_length[1] = 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ typedef enum {
|
|||
|
||||
typedef struct {
|
||||
mp_obj_t sample;
|
||||
uint8_t *buffer[2];
|
||||
uint8_t *buffer[2]; // Allocated through port_malloc so they are dma-able
|
||||
size_t buffer_length[2];
|
||||
uint32_t channels_to_load_mask;
|
||||
uint32_t output_register_address;
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@
|
|||
//
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
|
|
@ -89,8 +90,7 @@ extern uint32_t _ld_itcm_size;
|
|||
extern uint32_t _ld_itcm_flash_copy;
|
||||
|
||||
static tlsf_t _heap = NULL;
|
||||
static pool_t _ram_pool = NULL;
|
||||
static pool_t _psram_pool = NULL;
|
||||
static tlsf_t _psram_heap = NULL;
|
||||
static size_t _psram_size = 0;
|
||||
|
||||
#ifdef CIRCUITPY_PSRAM_CHIP_SELECT
|
||||
|
|
@ -245,10 +245,9 @@ static void _port_heap_init(void) {
|
|||
uint32_t *heap_bottom = port_heap_get_bottom();
|
||||
uint32_t *heap_top = port_heap_get_top();
|
||||
size_t size = (heap_top - heap_bottom) * sizeof(uint32_t);
|
||||
_heap = tlsf_create_with_pool(heap_bottom, size, 64 * 1024 * 1024);
|
||||
_ram_pool = tlsf_get_pool(_heap);
|
||||
_heap = tlsf_create_with_pool(heap_bottom, size, size);
|
||||
if (_psram_size > 0) {
|
||||
_psram_pool = tlsf_add_pool(_heap, (void *)0x11000000, _psram_size);
|
||||
_psram_heap = tlsf_create_with_pool((void *)0x11000000, _psram_size, _psram_size);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -257,15 +256,31 @@ void port_heap_init(void) {
|
|||
}
|
||||
|
||||
void *port_malloc(size_t size, bool dma_capable) {
|
||||
if (!dma_capable && _psram_size > 0) {
|
||||
void *block = tlsf_malloc(_psram_heap, size);
|
||||
if (block) {
|
||||
return block;
|
||||
}
|
||||
}
|
||||
void *block = tlsf_malloc(_heap, size);
|
||||
return block;
|
||||
}
|
||||
|
||||
void port_free(void *ptr) {
|
||||
tlsf_free(_heap, ptr);
|
||||
if (((size_t)ptr) < SRAM_BASE) {
|
||||
tlsf_free(_psram_heap, ptr);
|
||||
} else {
|
||||
tlsf_free(_heap, ptr);
|
||||
}
|
||||
}
|
||||
|
||||
void *port_realloc(void *ptr, size_t size) {
|
||||
void *port_realloc(void *ptr, size_t size, bool dma_capable) {
|
||||
if (_psram_size > 0 && ((ptr != NULL && ((size_t)ptr) < SRAM_BASE) || (ptr == NULL && !dma_capable))) {
|
||||
void *block = tlsf_realloc(_psram_heap, ptr, size);
|
||||
if (block) {
|
||||
return block;
|
||||
}
|
||||
}
|
||||
return tlsf_realloc(_heap, ptr, size);
|
||||
}
|
||||
|
||||
|
|
@ -279,12 +294,13 @@ static bool max_size_walker(void *ptr, size_t size, int used, void *user) {
|
|||
|
||||
size_t port_heap_get_largest_free_size(void) {
|
||||
size_t max_size = 0;
|
||||
tlsf_walk_pool(_ram_pool, max_size_walker, &max_size);
|
||||
if (_psram_pool != NULL) {
|
||||
tlsf_walk_pool(_psram_pool, max_size_walker, &max_size);
|
||||
tlsf_walk_pool(tlsf_get_pool(_heap), max_size_walker, &max_size);
|
||||
max_size = tlsf_fit_size(_heap, max_size);
|
||||
if (_psram_heap != NULL) {
|
||||
tlsf_walk_pool(tlsf_get_pool(_psram_heap), max_size_walker, &max_size);
|
||||
max_size = tlsf_fit_size(_psram_heap, max_size);
|
||||
}
|
||||
// IDF does this. Not sure why.
|
||||
return tlsf_fit_size(_heap, max_size);
|
||||
return max_size;
|
||||
}
|
||||
|
||||
safe_mode_t port_init(void) {
|
||||
|
|
|
|||
|
|
@ -227,7 +227,7 @@ void port_free(void *ptr) {
|
|||
tlsf_free(_heap, ptr);
|
||||
}
|
||||
|
||||
void *port_realloc(void *ptr, size_t size) {
|
||||
void *port_realloc(void *ptr, size_t size, bool dma_capable) {
|
||||
return tlsf_realloc(_heap, ptr, size);
|
||||
}
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -151,7 +151,7 @@ void port_free(void *ptr) {
|
|||
tlsf_free(heap, ptr);
|
||||
}
|
||||
|
||||
void *port_realloc(void *ptr, size_t size) {
|
||||
void *port_realloc(void *ptr, size_t size, bool dma_capable) {
|
||||
return tlsf_realloc(heap, ptr, size);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@
|
|||
#include <stdlib.h>
|
||||
#define port_free free
|
||||
#define port_malloc(sz, hint) (malloc(sz))
|
||||
#define port_realloc realloc
|
||||
#define port_realloc(ptr, size, dma_capable) realloc(ptr, size)
|
||||
#else
|
||||
#include "supervisor/port_heap.h"
|
||||
#endif
|
||||
|
|
@ -48,7 +48,7 @@ static void *scratchpad_alloc(size_t sz) {
|
|||
} else {
|
||||
if (scratchpad) {
|
||||
if (sz > scratchpad_size) {
|
||||
void *tmp = port_realloc(scratchpad, sz);
|
||||
void *tmp = port_realloc(scratchpad, sz, false);
|
||||
if (!tmp) {
|
||||
port_free(scratchpad);
|
||||
scratchpad = NULL;
|
||||
|
|
|
|||
|
|
@ -24,6 +24,6 @@ void *port_malloc(size_t size, bool dma_capable);
|
|||
|
||||
void port_free(void *ptr);
|
||||
|
||||
void *port_realloc(void *ptr, size_t size);
|
||||
void *port_realloc(void *ptr, size_t size, bool dma_capable);
|
||||
|
||||
size_t port_heap_get_largest_free_size(void);
|
||||
|
|
|
|||
|
|
@ -42,7 +42,7 @@ MP_WEAK void port_free(void *ptr) {
|
|||
tlsf_free(heap, ptr);
|
||||
}
|
||||
|
||||
MP_WEAK void *port_realloc(void *ptr, size_t size) {
|
||||
MP_WEAK void *port_realloc(void *ptr, size_t size, bool dma_capable) {
|
||||
return tlsf_realloc(heap, ptr, size);
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue