Back to home page

LXR

 
 

    


File indexing completed on 2025-05-11 08:23:43

0001 /* SPDX-License-Identifier: BSD-2-Clause */
0002 
0003 /*
0004  *  GR1553B BC driver, Descriptor LIST handling
0005  *
0006  *  COPYRIGHT (c) 2010.
0007  *  Cobham Gaisler AB.
0008  *
0009  * Redistribution and use in source and binary forms, with or without
0010  * modification, are permitted provided that the following conditions
0011  * are met:
0012  * 1. Redistributions of source code must retain the above copyright
0013  *    notice, this list of conditions and the following disclaimer.
0014  * 2. Redistributions in binary form must reproduce the above copyright
0015  *    notice, this list of conditions and the following disclaimer in the
0016  *    documentation and/or other materials provided with the distribution.
0017  *
0018  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
0019  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
0020  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
0021  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
0022  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
0023  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
0024  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
0025  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
0026  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
0027  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
0028  * POSSIBILITY OF SUCH DAMAGE.
0029  */
0030 
0031 #ifndef __GR1553BC_LIST_H__
0032 #define __GR1553BC_LIST_H__
0033 
0034 /*!\file doc/gr1553bc_list.h
0035  * \brief GR1553B BC driver
0036  *
0037  * \section OVERVIEW
0038  *
0039  * The BC device driver can schedule synchronous and asynchronous lists
0040  * of descriptors. The list contains a descriptor table and a software
0041  * description to make some operations possible, for example translate
0042  * descriptor-address into descriptor-number.
0043  *
0044  * This is the LIST API. It provides functionality to create and manage
0045  * a BC descriptor list.
0046  *
0047  * A list is built up by the following build blocks:
0048  *  - Major Frame (Consists of N Minor Frames)
0049  *  - Minor Frame (Consists of up to 32 1553 Message Slots)
0050  *  - Message Slot (Transfer/Condition BC descriptor)
0051  *
0052  * The user can configure lists with different configuration of number of
0053  * Major Frames, Minor Frame and messages slots within a Minor Frame. The
0054  * List manages a strait descriptor table (may be changed) and a Frame/Slot
0055  * tree in order to easily find it's way through all descriptor created.
0056  *
0057  * Each Minor frame consist of up to 32 message slot and 2 message slots
0058  * for time management and descriptor find operations. The list can manage
0059  * time slots per minor frame, for example a minor frame may be programmed
0060  * to take 8ms and when the user allocate a message slot within that Minor
0061  * frame the time spcified will be subtracted from the 8ms, and when the
0062  * message slot is freed the time will be returned to the Minor frame again.
0063  *
0064  * A Major, Minor and Message Slots are identified using a MID (Message-ID).
0065  * The MID is a way for the user to avoid using pointers are talk with the
0066  * list API in an easier way. For example a condition Slot that should jump
0067  * to a transfer slot can be created by knowing "MID and Jump-To-MID". When
0068  * allocating a Slot (with or without time) the user may specify a certain
0069  * Slot or a Minor frame, when a Minor frame is given then the API will find
0070  * a free Slot as early in the Minor Frame as possible and return it to the
0071  * user.
0072  *
0073  * A MID can be created using the macros:
0074  *   GR1553BC_ID(major,minor,slot)      - ID of a SLOT
0075  *   GR1553BC_MINOR_ID(major,minor)     - ID of a MINOR (Slot=0xff)
0076  *   GR1553BC_MAJOR_ID(major)           - ID of a Major (Minor=0xff,Slot=0xff)
0077  *
0078  * The typical approach create lists is in the following order:
0079  *   -# gr1553bc_list_alloc(&list, MAJOR_CNT)
0080  *   -# gr1553bc_list_config(list, &listcfg)
0081  *   -# Create all Major Frames and Minor frame, for each major frame:
0082  *       a) gr1553bc_major_alloc_skel(&major, &major_minor_cfg)
0083  *       b) gr1553bc_list_set_major(list, &major, MAJOR_NUM)
0084  *   -# link end Major Frames together:
0085  *       a) gr1553bc_list_set_major(&major7, &major0)   // Connect Major frames
0086  *   -# gr1553bc_list_table_alloc()   (Allocate Descriptor Table)
0087  *   -# gr1553bc_list_table_build()   (Build Descriptor Table from Majors/Minors)
0088  *   -# Allocate and initialize Descriptors pre defined before starting:
0089  *      -## gr1553bc_slot_alloc(list, &MID, TIME_REQUIRED, ..)
0090  *      -## gr1553bc_slot_transfer(MID, ...)
0091  *   -# START BC HARDWARE BY SHCDULING ABOVE LIST
0092  *   -# Operate on List
0093  *
0094  *
0095  * \section bc_list_update Changing a scheduled BC list (during BC-runtime)
0096  *
0097  *  One can use the INDICATION service to avoid modifying
0098  *  a descriptor currently in use by the BC core. One can also in most cases
0099  *  do descriptor initialization in three steps: Init Descriptor as Dummy 
0100  *  with and allocated time (often done before starting/scheduling list),
0101  *  then modify transfer options and data-pointers, then clear the Dummy
0102  *  bit in one atomic data store. This approach will avoid potential races
0103  *  between software has hardware.
0104  *
0105  *
0106  * \section bc_memory_setup Custom Memory Setup
0107  *
0108  *  For designs where dynamically memory is not an option, or the driver
0109  *  is used on a AMBA-over-PCI bus (where malloc() does not work), the
0110  *  API allows the user to provide custom addresses for descriptor table
0111  *  and object descriptions (lists, major frames, minor frames). Custom
0112  *  descriptor table is probably the most interesting thing for most, it
0113  *  is setup with gr1553bc_list_table_alloc(list, CUSTOM_ADDRESS).
0114  *
0115  *  Object descriptions are normally allocated during initialization
0116  *  procedure by providing the API with a object configuration, for 
0117  *  example a Major Frame configuration enables the API to allocate
0118  *  the software description of a Major Frame with all it's Minor frames.
0119  *
0120  *
0121  * \section major Major Frame
0122  *
0123  *  Consists of multiple Minor frames. A Major frame may be connected/linked
0124  *  with another Major frame, this will result in a Jump Slot from last
0125  *  Minor frame in the first Major to the first Minor in the second Major.
0126  *
0127  *
0128  * \section minor Minor Frame
0129  *
0130  *  Consists of up to 32 Message Slots. The services are Time-Management and
0131  *  Slot allocation.
0132  *
0133  *  Time-Management is optional.
0134  *
0135  *  Time-Slot-Management can be enabled per Minor frame. A Minor frame can be
0136  *  assigned a time in microseconds. The BC will not continue to the next
0137  *  Minor frame until the time has passed. It is managed by adding an extra
0138  *  Dummy Message Slot with the total minor frame time. Each time a message
0139  *  Slot is allocated (with a certain time: Slot-Time) the Slot-Time will
0140  *  be decremented from the total time of the Minor frame. This way the
0141  *  sum of the Message Slot will always sum up to the total time of the
0142  *  Minor configuration. When a message slot is freed, the Dymmy Message
0143  *  Slot's Slot-Time is incremented with the freed Slot-Time.
0144  *
0145  *  A Message Slot can be allocated by identifying a specific free Slot
0146  *  by the MID (Message-ID) or by letting the API allocate the first free
0147  *  Slot in the Minor Frame (Set MID Slot-ID to 0xff to identify Minor
0148  *  Frame).
0149  *
0150  *
0151  * \section slot Message Slot
0152  *
0153  *  The GR1553B BC core supports two Slot (Descriptor) Types:
0154  *   - Transfer descriptor
0155  *   - Condition descriptor (Jump, unconditional-IRQ)
0156  *
0157  *  See the hardware manual for a detail description of a descriptor (Slot).
0158  *
0159  *  The BC Core is unaware of lists, it steps through executing each 
0160  *  descriptor as the encountered, Conditionals resulting in jumps may
0161  *  let us to create more complex arrangements of buffer descriptos (BDs)
0162  *  which we call list.
0163  *
0164  *  Transfer BDs (TBDs) may have a time slot assigned, the BC core will wait
0165  *  until the time has expired before executing the next descriptor. Time
0166  *  slots are handled by a Minor frame in the list.
0167  *
0168  *  A Message Slot is allocated using the gr1553bc_slot_alloc() function,
0169  *  and configured by calling one of the below functions:
0170  *   - gr1553bc_slot_irq_prepare   [unconditional IRQ slot]
0171  *   - gr1553bc_slot_jump          [unconditional jump]
0172  *   - gr1553bc_slot_exttrig       [Dummy transfer, wait for EXTERNAL-TRIGGER]
0173  *   - gr1553bc_slot_transfer      [Transfer descriptor]
0174  *   - gr1553bc_slot_empty         [Create Dummy Transfer descriptor]
0175  *   - gr1553bc_slot_raw           [Custom Descriptor handling]
0176  *
0177  *   - gr1553bc_slot_dummy         [Set existing Transfer descriptor to Dummy]
0178  *   - gr1553bc_slot_update        [Update DataPointer|Status of a TBD]
0179  *
0180  *
0181  * \section bc_IRQ Interrupt Handling
0182  *
0183  * There are different types of interrupts, Error IRQs or transfer IRQs. The
0184  * Error IRQs are handled by the driver can a callback function is called. 
0185  *
0186  * Transfer Descriptors can be programmed to generate interrupt, and
0187  * condition descriptors can be programmed to generate interrupt
0188  * unconditionaly (there exists more conditional types). When a Transfer
0189  * descriptor causes IRQ the general ISR callback of the BC driver is 
0190  * called to let the user handle the interrupt. When a condition descriptor
0191  * causes an IRQ a custom IRQ handler is called (if assigned).
0192  *
0193  * Transfers descriptor IRQ is enabled by configuring the descriptor.
0194  *
0195  * The API provides functions for placing unconditional IRQ points anywhere
0196  * in the list. The order:
0197  *   -# gr1553bc_slot_alloc(&MID, TIME=0, ..)
0198  *   -# gr1553bc_slot_irq_prepare(MID, funcISR, data)
0199  *   -# gr1553bc_slot_irq_enable(MID)
0200  * 
0201  * \verbatim
0202  *  void funcISR(*bd, *data)
0203  *  {
0204  *    // HANDLE ONE OR MULTIPLE DESCRIPTORS (MULTIPLE IN THIS EXAMPLE):
0205  *    int MID;
0206  *    gr1553bc_mid_from_bd(bd,&MID,NULL);
0207  *    printf("IRQ ON %06x\n", MID);
0208  *  }
0209  * \endverbatim
0210  *
0211  * \ingroup GR1553BC
0212  */
0213 
0214 #include <stdint.h>
0215 #include "gr1553bc.h"
0216 
0217 /**** CONFIGURATION OPTIONS ****/
0218 
0219 /* Define GR1553BC_TIMESLOT to make driver take care of time
0220  * management of minor frames.
0221  */
0222 #define GR1553BC_TIMESLOT
0223 
0224 #define GR1553BC_MINOR_MAX 256
0225 #define GR1553BC_SLOT_MAX 32
0226 
0227 #ifdef __cplusplus
0228 extern "C" {
0229 #endif
0230 
0231 struct gr1553bc_list;
0232 struct gr1553bc_major;
0233 struct gr1553bc_minor;
0234 struct gr1553bc_minor_cfg;
0235 struct gr1553bc_major_cfg;
0236 
0237 struct gr1553bc_minor_cfg {
0238     int slot_cnt;
0239     int timeslot;       /* Total time of minor frame in us */
0240 };
0241 
0242 struct gr1553bc_major_cfg {
0243     int minor_cnt;              /* Number of Minor Frames */
0244     struct gr1553bc_minor_cfg minor_cfgs[1];
0245 };
0246 
0247 struct gr1553bc_list_cfg {
0248     unsigned char rt_timeout[31];   /* Number of us timeout tolerance per RT */
0249     unsigned char bc_timeout;   /* Number of us timeout tolerance of 
0250                      * broadcast transfers */
0251     int tropt_irq_on_err;       /* Generate IRQ on transfer error */
0252     int tropt_pause_on_err;     /* Pause list on transfer error */
0253     int async_list;         /* Set to non-zero if asyncronous list*/
0254 };
0255 
0256 /* Default Configuration */
0257 extern struct gr1553bc_list_cfg gr1553bc_def_cfg;
0258 
0259 /* Complete list of all major frames */
0260 struct gr1553bc_list {
0261     void *_table_custom;        /* Config option given by user */
0262     void *_table;           /* address of allocated bd-table */
0263     unsigned int table_hw;      /* Descriptor table base HW-ADR */
0264     unsigned int table_cpu;     /* Descriptor table base CPU-ADR */
0265     int table_size;         /* Descriptor Table Size */
0266     void *bc;           /* BC HW, needed for adr translation */
0267     unsigned char rt_timeout[32];   /* Tolerance per RT, default 20us
0268                      * Note: 31 is for Broadcast */
0269     uint32_t tropts;        /* Transfer descriptor options:
0270                      *  On transfer error the following bits
0271                      *  do affect:
0272                      *  - bit28 1=Generate IRQ
0273                      *  - bit26 1=Pause transfer list
0274                      *  
0275                      */
0276     int async_list;         /* async list or not */
0277     int major_cnt;          /* Number of Major frames */
0278     struct gr1553bc_major *majors[1];   /* Var-Array of Major Pointers*/
0279 };
0280 
0281 /* Alloc a List with a maximum number of Major frames supported */
0282 extern int gr1553bc_list_alloc(struct gr1553bc_list **list, int max_major);
0283 
0284 /* Free List if allocated with gr1553bc_list_alloc() */
0285 extern void gr1553bc_list_free(struct gr1553bc_list *list);
0286 
0287 /* Configure Global List parameters 
0288  *
0289  * \param list    List to be configured and initialized.
0290  * \param cfg     List Configuration
0291  * \param bc      The BC hardware device description
0292  *                  (only needed for address translation)
0293  */
0294 extern int gr1553bc_list_config
0295     (
0296     struct gr1553bc_list *list,
0297     struct gr1553bc_list_cfg *cfg,
0298     void *bc
0299     );
0300 
0301 /* Link a 'major' Major frame with next major frame 
0302  * The links affected:
0303  *   - major->next
0304  *   - major->minor[LAST]->next
0305  */
0306 extern void gr1553bc_list_link_major(
0307     struct gr1553bc_major *major,
0308     struct gr1553bc_major *next
0309     );
0310 
0311 /* Link in a Major frame into a BC list.
0312  * Calls gr1553bc_list_link_major() to link major frame with major-1 and
0313  * major+1. If ending or starting major frame the frame is wrapped around.
0314  */
0315 extern int gr1553bc_list_set_major(
0316     struct gr1553bc_list *list,
0317     struct gr1553bc_major *major,
0318     int no);
0319 
0320 /* Calculate the size required in the descriptor table by one minor frame. */
0321 extern int gr1553bc_minor_table_size(struct gr1553bc_minor *minor);
0322 
0323 /* Calculate the size required for the descriptor table.
0324  */
0325 extern int gr1553bc_list_table_size(struct gr1553bc_list *list);
0326 
0327 /* Allocate an empty descriptor table from list description suitable for
0328  * the BC given by 'bc'.
0329  *
0330  * \param bdtab_custom   Custom Descriptor Allocation options:
0331  *                         ZERO: Dynamically allocated by Driver (CPU near RAM)
0332  *                         Non-Zero: Use provided address as BASE of BD-TABLE
0333  *                         Non-Zero with LSB set: Same as Non-Zero but address
0334  *                          is given as HW address (used with AMBA-over-PCI to
0335  *                          to specify RAM location on PCI board).
0336  */
0337 extern int gr1553bc_list_table_alloc
0338     (
0339     struct gr1553bc_list *list,
0340     void *bdtab_custom
0341     );
0342 
0343 /* Free descriptor table allocated with gr1553bc_list_table_alloc() */
0344 extern void gr1553bc_list_table_free(struct gr1553bc_list *list);
0345 
0346 /* Build an empty descriptor table from list description, 
0347  * the minor frames will be linked together.
0348  */
0349 extern int gr1553bc_list_table_build(struct gr1553bc_list *list);
0350 
0351 /* Major Frame */
0352 struct gr1553bc_major {
0353     struct gr1553bc_major *next;        /* Next Major Frame */
0354     struct gr1553bc_major_cfg *cfg;     /* User Config of Major frame */
0355     struct gr1553bc_minor *minors[1];   /* Minor frames */
0356 };
0357 
0358 /* Minor Frame */
0359 struct gr1553bc_minor {
0360     struct gr1553bc_minor *next;    /* Next Minor Frame */
0361     struct gr1553bc_minor_cfg *cfg; /* User Config of Minor frame */
0362     uint32_t alloc;         /* Descripts allocated */
0363 
0364     /* Note: THIS POINTER MUST BE ALIGNED ON A 128-bit BOUNDARY */
0365     union gr1553bc_bd *bds; /* Descriptors for this minor frame (CPU ADRS)*/
0366 };
0367 
0368 /* Alloc a Major/Minor frame skeleton according to the configuration structure. 
0369  * The descriptor table is not allocated.
0370  */
0371 extern int gr1553bc_major_alloc_skel
0372     (
0373     struct gr1553bc_major **major,
0374     struct gr1553bc_major_cfg *cfg
0375     );
0376 
0377 /* Unique Message/Descriptor ID. Can be used to identify a Major or Minor 
0378  * Frame, or a Slot.
0379  *
0380  * - If minor_num is 0xff, the ID identifies a Major Frame
0381  * - If slot_num is 0xff, the ID identifies a Minor Frame
0382  * - If non of the above is true, the ID identifies a specific Slot
0383  */
0384 #define GR1553BC_ID(major_num, minor_num, slot_num) \
0385         ((((major_num)<<16)&0xff0000) | (((minor_num)<<8)&0xff00) | \
0386         ((slot_num) & 0xff))
0387 #define GR1553BC_MINOR_ID(major_num, minor_num) \
0388         GR1553BC_ID(major_num, minor_num, 0xff)
0389 #define GR1553BC_MAJOR_ID(major_num) \
0390         GR1553BC_ID(major_num, 0xff, 0xff)
0391 
0392 #define GR1553BC_MAJID_FROM_ID(mid) (((mid) >> 16) & 0xff)
0393 #define GR1553BC_MINID_FROM_ID(mid) (((mid) >> 8) & 0xff)
0394 #define GR1553BC_SLOTID_FROM_ID(mid) ((mid) & 0xff)
0395 #define GR1553BC_ID_SET_SLOT(mid, slot_num) (((mid) & ~0xff) | ((slot_num) & 0xff))
0396 
0397 extern struct gr1553bc_major *gr1553bc_major_from_id
0398     (
0399     struct gr1553bc_list *list,
0400     int mid
0401     );
0402 
0403 extern struct gr1553bc_minor *gr1553bc_minor_from_id
0404     (
0405     struct gr1553bc_list *list,
0406     int mid
0407     );
0408 
0409 /* Get free time left of minor frame identified by MID 'mid' */
0410 extern int gr1553bc_list_freetime(struct gr1553bc_list *list, int mid);
0411 
0412 /* Get free time left of minor frame */
0413 extern int gr1553bc_minor_freetime(struct gr1553bc_minor *minor);
0414 
0415 /* Allocate a time slot on a minor frame, major/minor frame is identified 
0416  * by MID. The 'mid' is a input/ouput parameter, the resulting slot taken
0417  * will be placed in 'mid', a pointer to the allocated descriptor is stored
0418  * into bd.
0419  *
0420  * Major/Minor must be specified by MID, if slot is specified that slot will
0421  * be allocated, if slot is 0xff, then the first free slot is allocated.
0422  *
0423  * The function fails (return negative) if timeslot is longer than remaining
0424  * time in minor frame, if no more slots are available in minor frame, if 
0425  * MID points to a bad major/minor or major/minor/slot.
0426  */
0427 extern int gr1553bc_slot_alloc(
0428     struct gr1553bc_list *list,
0429     int *mid,
0430     int timeslot,
0431     union gr1553bc_bd **bd
0432     );
0433 /* Same as gr1553bc_slot_alloc but identifies a minor instead of list.
0434  * The major/minor part of MID is ignored.
0435  */
0436 extern int gr1553bc_slot_alloc2(
0437     struct gr1553bc_minor *minor,
0438     int *mid,
0439     int timeslot,
0440     union gr1553bc_bd **bd
0441     );
0442 
0443 /* Free message slot and the time associated with it. The time taken by the
0444  * message slot is added to the END TIME descriptor, if managed by the driver
0445  * for this minor frame. The descriptor will be 
0446  */
0447 extern int gr1553bc_slot_free(struct gr1553bc_list *list, int mid);
0448 extern int gr1553bc_slot_free2(struct gr1553bc_minor *minor, int mid);
0449 
0450 /* Find MID from Descriptor pointer
0451  *
0452  * In the end of each minor frame is a unconditional jump 
0453  * to next minor frame descriptor. The hardware does not
0454  * use the last 8 bytes of conditional descriptors, in the
0455  * padding area a MID is stored so that we can lookup the
0456  * MID of a descriptor. This function finds the jump
0457  * descriptor and subtracs the offset from it.
0458  *
0459  * A faster way of looking up can be implemented if the
0460  * list is symertical, however in the current setup we
0461  * allow different numbers of slots in minor frames, and
0462  * different number of minor frames in a major frame.
0463  *
0464  * \param bd     IN: Descriptor to lookup MID of (CPU address of BD)
0465  * \param mid    OUT: Pointer to where Message-ID (Slot-ID) will be stored
0466  * \param async  OUT: Function will store non-zero value if BD belogs to 
0467  *                    async list.
0468  */
0469 extern int gr1553bc_mid_from_bd(
0470     union gr1553bc_bd *bd,
0471     int *mid,
0472     int *async
0473     );
0474 
0475 /********** TRANSFER DESCRIPTOR MANIPULATION **********/
0476 
0477 /* Get pointer to descriptor entry from MID. */
0478 extern union gr1553bc_bd *gr1553bc_slot_bd
0479     (
0480     struct gr1553bc_list *list,
0481     int mid
0482     );
0483 
0484 /* IRQ function */
0485 typedef void (*bcirq_func_t)(union gr1553bc_bd *bd, void *data);
0486 
0487 /* Create unconditional IRQ customly defined location.
0488  * The IRQ is disabled, enable it with gr1553bc_slot_irq_enable().
0489  */
0490 extern int gr1553bc_slot_irq_prepare
0491     (
0492     struct gr1553bc_list *list,
0493     int mid,
0494     bcirq_func_t func,
0495     void *data
0496     );
0497 
0498 /* Enable previously prepared unconditional IRQ */
0499 extern int gr1553bc_slot_irq_enable(struct gr1553bc_list *list, int mid);
0500 
0501 /* Disable unconditional IRQ point, changed to unconditional JUMP
0502  * to descriptor following.
0503  * After disabling it it can be enabled again, or freed.
0504  */
0505 extern int gr1553bc_slot_irq_disable(struct gr1553bc_list *list, int mid);
0506 
0507 /* Create custom jump to descriptor, conditional or unconditional, see 
0508  * hardware manual for conditions.
0509  *
0510  * set conditional to GR1553BC_UNCOND_JMP for unconditional jump.
0511  */
0512 extern int gr1553bc_slot_jump
0513     (
0514     struct gr1553bc_list *list,
0515     int mid,
0516     uint32_t condition,
0517     int to_mid
0518     );
0519 
0520 /* Create a dummy transfer, paused until external trigger is set. The
0521  * Slot is will have the dummy bit set, no transfer will take place.
0522  */
0523 extern int gr1553bc_slot_exttrig(struct gr1553bc_list *list, int mid);
0524 
0525 /* Create a transfer on a previous allocated descriptor. It is assumed
0526  * that the descriptor has been initialized empty before calling this
0527  * function, this is to avoid races.
0528  *
0529  * The settings that are controlled on a global level (and not
0530  * by this function):
0531  *  - IRQ after transfer error
0532  *  - IRQ after transfer (not supported, insert separate IRQ slot after this)
0533  *  - Pause schedule after transfer error
0534  *  - Pause schedule after transfer (not supported)
0535  *  - slot time optional (set when MID allocated), otherwise 0
0536  *  - (OPTIONAL) Dummy Bit, set using slot_empty() or ..._TT_DUMMY
0537  *  - RT timeout tolerance (managed per RT)
0538  *
0539  *  Input Parameters:
0540  *  - Retry Mode            (options)
0541  *  - Number of retires         (options)
0542  *  - Bus selection (A or B)        (options)
0543  *  - dummy bit             (options)
0544  *  - transfer type         (tt)
0545  *  - rt src/dst address        (tt)
0546  *  - RT subaddress         (tt)
0547  *  - word count            (tt)
0548  *  - mode code             (tt)
0549  *  - data pointer          (dptr)
0550  *
0551  *
0552  * See macros defined in this header file for creating transfer types (tt)
0553  * and word count etc.
0554  *
0555  * See macros defined in this header file for creating the mask of options.
0556  *
0557  * Note that if bit0 (LSB) of dptr is set, then the address is translated into
0558  * hardware address, otherwise the dptr is assumed to be accessible from the
0559  * 1553 core. This is an option only for AMBA-over-PCI.
0560  */
0561 extern int gr1553bc_slot_transfer(
0562     struct gr1553bc_list *list,
0563     int mid,
0564     int options,
0565     int tt,
0566     uint16_t *dptr);
0567 
0568 /* Remove or set dummy bit of a transfer descriptor
0569  * Bit31 of *dummy is written to the dummy bit, the 
0570  * old descriptor value is stored into *dummy.
0571  */
0572 extern int gr1553bc_slot_dummy(
0573     struct gr1553bc_list *list,
0574     int mid,
0575     unsigned int *dummy);
0576 
0577 /* Make a slot empty (BC will not generate bus transfers), time slot 
0578  * allocated is untouched (if assigned).
0579  */
0580 extern int gr1553bc_slot_empty(struct gr1553bc_list *list, int mid);
0581 
0582 /* Transfer descriptor status and/or update Transfer descriptor data pointer.
0583  *
0584  * Read and/or write Status of a slot. Writing the status word may be
0585  * used by software to indicate that result has been handled, or bit 31
0586  * may be written 1 telling software that when it reaches 0, then BC
0587  * has executed the request.
0588  *
0589  * Operation:
0590  *  bd->status = *stat & (bd->status 0xffffff) | (*stat & 0x80000000);
0591  *  *stat = Value of bd->status before rewrite.
0592  *
0593  * Note that the status word is not written when *stat is zero.
0594  *
0595  * Note that if bit0 (LSB) of dptr is set, then the address is translated into
0596  * hardware address, otherwise the dptr is assumed to be accessible from the
0597  * 1553 core. This is an option only for AMBA-over-PCI.
0598  */
0599 extern int gr1553bc_slot_update(
0600     struct gr1553bc_list *list,
0601     int mid,
0602     uint16_t *dptr,
0603     unsigned int *stat);
0604 
0605 /* Modify a transfer descriptor in any way,
0606  * 
0607  * flags:
0608  *  bit[N=0..3]: 1 = set BD wordN according to argument wordN,
0609  *               0 = do not modify BD wordN
0610  */
0611 extern int gr1553bc_slot_raw
0612     (
0613     struct gr1553bc_list *list,
0614     int mid,
0615     unsigned int flags,
0616     uint32_t word0,
0617     uint32_t word1,
0618     uint32_t word2,
0619     uint32_t word3
0620     );
0621 
0622 
0623 /***** Macros to create BC Transfer Types (tt) for gr1553bc_slot_transfer() *****/
0624 
0625 /* WRITE TO RT (BC-to-RT) */
0626 #define GR1553BC_BC2RT(rtadr, subadr, word_count) \
0627         ((rtadr<<11) | (subadr<<5) | (0x1f<<21) | (0<<10) | \
0628         ((word_count>=32) ? 0 : word_count))
0629 
0630 /* READ FROM RT (RT-to-BC) */
0631 #define GR1553BC_RT2BC(rtadr, subadr, word_count) \
0632         ((rtadr<<11) | (subadr<<5) | (0x1f<<21) | (1<<10) | \
0633         ((word_count>=32) ? 0 : word_count))
0634 
0635 /* RT(TX) WRITE TO RT(RX) (RT-to-RT) */
0636 #define GR1553BC_RT2RT(tx_rtadr, tx_subadr, rx_rtadr, rx_subadr, word_count) \
0637         ((rx_rtadr<<11) | (rx_subadr<<5) | \
0638         (tx_rtadr<<21) | (tx_subadr<<16) | \
0639         (0<<10) | \
0640         ((word_count>=32) ? 0 : word_count))
0641 
0642 /* Mode command without data. (BC-to-RT)
0643  * Mode code: 0,1,2,3,4,5,6,7 or 8.
0644  */
0645 #define GR1553BC_MC_NODATA(rtadr, modecode) \
0646         ((rtadr<<11) | (0x1f<<5) | (0x1f<<21) | \
0647         (modecode<<0) | (1<<10))
0648 
0649 /* Mode command with 4 byte data (RT-to-BC)
0650  * Mode code: 16, 18 or 19.
0651  */
0652 #define GR1553BC_MC_RT2BC(rtadr, modecode) \
0653         ((rtadr<<11) | (0x1f<<5) | (0x1f<<21) | \
0654         (modecode<<0) | (1<<10))
0655 
0656 /* Mode command with 4 byte data (BC-to-RT)
0657  * Mode code: 17, 20 or 21.
0658  */
0659 #define GR1553BC_MC_BC2RT(rtadr, modecode) \
0660         ((rtadr<<11) | (0x1f<<5) | (0x1f<<21) | \
0661         (modecode<<0) | (0<<10))
0662 
0663 /* Broadcast to all RTs, to a specific subaddress (BC-to-RTs) */
0664 #define GR1553BC_BC_BC2RT(subadr, word_count) \
0665         ((0x1f<<11) | (subadr<<5) | (0x1f<<21) | \
0666         (0<<10) | \
0667         ((word_count>=32) ? 0 : word_count))
0668 
0669 /* Request RT to broadcast to all RTs, to a specific subaddress (RT-to-RTs) */
0670 #define GR1553BC_BC_RT2RT(tx_rtadr, tx_subadr, rx_subadr, word_count) \
0671         ((0x1f<<11) | (rx_subadr<<5) | \
0672         (tx_rtadr<<21) | (tx_subadr<<16) | \
0673         (0<<10) | \
0674         ((word_count>=32) ? 0 : word_count))
0675 
0676 /* Broadcast mode command without data (BC-to-RTs) 
0677  * Mode code: 1,3,4,5,6,7 or 8
0678  */
0679 #define GR1553BC_BC_MC_NODATA(modecode) \
0680         ((0x1f<<11) | (0x1f<<5) | (0x1f<<21) | \
0681         ((modecode)<<0) | (1<<10))
0682 
0683 /* Broadcast mode command with 4 byte data (BC-to-RTs)
0684  * Mode code: 17, 20 or 21
0685  */
0686 #define GR1553BC_BC_MC_BC2RT(modecode) \
0687         ((0x1f<<11) | (0x1f<<5) | (0x1f<<21) | \
0688         ((modecode)<<0) | (0<<10))
0689 
0690 
0691 /***** Macros to create BC options (options) for gr1553bc_slot_transfer() *****/
0692 
0693 /* Dummy (BC does no bus trasactions) */
0694 #define GR1553BC_OPT_DUMMY (1<<1)
0695 
0696 /* Retry modes */
0697 #define GR1553BC_RETRY_SAME 0x0 /* Retry on the same bus only */
0698 #define GR1553BC_RETRY_ALTER    0x1 /* Retry alternating on both busses */
0699 #define GR1553BC_RETRY_ATTEMPT  0x2 /* Many attepts first on original 
0700                      * bus then on other bus */
0701 /* Number of retires supported */
0702 #define GR1553BC_RETRY_CNT_MAX  6
0703 
0704 /* Dummy bit: No transfer
0705  * Bus bit: 0=A, 1=B
0706  * Exttrig bit: Wait for external trigger (used for timesync)
0707  * Exclusive bit: 1=Don't allow other messages in this time slot.
0708  */
0709 #define GR1553BC_OPTIONS(dummy, exttrig, exclusive, retrymode, nretry, bus) \
0710         ((((exttrig) & 0x1) << 30) | (((exclusive) & 0x1) << 29) | \
0711         ((retrymode) << 23) | ((nretry) << 20) | \
0712         ((bus) & 1) | (((dummy) & 0x1) << 1))
0713 
0714 #define GR1553BC_OPTIONS_BUSA GR1553BC_OPTIONS(0,0,0,GR1553BC_RETRY_SAME,0,0)
0715 #define GR1553BC_OPTIONS_BUSB GR1553BC_OPTIONS(0,0,0,GR1553BC_RETRY_SAME,0,1)
0716 #define GR1553BC_OPTIONS_BUSA_DUM GR1553BC_OPTIONS(1,0,0,GR1553BC_RETRY_SAME,0,0)
0717 #define GR1553BC_OPTIONS_BUSB_DUM GR1553BC_OPTIONS(1,0,0,GR1553BC_RETRY_SAME,0,1)
0718 
0719 /* Show parts of a list - this is for debugging only */
0720 extern void gr1553bc_show_list(struct gr1553bc_list *list, int options);
0721 
0722 #ifdef __cplusplus
0723 }
0724 #endif
0725 
0726 #endif /* __GR1553BC_LIST_H__ */