summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorShu Zhong <shuz@nvidia.com>2016-09-01 16:40:00 -0400
committermobile promotions <svcmobile_promotions@nvidia.com>2016-09-09 17:03:46 -0400
commit21d71493c9327a09f7b752766152c55cfa07f4e5 (patch)
tree52e467f6d996ba48ec113137872545cf3dabb969
parenta3e6e6090817f992e3b526cf135ac6e2017b4bba (diff)
video: tegra: nvdisp: clear and init bw
1) The display driver should explicitly clear its ISO bw when all heads are disabled. 2) When display comes back, it will use the bw settings for the max config. These settings will eventually be adjusted through IMP, if supported by the client. Bug 1705477 Bug 1753714 Change-Id: Ibdff1440f2b1f8e4ff464a0ef3966a70fc3f2178 Signed-off-by: Shu Zhong <shuz@nvidia.com> Reviewed-on: http://git-master/r/1213146 Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> Tested-by: mobile promotions <svcmobile_promotions@nvidia.com>
-rw-r--r--drivers/video/tegra/dc/nvdisp/nvdisp.c15
-rw-r--r--drivers/video/tegra/dc/nvdisp/nvdisp.h2
-rw-r--r--drivers/video/tegra/dc/nvdisp/nvdisp_bandwidth.c64
3 files changed, 47 insertions, 34 deletions
diff --git a/drivers/video/tegra/dc/nvdisp/nvdisp.c b/drivers/video/tegra/dc/nvdisp/nvdisp.c
index c71ffc426..6991817c8 100644
--- a/drivers/video/tegra/dc/nvdisp/nvdisp.c
+++ b/drivers/video/tegra/dc/nvdisp/nvdisp.c
@@ -1373,8 +1373,9 @@ int tegra_nvdisp_head_disable(struct tegra_dc *dc)
1373 break; 1373 break;
1374 } 1374 }
1375 1375
1376 /* disable hub clock if none of the heads is using it */ 1376 /* disable hub clock if none of the heads is using it and clear bw */
1377 if (idx == TEGRA_MAX_DC) { 1377 if (idx == TEGRA_MAX_DC) {
1378 tegra_nvdisp_clear_bandwidth(dc);
1378 tegra_disp_clk_disable_unprepare(hubclk); 1379 tegra_disp_clk_disable_unprepare(hubclk);
1379 hubclk_already_on = false; 1380 hubclk_already_on = false;
1380 } 1381 }
@@ -1410,22 +1411,14 @@ int tegra_nvdisp_head_enable(struct tegra_dc *dc)
1410 } 1411 }
1411 clk_set_parent(hubclk, hubparent_clk); 1412 clk_set_parent(hubclk, hubparent_clk);
1412 1413
1413 /*
1414 * WAR for bug 200212319
1415 *
1416 * IMP will ultimately be responsible for setting the required hubclk
1417 * rate in the kernel, but it's not ready yet. As such, explicitly drive
1418 * the hubclk rate to 408MHz so that we're not stuck with the rate set
1419 * by BL.
1420 */
1421 clk_set_rate(hubclk, 408000000);
1422
1423 /* set clock status to inuse */ 1414 /* set clock status to inuse */
1424 mutex_lock(&tegra_nvdisp_lock); 1415 mutex_lock(&tegra_nvdisp_lock);
1425 clk_client[dc->ctrl_num].inuse = true; 1416 clk_client[dc->ctrl_num].inuse = true;
1426 clk_client[dc->ctrl_num].dc = dc; 1417 clk_client[dc->ctrl_num].dc = dc;
1427 1418
1419 /* turn on hub clock and init bw */
1428 if (!hubclk_already_on) { 1420 if (!hubclk_already_on) {
1421 tegra_nvdisp_init_bandwidth(dc);
1429 tegra_disp_clk_prepare_enable(hubclk); 1422 tegra_disp_clk_prepare_enable(hubclk);
1430 hubclk_already_on = true; 1423 hubclk_already_on = true;
1431 } 1424 }
diff --git a/drivers/video/tegra/dc/nvdisp/nvdisp.h b/drivers/video/tegra/dc/nvdisp/nvdisp.h
index 7641161f4..5bf446d31 100644
--- a/drivers/video/tegra/dc/nvdisp/nvdisp.h
+++ b/drivers/video/tegra/dc/nvdisp/nvdisp.h
@@ -57,4 +57,6 @@ void tegra_nvdisp_program_bandwidth(struct tegra_dc *dc, u32 proposed_bw,
57 u32 proposed_latency, u32 proposed_hubclk, bool before_win_udpate); 57 u32 proposed_latency, u32 proposed_hubclk, bool before_win_udpate);
58int tegra_nvdisp_negotiate_reserved_bw(struct tegra_dc *dc, u32 proposed_bw, 58int tegra_nvdisp_negotiate_reserved_bw(struct tegra_dc *dc, u32 proposed_bw,
59 u32 proposed_latency); 59 u32 proposed_latency);
60void tegra_nvdisp_init_bandwidth(struct tegra_dc *dc);
61void tegra_nvdisp_clear_bandwidth(struct tegra_dc *dc);
60#endif 62#endif
diff --git a/drivers/video/tegra/dc/nvdisp/nvdisp_bandwidth.c b/drivers/video/tegra/dc/nvdisp/nvdisp_bandwidth.c
index e0294cbbe..bdf77d59f 100644
--- a/drivers/video/tegra/dc/nvdisp/nvdisp_bandwidth.c
+++ b/drivers/video/tegra/dc/nvdisp/nvdisp_bandwidth.c
@@ -42,8 +42,8 @@
42 * - Pitch 42 * - Pitch
43 * - LUT disabled 43 * - LUT disabled
44 * 44 *
45 * NVDISP_BW_MAX_BW_KBPS and NVDISP_BW_TOTAL_MC_LATENCY were calculated with 45 * NVDISP_BW_MAX_BW_KBPS, NVDISP_BW_TOTAL_MC_LATENCY, and
46 * these settings: 46 * NVDISP_BW_REQ_HUBCLK_HZ were calculated with these settings:
47 * - 3 active heads: 47 * - 3 active heads:
48 * - 4096x2160@60p 48 * - 4096x2160@60p
49 * - 2 active windows on each head: 49 * - 2 active windows on each head:
@@ -73,6 +73,9 @@
73/* Total MC request latency that display can tolerate (usec) */ 73/* Total MC request latency that display can tolerate (usec) */
74#define NVDISP_BW_TOTAL_MC_LATENCY 1 74#define NVDISP_BW_TOTAL_MC_LATENCY 1
75 75
76/* Required hubclk rate for max config (Hz) */
77#define NVDISP_BW_REQ_HUBCLK_HZ 362000000
78
76/* Output id that we pass to tegra_dc_ext_process_bandwidth_negotiate */ 79/* Output id that we pass to tegra_dc_ext_process_bandwidth_negotiate */
77#define NVDISP_BW_OUTPUT_ID 0 80#define NVDISP_BW_OUTPUT_ID 0
78 81
@@ -189,6 +192,40 @@ void tegra_nvdisp_program_bandwidth(struct tegra_dc *dc,
189 } 192 }
190} 193}
191 194
195void tegra_nvdisp_init_bandwidth(struct tegra_dc *dc)
196{
197 /*
198 * Use the max config settings. These values will eventually be adjusted
199 * through IMP, if the client supports it.
200 */
201
202 u32 proposed_bw = NVDISP_BW_MAX_BW_KBPS;
203 u32 proposed_latency = NVDISP_BW_TOTAL_MC_LATENCY;
204 u32 proposed_hubclk = NVDISP_BW_REQ_HUBCLK_HZ;
205 bool before_win_update = true;
206
207 tegra_nvdisp_negotiate_reserved_bw(dc, proposed_bw, proposed_latency);
208 tegra_nvdisp_program_bandwidth(dc,
209 proposed_bw,
210 proposed_latency,
211 proposed_hubclk,
212 before_win_update);
213}
214
215void tegra_nvdisp_clear_bandwidth(struct tegra_dc *dc)
216{
217 u32 proposed_bw = 0;
218 u32 proposed_latency = 1000;
219 u32 proposed_hubclk = 0;
220 bool before_win_update = false;
221
222 tegra_nvdisp_program_bandwidth(dc,
223 proposed_bw,
224 proposed_latency,
225 proposed_hubclk,
226 before_win_update);
227}
228
192/* 229/*
193 * tegra_dc_calc_min_bandwidth - returns the minimum dedicated bw 230 * tegra_dc_calc_min_bandwidth - returns the minimum dedicated bw
194 * 231 *
@@ -284,7 +321,6 @@ void tegra_nvdisp_isomgr_attach(struct tegra_dc *dc)
284 */ 321 */
285int tegra_nvdisp_isomgr_register(enum tegra_iso_client client, u32 udedi_bw) 322int tegra_nvdisp_isomgr_register(enum tegra_iso_client client, u32 udedi_bw)
286{ 323{
287 u32 latency = 0;
288 int err = 0; 324 int err = 0;
289 325
290 mutex_lock(&tegra_nvdisp_lock); 326 mutex_lock(&tegra_nvdisp_lock);
@@ -303,26 +339,6 @@ int tegra_nvdisp_isomgr_register(enum tegra_iso_client client, u32 udedi_bw)
303 */ 339 */
304 ihub_bw_info.available_bw = UINT_MAX; 340 ihub_bw_info.available_bw = UINT_MAX;
305 341
306 /*
307 * Reserve and realize the max bw at start-up. There's no need to update
308 * the corresponding fields since these values will be adjusted through
309 * IMP anyways.
310 */
311 latency = tegra_isomgr_reserve(ihub_bw_info.isomgr_handle,
312 NVDISP_BW_MAX_BW_KBPS,
313 NVDISP_BW_TOTAL_MC_LATENCY);
314 if (latency) {
315 latency = tegra_isomgr_realize(ihub_bw_info.isomgr_handle);
316 if (!latency) {
317 WARN_ONCE(!latency, "tegra_isomgr_realize failed\n");
318 err = -ENOENT;
319 }
320 } else {
321 WARN_ONCE(1, "tegra_isomgr_reserve failed\n");
322 err = -ENOENT;
323 }
324 tegra_dc_set_latency_allowance(NVDISP_BW_MAX_BW_KBPS);
325
326unlock_and_ret: 342unlock_and_ret:
327 mutex_unlock(&tegra_nvdisp_lock); 343 mutex_unlock(&tegra_nvdisp_lock);
328 return err; 344 return err;
@@ -349,6 +365,8 @@ int tegra_nvdisp_negotiate_reserved_bw(struct tegra_dc *dc, u32 proposed_bw,
349{ 365{
350 return -ENOSYS; 366 return -ENOSYS;
351} 367}
368void tegra_nvdisp_init_bandwidth(struct tegra_dc *dc) {}
369void tegra_nvdisp_clear_bandwidth(struct tegra_dc *dc) {}
352long tegra_dc_calc_min_bandwidth(struct tegra_dc *dc) 370long tegra_dc_calc_min_bandwidth(struct tegra_dc *dc)
353{ 371{
354 return -ENOSYS; 372 return -ENOSYS;