diff options
| author | Koul, Vinod <vinod.koul@intel.com> | 2010-10-04 06:38:43 -0400 |
|---|---|---|
| committer | Dan Williams <dan.j.williams@intel.com> | 2010-10-07 18:03:44 -0400 |
| commit | 20dd63900d238e17b122fe0c7376ff090867f528 (patch) | |
| tree | 8f25adbbb5d49ca428df2596d1e2e24e8e40e428 | |
| parent | 8b6492231d2a92352a6371eebd622e3bc824a663 (diff) | |
intel_mid_dma: change the slave interface
In 2.6.36 kernel, dma slave control command was introduced,
this patch changes the intel-mid-dma driver to this
new kernel slave interface
Signed-off-by: Vinod Koul <vinod.koul@intel.com>
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
| -rw-r--r-- | drivers/dma/intel_mid_dma.c | 66 | ||||
| -rw-r--r-- | drivers/dma/intel_mid_dma_regs.h | 11 | ||||
| -rw-r--r-- | include/linux/intel_mid_dma.h | 15 |
3 files changed, 53 insertions, 39 deletions
diff --git a/drivers/dma/intel_mid_dma.c b/drivers/dma/intel_mid_dma.c index ef7ffb813fe9..338bc4eed1f3 100644 --- a/drivers/dma/intel_mid_dma.c +++ b/drivers/dma/intel_mid_dma.c | |||
| @@ -92,13 +92,13 @@ static int get_block_ts(int len, int tx_width, int block_size) | |||
| 92 | int byte_width = 0, block_ts = 0; | 92 | int byte_width = 0, block_ts = 0; |
| 93 | 93 | ||
| 94 | switch (tx_width) { | 94 | switch (tx_width) { |
| 95 | case LNW_DMA_WIDTH_8BIT: | 95 | case DMA_SLAVE_BUSWIDTH_1_BYTE: |
| 96 | byte_width = 1; | 96 | byte_width = 1; |
| 97 | break; | 97 | break; |
| 98 | case LNW_DMA_WIDTH_16BIT: | 98 | case DMA_SLAVE_BUSWIDTH_2_BYTES: |
| 99 | byte_width = 2; | 99 | byte_width = 2; |
| 100 | break; | 100 | break; |
| 101 | case LNW_DMA_WIDTH_32BIT: | 101 | case DMA_SLAVE_BUSWIDTH_4_BYTES: |
| 102 | default: | 102 | default: |
| 103 | byte_width = 4; | 103 | byte_width = 4; |
| 104 | break; | 104 | break; |
| @@ -367,7 +367,7 @@ static int midc_lli_fill_sg(struct intel_mid_dma_chan *midc, | |||
| 367 | int i; | 367 | int i; |
| 368 | 368 | ||
| 369 | pr_debug("MDMA: Entered midc_lli_fill_sg\n"); | 369 | pr_debug("MDMA: Entered midc_lli_fill_sg\n"); |
| 370 | mids = midc->chan.private; | 370 | mids = midc->mid_slave; |
| 371 | 371 | ||
| 372 | lli_bloc_desc = desc->lli; | 372 | lli_bloc_desc = desc->lli; |
| 373 | lli_next = desc->lli_phys; | 373 | lli_next = desc->lli_phys; |
| @@ -398,9 +398,9 @@ static int midc_lli_fill_sg(struct intel_mid_dma_chan *midc, | |||
| 398 | sg_phy_addr = sg_phys(sg); | 398 | sg_phy_addr = sg_phys(sg); |
| 399 | if (desc->dirn == DMA_TO_DEVICE) { | 399 | if (desc->dirn == DMA_TO_DEVICE) { |
| 400 | lli_bloc_desc->sar = sg_phy_addr; | 400 | lli_bloc_desc->sar = sg_phy_addr; |
| 401 | lli_bloc_desc->dar = mids->per_addr; | 401 | lli_bloc_desc->dar = mids->dma_slave.dst_addr; |
| 402 | } else if (desc->dirn == DMA_FROM_DEVICE) { | 402 | } else if (desc->dirn == DMA_FROM_DEVICE) { |
| 403 | lli_bloc_desc->sar = mids->per_addr; | 403 | lli_bloc_desc->sar = mids->dma_slave.src_addr; |
| 404 | lli_bloc_desc->dar = sg_phy_addr; | 404 | lli_bloc_desc->dar = sg_phy_addr; |
| 405 | } | 405 | } |
| 406 | /*Copy values into block descriptor in system memroy*/ | 406 | /*Copy values into block descriptor in system memroy*/ |
| @@ -507,6 +507,23 @@ static enum dma_status intel_mid_dma_tx_status(struct dma_chan *chan, | |||
| 507 | return ret; | 507 | return ret; |
| 508 | } | 508 | } |
| 509 | 509 | ||
| 510 | static int dma_slave_control(struct dma_chan *chan, unsigned long arg) | ||
| 511 | { | ||
| 512 | struct intel_mid_dma_chan *midc = to_intel_mid_dma_chan(chan); | ||
| 513 | struct dma_slave_config *slave = (struct dma_slave_config *)arg; | ||
| 514 | struct intel_mid_dma_slave *mid_slave; | ||
| 515 | |||
| 516 | BUG_ON(!midc); | ||
| 517 | BUG_ON(!slave); | ||
| 518 | pr_debug("MDMA: slave control called\n"); | ||
| 519 | |||
| 520 | mid_slave = to_intel_mid_dma_slave(slave); | ||
| 521 | |||
| 522 | BUG_ON(!mid_slave); | ||
| 523 | |||
| 524 | midc->mid_slave = mid_slave; | ||
| 525 | return 0; | ||
| 526 | } | ||
| 510 | /** | 527 | /** |
| 511 | * intel_mid_dma_device_control - DMA device control | 528 | * intel_mid_dma_device_control - DMA device control |
| 512 | * @chan: chan for DMA control | 529 | * @chan: chan for DMA control |
| @@ -523,6 +540,9 @@ static int intel_mid_dma_device_control(struct dma_chan *chan, | |||
| 523 | struct intel_mid_dma_desc *desc, *_desc; | 540 | struct intel_mid_dma_desc *desc, *_desc; |
| 524 | union intel_mid_dma_cfg_lo cfg_lo; | 541 | union intel_mid_dma_cfg_lo cfg_lo; |
| 525 | 542 | ||
| 543 | if (cmd == DMA_SLAVE_CONFIG) | ||
| 544 | return dma_slave_control(chan, arg); | ||
| 545 | |||
| 526 | if (cmd != DMA_TERMINATE_ALL) | 546 | if (cmd != DMA_TERMINATE_ALL) |
| 527 | return -ENXIO; | 547 | return -ENXIO; |
| 528 | 548 | ||
| @@ -540,7 +560,6 @@ static int intel_mid_dma_device_control(struct dma_chan *chan, | |||
| 540 | /* Disable interrupts */ | 560 | /* Disable interrupts */ |
| 541 | disable_dma_interrupt(midc); | 561 | disable_dma_interrupt(midc); |
| 542 | midc->descs_allocated = 0; | 562 | midc->descs_allocated = 0; |
| 543 | midc->slave = NULL; | ||
| 544 | 563 | ||
| 545 | spin_unlock_bh(&midc->lock); | 564 | spin_unlock_bh(&midc->lock); |
| 546 | list_for_each_entry_safe(desc, _desc, &midc->active_list, desc_node) { | 565 | list_for_each_entry_safe(desc, _desc, &midc->active_list, desc_node) { |
| @@ -578,23 +597,24 @@ static struct dma_async_tx_descriptor *intel_mid_dma_prep_memcpy( | |||
| 578 | union intel_mid_dma_ctl_hi ctl_hi; | 597 | union intel_mid_dma_ctl_hi ctl_hi; |
| 579 | union intel_mid_dma_cfg_lo cfg_lo; | 598 | union intel_mid_dma_cfg_lo cfg_lo; |
| 580 | union intel_mid_dma_cfg_hi cfg_hi; | 599 | union intel_mid_dma_cfg_hi cfg_hi; |
| 581 | enum intel_mid_dma_width width = 0; | 600 | enum dma_slave_buswidth width; |
| 582 | 601 | ||
| 583 | pr_debug("MDMA: Prep for memcpy\n"); | 602 | pr_debug("MDMA: Prep for memcpy\n"); |
| 584 | BUG_ON(!chan); | 603 | BUG_ON(!chan); |
| 585 | if (!len) | 604 | if (!len) |
| 586 | return NULL; | 605 | return NULL; |
| 587 | 606 | ||
| 588 | mids = chan->private; | ||
| 589 | BUG_ON(!mids); | ||
| 590 | |||
| 591 | midc = to_intel_mid_dma_chan(chan); | 607 | midc = to_intel_mid_dma_chan(chan); |
| 592 | BUG_ON(!midc); | 608 | BUG_ON(!midc); |
| 593 | 609 | ||
| 610 | mids = midc->mid_slave; | ||
| 611 | BUG_ON(!mids); | ||
| 612 | |||
| 594 | pr_debug("MDMA:called for DMA %x CH %d Length %zu\n", | 613 | pr_debug("MDMA:called for DMA %x CH %d Length %zu\n", |
| 595 | midc->dma->pci_id, midc->ch_id, len); | 614 | midc->dma->pci_id, midc->ch_id, len); |
| 596 | pr_debug("MDMA:Cfg passed Mode %x, Dirn %x, HS %x, Width %x\n", | 615 | pr_debug("MDMA:Cfg passed Mode %x, Dirn %x, HS %x, Width %x\n", |
| 597 | mids->cfg_mode, mids->dirn, mids->hs_mode, mids->src_width); | 616 | mids->cfg_mode, mids->dma_slave.direction, |
| 617 | mids->hs_mode, mids->dma_slave.src_addr_width); | ||
| 598 | 618 | ||
| 599 | /*calculate CFG_LO*/ | 619 | /*calculate CFG_LO*/ |
| 600 | if (mids->hs_mode == LNW_DMA_SW_HS) { | 620 | if (mids->hs_mode == LNW_DMA_SW_HS) { |
| @@ -613,13 +633,13 @@ static struct dma_async_tx_descriptor *intel_mid_dma_prep_memcpy( | |||
| 613 | if (midc->dma->pimr_mask) { | 633 | if (midc->dma->pimr_mask) { |
| 614 | cfg_hi.cfgx.protctl = 0x0; /*default value*/ | 634 | cfg_hi.cfgx.protctl = 0x0; /*default value*/ |
| 615 | cfg_hi.cfgx.fifo_mode = 1; | 635 | cfg_hi.cfgx.fifo_mode = 1; |
| 616 | if (mids->dirn == DMA_TO_DEVICE) { | 636 | if (mids->dma_slave.direction == DMA_TO_DEVICE) { |
| 617 | cfg_hi.cfgx.src_per = 0; | 637 | cfg_hi.cfgx.src_per = 0; |
| 618 | if (mids->device_instance == 0) | 638 | if (mids->device_instance == 0) |
| 619 | cfg_hi.cfgx.dst_per = 3; | 639 | cfg_hi.cfgx.dst_per = 3; |
| 620 | if (mids->device_instance == 1) | 640 | if (mids->device_instance == 1) |
| 621 | cfg_hi.cfgx.dst_per = 1; | 641 | cfg_hi.cfgx.dst_per = 1; |
| 622 | } else if (mids->dirn == DMA_FROM_DEVICE) { | 642 | } else if (mids->dma_slave.direction == DMA_FROM_DEVICE) { |
| 623 | if (mids->device_instance == 0) | 643 | if (mids->device_instance == 0) |
| 624 | cfg_hi.cfgx.src_per = 2; | 644 | cfg_hi.cfgx.src_per = 2; |
| 625 | if (mids->device_instance == 1) | 645 | if (mids->device_instance == 1) |
| @@ -636,7 +656,7 @@ static struct dma_async_tx_descriptor *intel_mid_dma_prep_memcpy( | |||
| 636 | /*calculate CTL_HI*/ | 656 | /*calculate CTL_HI*/ |
| 637 | ctl_hi.ctlx.reser = 0; | 657 | ctl_hi.ctlx.reser = 0; |
| 638 | ctl_hi.ctlx.done = 0; | 658 | ctl_hi.ctlx.done = 0; |
| 639 | width = mids->src_width; | 659 | width = mids->dma_slave.src_addr_width; |
| 640 | 660 | ||
| 641 | ctl_hi.ctlx.block_ts = get_block_ts(len, width, midc->dma->block_size); | 661 | ctl_hi.ctlx.block_ts = get_block_ts(len, width, midc->dma->block_size); |
| 642 | pr_debug("MDMA:calc len %d for block size %d\n", | 662 | pr_debug("MDMA:calc len %d for block size %d\n", |
| @@ -644,21 +664,21 @@ static struct dma_async_tx_descriptor *intel_mid_dma_prep_memcpy( | |||
| 644 | /*calculate CTL_LO*/ | 664 | /*calculate CTL_LO*/ |
| 645 | ctl_lo.ctl_lo = 0; | 665 | ctl_lo.ctl_lo = 0; |
| 646 | ctl_lo.ctlx.int_en = 1; | 666 | ctl_lo.ctlx.int_en = 1; |
| 647 | ctl_lo.ctlx.dst_tr_width = mids->dst_width; | 667 | ctl_lo.ctlx.dst_tr_width = mids->dma_slave.dst_addr_width; |
| 648 | ctl_lo.ctlx.src_tr_width = mids->src_width; | 668 | ctl_lo.ctlx.src_tr_width = mids->dma_slave.src_addr_width; |
| 649 | ctl_lo.ctlx.dst_msize = mids->src_msize; | 669 | ctl_lo.ctlx.dst_msize = mids->dma_slave.src_maxburst; |
| 650 | ctl_lo.ctlx.src_msize = mids->dst_msize; | 670 | ctl_lo.ctlx.src_msize = mids->dma_slave.dst_maxburst; |
| 651 | 671 | ||
| 652 | if (mids->cfg_mode == LNW_DMA_MEM_TO_MEM) { | 672 | if (mids->cfg_mode == LNW_DMA_MEM_TO_MEM) { |
| 653 | ctl_lo.ctlx.tt_fc = 0; | 673 | ctl_lo.ctlx.tt_fc = 0; |
| 654 | ctl_lo.ctlx.sinc = 0; | 674 | ctl_lo.ctlx.sinc = 0; |
| 655 | ctl_lo.ctlx.dinc = 0; | 675 | ctl_lo.ctlx.dinc = 0; |
| 656 | } else { | 676 | } else { |
| 657 | if (mids->dirn == DMA_TO_DEVICE) { | 677 | if (mids->dma_slave.direction == DMA_TO_DEVICE) { |
| 658 | ctl_lo.ctlx.sinc = 0; | 678 | ctl_lo.ctlx.sinc = 0; |
| 659 | ctl_lo.ctlx.dinc = 2; | 679 | ctl_lo.ctlx.dinc = 2; |
| 660 | ctl_lo.ctlx.tt_fc = 1; | 680 | ctl_lo.ctlx.tt_fc = 1; |
| 661 | } else if (mids->dirn == DMA_FROM_DEVICE) { | 681 | } else if (mids->dma_slave.direction == DMA_FROM_DEVICE) { |
| 662 | ctl_lo.ctlx.sinc = 2; | 682 | ctl_lo.ctlx.sinc = 2; |
| 663 | ctl_lo.ctlx.dinc = 0; | 683 | ctl_lo.ctlx.dinc = 0; |
| 664 | ctl_lo.ctlx.tt_fc = 2; | 684 | ctl_lo.ctlx.tt_fc = 2; |
| @@ -681,7 +701,7 @@ static struct dma_async_tx_descriptor *intel_mid_dma_prep_memcpy( | |||
| 681 | desc->ctl_lo = ctl_lo.ctl_lo; | 701 | desc->ctl_lo = ctl_lo.ctl_lo; |
| 682 | desc->ctl_hi = ctl_hi.ctl_hi; | 702 | desc->ctl_hi = ctl_hi.ctl_hi; |
| 683 | desc->width = width; | 703 | desc->width = width; |
| 684 | desc->dirn = mids->dirn; | 704 | desc->dirn = mids->dma_slave.direction; |
| 685 | desc->lli_phys = 0; | 705 | desc->lli_phys = 0; |
| 686 | desc->lli = NULL; | 706 | desc->lli = NULL; |
| 687 | desc->lli_pool = NULL; | 707 | desc->lli_pool = NULL; |
| @@ -722,7 +742,7 @@ static struct dma_async_tx_descriptor *intel_mid_dma_prep_slave_sg( | |||
| 722 | midc = to_intel_mid_dma_chan(chan); | 742 | midc = to_intel_mid_dma_chan(chan); |
| 723 | BUG_ON(!midc); | 743 | BUG_ON(!midc); |
| 724 | 744 | ||
| 725 | mids = chan->private; | 745 | mids = midc->mid_slave; |
| 726 | BUG_ON(!mids); | 746 | BUG_ON(!mids); |
| 727 | 747 | ||
| 728 | if (!midc->dma->pimr_mask) { | 748 | if (!midc->dma->pimr_mask) { |
diff --git a/drivers/dma/intel_mid_dma_regs.h b/drivers/dma/intel_mid_dma_regs.h index 7a5ac56d1324..709fecbdde79 100644 --- a/drivers/dma/intel_mid_dma_regs.h +++ b/drivers/dma/intel_mid_dma_regs.h | |||
| @@ -187,13 +187,13 @@ struct intel_mid_dma_chan { | |||
| 187 | struct list_head active_list; | 187 | struct list_head active_list; |
| 188 | struct list_head queue; | 188 | struct list_head queue; |
| 189 | struct list_head free_list; | 189 | struct list_head free_list; |
| 190 | struct intel_mid_dma_slave *slave; | ||
| 191 | unsigned int descs_allocated; | 190 | unsigned int descs_allocated; |
| 192 | struct middma_device *dma; | 191 | struct middma_device *dma; |
| 193 | bool busy; | 192 | bool busy; |
| 194 | bool in_use; | 193 | bool in_use; |
| 195 | u32 raw_tfr; | 194 | u32 raw_tfr; |
| 196 | u32 raw_block; | 195 | u32 raw_block; |
| 196 | struct intel_mid_dma_slave *mid_slave; | ||
| 197 | }; | 197 | }; |
| 198 | 198 | ||
| 199 | static inline struct intel_mid_dma_chan *to_intel_mid_dma_chan( | 199 | static inline struct intel_mid_dma_chan *to_intel_mid_dma_chan( |
| @@ -264,7 +264,7 @@ struct intel_mid_dma_desc { | |||
| 264 | dma_addr_t next; | 264 | dma_addr_t next; |
| 265 | enum dma_data_direction dirn; | 265 | enum dma_data_direction dirn; |
| 266 | enum dma_status status; | 266 | enum dma_status status; |
| 267 | enum intel_mid_dma_width width; /*width of DMA txn*/ | 267 | enum dma_slave_buswidth width; /*width of DMA txn*/ |
| 268 | enum intel_mid_dma_mode cfg_mode; /*mode configuration*/ | 268 | enum intel_mid_dma_mode cfg_mode; /*mode configuration*/ |
| 269 | 269 | ||
| 270 | }; | 270 | }; |
| @@ -289,6 +289,13 @@ static inline struct intel_mid_dma_desc *to_intel_mid_dma_desc | |||
| 289 | return container_of(txd, struct intel_mid_dma_desc, txd); | 289 | return container_of(txd, struct intel_mid_dma_desc, txd); |
| 290 | } | 290 | } |
| 291 | 291 | ||
| 292 | static inline struct intel_mid_dma_slave *to_intel_mid_dma_slave | ||
| 293 | (struct dma_slave_config *slave) | ||
| 294 | { | ||
| 295 | return container_of(slave, struct intel_mid_dma_slave, dma_slave); | ||
| 296 | } | ||
| 297 | |||
| 298 | |||
| 292 | int dma_resume(struct pci_dev *pci); | 299 | int dma_resume(struct pci_dev *pci); |
| 293 | 300 | ||
| 294 | #endif /*__INTEL_MID_DMAC_REGS_H__*/ | 301 | #endif /*__INTEL_MID_DMAC_REGS_H__*/ |
diff --git a/include/linux/intel_mid_dma.h b/include/linux/intel_mid_dma.h index befe3fbd9e28..10496bd24c5c 100644 --- a/include/linux/intel_mid_dma.h +++ b/include/linux/intel_mid_dma.h | |||
| @@ -28,14 +28,6 @@ | |||
| 28 | #include <linux/dmaengine.h> | 28 | #include <linux/dmaengine.h> |
| 29 | 29 | ||
| 30 | #define DMA_PREP_CIRCULAR_LIST (1 << 10) | 30 | #define DMA_PREP_CIRCULAR_LIST (1 << 10) |
| 31 | /*DMA transaction width, src and dstn width would be same | ||
| 32 | The DMA length must be width aligned, | ||
| 33 | for 32 bit width the length must be 32 bit (4bytes) aligned only*/ | ||
| 34 | enum intel_mid_dma_width { | ||
| 35 | LNW_DMA_WIDTH_8BIT = 0x0, | ||
| 36 | LNW_DMA_WIDTH_16BIT = 0x1, | ||
| 37 | LNW_DMA_WIDTH_32BIT = 0x2, | ||
| 38 | }; | ||
| 39 | 31 | ||
| 40 | /*DMA mode configurations*/ | 32 | /*DMA mode configurations*/ |
| 41 | enum intel_mid_dma_mode { | 33 | enum intel_mid_dma_mode { |
| @@ -75,15 +67,10 @@ enum intel_mid_dma_msize { | |||
| 75 | * peripheral device connected to single DMAC | 67 | * peripheral device connected to single DMAC |
| 76 | */ | 68 | */ |
| 77 | struct intel_mid_dma_slave { | 69 | struct intel_mid_dma_slave { |
| 78 | enum dma_data_direction dirn; | ||
| 79 | enum intel_mid_dma_width src_width; /*width of DMA src txn*/ | ||
| 80 | enum intel_mid_dma_width dst_width; /*width of DMA dst txn*/ | ||
| 81 | enum intel_mid_dma_hs_mode hs_mode; /*handshaking*/ | 70 | enum intel_mid_dma_hs_mode hs_mode; /*handshaking*/ |
| 82 | enum intel_mid_dma_mode cfg_mode; /*mode configuration*/ | 71 | enum intel_mid_dma_mode cfg_mode; /*mode configuration*/ |
| 83 | enum intel_mid_dma_msize src_msize; /*size if src burst*/ | ||
| 84 | enum intel_mid_dma_msize dst_msize; /*size of dst burst*/ | ||
| 85 | dma_addr_t per_addr; /*Peripheral address*/ | ||
| 86 | unsigned int device_instance; /*0, 1 for periphral instance*/ | 72 | unsigned int device_instance; /*0, 1 for periphral instance*/ |
| 73 | struct dma_slave_config dma_slave; | ||
| 87 | }; | 74 | }; |
| 88 | 75 | ||
| 89 | #endif /*__INTEL_MID_DMA_H__*/ | 76 | #endif /*__INTEL_MID_DMA_H__*/ |
