|
14 | 14 | #include <linux/of_graph.h>
|
15 | 15 | #include <linux/of_irq.h>
|
16 | 16 | #include <linux/pinctrl/consumer.h>
|
| 17 | +#include <linux/pm_opp.h> |
17 | 18 | #include <linux/regmap.h>
|
18 | 19 | #include <linux/regulator/consumer.h>
|
19 | 20 | #include <linux/spinlock.h>
|
@@ -111,6 +112,9 @@ struct msm_dsi_host {
|
111 | 112 | struct clk *pixel_clk_src;
|
112 | 113 | struct clk *byte_intf_clk;
|
113 | 114 |
|
| 115 | + struct opp_table *opp_table; |
| 116 | + bool has_opp_table; |
| 117 | + |
114 | 118 | u32 byte_clk_rate;
|
115 | 119 | u32 pixel_clk_rate;
|
116 | 120 | u32 esc_clk_rate;
|
@@ -512,9 +516,10 @@ int dsi_link_clk_set_rate_6g(struct msm_dsi_host *msm_host)
|
512 | 516 | DBG("Set clk rates: pclk=%d, byteclk=%d",
|
513 | 517 | msm_host->mode->clock, msm_host->byte_clk_rate);
|
514 | 518 |
|
515 |
| - ret = clk_set_rate(msm_host->byte_clk, msm_host->byte_clk_rate); |
| 519 | + ret = dev_pm_opp_set_rate(&msm_host->pdev->dev, |
| 520 | + msm_host->byte_clk_rate); |
516 | 521 | if (ret) {
|
517 |
| - pr_err("%s: Failed to set rate byte clk, %d\n", __func__, ret); |
| 522 | + pr_err("%s: dev_pm_opp_set_rate failed %d\n", __func__, ret); |
518 | 523 | return ret;
|
519 | 524 | }
|
520 | 525 |
|
@@ -658,6 +663,8 @@ int dsi_link_clk_enable_v2(struct msm_dsi_host *msm_host)
|
658 | 663 |
|
659 | 664 | void dsi_link_clk_disable_6g(struct msm_dsi_host *msm_host)
|
660 | 665 | {
|
| 666 | + /* Drop the performance state vote */ |
| 667 | + dev_pm_opp_set_rate(&msm_host->pdev->dev, 0); |
661 | 668 | clk_disable_unprepare(msm_host->esc_clk);
|
662 | 669 | clk_disable_unprepare(msm_host->pixel_clk);
|
663 | 670 | if (msm_host->byte_intf_clk)
|
@@ -1879,6 +1886,19 @@ int msm_dsi_host_init(struct msm_dsi *msm_dsi)
|
1879 | 1886 | goto fail;
|
1880 | 1887 | }
|
1881 | 1888 |
|
| 1889 | + msm_host->opp_table = dev_pm_opp_set_clkname(&pdev->dev, "byte"); |
| 1890 | + if (IS_ERR(msm_host->opp_table)) |
| 1891 | + return PTR_ERR(msm_host->opp_table); |
| 1892 | + /* OPP table is optional */ |
| 1893 | + ret = dev_pm_opp_of_add_table(&pdev->dev); |
| 1894 | + if (!ret) { |
| 1895 | + msm_host->has_opp_table = true; |
| 1896 | + } else if (ret != -ENODEV) { |
| 1897 | + dev_err(&pdev->dev, "invalid OPP table in device tree\n"); |
| 1898 | + dev_pm_opp_put_clkname(msm_host->opp_table); |
| 1899 | + return ret; |
| 1900 | + } |
| 1901 | + |
1882 | 1902 | init_completion(&msm_host->dma_comp);
|
1883 | 1903 | init_completion(&msm_host->video_comp);
|
1884 | 1904 | mutex_init(&msm_host->dev_mutex);
|
@@ -1914,6 +1934,9 @@ void msm_dsi_host_destroy(struct mipi_dsi_host *host)
|
1914 | 1934 | mutex_destroy(&msm_host->cmd_mutex);
|
1915 | 1935 | mutex_destroy(&msm_host->dev_mutex);
|
1916 | 1936 |
|
| 1937 | + if (msm_host->has_opp_table) |
| 1938 | + dev_pm_opp_of_remove_table(&msm_host->pdev->dev); |
| 1939 | + dev_pm_opp_put_clkname(msm_host->opp_table); |
1917 | 1940 | pm_runtime_disable(&msm_host->pdev->dev);
|
1918 | 1941 | }
|
1919 | 1942 |
|
|
0 commit comments