diff options
Diffstat (limited to 'drivers/gpu/drm/vmwgfx/vmwgfx_fb.c')
-rw-r--r-- | drivers/gpu/drm/vmwgfx/vmwgfx_fb.c | 87 |
1 files changed, 24 insertions, 63 deletions
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_fb.c b/drivers/gpu/drm/vmwgfx/vmwgfx_fb.c index 7421aaad8d09..b0866f04ec76 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_fb.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_fb.c | |||
@@ -132,16 +132,14 @@ static int vmw_fb_check_var(struct fb_var_screeninfo *var, | |||
132 | return -EINVAL; | 132 | return -EINVAL; |
133 | } | 133 | } |
134 | 134 | ||
135 | /* without multimon its hard to resize */ | 135 | if (!(vmw_priv->capabilities & SVGA_CAP_DISPLAY_TOPOLOGY) && |
136 | if (!(vmw_priv->capabilities & SVGA_CAP_MULTIMON) && | 136 | (var->xoffset != 0 || var->yoffset != 0)) { |
137 | (var->xres != par->max_width || | 137 | DRM_ERROR("Can not handle panning without display topology\n"); |
138 | var->yres != par->max_height)) { | ||
139 | DRM_ERROR("Tried to resize, but we don't have multimon\n"); | ||
140 | return -EINVAL; | 138 | return -EINVAL; |
141 | } | 139 | } |
142 | 140 | ||
143 | if (var->xres > par->max_width || | 141 | if ((var->xoffset + var->xres) > par->max_width || |
144 | var->yres > par->max_height) { | 142 | (var->yoffset + var->yres) > par->max_height) { |
145 | DRM_ERROR("Requested geom can not fit in framebuffer\n"); | 143 | DRM_ERROR("Requested geom can not fit in framebuffer\n"); |
146 | return -EINVAL; | 144 | return -EINVAL; |
147 | } | 145 | } |
@@ -154,27 +152,11 @@ static int vmw_fb_set_par(struct fb_info *info) | |||
154 | struct vmw_fb_par *par = info->par; | 152 | struct vmw_fb_par *par = info->par; |
155 | struct vmw_private *vmw_priv = par->vmw_priv; | 153 | struct vmw_private *vmw_priv = par->vmw_priv; |
156 | 154 | ||
157 | if (vmw_priv->capabilities & SVGA_CAP_MULTIMON) { | 155 | vmw_kms_write_svga(vmw_priv, info->var.xres, info->var.yres, |
158 | vmw_write(vmw_priv, SVGA_REG_NUM_GUEST_DISPLAYS, 1); | 156 | info->fix.line_length, |
159 | vmw_write(vmw_priv, SVGA_REG_DISPLAY_ID, 0); | 157 | par->bpp, par->depth); |
160 | vmw_write(vmw_priv, SVGA_REG_DISPLAY_IS_PRIMARY, true); | 158 | if (vmw_priv->capabilities & SVGA_CAP_DISPLAY_TOPOLOGY) { |
161 | vmw_write(vmw_priv, SVGA_REG_DISPLAY_POSITION_X, 0); | ||
162 | vmw_write(vmw_priv, SVGA_REG_DISPLAY_POSITION_Y, 0); | ||
163 | vmw_write(vmw_priv, SVGA_REG_DISPLAY_WIDTH, 0); | ||
164 | vmw_write(vmw_priv, SVGA_REG_DISPLAY_HEIGHT, 0); | ||
165 | vmw_write(vmw_priv, SVGA_REG_DISPLAY_ID, SVGA_ID_INVALID); | ||
166 | |||
167 | vmw_write(vmw_priv, SVGA_REG_ENABLE, 1); | ||
168 | vmw_write(vmw_priv, SVGA_REG_WIDTH, par->max_width); | ||
169 | vmw_write(vmw_priv, SVGA_REG_HEIGHT, par->max_height); | ||
170 | vmw_write(vmw_priv, SVGA_REG_BITS_PER_PIXEL, par->bpp); | ||
171 | vmw_write(vmw_priv, SVGA_REG_DEPTH, par->depth); | ||
172 | vmw_write(vmw_priv, SVGA_REG_RED_MASK, 0x00ff0000); | ||
173 | vmw_write(vmw_priv, SVGA_REG_GREEN_MASK, 0x0000ff00); | ||
174 | vmw_write(vmw_priv, SVGA_REG_BLUE_MASK, 0x000000ff); | ||
175 | |||
176 | /* TODO check if pitch and offset changes */ | 159 | /* TODO check if pitch and offset changes */ |
177 | |||
178 | vmw_write(vmw_priv, SVGA_REG_NUM_GUEST_DISPLAYS, 1); | 160 | vmw_write(vmw_priv, SVGA_REG_NUM_GUEST_DISPLAYS, 1); |
179 | vmw_write(vmw_priv, SVGA_REG_DISPLAY_ID, 0); | 161 | vmw_write(vmw_priv, SVGA_REG_DISPLAY_ID, 0); |
180 | vmw_write(vmw_priv, SVGA_REG_DISPLAY_IS_PRIMARY, true); | 162 | vmw_write(vmw_priv, SVGA_REG_DISPLAY_IS_PRIMARY, true); |
@@ -183,13 +165,13 @@ static int vmw_fb_set_par(struct fb_info *info) | |||
183 | vmw_write(vmw_priv, SVGA_REG_DISPLAY_WIDTH, info->var.xres); | 165 | vmw_write(vmw_priv, SVGA_REG_DISPLAY_WIDTH, info->var.xres); |
184 | vmw_write(vmw_priv, SVGA_REG_DISPLAY_HEIGHT, info->var.yres); | 166 | vmw_write(vmw_priv, SVGA_REG_DISPLAY_HEIGHT, info->var.yres); |
185 | vmw_write(vmw_priv, SVGA_REG_DISPLAY_ID, SVGA_ID_INVALID); | 167 | vmw_write(vmw_priv, SVGA_REG_DISPLAY_ID, SVGA_ID_INVALID); |
186 | } else { | ||
187 | vmw_write(vmw_priv, SVGA_REG_WIDTH, info->var.xres); | ||
188 | vmw_write(vmw_priv, SVGA_REG_HEIGHT, info->var.yres); | ||
189 | |||
190 | /* TODO check if pitch and offset changes */ | ||
191 | } | 168 | } |
192 | 169 | ||
170 | /* This is really helpful since if this fails the user | ||
171 | * can probably not see anything on the screen. | ||
172 | */ | ||
173 | WARN_ON(vmw_read(vmw_priv, SVGA_REG_FB_OFFSET) != 0); | ||
174 | |||
193 | return 0; | 175 | return 0; |
194 | } | 176 | } |
195 | 177 | ||
@@ -416,48 +398,23 @@ int vmw_fb_init(struct vmw_private *vmw_priv) | |||
416 | unsigned fb_bbp, fb_depth, fb_offset, fb_pitch, fb_size; | 398 | unsigned fb_bbp, fb_depth, fb_offset, fb_pitch, fb_size; |
417 | int ret; | 399 | int ret; |
418 | 400 | ||
401 | /* XXX These shouldn't be hardcoded. */ | ||
419 | initial_width = 800; | 402 | initial_width = 800; |
420 | initial_height = 600; | 403 | initial_height = 600; |
421 | 404 | ||
422 | fb_bbp = 32; | 405 | fb_bbp = 32; |
423 | fb_depth = 24; | 406 | fb_depth = 24; |
424 | 407 | ||
425 | if (vmw_priv->capabilities & SVGA_CAP_MULTIMON) { | 408 | /* XXX As shouldn't these be as well. */ |
426 | fb_width = min(vmw_priv->fb_max_width, (unsigned)2048); | 409 | fb_width = min(vmw_priv->fb_max_width, (unsigned)2048); |
427 | fb_height = min(vmw_priv->fb_max_height, (unsigned)2048); | 410 | fb_height = min(vmw_priv->fb_max_height, (unsigned)2048); |
428 | } else { | ||
429 | fb_width = min(vmw_priv->fb_max_width, initial_width); | ||
430 | fb_height = min(vmw_priv->fb_max_height, initial_height); | ||
431 | } | ||
432 | 411 | ||
433 | initial_width = min(fb_width, initial_width); | 412 | initial_width = min(fb_width, initial_width); |
434 | initial_height = min(fb_height, initial_height); | 413 | initial_height = min(fb_height, initial_height); |
435 | 414 | ||
436 | vmw_write(vmw_priv, SVGA_REG_WIDTH, fb_width); | 415 | fb_pitch = fb_width * fb_bbp / 8; |
437 | vmw_write(vmw_priv, SVGA_REG_HEIGHT, fb_height); | 416 | fb_size = fb_pitch * fb_height; |
438 | vmw_write(vmw_priv, SVGA_REG_BITS_PER_PIXEL, fb_bbp); | ||
439 | vmw_write(vmw_priv, SVGA_REG_DEPTH, fb_depth); | ||
440 | vmw_write(vmw_priv, SVGA_REG_RED_MASK, 0x00ff0000); | ||
441 | vmw_write(vmw_priv, SVGA_REG_GREEN_MASK, 0x0000ff00); | ||
442 | vmw_write(vmw_priv, SVGA_REG_BLUE_MASK, 0x000000ff); | ||
443 | |||
444 | fb_size = vmw_read(vmw_priv, SVGA_REG_FB_SIZE); | ||
445 | fb_offset = vmw_read(vmw_priv, SVGA_REG_FB_OFFSET); | 417 | fb_offset = vmw_read(vmw_priv, SVGA_REG_FB_OFFSET); |
446 | fb_pitch = vmw_read(vmw_priv, SVGA_REG_BYTES_PER_LINE); | ||
447 | |||
448 | DRM_DEBUG("width %u\n", vmw_read(vmw_priv, SVGA_REG_MAX_WIDTH)); | ||
449 | DRM_DEBUG("height %u\n", vmw_read(vmw_priv, SVGA_REG_MAX_HEIGHT)); | ||
450 | DRM_DEBUG("width %u\n", vmw_read(vmw_priv, SVGA_REG_WIDTH)); | ||
451 | DRM_DEBUG("height %u\n", vmw_read(vmw_priv, SVGA_REG_HEIGHT)); | ||
452 | DRM_DEBUG("bpp %u\n", vmw_read(vmw_priv, SVGA_REG_BITS_PER_PIXEL)); | ||
453 | DRM_DEBUG("depth %u\n", vmw_read(vmw_priv, SVGA_REG_DEPTH)); | ||
454 | DRM_DEBUG("bpl %u\n", vmw_read(vmw_priv, SVGA_REG_BYTES_PER_LINE)); | ||
455 | DRM_DEBUG("r mask %08x\n", vmw_read(vmw_priv, SVGA_REG_RED_MASK)); | ||
456 | DRM_DEBUG("g mask %08x\n", vmw_read(vmw_priv, SVGA_REG_GREEN_MASK)); | ||
457 | DRM_DEBUG("b mask %08x\n", vmw_read(vmw_priv, SVGA_REG_BLUE_MASK)); | ||
458 | DRM_DEBUG("fb_offset 0x%08x\n", fb_offset); | ||
459 | DRM_DEBUG("fb_pitch %u\n", fb_pitch); | ||
460 | DRM_DEBUG("fb_size %u kiB\n", fb_size / 1024); | ||
461 | 418 | ||
462 | info = framebuffer_alloc(sizeof(*par), device); | 419 | info = framebuffer_alloc(sizeof(*par), device); |
463 | if (!info) | 420 | if (!info) |
@@ -659,6 +616,10 @@ int vmw_dmabuf_to_start_of_vram(struct vmw_private *vmw_priv, | |||
659 | goto err_unlock; | 616 | goto err_unlock; |
660 | 617 | ||
661 | ret = ttm_bo_validate(bo, &ne_placement, false, false, false); | 618 | ret = ttm_bo_validate(bo, &ne_placement, false, false, false); |
619 | |||
620 | /* Could probably bug on */ | ||
621 | WARN_ON(bo->offset != 0); | ||
622 | |||
662 | ttm_bo_unreserve(bo); | 623 | ttm_bo_unreserve(bo); |
663 | err_unlock: | 624 | err_unlock: |
664 | ttm_write_unlock(&vmw_priv->active_master->lock); | 625 | ttm_write_unlock(&vmw_priv->active_master->lock); |