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

drm/rcar-du: Fix buffer pitch alignment

The DU requires a 16 pixels pitch alignement. Make sure dumb buffers are
allocated with the correct pitch, and validate the pitch when creating
frame buffers.

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
Signed-off-by: Dave Airlie <airlied@redhat.com>

authored by

Laurent Pinchart and committed by
Dave Airlie
59e32642 3463ff67

+22 -2
+1 -1
drivers/gpu/drm/rcar-du/rcar_du_drv.c
··· 251 251 .prime_fd_to_handle = drm_gem_prime_fd_to_handle, 252 252 .gem_prime_import = drm_gem_cma_dmabuf_import, 253 253 .gem_prime_export = drm_gem_cma_dmabuf_export, 254 - .dumb_create = drm_gem_cma_dumb_create, 254 + .dumb_create = rcar_du_dumb_create, 255 255 .dumb_map_offset = drm_gem_cma_dumb_map_offset, 256 256 .dumb_destroy = drm_gem_cma_dumb_destroy, 257 257 .fops = &rcar_du_fops,
+18 -1
drivers/gpu/drm/rcar-du/rcar_du_kms.c
··· 138 138 * Frame buffer 139 139 */ 140 140 141 + int rcar_du_dumb_create(struct drm_file *file, struct drm_device *dev, 142 + struct drm_mode_create_dumb *args) 143 + { 144 + unsigned int min_pitch = DIV_ROUND_UP(args->width * args->bpp, 8); 145 + unsigned int align; 146 + 147 + /* The pitch must be aligned to a 16 pixels boundary. */ 148 + align = 16 * args->bpp / 8; 149 + args->pitch = roundup(max(args->pitch, min_pitch), align); 150 + 151 + return drm_gem_cma_dumb_create(file, dev, args); 152 + } 153 + 141 154 static struct drm_framebuffer * 142 155 rcar_du_fb_create(struct drm_device *dev, struct drm_file *file_priv, 143 156 struct drm_mode_fb_cmd2 *mode_cmd) 144 157 { 145 158 const struct rcar_du_format_info *format; 159 + unsigned int align; 146 160 147 161 format = rcar_du_format_info(mode_cmd->pixel_format); 148 162 if (format == NULL) { ··· 165 151 return ERR_PTR(-EINVAL); 166 152 } 167 153 168 - if (mode_cmd->pitches[0] & 15 || mode_cmd->pitches[0] >= 8192) { 154 + align = 16 * format->bpp / 8; 155 + 156 + if (mode_cmd->pitches[0] & (align - 1) || 157 + mode_cmd->pitches[0] >= 8192) { 169 158 dev_dbg(dev->dev, "invalid pitch value %u\n", 170 159 mode_cmd->pitches[0]); 171 160 return ERR_PTR(-EINVAL);
+3
drivers/gpu/drm/rcar-du/rcar_du_kms.h
··· 56 56 57 57 int rcar_du_modeset_init(struct rcar_du_device *rcdu); 58 58 59 + int rcar_du_dumb_create(struct drm_file *file, struct drm_device *dev, 60 + struct drm_mode_create_dumb *args); 61 + 59 62 #endif /* __RCAR_DU_KMS_H__ */