aboutsummaryrefslogtreecommitdiffstats
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
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>
-rw-r--r--drivers/video/mb862xx/mb862xx_reg.h31
-rw-r--r--drivers/video/mb862xx/mb862xxfb.h27
-rw-r--r--drivers/video/mb862xx/mb862xxfbdrv.c116
3 files changed, 173 insertions, 1 deletions
diff --git a/drivers/video/mb862xx/mb862xx_reg.h b/drivers/video/mb862xx/mb862xx_reg.h
index 5784b018f15d..9df48b8edc94 100644
--- a/drivers/video/mb862xx/mb862xx_reg.h
+++ b/drivers/video/mb862xx/mb862xx_reg.h
@@ -51,10 +51,16 @@
51#define GC_L0OA0 0x00000024 51#define GC_L0OA0 0x00000024
52#define GC_L0DA0 0x00000028 52#define GC_L0DA0 0x00000028
53#define GC_L0DY_L0DX 0x0000002c 53#define GC_L0DY_L0DX 0x0000002c
54#define GC_L1M 0x00000030
55#define GC_L1DA 0x00000034
54#define GC_DCM1 0x00000100 56#define GC_DCM1 0x00000100
55#define GC_L0EM 0x00000110 57#define GC_L0EM 0x00000110
56#define GC_L0WY_L0WX 0x00000114 58#define GC_L0WY_L0WX 0x00000114
57#define GC_L0WH_L0WW 0x00000118 59#define GC_L0WH_L0WW 0x00000118
60#define GC_L1EM 0x00000120
61#define GC_L1WY_L1WX 0x00000124
62#define GC_L1WH_L1WW 0x00000128
63#define GC_DLS 0x00000180
58#define GC_DCM2 0x00000104 64#define GC_DCM2 0x00000104
59#define GC_DCM3 0x00000108 65#define GC_DCM3 0x00000108
60#define GC_CPM_CUTC 0x000000a0 66#define GC_CPM_CUTC 0x000000a0
@@ -66,6 +72,11 @@
66 72
67#define GC_CPM_CEN0 0x00100000 73#define GC_CPM_CEN0 0x00100000
68#define GC_CPM_CEN1 0x00200000 74#define GC_CPM_CEN1 0x00200000
75#define GC_DCM1_DEN 0x80000000
76#define GC_DCM1_L1E 0x00020000
77#define GC_L1M_16 0x80000000
78#define GC_L1M_YC 0x40000000
79#define GC_L1M_CS 0x20000000
69 80
70#define GC_DCM01_ESY 0x00000004 81#define GC_DCM01_ESY 0x00000004
71#define GC_DCM01_SC 0x00003f00 82#define GC_DCM01_SC 0x00003f00
@@ -77,6 +88,7 @@
77#define GC_L0M_L0C_16 0x80000000 88#define GC_L0M_L0C_16 0x80000000
78#define GC_L0EM_L0EC_24 0x40000000 89#define GC_L0EM_L0EC_24 0x40000000
79#define GC_L0M_L0W_UNIT 64 90#define GC_L0M_L0W_UNIT 64
91#define GC_L1EM_DM 0x02000000
80 92
81#define GC_DISP_REFCLK_400 400 93#define GC_DISP_REFCLK_400 400
82 94
@@ -101,6 +113,25 @@
101#define I2C_TRX 0x80 113#define I2C_TRX 0x80
102#define I2C_LRB 0x10 114#define I2C_LRB 0x10
103 115
116/* Capture registers and bits */
117#define GC_CAP_VCM 0x00000000
118#define GC_CAP_CSC 0x00000004
119#define GC_CAP_VCS 0x00000008
120#define GC_CAP_CBM 0x00000010
121#define GC_CAP_CBOA 0x00000014
122#define GC_CAP_CBLA 0x00000018
123#define GC_CAP_IMG_START 0x0000001C
124#define GC_CAP_IMG_END 0x00000020
125#define GC_CAP_CMSS 0x00000048
126#define GC_CAP_CMDS 0x0000004C
127
128#define GC_VCM_VIE 0x80000000
129#define GC_VCM_CM 0x03000000
130#define GC_VCM_VS_PAL 0x00000002
131#define GC_CBM_OO 0x80000000
132#define GC_CBM_HRV 0x00000010
133#define GC_CBM_CBST 0x00000001
134
104/* Carmine specific */ 135/* Carmine specific */
105#define MB86297_DRAW_BASE 0x00020000 136#define MB86297_DRAW_BASE 0x00020000
106#define MB86297_DISP0_BASE 0x00100000 137#define MB86297_DISP0_BASE 0x00100000
diff --git a/drivers/video/mb862xx/mb862xxfb.h b/drivers/video/mb862xx/mb862xxfb.h
index d5dd7d9ec0cd..8550630c1e01 100644
--- a/drivers/video/mb862xx/mb862xxfb.h
+++ b/drivers/video/mb862xx/mb862xxfb.h
@@ -1,6 +1,26 @@
1#ifndef __MB862XX_H__ 1#ifndef __MB862XX_H__
2#define __MB862XX_H__ 2#define __MB862XX_H__
3 3
4struct mb862xx_l1_cfg {
5 unsigned short sx;
6 unsigned short sy;
7 unsigned short sw;
8 unsigned short sh;
9 unsigned short dx;
10 unsigned short dy;
11 unsigned short dw;
12 unsigned short dh;
13 int mirror;
14};
15
16#define MB862XX_BASE 'M'
17#define MB862XX_L1_GET_CFG _IOR(MB862XX_BASE, 0, struct mb862xx_l1_cfg*)
18#define MB862XX_L1_SET_CFG _IOW(MB862XX_BASE, 1, struct mb862xx_l1_cfg*)
19#define MB862XX_L1_ENABLE _IOW(MB862XX_BASE, 2, int)
20#define MB862XX_L1_CAP_CTL _IOW(MB862XX_BASE, 3, int)
21
22#ifdef __KERNEL__
23
4#define PCI_VENDOR_ID_FUJITSU_LIMITED 0x10cf 24#define PCI_VENDOR_ID_FUJITSU_LIMITED 0x10cf
5#define PCI_DEVICE_ID_FUJITSU_CORALP 0x2019 25#define PCI_DEVICE_ID_FUJITSU_CORALP 0x2019
6#define PCI_DEVICE_ID_FUJITSU_CORALPA 0x201e 26#define PCI_DEVICE_ID_FUJITSU_CORALPA 0x201e
@@ -38,6 +58,8 @@ struct mb862xxfb_par {
38 void __iomem *mmio_base; /* remapped registers */ 58 void __iomem *mmio_base; /* remapped registers */
39 size_t mapped_vram; /* length of remapped vram */ 59 size_t mapped_vram; /* length of remapped vram */
40 size_t mmio_len; /* length of register region */ 60 size_t mmio_len; /* length of register region */
61 unsigned long cap_buf; /* capture buffers offset */
62 size_t cap_len; /* length of capture buffers */
41 63
42 void __iomem *host; /* relocatable reg. bases */ 64 void __iomem *host; /* relocatable reg. bases */
43 void __iomem *i2c; 65 void __iomem *i2c;
@@ -60,6 +82,9 @@ struct mb862xxfb_par {
60 struct i2c_adapter *adap; /* GDC I2C bus adapter */ 82 struct i2c_adapter *adap; /* GDC I2C bus adapter */
61 int i2c_rs; 83 int i2c_rs;
62 84
85 struct mb862xx_l1_cfg l1_cfg;
86 int l1_stride;
87
63 u32 pseudo_palette[16]; 88 u32 pseudo_palette[16];
64}; 89};
65 90
@@ -91,4 +116,6 @@ static inline void mb862xx_i2c_exit(struct mb862xxfb_par *par) { }
91 116
92#define pack(a, b) (((a) << 16) | (b)) 117#define pack(a, b) (((a) << 16) | (b))
93 118
119#endif /* __KERNEL__ */
120
94#endif 121#endif
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