]> asedeno.scripts.mit.edu Git - linux.git/blobdiff - drivers/net/ethernet/ti/davinci_cpdma.c
net: ethernet: ti: davinci_cpdma: fix fixed prio cpdma ctlr configuration
[linux.git] / drivers / net / ethernet / ti / davinci_cpdma.c
index 8f7b42053bbbe77296f622f84199529ce28861e2..56395cefb92632654fe8591f903921234b3bd56b 100644 (file)
@@ -124,6 +124,29 @@ struct cpdma_chan {
        int     int_set, int_clear, td;
 };
 
+struct cpdma_control_info {
+       u32             reg;
+       u32             shift, mask;
+       int             access;
+#define ACCESS_RO      BIT(0)
+#define ACCESS_WO      BIT(1)
+#define ACCESS_RW      (ACCESS_RO | ACCESS_WO)
+};
+
+static struct cpdma_control_info controls[] = {
+       [CPDMA_CMD_IDLE]          = {CPDMA_DMACONTROL,  3,  1,      ACCESS_WO},
+       [CPDMA_COPY_ERROR_FRAMES] = {CPDMA_DMACONTROL,  4,  1,      ACCESS_RW},
+       [CPDMA_RX_OFF_LEN_UPDATE] = {CPDMA_DMACONTROL,  2,  1,      ACCESS_RW},
+       [CPDMA_RX_OWNERSHIP_FLIP] = {CPDMA_DMACONTROL,  1,  1,      ACCESS_RW},
+       [CPDMA_TX_PRIO_FIXED]     = {CPDMA_DMACONTROL,  0,  1,      ACCESS_RW},
+       [CPDMA_STAT_IDLE]         = {CPDMA_DMASTATUS,   31, 1,      ACCESS_RO},
+       [CPDMA_STAT_TX_ERR_CODE]  = {CPDMA_DMASTATUS,   20, 0xf,    ACCESS_RW},
+       [CPDMA_STAT_TX_ERR_CHAN]  = {CPDMA_DMASTATUS,   16, 0x7,    ACCESS_RW},
+       [CPDMA_STAT_RX_ERR_CODE]  = {CPDMA_DMASTATUS,   12, 0xf,    ACCESS_RW},
+       [CPDMA_STAT_RX_ERR_CHAN]  = {CPDMA_DMASTATUS,   8,  0x7,    ACCESS_RW},
+       [CPDMA_RX_BUFFER_OFFSET]  = {CPDMA_RXBUFFOFS,   0,  0xffff, ACCESS_RW},
+};
+
 #define tx_chan_num(chan)      (chan)
 #define rx_chan_num(chan)      ((chan) + CPDMA_MAX_CHANNELS)
 #define is_rx_chan(chan)       ((chan)->chan_num >= CPDMA_MAX_CHANNELS)
@@ -253,6 +276,31 @@ static void cpdma_desc_free(struct cpdma_desc_pool *pool,
        gen_pool_free(pool->gen_pool, (unsigned long)desc, pool->desc_size);
 }
 
+static int _cpdma_control_set(struct cpdma_ctlr *ctlr, int control, int value)
+{
+       struct cpdma_control_info *info = &controls[control];
+       u32 val;
+
+       if (!ctlr->params.has_ext_regs)
+               return -ENOTSUPP;
+
+       if (ctlr->state != CPDMA_STATE_ACTIVE)
+               return -EINVAL;
+
+       if (control < 0 || control >= ARRAY_SIZE(controls))
+               return -ENOENT;
+
+       if ((info->access & ACCESS_WO) != ACCESS_WO)
+               return -EPERM;
+
+       val  = dma_reg_read(ctlr, info->reg);
+       val &= ~(info->mask << info->shift);
+       val |= (value & info->mask) << info->shift;
+       dma_reg_write(ctlr, info->reg, val);
+
+       return 0;
+}
+
 struct cpdma_ctlr *cpdma_ctlr_create(struct cpdma_params *params)
 {
        struct cpdma_ctlr *ctlr;
@@ -324,6 +372,10 @@ int cpdma_ctlr_start(struct cpdma_ctlr *ctlr)
                if (ctlr->channels[i])
                        cpdma_chan_start(ctlr->channels[i]);
        }
+
+       _cpdma_control_set(ctlr, CPDMA_TX_PRIO_FIXED, 1);
+       _cpdma_control_set(ctlr, CPDMA_RX_BUFFER_OFFSET, 0);
+
        spin_unlock_irqrestore(&ctlr->lock, flags);
        return 0;
 }
@@ -874,29 +926,6 @@ int cpdma_chan_int_ctrl(struct cpdma_chan *chan, bool enable)
        return 0;
 }
 
-struct cpdma_control_info {
-       u32             reg;
-       u32             shift, mask;
-       int             access;
-#define ACCESS_RO      BIT(0)
-#define ACCESS_WO      BIT(1)
-#define ACCESS_RW      (ACCESS_RO | ACCESS_WO)
-};
-
-static struct cpdma_control_info controls[] = {
-       [CPDMA_CMD_IDLE]          = {CPDMA_DMACONTROL,  3,  1,      ACCESS_WO},
-       [CPDMA_COPY_ERROR_FRAMES] = {CPDMA_DMACONTROL,  4,  1,      ACCESS_RW},
-       [CPDMA_RX_OFF_LEN_UPDATE] = {CPDMA_DMACONTROL,  2,  1,      ACCESS_RW},
-       [CPDMA_RX_OWNERSHIP_FLIP] = {CPDMA_DMACONTROL,  1,  1,      ACCESS_RW},
-       [CPDMA_TX_PRIO_FIXED]     = {CPDMA_DMACONTROL,  0,  1,      ACCESS_RW},
-       [CPDMA_STAT_IDLE]         = {CPDMA_DMASTATUS,   31, 1,      ACCESS_RO},
-       [CPDMA_STAT_TX_ERR_CODE]  = {CPDMA_DMASTATUS,   20, 0xf,    ACCESS_RW},
-       [CPDMA_STAT_TX_ERR_CHAN]  = {CPDMA_DMASTATUS,   16, 0x7,    ACCESS_RW},
-       [CPDMA_STAT_RX_ERR_CODE]  = {CPDMA_DMASTATUS,   12, 0xf,    ACCESS_RW},
-       [CPDMA_STAT_RX_ERR_CHAN]  = {CPDMA_DMASTATUS,   8,  0x7,    ACCESS_RW},
-       [CPDMA_RX_BUFFER_OFFSET]  = {CPDMA_RXBUFFOFS,   0,  0xffff, ACCESS_RW},
-};
-
 int cpdma_control_get(struct cpdma_ctlr *ctlr, int control)
 {
        unsigned long flags;
@@ -931,35 +960,10 @@ int cpdma_control_get(struct cpdma_ctlr *ctlr, int control)
 int cpdma_control_set(struct cpdma_ctlr *ctlr, int control, int value)
 {
        unsigned long flags;
-       struct cpdma_control_info *info = &controls[control];
        int ret;
-       u32 val;
 
        spin_lock_irqsave(&ctlr->lock, flags);
-
-       ret = -ENOTSUPP;
-       if (!ctlr->params.has_ext_regs)
-               goto unlock_ret;
-
-       ret = -EINVAL;
-       if (ctlr->state != CPDMA_STATE_ACTIVE)
-               goto unlock_ret;
-
-       ret = -ENOENT;
-       if (control < 0 || control >= ARRAY_SIZE(controls))
-               goto unlock_ret;
-
-       ret = -EPERM;
-       if ((info->access & ACCESS_WO) != ACCESS_WO)
-               goto unlock_ret;
-
-       val  = dma_reg_read(ctlr, info->reg);
-       val &= ~(info->mask << info->shift);
-       val |= (value & info->mask) << info->shift;
-       dma_reg_write(ctlr, info->reg, val);
-       ret = 0;
-
-unlock_ret:
+       ret = _cpdma_control_set(ctlr, control, value);
        spin_unlock_irqrestore(&ctlr->lock, flags);
        return ret;
 }