aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSameer Pujar <spujar@nvidia.com>2019-05-02 08:55:14 -0400
committerVinod Koul <vkoul@kernel.org>2019-05-04 06:43:41 -0400
commit433de642a76c9e68641ee5a8c7b2720d4e8629a5 (patch)
tree84a7b9d4a1b395919fe01f82e7a51825ce353792
parentc0e74dd25422e32f2e65ee868c8b5c828b8c5b61 (diff)
dmaengine: tegra210-adma: add support for Tegra186/Tegra194
Add Tegra186 specific macro defines and chip_data structure for chip specific information. New compatibility is added to select relevant chip details. There is no major change for Tegra194 and hence it can use the same chip data. The bits in the BURST_SIZE field of the ADMA CH_CONFIG register are encoded differently on Tegra186 and Tegra194 compared with Tegra210. On Tegra210 the bits are encoded as follows ... 1 = WORD_1 2 = WORDS_2 3 = WORDS_4 4 = WORDS_8 5 = WORDS_16 Where as on Tegra186 and Tegra194 the bits are encoded as ... 0 = WORD_1 1 = WORDS_2 2 = WORDS_3 3 = WORDS_4 4 = WORDS_5 ... 15 = WORDS_16 Add helper functions for generating the correct burst size. Signed-off-by: Sameer Pujar <spujar@nvidia.com> Reviewed-by: Jon Hunter <jonathanh@nvidia.com> Signed-off-by: Vinod Koul <vkoul@kernel.org>
-rw-r--r--drivers/dma/tegra210-adma.c45
1 files changed, 37 insertions, 8 deletions
diff --git a/drivers/dma/tegra210-adma.c b/drivers/dma/tegra210-adma.c
index 9aee015609bd..115ee10f067c 100644
--- a/drivers/dma/tegra210-adma.c
+++ b/drivers/dma/tegra210-adma.c
@@ -45,8 +45,8 @@
45#define ADMA_CH_CONFIG 0x28 45#define ADMA_CH_CONFIG 0x28
46#define ADMA_CH_CONFIG_SRC_BUF(val) (((val) & 0x7) << 28) 46#define ADMA_CH_CONFIG_SRC_BUF(val) (((val) & 0x7) << 28)
47#define ADMA_CH_CONFIG_TRG_BUF(val) (((val) & 0x7) << 24) 47#define ADMA_CH_CONFIG_TRG_BUF(val) (((val) & 0x7) << 24)
48#define ADMA_CH_CONFIG_BURST_SIZE(val) (((val) & 0x7) << 20) 48#define ADMA_CH_CONFIG_BURST_SIZE_SHIFT 20
49#define ADMA_CH_CONFIG_BURST_16 5 49#define ADMA_CH_CONFIG_MAX_BURST_SIZE 16
50#define ADMA_CH_CONFIG_WEIGHT_FOR_WRR(val) ((val) & 0xf) 50#define ADMA_CH_CONFIG_WEIGHT_FOR_WRR(val) ((val) & 0xf)
51#define ADMA_CH_CONFIG_MAX_BUFS 8 51#define ADMA_CH_CONFIG_MAX_BUFS 8
52 52
@@ -87,6 +87,7 @@ struct tegra_adma;
87 * @nr_channels: Number of DMA channels available. 87 * @nr_channels: Number of DMA channels available.
88 */ 88 */
89struct tegra_adma_chip_data { 89struct tegra_adma_chip_data {
90 unsigned int (*adma_get_burst_config)(unsigned int burst_size);
90 unsigned int global_reg_offset; 91 unsigned int global_reg_offset;
91 unsigned int global_int_clear; 92 unsigned int global_int_clear;
92 unsigned int ch_req_tx_shift; 93 unsigned int ch_req_tx_shift;
@@ -489,6 +490,22 @@ static enum dma_status tegra_adma_tx_status(struct dma_chan *dc,
489 return ret; 490 return ret;
490} 491}
491 492
493static unsigned int tegra210_adma_get_burst_config(unsigned int burst_size)
494{
495 if (!burst_size || burst_size > ADMA_CH_CONFIG_MAX_BURST_SIZE)
496 burst_size = ADMA_CH_CONFIG_MAX_BURST_SIZE;
497
498 return fls(burst_size) << ADMA_CH_CONFIG_BURST_SIZE_SHIFT;
499}
500
501static unsigned int tegra186_adma_get_burst_config(unsigned int burst_size)
502{
503 if (!burst_size || burst_size > ADMA_CH_CONFIG_MAX_BURST_SIZE)
504 burst_size = ADMA_CH_CONFIG_MAX_BURST_SIZE;
505
506 return (burst_size - 1) << ADMA_CH_CONFIG_BURST_SIZE_SHIFT;
507}
508
492static int tegra_adma_set_xfer_params(struct tegra_adma_chan *tdc, 509static int tegra_adma_set_xfer_params(struct tegra_adma_chan *tdc,
493 struct tegra_adma_desc *desc, 510 struct tegra_adma_desc *desc,
494 dma_addr_t buf_addr, 511 dma_addr_t buf_addr,
@@ -504,7 +521,7 @@ static int tegra_adma_set_xfer_params(struct tegra_adma_chan *tdc,
504 switch (direction) { 521 switch (direction) {
505 case DMA_MEM_TO_DEV: 522 case DMA_MEM_TO_DEV:
506 adma_dir = ADMA_CH_CTRL_DIR_MEM2AHUB; 523 adma_dir = ADMA_CH_CTRL_DIR_MEM2AHUB;
507 burst_size = fls(tdc->sconfig.dst_maxburst); 524 burst_size = tdc->sconfig.dst_maxburst;
508 ch_regs->config = ADMA_CH_CONFIG_SRC_BUF(desc->num_periods - 1); 525 ch_regs->config = ADMA_CH_CONFIG_SRC_BUF(desc->num_periods - 1);
509 ch_regs->ctrl = ADMA_CH_REG_FIELD_VAL(tdc->sreq_index, 526 ch_regs->ctrl = ADMA_CH_REG_FIELD_VAL(tdc->sreq_index,
510 cdata->ch_req_mask, 527 cdata->ch_req_mask,
@@ -514,7 +531,7 @@ static int tegra_adma_set_xfer_params(struct tegra_adma_chan *tdc,
514 531
515 case DMA_DEV_TO_MEM: 532 case DMA_DEV_TO_MEM:
516 adma_dir = ADMA_CH_CTRL_DIR_AHUB2MEM; 533 adma_dir = ADMA_CH_CTRL_DIR_AHUB2MEM;
517 burst_size = fls(tdc->sconfig.src_maxburst); 534 burst_size = tdc->sconfig.src_maxburst;
518 ch_regs->config = ADMA_CH_CONFIG_TRG_BUF(desc->num_periods - 1); 535 ch_regs->config = ADMA_CH_CONFIG_TRG_BUF(desc->num_periods - 1);
519 ch_regs->ctrl = ADMA_CH_REG_FIELD_VAL(tdc->sreq_index, 536 ch_regs->ctrl = ADMA_CH_REG_FIELD_VAL(tdc->sreq_index,
520 cdata->ch_req_mask, 537 cdata->ch_req_mask,
@@ -527,13 +544,10 @@ static int tegra_adma_set_xfer_params(struct tegra_adma_chan *tdc,
527 return -EINVAL; 544 return -EINVAL;
528 } 545 }
529 546
530 if (!burst_size || burst_size > ADMA_CH_CONFIG_BURST_16)
531 burst_size = ADMA_CH_CONFIG_BURST_16;
532
533 ch_regs->ctrl |= ADMA_CH_CTRL_DIR(adma_dir) | 547 ch_regs->ctrl |= ADMA_CH_CTRL_DIR(adma_dir) |
534 ADMA_CH_CTRL_MODE_CONTINUOUS | 548 ADMA_CH_CTRL_MODE_CONTINUOUS |
535 ADMA_CH_CTRL_FLOWCTRL_EN; 549 ADMA_CH_CTRL_FLOWCTRL_EN;
536 ch_regs->config |= ADMA_CH_CONFIG_BURST_SIZE(burst_size); 550 ch_regs->config |= cdata->adma_get_burst_config(burst_size);
537 ch_regs->config |= ADMA_CH_CONFIG_WEIGHT_FOR_WRR(1); 551 ch_regs->config |= ADMA_CH_CONFIG_WEIGHT_FOR_WRR(1);
538 ch_regs->fifo_ctrl = ADMA_CH_FIFO_CTRL_DEFAULT; 552 ch_regs->fifo_ctrl = ADMA_CH_FIFO_CTRL_DEFAULT;
539 ch_regs->tc = desc->period_len & ADMA_CH_TC_COUNT_MASK; 553 ch_regs->tc = desc->period_len & ADMA_CH_TC_COUNT_MASK;
@@ -671,6 +685,7 @@ static int tegra_adma_runtime_resume(struct device *dev)
671} 685}
672 686
673static const struct tegra_adma_chip_data tegra210_chip_data = { 687static const struct tegra_adma_chip_data tegra210_chip_data = {
688 .adma_get_burst_config = tegra210_adma_get_burst_config,
674 .global_reg_offset = 0xc00, 689 .global_reg_offset = 0xc00,
675 .global_int_clear = 0x20, 690 .global_int_clear = 0x20,
676 .ch_req_tx_shift = 28, 691 .ch_req_tx_shift = 28,
@@ -682,8 +697,22 @@ static const struct tegra_adma_chip_data tegra210_chip_data = {
682 .nr_channels = 22, 697 .nr_channels = 22,
683}; 698};
684 699
700static const struct tegra_adma_chip_data tegra186_chip_data = {
701 .adma_get_burst_config = tegra186_adma_get_burst_config,
702 .global_reg_offset = 0,
703 .global_int_clear = 0x402c,
704 .ch_req_tx_shift = 27,
705 .ch_req_rx_shift = 22,
706 .ch_base_offset = 0x10000,
707 .ch_req_mask = 0x1f,
708 .ch_req_max = 20,
709 .ch_reg_size = 0x100,
710 .nr_channels = 32,
711};
712
685static const struct of_device_id tegra_adma_of_match[] = { 713static const struct of_device_id tegra_adma_of_match[] = {
686 { .compatible = "nvidia,tegra210-adma", .data = &tegra210_chip_data }, 714 { .compatible = "nvidia,tegra210-adma", .data = &tegra210_chip_data },
715 { .compatible = "nvidia,tegra186-adma", .data = &tegra186_chip_data },
687 { }, 716 { },
688}; 717};
689MODULE_DEVICE_TABLE(of, tegra_adma_of_match); 718MODULE_DEVICE_TABLE(of, tegra_adma_of_match);