summaryrefslogtreecommitdiffstats
path: root/drivers/video
diff options
context:
space:
mode:
authorJon Mayo <jmayo@nvidia.com>2012-01-11 17:59:55 -0500
committerDan Willemsen <dwillemsen@nvidia.com>2015-03-18 15:02:02 -0400
commit5374c03a6c5b5ee5cfe7dfba08c02e91391b653e (patch)
tree724fc4aff0f4fcb5ee2ae9d6d628bd408f7ae750 /drivers/video
parent3b1ddb6ae7d6bfa8f7a917873298c31ff03a4c38 (diff)
video: tegra: dc: 1-shot bandwidth calculation
In one-shot mode(DSI) report emc rate as disabled to reduce bandwidth in this idle state. Use this same tegra_dc_clear_bandwidth() function to handle display disable for all types of displays. Bug 914917 Change-Id: I84ca1341d71999b3558f9dadb103b258a1a6ab6f Signed-off-by: Jon Mayo <jmayo@nvidia.com> Reviewed-on: http://git-master/r/74652 Reviewed-by: Automatic_Commit_Validation_User Reviewed-by: Kevin Huang (Eng-SW) <kevinh@nvidia.com> Tested-by: Xin Xie <xxie@nvidia.com> Reviewed-on: http://git-master/r/75536 Reviewed-by: Rohan Somvanshi <rsomvanshi@nvidia.com> Tested-by: Rohan Somvanshi <rsomvanshi@nvidia.com> Rebase-Id: Rf8b841c11fa8bf67ed3685b671edb221318e3281
Diffstat (limited to 'drivers/video')
-rw-r--r--drivers/video/tegra/dc/dc.c30
-rw-r--r--drivers/video/tegra/dc/dc_priv.h1
2 files changed, 25 insertions, 6 deletions
diff --git a/drivers/video/tegra/dc/dc.c b/drivers/video/tegra/dc/dc.c
index 73357ab81..73320b38c 100644
--- a/drivers/video/tegra/dc/dc.c
+++ b/drivers/video/tegra/dc/dc.c
@@ -973,11 +973,21 @@ unsigned long tegra_dc_get_bandwidth(struct tegra_dc_win *windows[], int n)
973 return tegra_dc_find_max_bandwidth(windows, n); 973 return tegra_dc_find_max_bandwidth(windows, n);
974} 974}
975 975
976/* to save power, call when display memory clients would be idle */
977static void tegra_dc_clear_bandwidth(struct tegra_dc *dc)
978{
979 if (dc->emc_clk_rate)
980 clk_disable(dc->emc_clk);
981 dc->emc_clk_rate = 0;
982}
983
976static void tegra_dc_program_bandwidth(struct tegra_dc *dc) 984static void tegra_dc_program_bandwidth(struct tegra_dc *dc)
977{ 985{
978 unsigned i; 986 unsigned i;
979 987
980 if (dc->emc_clk_rate != dc->new_emc_clk_rate) { 988 if (dc->emc_clk_rate != dc->new_emc_clk_rate) {
989 if (!dc->emc_clk_rate) /* going from 0 to non-zero */
990 clk_enable(dc->emc_clk);
981 dc->emc_clk_rate = dc->new_emc_clk_rate; 991 dc->emc_clk_rate = dc->new_emc_clk_rate;
982 clk_set_rate(dc->emc_clk, dc->emc_clk_rate); 992 clk_set_rate(dc->emc_clk, dc->emc_clk_rate);
983 } 993 }
@@ -1249,6 +1259,9 @@ int tegra_dc_update_windows(struct tegra_dc_win *windows[], int n)
1249 if (dc->out->flags & TEGRA_DC_OUT_ONE_SHOT_MODE) 1259 if (dc->out->flags & TEGRA_DC_OUT_ONE_SHOT_MODE)
1250 tegra_dc_writel(dc, NC_HOST_TRIG, DC_CMD_STATE_CONTROL); 1260 tegra_dc_writel(dc, NC_HOST_TRIG, DC_CMD_STATE_CONTROL);
1251 1261
1262 /* update EMC clock if calculated bandwidth has changed */
1263 tegra_dc_program_bandwidth(dc);
1264
1252 mutex_unlock(&dc->lock); 1265 mutex_unlock(&dc->lock);
1253 1266
1254 return 0; 1267 return 0;
@@ -1922,9 +1935,6 @@ static void tegra_dc_vblank(struct work_struct *work)
1922 1935
1923 mutex_lock(&dc->lock); 1936 mutex_lock(&dc->lock);
1924 1937
1925 /* update EMC clock if calculated bandwidth has changed */
1926 tegra_dc_program_bandwidth(dc);
1927
1928 /* Update the SD brightness */ 1938 /* Update the SD brightness */
1929 if (dc->enabled && dc->out->sd_settings) 1939 if (dc->enabled && dc->out->sd_settings)
1930 nvsd_updated = nvsd_update_brightness(dc); 1940 nvsd_updated = nvsd_update_brightness(dc);
@@ -1942,6 +1952,13 @@ static void tegra_dc_vblank(struct work_struct *work)
1942 } 1952 }
1943} 1953}
1944 1954
1955static void tegra_dc_one_shot_worker(struct work_struct *work)
1956{
1957 struct tegra_dc *dc = container_of(work, struct tegra_dc, one_shot_work);
1958 /* memory client has gone idle */
1959 tegra_dc_clear_bandwidth(dc);
1960}
1961
1945/* return an arbitrarily large number if count overflow occurs. 1962/* return an arbitrarily large number if count overflow occurs.
1946 * make it a nice base-10 number to show up in stats output */ 1963 * make it a nice base-10 number to show up in stats output */
1947static u64 tegra_dc_underflow_count(struct tegra_dc *dc, unsigned reg) 1964static u64 tegra_dc_underflow_count(struct tegra_dc *dc, unsigned reg)
@@ -2038,6 +2055,8 @@ static void tegra_dc_one_shot_irq(struct tegra_dc *dc, unsigned long status)
2038 } 2055 }
2039 2056
2040 if (status & FRAME_END_INT) { 2057 if (status & FRAME_END_INT) {
2058 schedule_work(&dc->one_shot_work);
2059
2041 /* Mark the frame_end as complete. */ 2060 /* Mark the frame_end as complete. */
2042 if (!completion_done(&dc->frame_end_complete)) 2061 if (!completion_done(&dc->frame_end_complete))
2043 complete(&dc->frame_end_complete); 2062 complete(&dc->frame_end_complete);
@@ -2288,7 +2307,6 @@ static bool _tegra_dc_controller_enable(struct tegra_dc *dc)
2288 2307
2289 tegra_dc_setup_clk(dc, dc->clk); 2308 tegra_dc_setup_clk(dc, dc->clk);
2290 clk_enable(dc->clk); 2309 clk_enable(dc->clk);
2291 clk_enable(dc->emc_clk);
2292 2310
2293 /* do not accept interrupts during initialization */ 2311 /* do not accept interrupts during initialization */
2294 tegra_dc_writel(dc, 0, DC_CMD_INT_ENABLE); 2312 tegra_dc_writel(dc, 0, DC_CMD_INT_ENABLE);
@@ -2320,7 +2338,6 @@ static bool _tegra_dc_controller_reset_enable(struct tegra_dc *dc)
2320 2338
2321 tegra_dc_setup_clk(dc, dc->clk); 2339 tegra_dc_setup_clk(dc, dc->clk);
2322 clk_enable(dc->clk); 2340 clk_enable(dc->clk);
2323 clk_enable(dc->emc_clk);
2324 2341
2325 if (dc->ndev->id == 0 && tegra_dcs[1] != NULL) { 2342 if (dc->ndev->id == 0 && tegra_dcs[1] != NULL) {
2326 mutex_lock(&tegra_dcs[1]->lock); 2343 mutex_lock(&tegra_dcs[1]->lock);
@@ -2397,7 +2414,7 @@ static void _tegra_dc_controller_disable(struct tegra_dc *dc)
2397 if (dc->out_ops && dc->out_ops->disable) 2414 if (dc->out_ops && dc->out_ops->disable)
2398 dc->out_ops->disable(dc); 2415 dc->out_ops->disable(dc);
2399 2416
2400 clk_disable(dc->emc_clk); 2417 tegra_dc_clear_bandwidth(dc);
2401 clk_disable(dc->clk); 2418 clk_disable(dc->clk);
2402 tegra_dvfs_set_rate(dc->clk, 0); 2419 tegra_dvfs_set_rate(dc->clk, 0);
2403 2420
@@ -2653,6 +2670,7 @@ static int tegra_dc_probe(struct nvhost_device *ndev)
2653#endif 2670#endif
2654 INIT_WORK(&dc->vblank_work, tegra_dc_vblank); 2671 INIT_WORK(&dc->vblank_work, tegra_dc_vblank);
2655 INIT_DELAYED_WORK(&dc->underflow_work, tegra_dc_underflow_worker); 2672 INIT_DELAYED_WORK(&dc->underflow_work, tegra_dc_underflow_worker);
2673 INIT_WORK(&dc->one_shot_work, tegra_dc_one_shot_worker);
2656 2674
2657 tegra_dc_init_lut_defaults(&dc->fb_lut); 2675 tegra_dc_init_lut_defaults(&dc->fb_lut);
2658 2676
diff --git a/drivers/video/tegra/dc/dc_priv.h b/drivers/video/tegra/dc/dc_priv.h
index 2245b4eb4..989fa1b5f 100644
--- a/drivers/video/tegra/dc/dc_priv.h
+++ b/drivers/video/tegra/dc/dc_priv.h
@@ -133,6 +133,7 @@ struct tegra_dc {
133#endif 133#endif
134 struct tegra_dc_lut fb_lut; 134 struct tegra_dc_lut fb_lut;
135 struct delayed_work underflow_work; 135 struct delayed_work underflow_work;
136 struct work_struct one_shot_work;
136}; 137};
137 138
138static inline void tegra_dc_io_start(struct tegra_dc *dc) 139static inline void tegra_dc_io_start(struct tegra_dc *dc)