A modern Music Player Daemon based on Rockbox open source high quality audio player
libadwaita audio rust zig deno mpris rockbox mpd
at master 270 lines 10 kB view raw
1/*************************************************************************** 2 * __________ __ ___. 3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___ 4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / 5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < 6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ 7 * \/ \/ \/ \/ \/ 8 * $Id$ 9 * 10 * Copyright (C) 2014 Cástor Muñoz 11 * 12 * This program is free software; you can redistribute it and/or 13 * modify it under the terms of the GNU General Public License 14 * as published by the Free Software Foundation; either version 2 15 * of the License, or (at your option) any later version. 16 * 17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY 18 * KIND, either express or implied. 19 * 20 ****************************************************************************/ 21#ifndef _PL080_H 22#define _PL080_H 23 24/* 25 * ARM PrimeCell PL080 Multiple Master DMA controller 26 */ 27#include <stdint.h> 28#include <stddef.h> 29#include <stdbool.h> 30 31/* general defines */ 32#define DMAC_CH_COUNT 8 33#define DMAC_LLI_MAX_COUNT 0xfff 34#define DMAC_CH_PRIO(x) (x) 35#define DMAC_CH_BASE(dmac_ba,ch_n) ((dmac_ba) + 0x100 + ((ch_n) << 5)) 36 37/* PL080 controller registers */ 38#define DMACINTSTS(base) (*((uint32_t volatile*)((base) + 0x00))) 39#define DMACINTTCSTS(base) (*((uint32_t volatile*)((base) + 0x04))) 40#define DMACINTTCCLR(base) (*((uint32_t volatile*)((base) + 0x08))) 41#define DMACINTERRSTS(base) (*((uint32_t volatile*)((base) + 0x0c))) 42#define DMACINTERRCLR(base) (*((uint32_t volatile*)((base) + 0x10))) 43#define DMACRAWINTTCSTS(base) (*((uint32_t volatile*)((base) + 0x14))) 44#define DMACRAWINTERRSTS(base) (*((uint32_t volatile*)((base) + 0x18))) 45#define DMACENABLEDCHANS(base) (*((uint32_t volatile*)((base) + 0x1c))) 46#define DMACSOFTBREQ(base) (*((uint32_t volatile*)((base) + 0x20))) 47#define DMACSOFTSREQ(base) (*((uint32_t volatile*)((base) + 0x24))) 48#define DMACSOFTLBREQ(base) (*((uint32_t volatile*)((base) + 0x28))) 49#define DMACSOFTLSREQ(base) (*((uint32_t volatile*)((base) + 0x2c))) 50#define DMACCONFIG(base) (*((uint32_t volatile*)((base) + 0x30))) 51#define DMACSYNC(base) (*((uint32_t volatile*)((base) + 0x34))) 52 53/* PL080 controller channel registers */ 54#define DMACCxSRCADDR(base) (*((void* volatile*)((base) + 0x00))) 55#define DMACCxDESTADDR(base) (*((void* volatile*)((base) + 0x04))) 56#define DMACCxLINK(base) (*((uint32_t volatile*)((base) + 0x08))) 57#define DMACCxCONTROL(base) (*((uint32_t volatile*)((base) + 0x0c))) 58#define DMACCxCONFIG(base) (*((uint32_t volatile*)((base) + 0x10))) 59 60/* PL080 controller channel LLI */ 61#define DMACCxLLI(base) ((struct dmac_lli volatile*)(base)) 62 63/* PL080 DMA controller configuration register */ 64#define DMACCONFIG_E_POS 0 /* DMAC enable */ 65#define DMACCONFIG_E_MSK 0x1 66#define DMACCONFIG_M1_POS 1 /* AHB Master 1 endianness */ 67#define DMACCONFIG_M1_MSK 0x1 68#define DMACCONFIG_M2_POS 2 /* AHB Master 2 endianness */ 69#define DMACCONFIG_M2_MSK 0x1 70 71#define DMACCONFIG_E_BIT (1 << DMACCONFIG_E_POS) 72#define DMACCONFIG_M1_BIT (1 << DMACCCONFI_M1_POS) 73#define DMACCONFIG_M2_BIT (1 << DMACCCONFI_M2_POS) 74 75#define DMACCONFIG_M_LITTLE_ENDIAN 0 76#define DMACCONFIG_M_BIG_ENDIAN 1 77 78/* PL080 DMA controller channel LLI register */ 79#define DMACCxLINK_LM_POS 0 80#define DMACCxLINK_LM_MSK 0x1 81#define DMACCxLINK_NEXTLLI_POS 2 82#define DMACCxLINK_NEXTLLI_MSK 0x3fffffff 83 84/* PL080 channel control register */ 85#define DMACCxCONTROL_I_POS 31 /* terminal count interrupt */ 86#define DMACCxCONTROL_I_MSK 0x1 87#define DMACCxCONTROL_PROT_POS 28 /* protection bits */ 88#define DMACCxCONTROL_PROT_MSK 0x7 89#define DMACCxCONTROL_DI_POS 27 /* destination addr increment */ 90#define DMACCxCONTROL_DI_MSK 0x1 91#define DMACCxCONTROL_SI_POS 26 /* source addr increment */ 92#define DMACCxCONTROL_SI_MSK 0x1 93#define DMACCxCONTROL_D_POS 25 /* destinantion AHB master */ 94#define DMACCxCONTROL_D_MSK 0x1 95#define DMACCxCONTROL_S_POS 24 /* source AHB master */ 96#define DMACCxCONTROL_S_MSK 0x1 97#define DMACCxCONTROL_DWIDTH_POS 21 /* destinantion transfer width */ 98#define DMACCxCONTROL_DWIDTH_MSK 0x7 99#define DMACCxCONTROL_SWIDTH_POS 18 /* source transfer width */ 100#define DMACCxCONTROL_SWIDTH_MSK 0x7 101#define DMACCxCONTROL_DBSIZE_POS 15 /* destinantion burst size */ 102#define DMACCxCONTROL_DBSIZE_MSK 0x7 103#define DMACCxCONTROL_SBSIZE_POS 12 /* source burst size */ 104#define DMACCxCONTROL_SBSIZE_MSK 0x7 105#define DMACCxCONTROL_COUNT_POS 0 /* n SWIDTH size transfers */ 106#define DMACCxCONTROL_COUNT_MSK 0xfff 107 108#define DMACCxCONTROL_WIDTH_8 0 109#define DMACCxCONTROL_WIDTH_16 1 110#define DMACCxCONTROL_WIDTH_32 2 111 112#define DMACCxCONTROL_BSIZE_1 0 113#define DMACCxCONTROL_BSIZE_4 1 114#define DMACCxCONTROL_BSIZE_8 2 115#define DMACCxCONTROL_BSIZE_16 3 116#define DMACCxCONTROL_BSIZE_32 4 117#define DMACCxCONTROL_BSIZE_64 5 118#define DMACCxCONTROL_BSIZE_128 6 119#define DMACCxCONTROL_BSIZE_256 7 120 121#define DMACCxCONTROL_INC_DISABLE 0 122#define DMACCxCONTROL_INC_ENABLE 1 123 124#define DMACCxCONTROL_I_BIT (1 << DMACCxCONTROL_I_POS) 125 126/* protection bits */ 127#define DMAC_PROT_PRIV (1 << 0) 128#define DMAC_PROT_BUFF (1 << 1) 129#define DMAC_PROT_CACH (1 << 2) 130 131/* bus */ 132#define DMAC_MASTER_AHB1 0 133#define DMAC_MASTER_AHB2 1 134 135/* PL080 channel configuration register */ 136#define DMACCxCONFIG_E_POS 0 /* enable */ 137#define DMACCxCONFIG_E_MSK 0x1 138#define DMACCxCONFIG_SRCPERI_POS 1 /* source peripheral */ 139#define DMACCxCONFIG_SRCPERI_MSK 0xf 140#define DMACCxCONFIG_DESTPERI_POS 6 /* destination peripheral */ 141#define DMACCxCONFIG_DESTPERI_MSK 0xf 142#define DMACCxCONFIG_FLOWCNTRL_POS 11 /* DMA transfer type */ 143#define DMACCxCONFIG_FLOWCNTRL_MSK 0x7 144#define DMACCxCONFIG_IE_POS 14 /* interrupt error mask */ 145#define DMACCxCONFIG_IE_MSK 0x1 146#define DMACCxCONFIG_ITC_POS 15 /* interrupt terminal count mask */ 147#define DMACCxCONFIG_ITC_MSK 0x1 148#define DMACCxCONFIG_L_POS 16 /* lock */ 149#define DMACCxCONFIG_L_MSK 0x1 150#define DMACCxCONFIG_A_POS 17 /* active */ 151#define DMACCxCONFIG_A_MSK 0x1 152#define DMACCxCONFIG_H_POS 18 /* halt */ 153#define DMACCxCONFIG_H_MSK 0x1 154 155#define DMACCxCONFIG_E_BIT (1 << DMACCxCONFIG_E_POS) 156#define DMACCxCONFIG_IE_BIT (1 << DMACCxCONFIG_IE_POS) 157#define DMACCxCONFIG_ITC_BIT (1 << DMACCxCONFIG_ITC_POS) 158#define DMACCxCONFIG_L_BIT (1 << DMACCxCONFIG_L_POS) 159#define DMACCxCONFIG_A_BIT (1 << DMACCxCONFIG_A_POS) 160#define DMACCxCONFIG_H_BIT (1 << DMACCxCONFIG_H_POS) 161 162#define DMACCxCONFIG_FLOWCNTRL_MEMMEM_DMA 0 163#define DMACCxCONFIG_FLOWCNTRL_MEMPERI_DMA 1 164#define DMACCxCONFIG_FLOWCNTRL_PERIMEM_DMA 2 165#define DMACCxCONFIG_FLOWCNTRL_PERIPERI_DMA 3 166#define DMACCxCONFIG_FLOWCNTRL_PERIPERI_DSTPERI 4 167#define DMACCxCONFIG_FLOWCNTRL_MEMPERI_PERI 5 168#define DMACCxCONFIG_FLOWCNTRL_PERIMEM_PERI 6 169#define DMACCxCONFIG_FLOWCNTRL_PERIPERI_SRCPERI 7 170 171/* 172 * types 173 */ 174struct dmac_lli { 175 void* srcaddr; 176 void* dstaddr; 177 uint32_t link; 178 uint32_t control; 179} __attribute__((aligned(16))); 180 181struct dmac_tsk { 182 struct dmac_lli volatile *start_lli; 183 struct dmac_lli volatile *end_lli; 184 uint32_t size; 185 void *cb_data; 186}; 187 188/* used when src/dst peri is memory */ 189#define DMAC_PERI_NONE 0x80 190 191struct dmac_ch_cfg { 192 uint8_t srcperi; 193 uint8_t dstperi; 194 uint8_t sbsize; 195 uint8_t dbsize; 196 uint8_t swidth; 197 uint8_t dwidth; 198 uint8_t sbus; 199 uint8_t dbus; 200 uint8_t sinc; 201 uint8_t dinc; 202 uint8_t prot; 203 uint16_t lli_xfer_max_count; 204}; 205 206struct dmac_ch { 207 /** user configurable data **/ 208 struct dmac *dmac; 209 unsigned int prio; 210 void (*cb_fn)(void *cb_data); 211 /* tsk circular buffer */ 212 struct dmac_tsk *tskbuf; 213 uint32_t tskbuf_mask; 214 uint32_t queue_mode; 215 /* lli circular buffer */ 216 struct dmac_lli volatile *llibuf; 217 uint32_t llibuf_mask; 218 uint32_t llibuf_bus; 219 220 /** private driver data **/ 221 uint32_t baddr; 222 struct dmac_lli volatile *llibuf_top; 223 uint32_t tasks_queued; /* roll-over counter */ 224 uint32_t tasks_done; /* roll-over counter */ 225 uint32_t control; 226 struct dmac_ch_cfg *cfg; 227}; 228 229struct dmac { 230 /* user configurable data */ 231 const uint32_t baddr; 232 const uint8_t m1; 233 const uint8_t m2; 234 235 /* driver private data */ 236 struct dmac_ch *ch_l[DMAC_CH_COUNT]; 237 uint32_t ch_run_status; /* channel running status mask */ 238}; 239 240/* dmac_ch->queue_mode */ 241enum { 242 QUEUE_NORMAL, 243 QUEUE_LINK, 244}; 245 246/* 247 * prototypes 248 */ 249void dmac_callback(struct dmac *dmac); 250 251void dmac_open(struct dmac *dmac); 252 253void dmac_ch_init(struct dmac_ch *ch, struct dmac_ch_cfg *cfg); 254 255void dmac_ch_lock_int(struct dmac_ch *ch); 256void dmac_ch_unlock_int(struct dmac_ch *ch); 257 258void dmac_ch_queue_2d(struct dmac_ch *ch, void *srcaddr, void *dstaddr, 259 size_t size, size_t width, size_t stride, void *cb_data); 260#define dmac_ch_queue(ch, srcaddr, dstaddr, size, cb_data) \ 261 dmac_ch_queue_2d(ch, srcaddr, dstaddr, size, 0, 0, cb_data) 262 263void dmac_ch_stop(struct dmac_ch* ch); 264 265bool dmac_ch_running(struct dmac_ch *ch); 266 267void *dmac_ch_get_info(struct dmac_ch *ch, 268 size_t *bytes, size_t *t_bytes); 269 270#endif /* _PL080_H */