summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorShu Zhong <shuz@nvidia.com>2018-02-15 23:20:35 -0500
committermobile promotions <svcmobile_promotions@nvidia.com>2018-03-01 16:53:05 -0500
commit8ff3d2b80196feeabbcf8a543f257943893ad680 (patch)
tree42b4997d0b28538b88d977015468309914960d1b
parent547e255c8a87916ae58d26bed361738b158deaf5 (diff)
dc: remove REF_TO_SYNC programming for nvdisp
H_REF_TO_SYNC and V_REF_TO_SYNC are legacy timing parameters that don't apply to nvdisplay. This patch cleans up and fixes our common mode handling logic accordingly: 1) Update tegra_dc_get_override_mode() so that it only reads the DC_DISP_REF_TO_SYNC register for T21x when querying the BL mode. This register doesn't even exist anymore on T186/T194. 2) Update the DP/HDMI mode filters so that they only enforce the V_FRONT_PORCH >= V_REF_TO_SYNC + 1 constraint for T21x. 3) Update tegra_dsi_wait_frame_end() so that it waits for V_REF_TO_SYNC additional lines only on T21x. 4) Fork off a separate mode check function for nvdisplay. This function contains the appropriate constraints as per the HW guidelines. 5) Update parse_modes() in of_dc so that it ignores the "nvidia,h-ref-to-sync" and "nvidia,v-ref-to-sync" properties on nvdisplay. 6) Completely stub out the tegra_dc_sor_disable_win_short_raster() and tegra_dc_sor_restore_win_and_raster() functions for nvdisplay. These functions are currently invoked as part of the SOR detach sequence, but make no sense for the most part, given the current T186/T194 SOR programming guidelines. The window detach and restore sequences are still needed, but this will be cleaned up in a follow-up change. As part of this SOR change, update the MSA source so that it's generated from the RG, instead of the OR. Beginning with T186, async FIFOs were added between the RG and OR to buffer MSA data coming directly from the RG via a new bus. We should be using this method instead. Bug 200388676 JIRA TDS-2003 Change-Id: I115ee96c9510b477b90257c3510c11afbad51d23 Signed-off-by: Shu Zhong <shuz@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/1659736 GVS: Gerrit_Virtual_Submit Reviewed-by: Ujwal Patel <ujwalp@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> Tested-by: mobile promotions <svcmobile_promotions@nvidia.com>
-rw-r--r--drivers/video/tegra/dc/dc.c12
-rw-r--r--drivers/video/tegra/dc/dp.c6
-rw-r--r--drivers/video/tegra/dc/dsi.c3
-rw-r--r--drivers/video/tegra/dc/hdmi2.0.c6
-rw-r--r--drivers/video/tegra/dc/mode.c77
-rw-r--r--drivers/video/tegra/dc/of_dc.c28
-rw-r--r--drivers/video/tegra/dc/sor.c27
7 files changed, 97 insertions, 62 deletions
diff --git a/drivers/video/tegra/dc/dc.c b/drivers/video/tegra/dc/dc.c
index fb73e93ce..2fddad89f 100644
--- a/drivers/video/tegra/dc/dc.c
+++ b/drivers/video/tegra/dc/dc.c
@@ -3874,9 +3874,13 @@ static struct tegra_dc_mode *tegra_dc_get_override_mode(struct tegra_dc *dc)
3874 mode->rated_pclk = 0; 3874 mode->rated_pclk = 0;
3875 3875
3876 tegra_dc_get(dc); 3876 tegra_dc_get(dc);
3877 val = tegra_dc_readl(dc, DC_DISP_REF_TO_SYNC); 3877
3878 mode->h_ref_to_sync = val & 0xffff; 3878 /* {V,H}_REF_TO_SYNC do NOT exist on nvdisplay. */
3879 mode->v_ref_to_sync = (val >> 16) & 0xffff; 3879 if (!tegra_dc_is_nvdisplay()) {
3880 val = tegra_dc_readl(dc, DC_DISP_REF_TO_SYNC);
3881 mode->h_ref_to_sync = val & 0xffff;
3882 mode->v_ref_to_sync = (val >> 16) & 0xffff;
3883 }
3880 3884
3881 val = tegra_dc_readl(dc, DC_DISP_SYNC_WIDTH); 3885 val = tegra_dc_readl(dc, DC_DISP_SYNC_WIDTH);
3882 mode->h_sync_width = val & 0xffff; 3886 mode->h_sync_width = val & 0xffff;
@@ -4433,7 +4437,7 @@ static void tegra_dc_prism_update_backlight(struct tegra_dc *dc)
4433void tegra_dc_set_act_vfp(struct tegra_dc *dc, int vfp) 4437void tegra_dc_set_act_vfp(struct tegra_dc *dc, int vfp)
4434{ 4438{
4435 WARN_ON(!mutex_is_locked(&dc->lock)); 4439 WARN_ON(!mutex_is_locked(&dc->lock));
4436 WARN_ON(vfp < dc->mode.v_ref_to_sync + 1); 4440 WARN_ON(!tegra_dc_is_nvdisplay() && vfp < dc->mode.v_ref_to_sync + 1);
4437 /* It's very unlikely that active vfp will need to 4441 /* It's very unlikely that active vfp will need to
4438 * be changed outside of vrr context */ 4442 * be changed outside of vrr context */
4439 WARN_ON(!dc->out->vrr || !dc->out->vrr->capability); 4443 WARN_ON(!dc->out->vrr || !dc->out->vrr->capability);
diff --git a/drivers/video/tegra/dc/dp.c b/drivers/video/tegra/dc/dp.c
index afc04056a..0f02b74a8 100644
--- a/drivers/video/tegra/dc/dp.c
+++ b/drivers/video/tegra/dc/dp.c
@@ -2922,10 +2922,12 @@ static bool tegra_dp_mode_filter(const struct tegra_dc *dc,
2922 return false; 2922 return false;
2923 2923
2924 /* 2924 /*
2925 * Work around for modes that fail the constraint: 2925 * Workaround for modes that fail the constraint:
2926 * V_FRONT_PORCH >= V_REF_TO_SYNC + 1 2926 * V_FRONT_PORCH >= V_REF_TO_SYNC + 1
2927 *
2928 * This constraint does not apply to nvdisplay.
2927 */ 2929 */
2928 if (mode->lower_margin == 1) { 2930 if (!tegra_dc_is_nvdisplay() && mode->lower_margin == 1) {
2929 mode->lower_margin++; 2931 mode->lower_margin++;
2930 mode->upper_margin--; 2932 mode->upper_margin--;
2931 mode->vmode |= FB_VMODE_ADJUSTED; 2933 mode->vmode |= FB_VMODE_ADJUSTED;
diff --git a/drivers/video/tegra/dc/dsi.c b/drivers/video/tegra/dc/dsi.c
index 91b04d3e1..a75c79f85 100644
--- a/drivers/video/tegra/dc/dsi.c
+++ b/drivers/video/tegra/dc/dsi.c
@@ -1998,7 +1998,8 @@ static int tegra_dsi_wait_frame_end(struct tegra_dc *dc,
1998 frame_period); 1998 frame_period);
1999 1999
2000 /* wait for v_ref_to_sync no. of lines after frame end interrupt */ 2000 /* wait for v_ref_to_sync no. of lines after frame end interrupt */
2001 udelay(mode.v_ref_to_sync * line_period); 2001 if (!tegra_dc_is_nvdisplay())
2002 udelay(mode.v_ref_to_sync * line_period);
2002 2003
2003 return timeout; 2004 return timeout;
2004} 2005}
diff --git a/drivers/video/tegra/dc/hdmi2.0.c b/drivers/video/tegra/dc/hdmi2.0.c
index 05394137f..b0961a033 100644
--- a/drivers/video/tegra/dc/hdmi2.0.c
+++ b/drivers/video/tegra/dc/hdmi2.0.c
@@ -367,10 +367,12 @@ static bool tegra_hdmi_fb_mode_filter(const struct tegra_dc *dc,
367 return false; 367 return false;
368 368
369 /* 369 /*
370 * Work around for modes that fail the constraint: 370 * Workaround for modes that fail the constraint:
371 * V_FRONT_PORCH >= V_REF_TO_SYNC + 1 371 * V_FRONT_PORCH >= V_REF_TO_SYNC + 1
372 *
373 * This constraint does not apply to nvdisplay.
372 */ 374 */
373 if (mode->lower_margin == 1) { 375 if (!tegra_dc_is_nvdisplay() && mode->lower_margin == 1) {
374 mode->lower_margin++; 376 mode->lower_margin++;
375 mode->upper_margin--; 377 mode->upper_margin--;
376 mode->vmode |= FB_VMODE_ADJUSTED; 378 mode->vmode |= FB_VMODE_ADJUSTED;
diff --git a/drivers/video/tegra/dc/mode.c b/drivers/video/tegra/dc/mode.c
index 0998dc83e..72532300c 100644
--- a/drivers/video/tegra/dc/mode.c
+++ b/drivers/video/tegra/dc/mode.c
@@ -368,32 +368,22 @@ static bool check_yuv_timings(struct tegra_dc_mode *mode, bool verbose)
368 return true; 368 return true;
369} 369}
370 370
371static bool check_mode_timings(const struct tegra_dc *dc, 371static bool check_t21x_mode_timings(const struct tegra_dc *dc,
372 struct tegra_dc_mode *mode, bool verbose) 372 struct tegra_dc_mode *mode, bool verbose)
373{ 373{
374#if defined(CONFIG_TEGRA_HDMI2_0)
375 if ((mode->vmode & FB_VMODE_Y420) || 374 if ((mode->vmode & FB_VMODE_Y420) ||
376 (mode->vmode & FB_VMODE_Y420_ONLY)) { 375 (mode->vmode & FB_VMODE_Y420_ONLY))
377 mode->v_ref_to_sync = 1; 376 mode->v_ref_to_sync = 1;
378 } else { 377 else
379 calc_ref_to_sync(mode); 378 calc_ref_to_sync(mode);
380 } 379
381 mode->h_ref_to_sync = 1; 380 mode->h_ref_to_sync = 1;
382#else
383 if (dc->out->type == TEGRA_DC_OUT_HDMI) {
384 /* HDMI controller requires h_ref=1, v_ref=1 */
385 mode->h_ref_to_sync = 1;
386 mode->v_ref_to_sync = 1;
387 } else {
388 calc_ref_to_sync(mode);
389 }
390#endif
391 381
392 if (dc->out->type == TEGRA_DC_OUT_DSI && dc->out->vrr) { 382 if (dc->out->type == TEGRA_DC_OUT_DSI && dc->out->vrr) {
393 mode->h_ref_to_sync = 383 mode->h_ref_to_sync =
394 dc->out->modes[dc->out->n_modes-1].h_ref_to_sync; 384 dc->out->modes[dc->out->n_modes - 1].h_ref_to_sync;
395 mode->v_ref_to_sync = 385 mode->v_ref_to_sync =
396 dc->out->modes[dc->out->n_modes-1].v_ref_to_sync; 386 dc->out->modes[dc->out->n_modes - 1].v_ref_to_sync;
397 } 387 }
398 388
399 if (dc->out->type == TEGRA_DC_OUT_DP) { 389 if (dc->out->type == TEGRA_DC_OUT_DP) {
@@ -408,16 +398,69 @@ static bool check_mode_timings(const struct tegra_dc *dc,
408 return false; 398 return false;
409 } 399 }
410 400
401 return true;
402}
403
404static bool check_nvdisp_mode_timings(const struct tegra_dc *dc,
405 struct tegra_dc_mode *mode, bool verbose)
406{
407 int h_total, v_total;
408
409 /*
410 * Constraint 1: V_SYNC_WIDTH >= 1
411 * H_SYNC_WIDTH >= 1
412 * V_FRONT_PORCH >= 1
413 * H_FRONT_PORCH >= 1
414 */
415 CHK(mode->v_sync_width < 1 || mode->h_sync_width < 1 ||
416 mode->v_front_porch < 1 || mode->h_front_porch < 1,
417 "{V,H}_SYNC_WIDTH >= 1, {V,H}_FRONT_PORCH >= 1\n");
418
419 /*
420 * Constraint 2: H_DISP_ACTIVE >= 8
421 * V_DISP_ACTIVE >= 4
422 */
423 CHK(mode->h_active < 8 || mode->v_active < 4,
424 "H_DISP_ACTIVE >= 8, V_DISP_ACTIVE >= 4\n");
425
426 /*
427 * Constraint 3: H_TOTAL < 32768
428 * V_TOTAL < 32768
429 */
430 h_total = mode->h_sync_width + mode->h_back_porch + mode->h_active +
431 mode->h_front_porch;
432 v_total = mode->v_sync_width + mode->v_back_porch + mode->v_active +
433 mode->v_front_porch;
434 CHK(h_total >= 32768 || v_total >= 32768,
435 "H_TOTAL < 32768, V_TOTAL < 32768\n");
436
437 /* Constraint 4: H_BLANK >= 25 */
438 CHK(h_total - mode->h_active < 25,
439 "H_BLANK >= 25\n");
440
441 return true;
442}
443
444static bool check_mode_timings(const struct tegra_dc *dc,
445 struct tegra_dc_mode *mode, bool verbose)
446{
447 bool check;
448
411 if (!check_yuv_timings(mode, verbose)) 449 if (!check_yuv_timings(mode, verbose))
412 return false; 450 return false;
413 451
452 if (tegra_dc_is_nvdisplay())
453 check = check_nvdisp_mode_timings(dc, mode, verbose);
454 else
455 check = check_t21x_mode_timings(dc, mode, verbose);
456
414 if (verbose) 457 if (verbose)
415 dev_dbg(&dc->ndev->dev, 458 dev_dbg(&dc->ndev->dev,
416 "Using mode %dx%d pclk=%d href=%d vref=%d\n", 459 "Using mode %dx%d pclk=%d href=%d vref=%d\n",
417 mode->h_active, mode->v_active, mode->pclk, 460 mode->h_active, mode->v_active, mode->pclk,
418 mode->h_ref_to_sync, mode->v_ref_to_sync); 461 mode->h_ref_to_sync, mode->v_ref_to_sync);
419 462
420 return true; 463 return check;
421} 464}
422 465
423bool check_fb_videomode_timings(const struct tegra_dc *dc, 466bool check_fb_videomode_timings(const struct tegra_dc *dc,
diff --git a/drivers/video/tegra/dc/of_dc.c b/drivers/video/tegra/dc/of_dc.c
index c0e500e14..86cdffefe 100644
--- a/drivers/video/tegra/dc/of_dc.c
+++ b/drivers/video/tegra/dc/of_dc.c
@@ -1128,24 +1128,28 @@ static int parse_modes(struct tegra_dc_out *default_out,
1128 const struct tegra_dc_out_pin *pins = default_out->out_pins; 1128 const struct tegra_dc_out_pin *pins = default_out->out_pins;
1129 int i; 1129 int i;
1130 1130
1131 /* {V,H}_REF_TO_SYNC do NOT exist on nvdisplay. */
1132 if (!tegra_dc_is_nvdisplay()) {
1133 if (!of_property_read_u32(np, "nvidia,h-ref-to-sync", &temp)) {
1134 modes->h_ref_to_sync = temp;
1135 } else {
1136 OF_DC_LOG("of h_ref_to_sync %d\n", temp);
1137 goto parse_modes_fail;
1138 }
1139 if (!of_property_read_u32(np, "nvidia,v-ref-to-sync", &temp)) {
1140 modes->v_ref_to_sync = temp;
1141 } else {
1142 OF_DC_LOG("of v_ref_to_sync %d\n", temp);
1143 goto parse_modes_fail;
1144 }
1145 }
1146
1131 if (!of_property_read_u32(np, "clock-frequency", &temp)) { 1147 if (!of_property_read_u32(np, "clock-frequency", &temp)) {
1132 modes->pclk = temp; 1148 modes->pclk = temp;
1133 OF_DC_LOG("of pclk %d\n", temp); 1149 OF_DC_LOG("of pclk %d\n", temp);
1134 } else { 1150 } else {
1135 goto parse_modes_fail; 1151 goto parse_modes_fail;
1136 } 1152 }
1137 if (!of_property_read_u32(np, "nvidia,h-ref-to-sync", &temp)) {
1138 modes->h_ref_to_sync = temp;
1139 } else {
1140 OF_DC_LOG("of h_ref_to_sync %d\n", temp);
1141 goto parse_modes_fail;
1142 }
1143 if (!of_property_read_u32(np, "nvidia,v-ref-to-sync", &temp)) {
1144 modes->v_ref_to_sync = temp;
1145 } else {
1146 OF_DC_LOG("of v_ref_to_sync %d\n", temp);
1147 goto parse_modes_fail;
1148 }
1149 if (!of_property_read_u32(np, "hsync-len", &temp)) { 1153 if (!of_property_read_u32(np, "hsync-len", &temp)) {
1150 modes->h_sync_width = temp; 1154 modes->h_sync_width = temp;
1151 } else { 1155 } else {
diff --git a/drivers/video/tegra/dc/sor.c b/drivers/video/tegra/dc/sor.c
index b099fa892..59687bc95 100644
--- a/drivers/video/tegra/dc/sor.c
+++ b/drivers/video/tegra/dc/sor.c
@@ -149,24 +149,13 @@ static struct tegra_dc_mode min_mode = {
149 .h_sync_width = 1, 149 .h_sync_width = 1,
150 .v_sync_width = 1, 150 .v_sync_width = 1,
151 .h_back_porch = 20, 151 .h_back_porch = 20,
152 /* V back porch for T21x is 0 and for Nvdisplay is 2 . 152 .v_back_porch = 0,
153 * Its populated in tegra_dc_populate_min_mode.
154 */
155 .v_back_porch = 2,
156 .h_active = 16, 153 .h_active = 16,
157 .v_active = 16, 154 .v_active = 16,
158 .h_front_porch = 1, 155 .h_front_porch = 1,
159 .v_front_porch = 2, 156 .v_front_porch = 2,
160}; 157};
161 158
162static void tegra_dc_populate_min_mode(void)
163{
164 if (tegra_dc_is_nvdisplay())
165 min_mode.v_back_porch = 2;
166 else
167 min_mode.v_back_porch = 0;
168}
169
170unsigned long 159unsigned long
171tegra_dc_sor_poll_register(struct tegra_dc_sor_data *sor, 160tegra_dc_sor_poll_register(struct tegra_dc_sor_data *sor,
172 u32 reg, u32 mask, u32 exp_val, 161 u32 reg, u32 mask, u32 exp_val,
@@ -883,8 +872,6 @@ struct tegra_dc_sor_data *tegra_dc_sor_init(struct tegra_dc *dc,
883 tegra_sor_fpga_settings(dc, sor); 872 tegra_sor_fpga_settings(dc, sor);
884 init_rwsem(&sor->reset_lock); 873 init_rwsem(&sor->reset_lock);
885 874
886 tegra_dc_populate_min_mode();
887
888 return sor; 875 return sor;
889 876
890err_rst: __maybe_unused 877err_rst: __maybe_unused
@@ -1747,7 +1734,7 @@ tegra_dc_sor_disable_win_short_raster(struct tegra_dc *dc, int *dc_reg_ctx)
1747{ 1734{
1748 int selected_windows, i; 1735 int selected_windows, i;
1749 1736
1750 if (tegra_platform_is_vdk()) 1737 if (tegra_dc_is_nvdisplay())
1751 return; 1738 return;
1752 1739
1753 selected_windows = tegra_dc_readl(dc, DC_CMD_DISPLAY_WINDOW_HEADER); 1740 selected_windows = tegra_dc_readl(dc, DC_CMD_DISPLAY_WINDOW_HEADER);
@@ -1796,7 +1783,7 @@ tegra_dc_sor_restore_win_and_raster(struct tegra_dc *dc, int *dc_reg_ctx)
1796{ 1783{
1797 int selected_windows, i; 1784 int selected_windows, i;
1798 1785
1799 if (tegra_platform_is_vdk()) 1786 if (tegra_dc_is_nvdisplay())
1800 return; 1787 return;
1801 1788
1802 selected_windows = tegra_dc_readl(dc, DC_CMD_DISPLAY_WINDOW_HEADER); 1789 selected_windows = tegra_dc_readl(dc, DC_CMD_DISPLAY_WINDOW_HEADER);
@@ -1988,14 +1975,6 @@ void tegra_dc_sor_set_internal_panel(struct tegra_dc_sor_data *sor, bool is_int)
1988 1975
1989 tegra_sor_writel(sor, NV_SOR_DP_SPARE(sor->portnum), reg_val); 1976 tegra_sor_writel(sor, NV_SOR_DP_SPARE(sor->portnum), reg_val);
1990 1977
1991 if (tegra_dc_is_nvdisplay()) {
1992 if (sor->dc->out->type == TEGRA_DC_OUT_DP)
1993 tegra_sor_write_field(sor,
1994 NV_SOR_DP_SPARE(sor->portnum),
1995 NV_SOR_DP_SPARE_MSA_SRC_MASK,
1996 NV_SOR_DP_SPARE_MSA_SRC_SOR);
1997 }
1998
1999 if (sor->dc->out->type == TEGRA_DC_OUT_HDMI) { 1978 if (sor->dc->out->type == TEGRA_DC_OUT_HDMI) {
2000 if (tegra_dc_is_nvdisplay()) 1979 if (tegra_dc_is_nvdisplay())
2001 tegra_sor_write_field(sor, 1980 tegra_sor_write_field(sor,