diff options
author | Tomi Valkeinen <tomi.valkeinen@ti.com> | 2014-02-13 08:31:38 -0500 |
---|---|---|
committer | Tomi Valkeinen <tomi.valkeinen@ti.com> | 2014-04-17 01:10:19 -0400 |
commit | f7018c21350204c4cf628462f229d44d03545254 (patch) | |
tree | 408787177164cf51cc06f7aabdb04fcff8d2b6aa /drivers/video/mb862xx | |
parent | c26ef3eb3c11274bad1b64498d0a134f85755250 (diff) |
video: move fbdev to drivers/video/fbdev
The drivers/video directory is a mess. It contains generic video related
files, directories for backlight, console, linux logo, lots of fbdev
device drivers, fbdev framework files.
Make some order into the chaos by creating drivers/video/fbdev
directory, and move all fbdev related files there.
No functionality is changed, although I guess it is possible that some
subtle Makefile build order related issue could be created by this
patch.
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
Acked-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Acked-by: Geert Uytterhoeven <geert@linux-m68k.org>
Acked-by: Rob Clark <robdclark@gmail.com>
Acked-by: Jingoo Han <jg1.han@samsung.com>
Acked-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Diffstat (limited to 'drivers/video/mb862xx')
-rw-r--r-- | drivers/video/mb862xx/Makefile | 8 | ||||
-rw-r--r-- | drivers/video/mb862xx/mb862xx-i2c.c | 179 | ||||
-rw-r--r-- | drivers/video/mb862xx/mb862xx_reg.h | 188 | ||||
-rw-r--r-- | drivers/video/mb862xx/mb862xxfb.h | 121 | ||||
-rw-r--r-- | drivers/video/mb862xx/mb862xxfb_accel.c | 335 | ||||
-rw-r--r-- | drivers/video/mb862xx/mb862xxfb_accel.h | 203 | ||||
-rw-r--r-- | drivers/video/mb862xx/mb862xxfbdrv.c | 1206 |
7 files changed, 0 insertions, 2240 deletions
diff --git a/drivers/video/mb862xx/Makefile b/drivers/video/mb862xx/Makefile deleted file mode 100644 index 5707ed0e31a7..000000000000 --- a/drivers/video/mb862xx/Makefile +++ /dev/null | |||
@@ -1,8 +0,0 @@ | |||
1 | # | ||
2 | # Makefile for the MB862xx framebuffer driver | ||
3 | # | ||
4 | |||
5 | obj-$(CONFIG_FB_MB862XX) += mb862xxfb.o | ||
6 | |||
7 | mb862xxfb-y := mb862xxfbdrv.o mb862xxfb_accel.o | ||
8 | mb862xxfb-$(CONFIG_FB_MB862XX_I2C) += mb862xx-i2c.o | ||
diff --git a/drivers/video/mb862xx/mb862xx-i2c.c b/drivers/video/mb862xx/mb862xx-i2c.c deleted file mode 100644 index c87e17afb3e2..000000000000 --- a/drivers/video/mb862xx/mb862xx-i2c.c +++ /dev/null | |||
@@ -1,179 +0,0 @@ | |||
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 | #include <linux/delay.h> | ||
16 | #include <linux/export.h> | ||
17 | |||
18 | #include "mb862xxfb.h" | ||
19 | #include "mb862xx_reg.h" | ||
20 | |||
21 | static int mb862xx_i2c_wait_event(struct i2c_adapter *adap) | ||
22 | { | ||
23 | struct mb862xxfb_par *par = adap->algo_data; | ||
24 | u32 reg; | ||
25 | |||
26 | do { | ||
27 | udelay(10); | ||
28 | reg = inreg(i2c, GC_I2C_BCR); | ||
29 | if (reg & (I2C_INT | I2C_BER)) | ||
30 | break; | ||
31 | } while (1); | ||
32 | |||
33 | return (reg & I2C_BER) ? 0 : 1; | ||
34 | } | ||
35 | |||
36 | static int mb862xx_i2c_do_address(struct i2c_adapter *adap, int addr) | ||
37 | { | ||
38 | struct mb862xxfb_par *par = adap->algo_data; | ||
39 | |||
40 | outreg(i2c, GC_I2C_DAR, addr); | ||
41 | outreg(i2c, GC_I2C_CCR, I2C_CLOCK_AND_ENABLE); | ||
42 | outreg(i2c, GC_I2C_BCR, par->i2c_rs ? I2C_REPEATED_START : I2C_START); | ||
43 | if (!mb862xx_i2c_wait_event(adap)) | ||
44 | return -EIO; | ||
45 | par->i2c_rs = !(inreg(i2c, GC_I2C_BSR) & I2C_LRB); | ||
46 | return par->i2c_rs; | ||
47 | } | ||
48 | |||
49 | static int mb862xx_i2c_write_byte(struct i2c_adapter *adap, u8 byte) | ||
50 | { | ||
51 | struct mb862xxfb_par *par = adap->algo_data; | ||
52 | |||
53 | outreg(i2c, GC_I2C_DAR, byte); | ||
54 | outreg(i2c, GC_I2C_BCR, I2C_START); | ||
55 | if (!mb862xx_i2c_wait_event(adap)) | ||
56 | return -EIO; | ||
57 | return !(inreg(i2c, GC_I2C_BSR) & I2C_LRB); | ||
58 | } | ||
59 | |||
60 | static int mb862xx_i2c_read_byte(struct i2c_adapter *adap, u8 *byte, int last) | ||
61 | { | ||
62 | struct mb862xxfb_par *par = adap->algo_data; | ||
63 | |||
64 | outreg(i2c, GC_I2C_BCR, I2C_START | (last ? 0 : I2C_ACK)); | ||
65 | if (!mb862xx_i2c_wait_event(adap)) | ||
66 | return 0; | ||
67 | *byte = inreg(i2c, GC_I2C_DAR); | ||
68 | return 1; | ||
69 | } | ||
70 | |||
71 | static void mb862xx_i2c_stop(struct i2c_adapter *adap) | ||
72 | { | ||
73 | struct mb862xxfb_par *par = adap->algo_data; | ||
74 | |||
75 | outreg(i2c, GC_I2C_BCR, I2C_STOP); | ||
76 | outreg(i2c, GC_I2C_CCR, I2C_DISABLE); | ||
77 | par->i2c_rs = 0; | ||
78 | } | ||
79 | |||
80 | static int mb862xx_i2c_read(struct i2c_adapter *adap, struct i2c_msg *m) | ||
81 | { | ||
82 | int i, ret = 0; | ||
83 | int last = m->len - 1; | ||
84 | |||
85 | for (i = 0; i < m->len; i++) { | ||
86 | if (!mb862xx_i2c_read_byte(adap, &m->buf[i], i == last)) { | ||
87 | ret = -EIO; | ||
88 | break; | ||
89 | } | ||
90 | } | ||
91 | return ret; | ||
92 | } | ||
93 | |||
94 | static int mb862xx_i2c_write(struct i2c_adapter *adap, struct i2c_msg *m) | ||
95 | { | ||
96 | int i, ret = 0; | ||
97 | |||
98 | for (i = 0; i < m->len; i++) { | ||
99 | if (!mb862xx_i2c_write_byte(adap, m->buf[i])) { | ||
100 | ret = -EIO; | ||
101 | break; | ||
102 | } | ||
103 | } | ||
104 | return ret; | ||
105 | } | ||
106 | |||
107 | static int mb862xx_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, | ||
108 | int num) | ||
109 | { | ||
110 | struct mb862xxfb_par *par = adap->algo_data; | ||
111 | struct i2c_msg *m; | ||
112 | int addr; | ||
113 | int i = 0, err = 0; | ||
114 | |||
115 | dev_dbg(par->dev, "%s: %d msgs\n", __func__, num); | ||
116 | |||
117 | for (i = 0; i < num; i++) { | ||
118 | m = &msgs[i]; | ||
119 | if (!m->len) { | ||
120 | dev_dbg(par->dev, "%s: null msgs\n", __func__); | ||
121 | continue; | ||
122 | } | ||
123 | addr = m->addr; | ||
124 | if (m->flags & I2C_M_RD) | ||
125 | addr |= 1; | ||
126 | |||
127 | err = mb862xx_i2c_do_address(adap, addr); | ||
128 | if (err < 0) | ||
129 | break; | ||
130 | if (m->flags & I2C_M_RD) | ||
131 | err = mb862xx_i2c_read(adap, m); | ||
132 | else | ||
133 | err = mb862xx_i2c_write(adap, m); | ||
134 | } | ||
135 | |||
136 | if (i) | ||
137 | mb862xx_i2c_stop(adap); | ||
138 | |||
139 | return (err < 0) ? err : i; | ||
140 | } | ||
141 | |||
142 | static u32 mb862xx_func(struct i2c_adapter *adap) | ||
143 | { | ||
144 | return I2C_FUNC_SMBUS_BYTE_DATA; | ||
145 | } | ||
146 | |||
147 | static const struct i2c_algorithm mb862xx_algo = { | ||
148 | .master_xfer = mb862xx_xfer, | ||
149 | .functionality = mb862xx_func, | ||
150 | }; | ||
151 | |||
152 | static struct i2c_adapter mb862xx_i2c_adapter = { | ||
153 | .name = "MB862xx I2C adapter", | ||
154 | .algo = &mb862xx_algo, | ||
155 | .owner = THIS_MODULE, | ||
156 | }; | ||
157 | |||
158 | int mb862xx_i2c_init(struct mb862xxfb_par *par) | ||
159 | { | ||
160 | int ret; | ||
161 | |||
162 | mb862xx_i2c_adapter.algo_data = par; | ||
163 | par->adap = &mb862xx_i2c_adapter; | ||
164 | |||
165 | ret = i2c_add_adapter(par->adap); | ||
166 | if (ret < 0) { | ||
167 | dev_err(par->dev, "failed to add %s\n", | ||
168 | mb862xx_i2c_adapter.name); | ||
169 | } | ||
170 | return ret; | ||
171 | } | ||
172 | |||
173 | void mb862xx_i2c_exit(struct mb862xxfb_par *par) | ||
174 | { | ||
175 | if (par->adap) { | ||
176 | i2c_del_adapter(par->adap); | ||
177 | par->adap = NULL; | ||
178 | } | ||
179 | } | ||
diff --git a/drivers/video/mb862xx/mb862xx_reg.h b/drivers/video/mb862xx/mb862xx_reg.h deleted file mode 100644 index 9df48b8edc94..000000000000 --- a/drivers/video/mb862xx/mb862xx_reg.h +++ /dev/null | |||
@@ -1,188 +0,0 @@ | |||
1 | /* | ||
2 | * Fujitsu MB862xx Graphics Controller Registers/Bits | ||
3 | */ | ||
4 | |||
5 | #ifndef _MB862XX_REG_H | ||
6 | #define _MB862XX_REG_H | ||
7 | |||
8 | #define MB862XX_MMIO_BASE 0x01fc0000 | ||
9 | #define MB862XX_MMIO_HIGH_BASE 0x03fc0000 | ||
10 | #define MB862XX_I2C_BASE 0x0000c000 | ||
11 | #define MB862XX_DISP_BASE 0x00010000 | ||
12 | #define MB862XX_CAP_BASE 0x00018000 | ||
13 | #define MB862XX_DRAW_BASE 0x00030000 | ||
14 | #define MB862XX_GEO_BASE 0x00038000 | ||
15 | #define MB862XX_PIO_BASE 0x00038000 | ||
16 | #define MB862XX_MMIO_SIZE 0x40000 | ||
17 | |||
18 | /* Host interface/pio registers */ | ||
19 | #define GC_IST 0x00000020 | ||
20 | #define GC_IMASK 0x00000024 | ||
21 | #define GC_SRST 0x0000002c | ||
22 | #define GC_CCF 0x00000038 | ||
23 | #define GC_RSW 0x0000005c | ||
24 | #define GC_CID 0x000000f0 | ||
25 | #define GC_REVISION 0x00000084 | ||
26 | |||
27 | #define GC_CCF_CGE_100 0x00000000 | ||
28 | #define GC_CCF_CGE_133 0x00040000 | ||
29 | #define GC_CCF_CGE_166 0x00080000 | ||
30 | #define GC_CCF_COT_100 0x00000000 | ||
31 | #define GC_CCF_COT_133 0x00010000 | ||
32 | #define GC_CID_CNAME_MSK 0x0000ff00 | ||
33 | #define GC_CID_VERSION_MSK 0x000000ff | ||
34 | |||
35 | /* define enabled interrupts hereby */ | ||
36 | #define GC_INT_EN 0x00000000 | ||
37 | |||
38 | /* Memory interface mode register */ | ||
39 | #define GC_MMR 0x0000fffc | ||
40 | |||
41 | /* Display Controller registers */ | ||
42 | #define GC_DCM0 0x00000000 | ||
43 | #define GC_HTP 0x00000004 | ||
44 | #define GC_HDB_HDP 0x00000008 | ||
45 | #define GC_VSW_HSW_HSP 0x0000000c | ||
46 | #define GC_VTR 0x00000010 | ||
47 | #define GC_VDP_VSP 0x00000014 | ||
48 | #define GC_WY_WX 0x00000018 | ||
49 | #define GC_WH_WW 0x0000001c | ||
50 | #define GC_L0M 0x00000020 | ||
51 | #define GC_L0OA0 0x00000024 | ||
52 | #define GC_L0DA0 0x00000028 | ||
53 | #define GC_L0DY_L0DX 0x0000002c | ||
54 | #define GC_L1M 0x00000030 | ||
55 | #define GC_L1DA 0x00000034 | ||
56 | #define GC_DCM1 0x00000100 | ||
57 | #define GC_L0EM 0x00000110 | ||
58 | #define GC_L0WY_L0WX 0x00000114 | ||
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 | ||
64 | #define GC_DCM2 0x00000104 | ||
65 | #define GC_DCM3 0x00000108 | ||
66 | #define GC_CPM_CUTC 0x000000a0 | ||
67 | #define GC_CUOA0 0x000000a4 | ||
68 | #define GC_CUY0_CUX0 0x000000a8 | ||
69 | #define GC_CUOA1 0x000000ac | ||
70 | #define GC_CUY1_CUX1 0x000000b0 | ||
71 | #define GC_L0PAL0 0x00000400 | ||
72 | |||
73 | #define GC_CPM_CEN0 0x00100000 | ||
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 | ||
80 | |||
81 | #define GC_DCM01_ESY 0x00000004 | ||
82 | #define GC_DCM01_SC 0x00003f00 | ||
83 | #define GC_DCM01_RESV 0x00004000 | ||
84 | #define GC_DCM01_CKS 0x00008000 | ||
85 | #define GC_DCM01_L0E 0x00010000 | ||
86 | #define GC_DCM01_DEN 0x80000000 | ||
87 | #define GC_L0M_L0C_8 0x00000000 | ||
88 | #define GC_L0M_L0C_16 0x80000000 | ||
89 | #define GC_L0EM_L0EC_24 0x40000000 | ||
90 | #define GC_L0M_L0W_UNIT 64 | ||
91 | #define GC_L1EM_DM 0x02000000 | ||
92 | |||
93 | #define GC_DISP_REFCLK_400 400 | ||
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 | |||
135 | /* Carmine specific */ | ||
136 | #define MB86297_DRAW_BASE 0x00020000 | ||
137 | #define MB86297_DISP0_BASE 0x00100000 | ||
138 | #define MB86297_DISP1_BASE 0x00140000 | ||
139 | #define MB86297_WRBACK_BASE 0x00180000 | ||
140 | #define MB86297_CAP0_BASE 0x00200000 | ||
141 | #define MB86297_CAP1_BASE 0x00280000 | ||
142 | #define MB86297_DRAMCTRL_BASE 0x00300000 | ||
143 | #define MB86297_CTRL_BASE 0x00400000 | ||
144 | #define MB86297_I2C_BASE 0x00500000 | ||
145 | |||
146 | #define GC_CTRL_STATUS 0x00000000 | ||
147 | #define GC_CTRL_INT_MASK 0x00000004 | ||
148 | #define GC_CTRL_CLK_ENABLE 0x0000000c | ||
149 | #define GC_CTRL_SOFT_RST 0x00000010 | ||
150 | |||
151 | #define GC_CTRL_CLK_EN_DRAM 0x00000001 | ||
152 | #define GC_CTRL_CLK_EN_2D3D 0x00000002 | ||
153 | #define GC_CTRL_CLK_EN_DISP0 0x00000020 | ||
154 | #define GC_CTRL_CLK_EN_DISP1 0x00000040 | ||
155 | |||
156 | #define GC_2D3D_REV 0x000004b4 | ||
157 | #define GC_RE_REVISION 0x24240200 | ||
158 | |||
159 | /* define enabled interrupts hereby */ | ||
160 | #define GC_CARMINE_INT_EN 0x00000004 | ||
161 | |||
162 | /* DRAM controller */ | ||
163 | #define GC_DCTL_MODE_ADD 0x00000000 | ||
164 | #define GC_DCTL_SETTIME1_EMODE 0x00000004 | ||
165 | #define GC_DCTL_REFRESH_SETTIME2 0x00000008 | ||
166 | #define GC_DCTL_RSV0_STATES 0x0000000C | ||
167 | #define GC_DCTL_RSV2_RSV1 0x00000010 | ||
168 | #define GC_DCTL_DDRIF2_DDRIF1 0x00000014 | ||
169 | #define GC_DCTL_IOCONT1_IOCONT0 0x00000024 | ||
170 | |||
171 | #define GC_DCTL_STATES_MSK 0x0000000f | ||
172 | #define GC_DCTL_INIT_WAIT_CNT 3000 | ||
173 | #define GC_DCTL_INIT_WAIT_INTERVAL 1 | ||
174 | |||
175 | /* DRAM ctrl values for Carmine PCI Eval. board */ | ||
176 | #define GC_EVB_DCTL_MODE_ADD 0x012105c3 | ||
177 | #define GC_EVB_DCTL_MODE_ADD_AFT_RST 0x002105c3 | ||
178 | #define GC_EVB_DCTL_SETTIME1_EMODE 0x47498000 | ||
179 | #define GC_EVB_DCTL_REFRESH_SETTIME2 0x00422a22 | ||
180 | #define GC_EVB_DCTL_RSV0_STATES 0x00200003 | ||
181 | #define GC_EVB_DCTL_RSV0_STATES_AFT_RST 0x00200002 | ||
182 | #define GC_EVB_DCTL_RSV2_RSV1 0x0000000f | ||
183 | #define GC_EVB_DCTL_DDRIF2_DDRIF1 0x00556646 | ||
184 | #define GC_EVB_DCTL_IOCONT1_IOCONT0 0x05550555 | ||
185 | |||
186 | #define GC_DISP_REFCLK_533 533 | ||
187 | |||
188 | #endif | ||
diff --git a/drivers/video/mb862xx/mb862xxfb.h b/drivers/video/mb862xx/mb862xxfb.h deleted file mode 100644 index 8550630c1e01..000000000000 --- a/drivers/video/mb862xx/mb862xxfb.h +++ /dev/null | |||
@@ -1,121 +0,0 @@ | |||
1 | #ifndef __MB862XX_H__ | ||
2 | #define __MB862XX_H__ | ||
3 | |||
4 | struct 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 | |||
24 | #define PCI_VENDOR_ID_FUJITSU_LIMITED 0x10cf | ||
25 | #define PCI_DEVICE_ID_FUJITSU_CORALP 0x2019 | ||
26 | #define PCI_DEVICE_ID_FUJITSU_CORALPA 0x201e | ||
27 | #define PCI_DEVICE_ID_FUJITSU_CARMINE 0x202b | ||
28 | |||
29 | #define GC_MMR_CORALP_EVB_VAL 0x11d7fa13 | ||
30 | |||
31 | enum gdctype { | ||
32 | BT_NONE, | ||
33 | BT_LIME, | ||
34 | BT_MINT, | ||
35 | BT_CORAL, | ||
36 | BT_CORALP, | ||
37 | BT_CARMINE, | ||
38 | }; | ||
39 | |||
40 | struct mb862xx_gc_mode { | ||
41 | struct fb_videomode def_mode; /* mode of connected display */ | ||
42 | unsigned int def_bpp; /* default depth */ | ||
43 | unsigned long max_vram; /* connected SDRAM size */ | ||
44 | unsigned long ccf; /* gdc clk */ | ||
45 | unsigned long mmr; /* memory mode for SDRAM */ | ||
46 | }; | ||
47 | |||
48 | /* private data */ | ||
49 | struct mb862xxfb_par { | ||
50 | struct fb_info *info; /* fb info head */ | ||
51 | struct device *dev; | ||
52 | struct pci_dev *pdev; | ||
53 | struct resource *res; /* framebuffer/mmio resource */ | ||
54 | |||
55 | resource_size_t fb_base_phys; /* fb base, 36-bit PPC440EPx */ | ||
56 | resource_size_t mmio_base_phys; /* io base addr */ | ||
57 | void __iomem *fb_base; /* remapped framebuffer */ | ||
58 | void __iomem *mmio_base; /* remapped registers */ | ||
59 | size_t mapped_vram; /* length of remapped vram */ | ||
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 */ | ||
63 | |||
64 | void __iomem *host; /* relocatable reg. bases */ | ||
65 | void __iomem *i2c; | ||
66 | void __iomem *disp; | ||
67 | void __iomem *disp1; | ||
68 | void __iomem *cap; | ||
69 | void __iomem *cap1; | ||
70 | void __iomem *draw; | ||
71 | void __iomem *geo; | ||
72 | void __iomem *pio; | ||
73 | void __iomem *ctrl; | ||
74 | void __iomem *dram_ctrl; | ||
75 | void __iomem *wrback; | ||
76 | |||
77 | unsigned int irq; | ||
78 | unsigned int type; /* GDC type */ | ||
79 | unsigned int refclk; /* disp. reference clock */ | ||
80 | struct mb862xx_gc_mode *gc_mode; /* GDC mode init data */ | ||
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; | ||
87 | |||
88 | u32 pseudo_palette[16]; | ||
89 | }; | ||
90 | |||
91 | extern void mb862xxfb_init_accel(struct fb_info *info, int xres); | ||
92 | #ifdef CONFIG_FB_MB862XX_I2C | ||
93 | extern int mb862xx_i2c_init(struct mb862xxfb_par *par); | ||
94 | extern void mb862xx_i2c_exit(struct mb862xxfb_par *par); | ||
95 | #else | ||
96 | static inline int mb862xx_i2c_init(struct mb862xxfb_par *par) { return 0; } | ||
97 | static inline void mb862xx_i2c_exit(struct mb862xxfb_par *par) { } | ||
98 | #endif | ||
99 | |||
100 | #if defined(CONFIG_FB_MB862XX_LIME) && defined(CONFIG_FB_MB862XX_PCI_GDC) | ||
101 | #error "Select Lime GDC or CoralP/Carmine support, but not both together" | ||
102 | #endif | ||
103 | #if defined(CONFIG_FB_MB862XX_LIME) | ||
104 | #define gdc_read __raw_readl | ||
105 | #define gdc_write __raw_writel | ||
106 | #else | ||
107 | #define gdc_read readl | ||
108 | #define gdc_write writel | ||
109 | #endif | ||
110 | |||
111 | #define inreg(type, off) \ | ||
112 | gdc_read((par->type + (off))) | ||
113 | |||
114 | #define outreg(type, off, val) \ | ||
115 | gdc_write((val), (par->type + (off))) | ||
116 | |||
117 | #define pack(a, b) (((a) << 16) | (b)) | ||
118 | |||
119 | #endif /* __KERNEL__ */ | ||
120 | |||
121 | #endif | ||
diff --git a/drivers/video/mb862xx/mb862xxfb_accel.c b/drivers/video/mb862xx/mb862xxfb_accel.c deleted file mode 100644 index fe92eed6da70..000000000000 --- a/drivers/video/mb862xx/mb862xxfb_accel.c +++ /dev/null | |||
@@ -1,335 +0,0 @@ | |||
1 | /* | ||
2 | * drivers/mb862xx/mb862xxfb_accel.c | ||
3 | * | ||
4 | * Fujitsu Carmine/Coral-P(A)/Lime framebuffer driver acceleration support | ||
5 | * | ||
6 | * (C) 2007 Alexander Shishkin <virtuoso@slind.org> | ||
7 | * (C) 2009 Valentin Sitdikov <v.sitdikov@gmail.com> | ||
8 | * (C) 2009 Siemens AG | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify | ||
11 | * it under the terms of the GNU General Public License version 2 as | ||
12 | * published by the Free Software Foundation. | ||
13 | * | ||
14 | */ | ||
15 | #include <linux/fb.h> | ||
16 | #include <linux/delay.h> | ||
17 | #include <linux/init.h> | ||
18 | #include <linux/interrupt.h> | ||
19 | #include <linux/module.h> | ||
20 | #include <linux/pci.h> | ||
21 | #include <linux/slab.h> | ||
22 | #if defined(CONFIG_OF) | ||
23 | #include <linux/of_platform.h> | ||
24 | #endif | ||
25 | #include "mb862xxfb.h" | ||
26 | #include "mb862xx_reg.h" | ||
27 | #include "mb862xxfb_accel.h" | ||
28 | |||
29 | static void mb862xxfb_write_fifo(u32 count, u32 *data, struct fb_info *info) | ||
30 | { | ||
31 | struct mb862xxfb_par *par = info->par; | ||
32 | static u32 free; | ||
33 | |||
34 | u32 total = 0; | ||
35 | while (total < count) { | ||
36 | if (free) { | ||
37 | outreg(geo, GDC_GEO_REG_INPUT_FIFO, data[total]); | ||
38 | total++; | ||
39 | free--; | ||
40 | } else { | ||
41 | free = (u32) inreg(draw, GDC_REG_FIFO_COUNT); | ||
42 | } | ||
43 | } | ||
44 | } | ||
45 | |||
46 | static void mb86290fb_copyarea(struct fb_info *info, | ||
47 | const struct fb_copyarea *area) | ||
48 | { | ||
49 | __u32 cmd[6]; | ||
50 | |||
51 | cmd[0] = (GDC_TYPE_SETREGISTER << 24) | (1 << 16) | GDC_REG_MODE_BITMAP; | ||
52 | /* Set raster operation */ | ||
53 | cmd[1] = (2 << 7) | (GDC_ROP_COPY << 9); | ||
54 | cmd[2] = GDC_TYPE_BLTCOPYP << 24; | ||
55 | |||
56 | if (area->sx >= area->dx && area->sy >= area->dy) | ||
57 | cmd[2] |= GDC_CMD_BLTCOPY_TOP_LEFT << 16; | ||
58 | else if (area->sx >= area->dx && area->sy <= area->dy) | ||
59 | cmd[2] |= GDC_CMD_BLTCOPY_BOTTOM_LEFT << 16; | ||
60 | else if (area->sx <= area->dx && area->sy >= area->dy) | ||
61 | cmd[2] |= GDC_CMD_BLTCOPY_TOP_RIGHT << 16; | ||
62 | else | ||
63 | cmd[2] |= GDC_CMD_BLTCOPY_BOTTOM_RIGHT << 16; | ||
64 | |||
65 | cmd[3] = (area->sy << 16) | area->sx; | ||
66 | cmd[4] = (area->dy << 16) | area->dx; | ||
67 | cmd[5] = (area->height << 16) | area->width; | ||
68 | mb862xxfb_write_fifo(6, cmd, info); | ||
69 | } | ||
70 | |||
71 | /* | ||
72 | * Fill in the cmd array /GDC FIFO commands/ to draw a 1bit image. | ||
73 | * Make sure cmd has enough room! | ||
74 | */ | ||
75 | static void mb86290fb_imageblit1(u32 *cmd, u16 step, u16 dx, u16 dy, | ||
76 | u16 width, u16 height, u32 fgcolor, | ||
77 | u32 bgcolor, const struct fb_image *image, | ||
78 | struct fb_info *info) | ||
79 | { | ||
80 | int i; | ||
81 | unsigned const char *line; | ||
82 | u16 bytes; | ||
83 | |||
84 | /* set colors and raster operation regs */ | ||
85 | cmd[0] = (GDC_TYPE_SETREGISTER << 24) | (1 << 16) | GDC_REG_MODE_BITMAP; | ||
86 | /* Set raster operation */ | ||
87 | cmd[1] = (2 << 7) | (GDC_ROP_COPY << 9); | ||
88 | cmd[2] = | ||
89 | (GDC_TYPE_SETCOLORREGISTER << 24) | (GDC_CMD_BODY_FORE_COLOR << 16); | ||
90 | cmd[3] = fgcolor; | ||
91 | cmd[4] = | ||
92 | (GDC_TYPE_SETCOLORREGISTER << 24) | (GDC_CMD_BODY_BACK_COLOR << 16); | ||
93 | cmd[5] = bgcolor; | ||
94 | |||
95 | i = 0; | ||
96 | line = image->data; | ||
97 | bytes = (image->width + 7) >> 3; | ||
98 | |||
99 | /* and the image */ | ||
100 | cmd[6] = (GDC_TYPE_DRAWBITMAPP << 24) | | ||
101 | (GDC_CMD_BITMAP << 16) | (2 + (step * height)); | ||
102 | cmd[7] = (dy << 16) | dx; | ||
103 | cmd[8] = (height << 16) | width; | ||
104 | |||
105 | while (i < height) { | ||
106 | memcpy(&cmd[9 + i * step], line, step << 2); | ||
107 | #ifdef __LITTLE_ENDIAN | ||
108 | { | ||
109 | int k = 0; | ||
110 | for (k = 0; k < step; k++) | ||
111 | cmd[9 + i * step + k] = | ||
112 | cpu_to_be32(cmd[9 + i * step + k]); | ||
113 | } | ||
114 | #endif | ||
115 | line += bytes; | ||
116 | i++; | ||
117 | } | ||
118 | } | ||
119 | |||
120 | /* | ||
121 | * Fill in the cmd array /GDC FIFO commands/ to draw a 8bit image. | ||
122 | * Make sure cmd has enough room! | ||
123 | */ | ||
124 | static void mb86290fb_imageblit8(u32 *cmd, u16 step, u16 dx, u16 dy, | ||
125 | u16 width, u16 height, u32 fgcolor, | ||
126 | u32 bgcolor, const struct fb_image *image, | ||
127 | struct fb_info *info) | ||
128 | { | ||
129 | int i, j; | ||
130 | unsigned const char *line, *ptr; | ||
131 | u16 bytes; | ||
132 | |||
133 | cmd[0] = (GDC_TYPE_DRAWBITMAPP << 24) | | ||
134 | (GDC_CMD_BLT_DRAW << 16) | (2 + (height * step)); | ||
135 | cmd[1] = (dy << 16) | dx; | ||
136 | cmd[2] = (height << 16) | width; | ||
137 | |||
138 | i = 0; | ||
139 | line = ptr = image->data; | ||
140 | bytes = image->width; | ||
141 | |||
142 | while (i < height) { | ||
143 | ptr = line; | ||
144 | for (j = 0; j < step; j++) { | ||
145 | cmd[3 + i * step + j] = | ||
146 | (((u32 *) (info->pseudo_palette))[*ptr]) & 0xffff; | ||
147 | ptr++; | ||
148 | cmd[3 + i * step + j] |= | ||
149 | ((((u32 *) (info-> | ||
150 | pseudo_palette))[*ptr]) & 0xffff) << 16; | ||
151 | ptr++; | ||
152 | } | ||
153 | |||
154 | line += bytes; | ||
155 | i++; | ||
156 | } | ||
157 | } | ||
158 | |||
159 | /* | ||
160 | * Fill in the cmd array /GDC FIFO commands/ to draw a 16bit image. | ||
161 | * Make sure cmd has enough room! | ||
162 | */ | ||
163 | static void mb86290fb_imageblit16(u32 *cmd, u16 step, u16 dx, u16 dy, | ||
164 | u16 width, u16 height, u32 fgcolor, | ||
165 | u32 bgcolor, const struct fb_image *image, | ||
166 | struct fb_info *info) | ||
167 | { | ||
168 | int i; | ||
169 | unsigned const char *line; | ||
170 | u16 bytes; | ||
171 | |||
172 | i = 0; | ||
173 | line = image->data; | ||
174 | bytes = image->width << 1; | ||
175 | |||
176 | cmd[0] = (GDC_TYPE_DRAWBITMAPP << 24) | | ||
177 | (GDC_CMD_BLT_DRAW << 16) | (2 + step * height); | ||
178 | cmd[1] = (dy << 16) | dx; | ||
179 | cmd[2] = (height << 16) | width; | ||
180 | |||
181 | while (i < height) { | ||
182 | memcpy(&cmd[3 + i * step], line, step); | ||
183 | line += bytes; | ||
184 | i++; | ||
185 | } | ||
186 | } | ||
187 | |||
188 | static void mb86290fb_imageblit(struct fb_info *info, | ||
189 | const struct fb_image *image) | ||
190 | { | ||
191 | int mdr; | ||
192 | u32 *cmd = NULL; | ||
193 | void (*cmdfn) (u32 *, u16, u16, u16, u16, u16, u32, u32, | ||
194 | const struct fb_image *, struct fb_info *) = NULL; | ||
195 | u32 cmdlen; | ||
196 | u32 fgcolor = 0, bgcolor = 0; | ||
197 | u16 step; | ||
198 | |||
199 | u16 width = image->width, height = image->height; | ||
200 | u16 dx = image->dx, dy = image->dy; | ||
201 | int x2, y2, vxres, vyres; | ||
202 | |||
203 | mdr = (GDC_ROP_COPY << 9); | ||
204 | x2 = image->dx + image->width; | ||
205 | y2 = image->dy + image->height; | ||
206 | vxres = info->var.xres_virtual; | ||
207 | vyres = info->var.yres_virtual; | ||
208 | x2 = min(x2, vxres); | ||
209 | y2 = min(y2, vyres); | ||
210 | width = x2 - dx; | ||
211 | height = y2 - dy; | ||
212 | |||
213 | switch (image->depth) { | ||
214 | case 1: | ||
215 | step = (width + 31) >> 5; | ||
216 | cmdlen = 9 + height * step; | ||
217 | cmdfn = mb86290fb_imageblit1; | ||
218 | if (info->fix.visual == FB_VISUAL_TRUECOLOR || | ||
219 | info->fix.visual == FB_VISUAL_DIRECTCOLOR) { | ||
220 | fgcolor = | ||
221 | ((u32 *) (info->pseudo_palette))[image->fg_color]; | ||
222 | bgcolor = | ||
223 | ((u32 *) (info->pseudo_palette))[image->bg_color]; | ||
224 | } else { | ||
225 | fgcolor = image->fg_color; | ||
226 | bgcolor = image->bg_color; | ||
227 | } | ||
228 | |||
229 | break; | ||
230 | |||
231 | case 8: | ||
232 | step = (width + 1) >> 1; | ||
233 | cmdlen = 3 + height * step; | ||
234 | cmdfn = mb86290fb_imageblit8; | ||
235 | break; | ||
236 | |||
237 | case 16: | ||
238 | step = (width + 1) >> 1; | ||
239 | cmdlen = 3 + height * step; | ||
240 | cmdfn = mb86290fb_imageblit16; | ||
241 | break; | ||
242 | |||
243 | default: | ||
244 | cfb_imageblit(info, image); | ||
245 | return; | ||
246 | } | ||
247 | |||
248 | cmd = kmalloc(cmdlen * 4, GFP_DMA); | ||
249 | if (!cmd) | ||
250 | return cfb_imageblit(info, image); | ||
251 | cmdfn(cmd, step, dx, dy, width, height, fgcolor, bgcolor, image, info); | ||
252 | mb862xxfb_write_fifo(cmdlen, cmd, info); | ||
253 | kfree(cmd); | ||
254 | } | ||
255 | |||
256 | static void mb86290fb_fillrect(struct fb_info *info, | ||
257 | const struct fb_fillrect *rect) | ||
258 | { | ||
259 | |||
260 | u32 x2, y2, vxres, vyres, height, width, fg; | ||
261 | u32 cmd[7]; | ||
262 | |||
263 | vxres = info->var.xres_virtual; | ||
264 | vyres = info->var.yres_virtual; | ||
265 | |||
266 | if (!rect->width || !rect->height || rect->dx > vxres | ||
267 | || rect->dy > vyres) | ||
268 | return; | ||
269 | |||
270 | /* We could use hardware clipping but on many cards you get around | ||
271 | * hardware clipping by writing to framebuffer directly. */ | ||
272 | x2 = rect->dx + rect->width; | ||
273 | y2 = rect->dy + rect->height; | ||
274 | x2 = min(x2, vxres); | ||
275 | y2 = min(y2, vyres); | ||
276 | width = x2 - rect->dx; | ||
277 | height = y2 - rect->dy; | ||
278 | if (info->fix.visual == FB_VISUAL_TRUECOLOR || | ||
279 | info->fix.visual == FB_VISUAL_DIRECTCOLOR) | ||
280 | fg = ((u32 *) (info->pseudo_palette))[rect->color]; | ||
281 | else | ||
282 | fg = rect->color; | ||
283 | |||
284 | switch (rect->rop) { | ||
285 | |||
286 | case ROP_XOR: | ||
287 | /* Set raster operation */ | ||
288 | cmd[1] = (2 << 7) | (GDC_ROP_XOR << 9); | ||
289 | break; | ||
290 | |||
291 | case ROP_COPY: | ||
292 | /* Set raster operation */ | ||
293 | cmd[1] = (2 << 7) | (GDC_ROP_COPY << 9); | ||
294 | break; | ||
295 | |||
296 | } | ||
297 | |||
298 | cmd[0] = (GDC_TYPE_SETREGISTER << 24) | (1 << 16) | GDC_REG_MODE_BITMAP; | ||
299 | /* cmd[1] set earlier */ | ||
300 | cmd[2] = | ||
301 | (GDC_TYPE_SETCOLORREGISTER << 24) | (GDC_CMD_BODY_FORE_COLOR << 16); | ||
302 | cmd[3] = fg; | ||
303 | cmd[4] = (GDC_TYPE_DRAWRECTP << 24) | (GDC_CMD_BLT_FILL << 16); | ||
304 | cmd[5] = (rect->dy << 16) | (rect->dx); | ||
305 | cmd[6] = (height << 16) | width; | ||
306 | |||
307 | mb862xxfb_write_fifo(7, cmd, info); | ||
308 | } | ||
309 | |||
310 | void mb862xxfb_init_accel(struct fb_info *info, int xres) | ||
311 | { | ||
312 | struct mb862xxfb_par *par = info->par; | ||
313 | |||
314 | if (info->var.bits_per_pixel == 32) { | ||
315 | info->fbops->fb_fillrect = cfb_fillrect; | ||
316 | info->fbops->fb_copyarea = cfb_copyarea; | ||
317 | info->fbops->fb_imageblit = cfb_imageblit; | ||
318 | } else { | ||
319 | outreg(disp, GC_L0EM, 3); | ||
320 | info->fbops->fb_fillrect = mb86290fb_fillrect; | ||
321 | info->fbops->fb_copyarea = mb86290fb_copyarea; | ||
322 | info->fbops->fb_imageblit = mb86290fb_imageblit; | ||
323 | } | ||
324 | outreg(draw, GDC_REG_DRAW_BASE, 0); | ||
325 | outreg(draw, GDC_REG_MODE_MISC, 0x8000); | ||
326 | outreg(draw, GDC_REG_X_RESOLUTION, xres); | ||
327 | |||
328 | info->flags |= | ||
329 | FBINFO_HWACCEL_COPYAREA | FBINFO_HWACCEL_FILLRECT | | ||
330 | FBINFO_HWACCEL_IMAGEBLIT; | ||
331 | info->fix.accel = 0xff; /*FIXME: add right define */ | ||
332 | } | ||
333 | EXPORT_SYMBOL(mb862xxfb_init_accel); | ||
334 | |||
335 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/drivers/video/mb862xx/mb862xxfb_accel.h b/drivers/video/mb862xx/mb862xxfb_accel.h deleted file mode 100644 index 96a2dfef0f60..000000000000 --- a/drivers/video/mb862xx/mb862xxfb_accel.h +++ /dev/null | |||
@@ -1,203 +0,0 @@ | |||
1 | #ifndef __MB826XXFB_ACCEL_H__ | ||
2 | #define __MB826XXFB_ACCEL_H__ | ||
3 | |||
4 | /* registers */ | ||
5 | #define GDC_GEO_REG_INPUT_FIFO 0x00000400L | ||
6 | |||
7 | /* Special Registers */ | ||
8 | #define GDC_REG_CTRL 0x00000400L | ||
9 | #define GDC_REG_FIFO_STATUS 0x00000404L | ||
10 | #define GDC_REG_FIFO_COUNT 0x00000408L | ||
11 | #define GDC_REG_SETUP_STATUS 0x0000040CL | ||
12 | #define GDC_REG_DDA_STATUS 0x00000410L | ||
13 | #define GDC_REG_ENGINE_STATUS 0x00000414L | ||
14 | #define GDC_REG_ERROR_STATUS 0x00000418L | ||
15 | #define GDC_REG_MODE_MISC 0x00000420L /* MDR0 */ | ||
16 | #define GDC_REG_MODE_LINE 0x00000424L /* MDR1 */ | ||
17 | #define GDC_REG_MODE_POLYGON 0x00000428L /* MDR2 */ | ||
18 | #define GDC_REG_MODE_TEXTURE 0x0000042CL /* MDR3 */ | ||
19 | #define GDC_REG_MODE_BITMAP 0x00000430L /* MDR4 */ | ||
20 | #define GDC_REG_MODE_EXTENSION 0x0000043CL /* MDR7 */ | ||
21 | |||
22 | /* Configuration Registers */ | ||
23 | #define GDC_REG_DRAW_BASE 0x00000440L | ||
24 | #define GDC_REG_X_RESOLUTION 0x00000444L | ||
25 | #define GDC_REG_Z_BASE 0x00000448L | ||
26 | #define GDC_REG_TEXTURE_BASE 0x0000044CL | ||
27 | #define GDC_REG_POLYGON_FLAG_BASE 0x00000450L | ||
28 | #define GDC_REG_CLIP_XMIN 0x00000454L | ||
29 | #define GDC_REG_CLIP_XMAX 0x00000458L | ||
30 | #define GDC_REG_CLIP_YMIN 0x0000045CL | ||
31 | #define GDC_REG_CLIP_YMAX 0x00000460L | ||
32 | #define GDC_REG_TEXURE_SIZE 0x00000464L | ||
33 | #define GDC_REG_TILE_SIZE 0x00000468L | ||
34 | #define GDC_REG_TEX_BUF_OFFSET 0x0000046CL | ||
35 | |||
36 | /* for MB86293 or later */ | ||
37 | #define GDC_REG_ALPHA_MAP_BASE 0x00000474L /* ABR */ | ||
38 | |||
39 | /* Constant Registers */ | ||
40 | #define GDC_REG_FOREGROUND_COLOR 0x00000480L | ||
41 | #define GDC_REG_BACKGROUND_COLOR 0x00000484L | ||
42 | #define GDC_REG_ALPHA 0x00000488L | ||
43 | #define GDC_REG_LINE_PATTERN 0x0000048CL | ||
44 | #define GDC_REG_TEX_BORDER_COLOR 0x00000494L | ||
45 | #define GDC_REG_LINE_PATTERN_OFFSET 0x000003E0L | ||
46 | |||
47 | /* Coomand Code */ | ||
48 | #define GDC_CMD_PIXEL 0x00000000L | ||
49 | #define GDC_CMD_PIXEL_Z 0x00000001L | ||
50 | |||
51 | #define GDC_CMD_X_VECTOR 0x00000020L | ||
52 | #define GDC_CMD_Y_VECTOR 0x00000021L | ||
53 | #define GDC_CMD_X_VECTOR_NOEND 0x00000022L | ||
54 | #define GDC_CMD_Y_VECTOR_NOEND 0x00000023L | ||
55 | #define GDC_CMD_X_VECTOR_BLPO 0x00000024L | ||
56 | #define GDC_CMD_Y_VECTOR_BLPO 0x00000025L | ||
57 | #define GDC_CMD_X_VECTOR_NOEND_BLPO 0x00000026L | ||
58 | #define GDC_CMD_Y_VECTOR_NOEND_BLPO 0x00000027L | ||
59 | #define GDC_CMD_AA_X_VECTOR 0x00000028L | ||
60 | #define GDC_CMD_AA_Y_VECTOR 0x00000029L | ||
61 | #define GDC_CMD_AA_X_VECTOR_NOEND 0x0000002AL | ||
62 | #define GDC_CMD_AA_Y_VECTOR_NOEND 0x0000002BL | ||
63 | #define GDC_CMD_AA_X_VECTOR_BLPO 0x0000002CL | ||
64 | #define GDC_CMD_AA_Y_VECTOR_BLPO 0x0000002DL | ||
65 | #define GDC_CMD_AA_X_VECTOR_NOEND_BLPO 0x0000002EL | ||
66 | #define GDC_CMD_AA_Y_VECTOR_NOEND_BLPO 0x0000002FL | ||
67 | |||
68 | #define GDC_CMD_0_VECTOR 0x00000030L | ||
69 | #define GDC_CMD_1_VECTOR 0x00000031L | ||
70 | #define GDC_CMD_0_VECTOR_NOEND 0x00000032L | ||
71 | #define GDC_CMD_1_VECTOR_NOEND 0x00000033L | ||
72 | #define GDC_CMD_0_VECTOR_BLPO 0x00000034L | ||
73 | #define GDC_CMD_1_VECTOR_BLPO 0x00000035L | ||
74 | #define GDC_CMD_0_VECTOR_NOEND_BLPO 0x00000036L | ||
75 | #define GDC_CMD_1_VECTOR_NOEND_BLPO 0x00000037L | ||
76 | #define GDC_CMD_AA_0_VECTOR 0x00000038L | ||
77 | #define GDC_CMD_AA_1_VECTOR 0x00000039L | ||
78 | #define GDC_CMD_AA_0_VECTOR_NOEND 0x0000003AL | ||
79 | #define GDC_CMD_AA_1_VECTOR_NOEND 0x0000003BL | ||
80 | #define GDC_CMD_AA_0_VECTOR_BLPO 0x0000003CL | ||
81 | #define GDC_CMD_AA_1_VECTOR_BLPO 0x0000003DL | ||
82 | #define GDC_CMD_AA_0_VECTOR_NOEND_BLPO 0x0000003EL | ||
83 | #define GDC_CMD_AA_1_VECTOR_NOEND_BLPO 0x0000003FL | ||
84 | |||
85 | #define GDC_CMD_BLT_FILL 0x00000041L | ||
86 | #define GDC_CMD_BLT_DRAW 0x00000042L | ||
87 | #define GDC_CMD_BITMAP 0x00000043L | ||
88 | #define GDC_CMD_BLTCOPY_TOP_LEFT 0x00000044L | ||
89 | #define GDC_CMD_BLTCOPY_TOP_RIGHT 0x00000045L | ||
90 | #define GDC_CMD_BLTCOPY_BOTTOM_LEFT 0x00000046L | ||
91 | #define GDC_CMD_BLTCOPY_BOTTOM_RIGHT 0x00000047L | ||
92 | #define GDC_CMD_LOAD_TEXTURE 0x00000048L | ||
93 | #define GDC_CMD_LOAD_TILE 0x00000049L | ||
94 | |||
95 | #define GDC_CMD_TRAP_RIGHT 0x00000060L | ||
96 | #define GDC_CMD_TRAP_LEFT 0x00000061L | ||
97 | #define GDC_CMD_TRIANGLE_FAN 0x00000062L | ||
98 | #define GDC_CMD_FLAG_TRIANGLE_FAN 0x00000063L | ||
99 | |||
100 | #define GDC_CMD_FLUSH_FB 0x000000C1L | ||
101 | #define GDC_CMD_FLUSH_Z 0x000000C2L | ||
102 | |||
103 | #define GDC_CMD_POLYGON_BEGIN 0x000000E0L | ||
104 | #define GDC_CMD_POLYGON_END 0x000000E1L | ||
105 | #define GDC_CMD_CLEAR_POLY_FLAG 0x000000E2L | ||
106 | #define GDC_CMD_NORMAL 0x000000FFL | ||
107 | |||
108 | #define GDC_CMD_VECTOR_BLPO_FLAG 0x00040000L | ||
109 | #define GDC_CMD_FAST_VECTOR_BLPO_FLAG 0x00000004L | ||
110 | |||
111 | /* for MB86293 or later */ | ||
112 | #define GDC_CMD_MDR1 0x00000000L | ||
113 | #define GDC_CMD_MDR1S 0x00000002L | ||
114 | #define GDC_CMD_MDR1B 0x00000004L | ||
115 | #define GDC_CMD_MDR2 0x00000001L | ||
116 | #define GDC_CMD_MDR2S 0x00000003L | ||
117 | #define GDC_CMD_MDR2TL 0x00000007L | ||
118 | #define GDC_CMD_GMDR1E 0x00000010L | ||
119 | #define GDC_CMD_GMDR2E 0x00000020L | ||
120 | #define GDC_CMD_OVERLAP_SHADOW_XY 0x00000000L | ||
121 | #define GDC_CMD_OVERLAP_SHADOW_XY_COMPOSITION 0x00000001L | ||
122 | #define GDC_CMD_OVERLAP_Z_PACKED_ONBS 0x00000007L | ||
123 | #define GDC_CMD_OVERLAP_Z_ORIGIN 0x00000000L | ||
124 | #define GDC_CMD_OVERLAP_Z_NON_TOPLEFT 0x00000001L | ||
125 | #define GDC_CMD_OVERLAP_Z_BORDER 0x00000002L | ||
126 | #define GDC_CMD_OVERLAP_Z_SHADOW 0x00000003L | ||
127 | #define GDC_CMD_BLTCOPY_ALT_ALPHA 0x00000000L /* Reserverd */ | ||
128 | #define GDC_CMD_DC_LOGOUT 0x00000000L /* Reserverd */ | ||
129 | #define GDC_CMD_BODY_FORE_COLOR 0x00000000L | ||
130 | #define GDC_CMD_BODY_BACK_COLOR 0x00000001L | ||
131 | #define GDC_CMD_SHADOW_FORE_COLOR 0x00000002L | ||
132 | #define GDC_CMD_SHADOW_BACK_COLOR 0x00000003L | ||
133 | #define GDC_CMD_BORDER_FORE_COLOR 0x00000004L | ||
134 | #define GDC_CMD_BORDER_BACK_COLOR 0x00000005L | ||
135 | |||
136 | /* Type Code Table */ | ||
137 | #define GDC_TYPE_G_NOP 0x00000020L | ||
138 | #define GDC_TYPE_G_BEGIN 0x00000021L | ||
139 | #define GDC_TYPE_G_BEGINCONT 0x00000022L | ||
140 | #define GDC_TYPE_G_END 0x00000023L | ||
141 | #define GDC_TYPE_G_VERTEX 0x00000030L | ||
142 | #define GDC_TYPE_G_VERTEXLOG 0x00000032L | ||
143 | #define GDC_TYPE_G_VERTEXNOPLOG 0x00000033L | ||
144 | #define GDC_TYPE_G_INIT 0x00000040L | ||
145 | #define GDC_TYPE_G_VIEWPORT 0x00000041L | ||
146 | #define GDC_TYPE_G_DEPTHRANGE 0x00000042L | ||
147 | #define GDC_TYPE_G_LOADMATRIX 0x00000043L | ||
148 | #define GDC_TYPE_G_VIEWVOLUMEXYCLIP 0x00000044L | ||
149 | #define GDC_TYPE_G_VIEWVOLUMEZCLIP 0x00000045L | ||
150 | #define GDC_TYPE_G_VIEWVOLUMEWCLIP 0x00000046L | ||
151 | #define GDC_TYPE_SETLVERTEX2I 0x00000072L | ||
152 | #define GDC_TYPE_SETLVERTEX2IP 0x00000073L | ||
153 | #define GDC_TYPE_SETMODEREGISTER 0x000000C0L | ||
154 | #define GDC_TYPE_SETGMODEREGISTER 0x000000C1L | ||
155 | #define GDC_TYPE_OVERLAPXYOFFT 0x000000C8L | ||
156 | #define GDC_TYPE_OVERLAPZOFFT 0x000000C9L | ||
157 | #define GDC_TYPE_DC_LOGOUTADDR 0x000000CCL | ||
158 | #define GDC_TYPE_SETCOLORREGISTER 0x000000CEL | ||
159 | #define GDC_TYPE_G_BEGINE 0x000000E1L | ||
160 | #define GDC_TYPE_G_BEGINCONTE 0x000000E2L | ||
161 | #define GDC_TYPE_G_ENDE 0x000000E3L | ||
162 | #define GDC_TYPE_DRAWPIXEL 0x00000000L | ||
163 | #define GDC_TYPE_DRAWPIXELZ 0x00000001L | ||
164 | #define GDC_TYPE_DRAWLINE 0x00000002L | ||
165 | #define GDC_TYPE_DRAWLINE2I 0x00000003L | ||
166 | #define GDC_TYPE_DRAWLINE2IP 0x00000004L | ||
167 | #define GDC_TYPE_DRAWTRAP 0x00000005L | ||
168 | #define GDC_TYPE_DRAWVERTEX2I 0x00000006L | ||
169 | #define GDC_TYPE_DRAWVERTEX2IP 0x00000007L | ||
170 | #define GDC_TYPE_DRAWRECTP 0x00000009L | ||
171 | #define GDC_TYPE_DRAWBITMAPP 0x0000000BL | ||
172 | #define GDC_TYPE_BLTCOPYP 0x0000000DL | ||
173 | #define GDC_TYPE_BLTCOPYALTERNATEP 0x0000000FL | ||
174 | #define GDC_TYPE_LOADTEXTUREP 0x00000011L | ||
175 | #define GDC_TYPE_BLTTEXTUREP 0x00000013L | ||
176 | #define GDC_TYPE_BLTCOPYALTALPHABLENDP 0x0000001FL | ||
177 | #define GDC_TYPE_SETVERTEX2I 0x00000070L | ||
178 | #define GDC_TYPE_SETVERTEX2IP 0x00000071L | ||
179 | #define GDC_TYPE_DRAW 0x000000F0L | ||
180 | #define GDC_TYPE_SETREGISTER 0x000000F1L | ||
181 | #define GDC_TYPE_SYNC 0x000000FCL | ||
182 | #define GDC_TYPE_INTERRUPT 0x000000FDL | ||
183 | #define GDC_TYPE_NOP 0x0 | ||
184 | |||
185 | /* Raster operation */ | ||
186 | #define GDC_ROP_CLEAR 0x0000 | ||
187 | #define GDC_ROP_AND 0x0001 | ||
188 | #define GDC_ROP_AND_REVERSE 0x0002 | ||
189 | #define GDC_ROP_COPY 0x0003 | ||
190 | #define GDC_ROP_AND_INVERTED 0x0004 | ||
191 | #define GDC_ROP_NOP 0x0005 | ||
192 | #define GDC_ROP_XOR 0x0006 | ||
193 | #define GDC_ROP_OR 0x0007 | ||
194 | #define GDC_ROP_NOR 0x0008 | ||
195 | #define GDC_ROP_EQUIV 0x0009 | ||
196 | #define GDC_ROP_INVERT 0x000A | ||
197 | #define GDC_ROP_OR_REVERSE 0x000B | ||
198 | #define GDC_ROP_COPY_INVERTED 0x000C | ||
199 | #define GDC_ROP_OR_INVERTED 0x000D | ||
200 | #define GDC_ROP_NAND 0x000E | ||
201 | #define GDC_ROP_SET 0x000F | ||
202 | |||
203 | #endif | ||
diff --git a/drivers/video/mb862xx/mb862xxfbdrv.c b/drivers/video/mb862xx/mb862xxfbdrv.c deleted file mode 100644 index 0cd4c3318511..000000000000 --- a/drivers/video/mb862xx/mb862xxfbdrv.c +++ /dev/null | |||
@@ -1,1206 +0,0 @@ | |||
1 | /* | ||
2 | * drivers/mb862xx/mb862xxfb.c | ||
3 | * | ||
4 | * Fujitsu Carmine/Coral-P(A)/Lime framebuffer driver | ||
5 | * | ||
6 | * (C) 2008 Anatolij Gustschin <agust@denx.de> | ||
7 | * DENX Software Engineering | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or modify | ||
10 | * it under the terms of the GNU General Public License version 2 as | ||
11 | * published by the Free Software Foundation. | ||
12 | * | ||
13 | */ | ||
14 | |||
15 | #undef DEBUG | ||
16 | |||
17 | #include <linux/fb.h> | ||
18 | #include <linux/delay.h> | ||
19 | #include <linux/uaccess.h> | ||
20 | #include <linux/module.h> | ||
21 | #include <linux/init.h> | ||
22 | #include <linux/interrupt.h> | ||
23 | #include <linux/pci.h> | ||
24 | #if defined(CONFIG_OF) | ||
25 | #include <linux/of_platform.h> | ||
26 | #endif | ||
27 | #include "mb862xxfb.h" | ||
28 | #include "mb862xx_reg.h" | ||
29 | |||
30 | #define NR_PALETTE 256 | ||
31 | #define MB862XX_MEM_SIZE 0x1000000 | ||
32 | #define CORALP_MEM_SIZE 0x2000000 | ||
33 | #define CARMINE_MEM_SIZE 0x8000000 | ||
34 | #define DRV_NAME "mb862xxfb" | ||
35 | |||
36 | #if defined(CONFIG_SOCRATES) | ||
37 | static struct mb862xx_gc_mode socrates_gc_mode = { | ||
38 | /* Mode for Prime View PM070WL4 TFT LCD Panel */ | ||
39 | { "800x480", 45, 800, 480, 40000, 86, 42, 33, 10, 128, 2, 0, 0, 0 }, | ||
40 | /* 16 bits/pixel, 16MB, 133MHz, SDRAM memory mode value */ | ||
41 | 16, 0x1000000, GC_CCF_COT_133, 0x4157ba63 | ||
42 | }; | ||
43 | #endif | ||
44 | |||
45 | /* Helpers */ | ||
46 | static inline int h_total(struct fb_var_screeninfo *var) | ||
47 | { | ||
48 | return var->xres + var->left_margin + | ||
49 | var->right_margin + var->hsync_len; | ||
50 | } | ||
51 | |||
52 | static inline int v_total(struct fb_var_screeninfo *var) | ||
53 | { | ||
54 | return var->yres + var->upper_margin + | ||
55 | var->lower_margin + var->vsync_len; | ||
56 | } | ||
57 | |||
58 | static inline int hsp(struct fb_var_screeninfo *var) | ||
59 | { | ||
60 | return var->xres + var->right_margin - 1; | ||
61 | } | ||
62 | |||
63 | static inline int vsp(struct fb_var_screeninfo *var) | ||
64 | { | ||
65 | return var->yres + var->lower_margin - 1; | ||
66 | } | ||
67 | |||
68 | static inline int d_pitch(struct fb_var_screeninfo *var) | ||
69 | { | ||
70 | return var->xres * var->bits_per_pixel / 8; | ||
71 | } | ||
72 | |||
73 | static inline unsigned int chan_to_field(unsigned int chan, | ||
74 | struct fb_bitfield *bf) | ||
75 | { | ||
76 | chan &= 0xffff; | ||
77 | chan >>= 16 - bf->length; | ||
78 | return chan << bf->offset; | ||
79 | } | ||
80 | |||
81 | static int mb862xxfb_setcolreg(unsigned regno, | ||
82 | unsigned red, unsigned green, unsigned blue, | ||
83 | unsigned transp, struct fb_info *info) | ||
84 | { | ||
85 | struct mb862xxfb_par *par = info->par; | ||
86 | unsigned int val; | ||
87 | |||
88 | switch (info->fix.visual) { | ||
89 | case FB_VISUAL_TRUECOLOR: | ||
90 | if (regno < 16) { | ||
91 | val = chan_to_field(red, &info->var.red); | ||
92 | val |= chan_to_field(green, &info->var.green); | ||
93 | val |= chan_to_field(blue, &info->var.blue); | ||
94 | par->pseudo_palette[regno] = val; | ||
95 | } | ||
96 | break; | ||
97 | case FB_VISUAL_PSEUDOCOLOR: | ||
98 | if (regno < 256) { | ||
99 | val = (red >> 8) << 16; | ||
100 | val |= (green >> 8) << 8; | ||
101 | val |= blue >> 8; | ||
102 | outreg(disp, GC_L0PAL0 + (regno * 4), val); | ||
103 | } | ||
104 | break; | ||
105 | default: | ||
106 | return 1; /* unsupported type */ | ||
107 | } | ||
108 | return 0; | ||
109 | } | ||
110 | |||
111 | static int mb862xxfb_check_var(struct fb_var_screeninfo *var, | ||
112 | struct fb_info *fbi) | ||
113 | { | ||
114 | unsigned long tmp; | ||
115 | |||
116 | if (fbi->dev) | ||
117 | dev_dbg(fbi->dev, "%s\n", __func__); | ||
118 | |||
119 | /* check if these values fit into the registers */ | ||
120 | if (var->hsync_len > 255 || var->vsync_len > 255) | ||
121 | return -EINVAL; | ||
122 | |||
123 | if ((var->xres + var->right_margin) >= 4096) | ||
124 | return -EINVAL; | ||
125 | |||
126 | if ((var->yres + var->lower_margin) > 4096) | ||
127 | return -EINVAL; | ||
128 | |||
129 | if (h_total(var) > 4096 || v_total(var) > 4096) | ||
130 | return -EINVAL; | ||
131 | |||
132 | if (var->xres_virtual > 4096 || var->yres_virtual > 4096) | ||
133 | return -EINVAL; | ||
134 | |||
135 | if (var->bits_per_pixel <= 8) | ||
136 | var->bits_per_pixel = 8; | ||
137 | else if (var->bits_per_pixel <= 16) | ||
138 | var->bits_per_pixel = 16; | ||
139 | else if (var->bits_per_pixel <= 32) | ||
140 | var->bits_per_pixel = 32; | ||
141 | |||
142 | /* | ||
143 | * can cope with 8,16 or 24/32bpp if resulting | ||
144 | * pitch is divisible by 64 without remainder | ||
145 | */ | ||
146 | if (d_pitch(&fbi->var) % GC_L0M_L0W_UNIT) { | ||
147 | int r; | ||
148 | |||
149 | var->bits_per_pixel = 0; | ||
150 | do { | ||
151 | var->bits_per_pixel += 8; | ||
152 | r = d_pitch(&fbi->var) % GC_L0M_L0W_UNIT; | ||
153 | } while (r && var->bits_per_pixel <= 32); | ||
154 | |||
155 | if (d_pitch(&fbi->var) % GC_L0M_L0W_UNIT) | ||
156 | return -EINVAL; | ||
157 | } | ||
158 | |||
159 | /* line length is going to be 128 bit aligned */ | ||
160 | tmp = (var->xres * var->bits_per_pixel) / 8; | ||
161 | if ((tmp & 15) != 0) | ||
162 | return -EINVAL; | ||
163 | |||
164 | /* set r/g/b positions and validate bpp */ | ||
165 | switch (var->bits_per_pixel) { | ||
166 | case 8: | ||
167 | var->red.length = var->bits_per_pixel; | ||
168 | var->green.length = var->bits_per_pixel; | ||
169 | var->blue.length = var->bits_per_pixel; | ||
170 | var->red.offset = 0; | ||
171 | var->green.offset = 0; | ||
172 | var->blue.offset = 0; | ||
173 | var->transp.length = 0; | ||
174 | break; | ||
175 | case 16: | ||
176 | var->red.length = 5; | ||
177 | var->green.length = 5; | ||
178 | var->blue.length = 5; | ||
179 | var->red.offset = 10; | ||
180 | var->green.offset = 5; | ||
181 | var->blue.offset = 0; | ||
182 | var->transp.length = 0; | ||
183 | break; | ||
184 | case 24: | ||
185 | case 32: | ||
186 | var->transp.length = 8; | ||
187 | var->red.length = 8; | ||
188 | var->green.length = 8; | ||
189 | var->blue.length = 8; | ||
190 | var->transp.offset = 24; | ||
191 | var->red.offset = 16; | ||
192 | var->green.offset = 8; | ||
193 | var->blue.offset = 0; | ||
194 | break; | ||
195 | default: | ||
196 | return -EINVAL; | ||
197 | } | ||
198 | return 0; | ||
199 | } | ||
200 | |||
201 | /* | ||
202 | * set display parameters | ||
203 | */ | ||
204 | static int mb862xxfb_set_par(struct fb_info *fbi) | ||
205 | { | ||
206 | struct mb862xxfb_par *par = fbi->par; | ||
207 | unsigned long reg, sc; | ||
208 | |||
209 | dev_dbg(par->dev, "%s\n", __func__); | ||
210 | if (par->type == BT_CORALP) | ||
211 | mb862xxfb_init_accel(fbi, fbi->var.xres); | ||
212 | |||
213 | if (par->pre_init) | ||
214 | return 0; | ||
215 | |||
216 | /* disp off */ | ||
217 | reg = inreg(disp, GC_DCM1); | ||
218 | reg &= ~GC_DCM01_DEN; | ||
219 | outreg(disp, GC_DCM1, reg); | ||
220 | |||
221 | /* set display reference clock div. */ | ||
222 | sc = par->refclk / (1000000 / fbi->var.pixclock) - 1; | ||
223 | reg = inreg(disp, GC_DCM1); | ||
224 | reg &= ~(GC_DCM01_CKS | GC_DCM01_RESV | GC_DCM01_SC); | ||
225 | reg |= sc << 8; | ||
226 | outreg(disp, GC_DCM1, reg); | ||
227 | dev_dbg(par->dev, "SC 0x%lx\n", sc); | ||
228 | |||
229 | /* disp dimension, format */ | ||
230 | reg = pack(d_pitch(&fbi->var) / GC_L0M_L0W_UNIT, | ||
231 | (fbi->var.yres - 1)); | ||
232 | if (fbi->var.bits_per_pixel == 16) | ||
233 | reg |= GC_L0M_L0C_16; | ||
234 | outreg(disp, GC_L0M, reg); | ||
235 | |||
236 | if (fbi->var.bits_per_pixel == 32) { | ||
237 | reg = inreg(disp, GC_L0EM); | ||
238 | outreg(disp, GC_L0EM, reg | GC_L0EM_L0EC_24); | ||
239 | } | ||
240 | outreg(disp, GC_WY_WX, 0); | ||
241 | reg = pack(fbi->var.yres - 1, fbi->var.xres); | ||
242 | outreg(disp, GC_WH_WW, reg); | ||
243 | outreg(disp, GC_L0OA0, 0); | ||
244 | outreg(disp, GC_L0DA0, 0); | ||
245 | outreg(disp, GC_L0DY_L0DX, 0); | ||
246 | outreg(disp, GC_L0WY_L0WX, 0); | ||
247 | outreg(disp, GC_L0WH_L0WW, reg); | ||
248 | |||
249 | /* both HW-cursors off */ | ||
250 | reg = inreg(disp, GC_CPM_CUTC); | ||
251 | reg &= ~(GC_CPM_CEN0 | GC_CPM_CEN1); | ||
252 | outreg(disp, GC_CPM_CUTC, reg); | ||
253 | |||
254 | /* timings */ | ||
255 | reg = pack(fbi->var.xres - 1, fbi->var.xres - 1); | ||
256 | outreg(disp, GC_HDB_HDP, reg); | ||
257 | reg = pack((fbi->var.yres - 1), vsp(&fbi->var)); | ||
258 | outreg(disp, GC_VDP_VSP, reg); | ||
259 | reg = ((fbi->var.vsync_len - 1) << 24) | | ||
260 | pack((fbi->var.hsync_len - 1), hsp(&fbi->var)); | ||
261 | outreg(disp, GC_VSW_HSW_HSP, reg); | ||
262 | outreg(disp, GC_HTP, pack(h_total(&fbi->var) - 1, 0)); | ||
263 | outreg(disp, GC_VTR, pack(v_total(&fbi->var) - 1, 0)); | ||
264 | |||
265 | /* display on */ | ||
266 | reg = inreg(disp, GC_DCM1); | ||
267 | reg |= GC_DCM01_DEN | GC_DCM01_L0E; | ||
268 | reg &= ~GC_DCM01_ESY; | ||
269 | outreg(disp, GC_DCM1, reg); | ||
270 | return 0; | ||
271 | } | ||
272 | |||
273 | static int mb862xxfb_pan(struct fb_var_screeninfo *var, | ||
274 | struct fb_info *info) | ||
275 | { | ||
276 | struct mb862xxfb_par *par = info->par; | ||
277 | unsigned long reg; | ||
278 | |||
279 | reg = pack(var->yoffset, var->xoffset); | ||
280 | outreg(disp, GC_L0WY_L0WX, reg); | ||
281 | |||
282 | reg = pack(info->var.yres_virtual, info->var.xres_virtual); | ||
283 | outreg(disp, GC_L0WH_L0WW, reg); | ||
284 | return 0; | ||
285 | } | ||
286 | |||
287 | static int mb862xxfb_blank(int mode, struct fb_info *fbi) | ||
288 | { | ||
289 | struct mb862xxfb_par *par = fbi->par; | ||
290 | unsigned long reg; | ||
291 | |||
292 | dev_dbg(fbi->dev, "blank mode=%d\n", mode); | ||
293 | |||
294 | switch (mode) { | ||
295 | case FB_BLANK_POWERDOWN: | ||
296 | reg = inreg(disp, GC_DCM1); | ||
297 | reg &= ~GC_DCM01_DEN; | ||
298 | outreg(disp, GC_DCM1, reg); | ||
299 | break; | ||
300 | case FB_BLANK_UNBLANK: | ||
301 | reg = inreg(disp, GC_DCM1); | ||
302 | reg |= GC_DCM01_DEN; | ||
303 | outreg(disp, GC_DCM1, reg); | ||
304 | break; | ||
305 | case FB_BLANK_NORMAL: | ||
306 | case FB_BLANK_VSYNC_SUSPEND: | ||
307 | case FB_BLANK_HSYNC_SUSPEND: | ||
308 | default: | ||
309 | return 1; | ||
310 | } | ||
311 | return 0; | ||
312 | } | ||
313 | |||
314 | static int mb862xxfb_ioctl(struct fb_info *fbi, unsigned int cmd, | ||
315 | unsigned long arg) | ||
316 | { | ||
317 | struct mb862xxfb_par *par = fbi->par; | ||
318 | struct mb862xx_l1_cfg *l1_cfg = &par->l1_cfg; | ||
319 | void __user *argp = (void __user *)arg; | ||
320 | int *enable; | ||
321 | u32 l1em = 0; | ||
322 | |||
323 | switch (cmd) { | ||
324 | case MB862XX_L1_GET_CFG: | ||
325 | if (copy_to_user(argp, l1_cfg, sizeof(*l1_cfg))) | ||
326 | return -EFAULT; | ||
327 | break; | ||
328 | case MB862XX_L1_SET_CFG: | ||
329 | if (copy_from_user(l1_cfg, argp, sizeof(*l1_cfg))) | ||
330 | return -EFAULT; | ||
331 | if (l1_cfg->dh == 0 || l1_cfg->dw == 0) | ||
332 | return -EINVAL; | ||
333 | if ((l1_cfg->sw >= l1_cfg->dw) && (l1_cfg->sh >= l1_cfg->dh)) { | ||
334 | /* downscaling */ | ||
335 | outreg(cap, GC_CAP_CSC, | ||
336 | pack((l1_cfg->sh << 11) / l1_cfg->dh, | ||
337 | (l1_cfg->sw << 11) / l1_cfg->dw)); | ||
338 | l1em = inreg(disp, GC_L1EM); | ||
339 | l1em &= ~GC_L1EM_DM; | ||
340 | } else if ((l1_cfg->sw <= l1_cfg->dw) && | ||
341 | (l1_cfg->sh <= l1_cfg->dh)) { | ||
342 | /* upscaling */ | ||
343 | outreg(cap, GC_CAP_CSC, | ||
344 | pack((l1_cfg->sh << 11) / l1_cfg->dh, | ||
345 | (l1_cfg->sw << 11) / l1_cfg->dw)); | ||
346 | outreg(cap, GC_CAP_CMSS, | ||
347 | pack(l1_cfg->sw >> 1, l1_cfg->sh)); | ||
348 | outreg(cap, GC_CAP_CMDS, | ||
349 | pack(l1_cfg->dw >> 1, l1_cfg->dh)); | ||
350 | l1em = inreg(disp, GC_L1EM); | ||
351 | l1em |= GC_L1EM_DM; | ||
352 | } | ||
353 | |||
354 | if (l1_cfg->mirror) { | ||
355 | outreg(cap, GC_CAP_CBM, | ||
356 | inreg(cap, GC_CAP_CBM) | GC_CBM_HRV); | ||
357 | l1em |= l1_cfg->dw * 2 - 8; | ||
358 | } else { | ||
359 | outreg(cap, GC_CAP_CBM, | ||
360 | inreg(cap, GC_CAP_CBM) & ~GC_CBM_HRV); | ||
361 | l1em &= 0xffff0000; | ||
362 | } | ||
363 | outreg(disp, GC_L1EM, l1em); | ||
364 | break; | ||
365 | case MB862XX_L1_ENABLE: | ||
366 | enable = (int *)arg; | ||
367 | if (*enable) { | ||
368 | outreg(disp, GC_L1DA, par->cap_buf); | ||
369 | outreg(cap, GC_CAP_IMG_START, | ||
370 | pack(l1_cfg->sy >> 1, l1_cfg->sx)); | ||
371 | outreg(cap, GC_CAP_IMG_END, | ||
372 | pack(l1_cfg->sh, l1_cfg->sw)); | ||
373 | outreg(disp, GC_L1M, GC_L1M_16 | GC_L1M_YC | GC_L1M_CS | | ||
374 | (par->l1_stride << 16)); | ||
375 | outreg(disp, GC_L1WY_L1WX, | ||
376 | pack(l1_cfg->dy, l1_cfg->dx)); | ||
377 | outreg(disp, GC_L1WH_L1WW, | ||
378 | pack(l1_cfg->dh - 1, l1_cfg->dw)); | ||
379 | outreg(disp, GC_DLS, 1); | ||
380 | outreg(cap, GC_CAP_VCM, | ||
381 | GC_VCM_VIE | GC_VCM_CM | GC_VCM_VS_PAL); | ||
382 | outreg(disp, GC_DCM1, inreg(disp, GC_DCM1) | | ||
383 | GC_DCM1_DEN | GC_DCM1_L1E); | ||
384 | } else { | ||
385 | outreg(cap, GC_CAP_VCM, | ||
386 | inreg(cap, GC_CAP_VCM) & ~GC_VCM_VIE); | ||
387 | outreg(disp, GC_DCM1, | ||
388 | inreg(disp, GC_DCM1) & ~GC_DCM1_L1E); | ||
389 | } | ||
390 | break; | ||
391 | case MB862XX_L1_CAP_CTL: | ||
392 | enable = (int *)arg; | ||
393 | if (*enable) { | ||
394 | outreg(cap, GC_CAP_VCM, | ||
395 | inreg(cap, GC_CAP_VCM) | GC_VCM_VIE); | ||
396 | } else { | ||
397 | outreg(cap, GC_CAP_VCM, | ||
398 | inreg(cap, GC_CAP_VCM) & ~GC_VCM_VIE); | ||
399 | } | ||
400 | break; | ||
401 | default: | ||
402 | return -EINVAL; | ||
403 | } | ||
404 | return 0; | ||
405 | } | ||
406 | |||
407 | /* framebuffer ops */ | ||
408 | static struct fb_ops mb862xxfb_ops = { | ||
409 | .owner = THIS_MODULE, | ||
410 | .fb_check_var = mb862xxfb_check_var, | ||
411 | .fb_set_par = mb862xxfb_set_par, | ||
412 | .fb_setcolreg = mb862xxfb_setcolreg, | ||
413 | .fb_blank = mb862xxfb_blank, | ||
414 | .fb_pan_display = mb862xxfb_pan, | ||
415 | .fb_fillrect = cfb_fillrect, | ||
416 | .fb_copyarea = cfb_copyarea, | ||
417 | .fb_imageblit = cfb_imageblit, | ||
418 | .fb_ioctl = mb862xxfb_ioctl, | ||
419 | }; | ||
420 | |||
421 | /* initialize fb_info data */ | ||
422 | static int mb862xxfb_init_fbinfo(struct fb_info *fbi) | ||
423 | { | ||
424 | struct mb862xxfb_par *par = fbi->par; | ||
425 | struct mb862xx_gc_mode *mode = par->gc_mode; | ||
426 | unsigned long reg; | ||
427 | int stride; | ||
428 | |||
429 | fbi->fbops = &mb862xxfb_ops; | ||
430 | fbi->pseudo_palette = par->pseudo_palette; | ||
431 | fbi->screen_base = par->fb_base; | ||
432 | fbi->screen_size = par->mapped_vram; | ||
433 | |||
434 | strcpy(fbi->fix.id, DRV_NAME); | ||
435 | fbi->fix.smem_start = (unsigned long)par->fb_base_phys; | ||
436 | fbi->fix.mmio_start = (unsigned long)par->mmio_base_phys; | ||
437 | fbi->fix.mmio_len = par->mmio_len; | ||
438 | fbi->fix.accel = FB_ACCEL_NONE; | ||
439 | fbi->fix.type = FB_TYPE_PACKED_PIXELS; | ||
440 | fbi->fix.type_aux = 0; | ||
441 | fbi->fix.xpanstep = 1; | ||
442 | fbi->fix.ypanstep = 1; | ||
443 | fbi->fix.ywrapstep = 0; | ||
444 | |||
445 | reg = inreg(disp, GC_DCM1); | ||
446 | if (reg & GC_DCM01_DEN && reg & GC_DCM01_L0E) { | ||
447 | /* get the disp mode from active display cfg */ | ||
448 | unsigned long sc = ((reg & GC_DCM01_SC) >> 8) + 1; | ||
449 | unsigned long hsp, vsp, ht, vt; | ||
450 | |||
451 | dev_dbg(par->dev, "using bootloader's disp. mode\n"); | ||
452 | fbi->var.pixclock = (sc * 1000000) / par->refclk; | ||
453 | fbi->var.xres = (inreg(disp, GC_HDB_HDP) & 0x0fff) + 1; | ||
454 | reg = inreg(disp, GC_VDP_VSP); | ||
455 | fbi->var.yres = ((reg >> 16) & 0x0fff) + 1; | ||
456 | vsp = (reg & 0x0fff) + 1; | ||
457 | fbi->var.xres_virtual = fbi->var.xres; | ||
458 | fbi->var.yres_virtual = fbi->var.yres; | ||
459 | reg = inreg(disp, GC_L0EM); | ||
460 | if (reg & GC_L0EM_L0EC_24) { | ||
461 | fbi->var.bits_per_pixel = 32; | ||
462 | } else { | ||
463 | reg = inreg(disp, GC_L0M); | ||
464 | if (reg & GC_L0M_L0C_16) | ||
465 | fbi->var.bits_per_pixel = 16; | ||
466 | else | ||
467 | fbi->var.bits_per_pixel = 8; | ||
468 | } | ||
469 | reg = inreg(disp, GC_VSW_HSW_HSP); | ||
470 | fbi->var.hsync_len = ((reg & 0xff0000) >> 16) + 1; | ||
471 | fbi->var.vsync_len = ((reg & 0x3f000000) >> 24) + 1; | ||
472 | hsp = (reg & 0xffff) + 1; | ||
473 | ht = ((inreg(disp, GC_HTP) & 0xfff0000) >> 16) + 1; | ||
474 | fbi->var.right_margin = hsp - fbi->var.xres; | ||
475 | fbi->var.left_margin = ht - hsp - fbi->var.hsync_len; | ||
476 | vt = ((inreg(disp, GC_VTR) & 0xfff0000) >> 16) + 1; | ||
477 | fbi->var.lower_margin = vsp - fbi->var.yres; | ||
478 | fbi->var.upper_margin = vt - vsp - fbi->var.vsync_len; | ||
479 | } else if (mode) { | ||
480 | dev_dbg(par->dev, "using supplied mode\n"); | ||
481 | fb_videomode_to_var(&fbi->var, (struct fb_videomode *)mode); | ||
482 | fbi->var.bits_per_pixel = mode->def_bpp ? mode->def_bpp : 8; | ||
483 | } else { | ||
484 | int ret; | ||
485 | |||
486 | ret = fb_find_mode(&fbi->var, fbi, "640x480-16@60", | ||
487 | NULL, 0, NULL, 16); | ||
488 | if (ret == 0 || ret == 4) { | ||
489 | dev_err(par->dev, | ||
490 | "failed to get initial mode\n"); | ||
491 | return -EINVAL; | ||
492 | } | ||
493 | } | ||
494 | |||
495 | fbi->var.xoffset = 0; | ||
496 | fbi->var.yoffset = 0; | ||
497 | fbi->var.grayscale = 0; | ||
498 | fbi->var.nonstd = 0; | ||
499 | fbi->var.height = -1; | ||
500 | fbi->var.width = -1; | ||
501 | fbi->var.accel_flags = 0; | ||
502 | fbi->var.vmode = FB_VMODE_NONINTERLACED; | ||
503 | fbi->var.activate = FB_ACTIVATE_NOW; | ||
504 | fbi->flags = FBINFO_DEFAULT | | ||
505 | #ifdef __BIG_ENDIAN | ||
506 | FBINFO_FOREIGN_ENDIAN | | ||
507 | #endif | ||
508 | FBINFO_HWACCEL_XPAN | | ||
509 | FBINFO_HWACCEL_YPAN; | ||
510 | |||
511 | /* check and possibly fix bpp */ | ||
512 | if ((fbi->fbops->fb_check_var)(&fbi->var, fbi)) | ||
513 | dev_err(par->dev, "check_var() failed on initial setup?\n"); | ||
514 | |||
515 | fbi->fix.visual = fbi->var.bits_per_pixel == 8 ? | ||
516 | FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_TRUECOLOR; | ||
517 | fbi->fix.line_length = (fbi->var.xres_virtual * | ||
518 | fbi->var.bits_per_pixel) / 8; | ||
519 | fbi->fix.smem_len = fbi->fix.line_length * fbi->var.yres_virtual; | ||
520 | |||
521 | /* | ||
522 | * reserve space for capture buffers and two cursors | ||
523 | * at the end of vram: 720x576 * 2 * 2.2 + 64x64 * 16. | ||
524 | */ | ||
525 | par->cap_buf = par->mapped_vram - 0x1bd800 - 0x10000; | ||
526 | par->cap_len = 0x1bd800; | ||
527 | par->l1_cfg.sx = 0; | ||
528 | par->l1_cfg.sy = 0; | ||
529 | par->l1_cfg.sw = 720; | ||
530 | par->l1_cfg.sh = 576; | ||
531 | par->l1_cfg.dx = 0; | ||
532 | par->l1_cfg.dy = 0; | ||
533 | par->l1_cfg.dw = 720; | ||
534 | par->l1_cfg.dh = 576; | ||
535 | stride = par->l1_cfg.sw * (fbi->var.bits_per_pixel / 8); | ||
536 | par->l1_stride = stride / 64 + ((stride % 64) ? 1 : 0); | ||
537 | outreg(cap, GC_CAP_CBM, GC_CBM_OO | GC_CBM_CBST | | ||
538 | (par->l1_stride << 16)); | ||
539 | outreg(cap, GC_CAP_CBOA, par->cap_buf); | ||
540 | outreg(cap, GC_CAP_CBLA, par->cap_buf + par->cap_len); | ||
541 | return 0; | ||
542 | } | ||
543 | |||
544 | /* | ||
545 | * show some display controller and cursor registers | ||
546 | */ | ||
547 | static ssize_t mb862xxfb_show_dispregs(struct device *dev, | ||
548 | struct device_attribute *attr, char *buf) | ||
549 | { | ||
550 | struct fb_info *fbi = dev_get_drvdata(dev); | ||
551 | struct mb862xxfb_par *par = fbi->par; | ||
552 | char *ptr = buf; | ||
553 | unsigned int reg; | ||
554 | |||
555 | for (reg = GC_DCM0; reg <= GC_L0DY_L0DX; reg += 4) | ||
556 | ptr += sprintf(ptr, "%08x = %08x\n", | ||
557 | reg, inreg(disp, reg)); | ||
558 | |||
559 | for (reg = GC_CPM_CUTC; reg <= GC_CUY1_CUX1; reg += 4) | ||
560 | ptr += sprintf(ptr, "%08x = %08x\n", | ||
561 | reg, inreg(disp, reg)); | ||
562 | |||
563 | for (reg = GC_DCM1; reg <= GC_L0WH_L0WW; reg += 4) | ||
564 | ptr += sprintf(ptr, "%08x = %08x\n", | ||
565 | reg, inreg(disp, reg)); | ||
566 | |||
567 | for (reg = 0x400; reg <= 0x410; reg += 4) | ||
568 | ptr += sprintf(ptr, "geo %08x = %08x\n", | ||
569 | reg, inreg(geo, reg)); | ||
570 | |||
571 | for (reg = 0x400; reg <= 0x410; reg += 4) | ||
572 | ptr += sprintf(ptr, "draw %08x = %08x\n", | ||
573 | reg, inreg(draw, reg)); | ||
574 | |||
575 | for (reg = 0x440; reg <= 0x450; reg += 4) | ||
576 | ptr += sprintf(ptr, "draw %08x = %08x\n", | ||
577 | reg, inreg(draw, reg)); | ||
578 | |||
579 | return ptr - buf; | ||
580 | } | ||
581 | |||
582 | static DEVICE_ATTR(dispregs, 0444, mb862xxfb_show_dispregs, NULL); | ||
583 | |||
584 | static irqreturn_t mb862xx_intr(int irq, void *dev_id) | ||
585 | { | ||
586 | struct mb862xxfb_par *par = (struct mb862xxfb_par *) dev_id; | ||
587 | unsigned long reg_ist, mask; | ||
588 | |||
589 | if (!par) | ||
590 | return IRQ_NONE; | ||
591 | |||
592 | if (par->type == BT_CARMINE) { | ||
593 | /* Get Interrupt Status */ | ||
594 | reg_ist = inreg(ctrl, GC_CTRL_STATUS); | ||
595 | mask = inreg(ctrl, GC_CTRL_INT_MASK); | ||
596 | if (reg_ist == 0) | ||
597 | return IRQ_HANDLED; | ||
598 | |||
599 | reg_ist &= mask; | ||
600 | if (reg_ist == 0) | ||
601 | return IRQ_HANDLED; | ||
602 | |||
603 | /* Clear interrupt status */ | ||
604 | outreg(ctrl, 0x0, reg_ist); | ||
605 | } else { | ||
606 | /* Get status */ | ||
607 | reg_ist = inreg(host, GC_IST); | ||
608 | mask = inreg(host, GC_IMASK); | ||
609 | |||
610 | reg_ist &= mask; | ||
611 | if (reg_ist == 0) | ||
612 | return IRQ_HANDLED; | ||
613 | |||
614 | /* Clear status */ | ||
615 | outreg(host, GC_IST, ~reg_ist); | ||
616 | } | ||
617 | return IRQ_HANDLED; | ||
618 | } | ||
619 | |||
620 | #if defined(CONFIG_FB_MB862XX_LIME) | ||
621 | /* | ||
622 | * GDC (Lime, Coral(B/Q), Mint, ...) on host bus | ||
623 | */ | ||
624 | static int mb862xx_gdc_init(struct mb862xxfb_par *par) | ||
625 | { | ||
626 | unsigned long ccf, mmr; | ||
627 | unsigned long ver, rev; | ||
628 | |||
629 | if (!par) | ||
630 | return -ENODEV; | ||
631 | |||
632 | #if defined(CONFIG_FB_PRE_INIT_FB) | ||
633 | par->pre_init = 1; | ||
634 | #endif | ||
635 | par->host = par->mmio_base; | ||
636 | par->i2c = par->mmio_base + MB862XX_I2C_BASE; | ||
637 | par->disp = par->mmio_base + MB862XX_DISP_BASE; | ||
638 | par->cap = par->mmio_base + MB862XX_CAP_BASE; | ||
639 | par->draw = par->mmio_base + MB862XX_DRAW_BASE; | ||
640 | par->geo = par->mmio_base + MB862XX_GEO_BASE; | ||
641 | par->pio = par->mmio_base + MB862XX_PIO_BASE; | ||
642 | |||
643 | par->refclk = GC_DISP_REFCLK_400; | ||
644 | |||
645 | ver = inreg(host, GC_CID); | ||
646 | rev = inreg(pio, GC_REVISION); | ||
647 | if ((ver == 0x303) && (rev & 0xffffff00) == 0x20050100) { | ||
648 | dev_info(par->dev, "Fujitsu Lime v1.%d found\n", | ||
649 | (int)rev & 0xff); | ||
650 | par->type = BT_LIME; | ||
651 | ccf = par->gc_mode ? par->gc_mode->ccf : GC_CCF_COT_100; | ||
652 | mmr = par->gc_mode ? par->gc_mode->mmr : 0x414fb7f2; | ||
653 | } else { | ||
654 | dev_info(par->dev, "? GDC, CID/Rev.: 0x%lx/0x%lx \n", ver, rev); | ||
655 | return -ENODEV; | ||
656 | } | ||
657 | |||
658 | if (!par->pre_init) { | ||
659 | outreg(host, GC_CCF, ccf); | ||
660 | udelay(200); | ||
661 | outreg(host, GC_MMR, mmr); | ||
662 | udelay(10); | ||
663 | } | ||
664 | |||
665 | /* interrupt status */ | ||
666 | outreg(host, GC_IST, 0); | ||
667 | outreg(host, GC_IMASK, GC_INT_EN); | ||
668 | return 0; | ||
669 | } | ||
670 | |||
671 | static int of_platform_mb862xx_probe(struct platform_device *ofdev) | ||
672 | { | ||
673 | struct device_node *np = ofdev->dev.of_node; | ||
674 | struct device *dev = &ofdev->dev; | ||
675 | struct mb862xxfb_par *par; | ||
676 | struct fb_info *info; | ||
677 | struct resource res; | ||
678 | resource_size_t res_size; | ||
679 | unsigned long ret = -ENODEV; | ||
680 | |||
681 | if (of_address_to_resource(np, 0, &res)) { | ||
682 | dev_err(dev, "Invalid address\n"); | ||
683 | return -ENXIO; | ||
684 | } | ||
685 | |||
686 | info = framebuffer_alloc(sizeof(struct mb862xxfb_par), dev); | ||
687 | if (info == NULL) { | ||
688 | dev_err(dev, "cannot allocate framebuffer\n"); | ||
689 | return -ENOMEM; | ||
690 | } | ||
691 | |||
692 | par = info->par; | ||
693 | par->info = info; | ||
694 | par->dev = dev; | ||
695 | |||
696 | par->irq = irq_of_parse_and_map(np, 0); | ||
697 | if (par->irq == NO_IRQ) { | ||
698 | dev_err(dev, "failed to map irq\n"); | ||
699 | ret = -ENODEV; | ||
700 | goto fbrel; | ||
701 | } | ||
702 | |||
703 | res_size = resource_size(&res); | ||
704 | par->res = request_mem_region(res.start, res_size, DRV_NAME); | ||
705 | if (par->res == NULL) { | ||
706 | dev_err(dev, "Cannot claim framebuffer/mmio\n"); | ||
707 | ret = -ENXIO; | ||
708 | goto irqdisp; | ||
709 | } | ||
710 | |||
711 | #if defined(CONFIG_SOCRATES) | ||
712 | par->gc_mode = &socrates_gc_mode; | ||
713 | #endif | ||
714 | |||
715 | par->fb_base_phys = res.start; | ||
716 | par->mmio_base_phys = res.start + MB862XX_MMIO_BASE; | ||
717 | par->mmio_len = MB862XX_MMIO_SIZE; | ||
718 | if (par->gc_mode) | ||
719 | par->mapped_vram = par->gc_mode->max_vram; | ||
720 | else | ||
721 | par->mapped_vram = MB862XX_MEM_SIZE; | ||
722 | |||
723 | par->fb_base = ioremap(par->fb_base_phys, par->mapped_vram); | ||
724 | if (par->fb_base == NULL) { | ||
725 | dev_err(dev, "Cannot map framebuffer\n"); | ||
726 | goto rel_reg; | ||
727 | } | ||
728 | |||
729 | par->mmio_base = ioremap(par->mmio_base_phys, par->mmio_len); | ||
730 | if (par->mmio_base == NULL) { | ||
731 | dev_err(dev, "Cannot map registers\n"); | ||
732 | goto fb_unmap; | ||
733 | } | ||
734 | |||
735 | dev_dbg(dev, "fb phys 0x%llx 0x%lx\n", | ||
736 | (u64)par->fb_base_phys, (ulong)par->mapped_vram); | ||
737 | dev_dbg(dev, "mmio phys 0x%llx 0x%lx, (irq = %d)\n", | ||
738 | (u64)par->mmio_base_phys, (ulong)par->mmio_len, par->irq); | ||
739 | |||
740 | if (mb862xx_gdc_init(par)) | ||
741 | goto io_unmap; | ||
742 | |||
743 | if (request_irq(par->irq, mb862xx_intr, 0, | ||
744 | DRV_NAME, (void *)par)) { | ||
745 | dev_err(dev, "Cannot request irq\n"); | ||
746 | goto io_unmap; | ||
747 | } | ||
748 | |||
749 | mb862xxfb_init_fbinfo(info); | ||
750 | |||
751 | if (fb_alloc_cmap(&info->cmap, NR_PALETTE, 0) < 0) { | ||
752 | dev_err(dev, "Could not allocate cmap for fb_info.\n"); | ||
753 | goto free_irq; | ||
754 | } | ||
755 | |||
756 | if ((info->fbops->fb_set_par)(info)) | ||
757 | dev_err(dev, "set_var() failed on initial setup?\n"); | ||
758 | |||
759 | if (register_framebuffer(info)) { | ||
760 | dev_err(dev, "failed to register framebuffer\n"); | ||
761 | goto rel_cmap; | ||
762 | } | ||
763 | |||
764 | dev_set_drvdata(dev, info); | ||
765 | |||
766 | if (device_create_file(dev, &dev_attr_dispregs)) | ||
767 | dev_err(dev, "Can't create sysfs regdump file\n"); | ||
768 | return 0; | ||
769 | |||
770 | rel_cmap: | ||
771 | fb_dealloc_cmap(&info->cmap); | ||
772 | free_irq: | ||
773 | outreg(host, GC_IMASK, 0); | ||
774 | free_irq(par->irq, (void *)par); | ||
775 | io_unmap: | ||
776 | iounmap(par->mmio_base); | ||
777 | fb_unmap: | ||
778 | iounmap(par->fb_base); | ||
779 | rel_reg: | ||
780 | release_mem_region(res.start, res_size); | ||
781 | irqdisp: | ||
782 | irq_dispose_mapping(par->irq); | ||
783 | fbrel: | ||
784 | framebuffer_release(info); | ||
785 | return ret; | ||
786 | } | ||
787 | |||
788 | static int of_platform_mb862xx_remove(struct platform_device *ofdev) | ||
789 | { | ||
790 | struct fb_info *fbi = dev_get_drvdata(&ofdev->dev); | ||
791 | struct mb862xxfb_par *par = fbi->par; | ||
792 | resource_size_t res_size = resource_size(par->res); | ||
793 | unsigned long reg; | ||
794 | |||
795 | dev_dbg(fbi->dev, "%s release\n", fbi->fix.id); | ||
796 | |||
797 | /* display off */ | ||
798 | reg = inreg(disp, GC_DCM1); | ||
799 | reg &= ~(GC_DCM01_DEN | GC_DCM01_L0E); | ||
800 | outreg(disp, GC_DCM1, reg); | ||
801 | |||
802 | /* disable interrupts */ | ||
803 | outreg(host, GC_IMASK, 0); | ||
804 | |||
805 | free_irq(par->irq, (void *)par); | ||
806 | irq_dispose_mapping(par->irq); | ||
807 | |||
808 | device_remove_file(&ofdev->dev, &dev_attr_dispregs); | ||
809 | |||
810 | unregister_framebuffer(fbi); | ||
811 | fb_dealloc_cmap(&fbi->cmap); | ||
812 | |||
813 | iounmap(par->mmio_base); | ||
814 | iounmap(par->fb_base); | ||
815 | |||
816 | release_mem_region(par->res->start, res_size); | ||
817 | framebuffer_release(fbi); | ||
818 | return 0; | ||
819 | } | ||
820 | |||
821 | /* | ||
822 | * common types | ||
823 | */ | ||
824 | static struct of_device_id of_platform_mb862xx_tbl[] = { | ||
825 | { .compatible = "fujitsu,MB86276", }, | ||
826 | { .compatible = "fujitsu,lime", }, | ||
827 | { .compatible = "fujitsu,MB86277", }, | ||
828 | { .compatible = "fujitsu,mint", }, | ||
829 | { .compatible = "fujitsu,MB86293", }, | ||
830 | { .compatible = "fujitsu,MB86294", }, | ||
831 | { .compatible = "fujitsu,coral", }, | ||
832 | { /* end */ } | ||
833 | }; | ||
834 | |||
835 | static struct platform_driver of_platform_mb862xxfb_driver = { | ||
836 | .driver = { | ||
837 | .name = DRV_NAME, | ||
838 | .owner = THIS_MODULE, | ||
839 | .of_match_table = of_platform_mb862xx_tbl, | ||
840 | }, | ||
841 | .probe = of_platform_mb862xx_probe, | ||
842 | .remove = of_platform_mb862xx_remove, | ||
843 | }; | ||
844 | #endif | ||
845 | |||
846 | #if defined(CONFIG_FB_MB862XX_PCI_GDC) | ||
847 | static int coralp_init(struct mb862xxfb_par *par) | ||
848 | { | ||
849 | int cn, ver; | ||
850 | |||
851 | par->host = par->mmio_base; | ||
852 | par->i2c = par->mmio_base + MB862XX_I2C_BASE; | ||
853 | par->disp = par->mmio_base + MB862XX_DISP_BASE; | ||
854 | par->cap = par->mmio_base + MB862XX_CAP_BASE; | ||
855 | par->draw = par->mmio_base + MB862XX_DRAW_BASE; | ||
856 | par->geo = par->mmio_base + MB862XX_GEO_BASE; | ||
857 | par->pio = par->mmio_base + MB862XX_PIO_BASE; | ||
858 | |||
859 | par->refclk = GC_DISP_REFCLK_400; | ||
860 | |||
861 | if (par->mapped_vram >= 0x2000000) { | ||
862 | /* relocate gdc registers space */ | ||
863 | writel(1, par->fb_base + MB862XX_MMIO_BASE + GC_RSW); | ||
864 | udelay(1); /* wait at least 20 bus cycles */ | ||
865 | } | ||
866 | |||
867 | ver = inreg(host, GC_CID); | ||
868 | cn = (ver & GC_CID_CNAME_MSK) >> 8; | ||
869 | ver = ver & GC_CID_VERSION_MSK; | ||
870 | if (cn == 3) { | ||
871 | unsigned long reg; | ||
872 | |||
873 | dev_info(par->dev, "Fujitsu Coral-%s GDC Rev.%d found\n",\ | ||
874 | (ver == 6) ? "P" : (ver == 8) ? "PA" : "?", | ||
875 | par->pdev->revision); | ||
876 | reg = inreg(disp, GC_DCM1); | ||
877 | if (reg & GC_DCM01_DEN && reg & GC_DCM01_L0E) | ||
878 | par->pre_init = 1; | ||
879 | |||
880 | if (!par->pre_init) { | ||
881 | outreg(host, GC_CCF, GC_CCF_CGE_166 | GC_CCF_COT_133); | ||
882 | udelay(200); | ||
883 | outreg(host, GC_MMR, GC_MMR_CORALP_EVB_VAL); | ||
884 | udelay(10); | ||
885 | } | ||
886 | /* Clear interrupt status */ | ||
887 | outreg(host, GC_IST, 0); | ||
888 | } else { | ||
889 | return -ENODEV; | ||
890 | } | ||
891 | |||
892 | mb862xx_i2c_init(par); | ||
893 | return 0; | ||
894 | } | ||
895 | |||
896 | static int init_dram_ctrl(struct mb862xxfb_par *par) | ||
897 | { | ||
898 | unsigned long i = 0; | ||
899 | |||
900 | /* | ||
901 | * Set io mode first! Spec. says IC may be destroyed | ||
902 | * if not set to SSTL2/LVCMOS before init. | ||
903 | */ | ||
904 | outreg(dram_ctrl, GC_DCTL_IOCONT1_IOCONT0, GC_EVB_DCTL_IOCONT1_IOCONT0); | ||
905 | |||
906 | /* DRAM init */ | ||
907 | outreg(dram_ctrl, GC_DCTL_MODE_ADD, GC_EVB_DCTL_MODE_ADD); | ||
908 | outreg(dram_ctrl, GC_DCTL_SETTIME1_EMODE, GC_EVB_DCTL_SETTIME1_EMODE); | ||
909 | outreg(dram_ctrl, GC_DCTL_REFRESH_SETTIME2, | ||
910 | GC_EVB_DCTL_REFRESH_SETTIME2); | ||
911 | outreg(dram_ctrl, GC_DCTL_RSV2_RSV1, GC_EVB_DCTL_RSV2_RSV1); | ||
912 | outreg(dram_ctrl, GC_DCTL_DDRIF2_DDRIF1, GC_EVB_DCTL_DDRIF2_DDRIF1); | ||
913 | outreg(dram_ctrl, GC_DCTL_RSV0_STATES, GC_EVB_DCTL_RSV0_STATES); | ||
914 | |||
915 | /* DLL reset done? */ | ||
916 | while ((inreg(dram_ctrl, GC_DCTL_RSV0_STATES) & GC_DCTL_STATES_MSK)) { | ||
917 | udelay(GC_DCTL_INIT_WAIT_INTERVAL); | ||
918 | if (i++ > GC_DCTL_INIT_WAIT_CNT) { | ||
919 | dev_err(par->dev, "VRAM init failed.\n"); | ||
920 | return -EINVAL; | ||
921 | } | ||
922 | } | ||
923 | outreg(dram_ctrl, GC_DCTL_MODE_ADD, GC_EVB_DCTL_MODE_ADD_AFT_RST); | ||
924 | outreg(dram_ctrl, GC_DCTL_RSV0_STATES, GC_EVB_DCTL_RSV0_STATES_AFT_RST); | ||
925 | return 0; | ||
926 | } | ||
927 | |||
928 | static int carmine_init(struct mb862xxfb_par *par) | ||
929 | { | ||
930 | unsigned long reg; | ||
931 | |||
932 | par->ctrl = par->mmio_base + MB86297_CTRL_BASE; | ||
933 | par->i2c = par->mmio_base + MB86297_I2C_BASE; | ||
934 | par->disp = par->mmio_base + MB86297_DISP0_BASE; | ||
935 | par->disp1 = par->mmio_base + MB86297_DISP1_BASE; | ||
936 | par->cap = par->mmio_base + MB86297_CAP0_BASE; | ||
937 | par->cap1 = par->mmio_base + MB86297_CAP1_BASE; | ||
938 | par->draw = par->mmio_base + MB86297_DRAW_BASE; | ||
939 | par->dram_ctrl = par->mmio_base + MB86297_DRAMCTRL_BASE; | ||
940 | par->wrback = par->mmio_base + MB86297_WRBACK_BASE; | ||
941 | |||
942 | par->refclk = GC_DISP_REFCLK_533; | ||
943 | |||
944 | /* warm up */ | ||
945 | reg = GC_CTRL_CLK_EN_DRAM | GC_CTRL_CLK_EN_2D3D | GC_CTRL_CLK_EN_DISP0; | ||
946 | outreg(ctrl, GC_CTRL_CLK_ENABLE, reg); | ||
947 | |||
948 | /* check for engine module revision */ | ||
949 | if (inreg(draw, GC_2D3D_REV) == GC_RE_REVISION) | ||
950 | dev_info(par->dev, "Fujitsu Carmine GDC Rev.%d found\n", | ||
951 | par->pdev->revision); | ||
952 | else | ||
953 | goto err_init; | ||
954 | |||
955 | reg &= ~GC_CTRL_CLK_EN_2D3D; | ||
956 | outreg(ctrl, GC_CTRL_CLK_ENABLE, reg); | ||
957 | |||
958 | /* set up vram */ | ||
959 | if (init_dram_ctrl(par) < 0) | ||
960 | goto err_init; | ||
961 | |||
962 | outreg(ctrl, GC_CTRL_INT_MASK, 0); | ||
963 | return 0; | ||
964 | |||
965 | err_init: | ||
966 | outreg(ctrl, GC_CTRL_CLK_ENABLE, 0); | ||
967 | return -EINVAL; | ||
968 | } | ||
969 | |||
970 | static inline int mb862xx_pci_gdc_init(struct mb862xxfb_par *par) | ||
971 | { | ||
972 | switch (par->type) { | ||
973 | case BT_CORALP: | ||
974 | return coralp_init(par); | ||
975 | case BT_CARMINE: | ||
976 | return carmine_init(par); | ||
977 | default: | ||
978 | return -ENODEV; | ||
979 | } | ||
980 | } | ||
981 | |||
982 | #define CHIP_ID(id) \ | ||
983 | { PCI_DEVICE(PCI_VENDOR_ID_FUJITSU_LIMITED, id) } | ||
984 | |||
985 | static struct pci_device_id mb862xx_pci_tbl[] = { | ||
986 | /* MB86295/MB86296 */ | ||
987 | CHIP_ID(PCI_DEVICE_ID_FUJITSU_CORALP), | ||
988 | CHIP_ID(PCI_DEVICE_ID_FUJITSU_CORALPA), | ||
989 | /* MB86297 */ | ||
990 | CHIP_ID(PCI_DEVICE_ID_FUJITSU_CARMINE), | ||
991 | { 0, } | ||
992 | }; | ||
993 | |||
994 | MODULE_DEVICE_TABLE(pci, mb862xx_pci_tbl); | ||
995 | |||
996 | static int mb862xx_pci_probe(struct pci_dev *pdev, | ||
997 | const struct pci_device_id *ent) | ||
998 | { | ||
999 | struct mb862xxfb_par *par; | ||
1000 | struct fb_info *info; | ||
1001 | struct device *dev = &pdev->dev; | ||
1002 | int ret; | ||
1003 | |||
1004 | ret = pci_enable_device(pdev); | ||
1005 | if (ret < 0) { | ||
1006 | dev_err(dev, "Cannot enable PCI device\n"); | ||
1007 | goto out; | ||
1008 | } | ||
1009 | |||
1010 | info = framebuffer_alloc(sizeof(struct mb862xxfb_par), dev); | ||
1011 | if (!info) { | ||
1012 | dev_err(dev, "framebuffer alloc failed\n"); | ||
1013 | ret = -ENOMEM; | ||
1014 | goto dis_dev; | ||
1015 | } | ||
1016 | |||
1017 | par = info->par; | ||
1018 | par->info = info; | ||
1019 | par->dev = dev; | ||
1020 | par->pdev = pdev; | ||
1021 | par->irq = pdev->irq; | ||
1022 | |||
1023 | ret = pci_request_regions(pdev, DRV_NAME); | ||
1024 | if (ret < 0) { | ||
1025 | dev_err(dev, "Cannot reserve region(s) for PCI device\n"); | ||
1026 | goto rel_fb; | ||
1027 | } | ||
1028 | |||
1029 | switch (pdev->device) { | ||
1030 | case PCI_DEVICE_ID_FUJITSU_CORALP: | ||
1031 | case PCI_DEVICE_ID_FUJITSU_CORALPA: | ||
1032 | par->fb_base_phys = pci_resource_start(par->pdev, 0); | ||
1033 | par->mapped_vram = CORALP_MEM_SIZE; | ||
1034 | if (par->mapped_vram >= 0x2000000) { | ||
1035 | par->mmio_base_phys = par->fb_base_phys + | ||
1036 | MB862XX_MMIO_HIGH_BASE; | ||
1037 | } else { | ||
1038 | par->mmio_base_phys = par->fb_base_phys + | ||
1039 | MB862XX_MMIO_BASE; | ||
1040 | } | ||
1041 | par->mmio_len = MB862XX_MMIO_SIZE; | ||
1042 | par->type = BT_CORALP; | ||
1043 | break; | ||
1044 | case PCI_DEVICE_ID_FUJITSU_CARMINE: | ||
1045 | par->fb_base_phys = pci_resource_start(par->pdev, 2); | ||
1046 | par->mmio_base_phys = pci_resource_start(par->pdev, 3); | ||
1047 | par->mmio_len = pci_resource_len(par->pdev, 3); | ||
1048 | par->mapped_vram = CARMINE_MEM_SIZE; | ||
1049 | par->type = BT_CARMINE; | ||
1050 | break; | ||
1051 | default: | ||
1052 | /* should never occur */ | ||
1053 | ret = -EIO; | ||
1054 | goto rel_reg; | ||
1055 | } | ||
1056 | |||
1057 | par->fb_base = ioremap(par->fb_base_phys, par->mapped_vram); | ||
1058 | if (par->fb_base == NULL) { | ||
1059 | dev_err(dev, "Cannot map framebuffer\n"); | ||
1060 | ret = -EIO; | ||
1061 | goto rel_reg; | ||
1062 | } | ||
1063 | |||
1064 | par->mmio_base = ioremap(par->mmio_base_phys, par->mmio_len); | ||
1065 | if (par->mmio_base == NULL) { | ||
1066 | dev_err(dev, "Cannot map registers\n"); | ||
1067 | ret = -EIO; | ||
1068 | goto fb_unmap; | ||
1069 | } | ||
1070 | |||
1071 | dev_dbg(dev, "fb phys 0x%llx 0x%lx\n", | ||
1072 | (unsigned long long)par->fb_base_phys, (ulong)par->mapped_vram); | ||
1073 | dev_dbg(dev, "mmio phys 0x%llx 0x%lx\n", | ||
1074 | (unsigned long long)par->mmio_base_phys, (ulong)par->mmio_len); | ||
1075 | |||
1076 | ret = mb862xx_pci_gdc_init(par); | ||
1077 | if (ret) | ||
1078 | goto io_unmap; | ||
1079 | |||
1080 | ret = request_irq(par->irq, mb862xx_intr, IRQF_SHARED, | ||
1081 | DRV_NAME, (void *)par); | ||
1082 | if (ret) { | ||
1083 | dev_err(dev, "Cannot request irq\n"); | ||
1084 | goto io_unmap; | ||
1085 | } | ||
1086 | |||
1087 | mb862xxfb_init_fbinfo(info); | ||
1088 | |||
1089 | if (fb_alloc_cmap(&info->cmap, NR_PALETTE, 0) < 0) { | ||
1090 | dev_err(dev, "Could not allocate cmap for fb_info.\n"); | ||
1091 | ret = -ENOMEM; | ||
1092 | goto free_irq; | ||
1093 | } | ||
1094 | |||
1095 | if ((info->fbops->fb_set_par)(info)) | ||
1096 | dev_err(dev, "set_var() failed on initial setup?\n"); | ||
1097 | |||
1098 | ret = register_framebuffer(info); | ||
1099 | if (ret < 0) { | ||
1100 | dev_err(dev, "failed to register framebuffer\n"); | ||
1101 | goto rel_cmap; | ||
1102 | } | ||
1103 | |||
1104 | pci_set_drvdata(pdev, info); | ||
1105 | |||
1106 | if (device_create_file(dev, &dev_attr_dispregs)) | ||
1107 | dev_err(dev, "Can't create sysfs regdump file\n"); | ||
1108 | |||
1109 | if (par->type == BT_CARMINE) | ||
1110 | outreg(ctrl, GC_CTRL_INT_MASK, GC_CARMINE_INT_EN); | ||
1111 | else | ||
1112 | outreg(host, GC_IMASK, GC_INT_EN); | ||
1113 | |||
1114 | return 0; | ||
1115 | |||
1116 | rel_cmap: | ||
1117 | fb_dealloc_cmap(&info->cmap); | ||
1118 | free_irq: | ||
1119 | free_irq(par->irq, (void *)par); | ||
1120 | io_unmap: | ||
1121 | iounmap(par->mmio_base); | ||
1122 | fb_unmap: | ||
1123 | iounmap(par->fb_base); | ||
1124 | rel_reg: | ||
1125 | pci_release_regions(pdev); | ||
1126 | rel_fb: | ||
1127 | framebuffer_release(info); | ||
1128 | dis_dev: | ||
1129 | pci_disable_device(pdev); | ||
1130 | out: | ||
1131 | return ret; | ||
1132 | } | ||
1133 | |||
1134 | static void mb862xx_pci_remove(struct pci_dev *pdev) | ||
1135 | { | ||
1136 | struct fb_info *fbi = pci_get_drvdata(pdev); | ||
1137 | struct mb862xxfb_par *par = fbi->par; | ||
1138 | unsigned long reg; | ||
1139 | |||
1140 | dev_dbg(fbi->dev, "%s release\n", fbi->fix.id); | ||
1141 | |||
1142 | /* display off */ | ||
1143 | reg = inreg(disp, GC_DCM1); | ||
1144 | reg &= ~(GC_DCM01_DEN | GC_DCM01_L0E); | ||
1145 | outreg(disp, GC_DCM1, reg); | ||
1146 | |||
1147 | if (par->type == BT_CARMINE) { | ||
1148 | outreg(ctrl, GC_CTRL_INT_MASK, 0); | ||
1149 | outreg(ctrl, GC_CTRL_CLK_ENABLE, 0); | ||
1150 | } else { | ||
1151 | outreg(host, GC_IMASK, 0); | ||
1152 | } | ||
1153 | |||
1154 | mb862xx_i2c_exit(par); | ||
1155 | |||
1156 | device_remove_file(&pdev->dev, &dev_attr_dispregs); | ||
1157 | |||
1158 | unregister_framebuffer(fbi); | ||
1159 | fb_dealloc_cmap(&fbi->cmap); | ||
1160 | |||
1161 | free_irq(par->irq, (void *)par); | ||
1162 | iounmap(par->mmio_base); | ||
1163 | iounmap(par->fb_base); | ||
1164 | |||
1165 | pci_release_regions(pdev); | ||
1166 | framebuffer_release(fbi); | ||
1167 | pci_disable_device(pdev); | ||
1168 | } | ||
1169 | |||
1170 | static struct pci_driver mb862xxfb_pci_driver = { | ||
1171 | .name = DRV_NAME, | ||
1172 | .id_table = mb862xx_pci_tbl, | ||
1173 | .probe = mb862xx_pci_probe, | ||
1174 | .remove = mb862xx_pci_remove, | ||
1175 | }; | ||
1176 | #endif | ||
1177 | |||
1178 | static int mb862xxfb_init(void) | ||
1179 | { | ||
1180 | int ret = -ENODEV; | ||
1181 | |||
1182 | #if defined(CONFIG_FB_MB862XX_LIME) | ||
1183 | ret = platform_driver_register(&of_platform_mb862xxfb_driver); | ||
1184 | #endif | ||
1185 | #if defined(CONFIG_FB_MB862XX_PCI_GDC) | ||
1186 | ret = pci_register_driver(&mb862xxfb_pci_driver); | ||
1187 | #endif | ||
1188 | return ret; | ||
1189 | } | ||
1190 | |||
1191 | static void __exit mb862xxfb_exit(void) | ||
1192 | { | ||
1193 | #if defined(CONFIG_FB_MB862XX_LIME) | ||
1194 | platform_driver_unregister(&of_platform_mb862xxfb_driver); | ||
1195 | #endif | ||
1196 | #if defined(CONFIG_FB_MB862XX_PCI_GDC) | ||
1197 | pci_unregister_driver(&mb862xxfb_pci_driver); | ||
1198 | #endif | ||
1199 | } | ||
1200 | |||
1201 | module_init(mb862xxfb_init); | ||
1202 | module_exit(mb862xxfb_exit); | ||
1203 | |||
1204 | MODULE_DESCRIPTION("Fujitsu MB862xx Framebuffer driver"); | ||
1205 | MODULE_AUTHOR("Anatolij Gustschin <agust@denx.de>"); | ||
1206 | MODULE_LICENSE("GPL v2"); | ||