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

drm/bochs: fix framebuffer setup.

The driver doesn't consider framebuffer pitch and offset, leading to a
wrong display in case offset != 0 or pitch != width * bpp. Fix it.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Acked-by: Thomas Zimmermann <tzimmermann@suse.de>
Link: http://patchwork.freedesktop.org/patch/msgid/20190627081206.23135-1-kraxel@redhat.com

+13 -6
+1 -1
drivers/gpu/drm/bochs/bochs.h
··· 86 86 void bochs_hw_setformat(struct bochs_device *bochs, 87 87 const struct drm_format_info *format); 88 88 void bochs_hw_setbase(struct bochs_device *bochs, 89 - int x, int y, u64 addr); 89 + int x, int y, int stride, u64 addr); 90 90 int bochs_hw_load_edid(struct bochs_device *bochs); 91 91 92 92 /* bochs_mm.c */
+10 -4
drivers/gpu/drm/bochs/bochs_hw.c
··· 255 255 } 256 256 257 257 void bochs_hw_setbase(struct bochs_device *bochs, 258 - int x, int y, u64 addr) 258 + int x, int y, int stride, u64 addr) 259 259 { 260 - unsigned long offset = (unsigned long)addr + 260 + unsigned long offset; 261 + unsigned int vx, vy, vwidth; 262 + 263 + bochs->stride = stride; 264 + offset = (unsigned long)addr + 261 265 y * bochs->stride + 262 266 x * (bochs->bpp / 8); 263 - int vy = offset / bochs->stride; 264 - int vx = (offset % bochs->stride) * 8 / bochs->bpp; 267 + vy = offset / bochs->stride; 268 + vx = (offset % bochs->stride) * 8 / bochs->bpp; 269 + vwidth = stride * 8 / bochs->bpp; 265 270 266 271 DRM_DEBUG_DRIVER("x %d, y %d, addr %llx -> offset %lx, vx %d, vy %d\n", 267 272 x, y, addr, offset, vx, vy); 273 + bochs_dispi_write(bochs, VBE_DISPI_INDEX_VIRT_WIDTH, vwidth); 268 274 bochs_dispi_write(bochs, VBE_DISPI_INDEX_X_OFFSET, vx); 269 275 bochs_dispi_write(bochs, VBE_DISPI_INDEX_Y_OFFSET, vy); 270 276 }
+2 -1
drivers/gpu/drm/bochs/bochs_kms.c
··· 36 36 bochs_hw_setbase(bochs, 37 37 state->crtc_x, 38 38 state->crtc_y, 39 - gbo->bo.offset); 39 + state->fb->pitches[0], 40 + state->fb->offsets[0] + gbo->bo.offset); 40 41 bochs_hw_setformat(bochs, state->fb->format); 41 42 } 42 43