Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

spi: tegra210-quad: Add runtime autosuspend support

Using Tegra234, it was found that it takes about 10us to disable clocks
and 20us to enable clocks, adding about 30us overhead per operation.
For a 4MB firmware update with 16,384 page programs, this results in
~491ms total overhead (12% impact).

With Tegra234, flash operations were observed to occur in bursts with
50-200μs gaps between page programs. Testing on Tegra234 with various
operation patterns shows 500ms delay provides optimal balance, and for
longer operations (>500ms), the overhead is negligible. Therefore,
update the driver to use pm-runtime autosuspend with the default timeout
of 500ms to reduce the clock gating overhead during consecutive QSPI
transfers.

Signed-off-by: Vishwaroop A <va@nvidia.com>
Link: https://patch.msgid.link/20260224092452.1482800-1-va@nvidia.com
Signed-off-by: Mark Brown <broonie@kernel.org>

authored by

Vishwaroop A and committed by
Mark Brown
7c12f6ea 507a071d

+16 -3
+16 -3
drivers/spi/spi-tegra210-quad.c
··· 1000 1000 1001 1001 spin_unlock_irqrestore(&tqspi->lock, flags); 1002 1002 1003 - pm_runtime_put(tqspi->dev); 1003 + pm_runtime_mark_last_busy(tqspi->dev); 1004 + pm_runtime_put_autosuspend(tqspi->dev); 1004 1005 1005 1006 return 0; 1006 1007 } ··· 1766 1765 init_completion(&tqspi->rx_dma_complete); 1767 1766 init_completion(&tqspi->xfer_completion); 1768 1767 1768 + /* 1769 + * Set autosuspend delay to 500ms. Testing shows this value eliminates 1770 + * suspend/resume overhead during burst operations while allowing quick 1771 + * suspension during idle. For longer operations, the overhead is negligible. 1772 + */ 1773 + pm_runtime_set_autosuspend_delay(&pdev->dev, 500); 1774 + pm_runtime_use_autosuspend(&pdev->dev); 1775 + 1769 1776 pm_runtime_enable(&pdev->dev); 1770 1777 ret = pm_runtime_resume_and_get(&pdev->dev); 1771 1778 if (ret < 0) { ··· 1790 1781 tqspi->spi_cs_timing2 = tegra_qspi_readl(tqspi, QSPI_CS_TIMING2); 1791 1782 tqspi->def_command2_reg = tegra_qspi_readl(tqspi, QSPI_COMMAND2); 1792 1783 1793 - pm_runtime_put(&pdev->dev); 1784 + pm_runtime_mark_last_busy(&pdev->dev); 1785 + pm_runtime_put_autosuspend(&pdev->dev); 1794 1786 1795 1787 ret = request_threaded_irq(tqspi->irq, NULL, 1796 1788 tegra_qspi_isr_thread, IRQF_ONESHOT, ··· 1812 1802 exit_free_irq: 1813 1803 free_irq(qspi_irq, tqspi); 1814 1804 exit_pm_disable: 1805 + pm_runtime_dont_use_autosuspend(&pdev->dev); 1815 1806 pm_runtime_force_suspend(&pdev->dev); 1816 1807 tegra_qspi_deinit_dma(tqspi); 1817 1808 return ret; ··· 1825 1814 1826 1815 spi_unregister_controller(host); 1827 1816 free_irq(tqspi->irq, tqspi); 1817 + pm_runtime_dont_use_autosuspend(&pdev->dev); 1828 1818 pm_runtime_force_suspend(&pdev->dev); 1829 1819 tegra_qspi_deinit_dma(tqspi); 1830 1820 } ··· 1851 1839 1852 1840 tegra_qspi_writel(tqspi, tqspi->command1_reg, QSPI_COMMAND1); 1853 1841 tegra_qspi_writel(tqspi, tqspi->def_command2_reg, QSPI_COMMAND2); 1854 - pm_runtime_put(dev); 1842 + pm_runtime_mark_last_busy(dev); 1843 + pm_runtime_put_autosuspend(dev); 1855 1844 1856 1845 return spi_controller_resume(host); 1857 1846 }