diff options
author | Yangbo Lu <yangbo.lu@nxp.com> | 2020-04-10 10:47:05 +0800 |
---|---|---|
committer | Petr Štetiar <ynezz@true.cz> | 2020-05-07 12:53:06 +0200 |
commit | cddd4591404fb4c53dc0b3c0b15b942cdbed4356 (patch) | |
tree | 392c1179de46b0f804e3789edca19069b64e6b44 /target/linux/layerscape/patches-5.4/806-dma-0012-MLK-17094-dma-fsl-edma-v3-add-suspend-resume-to-rest.patch | |
parent | d1d2c0b5579ea4f69a42246c9318539d61ba1999 (diff) | |
download | upstream-cddd4591404fb4c53dc0b3c0b15b942cdbed4356.tar.gz upstream-cddd4591404fb4c53dc0b3c0b15b942cdbed4356.tar.bz2 upstream-cddd4591404fb4c53dc0b3c0b15b942cdbed4356.zip |
layerscape: add patches-5.4
Add patches for linux-5.4. The patches are from NXP LSDK-20.04 release
which was tagged LSDK-20.04-V5.4.
https://source.codeaurora.org/external/qoriq/qoriq-components/linux/
For boards LS1021A-IOT, and Traverse-LS1043 which are not involved in
LSDK, port the dts patches from 4.14.
The patches are sorted into the following categories:
301-arch-xxxx
302-dts-xxxx
303-core-xxxx
701-net-xxxx
801-audio-xxxx
802-can-xxxx
803-clock-xxxx
804-crypto-xxxx
805-display-xxxx
806-dma-xxxx
807-gpio-xxxx
808-i2c-xxxx
809-jailhouse-xxxx
810-keys-xxxx
811-kvm-xxxx
812-pcie-xxxx
813-pm-xxxx
814-qe-xxxx
815-sata-xxxx
816-sdhc-xxxx
817-spi-xxxx
818-thermal-xxxx
819-uart-xxxx
820-usb-xxxx
821-vfio-xxxx
Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
Diffstat (limited to 'target/linux/layerscape/patches-5.4/806-dma-0012-MLK-17094-dma-fsl-edma-v3-add-suspend-resume-to-rest.patch')
-rw-r--r-- | target/linux/layerscape/patches-5.4/806-dma-0012-MLK-17094-dma-fsl-edma-v3-add-suspend-resume-to-rest.patch | 192 |
1 files changed, 192 insertions, 0 deletions
diff --git a/target/linux/layerscape/patches-5.4/806-dma-0012-MLK-17094-dma-fsl-edma-v3-add-suspend-resume-to-rest.patch b/target/linux/layerscape/patches-5.4/806-dma-0012-MLK-17094-dma-fsl-edma-v3-add-suspend-resume-to-rest.patch new file mode 100644 index 0000000000..e9ca236556 --- /dev/null +++ b/target/linux/layerscape/patches-5.4/806-dma-0012-MLK-17094-dma-fsl-edma-v3-add-suspend-resume-to-rest.patch @@ -0,0 +1,192 @@ +From 411a2f6ad13bd58646de34a340553232044f0951 Mon Sep 17 00:00:00 2001 +From: Robin Gong <yibin.gong@nxp.com> +Date: Mon, 4 Dec 2017 15:35:09 +0800 +Subject: [PATCH] MLK-17094 dma: fsl-edma-v3: add suspend/resume to restore + back channel registers + +Add suspend to save channel registers and resume to restore them back since +edmav3 may powered off in suspend. + +Signed-off-by: Robin Gong <yibin.gong@nxp.com> +(cherry picked from commit 7eda1ae538ec7e7c0f993b3ea91805459f3dedd3) +--- + drivers/dma/fsl-edma-v3.c | 86 +++++++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 86 insertions(+) + +--- a/drivers/dma/fsl-edma-v3.c ++++ b/drivers/dma/fsl-edma-v3.c +@@ -111,6 +111,11 @@ + #define CHAN_PREFIX "edma0-chan" + #define CHAN_POSFIX "-tx" + ++enum fsl_edma3_pm_state { ++ RUNNING = 0, ++ SUSPENDED, ++}; ++ + struct fsl_edma3_hw_tcd { + __le32 saddr; + __le16 soff; +@@ -142,6 +147,8 @@ struct fsl_edma3_slave_config { + struct fsl_edma3_chan { + struct virt_dma_chan vchan; + enum dma_status status; ++ enum fsl_edma3_pm_state pm_state; ++ bool idle; + struct fsl_edma3_engine *edma3; + struct fsl_edma3_desc *edesc; + struct fsl_edma3_slave_config fsc; +@@ -165,11 +172,18 @@ struct fsl_edma3_desc { + struct fsl_edma3_sw_tcd tcd[]; + }; + ++struct fsl_edma3_reg_save { ++ u32 csr; ++ u32 sbr; ++}; ++ + struct fsl_edma3_engine { + struct dma_device dma_dev; + struct mutex fsl_edma3_mutex; + u32 n_chans; + int errirq; ++ #define MAX_CHAN_NUM 32 ++ struct fsl_edma3_reg_save edma_regs[MAX_CHAN_NUM]; + bool swap; /* remote/local swapped on Audio edma */ + struct fsl_edma3_chan chans[]; + }; +@@ -266,6 +280,7 @@ static int fsl_edma3_terminate_all(struc + spin_lock_irqsave(&fsl_chan->vchan.lock, flags); + fsl_edma3_disable_request(fsl_chan); + fsl_chan->edesc = NULL; ++ fsl_chan->idle = true; + vchan_get_all_descriptors(&fsl_chan->vchan, &head); + spin_unlock_irqrestore(&fsl_chan->vchan.lock, flags); + vchan_dma_desc_free_list(&fsl_chan->vchan, &head); +@@ -281,6 +296,7 @@ static int fsl_edma3_pause(struct dma_ch + if (fsl_chan->edesc) { + fsl_edma3_disable_request(fsl_chan); + fsl_chan->status = DMA_PAUSED; ++ fsl_chan->idle = true; + } + spin_unlock_irqrestore(&fsl_chan->vchan.lock, flags); + return 0; +@@ -295,6 +311,7 @@ static int fsl_edma3_resume(struct dma_c + if (fsl_chan->edesc) { + fsl_edma3_enable_request(fsl_chan); + fsl_chan->status = DMA_IN_PROGRESS; ++ fsl_chan->idle = false; + } + spin_unlock_irqrestore(&fsl_chan->vchan.lock, flags); + return 0; +@@ -664,6 +681,7 @@ static void fsl_edma3_xfer_desc(struct f + fsl_edma3_set_tcd_regs(fsl_chan, fsl_chan->edesc->tcd[0].vtcd); + fsl_edma3_enable_request(fsl_chan); + fsl_chan->status = DMA_IN_PROGRESS; ++ fsl_chan->idle = false; + } + + static size_t fsl_edma3_desc_residue(struct fsl_edma3_chan *fsl_chan, +@@ -700,6 +718,7 @@ static irqreturn_t fsl_edma3_tx_handler( + vchan_cookie_complete(&fsl_chan->edesc->vdesc); + fsl_chan->edesc = NULL; + fsl_chan->status = DMA_COMPLETE; ++ fsl_chan->idle = true; + } else { + vchan_cyclic_callback(&fsl_chan->edesc->vdesc); + } +@@ -719,6 +738,12 @@ static void fsl_edma3_issue_pending(stru + + spin_lock_irqsave(&fsl_chan->vchan.lock, flags); + ++ if (unlikely(fsl_chan->pm_state != RUNNING)) { ++ spin_unlock_irqrestore(&fsl_chan->vchan.lock, flags); ++ /* cannot submit due to suspend */ ++ return; ++ } ++ + if (vchan_issue_pending(&fsl_chan->vchan) && !fsl_chan->edesc) + fsl_edma3_xfer_desc(fsl_chan); + +@@ -821,6 +846,8 @@ static int fsl_edma3_probe(struct platfo + unsigned long val; + + fsl_chan->edma3 = fsl_edma3; ++ fsl_chan->pm_state = RUNNING; ++ fsl_chan->idle = true; + /* Get per channel membase */ + res = platform_get_resource(pdev, IORESOURCE_MEM, i); + fsl_chan->membase = devm_ioremap_resource(&pdev->dev, res); +@@ -932,6 +959,64 @@ static int fsl_edma3_remove(struct platf + return 0; + } + ++static int fsl_edma3_suspend_late(struct device *dev) ++{ ++ struct fsl_edma3_engine *fsl_edma = dev_get_drvdata(dev); ++ struct fsl_edma3_chan *fsl_chan; ++ unsigned long flags; ++ void __iomem *addr; ++ int i; ++ ++ for (i = 0; i < fsl_edma->n_chans; i++) { ++ fsl_chan = &fsl_edma->chans[i]; ++ addr = fsl_chan->membase; ++ ++ spin_lock_irqsave(&fsl_chan->vchan.lock, flags); ++ fsl_edma->edma_regs[i].csr = readl(addr + EDMA_CH_CSR); ++ fsl_edma->edma_regs[i].sbr = readl(addr + EDMA_CH_SBR); ++ /* Make sure chan is idle or will force disable. */ ++ if (unlikely(!fsl_chan->idle)) { ++ dev_warn(dev, "WARN: There is non-idle channel."); ++ fsl_edma3_disable_request(fsl_chan); ++ } ++ fsl_chan->pm_state = SUSPENDED; ++ spin_unlock_irqrestore(&fsl_chan->vchan.lock, flags); ++ } ++ ++ return 0; ++} ++ ++static int fsl_edma3_resume_early(struct device *dev) ++{ ++ struct fsl_edma3_engine *fsl_edma = dev_get_drvdata(dev); ++ struct fsl_edma3_chan *fsl_chan; ++ void __iomem *addr; ++ unsigned long flags; ++ int i; ++ ++ for (i = 0; i < fsl_edma->n_chans; i++) { ++ fsl_chan = &fsl_edma->chans[i]; ++ addr = fsl_chan->membase; ++ ++ spin_lock_irqsave(&fsl_chan->vchan.lock, flags); ++ writel(fsl_edma->edma_regs[i].csr, addr + EDMA_CH_CSR); ++ writel(fsl_edma->edma_regs[i].sbr, addr + EDMA_CH_SBR); ++ /* restore tcd if this channel not terminated before suspend */ ++ if (fsl_chan->edesc) ++ fsl_edma3_set_tcd_regs(fsl_chan, ++ fsl_chan->edesc->tcd[0].vtcd); ++ fsl_chan->pm_state = RUNNING; ++ spin_unlock_irqrestore(&fsl_chan->vchan.lock, flags); ++ } ++ ++ return 0; ++} ++ ++static const struct dev_pm_ops fsl_edma3_pm_ops = { ++ .suspend_late = fsl_edma3_suspend_late, ++ .resume_early = fsl_edma3_resume_early, ++}; ++ + static const struct of_device_id fsl_edma3_dt_ids[] = { + { .compatible = "fsl,imx8qm-edma", }, + { .compatible = "fsl,imx8qm-adma", }, +@@ -943,6 +1028,7 @@ static struct platform_driver fsl_edma3_ + .driver = { + .name = "fsl-edma-v3", + .of_match_table = fsl_edma3_dt_ids, ++ .pm = &fsl_edma3_pm_ops, + }, + .probe = fsl_edma3_probe, + .remove = fsl_edma3_remove, |