|
Lines 55-60
struct vmw_fb_par {
Link Here
|
| 55 |
unsigned bo_size; |
55 |
unsigned bo_size; |
| 56 |
bool bo_iowrite; |
56 |
bool bo_iowrite; |
| 57 |
|
57 |
|
|
|
58 |
/* for page-fault screen updates (single-buffered) */ |
| 58 |
struct { |
59 |
struct { |
| 59 |
spinlock_t lock; |
60 |
spinlock_t lock; |
| 60 |
bool active; |
61 |
bool active; |
|
Lines 63-70
struct vmw_fb_par {
Link Here
|
| 63 |
unsigned x2; |
64 |
unsigned x2; |
| 64 |
unsigned y2; |
65 |
unsigned y2; |
| 65 |
} dirty; |
66 |
} dirty; |
|
|
67 |
|
| 68 |
/* for pan-based screen updates (multi-buffered) */ |
| 69 |
struct delayed_work pan_delayed_work; |
| 66 |
}; |
70 |
}; |
| 67 |
|
71 |
|
|
|
72 |
struct fb_deferred_io vmw_defio; |
| 73 |
static void vmw_deferred_io(struct fb_info *info, |
| 74 |
struct list_head *pagelist); |
| 75 |
static void vmw_deferred_io_noop(struct fb_info *info, |
| 76 |
struct list_head *pagelist); |
| 77 |
|
| 68 |
static int vmw_fb_setcolreg(unsigned regno, unsigned red, unsigned green, |
78 |
static int vmw_fb_setcolreg(unsigned regno, unsigned red, unsigned green, |
| 69 |
unsigned blue, unsigned transp, |
79 |
unsigned blue, unsigned transp, |
| 70 |
struct fb_info *info) |
80 |
struct fb_info *info) |
|
Lines 188-200
static int vmw_fb_set_par(struct fb_info *info)
Link Here
|
| 188 |
*/ |
198 |
*/ |
| 189 |
WARN_ON(vmw_read(vmw_priv, SVGA_REG_FB_OFFSET) != 0); |
199 |
WARN_ON(vmw_read(vmw_priv, SVGA_REG_FB_OFFSET) != 0); |
| 190 |
|
200 |
|
|
|
201 |
#ifdef CONFIG_DRM_VMWGFX_FB_PAN |
| 202 |
if ( |
| 203 |
info->var.yres_virtual > info->var.yres && |
| 204 |
!(info->var.yres_virtual % info->var.yres) |
| 205 |
) { |
| 206 |
/* the fb_deferred_io work that happens as a result of page faults |
| 207 |
* is disabled, user _must_ manually pan display |
| 208 |
*/ |
| 209 |
cancel_delayed_work_sync(&info->deferred_work); |
| 210 |
vmw_defio.deferred_io = vmw_deferred_io_noop; |
| 211 |
} else { |
| 212 |
/* the fb_deferred_io work that happens as a result of page faults |
| 213 |
* is enabled |
| 214 |
*/ |
| 215 |
cancel_delayed_work_sync(&par->pan_delayed_work); |
| 216 |
vmw_defio.deferred_io = vmw_deferred_io; |
| 217 |
} |
| 218 |
#endif |
| 219 |
|
| 191 |
return 0; |
220 |
return 0; |
| 192 |
} |
221 |
} |
| 193 |
|
222 |
|
| 194 |
static int vmw_fb_pan_display(struct fb_var_screeninfo *var, |
223 |
static int vmw_fb_pan_display(struct fb_var_screeninfo *var, |
| 195 |
struct fb_info *info) |
224 |
struct fb_info *info) |
| 196 |
{ |
225 |
{ |
| 197 |
return 0; |
226 |
int ret = 0; |
|
|
227 |
#ifdef CONFIG_DRM_VMWGFX_FB_PAN |
| 228 |
struct vmw_fb_par *par = info->par; |
| 229 |
|
| 230 |
ret = |
| 231 |
var->yoffset >= info->var.yres_virtual || |
| 232 |
var->yoffset % info->var.yres |
| 233 |
? -EINVAL |
| 234 |
: 0; |
| 235 |
if ( !ret ) { |
| 236 |
info->var.yoffset = var->yoffset; |
| 237 |
schedule_delayed_work(&par->pan_delayed_work, VMW_DIRTY_DELAY); |
| 238 |
} |
| 239 |
#endif |
| 240 |
return ret; |
| 198 |
} |
241 |
} |
| 199 |
|
242 |
|
| 200 |
static int vmw_fb_blank(int blank, struct fb_info *info) |
243 |
static int vmw_fb_blank(int blank, struct fb_info *info) |
|
Lines 325-335
static void vmw_deferred_io(struct fb_info *info,
Link Here
|
| 325 |
vmw_fb_dirty_flush(par); |
368 |
vmw_fb_dirty_flush(par); |
| 326 |
}; |
369 |
}; |
| 327 |
|
370 |
|
|
|
371 |
static void vmw_deferred_io_noop(struct fb_info *info, |
| 372 |
struct list_head *pagelist) |
| 373 |
{ |
| 374 |
} |
| 375 |
|
| 328 |
struct fb_deferred_io vmw_defio = { |
376 |
struct fb_deferred_io vmw_defio = { |
| 329 |
.delay = VMW_DIRTY_DELAY, |
377 |
.delay = VMW_DIRTY_DELAY, |
| 330 |
.deferred_io = vmw_deferred_io, |
378 |
.deferred_io = vmw_deferred_io, |
| 331 |
}; |
379 |
}; |
| 332 |
|
380 |
|
|
|
381 |
static void vmw_delayed_work_pan(struct work_struct *work) |
| 382 |
{ |
| 383 |
int i, k; |
| 384 |
|
| 385 |
struct vmw_fb_par *par = container_of(work, struct vmw_fb_par, |
| 386 |
pan_delayed_work.work); |
| 387 |
struct vmw_private *vmw_priv = par->vmw_priv; |
| 388 |
struct fb_info *info = vmw_priv->fb_info; |
| 389 |
|
| 390 |
int *src = (int *)info->screen_base; |
| 391 |
__le32 __iomem *vram_mem = par->bo_ptr; |
| 392 |
|
| 393 |
struct { |
| 394 |
uint32_t header; |
| 395 |
SVGAFifoCmdUpdate body; |
| 396 |
} *cmd; |
| 397 |
|
| 398 |
for( |
| 399 |
i=0, k=info->var.yoffset*info->var.xres; |
| 400 |
i<info->var.yres*info->var.xres; |
| 401 |
k++, i++ |
| 402 |
) { |
| 403 |
iowrite32(src[k], vram_mem + i); |
| 404 |
} |
| 405 |
|
| 406 |
cmd = vmw_fifo_reserve(vmw_priv, sizeof(*cmd)); |
| 407 |
if (unlikely(cmd == NULL)) { |
| 408 |
DRM_ERROR("Fifo reserve failed.\n"); |
| 409 |
return; |
| 410 |
} |
| 411 |
|
| 412 |
cmd->header = cpu_to_le32(SVGA_CMD_UPDATE); |
| 413 |
cmd->body.x = cpu_to_le32(0); |
| 414 |
cmd->body.y = cpu_to_le32(0); |
| 415 |
cmd->body.width = cpu_to_le32(info->var.xres); |
| 416 |
cmd->body.height = cpu_to_le32(info->var.yres); |
| 417 |
vmw_fifo_commit(vmw_priv, sizeof(*cmd)); |
| 418 |
} |
| 419 |
|
| 333 |
/* |
420 |
/* |
| 334 |
* Draw code |
421 |
* Draw code |
| 335 |
*/ |
422 |
*/ |
|
Lines 533-538
int vmw_fb_init(struct vmw_private *vmw_priv)
Link Here
|
| 533 |
spin_lock_init(&par->dirty.lock); |
620 |
spin_lock_init(&par->dirty.lock); |
| 534 |
info->fbdefio = &vmw_defio; |
621 |
info->fbdefio = &vmw_defio; |
| 535 |
fb_deferred_io_init(info); |
622 |
fb_deferred_io_init(info); |
|
|
623 |
if ( CONFIG_DRM_VMWGFX_FB_PAN ) { |
| 624 |
INIT_DELAYED_WORK(&par->pan_delayed_work, vmw_delayed_work_pan); |
| 625 |
} |
| 536 |
|
626 |
|
| 537 |
ret = register_framebuffer(info); |
627 |
ret = register_framebuffer(info); |
| 538 |
if (unlikely(ret != 0)) |
628 |
if (unlikely(ret != 0)) |
|
Lines 569-574
int vmw_fb_close(struct vmw_private *vmw_priv)
Link Here
|
| 569 |
par->vmw_bo = NULL; |
659 |
par->vmw_bo = NULL; |
| 570 |
|
660 |
|
| 571 |
/* ??? order */ |
661 |
/* ??? order */ |
|
|
662 |
if ( CONFIG_DRM_VMWGFX_FB_PAN ) { |
| 663 |
cancel_delayed_work_sync(&par->pan_delayed_work); |
| 664 |
} |
| 572 |
fb_deferred_io_cleanup(info); |
665 |
fb_deferred_io_cleanup(info); |
| 573 |
unregister_framebuffer(info); |
666 |
unregister_framebuffer(info); |
| 574 |
|
667 |
|
|
Lines 598-603
int vmw_fb_off(struct vmw_private *vmw_priv)
Link Here
|
| 598 |
spin_unlock_irqrestore(&par->dirty.lock, flags); |
691 |
spin_unlock_irqrestore(&par->dirty.lock, flags); |
| 599 |
|
692 |
|
| 600 |
flush_delayed_work(&info->deferred_work); |
693 |
flush_delayed_work(&info->deferred_work); |
|
|
694 |
if ( CONFIG_DRM_VMWGFX_FB_PAN ) { |
| 695 |
flush_delayed_work(&par->pan_delayed_work); |
| 696 |
} |
| 601 |
|
697 |
|
| 602 |
par->bo_ptr = NULL; |
698 |
par->bo_ptr = NULL; |
| 603 |
ttm_bo_kunmap(&par->map); |
699 |
ttm_bo_kunmap(&par->map); |