From: Mohan Kumar <mkumard@xxxxxxxxxx> Tegra ADMA HW supports multiple PAGES for virtualization, to support virtualization support reg-names property has been added to DT binding to know the hypervisor mode. Also in hypervisor mode the ADMA global registers are not accessed by guest OS. Signed-off-by: Mohan Kumar <mkumard@xxxxxxxxxx> Signed-off-by: Sameer Pujar <spujar@xxxxxxxxxx> --- drivers/dma/tegra210-adma.c | 44 ++++++++++++++++++++++++++++++------- 1 file changed, 36 insertions(+), 8 deletions(-) diff --git a/drivers/dma/tegra210-adma.c b/drivers/dma/tegra210-adma.c index 24ad7077c53b..92f1c0c949dd 100644 --- a/drivers/dma/tegra210-adma.c +++ b/drivers/dma/tegra210-adma.c @@ -160,6 +160,8 @@ struct tegra_adma { /* Used to store global command register state when suspending */ unsigned int global_cmd; + bool is_virtualized; + const struct tegra_adma_chip_data *cdata; /* Last member of the structure */ @@ -222,8 +224,15 @@ static int tegra_adma_init(struct tegra_adma *tdma) u32 status; int ret; - /* Clear any interrupts */ - tdma_write(tdma, tdma->cdata->ch_base_offset + tdma->cdata->global_int_clear, 0x1); + if (!tdma->is_virtualized) { + /* Clear any interrupts */ + tdma_write(tdma, tdma->cdata->ch_base_offset + tdma->cdata->global_int_clear, 0x1); + } else { + /* For virtualized mode, ADMA global registers are not accessed */ + tdma_write(tdma, tdma->cdata->global_int_clear, 0x1); + tdma->global_cmd = 1; + return 0; + } /* Assert soft reset */ tdma_write(tdma, ADMA_GLOBAL_SOFT_RESET, 0x1); @@ -736,7 +745,9 @@ static int __maybe_unused tegra_adma_runtime_suspend(struct device *dev) struct tegra_adma_chan *tdc; int i; - tdma->global_cmd = tdma_read(tdma, ADMA_GLOBAL_CMD); + if (!tdma->is_virtualized) + tdma->global_cmd = tdma_read(tdma, ADMA_GLOBAL_CMD); + if (!tdma->global_cmd) goto clk_disable; @@ -777,7 +788,9 @@ static int __maybe_unused tegra_adma_runtime_resume(struct device *dev) dev_err(dev, "ahub clk_enable failed: %d\n", ret); return ret; } - tdma_write(tdma, ADMA_GLOBAL_CMD, tdma->global_cmd); + + if (!tdma->is_virtualized) + tdma_write(tdma, ADMA_GLOBAL_CMD, tdma->global_cmd); if (!tdma->global_cmd) return 0; @@ -846,6 +859,8 @@ static int tegra_adma_probe(struct platform_device *pdev) { const struct tegra_adma_chip_data *cdata; struct tegra_adma *tdma; + unsigned int ch_base_offset; + struct resource *res; int ret, i; cdata = of_device_get_match_data(&pdev->dev); @@ -865,9 +880,22 @@ static int tegra_adma_probe(struct platform_device *pdev) tdma->nr_channels = cdata->nr_channels; platform_set_drvdata(pdev, tdma); - tdma->base_addr = devm_platform_ioremap_resource(pdev, 0); - if (IS_ERR(tdma->base_addr)) - return PTR_ERR(tdma->base_addr); + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "vm"); + if (res) { + tdma->base_addr = devm_ioremap_resource(&pdev->dev, res); + if (IS_ERR(tdma->base_addr)) + return PTR_ERR(tdma->base_addr); + + tdma->is_virtualized = true; + ch_base_offset = 0; + } else { + tdma->base_addr = devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(tdma->base_addr)) + return PTR_ERR(tdma->base_addr); + + tdma->is_virtualized = false; + ch_base_offset = cdata->ch_base_offset; + } tdma->ahub_clk = devm_clk_get(&pdev->dev, "d_audio"); if (IS_ERR(tdma->ahub_clk)) { @@ -900,7 +928,7 @@ static int tegra_adma_probe(struct platform_device *pdev) if (!test_bit(i, tdma->dma_chan_mask)) continue; - tdc->chan_addr = tdma->base_addr + cdata->ch_base_offset + tdc->chan_addr = tdma->base_addr + ch_base_offset + (cdata->ch_reg_size * i); tdc->irq = of_irq_get(pdev->dev.of_node, i); -- 2.45.1