Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

drm: rcar-du: vsp: Extract framebuffer (un)mapping to separate functions

The rcar_du_vsp_plane_prepare_fb() and rcar_du_vsp_plane_cleanup_fb()
functions implement the DRM plane .prepare_fb() and .cleanup_fb()
operations. They map and unmap the framebuffer to/from the VSP
internally, which will be useful to implement writeback support. Split
the mapping and unmapping out to separate functions.

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham+renesas@ideasonboard.com>

+59 -27
+42 -27
drivers/gpu/drm/rcar-du/rcar_du_vsp.c
··· 10 10 #include <drm/drm_atomic_helper.h> 11 11 #include <drm/drm_crtc.h> 12 12 #include <drm/drm_fb_cma_helper.h> 13 + #include <drm/drm_fourcc.h> 13 14 #include <drm/drm_gem_cma_helper.h> 14 15 #include <drm/drm_gem_framebuffer_helper.h> 15 16 #include <drm/drm_plane_helper.h> ··· 175 174 plane->index, &cfg); 176 175 } 177 176 178 - static int rcar_du_vsp_plane_prepare_fb(struct drm_plane *plane, 179 - struct drm_plane_state *state) 177 + int rcar_du_vsp_map_fb(struct rcar_du_vsp *vsp, struct drm_framebuffer *fb, 178 + struct sg_table sg_tables[3]) 180 179 { 181 - struct rcar_du_vsp_plane_state *rstate = to_rcar_vsp_plane_state(state); 182 - struct rcar_du_vsp *vsp = to_rcar_vsp_plane(plane)->vsp; 183 180 struct rcar_du_device *rcdu = vsp->dev; 184 181 unsigned int i; 185 182 int ret; 186 183 187 - /* 188 - * There's no need to prepare (and unprepare) the framebuffer when the 189 - * plane is not visible, as it will not be displayed. 190 - */ 191 - if (!state->visible) 192 - return 0; 193 - 194 - for (i = 0; i < rstate->format->planes; ++i) { 195 - struct drm_gem_cma_object *gem = 196 - drm_fb_cma_get_gem_obj(state->fb, i); 197 - struct sg_table *sgt = &rstate->sg_tables[i]; 184 + for (i = 0; i < fb->format->num_planes; ++i) { 185 + struct drm_gem_cma_object *gem = drm_fb_cma_get_gem_obj(fb, i); 186 + struct sg_table *sgt = &sg_tables[i]; 198 187 199 188 ret = dma_get_sgtable(rcdu->dev, sgt, gem->vaddr, gem->paddr, 200 189 gem->base.size); ··· 199 208 } 200 209 } 201 210 202 - ret = drm_gem_fb_prepare_fb(plane, state); 203 - if (ret) 204 - goto fail; 205 - 206 211 return 0; 207 212 208 213 fail: 209 214 while (i--) { 210 - struct sg_table *sgt = &rstate->sg_tables[i]; 215 + struct sg_table *sgt = &sg_tables[i]; 211 216 212 217 vsp1_du_unmap_sg(vsp->vsp, sgt); 213 218 sg_free_table(sgt); ··· 212 225 return ret; 213 226 } 214 227 228 + static int rcar_du_vsp_plane_prepare_fb(struct drm_plane *plane, 229 + struct drm_plane_state *state) 230 + { 231 + struct rcar_du_vsp_plane_state *rstate = to_rcar_vsp_plane_state(state); 232 + struct rcar_du_vsp *vsp = to_rcar_vsp_plane(plane)->vsp; 233 + int ret; 234 + 235 + /* 236 + * There's no need to prepare (and unprepare) the framebuffer when the 237 + * plane is not visible, as it will not be displayed. 238 + */ 239 + if (!state->visible) 240 + return 0; 241 + 242 + ret = rcar_du_vsp_map_fb(vsp, state->fb, rstate->sg_tables); 243 + if (ret < 0) 244 + return ret; 245 + 246 + return drm_gem_fb_prepare_fb(plane, state); 247 + } 248 + 249 + void rcar_du_vsp_unmap_fb(struct rcar_du_vsp *vsp, struct drm_framebuffer *fb, 250 + struct sg_table sg_tables[3]) 251 + { 252 + unsigned int i; 253 + 254 + for (i = 0; i < fb->format->num_planes; ++i) { 255 + struct sg_table *sgt = &sg_tables[i]; 256 + 257 + vsp1_du_unmap_sg(vsp->vsp, sgt); 258 + sg_free_table(sgt); 259 + } 260 + } 261 + 215 262 static void rcar_du_vsp_plane_cleanup_fb(struct drm_plane *plane, 216 263 struct drm_plane_state *state) 217 264 { 218 265 struct rcar_du_vsp_plane_state *rstate = to_rcar_vsp_plane_state(state); 219 266 struct rcar_du_vsp *vsp = to_rcar_vsp_plane(plane)->vsp; 220 - unsigned int i; 221 267 222 268 if (!state->visible) 223 269 return; 224 270 225 - for (i = 0; i < rstate->format->planes; ++i) { 226 - struct sg_table *sgt = &rstate->sg_tables[i]; 227 - 228 - vsp1_du_unmap_sg(vsp->vsp, sgt); 229 - sg_free_table(sgt); 230 - } 271 + rcar_du_vsp_unmap_fb(vsp, state->fb, rstate->sg_tables); 231 272 } 232 273 233 274 static int rcar_du_vsp_plane_atomic_check(struct drm_plane *plane,
+17
drivers/gpu/drm/rcar-du/rcar_du_vsp.h
··· 12 12 13 13 #include <drm/drm_plane.h> 14 14 15 + struct drm_framebuffer; 15 16 struct rcar_du_format_info; 16 17 struct rcar_du_vsp; 18 + struct sg_table; 17 19 18 20 struct rcar_du_vsp_plane { 19 21 struct drm_plane plane; ··· 62 60 void rcar_du_vsp_disable(struct rcar_du_crtc *crtc); 63 61 void rcar_du_vsp_atomic_begin(struct rcar_du_crtc *crtc); 64 62 void rcar_du_vsp_atomic_flush(struct rcar_du_crtc *crtc); 63 + int rcar_du_vsp_map_fb(struct rcar_du_vsp *vsp, struct drm_framebuffer *fb, 64 + struct sg_table sg_tables[3]); 65 + void rcar_du_vsp_unmap_fb(struct rcar_du_vsp *vsp, struct drm_framebuffer *fb, 66 + struct sg_table sg_tables[3]); 65 67 #else 66 68 static inline int rcar_du_vsp_init(struct rcar_du_vsp *vsp, 67 69 struct device_node *np, ··· 77 71 static inline void rcar_du_vsp_disable(struct rcar_du_crtc *crtc) { }; 78 72 static inline void rcar_du_vsp_atomic_begin(struct rcar_du_crtc *crtc) { }; 79 73 static inline void rcar_du_vsp_atomic_flush(struct rcar_du_crtc *crtc) { }; 74 + static inline int rcar_du_vsp_map_fb(struct rcar_du_vsp *vsp, 75 + struct drm_framebuffer *fb, 76 + struct sg_table sg_tables[3]) 77 + { 78 + return -ENXIO; 79 + } 80 + static inline void rcar_du_vsp_unmap_fb(struct rcar_du_vsp *vsp, 81 + struct drm_framebuffer *fb, 82 + struct sg_table sg_tables[3]) 83 + { 84 + } 80 85 #endif 81 86 82 87 #endif /* __RCAR_DU_VSP_H__ */