dmaengine: dw: fix byte order of hw descriptor fields
If the DMA controller uses a different byte order than the host CPU, the hardware linked list descriptor fields need to be byte-swapped. This patch makes the driver write these fields using the same byte order it uses for mmio accesses to the DMA engine. I do not know if this is guaranteed to always be correct. Signed-off-by: Mans Rullgard <mans@mansr.com> Acked-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com> Signed-off-by: Vinod Koul <vinod.koul@intel.com>
这个提交包含在:
@@ -308,26 +308,44 @@ static inline struct dw_dma *to_dw_dma(struct dma_device *ddev)
|
||||
return container_of(ddev, struct dw_dma, dma);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_DW_DMAC_BIG_ENDIAN_IO
|
||||
typedef __be32 __dw32;
|
||||
#else
|
||||
typedef __le32 __dw32;
|
||||
#endif
|
||||
|
||||
/* LLI == Linked List Item; a.k.a. DMA block descriptor */
|
||||
struct dw_lli {
|
||||
/* values that are not changed by hardware */
|
||||
u32 sar;
|
||||
u32 dar;
|
||||
u32 llp; /* chain to next lli */
|
||||
u32 ctllo;
|
||||
__dw32 sar;
|
||||
__dw32 dar;
|
||||
__dw32 llp; /* chain to next lli */
|
||||
__dw32 ctllo;
|
||||
/* values that may get written back: */
|
||||
u32 ctlhi;
|
||||
__dw32 ctlhi;
|
||||
/* sstat and dstat can snapshot peripheral register state.
|
||||
* silicon config may discard either or both...
|
||||
*/
|
||||
u32 sstat;
|
||||
u32 dstat;
|
||||
__dw32 sstat;
|
||||
__dw32 dstat;
|
||||
};
|
||||
|
||||
struct dw_desc {
|
||||
/* FIRST values the hardware uses */
|
||||
struct dw_lli lli;
|
||||
|
||||
#ifdef CONFIG_DW_DMAC_BIG_ENDIAN_IO
|
||||
#define lli_set(d, reg, v) ((d)->lli.reg |= cpu_to_be32(v))
|
||||
#define lli_clear(d, reg, v) ((d)->lli.reg &= ~cpu_to_be32(v))
|
||||
#define lli_read(d, reg) be32_to_cpu((d)->lli.reg)
|
||||
#define lli_write(d, reg, v) ((d)->lli.reg = cpu_to_be32(v))
|
||||
#else
|
||||
#define lli_set(d, reg, v) ((d)->lli.reg |= cpu_to_le32(v))
|
||||
#define lli_clear(d, reg, v) ((d)->lli.reg &= ~cpu_to_le32(v))
|
||||
#define lli_read(d, reg) le32_to_cpu((d)->lli.reg)
|
||||
#define lli_write(d, reg, v) ((d)->lli.reg = cpu_to_le32(v))
|
||||
#endif
|
||||
|
||||
/* THEN values for driver housekeeping */
|
||||
struct list_head desc_node;
|
||||
struct list_head tx_list;
|
||||
|
在新工单中引用
屏蔽一个用户