bus: mvebu-mbus: Provide stub function for mvebu_mbus_get_io_win_info()
PATCH v3 1/2 bus: mvebu-mbus: Provide stub function for mvebu_mbus_get_io_win_info()
This patch provides a stub function for mvebu_mbus_get_io_win_info(), which will be used for all non-Orion (ARM32 MVEBU) platforms for compile test coverage.
On such platforms this function will return an error so that drivers might detect a potential problem.
---
v3:
- Include errno.h to fix the compile breakage on ARM64
- Change comment as suggested by Andrew
- Added Andrew to Cc
v2:
- Return error code in stub function. This may be useful on Armada 3700 boards. As Armada 3700 does not implement the MBus driver but some device driver might call into these functions anyways (e.g. mvneta).
include/linux/mbus.h | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-)
include/linux/mbus.h +16 -2
@@ -11,6 +11,8 @@#ifndef __LINUX_MBUS_H#define __LINUX_MBUS_H +#include <linux/errno.h> +struct resource ;struct mbus_dram_target_info
@@ -55,6 +57,8 @@ struct mbus_dram_target_info#ifdef CONFIG_PLAT_ORION extern const struct mbus_dram_target_info *mv_mbus_dram_info (void );extern const struct mbus_dram_target_info *mv_mbus_dram_info_nooverlap (void ); +int mvebu_mbus_get_io_win_info (phys_addr_t phyaddr,u32 *size,u8 *target, +u8 *attr);#else static inline const struct mbus_dram_target_info *mv_mbus_dram_info (void ) {
@@ -64,14 +68,24 @@ static inline const struct mbus_dram_target_info *mv_mbus_dram_info_nooverlap(vo {return NULL ; } +static inline int mvebu_mbus_get_io_win_info (phys_addr_t phyaddr,u32 *size, +u8 *target,u8 *attr) +{ +/* +* On all ARM32 MVEBU platforms with MBus support, this stub +* function will not get called. The real function from the +* MBus driver is called instead. ARM64 MVEBU platforms like +* the Armada 3700 could use the mv_xor device driver which calls +* into this function +*/ +return -EINVAL ; +}#endif int mvebu_mbus_save_cpu_target (u32 __iomem *store_addr);void mvebu_mbus_get_pcie_mem_aperture (struct resource *res);void mvebu_mbus_get_pcie_io_aperture (struct resource *res);int mvebu_mbus_get_dram_win_info (phys_addr_t phyaddr,u8 *target,u8 *attr); -int mvebu_mbus_get_io_win_info (phys_addr_t phyaddr,u32 *size,u8 *target, -u8 *attr); int mvebu_mbus_add_window_remap_by_id(unsigned int target, unsigned int attribute, phys_addr_t base, size_t size,
Signature · 1 line
2.9.3
PATCH v5 2/2 dmaengine: mv_xor: Add support for IO (PCIe) src/dst areas
To enable the access to a specific area, the MVEBU XOR controllers needs to have this area enabled / mapped via an address window. Right now, only the DRAM memory area is enabled via such memory windows. So using this driver to DMA to / from a e.g. PCIe memory region is currently not supported.
This patch now adds support for such PCIe / IO regions by checking if the src / dst address is located in an IO memory area in contrast to being located in DRAM. This is done by using the newly introduced MBus function mvebu_mbus_get_io_win_info(). If the src / dst address is located in such an IO area, a new address window is created in the XOR DMA controller. Enabling the controller to access this area.
---
v4 -> v5:
- Added Andrew to Cc
v3 -> v4:
- Don't try to add the IO windows on Armada 3700 which does not implement the MBus driver
v2 -> v3:
- Included separate patch to add a stub function for mvebu_mbus_get_io_win_info() to this patch series
- COMPILE_TEST added again, as the stub function now allows compilation on all platforms
v1 -> v2:
- Removed COMPILE_TEST from Kconfig entry as this results in compilation errors on non-Marvell platforms because of references to MBus driver functions. Since this driver will never be used on non-Marvell platforms this should be okay.
RFC -> v1:
- Use a cache for the already mapped areas for performance reasons, as the MMIO registers don't need to get queried any more if the area is already mapped now
drivers/dma/mv_xor.c | 95 +++++++++++++++++++++++++++++++++++++++++++++++++++- drivers/dma/mv_xor.h | 7 ++++ 2 files changed, 101 insertions(+), 1 deletion(-)
drivers/dma/mv_xor.c +94 -1
@@ -470,12 +470,90 @@ static int mv_xor_alloc_chan_resources(struct dma_chan *chan)return mv_chan->slots_allocated ? : -ENOMEM ; } +/* +* Check if source or destination is an PCIe/IO address (non-SDRAM) and add +* a new MBus window if necessary. Use a cache for these check so that +* the MMIO mapped registers don't have to be accessed for this check +* to speed up this process. +*/ +static int mv_xor_add_io_win (struct mv_xor_chan *mv_chan,u32 addr) +{ +struct mv_xor_device *xordev = mv_chan->xordev; +void __iomem *base = mv_chan->mmr_high_base; +u32 win_enable; +u32 size; +u8 target, attr; +int ret; +int i; + +/* Nothing needs to get done for the Armada 3700 */ +if (xordev->xor_type ==XOR_ARMADA_37XX ) +return 0 ; + +/* +* Loop over the cached windows to check, if the requested area +* is already mapped. If this the case, nothing needs to be done +* and we can return. +*/ +for (i =0 ; i <WINDOW_COUNT ; i++) { +if (addr >= xordev->win_start[i] && + addr <= xordev->win_end[i]) { +/* Window is already mapped */ +return 0 ; + } + } + +/* +* The window is not mapped, so we need to create the new mapping +*/ + +/* If no IO window is found that addr has to be located in SDRAM */ + ret =mvebu_mbus_get_io_win_info (addr, &size, &target, &attr); +if (ret <0 ) +return 0 ; + +/* +* Mask the base addr 'addr' according to 'size' read back from the +* MBus window. Otherwise we might end up with an address located +* somewhere in the middle of this area here. +*/ + size -=1 ; + addr &= ~size; + +/* +* Reading one of both enabled register is enough, as they are always +* programmed to the identical values +*/ + win_enable =readl (base +WINDOW_BAR_ENABLE (0 )); + +/* Set 'i' to the first free window to write the new values to */ + i =ffs (~win_enable) -1 ; +if (i >=WINDOW_COUNT ) +return -ENOMEM ; + +writel ((addr &0xffff0000 ) | (attr <<8 ) | target, + base +WINDOW_BASE (i)); +writel (size &0xffff0000 , base +WINDOW_SIZE (i)); + +/* Fill the caching variables for later use */ + xordev->win_start[i] = addr; + xordev->win_end[i] = addr + size; + + win_enable |= (1 << i); + win_enable |=3 << (16 + (2 * i)); +writel (win_enable, base +WINDOW_BAR_ENABLE (0 )); +writel (win_enable, base +WINDOW_BAR_ENABLE (1 )); + +return 0 ; +} +static struct dma_async_tx_descriptor *mv_xor_prep_dma_xor (struct dma_chan *chan,dma_addr_t dest,dma_addr_t *src,unsigned int src_cnt,size_t len,unsigned long flags) {struct mv_xor_chan *mv_chan =to_mv_xor_chan (chan);struct mv_xor_desc_slot *sw_desc; +int ret;if (unlikely (len <MV_XOR_MIN_BYTE_COUNT ))return NULL ;
@@ -486,6 +564,11 @@ mv_xor_prep_dma_xor(struct dma_chan *chan, dma_addr_t dest, dma_addr_t *src,"%s src_cnt: %d len: %zu dest %pad flags: %ld\n" , __func__, src_cnt, len, &dest, flags); +/* Check if a new window needs to get added for 'dest' */ + ret =mv_xor_add_io_win (mv_chan, dest); +if (ret) +return NULL ; + sw_desc =mv_chan_alloc_slot (mv_chan);if (sw_desc) { sw_desc->type =DMA_XOR ;
@@ -493,8 +576,13 @@ mv_xor_prep_dma_xor(struct dma_chan *chan, dma_addr_t dest, dma_addr_t *src,mv_desc_init (sw_desc, dest, len, flags);if (mv_chan->op_in_desc ==XOR_MODE_IN_DESC )mv_desc_set_mode (sw_desc); -while (src_cnt--) +while (src_cnt--) { +/* Check if a new window needs to get added for 'src' */ + ret =mv_xor_add_io_win (mv_chan, src[src_cnt]); +if (ret) +return NULL ;mv_desc_set_src_addr (sw_desc, src_cnt, src[src_cnt]); + } } dev_dbg(mv_chan_to_devp(mv_chan),
@@ -959,6 +1047,7 @@ mv_xor_channel_add(struct mv_xor_device *xordev, mv_chan->op_in_desc =XOR_MODE_IN_DESC ; dma_dev = &mv_chan->dmadev; + mv_chan->xordev = xordev;/* * These source and destination dummy buffers are used to implement
@@ -1086,6 +1175,10 @@ mv_xor_conf_mbus_windows(struct mv_xor_device *xordev, dram->mbus_dram_target_id, base + WINDOW_BASE(i));writel ((cs->size -1 ) &0xffff0000 , base +WINDOW_SIZE (i)); +/* Fill the caching variables for later use */ + xordev->win_start[i] = cs->base; + xordev->win_end[i] = cs->base + cs->size -1 ; + win_enable |= (1 << i); win_enable |=3 << (16 + (2 * i)); }
drivers/dma/mv_xor.h +7 -0
@@ -80,12 +80,17 @@#define WINDOW_BAR_ENABLE (chan) (0x40 + ((chan) << 2))#define WINDOW_OVERRIDE_CTRL (chan) (0xA0 + ((chan) << 2)) +#define WINDOW_COUNT 8 +struct mv_xor_device {void __iomem *xor_base;void __iomem *xor_high_base;struct clk *clk;struct mv_xor_chan *channels[MV_XOR_MAX_CHANNELS ];int xor_type; + +u32 win_start[WINDOW_COUNT ]; +u32 win_end[WINDOW_COUNT ]; };/**
@@ -127,6 +132,8 @@ struct mv_xor_chan {char dummy_dst[MV_XOR_MIN_BYTE_COUNT ];dma_addr_t dummy_src_addr, dummy_dst_addr;u32 saved_config_reg, saved_int_mask_reg; + +struct mv_xor_device *xordev; };/**
Signature · 1 line
2.9.3
PATCH v3 1/2 bus: mvebu-mbus: Provide stub function for mvebu_mbus_get_io_win_info()
In reply to Stefan RoeseHi,
Quoted 6 lines · Stefan Roese
This patch provides a stub function for
mvebu_mbus_get_io_win_info(), which will be used for all non-Orion (ARM32 MVEBU) platforms for compile test coverage.On such platforms this function will return an error so that drivers might detect a potential problem.
Vinod, if you happy with the second patch of the series you can apply both patches on your tree. It will allow to keep the bisactibility, and as I didn't have any commit modifying these file in my trees it won't generate merge conflict.
Thanks,
Gregory
Quoted 74 lines
Signed-off-by Stefan Roese <[email protected]>Cc Gregory CLEMENT <[email protected]>Cc Thomas Petazzoni <[email protected]>Cc Marcin Wojtas <[email protected]>Cc Arnd Bergmann <[email protected]>Cc Andrew Lunn <[email protected]>Cc Vinod Koul <[email protected]>---
v3:
- Includeerrno.hto fix the compile breakage on ARM64
- Change comment as suggested by Andrew
- Added Andrew to Ccv2:
- Return error code in stub function. This may be useful on Armada 3700 boards. As Armada 3700 does not implement the MBus driver but some device driver might call into these functions anyways (e.g. mvneta).include/linux/mbus.h | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-)include/linux/mbus.h +16
-2@@ -11,6 +11,8 @@#ifndef __LINUX_MBUS_H#define __LINUX_MBUS_H +#include <linux/errno.h> +struct resource ;struct mbus_dram_target_info @@ -55,6 +57,8 @@ struct mbus_dram_target_info#ifdef CONFIG_PLAT_ORION extern const struct mbus_dram_target_info *mv_mbus_dram_info (void );extern const struct mbus_dram_target_info *mv_mbus_dram_info_nooverlap (void ); +int mvebu_mbus_get_io_win_info (phys_addr_t phyaddr,u32 *size,u8 *target, +u8 *attr);#else static inline const struct mbus_dram_target_info *mv_mbus_dram_info (void ) {@@ -64,14 +68,24 @@ static inline const struct mbus_dram_target_info *mv_mbus_dram_info_nooverlap(vo {return NULL ; } +static inline int mvebu_mbus_get_io_win_info (phys_addr_t phyaddr,u32 *size, +u8 *target,u8 *attr) +{ +/* +* On all ARM32 MVEBU platforms with MBus support, this stub +* function will not get called. The real function from the +* MBus driver is called instead. ARM64 MVEBU platforms like +* the Armada 3700 could use the mv_xor device driver which calls +* into this function +*/ +return -EINVAL ; +}#endif int mvebu_mbus_save_cpu_target (u32 __iomem *store_addr);void mvebu_mbus_get_pcie_mem_aperture (struct resource *res);void mvebu_mbus_get_pcie_io_aperture (struct resource *res);int mvebu_mbus_get_dram_win_info (phys_addr_t phyaddr,u8 *target,u8 *attr); -int mvebu_mbus_get_io_win_info (phys_addr_t phyaddr,u32 *size,u8 *target, -u8 *attr); int mvebu_mbus_add_window_remap_by_id(unsigned int target, unsigned int attribute, phys_addr_t base, size_t size,Signature · 1 line
2.9.3
Signature · 4 lines
Gregory Clement, Free Electrons Kernel, drivers, real-time and embedded Linux development, consulting, training and support. http://free-electrons.com
PATCH v3 1/2 bus: mvebu-mbus: Provide stub function for mvebu_mbus_get_io_win_info()
Quoted 11 lines · Gregory CLEMENT
Hi,
Quoted 6 lines · Stefan Roese
This patch provides a stub function for
mvebu_mbus_get_io_win_info(), which will be used for all non-Orion (ARM32 MVEBU) platforms for compile test coverage.On such platforms this function will return an error so that drivers might detect a potential problem.
Quoted 6 lines
Acked-by Gregory CLEMENT <[email protected]>Vinod, if you happy with the second patch of the series you can apply both patches on your tree. It will allow to keep the bisactibility, and as I didn't have any commit modifying these file in my trees it won't generate merge conflict.
Okay, somehow I dont see this in my queue. Can you guys pls resend.
Thanks
Signature · 1 line
~Vinod
PATCH v3 1/2 bus: mvebu-mbus: Provide stub function for mvebu_mbus_get_io_win_info()
Hi Vinod,
Quoted 12 lines · Vinod Koul
Quoted 11 lines · Gregory CLEMENT
Hi,
Quoted 6 lines · Stefan Roese
This patch provides a stub function for
mvebu_mbus_get_io_win_info(), which will be used for all non-Orion (ARM32 MVEBU) platforms for compile test coverage.On such platforms this function will return an error so that drivers might detect a potential problem.
Quoted 8 lines
Quoted 6 lines
Acked-by Gregory CLEMENT <[email protected]>Vinod, if you happy with the second patch of the series you can apply both patches on your tree. It will allow to keep the bisactibility, and as I didn't have any commit modifying these file in my trees it won't generate merge conflict.
Okay, somehow I dont see this in my queue. Can you guys pls resend.
Sure. I'll resend it in a minute...
Thanks,
Stefan