summaryrefslogtreecommitdiffstats
path: root/drivers/video
diff options
context:
space:
mode:
authorAnimesh Kishore <ankishore@nvidia.com>2011-08-26 15:22:41 -0400
committerDan Willemsen <dwillemsen@nvidia.com>2015-03-18 15:01:40 -0400
commitf78de6b4d64b550db4bef14801351893bef3ea4a (patch)
tree65fd408ca8a0dd4d5df371ce8b4a87a1c3cffadf /drivers/video
parent64f2e2884bd3399599854baaf5e95898b91f9673 (diff)
video: tegra: dsi: deep sleep
Aggregate code for dsi deep sleep Bug 862427 Original-Change-Id: I5296e6659112642f9fe0fb84bec1d5938014c33a Reviewed-on: http://git-master/r/49506 Reviewed-by: Animesh Kishore <ankishore@nvidia.com> Tested-by: Animesh Kishore <ankishore@nvidia.com> Reviewed-by: Kevin Huang <kevinh@nvidia.com> Reviewed-by: Bitan Biswas <bbiswas@nvidia.com> Rebase-Id: Ref7c30c407efe88481af5f2d23e5892bb0d05ef3
Diffstat (limited to 'drivers/video')
-rw-r--r--drivers/video/tegra/dc/dsi.c160
1 files changed, 79 insertions, 81 deletions
diff --git a/drivers/video/tegra/dc/dsi.c b/drivers/video/tegra/dc/dsi.c
index 9c260ea7c..57208c2df 100644
--- a/drivers/video/tegra/dc/dsi.c
+++ b/drivers/video/tegra/dc/dsi.c
@@ -2069,70 +2069,95 @@ static void tegra_dc_dsi_destroy(struct tegra_dc *dc)
2069 kfree(dsi); 2069 kfree(dsi);
2070} 2070}
2071 2071
2072static void tegra_dc_dsi_disable(struct tegra_dc *dc) 2072static int tegra_dsi_deep_sleep(struct tegra_dc *dc,
2073 struct tegra_dc_dsi_data *dsi)
2073{ 2074{
2074 int err; 2075 int err = 0;
2075 u32 val; 2076 int val;
2076 struct clk *base_clk; 2077 struct clk *parent_clk = NULL;
2077 struct tegra_dc_dsi_data *dsi = tegra_dc_get_outdata(dc); 2078 struct clk *base_clk = NULL;
2078 2079
2079 tegra_dc_io_start(dc); 2080 if (!dsi->enabled) {
2080 mutex_lock(&dsi->lock); 2081 err = -EPERM;
2082 goto fail;
2083 }
2081 2084
2082 if (dsi->status.dc_stream == DSI_DC_STREAM_ENABLE) 2085 err = tegra_dsi_set_to_lp_mode(dc, dsi);
2083 tegra_dsi_stop_dc_stream_at_frame_end(dc, dsi); 2086 if (err < 0) {
2087 dev_err(&dc->ndev->dev,
2088 "DSI failed to go to LP mode\n");
2089 goto fail;
2090 }
2084 2091
2085 if (dsi->info.power_saving_suspend) { 2092 /* Suspend panel */
2086 if (!dsi->enabled) 2093 err = tegra_dsi_send_panel_cmd(dc, dsi,
2087 goto fail; 2094 dsi->info.dsi_suspend_cmd,
2095 dsi->info.n_suspend_cmd);
2096 if (err < 0) {
2097 dev_err(&dc->ndev->dev,
2098 "dsi: Error sending suspend cmd\n");
2099 goto fail;
2100 }
2088 2101
2089 err = tegra_dsi_set_to_lp_mode(dc, dsi); 2102 if (!dsi->ulpm) {
2103 err = tegra_dsi_enter_ulpm(dsi);
2090 if (err < 0) { 2104 if (err < 0) {
2091 dev_err(&dc->ndev->dev, 2105 dev_err(&dc->ndev->dev,
2092 "DSI failed to go to LP mode\n"); 2106 "DSI failed to enter ulpm\n");
2093 goto fail; 2107 goto fail;
2094 } 2108 }
2109 }
2095 2110
2096 err = tegra_dsi_send_panel_cmd(dc, dsi, 2111 /* Suspend pad */
2097 dsi->info.dsi_suspend_cmd, 2112 val = tegra_dsi_readl(dsi, DSI_PAD_CONTROL);
2098 dsi->info.n_suspend_cmd); 2113 val = DSI_PAD_CONTROL_PAD_PDIO(0x3) |
2099 if (err < 0) { 2114 DSI_PAD_CONTROL_PAD_PDIO_CLK(0x1) |
2100 dev_err(&dc->ndev->dev, 2115 DSI_PAD_CONTROL_PAD_PULLDN_ENAB(TEGRA_DSI_ENABLE);
2101 "dsi: Error sending suspend cmd\n"); 2116 tegra_dsi_writel(dsi, val, DSI_PAD_CONTROL);
2102 goto fail;
2103 }
2104 2117
2105 if (!dsi->ulpm) { 2118 /* Suspend core-logic */
2106 if (tegra_dsi_enter_ulpm(dsi) < 0) 2119 val = DSI_POWER_CONTROL_LEG_DSI_ENABLE(TEGRA_DSI_DISABLE);
2107 printk(KERN_ERR "DSI failed to enter ulpm\n"); 2120 tegra_dsi_writel(dsi, val, DSI_POWER_CONTROL);
2108 }
2109 2121
2110 /* Suspend pad */ 2122 /* Disable dsi fast and slow clock */
2111 val = tegra_dsi_readl(dsi, DSI_PAD_CONTROL); 2123 parent_clk = clk_get_parent(dsi->dsi_clk);
2112 val = DSI_PAD_CONTROL_PAD_PDIO(0x3) | 2124 base_clk = clk_get_parent(parent_clk);
2113 DSI_PAD_CONTROL_PAD_PDIO_CLK(0x1) | 2125 if (dsi->info.dsi_instance)
2114 DSI_PAD_CONTROL_PAD_PULLDN_ENAB(TEGRA_DSI_ENABLE); 2126 tegra_clk_cfg_ex(base_clk,
2115 tegra_dsi_writel(dsi, val, DSI_PAD_CONTROL); 2127 TEGRA_CLK_PLLD_CSI_OUT_ENB,
2128 0);
2129 else
2130 tegra_clk_cfg_ex(base_clk,
2131 TEGRA_CLK_PLLD_DSI_OUT_ENB,
2132 0);
2116 2133
2117 /* Suspend core-logic */ 2134 /* Disable dsi source clock */
2118 val = DSI_POWER_CONTROL_LEG_DSI_ENABLE(TEGRA_DSI_DISABLE); 2135 clk_disable(dsi->dsi_clk);
2119 tegra_dsi_writel(dsi, val, DSI_POWER_CONTROL);
2120 2136
2121 /* Disable phy clock */ 2137 dsi->clk_ref = false;
2122 base_clk = clk_get_parent(dsi->dsi_clk); 2138 dsi->enabled = false;
2123 if (dsi->info.dsi_instance)
2124 tegra_clk_cfg_ex(base_clk,
2125 TEGRA_CLK_PLLD_CSI_OUT_ENB,
2126 0);
2127 else
2128 tegra_clk_cfg_ex(base_clk,
2129 TEGRA_CLK_PLLD_DSI_OUT_ENB,
2130 0);
2131 2139
2132 /* Disable DSI source clock */ 2140 return 0;
2133 clk_disable(dsi->dsi_clk); 2141fail:
2134 dsi->clk_ref = false; 2142 return err;
2135 dsi->enabled = false; 2143}
2144
2145static void tegra_dc_dsi_disable(struct tegra_dc *dc)
2146{
2147 int err;
2148 struct tegra_dc_dsi_data *dsi = tegra_dc_get_outdata(dc);
2149
2150 tegra_dc_io_start(dc);
2151 mutex_lock(&dsi->lock);
2152
2153 if (dsi->status.dc_stream == DSI_DC_STREAM_ENABLE)
2154 tegra_dsi_stop_dc_stream_at_frame_end(dc, dsi);
2155
2156 if (dsi->info.power_saving_suspend) {
2157 if (tegra_dsi_deep_sleep(dc, dsi) < 0) {
2158 printk(KERN_ERR "DSI failed to enter deep sleep\n");
2159 goto fail;
2160 }
2136 } else { 2161 } else {
2137 if (dsi->info.dsi_early_suspend_cmd) { 2162 if (dsi->info.dsi_early_suspend_cmd) {
2138 err = tegra_dsi_send_panel_cmd(dc, dsi, 2163 err = tegra_dsi_send_panel_cmd(dc, dsi,
@@ -2146,8 +2171,10 @@ static void tegra_dc_dsi_disable(struct tegra_dc *dc)
2146 } 2171 }
2147 2172
2148 if (!dsi->ulpm) { 2173 if (!dsi->ulpm) {
2149 if (tegra_dsi_enter_ulpm(dsi) < 0) 2174 if (tegra_dsi_enter_ulpm(dsi) < 0) {
2150 printk(KERN_ERR "DSI failed to enter ulpm\n"); 2175 printk(KERN_ERR "DSI failed to enter ulpm\n");
2176 goto fail;
2177 }
2151 } 2178 }
2152 } 2179 }
2153 2180
@@ -2160,8 +2187,6 @@ fail:
2160static void tegra_dc_dsi_suspend(struct tegra_dc *dc) 2187static void tegra_dc_dsi_suspend(struct tegra_dc *dc)
2161{ 2188{
2162 struct tegra_dc_dsi_data *dsi; 2189 struct tegra_dc_dsi_data *dsi;
2163 int err;
2164 u32 val;
2165 2190
2166 dsi = tegra_dc_get_outdata(dc); 2191 dsi = tegra_dc_get_outdata(dc);
2167 2192
@@ -2179,37 +2204,10 @@ static void tegra_dc_dsi_suspend(struct tegra_dc *dc)
2179 } 2204 }
2180 } 2205 }
2181 2206
2182 /* Suspend Panel */ 2207 if (tegra_dsi_deep_sleep(dc, dsi) < 0) {
2183 err = tegra_dsi_send_panel_cmd(dc, dsi, 2208 printk(KERN_ERR "DSI failed to enter deep sleep\n");
2184 dsi->info.dsi_suspend_cmd,
2185 dsi->info.n_suspend_cmd);
2186 if (err < 0) {
2187 dev_err(&dc->ndev->dev,
2188 "dsi: Error sending suspend cmd\n");
2189 goto fail; 2209 goto fail;
2190 } 2210 }
2191 if (!dsi->ulpm) {
2192 if (tegra_dsi_enter_ulpm(dsi) < 0) {
2193 printk(KERN_ERR "DSI failed to enter ulpm\n");
2194 goto fail;
2195 }
2196 }
2197
2198 /* Suspend pad */
2199 val = tegra_dsi_readl(dsi, DSI_PAD_CONTROL);
2200 val = DSI_PAD_CONTROL_PAD_PDIO(0x3) |
2201 DSI_PAD_CONTROL_PAD_PDIO_CLK(0x1) |
2202 DSI_PAD_CONTROL_PAD_PULLDN_ENAB(TEGRA_DSI_ENABLE);
2203 tegra_dsi_writel(dsi, val, DSI_PAD_CONTROL);
2204
2205 /* Suspend core-logic */
2206 val = DSI_POWER_CONTROL_LEG_DSI_ENABLE(TEGRA_DSI_DISABLE);
2207 tegra_dsi_writel(dsi, val, DSI_POWER_CONTROL);
2208
2209 dsi->enabled = false;
2210
2211 clk_disable(dsi->dsi_clk);
2212 dsi->clk_ref = false;
2213 } 2211 }
2214fail: 2212fail:
2215 mutex_unlock(&dsi->lock); 2213 mutex_unlock(&dsi->lock);