diff options
author | Russell King <rmk+kernel@arm.linux.org.uk> | 2015-06-15 05:17:57 -0400 |
---|---|---|
committer | Russell King <rmk+kernel@arm.linux.org.uk> | 2015-07-15 11:45:29 -0400 |
commit | 98fb74f4ecb8a70c75d7cfcfec17432cb0db2f5d (patch) | |
tree | f56f9d8532acebc2e83b9f432ab9f5dc7dada067 | |
parent | 0481c8c47f5e858bfc020a825fd178004c14702d (diff) |
drm/armada: convert overlay to use drm_plane_helper_check_update()
Use drm_plane_helper_check_update() rather than our own code to validate
and limit the size of the displayed image. As we are able to support
scaling, permit the full scaling ability.
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
-rw-r--r-- | drivers/gpu/drm/armada/armada_overlay.c | 67 |
1 files changed, 39 insertions, 28 deletions
diff --git a/drivers/gpu/drm/armada/armada_overlay.c b/drivers/gpu/drm/armada/armada_overlay.c index f026ba062456..d7df34f3d504 100644 --- a/drivers/gpu/drm/armada/armada_overlay.c +++ b/drivers/gpu/drm/armada/armada_overlay.c | |||
@@ -7,6 +7,7 @@ | |||
7 | * published by the Free Software Foundation. | 7 | * published by the Free Software Foundation. |
8 | */ | 8 | */ |
9 | #include <drm/drmP.h> | 9 | #include <drm/drmP.h> |
10 | #include <drm/drm_plane_helper.h> | ||
10 | #include "armada_crtc.h" | 11 | #include "armada_crtc.h" |
11 | #include "armada_drm.h" | 12 | #include "armada_drm.h" |
12 | #include "armada_fb.h" | 13 | #include "armada_fb.h" |
@@ -89,16 +90,6 @@ static void armada_plane_vbl(struct armada_crtc *dcrtc, void *data) | |||
89 | wake_up(&dplane->vbl.wait); | 90 | wake_up(&dplane->vbl.wait); |
90 | } | 91 | } |
91 | 92 | ||
92 | static unsigned armada_limit(int start, unsigned size, unsigned max) | ||
93 | { | ||
94 | int end = start + size; | ||
95 | if (end < 0) | ||
96 | return 0; | ||
97 | if (start < 0) | ||
98 | start = 0; | ||
99 | return (unsigned)end > max ? max - start : end - start; | ||
100 | } | ||
101 | |||
102 | static int | 93 | static int |
103 | armada_plane_update(struct drm_plane *plane, struct drm_crtc *crtc, | 94 | armada_plane_update(struct drm_plane *plane, struct drm_crtc *crtc, |
104 | struct drm_framebuffer *fb, | 95 | struct drm_framebuffer *fb, |
@@ -107,26 +98,39 @@ armada_plane_update(struct drm_plane *plane, struct drm_crtc *crtc, | |||
107 | { | 98 | { |
108 | struct armada_plane *dplane = drm_to_armada_plane(plane); | 99 | struct armada_plane *dplane = drm_to_armada_plane(plane); |
109 | struct armada_crtc *dcrtc = drm_to_armada_crtc(crtc); | 100 | struct armada_crtc *dcrtc = drm_to_armada_crtc(crtc); |
101 | struct drm_rect src = { | ||
102 | .x1 = src_x, | ||
103 | .y1 = src_y, | ||
104 | .x2 = src_x + src_w, | ||
105 | .y2 = src_y + src_h, | ||
106 | }; | ||
107 | struct drm_rect dest = { | ||
108 | .x1 = crtc_x, | ||
109 | .y1 = crtc_y, | ||
110 | .x2 = crtc_x + crtc_w, | ||
111 | .y2 = crtc_y + crtc_h, | ||
112 | }; | ||
113 | const struct drm_rect clip = { | ||
114 | .x2 = crtc->mode.hdisplay, | ||
115 | .y2 = crtc->mode.vdisplay, | ||
116 | }; | ||
110 | uint32_t val, ctrl0; | 117 | uint32_t val, ctrl0; |
111 | unsigned idx = 0; | 118 | unsigned idx = 0; |
119 | bool visible; | ||
112 | int ret; | 120 | int ret; |
113 | 121 | ||
114 | crtc_w = armada_limit(crtc_x, crtc_w, dcrtc->crtc.mode.hdisplay); | 122 | ret = drm_plane_helper_check_update(plane, crtc, fb, &src, &dest, &clip, |
115 | crtc_h = armada_limit(crtc_y, crtc_h, dcrtc->crtc.mode.vdisplay); | 123 | 0, INT_MAX, true, false, &visible); |
124 | if (ret) | ||
125 | return ret; | ||
126 | |||
116 | ctrl0 = CFG_DMA_FMT(drm_fb_to_armada_fb(fb)->fmt) | | 127 | ctrl0 = CFG_DMA_FMT(drm_fb_to_armada_fb(fb)->fmt) | |
117 | CFG_DMA_MOD(drm_fb_to_armada_fb(fb)->mod) | | 128 | CFG_DMA_MOD(drm_fb_to_armada_fb(fb)->mod) | |
118 | CFG_CBSH_ENA | CFG_DMA_HSMOOTH | CFG_DMA_ENA; | 129 | CFG_CBSH_ENA | CFG_DMA_HSMOOTH | CFG_DMA_ENA; |
119 | 130 | ||
120 | /* Does the position/size result in nothing to display? */ | 131 | /* Does the position/size result in nothing to display? */ |
121 | if (crtc_w == 0 || crtc_h == 0) { | 132 | if (!visible) |
122 | ctrl0 &= ~CFG_DMA_ENA; | 133 | ctrl0 &= ~CFG_DMA_ENA; |
123 | } | ||
124 | |||
125 | /* | ||
126 | * FIXME: if the starting point is off screen, we need to | ||
127 | * adjust src_x, src_y, src_w, src_h appropriately, and | ||
128 | * according to the scale. | ||
129 | */ | ||
130 | 134 | ||
131 | if (!dcrtc->plane) { | 135 | if (!dcrtc->plane) { |
132 | dcrtc->plane = plane; | 136 | dcrtc->plane = plane; |
@@ -136,15 +140,19 @@ armada_plane_update(struct drm_plane *plane, struct drm_crtc *crtc, | |||
136 | /* FIXME: overlay on an interlaced display */ | 140 | /* FIXME: overlay on an interlaced display */ |
137 | /* Just updating the position/size? */ | 141 | /* Just updating the position/size? */ |
138 | if (plane->fb == fb && dplane->ctrl0 == ctrl0) { | 142 | if (plane->fb == fb && dplane->ctrl0 == ctrl0) { |
139 | val = (src_h & 0xffff0000) | src_w >> 16; | 143 | val = (drm_rect_height(&src) & 0xffff0000) | |
144 | drm_rect_width(&src) >> 16; | ||
140 | dplane->src_hw = val; | 145 | dplane->src_hw = val; |
141 | writel_relaxed(val, dcrtc->base + LCD_SPU_DMA_HPXL_VLN); | 146 | writel_relaxed(val, dcrtc->base + LCD_SPU_DMA_HPXL_VLN); |
142 | val = crtc_h << 16 | crtc_w; | 147 | |
148 | val = drm_rect_height(&dest) << 16 | drm_rect_width(&dest); | ||
143 | dplane->dst_hw = val; | 149 | dplane->dst_hw = val; |
144 | writel_relaxed(val, dcrtc->base + LCD_SPU_DZM_HPXL_VLN); | 150 | writel_relaxed(val, dcrtc->base + LCD_SPU_DZM_HPXL_VLN); |
145 | val = crtc_y << 16 | crtc_x; | 151 | |
152 | val = dest.y1 << 16 | dest.x1; | ||
146 | dplane->dst_yx = val; | 153 | dplane->dst_yx = val; |
147 | writel_relaxed(val, dcrtc->base + LCD_SPU_DMA_OVSA_HPXL_VLN); | 154 | writel_relaxed(val, dcrtc->base + LCD_SPU_DMA_OVSA_HPXL_VLN); |
155 | |||
148 | return 0; | 156 | return 0; |
149 | } else if (~dplane->ctrl0 & ctrl0 & CFG_DMA_ENA) { | 157 | } else if (~dplane->ctrl0 & ctrl0 & CFG_DMA_ENA) { |
150 | /* Power up the Y/U/V FIFOs on ENA 0->1 transitions */ | 158 | /* Power up the Y/U/V FIFOs on ENA 0->1 transitions */ |
@@ -178,8 +186,8 @@ armada_plane_update(struct drm_plane *plane, struct drm_crtc *crtc, | |||
178 | older_fb); | 186 | older_fb); |
179 | } | 187 | } |
180 | 188 | ||
181 | src_y >>= 16; | 189 | src_y = src.y1 >> 16; |
182 | src_x >>= 16; | 190 | src_x = src.x1 >> 16; |
183 | sy = obj->dev_addr + fb->offsets[0] + src_y * fb->pitches[0] + | 191 | sy = obj->dev_addr + fb->offsets[0] + src_y * fb->pitches[0] + |
184 | src_x * fb->bits_per_pixel / 8; | 192 | src_x * fb->bits_per_pixel / 8; |
185 | su = obj->dev_addr + fb->offsets[1] + src_y * fb->pitches[1] + | 193 | su = obj->dev_addr + fb->offsets[1] + src_y * fb->pitches[1] + |
@@ -208,24 +216,27 @@ armada_plane_update(struct drm_plane *plane, struct drm_crtc *crtc, | |||
208 | LCD_SPU_DMA_PITCH_UV); | 216 | LCD_SPU_DMA_PITCH_UV); |
209 | } | 217 | } |
210 | 218 | ||
211 | val = (src_h & 0xffff0000) | src_w >> 16; | 219 | val = (drm_rect_height(&src) & 0xffff0000) | drm_rect_width(&src) >> 16; |
212 | if (dplane->src_hw != val) { | 220 | if (dplane->src_hw != val) { |
213 | dplane->src_hw = val; | 221 | dplane->src_hw = val; |
214 | armada_reg_queue_set(dplane->vbl.regs, idx, val, | 222 | armada_reg_queue_set(dplane->vbl.regs, idx, val, |
215 | LCD_SPU_DMA_HPXL_VLN); | 223 | LCD_SPU_DMA_HPXL_VLN); |
216 | } | 224 | } |
217 | val = crtc_h << 16 | crtc_w; | 225 | |
226 | val = drm_rect_height(&dest) << 16 | drm_rect_width(&dest); | ||
218 | if (dplane->dst_hw != val) { | 227 | if (dplane->dst_hw != val) { |
219 | dplane->dst_hw = val; | 228 | dplane->dst_hw = val; |
220 | armada_reg_queue_set(dplane->vbl.regs, idx, val, | 229 | armada_reg_queue_set(dplane->vbl.regs, idx, val, |
221 | LCD_SPU_DZM_HPXL_VLN); | 230 | LCD_SPU_DZM_HPXL_VLN); |
222 | } | 231 | } |
223 | val = crtc_y << 16 | crtc_x; | 232 | |
233 | val = dest.y1 << 16 | dest.x1; | ||
224 | if (dplane->dst_yx != val) { | 234 | if (dplane->dst_yx != val) { |
225 | dplane->dst_yx = val; | 235 | dplane->dst_yx = val; |
226 | armada_reg_queue_set(dplane->vbl.regs, idx, val, | 236 | armada_reg_queue_set(dplane->vbl.regs, idx, val, |
227 | LCD_SPU_DMA_OVSA_HPXL_VLN); | 237 | LCD_SPU_DMA_OVSA_HPXL_VLN); |
228 | } | 238 | } |
239 | |||
229 | if (dplane->ctrl0 != ctrl0) { | 240 | if (dplane->ctrl0 != ctrl0) { |
230 | dplane->ctrl0 = ctrl0; | 241 | dplane->ctrl0 = ctrl0; |
231 | armada_reg_queue_mod(dplane->vbl.regs, idx, ctrl0, | 242 | armada_reg_queue_mod(dplane->vbl.regs, idx, ctrl0, |