22 Jul, 2019

3 commits

  • When building with 'make C=1', sparse reports an endianess bug:

    drivers/dma/dw-edma/dw-edma-v0-debugfs.c:60:30: warning: cast removes address space of expression
    drivers/dma/dw-edma/dw-edma-v0-debugfs.c:86:24: warning: incorrect type in argument 1 (different address spaces)
    drivers/dma/dw-edma/dw-edma-v0-debugfs.c:86:24: expected void const volatile [noderef] *addr
    drivers/dma/dw-edma/dw-edma-v0-debugfs.c:86:24: got void *[assigned] ptr
    drivers/dma/dw-edma/dw-edma-v0-debugfs.c:86:24: warning: incorrect type in argument 1 (different address spaces)
    drivers/dma/dw-edma/dw-edma-v0-debugfs.c:86:24: expected void const volatile [noderef] *addr
    drivers/dma/dw-edma/dw-edma-v0-debugfs.c:86:24: got void *[assigned] ptr
    drivers/dma/dw-edma/dw-edma-v0-debugfs.c:86:24: warning: incorrect type in argument 1 (different address spaces)
    drivers/dma/dw-edma/dw-edma-v0-debugfs.c:86:24: expected void const volatile [noderef] *addr
    drivers/dma/dw-edma/dw-edma-v0-debugfs.c:86:24: got void *[assigned] ptr

    The current code is clearly wrong, as it passes an endian-swapped word
    into a register function where it gets swapped again. Just pass the variables
    directly into lower_32_bits()/upper_32_bits().

    Fixes: 7e4b8a4fbe2c ("dmaengine: Add Synopsys eDMA IP version 0 support")
    Link: https://lore.kernel.org/lkml/20190617131820.2470686-1-arnd@arndb.de/
    Signed-off-by: Arnd Bergmann
    Acked-by: Gustavo Pimentel
    Link: https://lore.kernel.org/r/20190722124457.1093886-3-arnd@arndb.de
    Signed-off-by: Vinod Koul

    Arnd Bergmann
     
  • The new driver mixes up dma_addr_t and __iomem pointers, which results
    in warnings on some 32-bit architectures, like:

    drivers/dma/dw-edma/dw-edma-v0-core.c: In function '__dw_regs':
    drivers/dma/dw-edma/dw-edma-v0-core.c:28:9: error: cast to pointer from integer of different size [-Werror=int-to-pointer-cast]
    return (struct dw_edma_v0_regs __iomem *)dw->rg_region.vaddr;

    Make it use __iomem pointers consistently here, and avoid using dma_addr_t
    for __iomem tokens altogether.

    A small complication here is the debugfs code, which passes an __iomem
    token as the private data for debugfs files, requiring the use of
    extra __force.

    Fixes: 7e4b8a4fbe2c ("dmaengine: Add Synopsys eDMA IP version 0 support")
    Link: https://lore.kernel.org/lkml/20190617131918.2518727-1-arnd@arndb.de/
    Signed-off-by: Arnd Bergmann
    Link: https://lore.kernel.org/r/20190722124457.1093886-2-arnd@arndb.de
    Signed-off-by: Vinod Koul

    Arnd Bergmann
     
  • Putting large constant data on the stack causes unnecessary overhead
    and stack usage:

    drivers/dma/dw-edma/dw-edma-v0-debugfs.c:285:6: error: stack frame size of 1376 bytes in function 'dw_edma_v0_debugfs_on' [-Werror,-Wframe-larger-than=]

    Mark the variable 'static const' in order for the compiler to move it
    into the .rodata section where it does no such harm.

    Fixes: 305aebeff879 ("dmaengine: Add Synopsys eDMA IP version 0 debugfs support")
    Signed-off-by: Arnd Bergmann
    Acked-by: Gustavo Pimentel
    Link: https://lore.kernel.org/r/20190722124457.1093886-1-arnd@arndb.de
    Signed-off-by: Vinod Koul

    Arnd Bergmann
     

25 Jun, 2019

1 commit

  • drivers/dma/dw-edma/dw-edma-core.c:617:2-3: Unneeded semicolon

    Remove unneeded semicolon.

    Generated by: scripts/coccinelle/misc/semicolon.cocci

    Fixes: e63d79d1ffcd ("dmaengine: Add Synopsys eDMA IP core driver")
    CC: Gustavo Pimentel
    Signed-off-by: kbuild test robot
    Acked-by: Gustavo Pimentel
    Signed-off-by: Vinod Koul

    kbuild test robot
     

12 Jun, 2019

1 commit

  • If CONFIG_PCI_MSI is not set, building with CONFIG_DW_EDMA
    fails:

    drivers/dma/dw-edma/dw-edma-core.c: In function dw_edma_irq_request:
    drivers/dma/dw-edma/dw-edma-core.c:784:21: error: implicit declaration of function pci_irq_vector; did you mean rcu_irq_enter? [-Werror=implicit-function-declaration]
    err = request_irq(pci_irq_vector(to_pci_dev(dev), 0),
    ^~~~~~~~~~~~~~

    Reported-by: Hulk Robot
    Fixes: e63d79d1ffcd ("dmaengine: Add Synopsys eDMA IP core driver")
    Signed-off-by: YueHaibing
    Reported-by: Randy Dunlap
    Signed-off-by: Vinod Koul

    YueHaibing
     

10 Jun, 2019

4 commits

  • Synopsys eDMA IP is normally distributed along with Synopsys PCIe
    EndPoint IP (depends of the use and licensing agreement).

    This IP requires some basic configurations, such as:
    - eDMA registers BAR
    - eDMA registers offset
    - eDMA registers size
    - eDMA linked list memory BAR
    - eDMA linked list memory offset
    - eDMA linked list memory size
    - eDMA data memory BAR
    - eDMA data memory offset
    - eDMA data memory size
    - eDMA version
    - eDMA mode
    - IRQs available for eDMA

    As a working example, PCIe glue-logic will attach to a Synopsys PCIe
    EndPoint IP prototype kit (Vendor ID = 0x16c3, Device ID = 0xedda),
    which has built-in an eDMA IP with this default configuration:
    - eDMA registers BAR = 0
    - eDMA registers offset = 0x00001000 (4 Kbytes)
    - eDMA registers size = 0x00002000 (8 Kbytes)
    - eDMA linked list memory BAR = 2
    - eDMA linked list memory offset = 0x00000000 (0 Kbytes)
    - eDMA linked list memory size = 0x00800000 (8 Mbytes)
    - eDMA data memory BAR = 2
    - eDMA data memory offset = 0x00800000 (8 Mbytes)
    - eDMA data memory size = 0x03800000 (56 Mbytes)
    - eDMA version = 0
    - eDMA mode = EDMA_MODE_UNROLL
    - IRQs = 1

    This driver can be compile as built-in or external module in kernel.

    To enable this driver just select DW_EDMA_PCIE option in kernel
    configuration, however it requires and selects automatically DW_EDMA
    option too.

    Signed-off-by: Gustavo Pimentel
    Cc: Vinod Koul
    Cc: Dan Williams
    Cc: Russell King
    Cc: Lorenzo Pieralisi
    Cc: Joao Pinto
    Signed-off-by: Gustavo Pimentel
    Signed-off-by: Vinod Koul

    Gustavo Pimentel
     
  • Add Synopsys eDMA IP version 0 debugfs support to assist any debug
    in the future.

    Creates a file system structure composed by folders and files that mimic
    the IP register map (this files are read only) to ease any debug.

    To enable this feature is necessary to select DEBUG_FS option on kernel
    configuration.

    Small output example:

    (eDMA IP version 0, unroll, 1 write + 1 read channels)

    % mount -t debugfs none /sys/kernel/debug/
    % tree /sys/kernel/debug/dw-edma-core:0/
    dw-edma/
    ├── version
    ├── mode
    ├── wr_ch_cnt
    ├── rd_ch_cnt
    └── registers
        ├── ctrl_data_arb_prior
        ├── ctrl
        ├── write
        │   ├── engine_en
        │   ├── doorbell
        │   ├── ch_arb_weight_low
        │   ├── ch_arb_weight_high
        │   ├── int_status
        │   ├── int_mask
        │   ├── int_clear
        │   ├── err_status
        │   ├── done_imwr_low
        │   ├── done_imwr_high
        │   ├── abort_imwr_low
        │   ├── abort_imwr_high
        │   ├── ch01_imwr_data
        │   ├── ch23_imwr_data
        │   ├── ch45_imwr_data
        │   ├── ch67_imwr_data
        │   ├── linked_list_err_en
        │   ├── engine_chgroup
        │   ├── engine_hshake_cnt_low
        │   ├── engine_hshake_cnt_high
        │   ├── ch0_pwr_en
        │   ├── ch1_pwr_en
        │   ├── ch2_pwr_en
        │   ├── ch3_pwr_en
        │   ├── ch4_pwr_en
        │   ├── ch5_pwr_en
        │   ├── ch6_pwr_en
        │   ├── ch7_pwr_en
        │   └── channel:0
        │       ├── ch_control1
        │       ├── ch_control2
        │       ├── transfer_size
        │       ├── sar_low
        │       ├── sar_high
        │       ├── dar_high
        │       ├── llp_low
        │       └── llp_high
        └── read
            ├── engine_en
            ├── doorbell
            ├── ch_arb_weight_low
            ├── ch_arb_weight_high
            ├── int_status
            ├── int_mask
            ├── int_clear
            ├── err_status_low
            ├── err_status_high
            ├── done_imwr_low
            ├── done_imwr_high
            ├── abort_imwr_low
            ├── abort_imwr_high
            ├── ch01_imwr_data
            ├── ch23_imwr_data
            ├── ch45_imwr_data
            ├── ch67_imwr_data
            ├── linked_list_err_en
            ├── engine_chgroup
            ├── engine_hshake_cnt_low
            ├── engine_hshake_cnt_high
            ├── ch0_pwr_en
            ├── ch1_pwr_en
            ├── ch2_pwr_en
            ├── ch3_pwr_en
            ├── ch4_pwr_en
            ├── ch5_pwr_en
            ├── ch6_pwr_en
            ├── ch7_pwr_en
            └── channel:0
                ├── ch_control1
                ├── ch_control2
                ├── transfer_size
                ├── sar_low
                ├── sar_high
                ├── dar_high
                ├── llp_low
                └── llp_high

    Signed-off-by: Gustavo Pimentel
    Cc: Vinod Koul
    Cc: Dan Williams
    Cc: Andy Shevchenko
    Cc: Russell King
    Cc: Joao Pinto
    Signed-off-by: Vinod Koul

    Gustavo Pimentel
     
  • Add support for the eDMA IP version 0 driver for both register maps (legacy
    and unroll).

    The legacy register mapping was the initial implementation, which consisted
    in having all registers belonging to channels multiplexed, which could be
    change anytime (which could led a race-condition) by view port register
    (access to only one channel available each time).

    This register mapping is not very effective and efficient in a multithread
    environment, which has led to the development of unroll registers mapping,
    which consists of having all channels registers accessible any time by
    spreading all channels registers by an offset between them.

    This version supports a maximum of 16 independent channels (8 write +
    8 read), which can run simultaneously.

    Implements a scatter-gather transfer through a linked list, where the size
    of linked list depends on the allocated memory divided equally among all
    channels.

    Each linked list descriptor can transfer from 1 byte to 4 Gbytes and is
    alignmented to DWORD.

    Both SAR (Source Address Register) and DAR (Destination Address Register)
    are alignmented to byte.

    Signed-off-by: Gustavo Pimentel
    Cc: Vinod Koul
    Cc: Dan Williams
    Cc: Andy Shevchenko
    Cc: Russell King
    Cc: Joao Pinto
    Signed-off-by: Vinod Koul

    Gustavo Pimentel
     
  • Add Synopsys PCIe Endpoint eDMA IP core driver to kernel.

    This IP is generally distributed with Synopsys PCIe Endpoint IP (depends
    of the use and licensing agreement).

    This core driver, initializes and configures the eDMA IP using vma-helpers
    functions and dma-engine subsystem.

    This driver can be compile as built-in or external module in kernel.

    To enable this driver just select DW_EDMA option in kernel configuration,
    however it requires and selects automatically DMA_ENGINE and
    DMA_VIRTUAL_CHANNELS option too.

    In order to transfer data from point A to B as fast as possible this IP
    requires a dedicated memory space containing linked list of elements.

    All elements of this linked list are continuous and each one describes a
    data transfer (source and destination addresses, length and a control
    variable).

    For the sake of simplicity, lets assume a memory space for channel write
    0 which allows about 42 elements.

    +---------+
    | Desc #0 |-+
    +---------+ |
    V
    +----------+
    | Chunk #0 |-+
    | CB = 1 | | +----------+ +-----+ +-----------+ +-----+
    +----------+ +->| Burst #0 |->| ... |->| Burst #41 |->| llp |
    | +----------+ +-----+ +-----------+ +-----+
    V
    +----------+
    | Chunk #1 |-+
    | CB = 0 | | +-----------+ +-----+ +-----------+ +-----+
    +----------+ +->| Burst #42 |->| ... |->| Burst #83 |->| llp |
    | +-----------+ +-----+ +-----------+ +-----+
    V
    +----------+
    | Chunk #2 |-+
    | CB = 1 | | +-----------+ +-----+ +------------+ +-----+
    +----------+ +->| Burst #84 |->| ... |->| Burst #125 |->| llp |
    | +-----------+ +-----+ +------------+ +-----+
    V
    +----------+
    | Chunk #3 |-+
    | CB = 0 | | +------------+ +-----+ +------------+ +-----+
    +----------+ +->| Burst #126 |->| ... |->| Burst #129 |->| llp |
    +------------+ +-----+ +------------+ +-----+

    Legend:
    - Linked list, also know as Chunk
    - Linked list element*, also know as Burst *CB*, also know as Change Bit,
    it's a control bit (and typically is toggled) that allows to easily
    identify and differentiate between the current linked list and the
    previous or the next one.
    - LLP, is a special element that indicates the end of the linked list
    element stream also informs that the next CB should be toggle

    On every last Burst of the Chunk (Burst #41, Burst #83, Burst #125 or
    even Burst #129) is set some flags on their control variable (RIE and
    LIE bits) that will trigger the send of "done" interruption.

    On the interruptions callback, is decided whether to recycle the linked
    list memory space by writing a new set of Bursts elements (if still
    exists Chunks to transfer) or is considered completed (if there is no
    Chunks available to transfer).

    On scatter-gather transfer mode, the client will submit a scatter-gather
    list of n (on this case 130) elements, that will be divide in multiple
    Chunks, each Chunk will have (on this case 42) a limited number of
    Bursts and after transferring all Bursts, an interrupt will be
    triggered, which will allow to recycle the all linked list dedicated
    memory again with the new information relative to the next Chunk and
    respective Burst associated and repeat the whole cycle again.

    On cyclic transfer mode, the client will submit a buffer pointer, length
    of it and number of repetitions, in this case each burst will correspond
    directly to each repetition.

    Each Burst can describes a data transfer from point A(source) to point
    B(destination) with a length that can be from 1 byte up to 4 GB. Since
    dedicated the memory space where the linked list will reside is limited,
    the whole n burst elements will be organized in several Chunks, that
    will be used later to recycle the dedicated memory space to initiate a
    new sequence of data transfers.

    The whole transfer is considered has completed when it was transferred
    all bursts.

    Currently this IP has a set well-known register map, which includes
    support for legacy and unroll modes. Legacy mode is version of this
    register map that has multiplexer register that allows to switch
    registers between all write and read channels and the unroll modes
    repeats all write and read channels registers with an offset between
    them. This register map is called v0.

    The IP team is creating a new register map more suitable to the latest
    PCIe features, that very likely will change the map register, which this
    version will be called v1. As soon as this new version is released by
    the IP team the support for this version in be included on this driver.

    According to the logic, patches 1, 2 and 3 should be squashed into 1
    unique patch, but for the sake of simplicity of review, it was divided
    in this 3 patches files.

    Signed-off-by: Gustavo Pimentel
    Cc: Vinod Koul
    Cc: Dan Williams
    Cc: Andy Shevchenko
    Cc: Russell King
    Cc: Joao Pinto
    Signed-off-by: Vinod Koul

    Gustavo Pimentel