summaryrefslogtreecommitdiffstats
path: root/drivers/dma/xilinx
diff options
context:
space:
mode:
authorKedareswara rao Appana <appana.durga.rao@xilinx.com>2016-04-06 01:08:08 -0400
committerVinod Koul <vinod.koul@intel.com>2016-04-06 11:41:14 -0400
commitb72db4005fe4bf4af16d1436abd3c9d3aac991d1 (patch)
treeab1a167134c432cfa684614bc75129eb510907f6 /drivers/dma/xilinx
parentf55532a0c0b8bb6148f4e07853b876ef73bc69ca (diff)
dmaengine: vdma: Add 64 bit addressing support to the driver
This VDMA is a soft ip, which can be programmed to support 32 bit addressing or greater than 32 bit addressing. When the VDMA ip is configured for 32 bit address space the buffer address is specified by a single register (0x5C for MM2S and 0xAC for S2MM channel). When the VDMA core is configured for an address space greater than 32 then each buffer address is specified by a combination of two registers. The first register specifies the LSB 32 bits of address, while the next register specifies the MSB 32 bits of address. For example, 5Ch will specify the LSB 32 bits while 60h will specify the MSB 32 bits of the first start address. So we need to program two registers at a time. This patch adds the 64 bit addressing support to the vdma driver. Signed-off-by: Anurag Kumar Vulisha <anuragku@xilinx.com> Signed-off-by: Kedareswara rao Appana <appanad@xilinx.com> Signed-off-by: Vinod Koul <vinod.koul@intel.com>
Diffstat (limited to 'drivers/dma/xilinx')
-rw-r--r--drivers/dma/xilinx/xilinx_vdma.c73
1 files changed, 65 insertions, 8 deletions
diff --git a/drivers/dma/xilinx/xilinx_vdma.c b/drivers/dma/xilinx/xilinx_vdma.c
index 0ee0321868d3..abe915c73266 100644
--- a/drivers/dma/xilinx/xilinx_vdma.c
+++ b/drivers/dma/xilinx/xilinx_vdma.c
@@ -100,6 +100,7 @@
100#define XILINX_VDMA_FRMDLY_STRIDE_STRIDE_SHIFT 0 100#define XILINX_VDMA_FRMDLY_STRIDE_STRIDE_SHIFT 0
101 101
102#define XILINX_VDMA_REG_START_ADDRESS(n) (0x000c + 4 * (n)) 102#define XILINX_VDMA_REG_START_ADDRESS(n) (0x000c + 4 * (n))
103#define XILINX_VDMA_REG_START_ADDRESS_64(n) (0x000c + 8 * (n))
103 104
104/* HW specific definitions */ 105/* HW specific definitions */
105#define XILINX_VDMA_MAX_CHANS_PER_DEVICE 0x2 106#define XILINX_VDMA_MAX_CHANS_PER_DEVICE 0x2
@@ -144,7 +145,7 @@
144 * @next_desc: Next Descriptor Pointer @0x00 145 * @next_desc: Next Descriptor Pointer @0x00
145 * @pad1: Reserved @0x04 146 * @pad1: Reserved @0x04
146 * @buf_addr: Buffer address @0x08 147 * @buf_addr: Buffer address @0x08
147 * @pad2: Reserved @0x0C 148 * @buf_addr_msb: MSB of Buffer address @0x0C
148 * @vsize: Vertical Size @0x10 149 * @vsize: Vertical Size @0x10
149 * @hsize: Horizontal Size @0x14 150 * @hsize: Horizontal Size @0x14
150 * @stride: Number of bytes between the first 151 * @stride: Number of bytes between the first
@@ -154,7 +155,7 @@ struct xilinx_vdma_desc_hw {
154 u32 next_desc; 155 u32 next_desc;
155 u32 pad1; 156 u32 pad1;
156 u32 buf_addr; 157 u32 buf_addr;
157 u32 pad2; 158 u32 buf_addr_msb;
158 u32 vsize; 159 u32 vsize;
159 u32 hsize; 160 u32 hsize;
160 u32 stride; 161 u32 stride;
@@ -207,6 +208,7 @@ struct xilinx_vdma_tx_descriptor {
207 * @config: Device configuration info 208 * @config: Device configuration info
208 * @flush_on_fsync: Flush on Frame sync 209 * @flush_on_fsync: Flush on Frame sync
209 * @desc_pendingcount: Descriptor pending count 210 * @desc_pendingcount: Descriptor pending count
211 * @ext_addr: Indicates 64 bit addressing is supported by dma channel
210 */ 212 */
211struct xilinx_vdma_chan { 213struct xilinx_vdma_chan {
212 struct xilinx_vdma_device *xdev; 214 struct xilinx_vdma_device *xdev;
@@ -230,6 +232,7 @@ struct xilinx_vdma_chan {
230 struct xilinx_vdma_config config; 232 struct xilinx_vdma_config config;
231 bool flush_on_fsync; 233 bool flush_on_fsync;
232 u32 desc_pendingcount; 234 u32 desc_pendingcount;
235 bool ext_addr;
233}; 236};
234 237
235/** 238/**
@@ -240,6 +243,7 @@ struct xilinx_vdma_chan {
240 * @chan: Driver specific VDMA channel 243 * @chan: Driver specific VDMA channel
241 * @has_sg: Specifies whether Scatter-Gather is present or not 244 * @has_sg: Specifies whether Scatter-Gather is present or not
242 * @flush_on_fsync: Flush on frame sync 245 * @flush_on_fsync: Flush on frame sync
246 * @ext_addr: Indicates 64 bit addressing is supported by dma device
243 */ 247 */
244struct xilinx_vdma_device { 248struct xilinx_vdma_device {
245 void __iomem *regs; 249 void __iomem *regs;
@@ -248,6 +252,7 @@ struct xilinx_vdma_device {
248 struct xilinx_vdma_chan *chan[XILINX_VDMA_MAX_CHANS_PER_DEVICE]; 252 struct xilinx_vdma_chan *chan[XILINX_VDMA_MAX_CHANS_PER_DEVICE];
249 bool has_sg; 253 bool has_sg;
250 u32 flush_on_fsync; 254 u32 flush_on_fsync;
255 bool ext_addr;
251}; 256};
252 257
253/* Macros */ 258/* Macros */
@@ -299,6 +304,27 @@ static inline void vdma_ctrl_set(struct xilinx_vdma_chan *chan, u32 reg,
299 vdma_ctrl_write(chan, reg, vdma_ctrl_read(chan, reg) | set); 304 vdma_ctrl_write(chan, reg, vdma_ctrl_read(chan, reg) | set);
300} 305}
301 306
307/**
308 * vdma_desc_write_64 - 64-bit descriptor write
309 * @chan: Driver specific VDMA channel
310 * @reg: Register to write
311 * @value_lsb: lower address of the descriptor.
312 * @value_msb: upper address of the descriptor.
313 *
314 * Since vdma driver is trying to write to a register offset which is not a
315 * multiple of 64 bits(ex : 0x5c), we are writing as two separate 32 bits
316 * instead of a single 64 bit register write.
317 */
318static inline void vdma_desc_write_64(struct xilinx_vdma_chan *chan, u32 reg,
319 u32 value_lsb, u32 value_msb)
320{
321 /* Write the lsb 32 bits*/
322 writel(value_lsb, chan->xdev->regs + chan->desc_offset + reg);
323
324 /* Write the msb 32 bits */
325 writel(value_msb, chan->xdev->regs + chan->desc_offset + reg + 4);
326}
327
302/* ----------------------------------------------------------------------------- 328/* -----------------------------------------------------------------------------
303 * Descriptors and segments alloc and free 329 * Descriptors and segments alloc and free
304 */ 330 */
@@ -693,9 +719,16 @@ static void xilinx_vdma_start_transfer(struct xilinx_vdma_chan *chan)
693 list_for_each_entry(desc, &chan->pending_list, node) { 719 list_for_each_entry(desc, &chan->pending_list, node) {
694 segment = list_first_entry(&desc->segments, 720 segment = list_first_entry(&desc->segments,
695 struct xilinx_vdma_tx_segment, node); 721 struct xilinx_vdma_tx_segment, node);
696 vdma_desc_write(chan, 722 if (chan->ext_addr)
723 vdma_desc_write_64(chan,
724 XILINX_VDMA_REG_START_ADDRESS_64(i++),
725 segment->hw.buf_addr,
726 segment->hw.buf_addr_msb);
727 else
728 vdma_desc_write(chan,
697 XILINX_VDMA_REG_START_ADDRESS(i++), 729 XILINX_VDMA_REG_START_ADDRESS(i++),
698 segment->hw.buf_addr); 730 segment->hw.buf_addr);
731
699 last = segment; 732 last = segment;
700 } 733 }
701 734
@@ -987,10 +1020,21 @@ xilinx_vdma_dma_prep_interleaved(struct dma_chan *dchan,
987 hw->stride |= chan->config.frm_dly << 1020 hw->stride |= chan->config.frm_dly <<
988 XILINX_VDMA_FRMDLY_STRIDE_FRMDLY_SHIFT; 1021 XILINX_VDMA_FRMDLY_STRIDE_FRMDLY_SHIFT;
989 1022
990 if (xt->dir != DMA_MEM_TO_DEV) 1023 if (xt->dir != DMA_MEM_TO_DEV) {
991 hw->buf_addr = xt->dst_start; 1024 if (chan->ext_addr) {
992 else 1025 hw->buf_addr = lower_32_bits(xt->dst_start);
993 hw->buf_addr = xt->src_start; 1026 hw->buf_addr_msb = upper_32_bits(xt->dst_start);
1027 } else {
1028 hw->buf_addr = xt->dst_start;
1029 }
1030 } else {
1031 if (chan->ext_addr) {
1032 hw->buf_addr = lower_32_bits(xt->src_start);
1033 hw->buf_addr_msb = upper_32_bits(xt->src_start);
1034 } else {
1035 hw->buf_addr = xt->src_start;
1036 }
1037 }
994 1038
995 /* Insert the segment into the descriptor segments list. */ 1039 /* Insert the segment into the descriptor segments list. */
996 list_add_tail(&segment->node, &desc->segments); 1040 list_add_tail(&segment->node, &desc->segments);
@@ -1140,6 +1184,7 @@ static int xilinx_vdma_chan_probe(struct xilinx_vdma_device *xdev,
1140 chan->xdev = xdev; 1184 chan->xdev = xdev;
1141 chan->has_sg = xdev->has_sg; 1185 chan->has_sg = xdev->has_sg;
1142 chan->desc_pendingcount = 0x0; 1186 chan->desc_pendingcount = 0x0;
1187 chan->ext_addr = xdev->ext_addr;
1143 1188
1144 spin_lock_init(&chan->lock); 1189 spin_lock_init(&chan->lock);
1145 INIT_LIST_HEAD(&chan->pending_list); 1190 INIT_LIST_HEAD(&chan->pending_list);
@@ -1254,7 +1299,7 @@ static int xilinx_vdma_probe(struct platform_device *pdev)
1254 struct xilinx_vdma_device *xdev; 1299 struct xilinx_vdma_device *xdev;
1255 struct device_node *child; 1300 struct device_node *child;
1256 struct resource *io; 1301 struct resource *io;
1257 u32 num_frames; 1302 u32 num_frames, addr_width;
1258 int i, err; 1303 int i, err;
1259 1304
1260 /* Allocate and initialize the DMA engine structure */ 1305 /* Allocate and initialize the DMA engine structure */
@@ -1284,6 +1329,18 @@ static int xilinx_vdma_probe(struct platform_device *pdev)
1284 if (err < 0) 1329 if (err < 0)
1285 dev_warn(xdev->dev, "missing xlnx,flush-fsync property\n"); 1330 dev_warn(xdev->dev, "missing xlnx,flush-fsync property\n");
1286 1331
1332 err = of_property_read_u32(node, "xlnx,addrwidth", &addr_width);
1333 if (err < 0)
1334 dev_warn(xdev->dev, "missing xlnx,addrwidth property\n");
1335
1336 if (addr_width > 32)
1337 xdev->ext_addr = true;
1338 else
1339 xdev->ext_addr = false;
1340
1341 /* Set the dma mask bits */
1342 dma_set_mask(xdev->dev, DMA_BIT_MASK(addr_width));
1343
1287 /* Initialize the DMA engine */ 1344 /* Initialize the DMA engine */
1288 xdev->common.dev = &pdev->dev; 1345 xdev->common.dev = &pdev->dev;
1289 1346