aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/video/mb862xx/mb862xxfbdrv.c
diff options
context:
space:
mode:
authorAnatolij Gustschin <agust@denx.de>2011-05-13 07:31:37 -0400
committerAnatolij Gustschin <agust@denx.de>2011-05-24 10:28:52 -0400
commitf64d8a5fdec35ed36f76130517a5580974a324a4 (patch)
tree97e278a48d00c6c0d7feeb038b9d89fecf480a9f /drivers/video/mb862xx/mb862xxfbdrv.c
parentf8a6b1f44833a4eb4c323b8b71fc592646212090 (diff)
video: mb862xxfb: add support for L1 displaying
Allow displaying L1 video data on top of the primary L0 layer. The L1 layer position and dimensions can be configured and the layer enabled/disabled by using the appropriate L1 controls added by this patch. Signed-off-by: Anatolij Gustschin <agust@denx.de>
Diffstat (limited to 'drivers/video/mb862xx/mb862xxfbdrv.c')
-rw-r--r--drivers/video/mb862xx/mb862xxfbdrv.c116
1 files changed, 115 insertions, 1 deletions
diff --git a/drivers/video/mb862xx/mb862xxfbdrv.c b/drivers/video/mb862xx/mb862xxfbdrv.c
index 0cc20b4fbcb5..ea39336addfb 100644
--- a/drivers/video/mb862xx/mb862xxfbdrv.c
+++ b/drivers/video/mb862xx/mb862xxfbdrv.c
@@ -27,7 +27,7 @@
27 27
28#define NR_PALETTE 256 28#define NR_PALETTE 256
29#define MB862XX_MEM_SIZE 0x1000000 29#define MB862XX_MEM_SIZE 0x1000000
30#define CORALP_MEM_SIZE 0x4000000 30#define CORALP_MEM_SIZE 0x2000000
31#define CARMINE_MEM_SIZE 0x8000000 31#define CARMINE_MEM_SIZE 0x8000000
32#define DRV_NAME "mb862xxfb" 32#define DRV_NAME "mb862xxfb"
33 33
@@ -309,6 +309,97 @@ static int mb862xxfb_blank(int mode, struct fb_info *fbi)
309 return 0; 309 return 0;
310} 310}
311 311
312static int mb862xxfb_ioctl(struct fb_info *fbi, unsigned int cmd,
313 unsigned long arg)
314{
315 struct mb862xxfb_par *par = fbi->par;
316 struct mb862xx_l1_cfg *l1_cfg = &par->l1_cfg;
317 void __user *argp = (void __user *)arg;
318 int *enable;
319 u32 l1em = 0;
320
321 switch (cmd) {
322 case MB862XX_L1_GET_CFG:
323 if (copy_to_user(argp, l1_cfg, sizeof(*l1_cfg)))
324 return -EFAULT;
325 break;
326 case MB862XX_L1_SET_CFG:
327 if (copy_from_user(l1_cfg, argp, sizeof(*l1_cfg)))
328 return -EFAULT;
329 if ((l1_cfg->sw >= l1_cfg->dw) && (l1_cfg->sh >= l1_cfg->dh)) {
330 /* downscaling */
331 outreg(cap, GC_CAP_CSC,
332 pack((l1_cfg->sh << 11) / l1_cfg->dh,
333 (l1_cfg->sw << 11) / l1_cfg->dw));
334 l1em = inreg(disp, GC_L1EM);
335 l1em &= ~GC_L1EM_DM;
336 } else if ((l1_cfg->sw <= l1_cfg->dw) &&
337 (l1_cfg->sh <= l1_cfg->dh)) {
338 /* upscaling */
339 outreg(cap, GC_CAP_CSC,
340 pack((l1_cfg->sh << 11) / l1_cfg->dh,
341 (l1_cfg->sw << 11) / l1_cfg->dw));
342 outreg(cap, GC_CAP_CMSS,
343 pack(l1_cfg->sw >> 1, l1_cfg->sh));
344 outreg(cap, GC_CAP_CMDS,
345 pack(l1_cfg->dw >> 1, l1_cfg->dh));
346 l1em = inreg(disp, GC_L1EM);
347 l1em |= GC_L1EM_DM;
348 }
349
350 if (l1_cfg->mirror) {
351 outreg(cap, GC_CAP_CBM,
352 inreg(cap, GC_CAP_CBM) | GC_CBM_HRV);
353 l1em |= l1_cfg->dw * 2 - 8;
354 } else {
355 outreg(cap, GC_CAP_CBM,
356 inreg(cap, GC_CAP_CBM) & ~GC_CBM_HRV);
357 l1em &= 0xffff0000;
358 }
359 outreg(disp, GC_L1EM, l1em);
360 break;
361 case MB862XX_L1_ENABLE:
362 enable = (int *)arg;
363 if (*enable) {
364 outreg(disp, GC_L1DA, par->cap_buf);
365 outreg(cap, GC_CAP_IMG_START,
366 pack(l1_cfg->sy >> 1, l1_cfg->sx));
367 outreg(cap, GC_CAP_IMG_END,
368 pack(l1_cfg->sh, l1_cfg->sw));
369 outreg(disp, GC_L1M, GC_L1M_16 | GC_L1M_YC | GC_L1M_CS |
370 (par->l1_stride << 16));
371 outreg(disp, GC_L1WY_L1WX,
372 pack(l1_cfg->dy, l1_cfg->dx));
373 outreg(disp, GC_L1WH_L1WW,
374 pack(l1_cfg->dh - 1, l1_cfg->dw));
375 outreg(disp, GC_DLS, 1);
376 outreg(cap, GC_CAP_VCM,
377 GC_VCM_VIE | GC_VCM_CM | GC_VCM_VS_PAL);
378 outreg(disp, GC_DCM1, inreg(disp, GC_DCM1) |
379 GC_DCM1_DEN | GC_DCM1_L1E);
380 } else {
381 outreg(cap, GC_CAP_VCM,
382 inreg(cap, GC_CAP_VCM) & ~GC_VCM_VIE);
383 outreg(disp, GC_DCM1,
384 inreg(disp, GC_DCM1) & ~GC_DCM1_L1E);
385 }
386 break;
387 case MB862XX_L1_CAP_CTL:
388 enable = (int *)arg;
389 if (*enable) {
390 outreg(cap, GC_CAP_VCM,
391 inreg(cap, GC_CAP_VCM) | GC_VCM_VIE);
392 } else {
393 outreg(cap, GC_CAP_VCM,
394 inreg(cap, GC_CAP_VCM) & ~GC_VCM_VIE);
395 }
396 break;
397 default:
398 return -EINVAL;
399 }
400 return 0;
401}
402
312/* framebuffer ops */ 403/* framebuffer ops */
313static struct fb_ops mb862xxfb_ops = { 404static struct fb_ops mb862xxfb_ops = {
314 .owner = THIS_MODULE, 405 .owner = THIS_MODULE,
@@ -320,6 +411,7 @@ static struct fb_ops mb862xxfb_ops = {
320 .fb_fillrect = cfb_fillrect, 411 .fb_fillrect = cfb_fillrect,
321 .fb_copyarea = cfb_copyarea, 412 .fb_copyarea = cfb_copyarea,
322 .fb_imageblit = cfb_imageblit, 413 .fb_imageblit = cfb_imageblit,
414 .fb_ioctl = mb862xxfb_ioctl,
323}; 415};
324 416
325/* initialize fb_info data */ 417/* initialize fb_info data */
@@ -328,6 +420,7 @@ static int mb862xxfb_init_fbinfo(struct fb_info *fbi)
328 struct mb862xxfb_par *par = fbi->par; 420 struct mb862xxfb_par *par = fbi->par;
329 struct mb862xx_gc_mode *mode = par->gc_mode; 421 struct mb862xx_gc_mode *mode = par->gc_mode;
330 unsigned long reg; 422 unsigned long reg;
423 int stride;
331 424
332 fbi->fbops = &mb862xxfb_ops; 425 fbi->fbops = &mb862xxfb_ops;
333 fbi->pseudo_palette = par->pseudo_palette; 426 fbi->pseudo_palette = par->pseudo_palette;
@@ -420,6 +513,27 @@ static int mb862xxfb_init_fbinfo(struct fb_info *fbi)
420 fbi->fix.line_length = (fbi->var.xres_virtual * 513 fbi->fix.line_length = (fbi->var.xres_virtual *
421 fbi->var.bits_per_pixel) / 8; 514 fbi->var.bits_per_pixel) / 8;
422 fbi->fix.smem_len = fbi->fix.line_length * fbi->var.yres_virtual; 515 fbi->fix.smem_len = fbi->fix.line_length * fbi->var.yres_virtual;
516
517 /*
518 * reserve space for capture buffers and two cursors
519 * at the end of vram: 720x576 * 2 * 2.2 + 64x64 * 16.
520 */
521 par->cap_buf = par->mapped_vram - 0x1bd800 - 0x10000;
522 par->cap_len = 0x1bd800;
523 par->l1_cfg.sx = 0;
524 par->l1_cfg.sy = 0;
525 par->l1_cfg.sw = 720;
526 par->l1_cfg.sh = 576;
527 par->l1_cfg.dx = 0;
528 par->l1_cfg.dy = 0;
529 par->l1_cfg.dw = 720;
530 par->l1_cfg.dh = 576;
531 stride = par->l1_cfg.sw * (fbi->var.bits_per_pixel / 8);
532 par->l1_stride = stride / 64 + ((stride % 64) ? 1 : 0);
533 outreg(cap, GC_CAP_CBM, GC_CBM_OO | GC_CBM_CBST |
534 (par->l1_stride << 16));
535 outreg(cap, GC_CAP_CBOA, par->cap_buf);
536 outreg(cap, GC_CAP_CBLA, par->cap_buf + par->cap_len);
423 return 0; 537 return 0;
424} 538}
425 539