diff options
author | Eric Anholt <eric@anholt.net> | 2015-12-28 17:34:44 -0500 |
---|---|---|
committer | Eric Anholt <eric@anholt.net> | 2016-02-16 14:24:08 -0500 |
commit | 5c6799942003df91801b1d2277bba34d71f99603 (patch) | |
tree | 1f6721970fbeb6a6965ef95039911405d88587ea | |
parent | 17eac75111ebda33e13d8d8d98aaedfc1a9c2abf (diff) |
drm/vc4: Move the plane clipping/scaling setup to a separate function.
As we add actual scaling, this is going to get way more complicated.
Signed-off-by: Eric Anholt <eric@anholt.net>
-rw-r--r-- | drivers/gpu/drm/vc4/vc4_plane.c | 78 |
1 files changed, 52 insertions, 26 deletions
diff --git a/drivers/gpu/drm/vc4/vc4_plane.c b/drivers/gpu/drm/vc4/vc4_plane.c index ed07ee57e1bf..554ed54cc8a7 100644 --- a/drivers/gpu/drm/vc4/vc4_plane.c +++ b/drivers/gpu/drm/vc4/vc4_plane.c | |||
@@ -40,6 +40,14 @@ struct vc4_plane_state { | |||
40 | * hardware at vc4_crtc_atomic_flush() time. | 40 | * hardware at vc4_crtc_atomic_flush() time. |
41 | */ | 41 | */ |
42 | u32 __iomem *hw_dlist; | 42 | u32 __iomem *hw_dlist; |
43 | |||
44 | /* Clipped coordinates of the plane on the display. */ | ||
45 | int crtc_x, crtc_y, crtc_w, crtc_h; | ||
46 | |||
47 | /* Offset to start scanning out from the start of the plane's | ||
48 | * BO. | ||
49 | */ | ||
50 | u32 offset; | ||
43 | }; | 51 | }; |
44 | 52 | ||
45 | static inline struct vc4_plane_state * | 53 | static inline struct vc4_plane_state * |
@@ -151,22 +159,17 @@ static void vc4_dlist_write(struct vc4_plane_state *vc4_state, u32 val) | |||
151 | vc4_state->dlist[vc4_state->dlist_count++] = val; | 159 | vc4_state->dlist[vc4_state->dlist_count++] = val; |
152 | } | 160 | } |
153 | 161 | ||
154 | /* Writes out a full display list for an active plane to the plane's | 162 | static int vc4_plane_setup_clipping_and_scaling(struct drm_plane_state *state) |
155 | * private dlist state. | ||
156 | */ | ||
157 | static int vc4_plane_mode_set(struct drm_plane *plane, | ||
158 | struct drm_plane_state *state) | ||
159 | { | 163 | { |
160 | struct vc4_plane_state *vc4_state = to_vc4_plane_state(state); | 164 | struct vc4_plane_state *vc4_state = to_vc4_plane_state(state); |
161 | struct drm_framebuffer *fb = state->fb; | 165 | struct drm_framebuffer *fb = state->fb; |
162 | struct drm_gem_cma_object *bo = drm_fb_cma_get_gem_obj(fb, 0); | 166 | |
163 | u32 ctl0_offset = vc4_state->dlist_count; | 167 | vc4_state->offset = fb->offsets[0]; |
164 | const struct hvs_format *format = vc4_get_hvs_format(fb->pixel_format); | 168 | |
165 | uint32_t offset = fb->offsets[0]; | 169 | vc4_state->crtc_x = state->crtc_x; |
166 | int crtc_x = state->crtc_x; | 170 | vc4_state->crtc_y = state->crtc_y; |
167 | int crtc_y = state->crtc_y; | 171 | vc4_state->crtc_w = state->crtc_w; |
168 | int crtc_w = state->crtc_w; | 172 | vc4_state->crtc_h = state->crtc_h; |
169 | int crtc_h = state->crtc_h; | ||
170 | 173 | ||
171 | if (state->crtc_w << 16 != state->src_w || | 174 | if (state->crtc_w << 16 != state->src_w || |
172 | state->crtc_h << 16 != state->src_h) { | 175 | state->crtc_h << 16 != state->src_h) { |
@@ -178,18 +181,41 @@ static int vc4_plane_mode_set(struct drm_plane *plane, | |||
178 | return -EINVAL; | 181 | return -EINVAL; |
179 | } | 182 | } |
180 | 183 | ||
181 | if (crtc_x < 0) { | 184 | if (vc4_state->crtc_x < 0) { |
182 | offset += drm_format_plane_cpp(fb->pixel_format, 0) * -crtc_x; | 185 | vc4_state->offset += (drm_format_plane_cpp(fb->pixel_format, |
183 | crtc_w += crtc_x; | 186 | 0) * |
184 | crtc_x = 0; | 187 | -vc4_state->crtc_x); |
188 | vc4_state->crtc_w += vc4_state->crtc_x; | ||
189 | vc4_state->crtc_x = 0; | ||
185 | } | 190 | } |
186 | 191 | ||
187 | if (crtc_y < 0) { | 192 | if (vc4_state->crtc_y < 0) { |
188 | offset += fb->pitches[0] * -crtc_y; | 193 | vc4_state->offset += fb->pitches[0] * -vc4_state->crtc_y; |
189 | crtc_h += crtc_y; | 194 | vc4_state->crtc_h += vc4_state->crtc_y; |
190 | crtc_y = 0; | 195 | vc4_state->crtc_y = 0; |
191 | } | 196 | } |
192 | 197 | ||
198 | return 0; | ||
199 | } | ||
200 | |||
201 | |||
202 | /* Writes out a full display list for an active plane to the plane's | ||
203 | * private dlist state. | ||
204 | */ | ||
205 | static int vc4_plane_mode_set(struct drm_plane *plane, | ||
206 | struct drm_plane_state *state) | ||
207 | { | ||
208 | struct vc4_plane_state *vc4_state = to_vc4_plane_state(state); | ||
209 | struct drm_framebuffer *fb = state->fb; | ||
210 | struct drm_gem_cma_object *bo = drm_fb_cma_get_gem_obj(fb, 0); | ||
211 | u32 ctl0_offset = vc4_state->dlist_count; | ||
212 | const struct hvs_format *format = vc4_get_hvs_format(fb->pixel_format); | ||
213 | int ret; | ||
214 | |||
215 | ret = vc4_plane_setup_clipping_and_scaling(state); | ||
216 | if (ret) | ||
217 | return ret; | ||
218 | |||
193 | vc4_dlist_write(vc4_state, | 219 | vc4_dlist_write(vc4_state, |
194 | SCALER_CTL0_VALID | | 220 | SCALER_CTL0_VALID | |
195 | (format->pixel_order << SCALER_CTL0_ORDER_SHIFT) | | 221 | (format->pixel_order << SCALER_CTL0_ORDER_SHIFT) | |
@@ -199,8 +225,8 @@ static int vc4_plane_mode_set(struct drm_plane *plane, | |||
199 | /* Position Word 0: Image Positions and Alpha Value */ | 225 | /* Position Word 0: Image Positions and Alpha Value */ |
200 | vc4_dlist_write(vc4_state, | 226 | vc4_dlist_write(vc4_state, |
201 | VC4_SET_FIELD(0xff, SCALER_POS0_FIXED_ALPHA) | | 227 | VC4_SET_FIELD(0xff, SCALER_POS0_FIXED_ALPHA) | |
202 | VC4_SET_FIELD(crtc_x, SCALER_POS0_START_X) | | 228 | VC4_SET_FIELD(vc4_state->crtc_x, SCALER_POS0_START_X) | |
203 | VC4_SET_FIELD(crtc_y, SCALER_POS0_START_Y)); | 229 | VC4_SET_FIELD(vc4_state->crtc_y, SCALER_POS0_START_Y)); |
204 | 230 | ||
205 | /* Position Word 1: Scaled Image Dimensions. | 231 | /* Position Word 1: Scaled Image Dimensions. |
206 | * Skipped due to SCALER_CTL0_UNITY scaling. | 232 | * Skipped due to SCALER_CTL0_UNITY scaling. |
@@ -212,8 +238,8 @@ static int vc4_plane_mode_set(struct drm_plane *plane, | |||
212 | SCALER_POS2_ALPHA_MODE_PIPELINE : | 238 | SCALER_POS2_ALPHA_MODE_PIPELINE : |
213 | SCALER_POS2_ALPHA_MODE_FIXED, | 239 | SCALER_POS2_ALPHA_MODE_FIXED, |
214 | SCALER_POS2_ALPHA_MODE) | | 240 | SCALER_POS2_ALPHA_MODE) | |
215 | VC4_SET_FIELD(crtc_w, SCALER_POS2_WIDTH) | | 241 | VC4_SET_FIELD(vc4_state->crtc_w, SCALER_POS2_WIDTH) | |
216 | VC4_SET_FIELD(crtc_h, SCALER_POS2_HEIGHT)); | 242 | VC4_SET_FIELD(vc4_state->crtc_h, SCALER_POS2_HEIGHT)); |
217 | 243 | ||
218 | /* Position Word 3: Context. Written by the HVS. */ | 244 | /* Position Word 3: Context. Written by the HVS. */ |
219 | vc4_dlist_write(vc4_state, 0xc0c0c0c0); | 245 | vc4_dlist_write(vc4_state, 0xc0c0c0c0); |
@@ -221,7 +247,7 @@ static int vc4_plane_mode_set(struct drm_plane *plane, | |||
221 | vc4_state->pw0_offset = vc4_state->dlist_count; | 247 | vc4_state->pw0_offset = vc4_state->dlist_count; |
222 | 248 | ||
223 | /* Pointer Word 0: RGB / Y Pointer */ | 249 | /* Pointer Word 0: RGB / Y Pointer */ |
224 | vc4_dlist_write(vc4_state, bo->paddr + offset); | 250 | vc4_dlist_write(vc4_state, bo->paddr + vc4_state->offset); |
225 | 251 | ||
226 | /* Pointer Context Word 0: Written by the HVS */ | 252 | /* Pointer Context Word 0: Written by the HVS */ |
227 | vc4_dlist_write(vc4_state, 0xc0c0c0c0); | 253 | vc4_dlist_write(vc4_state, 0xc0c0c0c0); |