aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEric Anholt <eric@anholt.net>2015-12-28 17:34:44 -0500
committerEric Anholt <eric@anholt.net>2016-02-16 14:24:08 -0500
commit5c6799942003df91801b1d2277bba34d71f99603 (patch)
tree1f6721970fbeb6a6965ef95039911405d88587ea
parent17eac75111ebda33e13d8d8d98aaedfc1a9c2abf (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.c78
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
45static inline struct vc4_plane_state * 53static 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 162static int vc4_plane_setup_clipping_and_scaling(struct drm_plane_state *state)
155 * private dlist state.
156 */
157static 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 */
205static 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);