linux/drivers/dma/txx9dmac.h
<<
>>
Prefs
   1/* SPDX-License-Identifier: GPL-2.0-only */
   2/*
   3 * Driver for the TXx9 SoC DMA Controller
   4 *
   5 * Copyright (C) 2009 Atsushi Nemoto
   6 */
   7#ifndef TXX9DMAC_H
   8#define TXX9DMAC_H
   9
  10#include <linux/dmaengine.h>
  11#include <asm/txx9/dmac.h>
  12
  13/*
  14 * Design Notes:
  15 *
  16 * This DMAC have four channels and one FIFO buffer.  Each channel can
  17 * be configured for memory-memory or device-memory transfer, but only
  18 * one channel can do alignment-free memory-memory transfer at a time
  19 * while the channel should occupy the FIFO buffer for effective
  20 * transfers.
  21 *
  22 * Instead of dynamically assign the FIFO buffer to channels, I chose
  23 * make one dedicated channel for memory-memory transfer.  The
  24 * dedicated channel is public.  Other channels are private and used
  25 * for slave transfer.  Some devices in the SoC are wired to certain
  26 * DMA channel.
  27 */
  28
  29#ifdef CONFIG_MACH_TX49XX
  30static inline bool txx9_dma_have_SMPCHN(void)
  31{
  32        return true;
  33}
  34#define TXX9_DMA_USE_SIMPLE_CHAIN
  35#else
  36static inline bool txx9_dma_have_SMPCHN(void)
  37{
  38        return false;
  39}
  40#endif
  41
  42#ifdef __LITTLE_ENDIAN
  43#ifdef CONFIG_MACH_TX49XX
  44#define CCR_LE  TXX9_DMA_CCR_LE
  45#define MCR_LE  0
  46#else
  47#define CCR_LE  0
  48#define MCR_LE  TXX9_DMA_MCR_LE
  49#endif
  50#else
  51#define CCR_LE  0
  52#define MCR_LE  0
  53#endif
  54
  55/*
  56 * Redefine this macro to handle differences between 32- and 64-bit
  57 * addressing, big vs. little endian, etc.
  58 */
  59#ifdef __BIG_ENDIAN
  60#define TXX9_DMA_REG32(name)            u32 __pad_##name; u32 name
  61#else
  62#define TXX9_DMA_REG32(name)            u32 name; u32 __pad_##name
  63#endif
  64
  65/* Hardware register definitions. */
  66struct txx9dmac_cregs {
  67#if defined(CONFIG_32BIT) && !defined(CONFIG_PHYS_ADDR_T_64BIT)
  68        TXX9_DMA_REG32(CHAR);   /* Chain Address Register */
  69#else
  70        u64 CHAR;               /* Chain Address Register */
  71#endif
  72        u64 SAR;                /* Source Address Register */
  73        u64 DAR;                /* Destination Address Register */
  74        TXX9_DMA_REG32(CNTR);   /* Count Register */
  75        TXX9_DMA_REG32(SAIR);   /* Source Address Increment Register */
  76        TXX9_DMA_REG32(DAIR);   /* Destination Address Increment Register */
  77        TXX9_DMA_REG32(CCR);    /* Channel Control Register */
  78        TXX9_DMA_REG32(CSR);    /* Channel Status Register */
  79};
  80struct txx9dmac_cregs32 {
  81        u32 CHAR;
  82        u32 SAR;
  83        u32 DAR;
  84        u32 CNTR;
  85        u32 SAIR;
  86        u32 DAIR;
  87        u32 CCR;
  88        u32 CSR;
  89};
  90
  91struct txx9dmac_regs {
  92        /* per-channel registers */
  93        struct txx9dmac_cregs   CHAN[TXX9_DMA_MAX_NR_CHANNELS];
  94        u64     __pad[9];
  95        u64     MFDR;           /* Memory Fill Data Register */
  96        TXX9_DMA_REG32(MCR);    /* Master Control Register */
  97};
  98struct txx9dmac_regs32 {
  99        struct txx9dmac_cregs32 CHAN[TXX9_DMA_MAX_NR_CHANNELS];
 100        u32     __pad[9];
 101        u32     MFDR;
 102        u32     MCR;
 103};
 104
 105/* bits for MCR */
 106#define TXX9_DMA_MCR_EIS(ch)    (0x10000000<<(ch))
 107#define TXX9_DMA_MCR_DIS(ch)    (0x01000000<<(ch))
 108#define TXX9_DMA_MCR_RSFIF      0x00000080
 109#define TXX9_DMA_MCR_FIFUM(ch)  (0x00000008<<(ch))
 110#define TXX9_DMA_MCR_LE         0x00000004
 111#define TXX9_DMA_MCR_RPRT       0x00000002
 112#define TXX9_DMA_MCR_MSTEN      0x00000001
 113
 114/* bits for CCRn */
 115#define TXX9_DMA_CCR_IMMCHN     0x20000000
 116#define TXX9_DMA_CCR_USEXFSZ    0x10000000
 117#define TXX9_DMA_CCR_LE         0x08000000
 118#define TXX9_DMA_CCR_DBINH      0x04000000
 119#define TXX9_DMA_CCR_SBINH      0x02000000
 120#define TXX9_DMA_CCR_CHRST      0x01000000
 121#define TXX9_DMA_CCR_RVBYTE     0x00800000
 122#define TXX9_DMA_CCR_ACKPOL     0x00400000
 123#define TXX9_DMA_CCR_REQPL      0x00200000
 124#define TXX9_DMA_CCR_EGREQ      0x00100000
 125#define TXX9_DMA_CCR_CHDN       0x00080000
 126#define TXX9_DMA_CCR_DNCTL      0x00060000
 127#define TXX9_DMA_CCR_EXTRQ      0x00010000
 128#define TXX9_DMA_CCR_INTRQD     0x0000e000
 129#define TXX9_DMA_CCR_INTENE     0x00001000
 130#define TXX9_DMA_CCR_INTENC     0x00000800
 131#define TXX9_DMA_CCR_INTENT     0x00000400
 132#define TXX9_DMA_CCR_CHNEN      0x00000200
 133#define TXX9_DMA_CCR_XFACT      0x00000100
 134#define TXX9_DMA_CCR_SMPCHN     0x00000020
 135#define TXX9_DMA_CCR_XFSZ(order)        (((order) << 2) & 0x0000001c)
 136#define TXX9_DMA_CCR_XFSZ_1     TXX9_DMA_CCR_XFSZ(0)
 137#define TXX9_DMA_CCR_XFSZ_2     TXX9_DMA_CCR_XFSZ(1)
 138#define TXX9_DMA_CCR_XFSZ_4     TXX9_DMA_CCR_XFSZ(2)
 139#define TXX9_DMA_CCR_XFSZ_8     TXX9_DMA_CCR_XFSZ(3)
 140#define TXX9_DMA_CCR_XFSZ_X4    TXX9_DMA_CCR_XFSZ(4)
 141#define TXX9_DMA_CCR_XFSZ_X8    TXX9_DMA_CCR_XFSZ(5)
 142#define TXX9_DMA_CCR_XFSZ_X16   TXX9_DMA_CCR_XFSZ(6)
 143#define TXX9_DMA_CCR_XFSZ_X32   TXX9_DMA_CCR_XFSZ(7)
 144#define TXX9_DMA_CCR_MEMIO      0x00000002
 145#define TXX9_DMA_CCR_SNGAD      0x00000001
 146
 147/* bits for CSRn */
 148#define TXX9_DMA_CSR_CHNEN      0x00000400
 149#define TXX9_DMA_CSR_STLXFER    0x00000200
 150#define TXX9_DMA_CSR_XFACT      0x00000100
 151#define TXX9_DMA_CSR_ABCHC      0x00000080
 152#define TXX9_DMA_CSR_NCHNC      0x00000040
 153#define TXX9_DMA_CSR_NTRNFC     0x00000020
 154#define TXX9_DMA_CSR_EXTDN      0x00000010
 155#define TXX9_DMA_CSR_CFERR      0x00000008
 156#define TXX9_DMA_CSR_CHERR      0x00000004
 157#define TXX9_DMA_CSR_DESERR     0x00000002
 158#define TXX9_DMA_CSR_SORERR     0x00000001
 159
 160struct txx9dmac_chan {
 161        struct dma_chan         chan;
 162        struct dma_device       dma;
 163        struct txx9dmac_dev     *ddev;
 164        void __iomem            *ch_regs;
 165        struct tasklet_struct   tasklet;
 166        int                     irq;
 167        u32                     ccr;
 168
 169        spinlock_t              lock;
 170
 171        /* these other elements are all protected by lock */
 172        struct list_head        active_list;
 173        struct list_head        queue;
 174        struct list_head        free_list;
 175
 176        unsigned int            descs_allocated;
 177};
 178
 179struct txx9dmac_dev {
 180        void __iomem            *regs;
 181        struct tasklet_struct   tasklet;
 182        int                     irq;
 183        struct txx9dmac_chan    *chan[TXX9_DMA_MAX_NR_CHANNELS];
 184        bool                    have_64bit_regs;
 185        unsigned int            descsize;
 186};
 187
 188static inline bool __is_dmac64(const struct txx9dmac_dev *ddev)
 189{
 190        return ddev->have_64bit_regs;
 191}
 192
 193static inline bool is_dmac64(const struct txx9dmac_chan *dc)
 194{
 195        return __is_dmac64(dc->ddev);
 196}
 197
 198#ifdef TXX9_DMA_USE_SIMPLE_CHAIN
 199/* Hardware descriptor definition. (for simple-chain) */
 200struct txx9dmac_hwdesc {
 201#if defined(CONFIG_32BIT) && !defined(CONFIG_PHYS_ADDR_T_64BIT)
 202        TXX9_DMA_REG32(CHAR);
 203#else
 204        u64 CHAR;
 205#endif
 206        u64 SAR;
 207        u64 DAR;
 208        TXX9_DMA_REG32(CNTR);
 209};
 210struct txx9dmac_hwdesc32 {
 211        u32 CHAR;
 212        u32 SAR;
 213        u32 DAR;
 214        u32 CNTR;
 215};
 216#else
 217#define txx9dmac_hwdesc txx9dmac_cregs
 218#define txx9dmac_hwdesc32 txx9dmac_cregs32
 219#endif
 220
 221struct txx9dmac_desc {
 222        /* FIRST values the hardware uses */
 223        union {
 224                struct txx9dmac_hwdesc hwdesc;
 225                struct txx9dmac_hwdesc32 hwdesc32;
 226        };
 227
 228        /* THEN values for driver housekeeping */
 229        struct list_head                desc_node ____cacheline_aligned;
 230        struct list_head                tx_list;
 231        struct dma_async_tx_descriptor  txd;
 232        size_t                          len;
 233};
 234
 235#ifdef TXX9_DMA_USE_SIMPLE_CHAIN
 236
 237static inline bool txx9dmac_chan_INTENT(struct txx9dmac_chan *dc)
 238{
 239        return (dc->ccr & TXX9_DMA_CCR_INTENT) != 0;
 240}
 241
 242static inline void txx9dmac_chan_set_INTENT(struct txx9dmac_chan *dc)
 243{
 244        dc->ccr |= TXX9_DMA_CCR_INTENT;
 245}
 246
 247static inline void txx9dmac_desc_set_INTENT(struct txx9dmac_dev *ddev,
 248                                            struct txx9dmac_desc *desc)
 249{
 250}
 251
 252static inline void txx9dmac_chan_set_SMPCHN(struct txx9dmac_chan *dc)
 253{
 254        dc->ccr |= TXX9_DMA_CCR_SMPCHN;
 255}
 256
 257static inline void txx9dmac_desc_set_nosimple(struct txx9dmac_dev *ddev,
 258                                              struct txx9dmac_desc *desc,
 259                                              u32 sair, u32 dair, u32 ccr)
 260{
 261}
 262
 263#else /* TXX9_DMA_USE_SIMPLE_CHAIN */
 264
 265static inline bool txx9dmac_chan_INTENT(struct txx9dmac_chan *dc)
 266{
 267        return true;
 268}
 269
 270static void txx9dmac_chan_set_INTENT(struct txx9dmac_chan *dc)
 271{
 272}
 273
 274static inline void txx9dmac_desc_set_INTENT(struct txx9dmac_dev *ddev,
 275                                            struct txx9dmac_desc *desc)
 276{
 277        if (__is_dmac64(ddev))
 278                desc->hwdesc.CCR |= TXX9_DMA_CCR_INTENT;
 279        else
 280                desc->hwdesc32.CCR |= TXX9_DMA_CCR_INTENT;
 281}
 282
 283static inline void txx9dmac_chan_set_SMPCHN(struct txx9dmac_chan *dc)
 284{
 285}
 286
 287static inline void txx9dmac_desc_set_nosimple(struct txx9dmac_dev *ddev,
 288                                              struct txx9dmac_desc *desc,
 289                                              u32 sai, u32 dai, u32 ccr)
 290{
 291        if (__is_dmac64(ddev)) {
 292                desc->hwdesc.SAIR = sai;
 293                desc->hwdesc.DAIR = dai;
 294                desc->hwdesc.CCR = ccr;
 295        } else {
 296                desc->hwdesc32.SAIR = sai;
 297                desc->hwdesc32.DAIR = dai;
 298                desc->hwdesc32.CCR = ccr;
 299        }
 300}
 301
 302#endif /* TXX9_DMA_USE_SIMPLE_CHAIN */
 303
 304#endif /* TXX9DMAC_H */
 305