aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/vmwgfx/vmwgfx_fb.c
diff options
context:
space:
mode:
authorJakob Bornecrantz <jakob@vmware.com>2010-05-28 05:21:59 -0400
committerDave Airlie <airlied@redhat.com>2010-05-31 19:37:25 -0400
commitd7e1958dbe4a7b81d4cab5fab545a068501b967e (patch)
tree92bf46006c21c4f1770bc8803ae6807461fa2e07 /drivers/gpu/drm/vmwgfx/vmwgfx_fb.c
parent1ae1ddd5e99bbc067414ff571ac18d4312b4c8cf (diff)
drm/vmwgfx: Support older hardware.
V2: Fix a couple of typos. Signed-off-by: Jakob Bornecrantz <jakob@vmware.com> Signed-off-by: Thomas Hellstrom <thellstrom@vmware.com> Signed-off-by: Dave Airlie <airlied@redhat.com>
Diffstat (limited to 'drivers/gpu/drm/vmwgfx/vmwgfx_fb.c')
-rw-r--r--drivers/gpu/drm/vmwgfx/vmwgfx_fb.c81
1 files changed, 28 insertions, 53 deletions
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_fb.c b/drivers/gpu/drm/vmwgfx/vmwgfx_fb.c
index 7421aaad8d09..fb66e62b8e2c 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,8 +152,8 @@ 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 if (vmw_priv->capabilities & SVGA_CAP_DISPLAY_TOPOLOGY) {
158 vmw_write(vmw_priv, SVGA_REG_NUM_GUEST_DISPLAYS, 1); 156 vmw_write(vmw_priv, SVGA_REG_ENABLE, 0);
159 vmw_write(vmw_priv, SVGA_REG_DISPLAY_ID, 0); 157 vmw_write(vmw_priv, SVGA_REG_DISPLAY_ID, 0);
160 vmw_write(vmw_priv, SVGA_REG_DISPLAY_IS_PRIMARY, true); 158 vmw_write(vmw_priv, SVGA_REG_DISPLAY_IS_PRIMARY, true);
161 vmw_write(vmw_priv, SVGA_REG_DISPLAY_POSITION_X, 0); 159 vmw_write(vmw_priv, SVGA_REG_DISPLAY_POSITION_X, 0);
@@ -164,18 +162,11 @@ static int vmw_fb_set_par(struct fb_info *info)
164 vmw_write(vmw_priv, SVGA_REG_DISPLAY_HEIGHT, 0); 162 vmw_write(vmw_priv, SVGA_REG_DISPLAY_HEIGHT, 0);
165 vmw_write(vmw_priv, SVGA_REG_DISPLAY_ID, SVGA_ID_INVALID); 163 vmw_write(vmw_priv, SVGA_REG_DISPLAY_ID, SVGA_ID_INVALID);
166 164
167 vmw_write(vmw_priv, SVGA_REG_ENABLE, 1); 165 vmw_kms_write_svga(vmw_priv, info->var.xres, info->var.yres,
168 vmw_write(vmw_priv, SVGA_REG_WIDTH, par->max_width); 166 info->fix.line_length,
169 vmw_write(vmw_priv, SVGA_REG_HEIGHT, par->max_height); 167 par->bpp, par->depth);
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 168
176 /* TODO check if pitch and offset changes */ 169 /* TODO check if pitch and offset changes */
177
178 vmw_write(vmw_priv, SVGA_REG_NUM_GUEST_DISPLAYS, 1);
179 vmw_write(vmw_priv, SVGA_REG_DISPLAY_ID, 0); 170 vmw_write(vmw_priv, SVGA_REG_DISPLAY_ID, 0);
180 vmw_write(vmw_priv, SVGA_REG_DISPLAY_IS_PRIMARY, true); 171 vmw_write(vmw_priv, SVGA_REG_DISPLAY_IS_PRIMARY, true);
181 vmw_write(vmw_priv, SVGA_REG_DISPLAY_POSITION_X, info->var.xoffset); 172 vmw_write(vmw_priv, SVGA_REG_DISPLAY_POSITION_X, info->var.xoffset);
@@ -183,13 +174,22 @@ static int vmw_fb_set_par(struct fb_info *info)
183 vmw_write(vmw_priv, SVGA_REG_DISPLAY_WIDTH, info->var.xres); 174 vmw_write(vmw_priv, SVGA_REG_DISPLAY_WIDTH, info->var.xres);
184 vmw_write(vmw_priv, SVGA_REG_DISPLAY_HEIGHT, info->var.yres); 175 vmw_write(vmw_priv, SVGA_REG_DISPLAY_HEIGHT, info->var.yres);
185 vmw_write(vmw_priv, SVGA_REG_DISPLAY_ID, SVGA_ID_INVALID); 176 vmw_write(vmw_priv, SVGA_REG_DISPLAY_ID, SVGA_ID_INVALID);
177 vmw_write(vmw_priv, SVGA_REG_NUM_GUEST_DISPLAYS, 1);
178 vmw_write(vmw_priv, SVGA_REG_ENABLE, 1);
186 } else { 179 } else {
187 vmw_write(vmw_priv, SVGA_REG_WIDTH, info->var.xres); 180 vmw_write(vmw_priv, SVGA_REG_ENABLE, 0);
188 vmw_write(vmw_priv, SVGA_REG_HEIGHT, info->var.yres); 181 vmw_kms_write_svga(vmw_priv, info->var.xres, info->var.yres,
182 info->fix.line_length,
183 par->bpp, par->depth);
184 vmw_write(vmw_priv, SVGA_REG_ENABLE, 1);
189 185
190 /* TODO check if pitch and offset changes */
191 } 186 }
192 187
188 /* This is really helpful since if this fails the user
189 * can probably not see anything on the screen.
190 */
191 WARN_ON(vmw_read(vmw_priv, SVGA_REG_FB_OFFSET) != 0);
192
193 return 0; 193 return 0;
194} 194}
195 195
@@ -416,48 +416,23 @@ int vmw_fb_init(struct vmw_private *vmw_priv)
416 unsigned fb_bbp, fb_depth, fb_offset, fb_pitch, fb_size; 416 unsigned fb_bbp, fb_depth, fb_offset, fb_pitch, fb_size;
417 int ret; 417 int ret;
418 418
419 /* XXX These shouldn't be hardcoded. */
419 initial_width = 800; 420 initial_width = 800;
420 initial_height = 600; 421 initial_height = 600;
421 422
422 fb_bbp = 32; 423 fb_bbp = 32;
423 fb_depth = 24; 424 fb_depth = 24;
424 425
425 if (vmw_priv->capabilities & SVGA_CAP_MULTIMON) { 426 /* XXX As shouldn't these be as well. */
426 fb_width = min(vmw_priv->fb_max_width, (unsigned)2048); 427 fb_width = min(vmw_priv->fb_max_width, (unsigned)2048);
427 fb_height = min(vmw_priv->fb_max_height, (unsigned)2048); 428 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 429
433 initial_width = min(fb_width, initial_width); 430 initial_width = min(fb_width, initial_width);
434 initial_height = min(fb_height, initial_height); 431 initial_height = min(fb_height, initial_height);
435 432
436 vmw_write(vmw_priv, SVGA_REG_WIDTH, fb_width); 433 fb_pitch = fb_width * fb_bbp / 8;
437 vmw_write(vmw_priv, SVGA_REG_HEIGHT, fb_height); 434 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); 435 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 436
462 info = framebuffer_alloc(sizeof(*par), device); 437 info = framebuffer_alloc(sizeof(*par), device);
463 if (!info) 438 if (!info)