Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0-only */
0002 /*
0003  * Driver for the TXx9 SoC DMA Controller
0004  *
0005  * Copyright (C) 2009 Atsushi Nemoto
0006  */
0007 #ifndef TXX9DMAC_H
0008 #define TXX9DMAC_H
0009 
0010 #include <linux/dmaengine.h>
0011 #include <asm/txx9/dmac.h>
0012 
0013 /*
0014  * Design Notes:
0015  *
0016  * This DMAC have four channels and one FIFO buffer.  Each channel can
0017  * be configured for memory-memory or device-memory transfer, but only
0018  * one channel can do alignment-free memory-memory transfer at a time
0019  * while the channel should occupy the FIFO buffer for effective
0020  * transfers.
0021  *
0022  * Instead of dynamically assign the FIFO buffer to channels, I chose
0023  * make one dedicated channel for memory-memory transfer.  The
0024  * dedicated channel is public.  Other channels are private and used
0025  * for slave transfer.  Some devices in the SoC are wired to certain
0026  * DMA channel.
0027  */
0028 
0029 #ifdef CONFIG_MACH_TX49XX
0030 static inline bool txx9_dma_have_SMPCHN(void)
0031 {
0032     return true;
0033 }
0034 #define TXX9_DMA_USE_SIMPLE_CHAIN
0035 #else
0036 static inline bool txx9_dma_have_SMPCHN(void)
0037 {
0038     return false;
0039 }
0040 #endif
0041 
0042 #ifdef __LITTLE_ENDIAN
0043 #ifdef CONFIG_MACH_TX49XX
0044 #define CCR_LE  TXX9_DMA_CCR_LE
0045 #define MCR_LE  0
0046 #else
0047 #define CCR_LE  0
0048 #define MCR_LE  TXX9_DMA_MCR_LE
0049 #endif
0050 #else
0051 #define CCR_LE  0
0052 #define MCR_LE  0
0053 #endif
0054 
0055 /*
0056  * Redefine this macro to handle differences between 32- and 64-bit
0057  * addressing, big vs. little endian, etc.
0058  */
0059 #ifdef __BIG_ENDIAN
0060 #define TXX9_DMA_REG32(name)        u32 __pad_##name; u32 name
0061 #else
0062 #define TXX9_DMA_REG32(name)        u32 name; u32 __pad_##name
0063 #endif
0064 
0065 /* Hardware register definitions. */
0066 struct txx9dmac_cregs {
0067 #if defined(CONFIG_32BIT) && !defined(CONFIG_PHYS_ADDR_T_64BIT)
0068     TXX9_DMA_REG32(CHAR);   /* Chain Address Register */
0069 #else
0070     u64 CHAR;       /* Chain Address Register */
0071 #endif
0072     u64 SAR;        /* Source Address Register */
0073     u64 DAR;        /* Destination Address Register */
0074     TXX9_DMA_REG32(CNTR);   /* Count Register */
0075     TXX9_DMA_REG32(SAIR);   /* Source Address Increment Register */
0076     TXX9_DMA_REG32(DAIR);   /* Destination Address Increment Register */
0077     TXX9_DMA_REG32(CCR);    /* Channel Control Register */
0078     TXX9_DMA_REG32(CSR);    /* Channel Status Register */
0079 };
0080 struct txx9dmac_cregs32 {
0081     u32 CHAR;
0082     u32 SAR;
0083     u32 DAR;
0084     u32 CNTR;
0085     u32 SAIR;
0086     u32 DAIR;
0087     u32 CCR;
0088     u32 CSR;
0089 };
0090 
0091 struct txx9dmac_regs {
0092     /* per-channel registers */
0093     struct txx9dmac_cregs   CHAN[TXX9_DMA_MAX_NR_CHANNELS];
0094     u64 __pad[9];
0095     u64 MFDR;       /* Memory Fill Data Register */
0096     TXX9_DMA_REG32(MCR);    /* Master Control Register */
0097 };
0098 struct txx9dmac_regs32 {
0099     struct txx9dmac_cregs32 CHAN[TXX9_DMA_MAX_NR_CHANNELS];
0100     u32 __pad[9];
0101     u32 MFDR;
0102     u32 MCR;
0103 };
0104 
0105 /* bits for MCR */
0106 #define TXX9_DMA_MCR_EIS(ch)    (0x10000000<<(ch))
0107 #define TXX9_DMA_MCR_DIS(ch)    (0x01000000<<(ch))
0108 #define TXX9_DMA_MCR_RSFIF  0x00000080
0109 #define TXX9_DMA_MCR_FIFUM(ch)  (0x00000008<<(ch))
0110 #define TXX9_DMA_MCR_LE     0x00000004
0111 #define TXX9_DMA_MCR_RPRT   0x00000002
0112 #define TXX9_DMA_MCR_MSTEN  0x00000001
0113 
0114 /* bits for CCRn */
0115 #define TXX9_DMA_CCR_IMMCHN 0x20000000
0116 #define TXX9_DMA_CCR_USEXFSZ    0x10000000
0117 #define TXX9_DMA_CCR_LE     0x08000000
0118 #define TXX9_DMA_CCR_DBINH  0x04000000
0119 #define TXX9_DMA_CCR_SBINH  0x02000000
0120 #define TXX9_DMA_CCR_CHRST  0x01000000
0121 #define TXX9_DMA_CCR_RVBYTE 0x00800000
0122 #define TXX9_DMA_CCR_ACKPOL 0x00400000
0123 #define TXX9_DMA_CCR_REQPL  0x00200000
0124 #define TXX9_DMA_CCR_EGREQ  0x00100000
0125 #define TXX9_DMA_CCR_CHDN   0x00080000
0126 #define TXX9_DMA_CCR_DNCTL  0x00060000
0127 #define TXX9_DMA_CCR_EXTRQ  0x00010000
0128 #define TXX9_DMA_CCR_INTRQD 0x0000e000
0129 #define TXX9_DMA_CCR_INTENE 0x00001000
0130 #define TXX9_DMA_CCR_INTENC 0x00000800
0131 #define TXX9_DMA_CCR_INTENT 0x00000400
0132 #define TXX9_DMA_CCR_CHNEN  0x00000200
0133 #define TXX9_DMA_CCR_XFACT  0x00000100
0134 #define TXX9_DMA_CCR_SMPCHN 0x00000020
0135 #define TXX9_DMA_CCR_XFSZ(order)    (((order) << 2) & 0x0000001c)
0136 #define TXX9_DMA_CCR_XFSZ_1 TXX9_DMA_CCR_XFSZ(0)
0137 #define TXX9_DMA_CCR_XFSZ_2 TXX9_DMA_CCR_XFSZ(1)
0138 #define TXX9_DMA_CCR_XFSZ_4 TXX9_DMA_CCR_XFSZ(2)
0139 #define TXX9_DMA_CCR_XFSZ_8 TXX9_DMA_CCR_XFSZ(3)
0140 #define TXX9_DMA_CCR_XFSZ_X4    TXX9_DMA_CCR_XFSZ(4)
0141 #define TXX9_DMA_CCR_XFSZ_X8    TXX9_DMA_CCR_XFSZ(5)
0142 #define TXX9_DMA_CCR_XFSZ_X16   TXX9_DMA_CCR_XFSZ(6)
0143 #define TXX9_DMA_CCR_XFSZ_X32   TXX9_DMA_CCR_XFSZ(7)
0144 #define TXX9_DMA_CCR_MEMIO  0x00000002
0145 #define TXX9_DMA_CCR_SNGAD  0x00000001
0146 
0147 /* bits for CSRn */
0148 #define TXX9_DMA_CSR_CHNEN  0x00000400
0149 #define TXX9_DMA_CSR_STLXFER    0x00000200
0150 #define TXX9_DMA_CSR_XFACT  0x00000100
0151 #define TXX9_DMA_CSR_ABCHC  0x00000080
0152 #define TXX9_DMA_CSR_NCHNC  0x00000040
0153 #define TXX9_DMA_CSR_NTRNFC 0x00000020
0154 #define TXX9_DMA_CSR_EXTDN  0x00000010
0155 #define TXX9_DMA_CSR_CFERR  0x00000008
0156 #define TXX9_DMA_CSR_CHERR  0x00000004
0157 #define TXX9_DMA_CSR_DESERR 0x00000002
0158 #define TXX9_DMA_CSR_SORERR 0x00000001
0159 
0160 struct txx9dmac_chan {
0161     struct dma_chan     chan;
0162     struct dma_device   dma;
0163     struct txx9dmac_dev *ddev;
0164     void __iomem        *ch_regs;
0165     struct tasklet_struct   tasklet;
0166     int         irq;
0167     u32         ccr;
0168 
0169     spinlock_t      lock;
0170 
0171     /* these other elements are all protected by lock */
0172     struct list_head    active_list;
0173     struct list_head    queue;
0174     struct list_head    free_list;
0175 
0176     unsigned int        descs_allocated;
0177 };
0178 
0179 struct txx9dmac_dev {
0180     void __iomem        *regs;
0181     struct tasklet_struct   tasklet;
0182     int         irq;
0183     struct txx9dmac_chan    *chan[TXX9_DMA_MAX_NR_CHANNELS];
0184     bool            have_64bit_regs;
0185     unsigned int        descsize;
0186 };
0187 
0188 static inline bool __is_dmac64(const struct txx9dmac_dev *ddev)
0189 {
0190     return ddev->have_64bit_regs;
0191 }
0192 
0193 static inline bool is_dmac64(const struct txx9dmac_chan *dc)
0194 {
0195     return __is_dmac64(dc->ddev);
0196 }
0197 
0198 #ifdef TXX9_DMA_USE_SIMPLE_CHAIN
0199 /* Hardware descriptor definition. (for simple-chain) */
0200 struct txx9dmac_hwdesc {
0201 #if defined(CONFIG_32BIT) && !defined(CONFIG_PHYS_ADDR_T_64BIT)
0202     TXX9_DMA_REG32(CHAR);
0203 #else
0204     u64 CHAR;
0205 #endif
0206     u64 SAR;
0207     u64 DAR;
0208     TXX9_DMA_REG32(CNTR);
0209 };
0210 struct txx9dmac_hwdesc32 {
0211     u32 CHAR;
0212     u32 SAR;
0213     u32 DAR;
0214     u32 CNTR;
0215 };
0216 #else
0217 #define txx9dmac_hwdesc txx9dmac_cregs
0218 #define txx9dmac_hwdesc32 txx9dmac_cregs32
0219 #endif
0220 
0221 struct txx9dmac_desc {
0222     /* FIRST values the hardware uses */
0223     union {
0224         struct txx9dmac_hwdesc hwdesc;
0225         struct txx9dmac_hwdesc32 hwdesc32;
0226     };
0227 
0228     /* THEN values for driver housekeeping */
0229     struct list_head        desc_node ____cacheline_aligned;
0230     struct list_head        tx_list;
0231     struct dma_async_tx_descriptor  txd;
0232     size_t              len;
0233 };
0234 
0235 #ifdef TXX9_DMA_USE_SIMPLE_CHAIN
0236 
0237 static inline bool txx9dmac_chan_INTENT(struct txx9dmac_chan *dc)
0238 {
0239     return (dc->ccr & TXX9_DMA_CCR_INTENT) != 0;
0240 }
0241 
0242 static inline void txx9dmac_chan_set_INTENT(struct txx9dmac_chan *dc)
0243 {
0244     dc->ccr |= TXX9_DMA_CCR_INTENT;
0245 }
0246 
0247 static inline void txx9dmac_desc_set_INTENT(struct txx9dmac_dev *ddev,
0248                         struct txx9dmac_desc *desc)
0249 {
0250 }
0251 
0252 static inline void txx9dmac_chan_set_SMPCHN(struct txx9dmac_chan *dc)
0253 {
0254     dc->ccr |= TXX9_DMA_CCR_SMPCHN;
0255 }
0256 
0257 static inline void txx9dmac_desc_set_nosimple(struct txx9dmac_dev *ddev,
0258                           struct txx9dmac_desc *desc,
0259                           u32 sair, u32 dair, u32 ccr)
0260 {
0261 }
0262 
0263 #else /* TXX9_DMA_USE_SIMPLE_CHAIN */
0264 
0265 static inline bool txx9dmac_chan_INTENT(struct txx9dmac_chan *dc)
0266 {
0267     return true;
0268 }
0269 
0270 static void txx9dmac_chan_set_INTENT(struct txx9dmac_chan *dc)
0271 {
0272 }
0273 
0274 static inline void txx9dmac_desc_set_INTENT(struct txx9dmac_dev *ddev,
0275                         struct txx9dmac_desc *desc)
0276 {
0277     if (__is_dmac64(ddev))
0278         desc->hwdesc.CCR |= TXX9_DMA_CCR_INTENT;
0279     else
0280         desc->hwdesc32.CCR |= TXX9_DMA_CCR_INTENT;
0281 }
0282 
0283 static inline void txx9dmac_chan_set_SMPCHN(struct txx9dmac_chan *dc)
0284 {
0285 }
0286 
0287 static inline void txx9dmac_desc_set_nosimple(struct txx9dmac_dev *ddev,
0288                           struct txx9dmac_desc *desc,
0289                           u32 sai, u32 dai, u32 ccr)
0290 {
0291     if (__is_dmac64(ddev)) {
0292         desc->hwdesc.SAIR = sai;
0293         desc->hwdesc.DAIR = dai;
0294         desc->hwdesc.CCR = ccr;
0295     } else {
0296         desc->hwdesc32.SAIR = sai;
0297         desc->hwdesc32.DAIR = dai;
0298         desc->hwdesc32.CCR = ccr;
0299     }
0300 }
0301 
0302 #endif /* TXX9_DMA_USE_SIMPLE_CHAIN */
0303 
0304 #endif /* TXX9DMAC_H */