aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPaul Mundt <lethal@linux-sh.org>2011-05-24 22:06:36 -0400
committerPaul Mundt <lethal@linux-sh.org>2011-05-24 22:06:36 -0400
commite2968f7018193eb5385a925225f135c9ba61eb93 (patch)
tree97e278a48d00c6c0d7feeb038b9d89fecf480a9f
parentaf1ce6b2fad7d572aef040d61a935da28a861853 (diff)
parentf64d8a5fdec35ed36f76130517a5580974a324a4 (diff)
Merge branch 'mb862xxfb-for-next' of git://git.denx.de/linux-2.6-agust
-rw-r--r--drivers/video/Kconfig9
-rw-r--r--drivers/video/mb862xx/Makefile5
-rw-r--r--drivers/video/mb862xx/mb862xx-i2c.c177
-rw-r--r--drivers/video/mb862xx/mb862xx_reg.h58
-rw-r--r--drivers/video/mb862xx/mb862xxfb.h36
-rw-r--r--drivers/video/mb862xx/mb862xxfbdrv.c (renamed from drivers/video/mb862xx/mb862xxfb.c)152
6 files changed, 425 insertions, 12 deletions
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
index 7326962565ce..549b960667c8 100644
--- a/drivers/video/Kconfig
+++ b/drivers/video/Kconfig
@@ -2294,6 +2294,15 @@ config FB_MB862XX_LIME
2294 2294
2295endchoice 2295endchoice
2296 2296
2297config FB_MB862XX_I2C
2298 bool "Support I2C bus on MB862XX GDC"
2299 depends on FB_MB862XX && I2C
2300 default y
2301 help
2302 Selecting this option adds Coral-P(A)/Lime GDC I2C bus adapter
2303 driver to support accessing I2C devices on controller's I2C bus.
2304 These are usually some video decoder chips.
2305
2297config FB_EP93XX 2306config FB_EP93XX
2298 tristate "EP93XX frame buffer support" 2307 tristate "EP93XX frame buffer support"
2299 depends on FB && ARCH_EP93XX 2308 depends on FB && ARCH_EP93XX
diff --git a/drivers/video/mb862xx/Makefile b/drivers/video/mb862xx/Makefile
index d7777714166b..5707ed0e31a7 100644
--- a/drivers/video/mb862xx/Makefile
+++ b/drivers/video/mb862xx/Makefile
@@ -2,4 +2,7 @@
2# Makefile for the MB862xx framebuffer driver 2# Makefile for the MB862xx framebuffer driver
3# 3#
4 4
5obj-$(CONFIG_FB_MB862XX) := mb862xxfb.o mb862xxfb_accel.o 5obj-$(CONFIG_FB_MB862XX) += mb862xxfb.o
6
7mb862xxfb-y := mb862xxfbdrv.o mb862xxfb_accel.o
8mb862xxfb-$(CONFIG_FB_MB862XX_I2C) += mb862xx-i2c.o
diff --git a/drivers/video/mb862xx/mb862xx-i2c.c b/drivers/video/mb862xx/mb862xx-i2c.c
new file mode 100644
index 000000000000..cb77d3b4657d
--- /dev/null
+++ b/drivers/video/mb862xx/mb862xx-i2c.c
@@ -0,0 +1,177 @@
1/*
2 * Coral-P(A)/Lime I2C adapter driver
3 *
4 * (C) 2011 DENX Software Engineering, Anatolij Gustschin <agust@denx.de>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 *
10 */
11
12#include <linux/fb.h>
13#include <linux/i2c.h>
14#include <linux/io.h>
15
16#include "mb862xxfb.h"
17#include "mb862xx_reg.h"
18
19static int mb862xx_i2c_wait_event(struct i2c_adapter *adap)
20{
21 struct mb862xxfb_par *par = adap->algo_data;
22 u32 reg;
23
24 do {
25 udelay(1);
26 reg = inreg(i2c, GC_I2C_BCR);
27 if (reg & (I2C_INT | I2C_BER))
28 break;
29 } while (1);
30
31 return (reg & I2C_BER) ? 0 : 1;
32}
33
34static int mb862xx_i2c_do_address(struct i2c_adapter *adap, int addr)
35{
36 struct mb862xxfb_par *par = adap->algo_data;
37
38 outreg(i2c, GC_I2C_DAR, addr);
39 outreg(i2c, GC_I2C_CCR, I2C_CLOCK_AND_ENABLE);
40 outreg(i2c, GC_I2C_BCR, par->i2c_rs ? I2C_REPEATED_START : I2C_START);
41 if (!mb862xx_i2c_wait_event(adap))
42 return -EIO;
43 par->i2c_rs = !(inreg(i2c, GC_I2C_BSR) & I2C_LRB);
44 return par->i2c_rs;
45}
46
47static int mb862xx_i2c_write_byte(struct i2c_adapter *adap, u8 byte)
48{
49 struct mb862xxfb_par *par = adap->algo_data;
50
51 outreg(i2c, GC_I2C_DAR, byte);
52 outreg(i2c, GC_I2C_BCR, I2C_START);
53 if (!mb862xx_i2c_wait_event(adap))
54 return -EIO;
55 return !(inreg(i2c, GC_I2C_BSR) & I2C_LRB);
56}
57
58static int mb862xx_i2c_read_byte(struct i2c_adapter *adap, u8 *byte, int last)
59{
60 struct mb862xxfb_par *par = adap->algo_data;
61
62 outreg(i2c, GC_I2C_BCR, I2C_START | (last ? 0 : I2C_ACK));
63 if (!mb862xx_i2c_wait_event(adap))
64 return 0;
65 *byte = inreg(i2c, GC_I2C_DAR);
66 return 1;
67}
68
69void mb862xx_i2c_stop(struct i2c_adapter *adap)
70{
71 struct mb862xxfb_par *par = adap->algo_data;
72
73 outreg(i2c, GC_I2C_BCR, I2C_STOP);
74 outreg(i2c, GC_I2C_CCR, I2C_DISABLE);
75 par->i2c_rs = 0;
76}
77
78static int mb862xx_i2c_read(struct i2c_adapter *adap, struct i2c_msg *m)
79{
80 int i, ret = 0;
81 int last = m->len - 1;
82
83 for (i = 0; i < m->len; i++) {
84 if (!mb862xx_i2c_read_byte(adap, &m->buf[i], i == last)) {
85 ret = -EIO;
86 break;
87 }
88 }
89 return ret;
90}
91
92static int mb862xx_i2c_write(struct i2c_adapter *adap, struct i2c_msg *m)
93{
94 int i, ret = 0;
95
96 for (i = 0; i < m->len; i++) {
97 if (!mb862xx_i2c_write_byte(adap, m->buf[i])) {
98 ret = -EIO;
99 break;
100 }
101 }
102 return ret;
103}
104
105static int mb862xx_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs,
106 int num)
107{
108 struct mb862xxfb_par *par = adap->algo_data;
109 struct i2c_msg *m;
110 int addr;
111 int i = 0, err = 0;
112
113 dev_dbg(par->dev, "%s: %d msgs\n", __func__, num);
114
115 for (i = 0; i < num; i++) {
116 m = &msgs[i];
117 if (!m->len) {
118 dev_dbg(par->dev, "%s: null msgs\n", __func__);
119 continue;
120 }
121 addr = m->addr;
122 if (m->flags & I2C_M_RD)
123 addr |= 1;
124
125 err = mb862xx_i2c_do_address(adap, addr);
126 if (err < 0)
127 break;
128 if (m->flags & I2C_M_RD)
129 err = mb862xx_i2c_read(adap, m);
130 else
131 err = mb862xx_i2c_write(adap, m);
132 }
133
134 if (i)
135 mb862xx_i2c_stop(adap);
136
137 return (err < 0) ? err : i;
138}
139
140static u32 mb862xx_func(struct i2c_adapter *adap)
141{
142 return I2C_FUNC_SMBUS_BYTE_DATA;
143}
144
145static const struct i2c_algorithm mb862xx_algo = {
146 .master_xfer = mb862xx_xfer,
147 .functionality = mb862xx_func,
148};
149
150static struct i2c_adapter mb862xx_i2c_adapter = {
151 .name = "MB862xx I2C adapter",
152 .algo = &mb862xx_algo,
153 .owner = THIS_MODULE,
154};
155
156int mb862xx_i2c_init(struct mb862xxfb_par *par)
157{
158 int ret;
159
160 mb862xx_i2c_adapter.algo_data = par;
161 par->adap = &mb862xx_i2c_adapter;
162
163 ret = i2c_add_adapter(par->adap);
164 if (ret < 0) {
165 dev_err(par->dev, "failed to add %s\n",
166 mb862xx_i2c_adapter.name);
167 }
168 return ret;
169}
170
171void mb862xx_i2c_exit(struct mb862xxfb_par *par)
172{
173 if (par->adap) {
174 i2c_del_adapter(par->adap);
175 par->adap = NULL;
176 }
177}
diff --git a/drivers/video/mb862xx/mb862xx_reg.h b/drivers/video/mb862xx/mb862xx_reg.h
index 2ba65e118500..9df48b8edc94 100644
--- a/drivers/video/mb862xx/mb862xx_reg.h
+++ b/drivers/video/mb862xx/mb862xx_reg.h
@@ -5,11 +5,8 @@
5#ifndef _MB862XX_REG_H 5#ifndef _MB862XX_REG_H
6#define _MB862XX_REG_H 6#define _MB862XX_REG_H
7 7
8#ifdef MB862XX_MMIO_BOTTOM
9#define MB862XX_MMIO_BASE 0x03fc0000
10#else
11#define MB862XX_MMIO_BASE 0x01fc0000 8#define MB862XX_MMIO_BASE 0x01fc0000
12#endif 9#define MB862XX_MMIO_HIGH_BASE 0x03fc0000
13#define MB862XX_I2C_BASE 0x0000c000 10#define MB862XX_I2C_BASE 0x0000c000
14#define MB862XX_DISP_BASE 0x00010000 11#define MB862XX_DISP_BASE 0x00010000
15#define MB862XX_CAP_BASE 0x00018000 12#define MB862XX_CAP_BASE 0x00018000
@@ -23,6 +20,7 @@
23#define GC_IMASK 0x00000024 20#define GC_IMASK 0x00000024
24#define GC_SRST 0x0000002c 21#define GC_SRST 0x0000002c
25#define GC_CCF 0x00000038 22#define GC_CCF 0x00000038
23#define GC_RSW 0x0000005c
26#define GC_CID 0x000000f0 24#define GC_CID 0x000000f0
27#define GC_REVISION 0x00000084 25#define GC_REVISION 0x00000084
28 26
@@ -53,10 +51,16 @@
53#define GC_L0OA0 0x00000024 51#define GC_L0OA0 0x00000024
54#define GC_L0DA0 0x00000028 52#define GC_L0DA0 0x00000028
55#define GC_L0DY_L0DX 0x0000002c 53#define GC_L0DY_L0DX 0x0000002c
54#define GC_L1M 0x00000030
55#define GC_L1DA 0x00000034
56#define GC_DCM1 0x00000100 56#define GC_DCM1 0x00000100
57#define GC_L0EM 0x00000110 57#define GC_L0EM 0x00000110
58#define GC_L0WY_L0WX 0x00000114 58#define GC_L0WY_L0WX 0x00000114
59#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
60#define GC_DCM2 0x00000104 64#define GC_DCM2 0x00000104
61#define GC_DCM3 0x00000108 65#define GC_DCM3 0x00000108
62#define GC_CPM_CUTC 0x000000a0 66#define GC_CPM_CUTC 0x000000a0
@@ -68,6 +72,11 @@
68 72
69#define GC_CPM_CEN0 0x00100000 73#define GC_CPM_CEN0 0x00100000
70#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
71 80
72#define GC_DCM01_ESY 0x00000004 81#define GC_DCM01_ESY 0x00000004
73#define GC_DCM01_SC 0x00003f00 82#define GC_DCM01_SC 0x00003f00
@@ -79,9 +88,50 @@
79#define GC_L0M_L0C_16 0x80000000 88#define GC_L0M_L0C_16 0x80000000
80#define GC_L0EM_L0EC_24 0x40000000 89#define GC_L0EM_L0EC_24 0x40000000
81#define GC_L0M_L0W_UNIT 64 90#define GC_L0M_L0W_UNIT 64
91#define GC_L1EM_DM 0x02000000
82 92
83#define GC_DISP_REFCLK_400 400 93#define GC_DISP_REFCLK_400 400
84 94
95/* I2C */
96#define GC_I2C_BSR 0x00000000 /* BSR */
97#define GC_I2C_BCR 0x00000004 /* BCR */
98#define GC_I2C_CCR 0x00000008 /* CCR */
99#define GC_I2C_ADR 0x0000000C /* ADR */
100#define GC_I2C_DAR 0x00000010 /* DAR */
101
102#define I2C_DISABLE 0x00000000
103#define I2C_STOP 0x00000000
104#define I2C_START 0x00000010
105#define I2C_REPEATED_START 0x00000030
106#define I2C_CLOCK_AND_ENABLE 0x0000003f
107#define I2C_READY 0x01
108#define I2C_INT 0x01
109#define I2C_INTE 0x02
110#define I2C_ACK 0x08
111#define I2C_BER 0x80
112#define I2C_BEIE 0x40
113#define I2C_TRX 0x80
114#define I2C_LRB 0x10
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
85/* Carmine specific */ 135/* Carmine specific */
86#define MB86297_DRAW_BASE 0x00020000 136#define MB86297_DRAW_BASE 0x00020000
87#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 d7e7cb76bbf2..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;
@@ -57,11 +79,23 @@ struct mb862xxfb_par {
57 unsigned int refclk; /* disp. reference clock */ 79 unsigned int refclk; /* disp. reference clock */
58 struct mb862xx_gc_mode *gc_mode; /* GDC mode init data */ 80 struct mb862xx_gc_mode *gc_mode; /* GDC mode init data */
59 int pre_init; /* don't init display if 1 */ 81 int pre_init; /* don't init display if 1 */
82 struct i2c_adapter *adap; /* GDC I2C bus adapter */
83 int i2c_rs;
84
85 struct mb862xx_l1_cfg l1_cfg;
86 int l1_stride;
60 87
61 u32 pseudo_palette[16]; 88 u32 pseudo_palette[16];
62}; 89};
63 90
64extern void mb862xxfb_init_accel(struct fb_info *info, int xres); 91extern void mb862xxfb_init_accel(struct fb_info *info, int xres);
92#ifdef CONFIG_FB_MB862XX_I2C
93extern int mb862xx_i2c_init(struct mb862xxfb_par *par);
94extern void mb862xx_i2c_exit(struct mb862xxfb_par *par);
95#else
96static inline int mb862xx_i2c_init(struct mb862xxfb_par *par) { return 0; }
97static inline void mb862xx_i2c_exit(struct mb862xxfb_par *par) { }
98#endif
65 99
66#if defined(CONFIG_FB_MB862XX_LIME) && defined(CONFIG_FB_MB862XX_PCI_GDC) 100#if defined(CONFIG_FB_MB862XX_LIME) && defined(CONFIG_FB_MB862XX_PCI_GDC)
67#error "Select Lime GDC or CoralP/Carmine support, but not both together" 101#error "Select Lime GDC or CoralP/Carmine support, but not both together"
@@ -82,4 +116,6 @@ extern void mb862xxfb_init_accel(struct fb_info *info, int xres);
82 116
83#define pack(a, b) (((a) << 16) | (b)) 117#define pack(a, b) (((a) << 16) | (b))
84 118
119#endif /* __KERNEL__ */
120
85#endif 121#endif
diff --git a/drivers/video/mb862xx/mb862xxfb.c b/drivers/video/mb862xx/mb862xxfbdrv.c
index c76e663a6cd4..ea39336addfb 100644
--- a/drivers/video/mb862xx/mb862xxfb.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;
@@ -336,7 +429,6 @@ static int mb862xxfb_init_fbinfo(struct fb_info *fbi)
336 429
337 strcpy(fbi->fix.id, DRV_NAME); 430 strcpy(fbi->fix.id, DRV_NAME);
338 fbi->fix.smem_start = (unsigned long)par->fb_base_phys; 431 fbi->fix.smem_start = (unsigned long)par->fb_base_phys;
339 fbi->fix.smem_len = par->mapped_vram;
340 fbi->fix.mmio_start = (unsigned long)par->mmio_base_phys; 432 fbi->fix.mmio_start = (unsigned long)par->mmio_base_phys;
341 fbi->fix.mmio_len = par->mmio_len; 433 fbi->fix.mmio_len = par->mmio_len;
342 fbi->fix.accel = FB_ACCEL_NONE; 434 fbi->fix.accel = FB_ACCEL_NONE;
@@ -420,6 +512,28 @@ static int mb862xxfb_init_fbinfo(struct fb_info *fbi)
420 FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_TRUECOLOR; 512 FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_TRUECOLOR;
421 fbi->fix.line_length = (fbi->var.xres_virtual * 513 fbi->fix.line_length = (fbi->var.xres_virtual *
422 fbi->var.bits_per_pixel) / 8; 514 fbi->var.bits_per_pixel) / 8;
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
@@ -742,22 +856,38 @@ static int coralp_init(struct mb862xxfb_par *par)
742 856
743 par->refclk = GC_DISP_REFCLK_400; 857 par->refclk = GC_DISP_REFCLK_400;
744 858
859 if (par->mapped_vram >= 0x2000000) {
860 /* relocate gdc registers space */
861 writel(1, par->fb_base + MB862XX_MMIO_BASE + GC_RSW);
862 udelay(1); /* wait at least 20 bus cycles */
863 }
864
745 ver = inreg(host, GC_CID); 865 ver = inreg(host, GC_CID);
746 cn = (ver & GC_CID_CNAME_MSK) >> 8; 866 cn = (ver & GC_CID_CNAME_MSK) >> 8;
747 ver = ver & GC_CID_VERSION_MSK; 867 ver = ver & GC_CID_VERSION_MSK;
748 if (cn == 3) { 868 if (cn == 3) {
869 unsigned long reg;
870
749 dev_info(par->dev, "Fujitsu Coral-%s GDC Rev.%d found\n",\ 871 dev_info(par->dev, "Fujitsu Coral-%s GDC Rev.%d found\n",\
750 (ver == 6) ? "P" : (ver == 8) ? "PA" : "?", 872 (ver == 6) ? "P" : (ver == 8) ? "PA" : "?",
751 par->pdev->revision); 873 par->pdev->revision);
752 outreg(host, GC_CCF, GC_CCF_CGE_166 | GC_CCF_COT_133); 874 reg = inreg(disp, GC_DCM1);
753 udelay(200); 875 if (reg & GC_DCM01_DEN && reg & GC_DCM01_L0E)
754 outreg(host, GC_MMR, GC_MMR_CORALP_EVB_VAL); 876 par->pre_init = 1;
755 udelay(10); 877
878 if (!par->pre_init) {
879 outreg(host, GC_CCF, GC_CCF_CGE_166 | GC_CCF_COT_133);
880 udelay(200);
881 outreg(host, GC_MMR, GC_MMR_CORALP_EVB_VAL);
882 udelay(10);
883 }
756 /* Clear interrupt status */ 884 /* Clear interrupt status */
757 outreg(host, GC_IST, 0); 885 outreg(host, GC_IST, 0);
758 } else { 886 } else {
759 return -ENODEV; 887 return -ENODEV;
760 } 888 }
889
890 mb862xx_i2c_init(par);
761 return 0; 891 return 0;
762} 892}
763 893
@@ -899,7 +1029,13 @@ static int __devinit mb862xx_pci_probe(struct pci_dev *pdev,
899 case PCI_DEVICE_ID_FUJITSU_CORALPA: 1029 case PCI_DEVICE_ID_FUJITSU_CORALPA:
900 par->fb_base_phys = pci_resource_start(par->pdev, 0); 1030 par->fb_base_phys = pci_resource_start(par->pdev, 0);
901 par->mapped_vram = CORALP_MEM_SIZE; 1031 par->mapped_vram = CORALP_MEM_SIZE;
902 par->mmio_base_phys = par->fb_base_phys + MB862XX_MMIO_BASE; 1032 if (par->mapped_vram >= 0x2000000) {
1033 par->mmio_base_phys = par->fb_base_phys +
1034 MB862XX_MMIO_HIGH_BASE;
1035 } else {
1036 par->mmio_base_phys = par->fb_base_phys +
1037 MB862XX_MMIO_BASE;
1038 }
903 par->mmio_len = MB862XX_MMIO_SIZE; 1039 par->mmio_len = MB862XX_MMIO_SIZE;
904 par->type = BT_CORALP; 1040 par->type = BT_CORALP;
905 break; 1041 break;
@@ -1009,6 +1145,8 @@ static void __devexit mb862xx_pci_remove(struct pci_dev *pdev)
1009 outreg(host, GC_IMASK, 0); 1145 outreg(host, GC_IMASK, 0);
1010 } 1146 }
1011 1147
1148 mb862xx_i2c_exit(par);
1149
1012 device_remove_file(&pdev->dev, &dev_attr_dispregs); 1150 device_remove_file(&pdev->dev, &dev_attr_dispregs);
1013 1151
1014 pci_set_drvdata(pdev, NULL); 1152 pci_set_drvdata(pdev, NULL);