linux/drivers/dma/dw/idma32.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2// Copyright (C) 2013,2018 Intel Corporation
   3
   4#include <linux/bitops.h>
   5#include <linux/dmaengine.h>
   6#include <linux/errno.h>
   7#include <linux/slab.h>
   8#include <linux/types.h>
   9
  10#include "internal.h"
  11
  12static void idma32_initialize_chan(struct dw_dma_chan *dwc)
  13{
  14        u32 cfghi = 0;
  15        u32 cfglo = 0;
  16
  17        /* Set default burst alignment */
  18        cfglo |= IDMA32C_CFGL_DST_BURST_ALIGN | IDMA32C_CFGL_SRC_BURST_ALIGN;
  19
  20        /* Low 4 bits of the request lines */
  21        cfghi |= IDMA32C_CFGH_DST_PER(dwc->dws.dst_id & 0xf);
  22        cfghi |= IDMA32C_CFGH_SRC_PER(dwc->dws.src_id & 0xf);
  23
  24        /* Request line extension (2 bits) */
  25        cfghi |= IDMA32C_CFGH_DST_PER_EXT(dwc->dws.dst_id >> 4 & 0x3);
  26        cfghi |= IDMA32C_CFGH_SRC_PER_EXT(dwc->dws.src_id >> 4 & 0x3);
  27
  28        channel_writel(dwc, CFG_LO, cfglo);
  29        channel_writel(dwc, CFG_HI, cfghi);
  30}
  31
  32static void idma32_suspend_chan(struct dw_dma_chan *dwc, bool drain)
  33{
  34        u32 cfglo = channel_readl(dwc, CFG_LO);
  35
  36        if (drain)
  37                cfglo |= IDMA32C_CFGL_CH_DRAIN;
  38
  39        channel_writel(dwc, CFG_LO, cfglo | DWC_CFGL_CH_SUSP);
  40}
  41
  42static void idma32_resume_chan(struct dw_dma_chan *dwc, bool drain)
  43{
  44        u32 cfglo = channel_readl(dwc, CFG_LO);
  45
  46        if (drain)
  47                cfglo &= ~IDMA32C_CFGL_CH_DRAIN;
  48
  49        channel_writel(dwc, CFG_LO, cfglo & ~DWC_CFGL_CH_SUSP);
  50}
  51
  52static u32 idma32_bytes2block(struct dw_dma_chan *dwc,
  53                              size_t bytes, unsigned int width, size_t *len)
  54{
  55        u32 block;
  56
  57        if (bytes > dwc->block_size) {
  58                block = dwc->block_size;
  59                *len = dwc->block_size;
  60        } else {
  61                block = bytes;
  62                *len = bytes;
  63        }
  64
  65        return block;
  66}
  67
  68static size_t idma32_block2bytes(struct dw_dma_chan *dwc, u32 block, u32 width)
  69{
  70        return IDMA32C_CTLH_BLOCK_TS(block);
  71}
  72
  73static u32 idma32_prepare_ctllo(struct dw_dma_chan *dwc)
  74{
  75        struct dma_slave_config *sconfig = &dwc->dma_sconfig;
  76        bool is_slave = is_slave_direction(dwc->direction);
  77        u8 smsize = is_slave ? sconfig->src_maxburst : IDMA32_MSIZE_8;
  78        u8 dmsize = is_slave ? sconfig->dst_maxburst : IDMA32_MSIZE_8;
  79
  80        return DWC_CTLL_LLP_D_EN | DWC_CTLL_LLP_S_EN |
  81               DWC_CTLL_DST_MSIZE(dmsize) | DWC_CTLL_SRC_MSIZE(smsize);
  82}
  83
  84static void idma32_encode_maxburst(struct dw_dma_chan *dwc, u32 *maxburst)
  85{
  86        *maxburst = *maxburst > 1 ? fls(*maxburst) - 1 : 0;
  87}
  88
  89static void idma32_set_device_name(struct dw_dma *dw, int id)
  90{
  91        snprintf(dw->name, sizeof(dw->name), "idma32:dmac%d", id);
  92}
  93
  94/*
  95 * Program FIFO size of channels.
  96 *
  97 * By default full FIFO (512 bytes) is assigned to channel 0. Here we
  98 * slice FIFO on equal parts between channels.
  99 */
 100static void idma32_fifo_partition(struct dw_dma *dw)
 101{
 102        u64 value = IDMA32C_FP_PSIZE_CH0(64) | IDMA32C_FP_PSIZE_CH1(64) |
 103                    IDMA32C_FP_UPDATE;
 104        u64 fifo_partition = 0;
 105
 106        /* Fill FIFO_PARTITION low bits (Channels 0..1, 4..5) */
 107        fifo_partition |= value << 0;
 108
 109        /* Fill FIFO_PARTITION high bits (Channels 2..3, 6..7) */
 110        fifo_partition |= value << 32;
 111
 112        /* Program FIFO Partition registers - 64 bytes per channel */
 113        idma32_writeq(dw, FIFO_PARTITION1, fifo_partition);
 114        idma32_writeq(dw, FIFO_PARTITION0, fifo_partition);
 115}
 116
 117static void idma32_disable(struct dw_dma *dw)
 118{
 119        do_dw_dma_off(dw);
 120        idma32_fifo_partition(dw);
 121}
 122
 123static void idma32_enable(struct dw_dma *dw)
 124{
 125        idma32_fifo_partition(dw);
 126        do_dw_dma_on(dw);
 127}
 128
 129int idma32_dma_probe(struct dw_dma_chip *chip)
 130{
 131        struct dw_dma *dw;
 132
 133        dw = devm_kzalloc(chip->dev, sizeof(*dw), GFP_KERNEL);
 134        if (!dw)
 135                return -ENOMEM;
 136
 137        /* Channel operations */
 138        dw->initialize_chan = idma32_initialize_chan;
 139        dw->suspend_chan = idma32_suspend_chan;
 140        dw->resume_chan = idma32_resume_chan;
 141        dw->prepare_ctllo = idma32_prepare_ctllo;
 142        dw->encode_maxburst = idma32_encode_maxburst;
 143        dw->bytes2block = idma32_bytes2block;
 144        dw->block2bytes = idma32_block2bytes;
 145
 146        /* Device operations */
 147        dw->set_device_name = idma32_set_device_name;
 148        dw->disable = idma32_disable;
 149        dw->enable = idma32_enable;
 150
 151        chip->dw = dw;
 152        return do_dma_probe(chip);
 153}
 154EXPORT_SYMBOL_GPL(idma32_dma_probe);
 155
 156int idma32_dma_remove(struct dw_dma_chip *chip)
 157{
 158        return do_dma_remove(chip);
 159}
 160EXPORT_SYMBOL_GPL(idma32_dma_remove);
 161