56d972ad57
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@24153 a1c6a512-1295-4272-9138-f99709370657
426 lines
15 KiB
C
426 lines
15 KiB
C
/***************************************************************************
|
|
* __________ __ ___.
|
|
* 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 */
|