diff options
author | Jakob Bornecrantz <jakob@vmware.com> | 2010-05-28 05:21:59 -0400 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2010-05-31 19:37:25 -0400 |
commit | d7e1958dbe4a7b81d4cab5fab545a068501b967e (patch) | |
tree | 92bf46006c21c4f1770bc8803ae6807461fa2e07 /drivers/gpu/drm/vmwgfx/vmwgfx_fb.c | |
parent | 1ae1ddd5e99bbc067414ff571ac18d4312b4c8cf (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.c | 81 |
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) |