/*************************************************************************** * __________ __ ___. * Open \______ \ ____ ____ | | _\_ |__ _______ ___ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ * \/ \/ \/ \/ \/ * $Id$ * * Copyright (C) 2009 by Michael Sevakis * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY * KIND, either express or implied. * ****************************************************************************/ /* Largely taken from sdmaStruct.h from the Linux BSP provided by Freescale. * Copyright 2007-2008 Freescale Semiconductor, Inc. All Rights Reserved. */ /* Other information gleaned from RE-ing the BSP and SDMA code */ #ifndef SDMA_STRUCT_H #define SDMA_STRUCT_H /** * Number of channels */ #define CH_NUM 32 /** * Ownership */ #define CH_OWNSHP_EVT (1 << 0) #define CH_OWNSHP_MCU (1 << 1) #if 0 #define CH_OWNSHP_DSP (1 << 2) #endif /** * Channel contexts management */ /* Contexts for each channel begin here within SDMA core */ #define CHANNEL_CONTEXT_BASE_ADDR 0x800 /* Compute SDMA address where context for a channel is stored */ #define CHANNEL_CONTEXT_ADDR(channel) \ (CHANNEL_CONTEXT_BASE_ADDR+sizeof(struct context_data)/4*(channel)) /** * Error bit set in the CCB status field by the SDMA, * in setbd routine, in case of a transfer error */ #define DATA_ERROR (1 << 28) /* BD_RROR set on last buffer descriptor */ #define DATA_FAULT (1 << 29) /* A source or destination fault occured */ /** * Buffer descriptor status values. */ #define BD_DONE 0x01 /* Set by host, cleared when SDMA has finished with this BD */ #define BD_WRAP 0x02 /* If set in last descriptor, allows circular buffer * structure. curr_bd_ptr will be reset to base_bd_ptr */ #define BD_CONT 0x04 /* If set, more descriptors follow (multi-buffer) */ #define BD_INTR 0x08 /* Interrupt when transfer complete */ #define BD_RROR 0x10 /* Error during BD processing (set by SDMA) */ #define BD_LAST 0x20 /* Set by SDMA ap_2_bp and bp_2_ap scripts. TODO: determine function */ #define BD_EXTD 0x80 /* Use extended buffer address (indicates BD is 12 bytes instead of 8) */ /** * Buffer descriptor channel 0 commands. */ #define C0_SETCTX 0x07 /* Write context for a channel (ch# = BD command [7:3]) */ #define C0_GETCTX 0x03 /* Read context for a channel (ch# = BD command [7:3]) */ #define C0_SETDM 0x01 /* Write 32-bit words to SDMA memory */ #define C0_GETDM 0x02 /* Read 32-bit words from SDMA memory */ #define C0_SETPM 0x04 /* Write 16-bit halfwords to SDMA memory */ #define C0_GETPM 0x08 /* Read 16-bit halfwords from SDMA memory */ /* Treated the same as those above */ #define C0_ADDR 0x01 #define C0_LOAD 0x02 #define C0_DUMP 0x03 /** * Transfer sizes, encoded in the BD command field (when not a C0_ command). */ #define TRANSFER_32BIT 0x00 #define TRANSFER_8BIT 0x01 #define TRANSFER_16BIT 0x02 #define TRANSFER_24BIT 0x03 /** * Change endianness indicator in the BD command field */ #define CHANGE_ENDIANNESS 0x80 /** * Size in bytes of struct buffer_descriptor */ #define SDMA_BD_SIZE 8 #define SDMA_EXTENDED_BD_SIZE 12 #define BD_NUMBER 4 /** * Channel interrupt policy */ #define DEFAULT_POLL 0 #define CALLBACK_ISR 1 /** * Channel status */ #define UNINITIALIZED 0 #define INITIALIZED 1 /** * IoCtl particular values */ #define SET_BIT_ALL 0xFFFFFFFF #define BD_NUM_OFFSET 16 #define BD_NUM_MASK 0xFFFF0000 /** * Maximum values for IoCtl calls, used in high or middle level calls */ #define MAX_BD_NUM 256 #define MAX_BD_SIZE 65536 #define MAX_BLOCKING 2 #define MAX_SYNCH 2 #define MAX_OWNERSHIP 8 #define MAX_CH_PRIORITY 8 #define MAX_TRUST 2 #define MAX_WML 256 /** * Default values for channel descriptor - nobody owns the channel */ #define CD_DEFAULT_OWNERSHIP 7 #if 0 /* IPC not used */ /** * Data Node descriptor status values. */ #define DND_END_OF_FRAME 0x80 #define DND_END_OF_XFER 0x40 #define DND_DONE 0x20 #define DND_UNUSED 0x01 /** * IPCV2 descriptor status values. */ #define BD_IPCV2_END_OF_FRAME 0x40 #define IPCV2_MAX_NODES 50 /** * User Type Section */ /** * Command/Mode/Count of buffer descriptors */ struct mode_count_ipcv2 { unsigned long count : 16; /* size of the buffer pointed by this BD */ unsigned long reserved : 8; /* reserved */ unsigned long status : 8; /* L, E, D bits stored here */ }; /** * Data Node descriptor - IPCv2 * (differentiated between evolutions of SDMA) */ struct data_node_descriptor { struct mode_count_ipcv2 mode; /* command, status and count */ void* buffer_addr; /* address of the buffer described */ }; struct mode_count_ipcv1_v2 { unsigned long count : 16; /* size of the buffer pointed by this BD */ unsigned long status : 8; /* E,R,I,C,W,D status bits stored here */ unsigned long reserved : 7; unsigned long endianness : 1; }; /** * Buffer descriptor * (differentiated between evolutions of SDMA) */ struct buffer_descriptor_ipcv1_v2 { struct mode_count_ipcv1_v2 mode; /* command, status and count */ void *buffer_addr; /* address of the buffer described */ void *ext_buffer_addr; /* extended buffer address */ }; #endif /* No IPC */ /** * Mode/Count of data node descriptors - IPCv2 */ struct mode_count { unsigned long count : 16; /* size of the buffer pointed by this BD */ unsigned long status : 8; /* E,R,I,C,W,D status bits stored here: * SDMA r/w */ unsigned long command : 8; /* channel 0 command or transfer size */ }; /** * Buffer descriptor - describes each buffer in a DMA transfer. * (differentiated between evolutions of SDMA) */ /* (mode.status & BD_EXTD) == 0 (8 bytes) */ struct buffer_descriptor { volatile struct mode_count mode; /* command, status and count: SDMA r/w */ void *buf_addr; /* address of the buffer described: SDMA r */ }; /* (mode.status & BD_EXTD) != 0 (12 bytes) */ struct buffer_descriptor_extd { struct buffer_descriptor bd; void *buf_addr_ext; /* extended buffer address described (r6): SDMA r */ }; #if 0 /* A different one is defined for Rockbox use - this has too much. * See below. */ struct channel_control_block; struct channel_descriptor; /** * Channel Descriptor */ struct channel_descriptor { unsigned char channel_number; /* stores the channel number */ unsigned char buffer_desc_count; /* number of BD's allocated for this channel */ unsigned short buffer_per_desc_size; /* size (in bytes) of buffer descriptors' data buffers */ unsigned long blocking : 3; /* polling/ callback method selection */ unsigned long callback_synch : 1; /* (iapi) blocking / non blocking feature selection */ unsigned long ownership : 3; /* ownership of the channel (host+dedicated+event) */ unsigned long priority : 3; /* reflects the SDMA channel priority register */ unsigned long trust : 1; /* trusted buffers or kernel allocated */ unsigned long use_data_size : 1; /* (iapi) indicates if the dataSize field is meaningfull */ unsigned long data_size : 2; /* (iapi->BD) data transfer size - 8,16,24 or 32 bits*/ unsigned long force_close : 1; /* If TRUE, close channel even with BD owned by SDMA*/ unsigned long script_id : 7; /* number of the script */ unsigned long watermark_level : 10; /* (greg) Watermark level for the peripheral access */ unsigned long event_mask1; /* (greg) First Event mask */ unsigned long event_mask2; /* (greg) Second Event mask */ unsigned long shp_addr; /* (greg) Address of the peripheral or its fifo when needed */ void (* callback)(struct channel_descriptor *); /* pointer to the callback function (or NULL) */ struct channel_control_block *ccb_ptr; /* pointer to the channel control block associated to this channel */ }; #endif /* Only what we need, members sorted by size, no code-bloating bitfields */ struct channel_descriptor { unsigned int bd_count; /* number of BD's allocated for this channel */ struct channel_control_block *ccb_ptr; /* pointer to the channel control block associated to this channel */ void (* callback)(void); /* pointer to the callback function (or NULL) */ unsigned long shp_addr; /* (greg) Address of the peripheral or its fifo when needed */ unsigned short wml; /* (greg) Watermark level for the peripheral access */ unsigned char per_type; /* Peripheral type */ unsigned char tran_type; /* Transfer type */ unsigned char event_id1; /* DMA request ID */ unsigned char event_id2; /* DMA request ID 2 */ unsigned char is_setup; /* Channel setup has been done */ }; /** * Channel Status */ struct channel_status { unsigned long unused : 28; unsigned long error : 1; /* Last BD triggered an error: SDMA r/w */ unsigned long opened_init : 1; /* Channel is initialized: SDMA r/w */ unsigned long state_direction : 1; /* SDMA is reading/writing (as seen from channel owner core) */ unsigned long execute : 1; /* Channel is being processed (started) or not */ }; /** * Channel control Block * SDMA ROM code expects these are 16-bytes each in an array * (MC0PTR + 16*CCR) */ struct channel_control_block { /* current buffer descriptor processed: SDMA r/w */ struct buffer_descriptor * volatile curr_bd_ptr; /* first element of buffer descriptor array: SDMA r */ struct buffer_descriptor *base_bd_ptr; /* pointer to the channel descriptor: SDMA ignored */ struct channel_descriptor *channel_desc; /* open/close ; started/stopped ; read/write: SDMA r/w */ volatile struct channel_status status; }; /** * Channel context structure. */ /* Channel state bits on SDMA core side */ struct state_registers { /* Offset 0 */ unsigned long pc : 14; /* program counter */ unsigned long unused0 : 1; unsigned long t : 1; /* test bit: status of arithmetic & test instruction */ unsigned long rpc : 14; /* return program counter */ unsigned long unused1 : 1; unsigned long sf : 1; /* source fault while loading data */ /* Offset 1 */ unsigned long spc : 14; /* loop start program counter */ unsigned long unused2 : 1; unsigned long df : 1; /* destination falut while storing data */ unsigned long epc : 14; /* loop end program counter */ unsigned long lm : 2; /* loop mode */ }; /* Context data saved for every channel on the SDMA core. This is 32 words * long which is specified in the SDMA initialization on the AP side. The * SDMA scripts utilize the scratch space. */ struct context_data { struct state_registers channel_state; /* channel state bits */ union { unsigned long r[8]; /* general registers (r0-r7) */ struct /* script usage of said when setting contexts */ { unsigned long event_mask2; /* 08h */ unsigned long event_mask1; /* 0Ch */ unsigned long r2; /* 10h */ unsigned long r3; /* 14h */ unsigned long r4; /* 18h */ unsigned long r5; /* 1Ch */ unsigned long shp_addr; /* 20h */ unsigned long wml; /* 24h */ }; }; unsigned long mda; /* burst dma destination address register */ unsigned long msa; /* burst dma source address register */ unsigned long ms; /* burst dma status register */ unsigned long md; /* burst dma data register */ unsigned long pda; /* peripheral dma destination address register */ unsigned long psa; /* peripheral dma source address register */ unsigned long ps; /* peripheral dma status register */ unsigned long pd; /* peripheral dma data register */ unsigned long ca; /* CRC polynomial register */ unsigned long cs; /* CRC accumulator register */ unsigned long dda; /* dedicated core destination address register */ unsigned long dsa; /* dedicated core source address register */ unsigned long ds; /* dedicated core status register */ unsigned long dd; /* dedicated core data register */ unsigned long scratch[8]; /* channel context scratch RAM */ }; /** * This structure holds the necessary data for the assignment in the * dynamic channel-script association */ struct script_data { unsigned long load_address; /* start address of the script */ unsigned long wml; /* parameters for the channel descriptor */ unsigned long shp_addr; /* shared peripheral base address */ unsigned long event_mask1; /* first event mask */ unsigned long event_mask2; /* second event mask */ }; /** * This structure holds the the useful bits of the CONFIG register */ struct configs_data { unsigned long dspdma : 1; /* indicates if the DSPDMA is used */ unsigned long rtdobs : 1; /* indicates if Real-Time Debug pins are enabled */ unsigned long acr : 1; /* indicates if AHB freq /core freq = 2 or 1 */ unsigned long csm : 2; /* indicates which context switch mode is selected */ }; #endif /* SDMA_STRUCT_H */