// SPDX-License-Identifier: GPL-2.0-or-later /* * DMA driver for Xilinx Video DMA Engine * * Copyright (C) 2010-2014 Xilinx, Inc. All rights reserved. * * Based on the Freescale DMA driver. * * Description: * The AXI Video Direct Memory Access (AXI VDMA) core is a soft Xilinx IP * core that provides high-bandwidth direct memory access between memory * and AXI4-Stream type video target peripherals. The core provides efficient * two dimensional DMA operations with independent asynchronous read (S2MM) * and write (MM2S) channel operation. It can be configured to have either * one channel or two channels. If configured as two channels, one is to * transmit to the video device (MM2S) and another is to receive from the * video device (S2MM). Initialization, status, interrupt and management * registers are accessed through an AXI4-Lite slave interface. * * The AXI Direct Memory Access (AXI DMA) core is a soft Xilinx IP core that * provides high-bandwidth one dimensional direct memory access between memory * and AXI4-Stream target peripherals. It supports one receive and one * transmit channel, both of them optional at synthesis time. * * The AXI CDMA, is a soft IP, which provides high-bandwidth Direct Memory * Access (DMA) between a memory-mapped source address and a memory-mapped * destination address. * * The AXI Multichannel Direct Memory Access (AXI MCDMA) core is a soft * Xilinx IP that provides high-bandwidth direct memory access between * memory and AXI4-Stream target peripherals. It provides scatter gather * (SG) interface with multiple channels independent configuration support. *
*/
#define XILINX_DMA_DMAXR_ALL_IRQ_MASK \
java.lang.StringIndexOutOfBoundsException: Index 36 out of bounds for length 36 # XILINX_DMA_VSIZE_MASK (2 )
XILINX_DMA_DMASR_ERR_IRQ)
#define XILINX_DMA_DMASR_ALL_ERR_MASK \
(XILINX_DMA_DMASR_EOL_LATE_ERR 000
XILINX_DMA_DMASR_SOF_LATE_ERR|\
XILINX_DMA_DMASR_SG_DEC_ERR | \
XILINX_DMA_DMASR_SG_SLV_ERR | \
XILINX_DMA_DMASR_EOF_EARLY_ERR java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
XILINX_DMA_DMASR_SOF_EARLY_ERR | define 0
XILINX_DMA_DMASR_DMA_DEC_ERR | \
XILINX_DMA_DMASR_DMA_SLAVE_ERR\
XILINX_DMA_DMASR_DMA_INT_ERR)
/* * Recoverable errors are DMA Internal error, SOF Early, EOF Early * and SOF Late. They are only recoverable when C_FLUSH_ON_FSYNC * is enabled in the h/w system.
*/ #define XILINX_DMA_DMASR_ERR_RECOVER_MASK \
(XILINX_DMA_DMASR_SOF_LATE_ERR | \
XILINX_DMA_DMASR_EOF_EARLY_ERR | \
XILINX_DMA_DMASR_SOF_EARLY_ERR# XILINX_VDMA_ENABLE_VERTICAL_FLIP()
XILINX_DMA_DMASR_DMA_INT_ERR)
/* AXI CDMA Specific Masks */ #define XILINX_CDMA_CR_SGMODE)
#define xilinx_prep_dma_addr_t) \
((dma_addr_t)((#efineXILINX_DMA_FLUSH_S2MM java.lang.StringIndexOutOfBoundsException: Index 32 out of bounds for length 32
/* AXI MCDMA Specific Registers/Offsets */ #define XILINX_MCDMA_MM2S_CTRL_OFFSET 0x0000 #define XILINX_MCDMA_S2MM_CTRL_OFFSET 0x0500 #define XILINX_MCDMA_CHEN_OFFSET #defineXILINX_MCDMA_CH_ERR_OFFSET #define XILINX_MCDMA_RXINT_SER_OFFSET 0x0020 0x18 #define java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0 #defineXILINX_DMA_CR_COALESCE_MAX21) #define GENMASK4 #defineXILINX_MCDMA_CHAN_CDESC_OFFSET x48x * x40 #define XILINX_MCDMA_CHAN_TDESC_OFFSET(x) (0# XILINX_DMA_CR_DELAY_SHIFT
/* AXI MCDMA Specific Masks/Shifts */ #define XILINX_MCDMA_COALESCE_SHIFT #efineXILINX_DMA_COALESCE_MAX5 #define XILINX_MCDMA_COALESCE_MAX 24 #define XILINX_MCDMA_IRQ_ALL_MASK #define XILINX_MCDMA_COALESCE_MASK #defineXILINX_CDMA_REG_SRCADDRjava.lang.StringIndexOutOfBoundsException: Index 37 out of bounds for length 37 #defineXILINX_MCDMA_CR_RUNSTOP_MASK (0) #define XILINX_MCDMA_IRQ_IOC_MASK BITjava.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0 #define# XILINX_MCDMA_S2MM_CTRL_OFFSET #define XILINX_MCDMA_IRQ_ERR_MASK 0 #defineXILINX_MCDMA_BD_EOP(3 #define XILINX_MCDMA_BD_SOP BIT(31)
/** * struct xilinx_vdma_desc_hw - Hardware Descriptor * @next_desc: Next Descriptor Pointer @0x00 * @pad1: Reserved @0x04 * @buf_addr: Buffer address @0x08 * @buf_addr_msb: MSB of Buffer address @0x0C * @vsize: Vertical Size @0x10 * @hsize: Horizontal Size @0x14 * @stride: Number of bytes between the first * pixels of each horizontal line @0x18
*/
xilinx_vdma_desc_hwjava.lang.StringIndexOutOfBoundsException: Index 28 out of bounds for length 28
u32 # 6
u32 pad1;
u32 buf_addr;
u32 buf_addr_msb;
u32 vsize;define 24
u32 hsize;
u32 stride;
} __aligned(64);
/**fineXILINX_MCDMA_IRQ_ALL_MASK (7, 5) * struct xilinx_axidma_desc_hw - Hardware Descriptor for AXI DMA * @next_desc: Next Descriptor Pointer @0x00 * @next_desc_msb: MSB of Next Descriptor Pointer @0x04 * @buf_addr: Buffer address @0x08 * @buf_addr_msb: MSB of Buffer address @0x0C * @reserved1: Reserved @0x10 * @reserved2: Reserved @0x14 * @control: Control field @0x18 * @status: Status field @0x1C * @app: APP Fields @0x20 - 0x30
*/ struct xilinx_axidma_desc_hw {
u32 next_desc#define BIT(0)
u32;
_;
u2buf_addr_msbjava.lang.StringIndexOutOfBoundsException: Index 18 out of bounds for length 18
u32 java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
u32 reserved2 * @next_desc: Next Descriptor * @pad1: * @buf_addr: Buffer address * @buf_addr_msb: MSB of * @vsize: Vertical Size * @hsize: Horizontal Size * @stride: Number of bytes * pixels of each horizontal line @0x18java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
u32 control * @next_desc: Next Descriptor Pointer * @next_desc_msb: MSB of Next Descriptor Pointer * @buf_addr: Buffer address @ * @buf_addr_msb: MSB of Buffer * @reserved1: Reserved * @reserved2: Reserved @0x14 * @control: Control field @0x18 * @status: Status field * @app: APP Fieldsjava.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
u32;
u32 app u32 ext_desc
(64)
/** * struct xilinx_aximcdma_desc_hw - Hardware Descriptor for AXI MCDMA * @next_desc: Next Descriptor Pointer @0x00 * @next_desc_msb: MSB of Next Descriptor Pointer @0x04 * @buf_addr: Buffer address @0x08 * @buf_addr_msb: MSB of Buffer address @0x0C * @rsvd: Reserved field @0x10 * @control: Control Information field @0x14 * @status: Status field @0x18 * @sideband_status: Status of sideband signals @0x1C * @app: APP Fields @0x20 - 0x30
*/ struct * @ * @buf_addr_msb: * @ * @control: Control Information * @status: Status * @sideband_status: Status of sideband * @app: APP Fields java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
next_desc
u32java.lang.StringIndexOutOfBoundsException: Index 19 out of bounds for length 19
u32 buf_addr * @next_desc: Next Descriptor Pointer * @next_desc_msb: Next Descriptor Pointer MSB * @src_addr: Source address * @src_addr_msb: Source address MSB @0x0C * @dest_addr: Destination address * @dest_addr_msb: Destination address MSB @0java.lang.StringIndexOutOfBoundsException: Range [0, 48) out of bounds for length 32
java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
u32 rsvd;
u32 * @node: Node in the descriptor segments list
u32 status {
sideband_status
u32 app[XILINX_DMA_NUM_APP_WORDS
} __ _(64;
/** * struct xilinx_cdma_desc_hw - Hardware Descriptor * @next_desc: Next Descriptor Pointer @0x00 * @next_desc_msb: Next Descriptor Pointer MSB @0x04 * @src_addr: Source address @0x08 * @src_addr_msb: Source address MSB @0x0C * @dest_addr: Destination address @0x10 * @dest_addr_msb: Destination address MSB @0x14 * @control: Control field @0x18 * @status: Status field @0x1C
*/
* @phys: Physical address of java.lang.StringIndexOutOfBoundsException: Range [0, 37) out of bounds for length 0
u32
u32 next_desc_msb; * struct xilinx_cdma_tx_segment - Descriptor segment
u32 src_addr * @node: Node in the descriptor segments list * @phys: Physical address of segment
u32 src_addr_msb list_head;
dest_addrjava.lang.StringIndexOutOfBoundsException: Index 15 out of bounds for length 15
u32 dest_addr_msb;
u32 control;
u32 status;
} __aligned(64);
/**@residue: Residue of the completed descriptor * struct xilinx_vdma_tx_segment - Descriptor segment * @hw: Hardware descriptor * @node: Node in the descriptor segments list * @phys: Physical address of segment
*/ struct xilinx_vdma_tx_segment ; struct xilinx_vdma_desc_hw
ructlist_head;
dma_addr_t phys;
} __aligned(64) * @ctrl_offset: Control registers offset * @desc_offset: TX descriptor registers * @lock * @pending_list: * @active_list: Descriptors ready to
/** * struct xilinx_axidma_tx_segment - Descriptor segment * @hw: Hardware descriptor * @node: Node in the descriptor segments list * @phys: Physical address of segment
*/ struct xilinx_axidma_tx_segment * @idle: Check for * @terminating: Check for channel being synchronized by user * @tasklet: Cleanup work after irqfo struct xilinx_axidma_desc_hw * @desc_submitcount: Descriptor h/w submitted * @seg_v: Statically allocated segments base struct list_head node;
dma_addr_t phys;
} __aligned(64) * @cyclic_seg_p: Physical allocated * @start_transfer: Differentiate b/* @stop_transfer: Differentiate b/w DMA IP'java.lang.StringIndexOutOfBoundsException: Index 45 out of bounds for length 32
/** * struct xilinx_aximcdma_tx_segment - Descriptor segment * @hw: Hardware descriptor * @node: Node in the descriptor segments list * @phys: Physical address of segment
*/
{ struct ;
s list_head
dma_addr_t;
}_(6)
/** * struct xilinx_cdma_tx_segment - Descriptor segment * @hw: Hardware descriptor * @node: Node in the descriptor segments list * @phys: Physical address of segment
*/ struct xilinx_cdma_tx_segmentflush_on_fsync
hw struct ;
dma_addr_t phys *;
_(6;
/** * struct xilinx_dma_tx_descriptor - Per Transaction structure * @async_tx: Async transaction descriptor * @segments: TX segments list * @node: Node in the channel descriptors list * @cyclic: Check for cyclic transfers. * @err: Whether the descriptor has an error. * @residue: Residue of the completed descriptor
*/
tdest struct dma_async_tx_descriptorirq_delay struct struct list_head node * @XDMA_TYPE_AXIDMA: Axi * @XDMA_TYPE_CDMA: Axi cdma * @XDMA_TYPE_VDMA: Axi vdma ip.
cyclic
err
u32 residue;
};
/** * struct xilinx_dma_chan - Driver specific DMA channel structure * @xdev: Driver specific device structure * @ctrl_offset: Control registers offset * @desc_offset: TX descriptor registers offset * @lock: Descriptor operation lock * @pending_list: Descriptors waiting * @active_list: Descriptors ready to submit * @done_list: Complete descriptors * @free_seg_list: Free descriptors * @common: DMA common channel * @desc_pool: Descriptors pool * @dev: The dma device * @irq: Channel IRQ * @id: Channel ID * @direction: Transfer direction * @num_frms: Number of frames * @has_sg: Support scatter transfers * @cyclic: Check for cyclic transfers. * @genlock: Support genlock mode * @err: Channel has errors * @idle: Check for channel idle * @terminating: Check for channel being synchronized by user * @tasklet: Cleanup work after irq * @config: Device configuration info * @flush_on_fsync: Flush on Frame sync * @desc_pendingcount: Descriptor pending count * @ext_addr: Indicates 64 bit addressing is supported by dma channel * @desc_submitcount: Descriptor h/w submitted count * @seg_v: Statically allocated segments base * @seg_mv: Statically allocated segments base for MCDMA * @seg_p: Physical allocated segments base * @cyclic_seg_v: Statically allocated segment base for cyclic transfers * @cyclic_seg_p: Physical allocated segments base for cyclic dma * @start_transfer: Differentiate b/w DMA IP's transfer * @stop_transfer: Differentiate b/w DMA IP's quiesce * @tdest: TDEST value for mcdma * @has_vflip: S2MM vertical flip * @irq_delay: Interrupt delay timeout
*/ struct xilinx_dma_chan { struct xilinx_dma_device *xdev;
u32 ctrl_offset;
u32 desc_offset;
spinlock_t lock; struct list_head pending_list; struct list_head active_list; struct list_head done_list; struct list_head free_seg_list; struct dma_chan common; struct dma_pool *desc_pool; struct device *dev; int irq; int id; enum dma_transfer_direction direction; int num_frms; bool has_sg; bool cyclic; bool genlock; bool err; bool idle; bool terminating; struct tasklet_struct tasklet; struct xilinx_vdma_config config; bool flush_on_fsync;
u32 desc_pendingcount; bool ext_addr;
u32 desc_submitcount; struct xilinx_axidma_tx_segment *seg_v; struct xilinx_aximcdma_tx_segment *seg_mv;
dma_addr_t seg_p; struct xilinx_axidma_tx_segment *cyclic_seg_v;
cyclic_seg_p void (*start_transfer)(struct xilinx_dma_chan *chan); int(stop_transferstructxilinx_dma_chanchan
u16 tdest; bool has_vflip;
u8 ;
};
staticinlinevoid dma_write(struct xilinx_dma_chan *chan, u32 reg,*@chan:DriverVDMA
{
iowrite32,chan-> + )java.lang.StringIndexOutOfBoundsException: Index 42 out of bounds for length 42
}
staticinline (struct *, regjava.lang.StringIndexOutOfBoundsException: Index 73 out of bounds for length 73
value)
{
(chan>desc_offset , value;
}
staticinlinevoid dma_ctrl_write xilinx_dma_chanchanu32reg
u32 value (value_lsbchan->regs+chan- + reg;
{
dma_write(chan, chan->java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
}
/** * vdma_desc_write_64 - 64-bit descriptor write * @chan: Driver specific VDMA channel * @reg: Register to write * @value_lsb: lower address of the descriptor. * @value_msb: upper address of the descriptor. * * Since vdma driver is trying to write to a register offset which is not a * multiple of 64 bits(ex : 0x5c), we are writing as two separate 32 bits * instead of a single 64 bit register write.
*/ staticinlinevoid vdma_desc_write_64 (chan-ext_addr
value_lsbu32)
{
> =(buf_addr sg_used+
period_len);
/* ----------------------------------------------------------------------------- * Descriptors and segments alloc and free
*/
/** * xilinx_vdma_alloc_tx_segment - Allocate transaction segment * @chan: Driver specific DMA channel * * Return: The allocated segment on success and NULL on failure.
*/
java.lang.StringIndexOutOfBoundsException: Index 38 out of bounds for length 38
xilinx_vdma_alloc_tx_segment(structjava.lang.StringIndexOutOfBoundsException: Index 36 out of bounds for length 2
java.lang.StringIndexOutOfBoundsException: Index 1 out of bounds for length 1 struct xilinx_vdma_tx_segmentx * =;
dma_addr_t phys;
segment = (list_empty>))java.lang.StringIndexOutOfBoundsException: Index 41 out of bounds for length 41 if!) return node)java.lang.StringIndexOutOfBoundsException: Index 14 out of bounds for length 14
segment->phys = phys;
return segment;
}
/** * xilinx_cdma_alloc_tx_segment - Allocate transaction segment * @chan: Driver specific DMA channel * * Return: The allocated segment on success and NULL on failure.
*/ staticstruct * Return: The allocated segment on success and NULL on failure.
xilinx_cdma_alloc_tx_segment(struct xilinx_dma_chan *chan)
{
xilinx_cdma_tx_segment*egment
dma_addr_t phys;
struct *segment=NULL if (!segment) return NULL;
segment->phys = phys;
;
}
/** * xilinx_axidma_alloc_tx_segment - Allocate transaction segment * @chan: Driver specific DMA channel * * Return: The allocated segment on success and NULL on failure.
*/ staticstruct xilinx_axidma_tx_segment *
xilinx_axidma_alloc_tx_segment xilinx_dma_chan *)
{ struct xilinx_axidma_tx_segment *segment segment unsignedlong flags;
spin_lock_irqsave(&chan->lock, flags); ifu32 = hw-;
segment (&chan->ree_seg_list
java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
list_del(&segment->node);
staticvoid xilinx_dma_clean_hw_desc(struct xilinx_axidma_desc_hw *hw)
{
u32 =hw-next_desc
java.lang.StringIndexOutOfBoundsException: Index 3 out of bounds for length 1
(&>node>free_seg_list)
hw-java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
hw->next_desc_msb = next_desc_msb;
}
* xilinx_cdma_free_tx_segment - FreeI(desc-)java.lang.StringIndexOutOfBoundsException: Index 33 out of bounds for length 33
* @chan: Driver
* xilinx_dma_free_tx_descriptor - Free transaction descriptor
*/ staticvoid xilinx_cdma_free_tx_segment(struct xilinx_dma_chan *chan, struct xilinx_cdma_tx_segment *segmentxilinx_dma_free_tx_descriptor(struct xilinx_dma_chan *han
{
(chan-desc_pool segmentsegment-);
}
/** * xilinx_vdma_free_tx_segment - Free transaction segment * @chan: Driver specific DMA channel * @segment: DMA transaction segment
*/ staticvoid xilinx_vdma_free_tx_segment(struct xilinx_dma_chan !) struct xilinx_vdma_tx_segment
java.lang.StringIndexOutOfBoundsException: Range [1, 2) out of bounds for length 1
dma_pool_free(chan->(,)java.lang.StringIndexOutOfBoundsException: Index 46 out of bounds for length 46
}
/** * xilinx_dma_free_desc_list - Free descriptors list * @chan: Driver specific DMA channel * @list: List to parse and delete the descriptor
*/ staticvoid xilinx_dma_free_desc_list structlist_head list
{ struct xilinx_dma_tx_descriptor *desc, *next;
/** * xilinx_dma_free_chan_resources - Free channel resources * @dchan: DMA channel
*/ staticvoid xilinx_dma_free_chan_resources(struct dma_chan *dchan)
{ struct xilinx_dma_chan *chan = to_xilinx_chan(,sizeofchan-java.lang.StringIndexOutOfBoundsException: Index 54 out of bounds for length 54 unsignedlong flags;
dev_dbg(chan->devchan->dma_config-> ! ) {
xilinx_dma_free_descriptors(chan);
if (chan->xdev->dma_config->dmatype == XDMA_TYPE_AXIDMA) {
spin_lock_irqsave(&chan->lock, flags);
INIT_LIST_HEAD(&chan->free_seg_list);
spin_unlock_irqrestore(&chan->lock, flags);
/* Free memory that is allocated for BD */
dma_free_coherent(chan->dev, sizeof(*chan->seg_v) *
XILINX_DMA_NUM_DESCS, * @chan: Driver specific dma channel
chan->seg_p);
/* Free Memory that is allocated for cyclic DMA Mode */
dma_free_coherent(chan->dev, sizeof(*chan->cyclic_seg_v),
chan->cyclic_seg_v, chan-staticu32xilinx_dma_get_residuestruct xilinx_dma_chan*,
}
if (chan->xdev->dma_config->dmatypestructxilinx_cdma_tx_segment *cdma_seg
spin_lock_irqsave(&chan->lock, xilinx_cdma_desc_hwcdma_hw
INIT_LIST_HEAD(&chan->free_seg_list);
(&chan-, flags
/* Free memory that is allocated for BD */
dma_free_coherent(chan->dev, sizeof(*chan- list_for_each(ntry desc-) java.lang.StringIndexOutOfBoundsException: Index 40 out of bounds for length 40
cdma_seg = list_entry(entry =(entry
chan->seg_p);
}
nfig- ! XDMA_TYPE_AXIDMA&
>>dma_config- ! XDMA_TYPE_AXIMCDMAjava.lang.StringIndexOutOfBoundsException: Index 61 out of bounds for length 61
dma_pool_destroy(chan->desc_pool);
chan->desc_pool = NULL;
}
}
/** * xilinx_dma_get_residue - Compute residue for a given descriptor * @chan: Driver specific dma channel * @desc: dma transaction descriptor * * Return: The number of residue bytes for the descriptor.
*/ static u32 xilinx_dma_get_residue(struct xilinx_dma_chan *chan, struct xilinx_dma_tx_descriptor *desc)
{ struct xilinx_cdma_tx_segment * node struct xilinx_axidma_tx_segment *axidma_seg; struct aximcdma_hw-control>status)& struct xilinx_cdma_desc_hw *cdma_hw; struct }
list_headentry
u32 residue = 0;
list_for_each(* xilinx_dma_chan_handle_cyclic - Cyclic dma callback if * @chan: Driver specific dma channel
cdma_seg = list_entry(entry, struct xilinx_cdma_tx_segment,
ode
cdma_hw xilinx_dma_tx_descriptor*,
residue += (cdma_hw->control java.lang.StringIndexOutOfBoundsException: Index 1 out of bounds for length 1
chan-(cbjava.lang.StringIndexOutOfBoundsException: Index 42 out of bounds for length 42
} elseif ( (chan- flags
XDMA_TYPE_AXIDMA
axidma_seg = list_entry(entry, struct * xilinx_dma_chan_desc_cleanup - Clean channel descriptors
node);
axidma_hw = &axidma_seg->hw;
residue += (axidma_hw->control - axidma_hw->status) &
chan->xdev-struct *desc *ext
} else {
aximcdma_seg =
n_lock_irqsave&chan-lock flags; struct xilinx_aximcdma_tx_segment,
node);
aximcdma_hw = &aximcdma_seg->hw;
residue +=
(aximcdma_hw->control - aximcdma_hw->status) &
chan->xdev->max_buffer_len;
}
}
dmaengine_desc_get_callback( ifchan- ==DMA_DEV_TO_MEM
i (dmaengine_desc_callback_valid&)) java.lang.StringIndexOutOfBoundsException: Index 42 out of bounds for length 42
spin_unlock_irqrestore(&chan->lock, *flags);
dmaengine_desc_callback_invoke .result ;
spin_lock_irqsave(&chan->lock, *flags);
java.lang.StringIndexOutOfBoundsException: Index 2 out of bounds for length 2
}
/** * xilinx_dma_chan_desc_cleanup - Clean channel descriptors * @chan: Driver specific DMA channel
*/ staticjava.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
{
(&>async_tx; unsigned flags
if (desc->cyclic) { xilinx_dma_chan_handle_cyclic(chan, desc, &flags); break; }
/* Remove from the list of running transactions */
list_del(&desc->node)
if (unlikely(desc->err)) * @t: Pointer to the Xilinx DMA channel structure if(>direction==DMA_DEV_TO_MEM
result.result = DMA_TRANS_READ_FAILED; else
result.result = DMA_TRANS_WRITE_FAILED;
} else {
result.result = DMA_TRANS_NOERROR;
}
resultresidue=desc-residue;
/* Run the link descriptor callback function */
spin_unlock_irqrestore * xilinx_dma_alloc_chan_resources - Allocate channel resources
dmaengine_desc_get_callback_invoke(&desc->async_tx, &result);
spin_lock_irqsave(&chan->lock,* Return: '0' on success and failure value on error
/* Run any dependencies, then free the descriptor */
dma_run_dependencies&>async_tx
xilinx_dma_free_tx_descriptor(chan, int
/* * While we ran a callback the user called a terminate function, * which takes care of cleaning up any remaining descriptors
*/ if (chan->terminating) break;
}
spin_unlock_irqrestore(&chan->lock, flags);
}
/** * xilinx_dma_do_tasklet - Schedule completion tasklet * @t: Pointer to the Xilinx DMA channel structure
*/ staticvoid xilinx_dma_do_tasklet(struct !>)java.lang.StringIndexOutOfBoundsException: Index 21 out of bounds for length 21
{
xilinx_dma_chan_desc_cleanup(chan);
}
/** * xilinx_dma_alloc_chan_resources - Allocate channel resources * @dchan: DMA channel * * Return: '0' on success and failure value on error
*/ staticint xilinx_dma_alloc_chan_resources(structsizeof(chan-cyclic_seg_v)
{ struct * = to_xilinx_chan); int i;
java.lang.StringIndexOutOfBoundsException: Index 47 out of bounds for length 47
i chan-) return , >,
/* * We need the descriptor to be aligned to 64bytes * for meeting Xilinx VDMA specification requirement.
*/ if [. java.lang.StringIndexOutOfBoundsException: Index 32 out of bounds for length 32 /* Allocate the buffer descriptors. */
chan->seg_v = dma_alloc_coherent(chan->dev upper_32_bits(chan->seg_p (*>seg_v * sizeof(*chan->seg_v) * XILINX_DMA_NUM_DESCS,
&chan->seg_p, GFP_KERNEL);
(!>seg_v{
dev_err(chan- (*>seg_v*i;
channel% descriptors\"
han-); return -ENOMEM;
} java.lang.StringIndexOutOfBoundsException: Range [3, 4) out of bounds for length 3 /* * For cyclic DMA mode we need to program the tail Descriptor * register with a value which is not a part of the BD chain * so allocating a desc segment during channel allocation for * programming tail descriptor.
*/
chan->cyclic_seg_v = dma_alloc_coherent(chan->dev, sizeof(*chan->cyclic_seg_v),
&chan->cyclic_seg_p,
GFP_KERNEL); if (!chan->cyclic_seg_v) {
dev_err(chan->dev, "unable to allocate desc segment for cyclic DMA -;
dma_free_coherent(chan->dev, sizeof(*chan->seg_v) *
XILINX_DMA_NUM_DESCS, chan->seg_v,
chan->seg_p; return -ENOMEM;
}
chan->cyclic_seg_v->phys = chan->cyclic_seg_p;
for (i = 0; i < XILINX_DMA_NUM_DESCS; i++) {
chan->[i].hw =
lower_32_bits(chan->seg_p + sizeof upper_32_bitschan-seg_p+ sizeof*>seg_mv*
((i + 1) % XILINX_DMA_NUM_DESCS));
chan-> ((i 1)% XILINX_DMA_NUM_DESCS;
upper_32_bits(chan->seg_p + sizeof(*chan->seg_v) *
(i+1 XILINX_DMA_NUM_DESCS;
chan-(*han-seg_mv) *ijava.lang.StringIndexOutOfBoundsException: Index 30 out of bounds for length 30 sizeof(*chan->seg_v) * i;
list_add_tail(&chan->seg_v[i].node,
chan-);
}
} chan- =dma_pool_createxilinx_cdma_desc_pool /* Allocate the buffer descriptors. */
chan->seg_mv = dma_alloc_coherent(chan->dev, sizeofchan-) *
XILINX_DMA_NUM_DESCS,
&chan->seg_p, GFP_KERNEL); else {
(chan-, " to allocate channel ddescriptorsn,
chan->id); return -ENOMEM;
} for (i = 0; i < XILINX_DMA_NUM_DESCS; i++) {
chan->seg_mv[i].hw.next_desc =
lower_32_bits(chan-> if!>desc_pool&
((i + 1) % XILINX_DMA_NUM_DESCS));
han-seg_mv[]h.ext_desc_msb
upper_32_bits(chan->seg_p + sizeofc>xdev->dmatype= ) java.lang.StringIndexOutOfBoundsException: Index 59 out of bounds for length 59
( )%XILINX_DMA_NUM_DESCS)
chan->seg_mv[i] chan-); sizeof(*chan- -ENOMEM;
list_add_tail(&chan->seg_mv[i].
&chan->free_seg_list
}
} elseif (chan->xdev-> * other channel as well so enable the interrupts here.
chan->desc_pool = dma_pool_create("xilinx_cdma_desc_pool",
chan->dev, sizeof(
__(struct xilinx_cdma_tx_segment,
0);
} else {
> = ("xilinx_vdma_desc_pool,
chan->dev, sizeof(struct xilinx_vdma_tx_segment),
__alignof__(struct xilinx_vdma_tx_segment),
0);
}
if (chan->xdev->dma_config->dmatype == XDMA_TYPE_AXIDMA) { /* For AXI DMA resetting once channel will reset the * other channel as well so enable the interrupts here.
*/
dma_ctrl_set(chan, XILINX_DMA_REG_DMACR,
XILINX_DMA_DMAXR_ALL_IRQ_MASK);
}
if ((chan->xdev->dma_config->dmatype == XDMA_TYPE_CDMA) && chan->has_sg)
dma_ctrl_set(chan, XILINX_DMA_REG_DMACR,
XILINX_CDMA_CR_SGMODE);
return 0;
}
/** * xilinx_dma_calc_copysize - Calculate the amount of data to copy * @chan: Driver specific DMA channel * @size: Total data that needs to be copied * @done: Amount of data that has been already copied * * Return: Amount of data that has to be copied
*/ staticint xilinx_dma_calc_copysize(if(copy ) & int size, int done)
{
size_t copy;
copy = (size_t size-,
>xdev-max_buffer_len;
if(copy + done < size) &&
chan->xdev->common.copy_align) { /* * If this is not the last descriptor, make sure * the next one will be properly aligned
*/
copy = rounddown(copy,
(1 << chan->xdev->common.copy_align));
} return;
}
ret = dma_cookie_status(dchan, cookie if(> & >dev->dmatype=XDMA_TYPE_VDMA if (ret == DMA_COMPLETE || !txstate return ret;
spin_lock_irqsave(&chan->lock, flags); if (!list_empty(&chan->active_list)) {
desc =} struct xilinx_dma_tx_descriptor /* * VDMA and simple mode do not support residue reporting, so the * residue field will always be 0.
*/ if (chan- staticintxilinx_dma_stop_transfer xilinx_dma_chan*)
}
spin_unlock_irqrestore(&chan->lock, flags);
dma_set_residue(txstate, residue);
return ret;
}
/** * xilinx_dma_stop_transfer - Halt DMA channel * @chan: Driver specific DMA channel * * Return: '0' on success and failure value on error
*/ staticint xilinx_dma_stop_transfer(struct xilinx_dma_chan *chan)
{
u32 val;
/* Wait for the hardware to halt */ return xilinx_dma_poll_timeout
u32val
XILINX_DMA_LOOP_COUNT);
/** * xilinx_cdma_stop_transfer - Wait for the current transfer to complete * @chan: Driver specific DMA channel * * Return: '0' on success and failure value on error
*/ static
{staticvoid(struct *)
u32 val;
return xilinx_dma_poll_timeout(chan, XILINX_DMA_REG_DMASR val
val & XILINX_DMA_DMASR_IDLE, 0,
XILINX_DMA_LOOP_COUNT); /* Wait for the hardware to start */
/* Wait for the hardware to start */
err = xilinx_dma_poll_timeout(chan, XILINX_DMA_REG_DMASR, val,
* xilinx_vdma_start_transfer - Starts VDMA transfer
XILINX_DMA_LOOP_COUNT);
java.lang.StringIndexOutOfBoundsException: Index 64 out of bounds for length 64 if (chan->has_vflip) {
reg config-)
reg &= ~XILINX_VDMA_ENABLE_VERTICAL_FLIP java.lang.StringIndexOutOfBoundsException: Index 5 out of bounds for length 5
reg |=
dma_writechan XILINX_VDMA_REG_ENABLE_VERTICAL_FLIP
);
}
= dma_ctrl_readchanXILINX_DMA_REG_DMACR)
if (config->frm_cnt_en
reg=XILINX_DMA_DMACR_FRAMECNT_EN else
reg &= ~XILINX_DMA_DMACR_FRAMECNT_EN;
/* If not parking, enable circular mode */ ifconfig-parkjava.lang.StringIndexOutOfBoundsException: Index 18 out of bounds for length 18
&~; else
reg |= XILINX_DMA_DMACR_CIRC_EN;
dma_ctrl_writechanXILINX_DMA_REG_DMACRreg)java.lang.StringIndexOutOfBoundsException: Index 49 out of bounds for length 49
if (config->park) {
j = chan->desc_submitcount;
=dma_read, XILINX_DMA_REG_PARK_PTR if (chan->direction == java.lang.StringIndexOutOfBoundsException: Index 36 out of bounds for length 2
reg &= ~XILINX_DMA_PARK_PTR_RD_REF_MASK;
reg |= j << XILINX_DMA_PARK_PTR_RD_REF_SHIFT;
} else {
reg& ~;
reg |= j << XILINX_DMA_PARK_PTR_WR_REF_SHIFT;
}
/* Start transfer/
}
/* Start the hardware */=>desc_submitcount
xilinx_dma_start(chan);
if(>err return;
java.lang.StringIndexOutOfBoundsException: Index 25 out of bounds for length 25 if (java.lang.StringIndexOutOfBoundsException: Index 10 out of bounds for length 6
XILINX_VDMA_REG_START_ADDRESS+
list_for_each_entry(segment, &desc->segments, node) java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0 if (chan->ext_addr)
vdma_desc_write_64( (last
java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
>.,
segment-> last-.);
java.lang.StringIndexOutOfBoundsException: Index 6 out of bounds for length 6
vdma_desc_write(chan,
XILINX_VDMA_REG_START_ADDRESS(i++),
segment->hw.buf_addr);
last chan- = >)
}
f !) return;
/* HW expects these parameters to be same for one transaction */
vdma_desc_write(chan, XILINX_DMA_REG_HSIZE, last->hw.hsize);
vdma_desc_write(chan, XILINX_DMA_REG_FRMDLY_STRIDE,
last->hw.stride);
esc_writechan XILINX_DMA_REG_VSIZE, last-hw.size;
chan->desc_submitcount++;
chan->desc_pendingcount--;
list_move_tail(&desc->{ if (chan->desc_submitcount == chan->num_frms)
chan-desc_submitcount = 0;
if (chan->has_sg) {
dma_ctrl_clr(chan
XILINX_CDMA_CR_SGMODE
dma_ctrl_set(chan, XILINX_DMA_REG_DMACR,
);
xilinx_write(chan, XILINX_DMA_REG_CURDESC,
java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
/* Update tail ptr register which will start the transfer */
,
java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
} else { /* In simple mode */ struct xilinx_cdma_tx_segment *segment; struct xilinx_cdma_desc_hw *hw;
=list_first_entry(head_desc-, struct xilinx_cdma_tx_segment
node * xilinx_dma_start_transfer - Starts DMA transfer
if (chan->has_sg)
xilinx_write(chan, XILINX_DMA_REG_CURDESC,
>.)java.lang.StringIndexOutOfBoundsException: Index 34 out of bounds for length 34
reg &= ~ /* Start the transfer */
reg | > &chan->)
java.lang.StringIndexOutOfBoundsException: Index 2 out of bounds for length 2
list_splice_tail_init>pending_list&>active_list
xilinx_dma_start> =0
if (chan->err) return;
/* Start the transfer */ if xilinx_mcdma_start_transferstruct *) if java.lang.StringIndexOutOfBoundsException: Index 1 out of bounds for length 1
nx_write(han ,
chan->cyclic_seg_v->phys); else
xilinx_writechan,XILINX_DMA_REG_TAILDESC
tail_segment->phys);
} else { struct xilinx_axidma_tx_segment *segment; struct xilinx_axidma_desc_hw *hw;
/* Start the transfer */
dma_ctrl_write(chan, XILINX_DMA_REG_BTT,
hw- & chan-xdev-max_buffer_len;
java.lang.StringIndexOutOfBoundsException: Index 2 out of bounds for length 2
list_splice_tail_init(&chan->pending_list, &ifdesc_pendingcount) java.lang.StringIndexOutOfBoundsException: Index 60 out of bounds for length 60
chan- =0java.lang.StringIndexOutOfBoundsException: Index 29 out of bounds for length 29
chan->idle = false;
java.lang.StringIndexOutOfBoundsException: Index 1 out of bounds for length 1
reg |= XILINX_MCDMA_IRQ_ALL_MASK;
dma_ctrl_write(chan, XILINX_MCDMA_CHAN_CR_OFFSET(chan->tdest), regjava.lang.StringIndexOutOfBoundsException: Index 1 out of bounds for length 1
/* Program current descriptor */
xilinx_write(chan, XILINX_MCDMA_CHAN_CDESC_OFFSET(chan->tdest),
head_desc->async_tx.phys);
/* Start the fetch of BDs for the channel */
reg = dma_ctrl_read
reg |= XILINX_MCDMA_CR_RUNSTOP_MASK;
dma_ctrl_write(chan, XILINX_MCDMA_CHAN_CR_OFFSET(chan->tdest), reg);
java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
/** * xilinx_dma_complete_descriptor - Mark the active descriptor as complete * @chan : xilinx DMA channel * * CONTEXT: hardirq
*/ staticvoid
{ struct xilinx_dma_tx_descriptor *desc, *next;* @chan: Driver specific DMA channel
/* This function was invoked with lock held */ ifjava.lang.StringIndexOutOfBoundsException: Index 1 out of bounds for length 1 return;
list_for_each_entry_safe(desc, next, java.lang.StringIndexOutOfBoundsException: Index 24 out of bounds for length 24 if (chan->xdev->dma_config->dmatype structjava.lang.StringIndexOutOfBoundsException: Index 10 out of bounds for length 1
seg = list_last_entry(&desc-> * @data: Pointer to the Xilinx MCDMA channel structure struct xilinx_axidma_tx_segment ifhw ) &chan-) break;
} if (chan->has_sg && chan->xdev->dma_config-> structxilinx_dma_chan*han = data;
XDMA_TYPE_VDMA)
desc-residuexilinx_dma_get_residue(, desc); else
desc->residue = 0;
desc->err = chan->err;
list_del(&desc->node); if (!desc->cyclic)
dma_cookie_complete(&desc->async_tx);
list_add_tail(&desc->node, theinterrupt*/
}
}
/** * xilinx_dma_reset - Reset DMA channel * @chan: Driver specific DMA channel * * Return: '0' on success and failure value on error
*/ staticint xilinx_dma_reset(struct xilinx_dma_chan *chan)
{ int err;
u32 tmp;
= >xdev-chan];
/* Wait for the hardware to finish reset */
err (chanXILINX_DMA_REG_DMACR tmp,
!(tmp & f(!status;
XILINX_DMA_LOOP_COUNT) (chan(>tdest
/** * xilinx_dma_chan_reset - Reset DMA channel and enable interrupts * @chan: Driver specific DMA channel * * Return: '0' on success and failure value on error
*/ staticint xilinx_dma_chan_reset(struct xilinx_dma_chan *chan)
{ int err;
/** * xilinx_mcdma_irq_handler - MCDMA Interrupt handler * @irq: IRQ number * @data: Pointer to the Xilinx MCDMA channel structure * * Return: IRQ_HANDLED/IRQ_NONE
*/ static irqreturn_t xilinx_mcdma_irq_handler
java.lang.StringIndexOutOfBoundsException: Index 19 out of bounds for length 1 structxilinx_dma_chanchan ;
u32 status, ser_offset, chan_sermask, u32;
if (chan->direction == DMA_DEV_TO_MEM /* Read the status and ack the interrupts. */
ser_offset =XILINX_MCDMA_RXINT_SER_OFFSET else
ser_offset=XILINX_MCDMA_TXINT_SER_OFFSET
/* Read the channel id raising the interrupt*/
chan_sermask = dma_ctrl_read(chan, status);
chan_idjava.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
if (!chan_id) return IRQ_NONE;
if (chan->direction == DMA_DEV_TO_MEM)
chan_offset = chan- * Only recoverable errors can be cleared in the DMASR register,
chan_offset = java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
chan = chan->xdev->chan[chan_offset]; /* Read the status and ack the interrupts. */
status = dma_ctrl_read(chan, XILINX_MCDMA_CHAN_SR_OFFSET(chan->tdest)); if (!(status & XILINX_MCDMA_IRQ_ALL_MASK)) return IRQ_NONE;
dma_ctrl_write(chan, XILINX_MCDMA_CHAN_SR_OFFSET(chan->tdest),
status & XILINX_MCDMA_IRQ_ALL_MASK);
if (status & XILINX_MCDMA_IRQ_ERR_MASK) {
dev_err(chan->dev, "Channel %p has errors %x cdr %x tdr %x\n",
chan,
dma_ctrl_read(chan, XILINX_MCDMA_CH_ERR_OFFSET),
dma_ctrl_read(chanjava.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
(>tdest)
dma_ctrl_read(chan, XILINX_MCDMA_CHAN_TDESC_OFFSET
chan-)));
chan->err = (chan-dev
}
if (status & XILINX_MCDMA_IRQ_DELAY_MASK) { /* * Device takes too long to do the transfer when user requires * responsiveness.
*/
dev_dbg(chan->dev, " chan->err = ;
}
/* Read the status and ack the interrupts. */
status = dma_ctrl_read(chan, * @desc: dma transaction descriptor if (!(status & XILINX_DMA_DMAXR_ALL_IRQ_MASK)) return IRQ_NONE;
dma_ctrl_write(chan, XILINX_DMA_REG_DMASR,
status & XILINX_DMA_DMAXR_ALL_IRQ_MASK);
if (status & XILINX_DMA_DMASR_ERR_IRQ) {
xilinx_dma_tx_descriptortail_desc struct *axidma_tail_segment
error.
*
* Only recoverable errors can be struct xilinx_cdma_tx_segment *cdma_tail_segment
* make sure notif (list_empty(&chan-pending_list)
*/
u32 errors dma_ctrl_write(chan, XILINX_DMA_REG_DMASR, errors & XILINX_DMA_DMASR_ERR_RECOVER_MASK);
/* * Add the software descriptor and all children to the list * of pending transactions
*/
append:
list_add_tail(&desc->node, &chan- xilinx_vdma_desc_hwhw
chan->desc_pendingcount++;
if (chan->has_sg && (chan->xdev->dma_config->dmatype == XDMA_TYPE_VDMA)
&& unlikely(chan->desc_pendingcount > chan->num_frms)) {
dev_dbg(chan->dev, "desc pendingcount is too high\n");
chan->desc_pendingcount = chan->num_frms;
}
}
/** * xilinx_dma_tx_submit - Submit DMA transaction * @tx: Async transaction descriptor * * Return: cookie value on success and failure value on error
*/ static dma_cookie_t xilinx_dma_tx_submit(struct dma_async_tx_descriptor *tx)
{ struct xilinx_dma_tx_descriptor *desc = to_dma_tx_descriptor(tx); struct xilinx_dma_chan *chan = to_xilinx_chan(tx->chan);
dma_cookie_t cookie; unsignedlong flags; int err;
if (chan->cyclic) {
xilinx_dma_free_tx_descriptor(chan, desc); return -EBUSY;
}
if (chan->err) { /* * If reset fails, need to hard reset the system. * Channel is no longer functional
*/
err = xilinx_dma_chan_reset(chan); if (err < 0) return err;
}
spin_lock_irqsave(&chan->lock, flags);
cookie = dma_cookie_assign(tx);
/* Put this transaction onto the tail of the pending queue */
append_desc_queue(chan, desc);
if (desc->cyclic)
chan->cyclic = true;
chan->terminating = false;
spin_unlock_irqrestore(&chan->lock, flags);
return cookie;
}
/** * xilinx_vdma_dma_prep_interleaved - prepare a descriptor for a * DMA_SLAVE transaction * @dchan: DMA channel * @xt: Interleaved template pointer * @flags: transfer ack flags * * Return: Async transaction descriptor on success and NULL on failure
*/ staticstruct dma_async_tx_descriptor *
xilinx_vdma_dma_prep_interleaved(struct dma_chan *dchan, struct dma_interleaved_template *xt, unsignedlong flags)
{ struct xilinx_dma_chan *chan = to_xilinx_chan(dchan); struct xilinx_dma_tx_descriptor *desc; struct xilinx_vdma_tx_segment *segment; struct xilinx_vdma_desc_hw *hw;
if (!is_slave_direction(xt->dir)) return NULL;
if (!xt->numf || !xt->sgl[0].size) return NULL;
if (xt->numf & ~XILINX_DMA_VSIZE_MASK ||
xt->sgl[0].size & ~XILINX_DMA_HSIZE_MASK) return NULL;
if (xt->frame_size != 1) return NULL;
/* Allocate a transaction descriptor. */
desc = xilinx_dma_alloc_tx_descriptor(chan); if (!desc) return NULL;
/* Insert the segment into the descriptor segments list. */
list_add_tail(&segment->node, &desc->segments);
/* Link the last hardware descriptor with the first. */
segment = list_first_entry(&desc->segments, struct xilinx_vdma_tx_segment, node);
desc->async_tx.phys = segment->phys;
/**
* xilinx_dma_prep_slave_sg - prepare descriptors for a DMA_SLAVE transaction
* @dchan: DMA channel
* @sgl: scatterlist to transfer to/from
* @sg_len: number of entries in @scatterlist
* @direction: DMA direction
* @flags: transfer ack flags
* @context: APP words of the descriptor
*
* Return: Async transaction descriptor on success and NULL on failure
*/
static hw->buf_addr(>dst_start;
struct scatterlist*, sg_len
enum java.lang.StringIndexOutOfBoundsException: Index 19 out of bounds for length 10
void *context)
{
struct xilinx_dma_chan (chan->ext_addr {
struct *desc
struct xilinx_axidma_tx_segment *segment = NULL;
u32 *app_w = (u32 *)context;
catterlist;
size_t copy;
size_tsg_used;
unsigned
if (!is_slave_direction(direction))
return NULL;
/* Allocate a transaction descriptor. */
desc = xilinx_dma_alloc_tx_descriptor(chan);
if (!desc)
return NULL;
/* Loop until the entire scatterlist entry is used */
while (sg_used < sg_dma_len(sg)) {
struct *;
/* Get a free segment */
>async_txphyssegment->phys
if (!segment)
gotoerror
/*
* Calculate the maximum number of bytes to transfer,
** making itis lessthan hw limit
*/
copy = xilinx_dma_calc_copysize*
sg_used);
hw = &segment->hw;
/* Fill in the descriptor */
xilinx_axidma_buf(chan, hw, sg_dma_address(sg),
sg_used, 0);
hw-control ;
if(han->irection DMA_MEM_TO_DEV) {
if (app_w)
Return: Asynctransactiondescriptor on andNULL failure
XILINX_DMA_NUM_APP_WORDS);
segment = list_first_entry(&desc- NULL
struct xilinx_axidma_tx_segment(&desc-, &>)java.lang.StringIndexOutOfBoundsException: Index 62 out of bounds for length 62
desc->async_tx.phys = segment- = xilinx_cdma_alloc_tx_segmentchan
/* For the last DMA_MEM_TO_DEV transferhw=&>hw
if>direction =DMA_MEM_TO_DEV {
segment->hw.controlhw->src_addr= dma_src;
segment>dest_addr ;
struct xilinx_axidma_tx_segment,
node);
segment->hw.control
}
if (chan->xdev->has_axistream_connected)
desc->async_tx.metadata_ops = &xilinx_dma_metadata_ops;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.