diff options
author | Marek Szyprowski <m.szyprowski@samsung.com> | 2015-11-30 08:53:28 -0500 |
---|---|---|
committer | Inki Dae <daeinki@gmail.com> | 2015-12-13 08:22:58 -0500 |
commit | d16a11a006272ba3cad29f0bf2c087c28023249c (patch) | |
tree | cc96df3968c0cbe220a838f8868f9f939eddb32f | |
parent | e463b0695a0d52e280c8c42668b9c118c6d06d82 (diff) |
drm/exynos: fix clipping when scaling is enabled
This patch fixes calculation of src x/y offset for negative crtc x/y
values when scaling is enabled. This fixes possible IOMMU fault when
scaling is enabled.
Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
Signed-off-by: Inki Dae <inki.dae@samsung.com>
-rw-r--r-- | drivers/gpu/drm/exynos/exynos_drm_plane.c | 13 |
1 files changed, 7 insertions, 6 deletions
diff --git a/drivers/gpu/drm/exynos/exynos_drm_plane.c b/drivers/gpu/drm/exynos/exynos_drm_plane.c index 9eaa8627175f..427aeec78a28 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_plane.c +++ b/drivers/gpu/drm/exynos/exynos_drm_plane.c | |||
@@ -85,25 +85,26 @@ static void exynos_plane_mode_set(struct exynos_drm_plane_state *exynos_state) | |||
85 | src_w = state->src_w >> 16; | 85 | src_w = state->src_w >> 16; |
86 | src_h = state->src_h >> 16; | 86 | src_h = state->src_h >> 16; |
87 | 87 | ||
88 | /* set ratio */ | ||
89 | exynos_state->h_ratio = (src_w << 16) / crtc_w; | ||
90 | exynos_state->v_ratio = (src_h << 16) / crtc_h; | ||
91 | |||
92 | /* clip to visible area */ | ||
88 | actual_w = exynos_plane_get_size(crtc_x, crtc_w, mode->hdisplay); | 93 | actual_w = exynos_plane_get_size(crtc_x, crtc_w, mode->hdisplay); |
89 | actual_h = exynos_plane_get_size(crtc_y, crtc_h, mode->vdisplay); | 94 | actual_h = exynos_plane_get_size(crtc_y, crtc_h, mode->vdisplay); |
90 | 95 | ||
91 | if (crtc_x < 0) { | 96 | if (crtc_x < 0) { |
92 | if (actual_w) | 97 | if (actual_w) |
93 | src_x -= crtc_x; | 98 | src_x += ((-crtc_x) * exynos_state->h_ratio) >> 16; |
94 | crtc_x = 0; | 99 | crtc_x = 0; |
95 | } | 100 | } |
96 | 101 | ||
97 | if (crtc_y < 0) { | 102 | if (crtc_y < 0) { |
98 | if (actual_h) | 103 | if (actual_h) |
99 | src_y -= crtc_y; | 104 | src_y += ((-crtc_y) * exynos_state->v_ratio) >> 16; |
100 | crtc_y = 0; | 105 | crtc_y = 0; |
101 | } | 106 | } |
102 | 107 | ||
103 | /* set ratio */ | ||
104 | exynos_state->h_ratio = (src_w << 16) / crtc_w; | ||
105 | exynos_state->v_ratio = (src_h << 16) / crtc_h; | ||
106 | |||
107 | /* set drm framebuffer data. */ | 108 | /* set drm framebuffer data. */ |
108 | exynos_state->src.x = src_x; | 109 | exynos_state->src.x = src_x; |
109 | exynos_state->src.y = src_y; | 110 | exynos_state->src.y = src_y; |