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

drm/tegra: hdmi: Implement runtime PM

Use runtime PM to clock-(un)gate and (de)assert reset to the HDMI
controller. This ties in nicely with atomic DPMS in that a runtime PM
reference is taken before a pipe is enabled and dropped after it has
been shut down.

Signed-off-by: Thierry Reding <treding@nvidia.com>

+88 -47
+88 -47
drivers/gpu/drm/tegra/hdmi.c
··· 11 11 #include <linux/debugfs.h> 12 12 #include <linux/gpio.h> 13 13 #include <linux/hdmi.h> 14 + #include <linux/pm_runtime.h> 14 15 #include <linux/regulator/consumer.h> 15 16 #include <linux/reset.h> 16 17 ··· 642 641 tegra_hdmi_writel(hdmi, value, HDMI_NV_PDISP_HDMI_GENERIC_CTRL); 643 642 } 644 643 644 + static void tegra_hdmi_write_eld(struct tegra_hdmi *hdmi) 645 + { 646 + size_t length = drm_eld_size(hdmi->output.connector.eld), i; 647 + u32 value; 648 + 649 + for (i = 0; i < length; i++) 650 + tegra_hdmi_writel(hdmi, i << 8 | hdmi->output.connector.eld[i], 651 + HDMI_NV_PDISP_SOR_AUDIO_HDA_ELD_BUFWR); 652 + 653 + /* 654 + * The HDA codec will always report an ELD buffer size of 96 bytes and 655 + * the HDA codec driver will check that each byte read from the buffer 656 + * is valid. Therefore every byte must be written, even if no 96 bytes 657 + * were parsed from EDID. 658 + */ 659 + for (i = length; i < HDMI_ELD_BUFFER_SIZE; i++) 660 + tegra_hdmi_writel(hdmi, i << 8 | 0, 661 + HDMI_NV_PDISP_SOR_AUDIO_HDA_ELD_BUFWR); 662 + 663 + value = SOR_AUDIO_HDA_PRESENSE_VALID | SOR_AUDIO_HDA_PRESENSE_PRESENT; 664 + tegra_hdmi_writel(hdmi, value, HDMI_NV_PDISP_SOR_AUDIO_HDA_PRESENSE); 665 + } 666 + 645 667 static inline u32 tegra_hdmi_subpack(const u8 *ptr, size_t size) 646 668 { 647 669 u32 value = 0; ··· 969 945 tegra_hdmi_disable_avi_infoframe(hdmi); 970 946 tegra_hdmi_disable_audio(hdmi); 971 947 } 972 - } 973 948 974 - static void tegra_hdmi_write_eld(struct tegra_hdmi *hdmi) 975 - { 976 - size_t length = drm_eld_size(hdmi->output.connector.eld), i; 977 - u32 value; 949 + tegra_hdmi_writel(hdmi, 0, HDMI_NV_PDISP_INT_ENABLE); 950 + tegra_hdmi_writel(hdmi, 0, HDMI_NV_PDISP_INT_MASK); 978 951 979 - for (i = 0; i < length; i++) 980 - tegra_hdmi_writel(hdmi, i << 8 | hdmi->output.connector.eld[i], 981 - HDMI_NV_PDISP_SOR_AUDIO_HDA_ELD_BUFWR); 982 - 983 - /* 984 - * The HDA codec will always report an ELD buffer size of 96 bytes and 985 - * the HDA codec driver will check that each byte read from the buffer 986 - * is valid. Therefore every byte must be written, even if no 96 bytes 987 - * were parsed from EDID. 988 - */ 989 - for (i = length; i < HDMI_ELD_BUFFER_SIZE; i++) 990 - tegra_hdmi_writel(hdmi, i << 8 | 0, 991 - HDMI_NV_PDISP_SOR_AUDIO_HDA_ELD_BUFWR); 992 - 993 - value = SOR_AUDIO_HDA_PRESENSE_VALID | SOR_AUDIO_HDA_PRESENSE_PRESENT; 994 - tegra_hdmi_writel(hdmi, value, HDMI_NV_PDISP_SOR_AUDIO_HDA_PRESENSE); 952 + pm_runtime_put(hdmi->dev); 995 953 } 996 954 997 955 static void tegra_hdmi_encoder_enable(struct drm_encoder *encoder) ··· 987 981 int retries = 1000; 988 982 u32 value; 989 983 int err; 984 + 985 + pm_runtime_get_sync(hdmi->dev); 986 + 987 + /* 988 + * Enable and unmask the HDA codec SCRATCH0 register interrupt. This 989 + * is used for interoperability between the HDA codec driver and the 990 + * HDMI driver. 991 + */ 992 + tegra_hdmi_writel(hdmi, INT_CODEC_SCRATCH0, HDMI_NV_PDISP_INT_ENABLE); 993 + tegra_hdmi_writel(hdmi, INT_CODEC_SCRATCH0, HDMI_NV_PDISP_INT_MASK); 990 994 991 995 hdmi->pixel_clock = mode->clock * 1000; 992 996 h_sync_width = mode->hsync_end - mode->hsync_start; ··· 1523 1507 return err; 1524 1508 } 1525 1509 1526 - err = clk_prepare_enable(hdmi->clk); 1527 - if (err < 0) { 1528 - dev_err(hdmi->dev, "failed to enable clock: %d\n", err); 1529 - return err; 1530 - } 1531 - 1532 - reset_control_deassert(hdmi->rst); 1533 - 1534 - /* 1535 - * Enable and unmask the HDA codec SCRATCH0 register interrupt. This 1536 - * is used for interoperability between the HDA codec driver and the 1537 - * HDMI driver. 1538 - */ 1539 - tegra_hdmi_writel(hdmi, INT_CODEC_SCRATCH0, HDMI_NV_PDISP_INT_ENABLE); 1540 - tegra_hdmi_writel(hdmi, INT_CODEC_SCRATCH0, HDMI_NV_PDISP_INT_MASK); 1541 - 1542 1510 return 0; 1543 1511 } 1544 1512 ··· 1530 1530 { 1531 1531 struct tegra_hdmi *hdmi = host1x_client_to_hdmi(client); 1532 1532 1533 - tegra_hdmi_writel(hdmi, 0, HDMI_NV_PDISP_INT_MASK); 1534 - tegra_hdmi_writel(hdmi, 0, HDMI_NV_PDISP_INT_ENABLE); 1535 - 1536 1533 tegra_output_exit(&hdmi->output); 1537 - 1538 - reset_control_assert(hdmi->rst); 1539 - clk_disable_unprepare(hdmi->clk); 1540 1534 1541 1535 regulator_disable(hdmi->vdd); 1542 1536 regulator_disable(hdmi->pll); ··· 1746 1752 return err; 1747 1753 } 1748 1754 1755 + platform_set_drvdata(pdev, hdmi); 1756 + pm_runtime_enable(&pdev->dev); 1757 + 1749 1758 INIT_LIST_HEAD(&hdmi->client.list); 1750 1759 hdmi->client.ops = &hdmi_client_ops; 1751 1760 hdmi->client.dev = &pdev->dev; ··· 1760 1763 return err; 1761 1764 } 1762 1765 1763 - platform_set_drvdata(pdev, hdmi); 1764 - 1765 1766 return 0; 1766 1767 } 1767 1768 ··· 1767 1772 { 1768 1773 struct tegra_hdmi *hdmi = platform_get_drvdata(pdev); 1769 1774 int err; 1775 + 1776 + pm_runtime_disable(&pdev->dev); 1770 1777 1771 1778 err = host1x_client_unregister(&hdmi->client); 1772 1779 if (err < 0) { ··· 1779 1782 1780 1783 tegra_output_remove(&hdmi->output); 1781 1784 1782 - clk_disable_unprepare(hdmi->clk_parent); 1785 + return 0; 1786 + } 1787 + 1788 + #ifdef CONFIG_PM 1789 + static int tegra_hdmi_suspend(struct device *dev) 1790 + { 1791 + struct tegra_hdmi *hdmi = dev_get_drvdata(dev); 1792 + int err; 1793 + 1794 + err = reset_control_assert(hdmi->rst); 1795 + if (err < 0) { 1796 + dev_err(dev, "failed to assert reset: %d\n", err); 1797 + return err; 1798 + } 1799 + 1800 + usleep_range(1000, 2000); 1801 + 1783 1802 clk_disable_unprepare(hdmi->clk); 1784 1803 1785 1804 return 0; 1786 1805 } 1787 1806 1807 + static int tegra_hdmi_resume(struct device *dev) 1808 + { 1809 + struct tegra_hdmi *hdmi = dev_get_drvdata(dev); 1810 + int err; 1811 + 1812 + err = clk_prepare_enable(hdmi->clk); 1813 + if (err < 0) { 1814 + dev_err(dev, "failed to enable clock: %d\n", err); 1815 + return err; 1816 + } 1817 + 1818 + usleep_range(1000, 2000); 1819 + 1820 + err = reset_control_deassert(hdmi->rst); 1821 + if (err < 0) { 1822 + dev_err(dev, "failed to deassert reset: %d\n", err); 1823 + clk_disable_unprepare(hdmi->clk); 1824 + return err; 1825 + } 1826 + 1827 + return 0; 1828 + } 1829 + #endif 1830 + 1831 + static const struct dev_pm_ops tegra_hdmi_pm_ops = { 1832 + SET_RUNTIME_PM_OPS(tegra_hdmi_suspend, tegra_hdmi_resume, NULL) 1833 + }; 1834 + 1788 1835 struct platform_driver tegra_hdmi_driver = { 1789 1836 .driver = { 1790 1837 .name = "tegra-hdmi", 1791 - .owner = THIS_MODULE, 1792 1838 .of_match_table = tegra_hdmi_of_match, 1839 + .pm = &tegra_hdmi_pm_ops, 1793 1840 }, 1794 1841 .probe = tegra_hdmi_probe, 1795 1842 .remove = tegra_hdmi_remove,