diff options
author | Thierry Reding <thierry.reding@avionic-design.de> | 2012-11-28 05:38:24 -0500 |
---|---|---|
committer | Thierry Reding <thierry.reding@avionic-design.de> | 2013-02-22 02:21:17 -0500 |
commit | 23fb47404e6118eb53fb34c95ed98a3f4f822a76 (patch) | |
tree | 15a02ad1ab7808ec37353ecd03da052f556906d5 | |
parent | f34bc78741815d0ad07298a42101a1ee2e2bcdd2 (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.c | 32 |
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 | ||
137 | static 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 | |||
137 | static const struct drm_crtc_funcs tegra_crtc_funcs = { | 160 | static 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 | ||
536 | static 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 | |||
513 | static void tegra_crtc_prepare(struct drm_crtc *crtc) | 544 | static 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, |