aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThierry Reding <thierry.reding@avionic-design.de>2012-11-28 05:38:24 -0500
committerThierry Reding <thierry.reding@avionic-design.de>2013-02-22 02:21:17 -0500
commit23fb47404e6118eb53fb34c95ed98a3f4f822a76 (patch)
tree15a02ad1ab7808ec37353ecd03da052f556906d5
parentf34bc78741815d0ad07298a42101a1ee2e2bcdd2 (diff)
drm/tegra: Implement .mode_set_base()
The sequence for replacing the scanout buffer is much shorter than a full mode change operation so implementing this callback considerably speeds up cases where only a new framebuffer is to be scanned out. Signed-off-by: Thierry Reding <thierry.reding@avionic-design.de>
-rw-r--r--drivers/gpu/drm/tegra/dc.c32
1 files changed, 32 insertions, 0 deletions
diff --git a/drivers/gpu/drm/tegra/dc.c b/drivers/gpu/drm/tegra/dc.c
index 52bf63fbf384..ceb2f52c8f7e 100644
--- a/drivers/gpu/drm/tegra/dc.c
+++ b/drivers/gpu/drm/tegra/dc.c
@@ -134,6 +134,29 @@ static int tegra_dc_add_planes(struct drm_device *drm, struct tegra_dc *dc)
134 return 0; 134 return 0;
135} 135}
136 136
137static int tegra_dc_set_base(struct tegra_dc *dc, int x, int y,
138 struct drm_framebuffer *fb)
139{
140 struct drm_gem_cma_object *gem = drm_fb_cma_get_gem_obj(fb, 0);
141 unsigned long value;
142
143 tegra_dc_writel(dc, WINDOW_A_SELECT, DC_CMD_DISPLAY_WINDOW_HEADER);
144
145 value = fb->offsets[0] + y * fb->pitches[0] +
146 x * fb->bits_per_pixel / 8;
147
148 tegra_dc_writel(dc, gem->paddr + value, DC_WINBUF_START_ADDR);
149 tegra_dc_writel(dc, fb->pitches[0], DC_WIN_LINE_STRIDE);
150
151 value = GENERAL_UPDATE | WIN_A_UPDATE;
152 tegra_dc_writel(dc, value, DC_CMD_STATE_CONTROL);
153
154 value = GENERAL_ACT_REQ | WIN_A_ACT_REQ;
155 tegra_dc_writel(dc, value, DC_CMD_STATE_CONTROL);
156
157 return 0;
158}
159
137static const struct drm_crtc_funcs tegra_crtc_funcs = { 160static const struct drm_crtc_funcs tegra_crtc_funcs = {
138 .set_config = drm_crtc_helper_set_config, 161 .set_config = drm_crtc_helper_set_config,
139 .destroy = drm_crtc_cleanup, 162 .destroy = drm_crtc_cleanup,
@@ -510,6 +533,14 @@ static int tegra_crtc_mode_set(struct drm_crtc *crtc,
510 return 0; 533 return 0;
511} 534}
512 535
536static int tegra_crtc_mode_set_base(struct drm_crtc *crtc, int x, int y,
537 struct drm_framebuffer *old_fb)
538{
539 struct tegra_dc *dc = to_tegra_dc(crtc);
540
541 return tegra_dc_set_base(dc, x, y, crtc->fb);
542}
543
513static void tegra_crtc_prepare(struct drm_crtc *crtc) 544static void tegra_crtc_prepare(struct drm_crtc *crtc)
514{ 545{
515 struct tegra_dc *dc = to_tegra_dc(crtc); 546 struct tegra_dc *dc = to_tegra_dc(crtc);
@@ -589,6 +620,7 @@ static const struct drm_crtc_helper_funcs tegra_crtc_helper_funcs = {
589 .disable = tegra_crtc_disable, 620 .disable = tegra_crtc_disable,
590 .mode_fixup = tegra_crtc_mode_fixup, 621 .mode_fixup = tegra_crtc_mode_fixup,
591 .mode_set = tegra_crtc_mode_set, 622 .mode_set = tegra_crtc_mode_set,
623 .mode_set_base = tegra_crtc_mode_set_base,
592 .prepare = tegra_crtc_prepare, 624 .prepare = tegra_crtc_prepare,
593 .commit = tegra_crtc_commit, 625 .commit = tegra_crtc_commit,
594 .load_lut = tegra_crtc_load_lut, 626 .load_lut = tegra_crtc_load_lut,