aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/video/Kconfig20
-rw-r--r--drivers/video/Makefile2
-rw-r--r--drivers/video/mx3fb.c2300
3 files changed, 1161 insertions, 1161 deletions
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
index 330204a61ea8..41c27a44bd82 100644
--- a/drivers/video/Kconfig
+++ b/drivers/video/Kconfig
@@ -2120,16 +2120,16 @@ config FB_PRE_INIT_FB
2120 the bootloader. 2120 the bootloader.
2121 2121
2122config FB_MX3 2122config FB_MX3
2123 tristate "MX3 Framebuffer support" 2123 tristate "MX3 Framebuffer support"
2124 depends on FB && MX3_IPU 2124 depends on FB && MX3_IPU
2125 select FB_CFB_FILLRECT 2125 select FB_CFB_FILLRECT
2126 select FB_CFB_COPYAREA 2126 select FB_CFB_COPYAREA
2127 select FB_CFB_IMAGEBLIT 2127 select FB_CFB_IMAGEBLIT
2128 default y 2128 default y
2129 help 2129 help
2130 This is a framebuffer device for the i.MX31 LCD Controller. So 2130 This is a framebuffer device for the i.MX31 LCD Controller. So
2131 far only synchronous displays are supported. If you plan to use 2131 far only synchronous displays are supported. If you plan to use
2132 an LCD display with your i.MX31 system, say Y here. 2132 an LCD display with your i.MX31 system, say Y here.
2133 2133
2134config FB_BROADSHEET 2134config FB_BROADSHEET
2135 tristate "E-Ink Broadsheet/Epson S1D13521 controller support" 2135 tristate "E-Ink Broadsheet/Epson S1D13521 controller support"
diff --git a/drivers/video/Makefile b/drivers/video/Makefile
index edd5a85c1eb5..bb265eca7d57 100644
--- a/drivers/video/Makefile
+++ b/drivers/video/Makefile
@@ -133,7 +133,7 @@ obj-$(CONFIG_FB_VGA16) += vga16fb.o
133obj-$(CONFIG_FB_OF) += offb.o 133obj-$(CONFIG_FB_OF) += offb.o
134obj-$(CONFIG_FB_BF54X_LQ043) += bf54x-lq043fb.o 134obj-$(CONFIG_FB_BF54X_LQ043) += bf54x-lq043fb.o
135obj-$(CONFIG_FB_BFIN_T350MCQB) += bfin-t350mcqb-fb.o 135obj-$(CONFIG_FB_BFIN_T350MCQB) += bfin-t350mcqb-fb.o
136obj-$(CONFIG_FB_MX3) += mx3fb.o 136obj-$(CONFIG_FB_MX3) += mx3fb.o
137 137
138# the test framebuffer is last 138# the test framebuffer is last
139obj-$(CONFIG_FB_VIRTUAL) += vfb.o 139obj-$(CONFIG_FB_VIRTUAL) += vfb.o
diff --git a/drivers/video/mx3fb.c b/drivers/video/mx3fb.c
index 0c27961e47f2..fa1a512ce030 100644
--- a/drivers/video/mx3fb.c
+++ b/drivers/video/mx3fb.c
@@ -34,240 +34,240 @@
34#include <asm/io.h> 34#include <asm/io.h>
35#include <asm/uaccess.h> 35#include <asm/uaccess.h>
36 36
37#define MX3FB_NAME "mx3_sdc_fb" 37#define MX3FB_NAME "mx3_sdc_fb"
38 38
39#define MX3FB_REG_OFFSET 0xB4 39#define MX3FB_REG_OFFSET 0xB4
40 40
41/* SDC Registers */ 41/* SDC Registers */
42#define SDC_COM_CONF (0xB4 - MX3FB_REG_OFFSET) 42#define SDC_COM_CONF (0xB4 - MX3FB_REG_OFFSET)
43#define SDC_GW_CTRL (0xB8 - MX3FB_REG_OFFSET) 43#define SDC_GW_CTRL (0xB8 - MX3FB_REG_OFFSET)
44#define SDC_FG_POS (0xBC - MX3FB_REG_OFFSET) 44#define SDC_FG_POS (0xBC - MX3FB_REG_OFFSET)
45#define SDC_BG_POS (0xC0 - MX3FB_REG_OFFSET) 45#define SDC_BG_POS (0xC0 - MX3FB_REG_OFFSET)
46#define SDC_CUR_POS (0xC4 - MX3FB_REG_OFFSET) 46#define SDC_CUR_POS (0xC4 - MX3FB_REG_OFFSET)
47#define SDC_PWM_CTRL (0xC8 - MX3FB_REG_OFFSET) 47#define SDC_PWM_CTRL (0xC8 - MX3FB_REG_OFFSET)
48#define SDC_CUR_MAP (0xCC - MX3FB_REG_OFFSET) 48#define SDC_CUR_MAP (0xCC - MX3FB_REG_OFFSET)
49#define SDC_HOR_CONF (0xD0 - MX3FB_REG_OFFSET) 49#define SDC_HOR_CONF (0xD0 - MX3FB_REG_OFFSET)
50#define SDC_VER_CONF (0xD4 - MX3FB_REG_OFFSET) 50#define SDC_VER_CONF (0xD4 - MX3FB_REG_OFFSET)
51#define SDC_SHARP_CONF_1 (0xD8 - MX3FB_REG_OFFSET) 51#define SDC_SHARP_CONF_1 (0xD8 - MX3FB_REG_OFFSET)
52#define SDC_SHARP_CONF_2 (0xDC - MX3FB_REG_OFFSET) 52#define SDC_SHARP_CONF_2 (0xDC - MX3FB_REG_OFFSET)
53 53
54/* Register bits */ 54/* Register bits */
55#define SDC_COM_TFT_COLOR 0x00000001UL 55#define SDC_COM_TFT_COLOR 0x00000001UL
56#define SDC_COM_FG_EN 0x00000010UL 56#define SDC_COM_FG_EN 0x00000010UL
57#define SDC_COM_GWSEL 0x00000020UL 57#define SDC_COM_GWSEL 0x00000020UL
58#define SDC_COM_GLB_A 0x00000040UL 58#define SDC_COM_GLB_A 0x00000040UL
59#define SDC_COM_KEY_COLOR_G 0x00000080UL 59#define SDC_COM_KEY_COLOR_G 0x00000080UL
60#define SDC_COM_BG_EN 0x00000200UL 60#define SDC_COM_BG_EN 0x00000200UL
61#define SDC_COM_SHARP 0x00001000UL 61#define SDC_COM_SHARP 0x00001000UL
62 62
63#define SDC_V_SYNC_WIDTH_L 0x00000001UL 63#define SDC_V_SYNC_WIDTH_L 0x00000001UL
64 64
65/* Display Interface registers */ 65/* Display Interface registers */
66#define DI_DISP_IF_CONF (0x0124 - MX3FB_REG_OFFSET) 66#define DI_DISP_IF_CONF (0x0124 - MX3FB_REG_OFFSET)
67#define DI_DISP_SIG_POL (0x0128 - MX3FB_REG_OFFSET) 67#define DI_DISP_SIG_POL (0x0128 - MX3FB_REG_OFFSET)
68#define DI_SER_DISP1_CONF (0x012C - MX3FB_REG_OFFSET) 68#define DI_SER_DISP1_CONF (0x012C - MX3FB_REG_OFFSET)
69#define DI_SER_DISP2_CONF (0x0130 - MX3FB_REG_OFFSET) 69#define DI_SER_DISP2_CONF (0x0130 - MX3FB_REG_OFFSET)
70#define DI_HSP_CLK_PER (0x0134 - MX3FB_REG_OFFSET) 70#define DI_HSP_CLK_PER (0x0134 - MX3FB_REG_OFFSET)
71#define DI_DISP0_TIME_CONF_1 (0x0138 - MX3FB_REG_OFFSET) 71#define DI_DISP0_TIME_CONF_1 (0x0138 - MX3FB_REG_OFFSET)
72#define DI_DISP0_TIME_CONF_2 (0x013C - MX3FB_REG_OFFSET) 72#define DI_DISP0_TIME_CONF_2 (0x013C - MX3FB_REG_OFFSET)
73#define DI_DISP0_TIME_CONF_3 (0x0140 - MX3FB_REG_OFFSET) 73#define DI_DISP0_TIME_CONF_3 (0x0140 - MX3FB_REG_OFFSET)
74#define DI_DISP1_TIME_CONF_1 (0x0144 - MX3FB_REG_OFFSET) 74#define DI_DISP1_TIME_CONF_1 (0x0144 - MX3FB_REG_OFFSET)
75#define DI_DISP1_TIME_CONF_2 (0x0148 - MX3FB_REG_OFFSET) 75#define DI_DISP1_TIME_CONF_2 (0x0148 - MX3FB_REG_OFFSET)
76#define DI_DISP1_TIME_CONF_3 (0x014C - MX3FB_REG_OFFSET) 76#define DI_DISP1_TIME_CONF_3 (0x014C - MX3FB_REG_OFFSET)
77#define DI_DISP2_TIME_CONF_1 (0x0150 - MX3FB_REG_OFFSET) 77#define DI_DISP2_TIME_CONF_1 (0x0150 - MX3FB_REG_OFFSET)
78#define DI_DISP2_TIME_CONF_2 (0x0154 - MX3FB_REG_OFFSET) 78#define DI_DISP2_TIME_CONF_2 (0x0154 - MX3FB_REG_OFFSET)
79#define DI_DISP2_TIME_CONF_3 (0x0158 - MX3FB_REG_OFFSET) 79#define DI_DISP2_TIME_CONF_3 (0x0158 - MX3FB_REG_OFFSET)
80#define DI_DISP3_TIME_CONF (0x015C - MX3FB_REG_OFFSET) 80#define DI_DISP3_TIME_CONF (0x015C - MX3FB_REG_OFFSET)
81#define DI_DISP0_DB0_MAP (0x0160 - MX3FB_REG_OFFSET) 81#define DI_DISP0_DB0_MAP (0x0160 - MX3FB_REG_OFFSET)
82#define DI_DISP0_DB1_MAP (0x0164 - MX3FB_REG_OFFSET) 82#define DI_DISP0_DB1_MAP (0x0164 - MX3FB_REG_OFFSET)
83#define DI_DISP0_DB2_MAP (0x0168 - MX3FB_REG_OFFSET) 83#define DI_DISP0_DB2_MAP (0x0168 - MX3FB_REG_OFFSET)
84#define DI_DISP0_CB0_MAP (0x016C - MX3FB_REG_OFFSET) 84#define DI_DISP0_CB0_MAP (0x016C - MX3FB_REG_OFFSET)
85#define DI_DISP0_CB1_MAP (0x0170 - MX3FB_REG_OFFSET) 85#define DI_DISP0_CB1_MAP (0x0170 - MX3FB_REG_OFFSET)
86#define DI_DISP0_CB2_MAP (0x0174 - MX3FB_REG_OFFSET) 86#define DI_DISP0_CB2_MAP (0x0174 - MX3FB_REG_OFFSET)
87#define DI_DISP1_DB0_MAP (0x0178 - MX3FB_REG_OFFSET) 87#define DI_DISP1_DB0_MAP (0x0178 - MX3FB_REG_OFFSET)
88#define DI_DISP1_DB1_MAP (0x017C - MX3FB_REG_OFFSET) 88#define DI_DISP1_DB1_MAP (0x017C - MX3FB_REG_OFFSET)
89#define DI_DISP1_DB2_MAP (0x0180 - MX3FB_REG_OFFSET) 89#define DI_DISP1_DB2_MAP (0x0180 - MX3FB_REG_OFFSET)
90#define DI_DISP1_CB0_MAP (0x0184 - MX3FB_REG_OFFSET) 90#define DI_DISP1_CB0_MAP (0x0184 - MX3FB_REG_OFFSET)
91#define DI_DISP1_CB1_MAP (0x0188 - MX3FB_REG_OFFSET) 91#define DI_DISP1_CB1_MAP (0x0188 - MX3FB_REG_OFFSET)
92#define DI_DISP1_CB2_MAP (0x018C - MX3FB_REG_OFFSET) 92#define DI_DISP1_CB2_MAP (0x018C - MX3FB_REG_OFFSET)
93#define DI_DISP2_DB0_MAP (0x0190 - MX3FB_REG_OFFSET) 93#define DI_DISP2_DB0_MAP (0x0190 - MX3FB_REG_OFFSET)
94#define DI_DISP2_DB1_MAP (0x0194 - MX3FB_REG_OFFSET) 94#define DI_DISP2_DB1_MAP (0x0194 - MX3FB_REG_OFFSET)
95#define DI_DISP2_DB2_MAP (0x0198 - MX3FB_REG_OFFSET) 95#define DI_DISP2_DB2_MAP (0x0198 - MX3FB_REG_OFFSET)
96#define DI_DISP2_CB0_MAP (0x019C - MX3FB_REG_OFFSET) 96#define DI_DISP2_CB0_MAP (0x019C - MX3FB_REG_OFFSET)
97#define DI_DISP2_CB1_MAP (0x01A0 - MX3FB_REG_OFFSET) 97#define DI_DISP2_CB1_MAP (0x01A0 - MX3FB_REG_OFFSET)
98#define DI_DISP2_CB2_MAP (0x01A4 - MX3FB_REG_OFFSET) 98#define DI_DISP2_CB2_MAP (0x01A4 - MX3FB_REG_OFFSET)
99#define DI_DISP3_B0_MAP (0x01A8 - MX3FB_REG_OFFSET) 99#define DI_DISP3_B0_MAP (0x01A8 - MX3FB_REG_OFFSET)
100#define DI_DISP3_B1_MAP (0x01AC - MX3FB_REG_OFFSET) 100#define DI_DISP3_B1_MAP (0x01AC - MX3FB_REG_OFFSET)
101#define DI_DISP3_B2_MAP (0x01B0 - MX3FB_REG_OFFSET) 101#define DI_DISP3_B2_MAP (0x01B0 - MX3FB_REG_OFFSET)
102#define DI_DISP_ACC_CC (0x01B4 - MX3FB_REG_OFFSET) 102#define DI_DISP_ACC_CC (0x01B4 - MX3FB_REG_OFFSET)
103#define DI_DISP_LLA_CONF (0x01B8 - MX3FB_REG_OFFSET) 103#define DI_DISP_LLA_CONF (0x01B8 - MX3FB_REG_OFFSET)
104#define DI_DISP_LLA_DATA (0x01BC - MX3FB_REG_OFFSET) 104#define DI_DISP_LLA_DATA (0x01BC - MX3FB_REG_OFFSET)
105 105
106/* DI_DISP_SIG_POL bits */ 106/* DI_DISP_SIG_POL bits */
107#define DI_D3_VSYNC_POL_SHIFT 28 107#define DI_D3_VSYNC_POL_SHIFT 28
108#define DI_D3_HSYNC_POL_SHIFT 27 108#define DI_D3_HSYNC_POL_SHIFT 27
109#define DI_D3_DRDY_SHARP_POL_SHIFT 26 109#define DI_D3_DRDY_SHARP_POL_SHIFT 26
110#define DI_D3_CLK_POL_SHIFT 25 110#define DI_D3_CLK_POL_SHIFT 25
111#define DI_D3_DATA_POL_SHIFT 24 111#define DI_D3_DATA_POL_SHIFT 24
112 112
113/* DI_DISP_IF_CONF bits */ 113/* DI_DISP_IF_CONF bits */
114#define DI_D3_CLK_IDLE_SHIFT 26 114#define DI_D3_CLK_IDLE_SHIFT 26
115#define DI_D3_CLK_SEL_SHIFT 25 115#define DI_D3_CLK_SEL_SHIFT 25
116#define DI_D3_DATAMSK_SHIFT 24 116#define DI_D3_DATAMSK_SHIFT 24
117 117
118enum ipu_panel { 118enum ipu_panel {
119 IPU_PANEL_SHARP_TFT, 119 IPU_PANEL_SHARP_TFT,
120 IPU_PANEL_TFT, 120 IPU_PANEL_TFT,
121}; 121};
122 122
123struct ipu_di_signal_cfg { 123struct ipu_di_signal_cfg {
124 unsigned datamask_en:1; 124 unsigned datamask_en:1;
125 unsigned clksel_en:1; 125 unsigned clksel_en:1;
126 unsigned clkidle_en:1; 126 unsigned clkidle_en:1;
127 unsigned data_pol:1; /* true = inverted */ 127 unsigned data_pol:1; /* true = inverted */
128 unsigned clk_pol:1; /* true = rising edge */ 128 unsigned clk_pol:1; /* true = rising edge */
129 unsigned enable_pol:1; 129 unsigned enable_pol:1;
130 unsigned Hsync_pol:1; /* true = active high */ 130 unsigned Hsync_pol:1; /* true = active high */
131 unsigned Vsync_pol:1; 131 unsigned Vsync_pol:1;
132}; 132};
133 133
134static const struct fb_videomode mx3fb_modedb[] = { 134static const struct fb_videomode mx3fb_modedb[] = {
135 { 135 {
136 /* 240x320 @ 60 Hz */ 136 /* 240x320 @ 60 Hz */
137 .name = "Sharp-QVGA", 137 .name = "Sharp-QVGA",
138 .refresh = 60, 138 .refresh = 60,
139 .xres = 240, 139 .xres = 240,
140 .yres = 320, 140 .yres = 320,
141 .pixclock = 185925, 141 .pixclock = 185925,
142 .left_margin = 9, 142 .left_margin = 9,
143 .right_margin = 16, 143 .right_margin = 16,
144 .upper_margin = 7, 144 .upper_margin = 7,
145 .lower_margin = 9, 145 .lower_margin = 9,
146 .hsync_len = 1, 146 .hsync_len = 1,
147 .vsync_len = 1, 147 .vsync_len = 1,
148 .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_SHARP_MODE | 148 .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_SHARP_MODE |
149 FB_SYNC_CLK_INVERT | FB_SYNC_DATA_INVERT | 149 FB_SYNC_CLK_INVERT | FB_SYNC_DATA_INVERT |
150 FB_SYNC_CLK_IDLE_EN, 150 FB_SYNC_CLK_IDLE_EN,
151 .vmode = FB_VMODE_NONINTERLACED, 151 .vmode = FB_VMODE_NONINTERLACED,
152 .flag = 0, 152 .flag = 0,
153 }, { 153 }, {
154 /* 240x33 @ 60 Hz */ 154 /* 240x33 @ 60 Hz */
155 .name = "Sharp-CLI", 155 .name = "Sharp-CLI",
156 .refresh = 60, 156 .refresh = 60,
157 .xres = 240, 157 .xres = 240,
158 .yres = 33, 158 .yres = 33,
159 .pixclock = 185925, 159 .pixclock = 185925,
160 .left_margin = 9, 160 .left_margin = 9,
161 .right_margin = 16, 161 .right_margin = 16,
162 .upper_margin = 7, 162 .upper_margin = 7,
163 .lower_margin = 9 + 287, 163 .lower_margin = 9 + 287,
164 .hsync_len = 1, 164 .hsync_len = 1,
165 .vsync_len = 1, 165 .vsync_len = 1,
166 .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_SHARP_MODE | 166 .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_SHARP_MODE |
167 FB_SYNC_CLK_INVERT | FB_SYNC_DATA_INVERT | 167 FB_SYNC_CLK_INVERT | FB_SYNC_DATA_INVERT |
168 FB_SYNC_CLK_IDLE_EN, 168 FB_SYNC_CLK_IDLE_EN,
169 .vmode = FB_VMODE_NONINTERLACED, 169 .vmode = FB_VMODE_NONINTERLACED,
170 .flag = 0, 170 .flag = 0,
171 }, { 171 }, {
172 /* 640x480 @ 60 Hz */ 172 /* 640x480 @ 60 Hz */
173 .name = "NEC-VGA", 173 .name = "NEC-VGA",
174 .refresh = 60, 174 .refresh = 60,
175 .xres = 640, 175 .xres = 640,
176 .yres = 480, 176 .yres = 480,
177 .pixclock = 38255, 177 .pixclock = 38255,
178 .left_margin = 144, 178 .left_margin = 144,
179 .right_margin = 0, 179 .right_margin = 0,
180 .upper_margin = 34, 180 .upper_margin = 34,
181 .lower_margin = 40, 181 .lower_margin = 40,
182 .hsync_len = 1, 182 .hsync_len = 1,
183 .vsync_len = 1, 183 .vsync_len = 1,
184 .sync = FB_SYNC_VERT_HIGH_ACT | FB_SYNC_OE_ACT_HIGH, 184 .sync = FB_SYNC_VERT_HIGH_ACT | FB_SYNC_OE_ACT_HIGH,
185 .vmode = FB_VMODE_NONINTERLACED, 185 .vmode = FB_VMODE_NONINTERLACED,
186 .flag = 0, 186 .flag = 0,
187 }, { 187 }, {
188 /* NTSC TV output */ 188 /* NTSC TV output */
189 .name = "TV-NTSC", 189 .name = "TV-NTSC",
190 .refresh = 60, 190 .refresh = 60,
191 .xres = 640, 191 .xres = 640,
192 .yres = 480, 192 .yres = 480,
193 .pixclock = 37538, 193 .pixclock = 37538,
194 .left_margin = 38, 194 .left_margin = 38,
195 .right_margin = 858 - 640 - 38 - 3, 195 .right_margin = 858 - 640 - 38 - 3,
196 .upper_margin = 36, 196 .upper_margin = 36,
197 .lower_margin = 518 - 480 - 36 - 1, 197 .lower_margin = 518 - 480 - 36 - 1,
198 .hsync_len = 3, 198 .hsync_len = 3,
199 .vsync_len = 1, 199 .vsync_len = 1,
200 .sync = 0, 200 .sync = 0,
201 .vmode = FB_VMODE_NONINTERLACED, 201 .vmode = FB_VMODE_NONINTERLACED,
202 .flag = 0, 202 .flag = 0,
203 }, { 203 }, {
204 /* PAL TV output */ 204 /* PAL TV output */
205 .name = "TV-PAL", 205 .name = "TV-PAL",
206 .refresh = 50, 206 .refresh = 50,
207 .xres = 640, 207 .xres = 640,
208 .yres = 480, 208 .yres = 480,
209 .pixclock = 37538, 209 .pixclock = 37538,
210 .left_margin = 38, 210 .left_margin = 38,
211 .right_margin = 960 - 640 - 38 - 32, 211 .right_margin = 960 - 640 - 38 - 32,
212 .upper_margin = 32, 212 .upper_margin = 32,
213 .lower_margin = 555 - 480 - 32 - 3, 213 .lower_margin = 555 - 480 - 32 - 3,
214 .hsync_len = 32, 214 .hsync_len = 32,
215 .vsync_len = 3, 215 .vsync_len = 3,
216 .sync = 0, 216 .sync = 0,
217 .vmode = FB_VMODE_NONINTERLACED, 217 .vmode = FB_VMODE_NONINTERLACED,
218 .flag = 0, 218 .flag = 0,
219 }, { 219 }, {
220 /* TV output VGA mode, 640x480 @ 65 Hz */ 220 /* TV output VGA mode, 640x480 @ 65 Hz */
221 .name = "TV-VGA", 221 .name = "TV-VGA",
222 .refresh = 60, 222 .refresh = 60,
223 .xres = 640, 223 .xres = 640,
224 .yres = 480, 224 .yres = 480,
225 .pixclock = 40574, 225 .pixclock = 40574,
226 .left_margin = 35, 226 .left_margin = 35,
227 .right_margin = 45, 227 .right_margin = 45,
228 .upper_margin = 9, 228 .upper_margin = 9,
229 .lower_margin = 1, 229 .lower_margin = 1,
230 .hsync_len = 46, 230 .hsync_len = 46,
231 .vsync_len = 5, 231 .vsync_len = 5,
232 .sync = 0, 232 .sync = 0,
233 .vmode = FB_VMODE_NONINTERLACED, 233 .vmode = FB_VMODE_NONINTERLACED,
234 .flag = 0, 234 .flag = 0,
235 }, 235 },
236}; 236};
237 237
238struct mx3fb_data { 238struct mx3fb_data {
239 struct fb_info *fbi; 239 struct fb_info *fbi;
240 int backlight_level; 240 int backlight_level;
241 void __iomem *reg_base; 241 void __iomem *reg_base;
242 spinlock_t lock; 242 spinlock_t lock;
243 struct device *dev; 243 struct device *dev;
244 244
245 uint32_t h_start_width; 245 uint32_t h_start_width;
246 uint32_t v_start_width; 246 uint32_t v_start_width;
247}; 247};
248 248
249struct dma_chan_request { 249struct dma_chan_request {
250 struct mx3fb_data *mx3fb; 250 struct mx3fb_data *mx3fb;
251 enum ipu_channel id; 251 enum ipu_channel id;
252}; 252};
253 253
254/* MX3 specific framebuffer information. */ 254/* MX3 specific framebuffer information. */
255struct mx3fb_info { 255struct mx3fb_info {
256 int blank; 256 int blank;
257 enum ipu_channel ipu_ch; 257 enum ipu_channel ipu_ch;
258 uint32_t cur_ipu_buf; 258 uint32_t cur_ipu_buf;
259 259
260 u32 pseudo_palette[16]; 260 u32 pseudo_palette[16];
261 261
262 struct completion flip_cmpl; 262 struct completion flip_cmpl;
263 struct mutex mutex; /* Protects fb-ops */ 263 struct mutex mutex; /* Protects fb-ops */
264 struct mx3fb_data *mx3fb; 264 struct mx3fb_data *mx3fb;
265 struct idmac_channel *idmac_channel; 265 struct idmac_channel *idmac_channel;
266 struct dma_async_tx_descriptor *txd; 266 struct dma_async_tx_descriptor *txd;
267 dma_cookie_t cookie; 267 dma_cookie_t cookie;
268 struct scatterlist sg[2]; 268 struct scatterlist sg[2];
269 269
270 u32 sync; /* preserve var->sync flags */ 270 u32 sync; /* preserve var->sync flags */
271}; 271};
272 272
273static void mx3fb_dma_done(void *); 273static void mx3fb_dma_done(void *);
@@ -278,389 +278,389 @@ static unsigned long default_bpp = 16;
278 278
279static u32 mx3fb_read_reg(struct mx3fb_data *mx3fb, unsigned long reg) 279static u32 mx3fb_read_reg(struct mx3fb_data *mx3fb, unsigned long reg)
280{ 280{
281 return __raw_readl(mx3fb->reg_base + reg); 281 return __raw_readl(mx3fb->reg_base + reg);
282} 282}
283 283
284static void mx3fb_write_reg(struct mx3fb_data *mx3fb, u32 value, unsigned long reg) 284static void mx3fb_write_reg(struct mx3fb_data *mx3fb, u32 value, unsigned long reg)
285{ 285{
286 __raw_writel(value, mx3fb->reg_base + reg); 286 __raw_writel(value, mx3fb->reg_base + reg);
287} 287}
288 288
289static const uint32_t di_mappings[] = { 289static const uint32_t di_mappings[] = {
290 0x1600AAAA, 0x00E05555, 0x00070000, 3, /* RGB888 */ 290 0x1600AAAA, 0x00E05555, 0x00070000, 3, /* RGB888 */
291 0x0005000F, 0x000B000F, 0x0011000F, 1, /* RGB666 */ 291 0x0005000F, 0x000B000F, 0x0011000F, 1, /* RGB666 */
292 0x0011000F, 0x000B000F, 0x0005000F, 1, /* BGR666 */ 292 0x0011000F, 0x000B000F, 0x0005000F, 1, /* BGR666 */
293 0x0004003F, 0x000A000F, 0x000F003F, 1 /* RGB565 */ 293 0x0004003F, 0x000A000F, 0x000F003F, 1 /* RGB565 */
294}; 294};
295 295
296static void sdc_fb_init(struct mx3fb_info *fbi) 296static void sdc_fb_init(struct mx3fb_info *fbi)
297{ 297{
298 struct mx3fb_data *mx3fb = fbi->mx3fb; 298 struct mx3fb_data *mx3fb = fbi->mx3fb;
299 uint32_t reg; 299 uint32_t reg;
300 300
301 reg = mx3fb_read_reg(mx3fb, SDC_COM_CONF); 301 reg = mx3fb_read_reg(mx3fb, SDC_COM_CONF);
302 302
303 mx3fb_write_reg(mx3fb, reg | SDC_COM_BG_EN, SDC_COM_CONF); 303 mx3fb_write_reg(mx3fb, reg | SDC_COM_BG_EN, SDC_COM_CONF);
304} 304}
305 305
306/* Returns enabled flag before uninit */ 306/* Returns enabled flag before uninit */
307static uint32_t sdc_fb_uninit(struct mx3fb_info *fbi) 307static uint32_t sdc_fb_uninit(struct mx3fb_info *fbi)
308{ 308{
309 struct mx3fb_data *mx3fb = fbi->mx3fb; 309 struct mx3fb_data *mx3fb = fbi->mx3fb;
310 uint32_t reg; 310 uint32_t reg;
311 311
312 reg = mx3fb_read_reg(mx3fb, SDC_COM_CONF); 312 reg = mx3fb_read_reg(mx3fb, SDC_COM_CONF);
313 313
314 mx3fb_write_reg(mx3fb, reg & ~SDC_COM_BG_EN, SDC_COM_CONF); 314 mx3fb_write_reg(mx3fb, reg & ~SDC_COM_BG_EN, SDC_COM_CONF);
315 315
316 return reg & SDC_COM_BG_EN; 316 return reg & SDC_COM_BG_EN;
317} 317}
318 318
319static void sdc_enable_channel(struct mx3fb_info *mx3_fbi) 319static void sdc_enable_channel(struct mx3fb_info *mx3_fbi)
320{ 320{
321 struct mx3fb_data *mx3fb = mx3_fbi->mx3fb; 321 struct mx3fb_data *mx3fb = mx3_fbi->mx3fb;
322 struct idmac_channel *ichan = mx3_fbi->idmac_channel; 322 struct idmac_channel *ichan = mx3_fbi->idmac_channel;
323 struct dma_chan *dma_chan = &ichan->dma_chan; 323 struct dma_chan *dma_chan = &ichan->dma_chan;
324 unsigned long flags; 324 unsigned long flags;
325 dma_cookie_t cookie; 325 dma_cookie_t cookie;
326 326
327 dev_dbg(mx3fb->dev, "mx3fbi %p, desc %p, sg %p\n", mx3_fbi, 327 dev_dbg(mx3fb->dev, "mx3fbi %p, desc %p, sg %p\n", mx3_fbi,
328 to_tx_desc(mx3_fbi->txd), to_tx_desc(mx3_fbi->txd)->sg); 328 to_tx_desc(mx3_fbi->txd), to_tx_desc(mx3_fbi->txd)->sg);
329 329
330 /* This enables the channel */ 330 /* This enables the channel */
331 if (mx3_fbi->cookie < 0) { 331 if (mx3_fbi->cookie < 0) {
332 mx3_fbi->txd = dma_chan->device->device_prep_slave_sg(dma_chan, 332 mx3_fbi->txd = dma_chan->device->device_prep_slave_sg(dma_chan,
333 &mx3_fbi->sg[0], 1, DMA_TO_DEVICE, DMA_PREP_INTERRUPT); 333 &mx3_fbi->sg[0], 1, DMA_TO_DEVICE, DMA_PREP_INTERRUPT);
334 if (!mx3_fbi->txd) { 334 if (!mx3_fbi->txd) {
335 dev_err(mx3fb->dev, "Cannot allocate descriptor on %d\n", 335 dev_err(mx3fb->dev, "Cannot allocate descriptor on %d\n",
336 dma_chan->chan_id); 336 dma_chan->chan_id);
337 return; 337 return;
338 } 338 }
339 339
340 mx3_fbi->txd->callback_param = mx3_fbi->txd; 340 mx3_fbi->txd->callback_param = mx3_fbi->txd;
341 mx3_fbi->txd->callback = mx3fb_dma_done; 341 mx3_fbi->txd->callback = mx3fb_dma_done;
342 342
343 cookie = mx3_fbi->txd->tx_submit(mx3_fbi->txd); 343 cookie = mx3_fbi->txd->tx_submit(mx3_fbi->txd);
344 dev_dbg(mx3fb->dev, "%d: Submit %p #%d [%c]\n", __LINE__, 344 dev_dbg(mx3fb->dev, "%d: Submit %p #%d [%c]\n", __LINE__,
345 mx3_fbi->txd, cookie, list_empty(&ichan->queue) ? '-' : '+'); 345 mx3_fbi->txd, cookie, list_empty(&ichan->queue) ? '-' : '+');
346 } else { 346 } else {
347 if (!mx3_fbi->txd || !mx3_fbi->txd->tx_submit) { 347 if (!mx3_fbi->txd || !mx3_fbi->txd->tx_submit) {
348 dev_err(mx3fb->dev, "Cannot enable channel %d\n", 348 dev_err(mx3fb->dev, "Cannot enable channel %d\n",
349 dma_chan->chan_id); 349 dma_chan->chan_id);
350 return; 350 return;
351 } 351 }
352 352
353 /* Just re-activate the same buffer */ 353 /* Just re-activate the same buffer */
354 dma_async_issue_pending(dma_chan); 354 dma_async_issue_pending(dma_chan);
355 cookie = mx3_fbi->cookie; 355 cookie = mx3_fbi->cookie;
356 dev_dbg(mx3fb->dev, "%d: Re-submit %p #%d [%c]\n", __LINE__, 356 dev_dbg(mx3fb->dev, "%d: Re-submit %p #%d [%c]\n", __LINE__,
357 mx3_fbi->txd, cookie, list_empty(&ichan->queue) ? '-' : '+'); 357 mx3_fbi->txd, cookie, list_empty(&ichan->queue) ? '-' : '+');
358 } 358 }
359 359
360 if (cookie >= 0) { 360 if (cookie >= 0) {
361 spin_lock_irqsave(&mx3fb->lock, flags); 361 spin_lock_irqsave(&mx3fb->lock, flags);
362 sdc_fb_init(mx3_fbi); 362 sdc_fb_init(mx3_fbi);
363 mx3_fbi->cookie = cookie; 363 mx3_fbi->cookie = cookie;
364 spin_unlock_irqrestore(&mx3fb->lock, flags); 364 spin_unlock_irqrestore(&mx3fb->lock, flags);
365 } 365 }
366 366
367 /* 367 /*
368 * Attention! Without this msleep the channel keeps generating 368 * Attention! Without this msleep the channel keeps generating
369 * interrupts. Next sdc_set_brightness() is going to be called 369 * interrupts. Next sdc_set_brightness() is going to be called
370 * from mx3fb_blank(). 370 * from mx3fb_blank().
371 */ 371 */
372 msleep(2); 372 msleep(2);
373} 373}
374 374
375static void sdc_disable_channel(struct mx3fb_info *mx3_fbi) 375static void sdc_disable_channel(struct mx3fb_info *mx3_fbi)
376{ 376{
377 struct mx3fb_data *mx3fb = mx3_fbi->mx3fb; 377 struct mx3fb_data *mx3fb = mx3_fbi->mx3fb;
378 uint32_t enabled; 378 uint32_t enabled;
379 unsigned long flags; 379 unsigned long flags;
380 380
381 spin_lock_irqsave(&mx3fb->lock, flags); 381 spin_lock_irqsave(&mx3fb->lock, flags);
382 382
383 enabled = sdc_fb_uninit(mx3_fbi); 383 enabled = sdc_fb_uninit(mx3_fbi);
384 384
385 spin_unlock_irqrestore(&mx3fb->lock, flags); 385 spin_unlock_irqrestore(&mx3fb->lock, flags);
386 386
387 mx3_fbi->txd->chan->device->device_terminate_all(mx3_fbi->txd->chan); 387 mx3_fbi->txd->chan->device->device_terminate_all(mx3_fbi->txd->chan);
388 mx3_fbi->txd = NULL; 388 mx3_fbi->txd = NULL;
389 mx3_fbi->cookie = -EINVAL; 389 mx3_fbi->cookie = -EINVAL;
390} 390}
391 391
392/** 392/**
393 * sdc_set_window_pos() - set window position of the respective plane. 393 * sdc_set_window_pos() - set window position of the respective plane.
394 * @mx3fb: mx3fb context. 394 * @mx3fb: mx3fb context.
395 * @channel: IPU DMAC channel ID. 395 * @channel: IPU DMAC channel ID.
396 * @x_pos: X coordinate relative to the top left corner to place window at. 396 * @x_pos: X coordinate relative to the top left corner to place window at.
397 * @y_pos: Y coordinate relative to the top left corner to place window at. 397 * @y_pos: Y coordinate relative to the top left corner to place window at.
398 * @return: 0 on success or negative error code on failure. 398 * @return: 0 on success or negative error code on failure.
399 */ 399 */
400static int sdc_set_window_pos(struct mx3fb_data *mx3fb, enum ipu_channel channel, 400static int sdc_set_window_pos(struct mx3fb_data *mx3fb, enum ipu_channel channel,
401 int16_t x_pos, int16_t y_pos) 401 int16_t x_pos, int16_t y_pos)
402{ 402{
403 x_pos += mx3fb->h_start_width; 403 x_pos += mx3fb->h_start_width;
404 y_pos += mx3fb->v_start_width; 404 y_pos += mx3fb->v_start_width;
405 405
406 if (channel != IDMAC_SDC_0) 406 if (channel != IDMAC_SDC_0)
407 return -EINVAL; 407 return -EINVAL;
408 408
409 mx3fb_write_reg(mx3fb, (x_pos << 16) | y_pos, SDC_BG_POS); 409 mx3fb_write_reg(mx3fb, (x_pos << 16) | y_pos, SDC_BG_POS);
410 return 0; 410 return 0;
411} 411}
412 412
413/** 413/**
414 * sdc_init_panel() - initialize a synchronous LCD panel. 414 * sdc_init_panel() - initialize a synchronous LCD panel.
415 * @mx3fb: mx3fb context. 415 * @mx3fb: mx3fb context.
416 * @panel: panel type. 416 * @panel: panel type.
417 * @pixel_clk: desired pixel clock frequency in Hz. 417 * @pixel_clk: desired pixel clock frequency in Hz.
418 * @width: width of panel in pixels. 418 * @width: width of panel in pixels.
419 * @height: height of panel in pixels. 419 * @height: height of panel in pixels.
420 * @pixel_fmt: pixel format of buffer as FOURCC ASCII code. 420 * @pixel_fmt: pixel format of buffer as FOURCC ASCII code.
421 * @h_start_width: number of pixel clocks between the HSYNC signal pulse 421 * @h_start_width: number of pixel clocks between the HSYNC signal pulse
422 * and the start of valid data. 422 * and the start of valid data.
423 * @h_sync_width: width of the HSYNC signal in units of pixel clocks. 423 * @h_sync_width: width of the HSYNC signal in units of pixel clocks.
424 * @h_end_width: number of pixel clocks between the end of valid data 424 * @h_end_width: number of pixel clocks between the end of valid data
425 * and the HSYNC signal for next line. 425 * and the HSYNC signal for next line.
426 * @v_start_width: number of lines between the VSYNC signal pulse and the 426 * @v_start_width: number of lines between the VSYNC signal pulse and the
427 * start of valid data. 427 * start of valid data.
428 * @v_sync_width: width of the VSYNC signal in units of lines 428 * @v_sync_width: width of the VSYNC signal in units of lines
429 * @v_end_width: number of lines between the end of valid data and the 429 * @v_end_width: number of lines between the end of valid data and the
430 * VSYNC signal for next frame. 430 * VSYNC signal for next frame.
431 * @sig: bitfield of signal polarities for LCD interface. 431 * @sig: bitfield of signal polarities for LCD interface.
432 * @return: 0 on success or negative error code on failure. 432 * @return: 0 on success or negative error code on failure.
433 */ 433 */
434static int sdc_init_panel(struct mx3fb_data *mx3fb, enum ipu_panel panel, 434static int sdc_init_panel(struct mx3fb_data *mx3fb, enum ipu_panel panel,
435 uint32_t pixel_clk, 435 uint32_t pixel_clk,
436 uint16_t width, uint16_t height, 436 uint16_t width, uint16_t height,
437 enum pixel_fmt pixel_fmt, 437 enum pixel_fmt pixel_fmt,
438 uint16_t h_start_width, uint16_t h_sync_width, 438 uint16_t h_start_width, uint16_t h_sync_width,
439 uint16_t h_end_width, uint16_t v_start_width, 439 uint16_t h_end_width, uint16_t v_start_width,
440 uint16_t v_sync_width, uint16_t v_end_width, 440 uint16_t v_sync_width, uint16_t v_end_width,
441 struct ipu_di_signal_cfg sig) 441 struct ipu_di_signal_cfg sig)
442{ 442{
443 unsigned long lock_flags; 443 unsigned long lock_flags;
444 uint32_t reg; 444 uint32_t reg;
445 uint32_t old_conf; 445 uint32_t old_conf;
446 uint32_t div; 446 uint32_t div;
447 struct clk *ipu_clk; 447 struct clk *ipu_clk;
448 448
449 dev_dbg(mx3fb->dev, "panel size = %d x %d", width, height); 449 dev_dbg(mx3fb->dev, "panel size = %d x %d", width, height);
450 450
451 if (v_sync_width == 0 || h_sync_width == 0) 451 if (v_sync_width == 0 || h_sync_width == 0)
452 return -EINVAL; 452 return -EINVAL;
453 453
454 /* Init panel size and blanking periods */ 454 /* Init panel size and blanking periods */
455 reg = ((uint32_t) (h_sync_width - 1) << 26) | 455 reg = ((uint32_t) (h_sync_width - 1) << 26) |
456 ((uint32_t) (width + h_start_width + h_end_width - 1) << 16); 456 ((uint32_t) (width + h_start_width + h_end_width - 1) << 16);
457 mx3fb_write_reg(mx3fb, reg, SDC_HOR_CONF); 457 mx3fb_write_reg(mx3fb, reg, SDC_HOR_CONF);
458 458
459#ifdef DEBUG 459#ifdef DEBUG
460 printk(KERN_CONT " hor_conf %x,", reg); 460 printk(KERN_CONT " hor_conf %x,", reg);
461#endif 461#endif
462 462
463 reg = ((uint32_t) (v_sync_width - 1) << 26) | SDC_V_SYNC_WIDTH_L | 463 reg = ((uint32_t) (v_sync_width - 1) << 26) | SDC_V_SYNC_WIDTH_L |
464 ((uint32_t) (height + v_start_width + v_end_width - 1) << 16); 464 ((uint32_t) (height + v_start_width + v_end_width - 1) << 16);
465 mx3fb_write_reg(mx3fb, reg, SDC_VER_CONF); 465 mx3fb_write_reg(mx3fb, reg, SDC_VER_CONF);
466 466
467#ifdef DEBUG 467#ifdef DEBUG
468 printk(KERN_CONT " ver_conf %x\n", reg); 468 printk(KERN_CONT " ver_conf %x\n", reg);
469#endif 469#endif
470 470
471 mx3fb->h_start_width = h_start_width; 471 mx3fb->h_start_width = h_start_width;
472 mx3fb->v_start_width = v_start_width; 472 mx3fb->v_start_width = v_start_width;
473 473
474 switch (panel) { 474 switch (panel) {
475 case IPU_PANEL_SHARP_TFT: 475 case IPU_PANEL_SHARP_TFT:
476 mx3fb_write_reg(mx3fb, 0x00FD0102L, SDC_SHARP_CONF_1); 476 mx3fb_write_reg(mx3fb, 0x00FD0102L, SDC_SHARP_CONF_1);
477 mx3fb_write_reg(mx3fb, 0x00F500F4L, SDC_SHARP_CONF_2); 477 mx3fb_write_reg(mx3fb, 0x00F500F4L, SDC_SHARP_CONF_2);
478 mx3fb_write_reg(mx3fb, SDC_COM_SHARP | SDC_COM_TFT_COLOR, SDC_COM_CONF); 478 mx3fb_write_reg(mx3fb, SDC_COM_SHARP | SDC_COM_TFT_COLOR, SDC_COM_CONF);
479 break; 479 break;
480 case IPU_PANEL_TFT: 480 case IPU_PANEL_TFT:
481 mx3fb_write_reg(mx3fb, SDC_COM_TFT_COLOR, SDC_COM_CONF); 481 mx3fb_write_reg(mx3fb, SDC_COM_TFT_COLOR, SDC_COM_CONF);
482 break; 482 break;
483 default: 483 default:
484 return -EINVAL; 484 return -EINVAL;
485 } 485 }
486 486
487 /* Init clocking */ 487 /* Init clocking */
488 488
489 /* 489 /*
490 * Calculate divider: fractional part is 4 bits so simply multiple by 490 * Calculate divider: fractional part is 4 bits so simply multiple by
491 * 24 to get fractional part, as long as we stay under ~250MHz and on 491 * 2^4 to get fractional part, as long as we stay under ~250MHz and on
492 * i.MX31 it (HSP_CLK) is <= 178MHz. Currently 128.267MHz 492 * i.MX31 it (HSP_CLK) is <= 178MHz. Currently 128.267MHz
493 */ 493 */
494 dev_dbg(mx3fb->dev, "pixel clk = %d\n", pixel_clk); 494 dev_dbg(mx3fb->dev, "pixel clk = %d\n", pixel_clk);
495 495
496 ipu_clk = clk_get(mx3fb->dev, NULL); 496 ipu_clk = clk_get(mx3fb->dev, NULL);
497 div = clk_get_rate(ipu_clk) * 16 / pixel_clk; 497 div = clk_get_rate(ipu_clk) * 16 / pixel_clk;
498 clk_put(ipu_clk); 498 clk_put(ipu_clk);
499 499
500 if (div < 0x40) { /* Divider less than 4 */ 500 if (div < 0x40) { /* Divider less than 4 */
501 dev_dbg(mx3fb->dev, 501 dev_dbg(mx3fb->dev,
502 "InitPanel() - Pixel clock divider less than 4\n"); 502 "InitPanel() - Pixel clock divider less than 4\n");
503 div = 0x40; 503 div = 0x40;
504 } 504 }
505 505
506 spin_lock_irqsave(&mx3fb->lock, lock_flags); 506 spin_lock_irqsave(&mx3fb->lock, lock_flags);
507 507
508 /* 508 /*
509 * DISP3_IF_CLK_DOWN_WR is half the divider value and 2 fraction bits 509 * DISP3_IF_CLK_DOWN_WR is half the divider value and 2 fraction bits
510 * fewer. Subtract 1 extra from DISP3_IF_CLK_DOWN_WR based on timing 510 * fewer. Subtract 1 extra from DISP3_IF_CLK_DOWN_WR based on timing
511 * debug. DISP3_IF_CLK_UP_WR is 0 511 * debug. DISP3_IF_CLK_UP_WR is 0
512 */ 512 */
513 mx3fb_write_reg(mx3fb, (((div / 8) - 1) << 22) | div, DI_DISP3_TIME_CONF); 513 mx3fb_write_reg(mx3fb, (((div / 8) - 1) << 22) | div, DI_DISP3_TIME_CONF);
514 514
515 /* DI settings */ 515 /* DI settings */
516 old_conf = mx3fb_read_reg(mx3fb, DI_DISP_IF_CONF) & 0x78FFFFFF; 516 old_conf = mx3fb_read_reg(mx3fb, DI_DISP_IF_CONF) & 0x78FFFFFF;
517 old_conf |= sig.datamask_en << DI_D3_DATAMSK_SHIFT | 517 old_conf |= sig.datamask_en << DI_D3_DATAMSK_SHIFT |
518 sig.clksel_en << DI_D3_CLK_SEL_SHIFT | 518 sig.clksel_en << DI_D3_CLK_SEL_SHIFT |
519 sig.clkidle_en << DI_D3_CLK_IDLE_SHIFT; 519 sig.clkidle_en << DI_D3_CLK_IDLE_SHIFT;
520 mx3fb_write_reg(mx3fb, old_conf, DI_DISP_IF_CONF); 520 mx3fb_write_reg(mx3fb, old_conf, DI_DISP_IF_CONF);
521 521
522 old_conf = mx3fb_read_reg(mx3fb, DI_DISP_SIG_POL) & 0xE0FFFFFF; 522 old_conf = mx3fb_read_reg(mx3fb, DI_DISP_SIG_POL) & 0xE0FFFFFF;
523 old_conf |= sig.data_pol << DI_D3_DATA_POL_SHIFT | 523 old_conf |= sig.data_pol << DI_D3_DATA_POL_SHIFT |
524 sig.clk_pol << DI_D3_CLK_POL_SHIFT | 524 sig.clk_pol << DI_D3_CLK_POL_SHIFT |
525 sig.enable_pol << DI_D3_DRDY_SHARP_POL_SHIFT | 525 sig.enable_pol << DI_D3_DRDY_SHARP_POL_SHIFT |
526 sig.Hsync_pol << DI_D3_HSYNC_POL_SHIFT | 526 sig.Hsync_pol << DI_D3_HSYNC_POL_SHIFT |
527 sig.Vsync_pol << DI_D3_VSYNC_POL_SHIFT; 527 sig.Vsync_pol << DI_D3_VSYNC_POL_SHIFT;
528 mx3fb_write_reg(mx3fb, old_conf, DI_DISP_SIG_POL); 528 mx3fb_write_reg(mx3fb, old_conf, DI_DISP_SIG_POL);
529 529
530 switch (pixel_fmt) { 530 switch (pixel_fmt) {
531 case IPU_PIX_FMT_RGB24: 531 case IPU_PIX_FMT_RGB24:
532 mx3fb_write_reg(mx3fb, di_mappings[0], DI_DISP3_B0_MAP); 532 mx3fb_write_reg(mx3fb, di_mappings[0], DI_DISP3_B0_MAP);
533 mx3fb_write_reg(mx3fb, di_mappings[1], DI_DISP3_B1_MAP); 533 mx3fb_write_reg(mx3fb, di_mappings[1], DI_DISP3_B1_MAP);
534 mx3fb_write_reg(mx3fb, di_mappings[2], DI_DISP3_B2_MAP); 534 mx3fb_write_reg(mx3fb, di_mappings[2], DI_DISP3_B2_MAP);
535 mx3fb_write_reg(mx3fb, mx3fb_read_reg(mx3fb, DI_DISP_ACC_CC) | 535 mx3fb_write_reg(mx3fb, mx3fb_read_reg(mx3fb, DI_DISP_ACC_CC) |
536 ((di_mappings[3] - 1) << 12), DI_DISP_ACC_CC); 536 ((di_mappings[3] - 1) << 12), DI_DISP_ACC_CC);
537 break; 537 break;
538 case IPU_PIX_FMT_RGB666: 538 case IPU_PIX_FMT_RGB666:
539 mx3fb_write_reg(mx3fb, di_mappings[4], DI_DISP3_B0_MAP); 539 mx3fb_write_reg(mx3fb, di_mappings[4], DI_DISP3_B0_MAP);
540 mx3fb_write_reg(mx3fb, di_mappings[5], DI_DISP3_B1_MAP); 540 mx3fb_write_reg(mx3fb, di_mappings[5], DI_DISP3_B1_MAP);
541 mx3fb_write_reg(mx3fb, di_mappings[6], DI_DISP3_B2_MAP); 541 mx3fb_write_reg(mx3fb, di_mappings[6], DI_DISP3_B2_MAP);
542 mx3fb_write_reg(mx3fb, mx3fb_read_reg(mx3fb, DI_DISP_ACC_CC) | 542 mx3fb_write_reg(mx3fb, mx3fb_read_reg(mx3fb, DI_DISP_ACC_CC) |
543 ((di_mappings[7] - 1) << 12), DI_DISP_ACC_CC); 543 ((di_mappings[7] - 1) << 12), DI_DISP_ACC_CC);
544 break; 544 break;
545 case IPU_PIX_FMT_BGR666: 545 case IPU_PIX_FMT_BGR666:
546 mx3fb_write_reg(mx3fb, di_mappings[8], DI_DISP3_B0_MAP); 546 mx3fb_write_reg(mx3fb, di_mappings[8], DI_DISP3_B0_MAP);
547 mx3fb_write_reg(mx3fb, di_mappings[9], DI_DISP3_B1_MAP); 547 mx3fb_write_reg(mx3fb, di_mappings[9], DI_DISP3_B1_MAP);
548 mx3fb_write_reg(mx3fb, di_mappings[10], DI_DISP3_B2_MAP); 548 mx3fb_write_reg(mx3fb, di_mappings[10], DI_DISP3_B2_MAP);
549 mx3fb_write_reg(mx3fb, mx3fb_read_reg(mx3fb, DI_DISP_ACC_CC) | 549 mx3fb_write_reg(mx3fb, mx3fb_read_reg(mx3fb, DI_DISP_ACC_CC) |
550 ((di_mappings[11] - 1) << 12), DI_DISP_ACC_CC); 550 ((di_mappings[11] - 1) << 12), DI_DISP_ACC_CC);
551 break; 551 break;
552 default: 552 default:
553 mx3fb_write_reg(mx3fb, di_mappings[12], DI_DISP3_B0_MAP); 553 mx3fb_write_reg(mx3fb, di_mappings[12], DI_DISP3_B0_MAP);
554 mx3fb_write_reg(mx3fb, di_mappings[13], DI_DISP3_B1_MAP); 554 mx3fb_write_reg(mx3fb, di_mappings[13], DI_DISP3_B1_MAP);
555 mx3fb_write_reg(mx3fb, di_mappings[14], DI_DISP3_B2_MAP); 555 mx3fb_write_reg(mx3fb, di_mappings[14], DI_DISP3_B2_MAP);
556 mx3fb_write_reg(mx3fb, mx3fb_read_reg(mx3fb, DI_DISP_ACC_CC) | 556 mx3fb_write_reg(mx3fb, mx3fb_read_reg(mx3fb, DI_DISP_ACC_CC) |
557 ((di_mappings[15] - 1) << 12), DI_DISP_ACC_CC); 557 ((di_mappings[15] - 1) << 12), DI_DISP_ACC_CC);
558 break; 558 break;
559 } 559 }
560 560
561 spin_unlock_irqrestore(&mx3fb->lock, lock_flags); 561 spin_unlock_irqrestore(&mx3fb->lock, lock_flags);
562 562
563 dev_dbg(mx3fb->dev, "DI_DISP_IF_CONF = 0x%08X\n", 563 dev_dbg(mx3fb->dev, "DI_DISP_IF_CONF = 0x%08X\n",
564 mx3fb_read_reg(mx3fb, DI_DISP_IF_CONF)); 564 mx3fb_read_reg(mx3fb, DI_DISP_IF_CONF));
565 dev_dbg(mx3fb->dev, "DI_DISP_SIG_POL = 0x%08X\n", 565 dev_dbg(mx3fb->dev, "DI_DISP_SIG_POL = 0x%08X\n",
566 mx3fb_read_reg(mx3fb, DI_DISP_SIG_POL)); 566 mx3fb_read_reg(mx3fb, DI_DISP_SIG_POL));
567 dev_dbg(mx3fb->dev, "DI_DISP3_TIME_CONF = 0x%08X\n", 567 dev_dbg(mx3fb->dev, "DI_DISP3_TIME_CONF = 0x%08X\n",
568 mx3fb_read_reg(mx3fb, DI_DISP3_TIME_CONF)); 568 mx3fb_read_reg(mx3fb, DI_DISP3_TIME_CONF));
569 569
570 return 0; 570 return 0;
571} 571}
572 572
573/** 573/**
574 * sdc_set_color_key() - set the transparent color key for SDC graphic plane. 574 * sdc_set_color_key() - set the transparent color key for SDC graphic plane.
575 * @mx3fb: mx3fb context. 575 * @mx3fb: mx3fb context.
576 * @channel: IPU DMAC channel ID. 576 * @channel: IPU DMAC channel ID.
577 * @enable: boolean to enable or disable color keyl. 577 * @enable: boolean to enable or disable color keyl.
578 * @color_key: 24-bit RGB color to use as transparent color key. 578 * @color_key: 24-bit RGB color to use as transparent color key.
579 * @return: 0 on success or negative error code on failure. 579 * @return: 0 on success or negative error code on failure.
580 */ 580 */
581static int sdc_set_color_key(struct mx3fb_data *mx3fb, enum ipu_channel channel, 581static int sdc_set_color_key(struct mx3fb_data *mx3fb, enum ipu_channel channel,
582 bool enable, uint32_t color_key) 582 bool enable, uint32_t color_key)
583{ 583{
584 uint32_t reg, sdc_conf; 584 uint32_t reg, sdc_conf;
585 unsigned long lock_flags; 585 unsigned long lock_flags;
586 586
587 spin_lock_irqsave(&mx3fb->lock, lock_flags); 587 spin_lock_irqsave(&mx3fb->lock, lock_flags);
588 588
589 sdc_conf = mx3fb_read_reg(mx3fb, SDC_COM_CONF); 589 sdc_conf = mx3fb_read_reg(mx3fb, SDC_COM_CONF);
590 if (channel == IDMAC_SDC_0) 590 if (channel == IDMAC_SDC_0)
591 sdc_conf &= ~SDC_COM_GWSEL; 591 sdc_conf &= ~SDC_COM_GWSEL;
592 else 592 else
593 sdc_conf |= SDC_COM_GWSEL; 593 sdc_conf |= SDC_COM_GWSEL;
594 594
595 if (enable) { 595 if (enable) {
596 reg = mx3fb_read_reg(mx3fb, SDC_GW_CTRL) & 0xFF000000L; 596 reg = mx3fb_read_reg(mx3fb, SDC_GW_CTRL) & 0xFF000000L;
597 mx3fb_write_reg(mx3fb, reg | (color_key & 0x00FFFFFFL), 597 mx3fb_write_reg(mx3fb, reg | (color_key & 0x00FFFFFFL),
598 SDC_GW_CTRL); 598 SDC_GW_CTRL);
599 599
600 sdc_conf |= SDC_COM_KEY_COLOR_G; 600 sdc_conf |= SDC_COM_KEY_COLOR_G;
601 } else { 601 } else {
602 sdc_conf &= ~SDC_COM_KEY_COLOR_G; 602 sdc_conf &= ~SDC_COM_KEY_COLOR_G;
603 } 603 }
604 mx3fb_write_reg(mx3fb, sdc_conf, SDC_COM_CONF); 604 mx3fb_write_reg(mx3fb, sdc_conf, SDC_COM_CONF);
605 605
606 spin_unlock_irqrestore(&mx3fb->lock, lock_flags); 606 spin_unlock_irqrestore(&mx3fb->lock, lock_flags);
607 607
608 return 0; 608 return 0;
609} 609}
610 610
611/** 611/**
612 * sdc_set_global_alpha() - set global alpha blending modes. 612 * sdc_set_global_alpha() - set global alpha blending modes.
613 * @mx3fb: mx3fb context. 613 * @mx3fb: mx3fb context.
614 * @enable: boolean to enable or disable global alpha blending. If disabled, 614 * @enable: boolean to enable or disable global alpha blending. If disabled,
615 * per pixel blending is used. 615 * per pixel blending is used.
616 * @alpha: global alpha value. 616 * @alpha: global alpha value.
617 * @return: 0 on success or negative error code on failure. 617 * @return: 0 on success or negative error code on failure.
618 */ 618 */
619static int sdc_set_global_alpha(struct mx3fb_data *mx3fb, bool enable, uint8_t alpha) 619static int sdc_set_global_alpha(struct mx3fb_data *mx3fb, bool enable, uint8_t alpha)
620{ 620{
621 uint32_t reg; 621 uint32_t reg;
622 unsigned long lock_flags; 622 unsigned long lock_flags;
623 623
624 spin_lock_irqsave(&mx3fb->lock, lock_flags); 624 spin_lock_irqsave(&mx3fb->lock, lock_flags);
625 625
626 if (enable) { 626 if (enable) {
627 reg = mx3fb_read_reg(mx3fb, SDC_GW_CTRL) & 0x00FFFFFFL; 627 reg = mx3fb_read_reg(mx3fb, SDC_GW_CTRL) & 0x00FFFFFFL;
628 mx3fb_write_reg(mx3fb, reg | ((uint32_t) alpha << 24), SDC_GW_CTRL); 628 mx3fb_write_reg(mx3fb, reg | ((uint32_t) alpha << 24), SDC_GW_CTRL);
629 629
630 reg = mx3fb_read_reg(mx3fb, SDC_COM_CONF); 630 reg = mx3fb_read_reg(mx3fb, SDC_COM_CONF);
631 mx3fb_write_reg(mx3fb, reg | SDC_COM_GLB_A, SDC_COM_CONF); 631 mx3fb_write_reg(mx3fb, reg | SDC_COM_GLB_A, SDC_COM_CONF);
632 } else { 632 } else {
633 reg = mx3fb_read_reg(mx3fb, SDC_COM_CONF); 633 reg = mx3fb_read_reg(mx3fb, SDC_COM_CONF);
634 mx3fb_write_reg(mx3fb, reg & ~SDC_COM_GLB_A, SDC_COM_CONF); 634 mx3fb_write_reg(mx3fb, reg & ~SDC_COM_GLB_A, SDC_COM_CONF);
635 } 635 }
636 636
637 spin_unlock_irqrestore(&mx3fb->lock, lock_flags); 637 spin_unlock_irqrestore(&mx3fb->lock, lock_flags);
638 638
639 return 0; 639 return 0;
640} 640}
641 641
642static void sdc_set_brightness(struct mx3fb_data *mx3fb, uint8_t value) 642static void sdc_set_brightness(struct mx3fb_data *mx3fb, uint8_t value)
643{ 643{
644 /* This might be board-specific */ 644 /* This might be board-specific */
645 mx3fb_write_reg(mx3fb, 0x03000000UL | value << 16, SDC_PWM_CTRL); 645 mx3fb_write_reg(mx3fb, 0x03000000UL | value << 16, SDC_PWM_CTRL);
646 return; 646 return;
647} 647}
648 648
649static uint32_t bpp_to_pixfmt(int bpp) 649static uint32_t bpp_to_pixfmt(int bpp)
650{ 650{
651 uint32_t pixfmt = 0; 651 uint32_t pixfmt = 0;
652 switch (bpp) { 652 switch (bpp) {
653 case 24: 653 case 24:
654 pixfmt = IPU_PIX_FMT_BGR24; 654 pixfmt = IPU_PIX_FMT_BGR24;
655 break; 655 break;
656 case 32: 656 case 32:
657 pixfmt = IPU_PIX_FMT_BGR32; 657 pixfmt = IPU_PIX_FMT_BGR32;
658 break; 658 break;
659 case 16: 659 case 16:
660 pixfmt = IPU_PIX_FMT_RGB565; 660 pixfmt = IPU_PIX_FMT_RGB565;
661 break; 661 break;
662 } 662 }
663 return pixfmt; 663 return pixfmt;
664} 664}
665 665
666static int mx3fb_blank(int blank, struct fb_info *fbi); 666static int mx3fb_blank(int blank, struct fb_info *fbi);
@@ -669,300 +669,300 @@ static int mx3fb_unmap_video_memory(struct fb_info *fbi);
669 669
670/** 670/**
671 * mx3fb_set_fix() - set fixed framebuffer parameters from variable settings. 671 * mx3fb_set_fix() - set fixed framebuffer parameters from variable settings.
672 * @info: framebuffer information pointer 672 * @info: framebuffer information pointer
673 * @return: 0 on success or negative error code on failure. 673 * @return: 0 on success or negative error code on failure.
674 */ 674 */
675static int mx3fb_set_fix(struct fb_info *fbi) 675static int mx3fb_set_fix(struct fb_info *fbi)
676{ 676{
677 struct fb_fix_screeninfo *fix = &fbi->fix; 677 struct fb_fix_screeninfo *fix = &fbi->fix;
678 struct fb_var_screeninfo *var = &fbi->var; 678 struct fb_var_screeninfo *var = &fbi->var;
679 679
680 strncpy(fix->id, "DISP3 BG", 8); 680 strncpy(fix->id, "DISP3 BG", 8);
681 681
682 fix->line_length = var->xres_virtual * var->bits_per_pixel / 8; 682 fix->line_length = var->xres_virtual * var->bits_per_pixel / 8;
683 683
684 fix->type = FB_TYPE_PACKED_PIXELS; 684 fix->type = FB_TYPE_PACKED_PIXELS;
685 fix->accel = FB_ACCEL_NONE; 685 fix->accel = FB_ACCEL_NONE;
686 fix->visual = FB_VISUAL_TRUECOLOR; 686 fix->visual = FB_VISUAL_TRUECOLOR;
687 fix->xpanstep = 1; 687 fix->xpanstep = 1;
688 fix->ypanstep = 1; 688 fix->ypanstep = 1;
689 689
690 return 0; 690 return 0;
691} 691}
692 692
693static void mx3fb_dma_done(void *arg) 693static void mx3fb_dma_done(void *arg)
694{ 694{
695 struct idmac_tx_desc *tx_desc = to_tx_desc(arg); 695 struct idmac_tx_desc *tx_desc = to_tx_desc(arg);
696 struct dma_chan *chan = tx_desc->txd.chan; 696 struct dma_chan *chan = tx_desc->txd.chan;
697 struct idmac_channel *ichannel = to_idmac_chan(chan); 697 struct idmac_channel *ichannel = to_idmac_chan(chan);
698 struct mx3fb_data *mx3fb = ichannel->client; 698 struct mx3fb_data *mx3fb = ichannel->client;
699 struct mx3fb_info *mx3_fbi = mx3fb->fbi->par; 699 struct mx3fb_info *mx3_fbi = mx3fb->fbi->par;
700 700
701 dev_dbg(mx3fb->dev, "irq %d callback\n", ichannel->eof_irq); 701 dev_dbg(mx3fb->dev, "irq %d callback\n", ichannel->eof_irq);
702 702
703 /* We only need one interrupt, it will be re-enabled as needed */ 703 /* We only need one interrupt, it will be re-enabled as needed */
704 disable_irq(ichannel->eof_irq); 704 disable_irq(ichannel->eof_irq);
705 705
706 complete(&mx3_fbi->flip_cmpl); 706 complete(&mx3_fbi->flip_cmpl);
707} 707}
708 708
709/** 709/**
710 * mx3fb_set_par() - set framebuffer parameters and change the operating mode. 710 * mx3fb_set_par() - set framebuffer parameters and change the operating mode.
711 * @fbi: framebuffer information pointer. 711 * @fbi: framebuffer information pointer.
712 * @return: 0 on success or negative error code on failure. 712 * @return: 0 on success or negative error code on failure.
713 */ 713 */
714static int mx3fb_set_par(struct fb_info *fbi) 714static int mx3fb_set_par(struct fb_info *fbi)
715{ 715{
716 u32 mem_len; 716 u32 mem_len;
717 struct ipu_di_signal_cfg sig_cfg; 717 struct ipu_di_signal_cfg sig_cfg;
718 enum ipu_panel mode = IPU_PANEL_TFT; 718 enum ipu_panel mode = IPU_PANEL_TFT;
719 struct mx3fb_info *mx3_fbi = fbi->par; 719 struct mx3fb_info *mx3_fbi = fbi->par;
720 struct mx3fb_data *mx3fb = mx3_fbi->mx3fb; 720 struct mx3fb_data *mx3fb = mx3_fbi->mx3fb;
721 struct idmac_channel *ichan = mx3_fbi->idmac_channel; 721 struct idmac_channel *ichan = mx3_fbi->idmac_channel;
722 struct idmac_video_param *video = &ichan->params.video; 722 struct idmac_video_param *video = &ichan->params.video;
723 struct scatterlist *sg = mx3_fbi->sg; 723 struct scatterlist *sg = mx3_fbi->sg;
724 size_t screen_size; 724 size_t screen_size;
725 725
726 dev_dbg(mx3fb->dev, "%s [%c]\n", __func__, list_empty(&ichan->queue) ? '-' : '+'); 726 dev_dbg(mx3fb->dev, "%s [%c]\n", __func__, list_empty(&ichan->queue) ? '-' : '+');
727 727
728 mutex_lock(&mx3_fbi->mutex); 728 mutex_lock(&mx3_fbi->mutex);
729 729
730 /* Total cleanup */ 730 /* Total cleanup */
731 if (mx3_fbi->txd) 731 if (mx3_fbi->txd)
732 sdc_disable_channel(mx3_fbi); 732 sdc_disable_channel(mx3_fbi);
733 733
734 mx3fb_set_fix(fbi); 734 mx3fb_set_fix(fbi);
735 735
736 mem_len = fbi->var.yres_virtual * fbi->fix.line_length; 736 mem_len = fbi->var.yres_virtual * fbi->fix.line_length;
737 if (mem_len > fbi->fix.smem_len) { 737 if (mem_len > fbi->fix.smem_len) {
738 if (fbi->fix.smem_start) 738 if (fbi->fix.smem_start)
739 mx3fb_unmap_video_memory(fbi); 739 mx3fb_unmap_video_memory(fbi);
740 740
741 fbi->fix.smem_len = mem_len; 741 fbi->fix.smem_len = mem_len;
742 if (mx3fb_map_video_memory(fbi) < 0) { 742 if (mx3fb_map_video_memory(fbi) < 0) {
743 mutex_unlock(&mx3_fbi->mutex); 743 mutex_unlock(&mx3_fbi->mutex);
744 return -ENOMEM; 744 return -ENOMEM;
745 } 745 }
746 } 746 }
747 747
748 screen_size = fbi->fix.line_length * fbi->var.yres; 748 screen_size = fbi->fix.line_length * fbi->var.yres;
749 749
750 sg_init_table(&sg[0], 1); 750 sg_init_table(&sg[0], 1);
751 sg_init_table(&sg[1], 1); 751 sg_init_table(&sg[1], 1);
752 752
753 sg_dma_address(&sg[0]) = fbi->fix.smem_start; 753 sg_dma_address(&sg[0]) = fbi->fix.smem_start;
754 sg_set_page(&sg[0], virt_to_page(fbi->screen_base), 754 sg_set_page(&sg[0], virt_to_page(fbi->screen_base),
755 fbi->fix.smem_len, 755 fbi->fix.smem_len,
756 offset_in_page(fbi->screen_base)); 756 offset_in_page(fbi->screen_base));
757 757
758 if (mx3_fbi->ipu_ch == IDMAC_SDC_0) { 758 if (mx3_fbi->ipu_ch == IDMAC_SDC_0) {
759 memset(&sig_cfg, 0, sizeof(sig_cfg)); 759 memset(&sig_cfg, 0, sizeof(sig_cfg));
760 if (fbi->var.sync & FB_SYNC_HOR_HIGH_ACT) 760 if (fbi->var.sync & FB_SYNC_HOR_HIGH_ACT)
761 sig_cfg.Hsync_pol = true; 761 sig_cfg.Hsync_pol = true;
762 if (fbi->var.sync & FB_SYNC_VERT_HIGH_ACT) 762 if (fbi->var.sync & FB_SYNC_VERT_HIGH_ACT)
763 sig_cfg.Vsync_pol = true; 763 sig_cfg.Vsync_pol = true;
764 if (fbi->var.sync & FB_SYNC_CLK_INVERT) 764 if (fbi->var.sync & FB_SYNC_CLK_INVERT)
765 sig_cfg.clk_pol = true; 765 sig_cfg.clk_pol = true;
766 if (fbi->var.sync & FB_SYNC_DATA_INVERT) 766 if (fbi->var.sync & FB_SYNC_DATA_INVERT)
767 sig_cfg.data_pol = true; 767 sig_cfg.data_pol = true;
768 if (fbi->var.sync & FB_SYNC_OE_ACT_HIGH) 768 if (fbi->var.sync & FB_SYNC_OE_ACT_HIGH)
769 sig_cfg.enable_pol = true; 769 sig_cfg.enable_pol = true;
770 if (fbi->var.sync & FB_SYNC_CLK_IDLE_EN) 770 if (fbi->var.sync & FB_SYNC_CLK_IDLE_EN)
771 sig_cfg.clkidle_en = true; 771 sig_cfg.clkidle_en = true;
772 if (fbi->var.sync & FB_SYNC_CLK_SEL_EN) 772 if (fbi->var.sync & FB_SYNC_CLK_SEL_EN)
773 sig_cfg.clksel_en = true; 773 sig_cfg.clksel_en = true;
774 if (fbi->var.sync & FB_SYNC_SHARP_MODE) 774 if (fbi->var.sync & FB_SYNC_SHARP_MODE)
775 mode = IPU_PANEL_SHARP_TFT; 775 mode = IPU_PANEL_SHARP_TFT;
776 776
777 dev_dbg(fbi->device, "pixclock = %ul Hz\n", 777 dev_dbg(fbi->device, "pixclock = %ul Hz\n",
778 (u32) (PICOS2KHZ(fbi->var.pixclock) * 1000UL)); 778 (u32) (PICOS2KHZ(fbi->var.pixclock) * 1000UL));
779 779
780 if (sdc_init_panel(mx3fb, mode, 780 if (sdc_init_panel(mx3fb, mode,
781 (PICOS2KHZ(fbi->var.pixclock)) * 1000UL, 781 (PICOS2KHZ(fbi->var.pixclock)) * 1000UL,
782 fbi->var.xres, fbi->var.yres, 782 fbi->var.xres, fbi->var.yres,
783 (fbi->var.sync & FB_SYNC_SWAP_RGB) ? 783 (fbi->var.sync & FB_SYNC_SWAP_RGB) ?
784 IPU_PIX_FMT_BGR666 : IPU_PIX_FMT_RGB666, 784 IPU_PIX_FMT_BGR666 : IPU_PIX_FMT_RGB666,
785 fbi->var.left_margin, 785 fbi->var.left_margin,
786 fbi->var.hsync_len, 786 fbi->var.hsync_len,
787 fbi->var.right_margin + 787 fbi->var.right_margin +
788 fbi->var.hsync_len, 788 fbi->var.hsync_len,
789 fbi->var.upper_margin, 789 fbi->var.upper_margin,
790 fbi->var.vsync_len, 790 fbi->var.vsync_len,
791 fbi->var.lower_margin + 791 fbi->var.lower_margin +
792 fbi->var.vsync_len, sig_cfg) != 0) { 792 fbi->var.vsync_len, sig_cfg) != 0) {
793 mutex_unlock(&mx3_fbi->mutex); 793 mutex_unlock(&mx3_fbi->mutex);
794 dev_err(fbi->device, 794 dev_err(fbi->device,
795 "mx3fb: Error initializing panel.\n"); 795 "mx3fb: Error initializing panel.\n");
796 return -EINVAL; 796 return -EINVAL;
797 } 797 }
798 } 798 }
799 799
800 sdc_set_window_pos(mx3fb, mx3_fbi->ipu_ch, 0, 0); 800 sdc_set_window_pos(mx3fb, mx3_fbi->ipu_ch, 0, 0);
801 801
802 mx3_fbi->cur_ipu_buf = 0; 802 mx3_fbi->cur_ipu_buf = 0;
803 803
804 video->out_pixel_fmt = bpp_to_pixfmt(fbi->var.bits_per_pixel); 804 video->out_pixel_fmt = bpp_to_pixfmt(fbi->var.bits_per_pixel);
805 video->out_width = fbi->var.xres; 805 video->out_width = fbi->var.xres;
806 video->out_height = fbi->var.yres; 806 video->out_height = fbi->var.yres;
807 video->out_stride = fbi->var.xres_virtual; 807 video->out_stride = fbi->var.xres_virtual;
808 808
809 if (mx3_fbi->blank == FB_BLANK_UNBLANK) 809 if (mx3_fbi->blank == FB_BLANK_UNBLANK)
810 sdc_enable_channel(mx3_fbi); 810 sdc_enable_channel(mx3_fbi);
811 811
812 mutex_unlock(&mx3_fbi->mutex); 812 mutex_unlock(&mx3_fbi->mutex);
813 813
814 return 0; 814 return 0;
815} 815}
816 816
817/** 817/**
818 * mx3fb_check_var() - check and adjust framebuffer variable parameters. 818 * mx3fb_check_var() - check and adjust framebuffer variable parameters.
819 * @var: framebuffer variable parameters 819 * @var: framebuffer variable parameters
820 * @fbi: framebuffer information pointer 820 * @fbi: framebuffer information pointer
821 */ 821 */
822static int mx3fb_check_var(struct fb_var_screeninfo *var, struct fb_info *fbi) 822static int mx3fb_check_var(struct fb_var_screeninfo *var, struct fb_info *fbi)
823{ 823{
824 struct mx3fb_info *mx3_fbi = fbi->par; 824 struct mx3fb_info *mx3_fbi = fbi->par;
825 u32 vtotal; 825 u32 vtotal;
826 u32 htotal; 826 u32 htotal;
827 827
828 dev_dbg(fbi->device, "%s\n", __func__); 828 dev_dbg(fbi->device, "%s\n", __func__);
829 829
830 if (var->xres_virtual < var->xres) 830 if (var->xres_virtual < var->xres)
831 var->xres_virtual = var->xres; 831 var->xres_virtual = var->xres;
832 if (var->yres_virtual < var->yres) 832 if (var->yres_virtual < var->yres)
833 var->yres_virtual = var->yres; 833 var->yres_virtual = var->yres;
834 834
835 if ((var->bits_per_pixel != 32) && (var->bits_per_pixel != 24) && 835 if ((var->bits_per_pixel != 32) && (var->bits_per_pixel != 24) &&
836 (var->bits_per_pixel != 16)) 836 (var->bits_per_pixel != 16))
837 var->bits_per_pixel = default_bpp; 837 var->bits_per_pixel = default_bpp;
838 838
839 switch (var->bits_per_pixel) { 839 switch (var->bits_per_pixel) {
840 case 16: 840 case 16:
841 var->red.length = 5; 841 var->red.length = 5;
842 var->red.offset = 11; 842 var->red.offset = 11;
843 var->red.msb_right = 0; 843 var->red.msb_right = 0;
844 844
845 var->green.length = 6; 845 var->green.length = 6;
846 var->green.offset = 5; 846 var->green.offset = 5;
847 var->green.msb_right = 0; 847 var->green.msb_right = 0;
848 848
849 var->blue.length = 5; 849 var->blue.length = 5;
850 var->blue.offset = 0; 850 var->blue.offset = 0;
851 var->blue.msb_right = 0; 851 var->blue.msb_right = 0;
852 852
853 var->transp.length = 0; 853 var->transp.length = 0;
854 var->transp.offset = 0; 854 var->transp.offset = 0;
855 var->transp.msb_right = 0; 855 var->transp.msb_right = 0;
856 break; 856 break;
857 case 24: 857 case 24:
858 var->red.length = 8; 858 var->red.length = 8;
859 var->red.offset = 16; 859 var->red.offset = 16;
860 var->red.msb_right = 0; 860 var->red.msb_right = 0;
861 861
862 var->green.length = 8; 862 var->green.length = 8;
863 var->green.offset = 8; 863 var->green.offset = 8;
864 var->green.msb_right = 0; 864 var->green.msb_right = 0;
865 865
866 var->blue.length = 8; 866 var->blue.length = 8;
867 var->blue.offset = 0; 867 var->blue.offset = 0;
868 var->blue.msb_right = 0; 868 var->blue.msb_right = 0;
869 869
870 var->transp.length = 0; 870 var->transp.length = 0;
871 var->transp.offset = 0; 871 var->transp.offset = 0;
872 var->transp.msb_right = 0; 872 var->transp.msb_right = 0;
873 break; 873 break;
874 case 32: 874 case 32:
875 var->red.length = 8; 875 var->red.length = 8;
876 var->red.offset = 16; 876 var->red.offset = 16;
877 var->red.msb_right = 0; 877 var->red.msb_right = 0;
878 878
879 var->green.length = 8; 879 var->green.length = 8;
880 var->green.offset = 8; 880 var->green.offset = 8;
881 var->green.msb_right = 0; 881 var->green.msb_right = 0;
882 882
883 var->blue.length = 8; 883 var->blue.length = 8;
884 var->blue.offset = 0; 884 var->blue.offset = 0;
885 var->blue.msb_right = 0; 885 var->blue.msb_right = 0;
886 886
887 var->transp.length = 8; 887 var->transp.length = 8;
888 var->transp.offset = 24; 888 var->transp.offset = 24;
889 var->transp.msb_right = 0; 889 var->transp.msb_right = 0;
890 break; 890 break;
891 } 891 }
892 892
893 if (var->pixclock < 1000) { 893 if (var->pixclock < 1000) {
894 htotal = var->xres + var->right_margin + var->hsync_len + 894 htotal = var->xres + var->right_margin + var->hsync_len +
895 var->left_margin; 895 var->left_margin;
896 vtotal = var->yres + var->lower_margin + var->vsync_len + 896 vtotal = var->yres + var->lower_margin + var->vsync_len +
897 var->upper_margin; 897 var->upper_margin;
898 var->pixclock = (vtotal * htotal * 6UL) / 100UL; 898 var->pixclock = (vtotal * htotal * 6UL) / 100UL;
899 var->pixclock = KHZ2PICOS(var->pixclock); 899 var->pixclock = KHZ2PICOS(var->pixclock);
900 dev_dbg(fbi->device, "pixclock set for 60Hz refresh = %u ps\n", 900 dev_dbg(fbi->device, "pixclock set for 60Hz refresh = %u ps\n",
901 var->pixclock); 901 var->pixclock);
902 } 902 }
903 903
904 var->height = -1; 904 var->height = -1;
905 var->width = -1; 905 var->width = -1;
906 var->grayscale = 0; 906 var->grayscale = 0;
907 907
908 /* Preserve sync flags */ 908 /* Preserve sync flags */
909 var->sync |= mx3_fbi->sync; 909 var->sync |= mx3_fbi->sync;
910 mx3_fbi->sync |= var->sync; 910 mx3_fbi->sync |= var->sync;
911 911
912 return 0; 912 return 0;
913} 913}
914 914
915static u32 chan_to_field(unsigned int chan, struct fb_bitfield *bf) 915static u32 chan_to_field(unsigned int chan, struct fb_bitfield *bf)
916{ 916{
917 chan &= 0xffff; 917 chan &= 0xffff;
918 chan >>= 16 - bf->length; 918 chan >>= 16 - bf->length;
919 return chan << bf->offset; 919 return chan << bf->offset;
920} 920}
921 921
922static int mx3fb_setcolreg(unsigned int regno, unsigned int red, 922static int mx3fb_setcolreg(unsigned int regno, unsigned int red,
923 unsigned int green, unsigned int blue, 923 unsigned int green, unsigned int blue,
924 unsigned int trans, struct fb_info *fbi) 924 unsigned int trans, struct fb_info *fbi)
925{ 925{
926 struct mx3fb_info *mx3_fbi = fbi->par; 926 struct mx3fb_info *mx3_fbi = fbi->par;
927 u32 val; 927 u32 val;
928 int ret = 1; 928 int ret = 1;
929 929
930 dev_dbg(fbi->device, "%s\n", __func__); 930 dev_dbg(fbi->device, "%s\n", __func__);
931 931
932 mutex_lock(&mx3_fbi->mutex); 932 mutex_lock(&mx3_fbi->mutex);
933 /* 933 /*
934 * If greyscale is true, then we convert the RGB value 934 * If greyscale is true, then we convert the RGB value
935 * to greyscale no matter what visual we are using. 935 * to greyscale no matter what visual we are using.
936 */ 936 */
937 if (fbi->var.grayscale) 937 if (fbi->var.grayscale)
938 red = green = blue = (19595 * red + 38470 * green + 938 red = green = blue = (19595 * red + 38470 * green +
939 7471 * blue) >> 16; 939 7471 * blue) >> 16;
940 switch (fbi->fix.visual) { 940 switch (fbi->fix.visual) {
941 case FB_VISUAL_TRUECOLOR: 941 case FB_VISUAL_TRUECOLOR:
942 /* 942 /*
943 * 16-bit True Colour. We encode the RGB value 943 * 16-bit True Colour. We encode the RGB value
944 * according to the RGB bitfield information. 944 * according to the RGB bitfield information.
945 */ 945 */
946 if (regno < 16) { 946 if (regno < 16) {
947 u32 *pal = fbi->pseudo_palette; 947 u32 *pal = fbi->pseudo_palette;
948 948
949 val = chan_to_field(red, &fbi->var.red); 949 val = chan_to_field(red, &fbi->var.red);
950 val |= chan_to_field(green, &fbi->var.green); 950 val |= chan_to_field(green, &fbi->var.green);
951 val |= chan_to_field(blue, &fbi->var.blue); 951 val |= chan_to_field(blue, &fbi->var.blue);
952 952
953 pal[regno] = val; 953 pal[regno] = val;
954 954
955 ret = 0; 955 ret = 0;
956 } 956 }
957 break; 957 break;
958 958
959 case FB_VISUAL_STATIC_PSEUDOCOLOR: 959 case FB_VISUAL_STATIC_PSEUDOCOLOR:
960 case FB_VISUAL_PSEUDOCOLOR: 960 case FB_VISUAL_PSEUDOCOLOR:
961 break; 961 break;
962 } 962 }
963 mutex_unlock(&mx3_fbi->mutex); 963 mutex_unlock(&mx3_fbi->mutex);
964 964
965 return ret; 965 return ret;
966} 966}
967 967
968/** 968/**
@@ -970,152 +970,152 @@ static int mx3fb_setcolreg(unsigned int regno, unsigned int red,
970 */ 970 */
971static int mx3fb_blank(int blank, struct fb_info *fbi) 971static int mx3fb_blank(int blank, struct fb_info *fbi)
972{ 972{
973 struct mx3fb_info *mx3_fbi = fbi->par; 973 struct mx3fb_info *mx3_fbi = fbi->par;
974 struct mx3fb_data *mx3fb = mx3_fbi->mx3fb; 974 struct mx3fb_data *mx3fb = mx3_fbi->mx3fb;
975 975
976 dev_dbg(fbi->device, "%s\n", __func__); 976 dev_dbg(fbi->device, "%s\n", __func__);
977 977
978 dev_dbg(fbi->device, "blank = %d\n", blank); 978 dev_dbg(fbi->device, "blank = %d\n", blank);
979 979
980 if (mx3_fbi->blank == blank) 980 if (mx3_fbi->blank == blank)
981 return 0; 981 return 0;
982 982
983 mutex_lock(&mx3_fbi->mutex); 983 mutex_lock(&mx3_fbi->mutex);
984 mx3_fbi->blank = blank; 984 mx3_fbi->blank = blank;
985 985
986 switch (blank) { 986 switch (blank) {
987 case FB_BLANK_POWERDOWN: 987 case FB_BLANK_POWERDOWN:
988 case FB_BLANK_VSYNC_SUSPEND: 988 case FB_BLANK_VSYNC_SUSPEND:
989 case FB_BLANK_HSYNC_SUSPEND: 989 case FB_BLANK_HSYNC_SUSPEND:
990 case FB_BLANK_NORMAL: 990 case FB_BLANK_NORMAL:
991 sdc_disable_channel(mx3_fbi); 991 sdc_disable_channel(mx3_fbi);
992 sdc_set_brightness(mx3fb, 0); 992 sdc_set_brightness(mx3fb, 0);
993 break; 993 break;
994 case FB_BLANK_UNBLANK: 994 case FB_BLANK_UNBLANK:
995 sdc_enable_channel(mx3_fbi); 995 sdc_enable_channel(mx3_fbi);
996 sdc_set_brightness(mx3fb, mx3fb->backlight_level); 996 sdc_set_brightness(mx3fb, mx3fb->backlight_level);
997 break; 997 break;
998 } 998 }
999 mutex_unlock(&mx3_fbi->mutex); 999 mutex_unlock(&mx3_fbi->mutex);
1000 1000
1001 return 0; 1001 return 0;
1002} 1002}
1003 1003
1004/** 1004/**
1005 * mx3fb_pan_display() - pan or wrap the display 1005 * mx3fb_pan_display() - pan or wrap the display
1006 * @var: variable screen buffer information. 1006 * @var: variable screen buffer information.
1007 * @info: framebuffer information pointer. 1007 * @info: framebuffer information pointer.
1008 * 1008 *
1009 * We look only at xoffset, yoffset and the FB_VMODE_YWRAP flag 1009 * We look only at xoffset, yoffset and the FB_VMODE_YWRAP flag
1010 */ 1010 */
1011static int mx3fb_pan_display(struct fb_var_screeninfo *var, 1011static int mx3fb_pan_display(struct fb_var_screeninfo *var,
1012 struct fb_info *fbi) 1012 struct fb_info *fbi)
1013{ 1013{
1014 struct mx3fb_info *mx3_fbi = fbi->par; 1014 struct mx3fb_info *mx3_fbi = fbi->par;
1015 u32 y_bottom; 1015 u32 y_bottom;
1016 unsigned long base; 1016 unsigned long base;
1017 off_t offset; 1017 off_t offset;
1018 dma_cookie_t cookie; 1018 dma_cookie_t cookie;
1019 struct scatterlist *sg = mx3_fbi->sg; 1019 struct scatterlist *sg = mx3_fbi->sg;
1020 struct dma_chan *dma_chan = &mx3_fbi->idmac_channel->dma_chan; 1020 struct dma_chan *dma_chan = &mx3_fbi->idmac_channel->dma_chan;
1021 struct dma_async_tx_descriptor *txd; 1021 struct dma_async_tx_descriptor *txd;
1022 int ret; 1022 int ret;
1023 1023
1024 dev_dbg(fbi->device, "%s [%c]\n", __func__, 1024 dev_dbg(fbi->device, "%s [%c]\n", __func__,
1025 list_empty(&mx3_fbi->idmac_channel->queue) ? '-' : '+'); 1025 list_empty(&mx3_fbi->idmac_channel->queue) ? '-' : '+');
1026 1026
1027 if (var->xoffset > 0) { 1027 if (var->xoffset > 0) {
1028 dev_dbg(fbi->device, "x panning not supported\n"); 1028 dev_dbg(fbi->device, "x panning not supported\n");
1029 return -EINVAL; 1029 return -EINVAL;
1030 } 1030 }
1031 1031
1032 if (fbi->var.xoffset == var->xoffset && 1032 if (fbi->var.xoffset == var->xoffset &&
1033 fbi->var.yoffset == var->yoffset) 1033 fbi->var.yoffset == var->yoffset)
1034 return 0; /* No change, do nothing */ 1034 return 0; /* No change, do nothing */
1035 1035
1036 y_bottom = var->yoffset; 1036 y_bottom = var->yoffset;
1037 1037
1038 if (!(var->vmode & FB_VMODE_YWRAP)) 1038 if (!(var->vmode & FB_VMODE_YWRAP))
1039 y_bottom += var->yres; 1039 y_bottom += var->yres;
1040 1040
1041 if (y_bottom > fbi->var.yres_virtual) 1041 if (y_bottom > fbi->var.yres_virtual)
1042 return -EINVAL; 1042 return -EINVAL;
1043 1043
1044 mutex_lock(&mx3_fbi->mutex); 1044 mutex_lock(&mx3_fbi->mutex);
1045 1045
1046 offset = (var->yoffset * var->xres_virtual + var->xoffset) * 1046 offset = (var->yoffset * var->xres_virtual + var->xoffset) *
1047 (var->bits_per_pixel / 8); 1047 (var->bits_per_pixel / 8);
1048 base = fbi->fix.smem_start + offset; 1048 base = fbi->fix.smem_start + offset;
1049 1049
1050 dev_dbg(fbi->device, "Updating SDC BG buf %d address=0x%08lX\n", 1050 dev_dbg(fbi->device, "Updating SDC BG buf %d address=0x%08lX\n",
1051 mx3_fbi->cur_ipu_buf, base); 1051 mx3_fbi->cur_ipu_buf, base);
1052 1052
1053 /* 1053 /*
1054 * We enable the End of Frame interrupt, which will free a tx-descriptor, 1054 * We enable the End of Frame interrupt, which will free a tx-descriptor,
1055 * which we will need for the next device_prep_slave_sg(). The 1055 * which we will need for the next device_prep_slave_sg(). The
1056 * IRQ-handler will disable the IRQ again. 1056 * IRQ-handler will disable the IRQ again.
1057 */ 1057 */
1058 init_completion(&mx3_fbi->flip_cmpl); 1058 init_completion(&mx3_fbi->flip_cmpl);
1059 enable_irq(mx3_fbi->idmac_channel->eof_irq); 1059 enable_irq(mx3_fbi->idmac_channel->eof_irq);
1060 1060
1061 ret = wait_for_completion_timeout(&mx3_fbi->flip_cmpl, HZ / 10); 1061 ret = wait_for_completion_timeout(&mx3_fbi->flip_cmpl, HZ / 10);
1062 if (ret <= 0) { 1062 if (ret <= 0) {
1063 mutex_unlock(&mx3_fbi->mutex); 1063 mutex_unlock(&mx3_fbi->mutex);
1064 dev_info(fbi->device, "Panning failed due to %s\n", ret < 0 ? 1064 dev_info(fbi->device, "Panning failed due to %s\n", ret < 0 ?
1065 "user interrupt" : "timeout"); 1065 "user interrupt" : "timeout");
1066 return ret ? : -ETIMEDOUT; 1066 return ret ? : -ETIMEDOUT;
1067 } 1067 }
1068 1068
1069 mx3_fbi->cur_ipu_buf = !mx3_fbi->cur_ipu_buf; 1069 mx3_fbi->cur_ipu_buf = !mx3_fbi->cur_ipu_buf;
1070 1070
1071 sg_dma_address(&sg[mx3_fbi->cur_ipu_buf]) = base; 1071 sg_dma_address(&sg[mx3_fbi->cur_ipu_buf]) = base;
1072 sg_set_page(&sg[mx3_fbi->cur_ipu_buf], 1072 sg_set_page(&sg[mx3_fbi->cur_ipu_buf],
1073 virt_to_page(fbi->screen_base + offset), fbi->fix.smem_len, 1073 virt_to_page(fbi->screen_base + offset), fbi->fix.smem_len,
1074 offset_in_page(fbi->screen_base + offset)); 1074 offset_in_page(fbi->screen_base + offset));
1075 1075
1076 txd = dma_chan->device->device_prep_slave_sg(dma_chan, sg + 1076 txd = dma_chan->device->device_prep_slave_sg(dma_chan, sg +
1077 mx3_fbi->cur_ipu_buf, 1, DMA_TO_DEVICE, DMA_PREP_INTERRUPT); 1077 mx3_fbi->cur_ipu_buf, 1, DMA_TO_DEVICE, DMA_PREP_INTERRUPT);
1078 if (!txd) { 1078 if (!txd) {
1079 dev_err(fbi->device, 1079 dev_err(fbi->device,
1080 "Error preparing a DMA transaction descriptor.\n"); 1080 "Error preparing a DMA transaction descriptor.\n");
1081 mutex_unlock(&mx3_fbi->mutex); 1081 mutex_unlock(&mx3_fbi->mutex);
1082 return -EIO; 1082 return -EIO;
1083 } 1083 }
1084 1084
1085 txd->callback_param = txd; 1085 txd->callback_param = txd;
1086 txd->callback = mx3fb_dma_done; 1086 txd->callback = mx3fb_dma_done;
1087 1087
1088 /* 1088 /*
1089 * Emulate original mx3fb behaviour: each new call to idmac_tx_submit() 1089 * Emulate original mx3fb behaviour: each new call to idmac_tx_submit()
1090 * should switch to another buffer 1090 * should switch to another buffer
1091 */ 1091 */
1092 cookie = txd->tx_submit(txd); 1092 cookie = txd->tx_submit(txd);
1093 dev_dbg(fbi->device, "%d: Submit %p #%d\n", __LINE__, txd, cookie); 1093 dev_dbg(fbi->device, "%d: Submit %p #%d\n", __LINE__, txd, cookie);
1094 if (cookie < 0) { 1094 if (cookie < 0) {
1095 dev_err(fbi->device, 1095 dev_err(fbi->device,
1096 "Error updating SDC buf %d to address=0x%08lX\n", 1096 "Error updating SDC buf %d to address=0x%08lX\n",
1097 mx3_fbi->cur_ipu_buf, base); 1097 mx3_fbi->cur_ipu_buf, base);
1098 mutex_unlock(&mx3_fbi->mutex); 1098 mutex_unlock(&mx3_fbi->mutex);
1099 return -EIO; 1099 return -EIO;
1100 } 1100 }
1101 1101
1102 if (mx3_fbi->txd) 1102 if (mx3_fbi->txd)
1103 async_tx_ack(mx3_fbi->txd); 1103 async_tx_ack(mx3_fbi->txd);
1104 mx3_fbi->txd = txd; 1104 mx3_fbi->txd = txd;
1105 1105
1106 fbi->var.xoffset = var->xoffset; 1106 fbi->var.xoffset = var->xoffset;
1107 fbi->var.yoffset = var->yoffset; 1107 fbi->var.yoffset = var->yoffset;
1108 1108
1109 if (var->vmode & FB_VMODE_YWRAP) 1109 if (var->vmode & FB_VMODE_YWRAP)
1110 fbi->var.vmode |= FB_VMODE_YWRAP; 1110 fbi->var.vmode |= FB_VMODE_YWRAP;
1111 else 1111 else
1112 fbi->var.vmode &= ~FB_VMODE_YWRAP; 1112 fbi->var.vmode &= ~FB_VMODE_YWRAP;
1113 1113
1114 mutex_unlock(&mx3_fbi->mutex); 1114 mutex_unlock(&mx3_fbi->mutex);
1115 1115
1116 dev_dbg(fbi->device, "Update complete\n"); 1116 dev_dbg(fbi->device, "Update complete\n");
1117 1117
1118 return 0; 1118 return 0;
1119} 1119}
1120 1120
1121/* 1121/*
@@ -1124,15 +1124,15 @@ static int mx3fb_pan_display(struct fb_var_screeninfo *var,
1124 * blitting, rectangle filling, copy regions and cursor definition. 1124 * blitting, rectangle filling, copy regions and cursor definition.
1125 */ 1125 */
1126static struct fb_ops mx3fb_ops = { 1126static struct fb_ops mx3fb_ops = {
1127 .owner = THIS_MODULE, 1127 .owner = THIS_MODULE,
1128 .fb_set_par = mx3fb_set_par, 1128 .fb_set_par = mx3fb_set_par,
1129 .fb_check_var = mx3fb_check_var, 1129 .fb_check_var = mx3fb_check_var,
1130 .fb_setcolreg = mx3fb_setcolreg, 1130 .fb_setcolreg = mx3fb_setcolreg,
1131 .fb_pan_display = mx3fb_pan_display, 1131 .fb_pan_display = mx3fb_pan_display,
1132 .fb_fillrect = cfb_fillrect, 1132 .fb_fillrect = cfb_fillrect,
1133 .fb_copyarea = cfb_copyarea, 1133 .fb_copyarea = cfb_copyarea,
1134 .fb_imageblit = cfb_imageblit, 1134 .fb_imageblit = cfb_imageblit,
1135 .fb_blank = mx3fb_blank, 1135 .fb_blank = mx3fb_blank,
1136}; 1136};
1137 1137
1138#ifdef CONFIG_PM 1138#ifdef CONFIG_PM
@@ -1146,19 +1146,19 @@ static struct fb_ops mx3fb_ops = {
1146 */ 1146 */
1147static int mx3fb_suspend(struct platform_device *pdev, pm_message_t state) 1147static int mx3fb_suspend(struct platform_device *pdev, pm_message_t state)
1148{ 1148{
1149 struct mx3fb_data *drv_data = platform_get_drvdata(pdev); 1149 struct mx3fb_data *drv_data = platform_get_drvdata(pdev);
1150 struct mx3fb_info *mx3_fbi = drv_data->fbi->par; 1150 struct mx3fb_info *mx3_fbi = drv_data->fbi->par;
1151 1151
1152 acquire_console_sem(); 1152 acquire_console_sem();
1153 fb_set_suspend(drv_data->fbi, 1); 1153 fb_set_suspend(drv_data->fbi, 1);
1154 release_console_sem(); 1154 release_console_sem();
1155 1155
1156 if (mx3_fbi->blank == FB_BLANK_UNBLANK) { 1156 if (mx3_fbi->blank == FB_BLANK_UNBLANK) {
1157 sdc_disable_channel(mx3_fbi); 1157 sdc_disable_channel(mx3_fbi);
1158 sdc_set_brightness(mx3fb, 0); 1158 sdc_set_brightness(mx3fb, 0);
1159 1159
1160 } 1160 }
1161 return 0; 1161 return 0;
1162} 1162}
1163 1163
1164/* 1164/*
@@ -1166,19 +1166,19 @@ static int mx3fb_suspend(struct platform_device *pdev, pm_message_t state)
1166 */ 1166 */
1167static int mx3fb_resume(struct platform_device *pdev) 1167static int mx3fb_resume(struct platform_device *pdev)
1168{ 1168{
1169 struct mx3fb_data *drv_data = platform_get_drvdata(pdev); 1169 struct mx3fb_data *drv_data = platform_get_drvdata(pdev);
1170 struct mx3fb_info *mx3_fbi = drv_data->fbi->par; 1170 struct mx3fb_info *mx3_fbi = drv_data->fbi->par;
1171 1171
1172 if (mx3_fbi->blank == FB_BLANK_UNBLANK) { 1172 if (mx3_fbi->blank == FB_BLANK_UNBLANK) {
1173 sdc_enable_channel(mx3_fbi); 1173 sdc_enable_channel(mx3_fbi);
1174 sdc_set_brightness(mx3fb, drv_data->backlight_level); 1174 sdc_set_brightness(mx3fb, drv_data->backlight_level);
1175 } 1175 }
1176 1176
1177 acquire_console_sem(); 1177 acquire_console_sem();
1178 fb_set_suspend(drv_data->fbi, 0); 1178 fb_set_suspend(drv_data->fbi, 0);
1179 release_console_sem(); 1179 release_console_sem();
1180 1180
1181 return 0; 1181 return 0;
1182} 1182}
1183#else 1183#else
1184#define mx3fb_suspend NULL 1184#define mx3fb_suspend NULL
@@ -1191,8 +1191,8 @@ static int mx3fb_resume(struct platform_device *pdev)
1191 1191
1192/** 1192/**
1193 * mx3fb_map_video_memory() - allocates the DRAM memory for the frame buffer. 1193 * mx3fb_map_video_memory() - allocates the DRAM memory for the frame buffer.
1194 * @fbi: framebuffer information pointer 1194 * @fbi: framebuffer information pointer
1195 * @return: Error code indicating success or failure 1195 * @return: Error code indicating success or failure
1196 * 1196 *
1197 * This buffer is remapped into a non-cached, non-buffered, memory region to 1197 * This buffer is remapped into a non-cached, non-buffered, memory region to
1198 * allow palette and pixel writes to occur without flushing the cache. Once this 1198 * allow palette and pixel writes to occur without flushing the cache. Once this
@@ -1201,349 +1201,349 @@ static int mx3fb_resume(struct platform_device *pdev)
1201 */ 1201 */
1202static int mx3fb_map_video_memory(struct fb_info *fbi) 1202static int mx3fb_map_video_memory(struct fb_info *fbi)
1203{ 1203{
1204 int retval = 0; 1204 int retval = 0;
1205 dma_addr_t addr; 1205 dma_addr_t addr;
1206 1206
1207 fbi->screen_base = dma_alloc_writecombine(fbi->device, 1207 fbi->screen_base = dma_alloc_writecombine(fbi->device,
1208 fbi->fix.smem_len, 1208 fbi->fix.smem_len,
1209 &addr, GFP_DMA); 1209 &addr, GFP_DMA);
1210 1210
1211 if (!fbi->screen_base) { 1211 if (!fbi->screen_base) {
1212 dev_err(fbi->device, "Cannot allocate %u bytes framebuffer memory\n", 1212 dev_err(fbi->device, "Cannot allocate %u bytes framebuffer memory\n",
1213 fbi->fix.smem_len); 1213 fbi->fix.smem_len);
1214 retval = -EBUSY; 1214 retval = -EBUSY;
1215 goto err0; 1215 goto err0;
1216 } 1216 }
1217 1217
1218 fbi->fix.smem_start = addr; 1218 fbi->fix.smem_start = addr;
1219 1219
1220 dev_dbg(fbi->device, "allocated fb @ p=0x%08x, v=0x%p, size=%d.\n", 1220 dev_dbg(fbi->device, "allocated fb @ p=0x%08x, v=0x%p, size=%d.\n",
1221 (uint32_t) fbi->fix.smem_start, fbi->screen_base, fbi->fix.smem_len); 1221 (uint32_t) fbi->fix.smem_start, fbi->screen_base, fbi->fix.smem_len);
1222 1222
1223 fbi->screen_size = fbi->fix.smem_len; 1223 fbi->screen_size = fbi->fix.smem_len;
1224 1224
1225 /* Clear the screen */ 1225 /* Clear the screen */
1226 memset((char *)fbi->screen_base, 0, fbi->fix.smem_len); 1226 memset((char *)fbi->screen_base, 0, fbi->fix.smem_len);
1227 1227
1228 return 0; 1228 return 0;
1229 1229
1230err0: 1230err0:
1231 fbi->fix.smem_len = 0; 1231 fbi->fix.smem_len = 0;
1232 fbi->fix.smem_start = 0; 1232 fbi->fix.smem_start = 0;
1233 fbi->screen_base = NULL; 1233 fbi->screen_base = NULL;
1234 return retval; 1234 return retval;
1235} 1235}
1236 1236
1237/** 1237/**
1238 * mx3fb_unmap_video_memory() - de-allocate frame buffer memory. 1238 * mx3fb_unmap_video_memory() - de-allocate frame buffer memory.
1239 * @fbi: framebuffer information pointer 1239 * @fbi: framebuffer information pointer
1240 * @return: error code indicating success or failure 1240 * @return: error code indicating success or failure
1241 */ 1241 */
1242static int mx3fb_unmap_video_memory(struct fb_info *fbi) 1242static int mx3fb_unmap_video_memory(struct fb_info *fbi)
1243{ 1243{
1244 dma_free_writecombine(fbi->device, fbi->fix.smem_len, 1244 dma_free_writecombine(fbi->device, fbi->fix.smem_len,
1245 fbi->screen_base, fbi->fix.smem_start); 1245 fbi->screen_base, fbi->fix.smem_start);
1246 1246
1247 fbi->screen_base = 0; 1247 fbi->screen_base = 0;
1248 fbi->fix.smem_start = 0; 1248 fbi->fix.smem_start = 0;
1249 fbi->fix.smem_len = 0; 1249 fbi->fix.smem_len = 0;
1250 return 0; 1250 return 0;
1251} 1251}
1252 1252
1253/** 1253/**
1254 * mx3fb_init_fbinfo() - initialize framebuffer information object. 1254 * mx3fb_init_fbinfo() - initialize framebuffer information object.
1255 * @return: initialized framebuffer structure. 1255 * @return: initialized framebuffer structure.
1256 */ 1256 */
1257static struct fb_info *mx3fb_init_fbinfo(struct device *dev, struct fb_ops *ops) 1257static struct fb_info *mx3fb_init_fbinfo(struct device *dev, struct fb_ops *ops)
1258{ 1258{
1259 struct fb_info *fbi; 1259 struct fb_info *fbi;
1260 struct mx3fb_info *mx3fbi; 1260 struct mx3fb_info *mx3fbi;
1261 int ret; 1261 int ret;
1262 1262
1263 /* Allocate sufficient memory for the fb structure */ 1263 /* Allocate sufficient memory for the fb structure */
1264 fbi = framebuffer_alloc(sizeof(struct mx3fb_info), dev); 1264 fbi = framebuffer_alloc(sizeof(struct mx3fb_info), dev);
1265 if (!fbi) 1265 if (!fbi)
1266 return NULL; 1266 return NULL;
1267 1267
1268 mx3fbi = fbi->par; 1268 mx3fbi = fbi->par;
1269 mx3fbi->cookie = -EINVAL; 1269 mx3fbi->cookie = -EINVAL;
1270 mx3fbi->cur_ipu_buf = 0; 1270 mx3fbi->cur_ipu_buf = 0;
1271 1271
1272 fbi->var.activate = FB_ACTIVATE_NOW; 1272 fbi->var.activate = FB_ACTIVATE_NOW;
1273 1273
1274 fbi->fbops = ops; 1274 fbi->fbops = ops;
1275 fbi->flags = FBINFO_FLAG_DEFAULT; 1275 fbi->flags = FBINFO_FLAG_DEFAULT;
1276 fbi->pseudo_palette = mx3fbi->pseudo_palette; 1276 fbi->pseudo_palette = mx3fbi->pseudo_palette;
1277 1277
1278 mutex_init(&mx3fbi->mutex); 1278 mutex_init(&mx3fbi->mutex);
1279 1279
1280 /* Allocate colormap */ 1280 /* Allocate colormap */
1281 ret = fb_alloc_cmap(&fbi->cmap, 16, 0); 1281 ret = fb_alloc_cmap(&fbi->cmap, 16, 0);
1282 if (ret < 0) { 1282 if (ret < 0) {
1283 framebuffer_release(fbi); 1283 framebuffer_release(fbi);
1284 return NULL; 1284 return NULL;
1285 } 1285 }
1286 1286
1287 return fbi; 1287 return fbi;
1288} 1288}
1289 1289
1290static int init_fb_chan(struct mx3fb_data *mx3fb, struct idmac_channel *ichan) 1290static int init_fb_chan(struct mx3fb_data *mx3fb, struct idmac_channel *ichan)
1291{ 1291{
1292 struct device *dev = mx3fb->dev; 1292 struct device *dev = mx3fb->dev;
1293 struct mx3fb_platform_data *mx3fb_pdata = dev->platform_data; 1293 struct mx3fb_platform_data *mx3fb_pdata = dev->platform_data;
1294 const char *name = mx3fb_pdata->name; 1294 const char *name = mx3fb_pdata->name;
1295 unsigned int irq; 1295 unsigned int irq;
1296 struct fb_info *fbi; 1296 struct fb_info *fbi;
1297 struct mx3fb_info *mx3fbi; 1297 struct mx3fb_info *mx3fbi;
1298 const struct fb_videomode *mode; 1298 const struct fb_videomode *mode;
1299 int ret, num_modes; 1299 int ret, num_modes;
1300 1300
1301 ichan->client = mx3fb; 1301 ichan->client = mx3fb;
1302 irq = ichan->eof_irq; 1302 irq = ichan->eof_irq;
1303 1303
1304 if (ichan->dma_chan.chan_id != IDMAC_SDC_0) 1304 if (ichan->dma_chan.chan_id != IDMAC_SDC_0)
1305 return -EINVAL; 1305 return -EINVAL;
1306 1306
1307 fbi = mx3fb_init_fbinfo(dev, &mx3fb_ops); 1307 fbi = mx3fb_init_fbinfo(dev, &mx3fb_ops);
1308 if (!fbi) 1308 if (!fbi)
1309 return -ENOMEM; 1309 return -ENOMEM;
1310 1310
1311 if (!fb_mode) 1311 if (!fb_mode)
1312 fb_mode = name; 1312 fb_mode = name;
1313 1313
1314 if (!fb_mode) { 1314 if (!fb_mode) {
1315 ret = -EINVAL; 1315 ret = -EINVAL;
1316 goto emode; 1316 goto emode;
1317 } 1317 }
1318 1318
1319 if (mx3fb_pdata->mode && mx3fb_pdata->num_modes) { 1319 if (mx3fb_pdata->mode && mx3fb_pdata->num_modes) {
1320 mode = mx3fb_pdata->mode; 1320 mode = mx3fb_pdata->mode;
1321 num_modes = mx3fb_pdata->num_modes; 1321 num_modes = mx3fb_pdata->num_modes;
1322 } else { 1322 } else {
1323 mode = mx3fb_modedb; 1323 mode = mx3fb_modedb;
1324 num_modes = ARRAY_SIZE(mx3fb_modedb); 1324 num_modes = ARRAY_SIZE(mx3fb_modedb);
1325 } 1325 }
1326 1326
1327 if (!fb_find_mode(&fbi->var, fbi, fb_mode, mode, 1327 if (!fb_find_mode(&fbi->var, fbi, fb_mode, mode,
1328 num_modes, NULL, default_bpp)) { 1328 num_modes, NULL, default_bpp)) {
1329 ret = -EBUSY; 1329 ret = -EBUSY;
1330 goto emode; 1330 goto emode;
1331 } 1331 }
1332 1332
1333 fb_videomode_to_modelist(mode, num_modes, &fbi->modelist); 1333 fb_videomode_to_modelist(mode, num_modes, &fbi->modelist);
1334 1334
1335 /* Default Y virtual size is 2x panel size */ 1335 /* Default Y virtual size is 2x panel size */
1336 fbi->var.yres_virtual = fbi->var.yres * 2; 1336 fbi->var.yres_virtual = fbi->var.yres * 2;
1337 1337
1338 mx3fb->fbi = fbi; 1338 mx3fb->fbi = fbi;
1339 1339
1340 /* set Display Interface clock period */ 1340 /* set Display Interface clock period */
1341 mx3fb_write_reg(mx3fb, 0x00100010L, DI_HSP_CLK_PER); 1341 mx3fb_write_reg(mx3fb, 0x00100010L, DI_HSP_CLK_PER);
1342 /* Might need to trigger HSP clock change - see 44.3.3.8.5 */ 1342 /* Might need to trigger HSP clock change - see 44.3.3.8.5 */
1343 1343
1344 sdc_set_brightness(mx3fb, 255); 1344 sdc_set_brightness(mx3fb, 255);
1345 sdc_set_global_alpha(mx3fb, true, 0xFF); 1345 sdc_set_global_alpha(mx3fb, true, 0xFF);
1346 sdc_set_color_key(mx3fb, IDMAC_SDC_0, false, 0); 1346 sdc_set_color_key(mx3fb, IDMAC_SDC_0, false, 0);
1347 1347
1348 mx3fbi = fbi->par; 1348 mx3fbi = fbi->par;
1349 mx3fbi->idmac_channel = ichan; 1349 mx3fbi->idmac_channel = ichan;
1350 mx3fbi->ipu_ch = ichan->dma_chan.chan_id; 1350 mx3fbi->ipu_ch = ichan->dma_chan.chan_id;
1351 mx3fbi->mx3fb = mx3fb; 1351 mx3fbi->mx3fb = mx3fb;
1352 mx3fbi->blank = FB_BLANK_NORMAL; 1352 mx3fbi->blank = FB_BLANK_NORMAL;
1353 1353
1354 init_completion(&mx3fbi->flip_cmpl); 1354 init_completion(&mx3fbi->flip_cmpl);
1355 disable_irq(ichan->eof_irq); 1355 disable_irq(ichan->eof_irq);
1356 dev_dbg(mx3fb->dev, "disabling irq %d\n", ichan->eof_irq); 1356 dev_dbg(mx3fb->dev, "disabling irq %d\n", ichan->eof_irq);
1357 ret = mx3fb_set_par(fbi); 1357 ret = mx3fb_set_par(fbi);
1358 if (ret < 0) 1358 if (ret < 0)
1359 goto esetpar; 1359 goto esetpar;
1360 1360
1361 mx3fb_blank(FB_BLANK_UNBLANK, fbi); 1361 mx3fb_blank(FB_BLANK_UNBLANK, fbi);
1362 1362
1363 dev_info(dev, "mx3fb: fb registered, using mode %s\n", fb_mode); 1363 dev_info(dev, "mx3fb: fb registered, using mode %s\n", fb_mode);
1364 1364
1365 ret = register_framebuffer(fbi); 1365 ret = register_framebuffer(fbi);
1366 if (ret < 0) 1366 if (ret < 0)
1367 goto erfb; 1367 goto erfb;
1368 1368
1369 return 0; 1369 return 0;
1370 1370
1371erfb: 1371erfb:
1372esetpar: 1372esetpar:
1373emode: 1373emode:
1374 fb_dealloc_cmap(&fbi->cmap); 1374 fb_dealloc_cmap(&fbi->cmap);
1375 framebuffer_release(fbi); 1375 framebuffer_release(fbi);
1376 1376
1377 return ret; 1377 return ret;
1378} 1378}
1379 1379
1380static bool chan_filter(struct dma_chan *chan, void *arg) 1380static bool chan_filter(struct dma_chan *chan, void *arg)
1381{ 1381{
1382 struct dma_chan_request *rq = arg; 1382 struct dma_chan_request *rq = arg;
1383 struct device *dev; 1383 struct device *dev;
1384 struct mx3fb_platform_data *mx3fb_pdata; 1384 struct mx3fb_platform_data *mx3fb_pdata;
1385 1385
1386 if (!rq) 1386 if (!rq)
1387 return false; 1387 return false;
1388 1388
1389 dev = rq->mx3fb->dev; 1389 dev = rq->mx3fb->dev;
1390 mx3fb_pdata = dev->platform_data; 1390 mx3fb_pdata = dev->platform_data;
1391 1391
1392 return rq->id == chan->chan_id && 1392 return rq->id == chan->chan_id &&
1393 mx3fb_pdata->dma_dev == chan->device->dev; 1393 mx3fb_pdata->dma_dev == chan->device->dev;
1394} 1394}
1395 1395
1396static void release_fbi(struct fb_info *fbi) 1396static void release_fbi(struct fb_info *fbi)
1397{ 1397{
1398 mx3fb_unmap_video_memory(fbi); 1398 mx3fb_unmap_video_memory(fbi);
1399 1399
1400 fb_dealloc_cmap(&fbi->cmap); 1400 fb_dealloc_cmap(&fbi->cmap);
1401 1401
1402 unregister_framebuffer(fbi); 1402 unregister_framebuffer(fbi);
1403 framebuffer_release(fbi); 1403 framebuffer_release(fbi);
1404} 1404}
1405 1405
1406static int mx3fb_probe(struct platform_device *pdev) 1406static int mx3fb_probe(struct platform_device *pdev)
1407{ 1407{
1408 struct device *dev = &pdev->dev; 1408 struct device *dev = &pdev->dev;
1409 int ret; 1409 int ret;
1410 struct resource *sdc_reg; 1410 struct resource *sdc_reg;
1411 struct mx3fb_data *mx3fb; 1411 struct mx3fb_data *mx3fb;
1412 dma_cap_mask_t mask; 1412 dma_cap_mask_t mask;
1413 struct dma_chan *chan; 1413 struct dma_chan *chan;
1414 struct dma_chan_request rq; 1414 struct dma_chan_request rq;
1415 1415
1416 /* 1416 /*
1417 * Display Interface (DI) and Synchronous Display Controller (SDC) 1417 * Display Interface (DI) and Synchronous Display Controller (SDC)
1418 * registers 1418 * registers
1419 */ 1419 */
1420 sdc_reg = platform_get_resource(pdev, IORESOURCE_MEM, 0); 1420 sdc_reg = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1421 if (!sdc_reg) 1421 if (!sdc_reg)
1422 return -EINVAL; 1422 return -EINVAL;
1423 1423
1424 mx3fb = kzalloc(sizeof(*mx3fb), GFP_KERNEL); 1424 mx3fb = kzalloc(sizeof(*mx3fb), GFP_KERNEL);
1425 if (!mx3fb) 1425 if (!mx3fb)
1426 return -ENOMEM; 1426 return -ENOMEM;
1427 1427
1428 spin_lock_init(&mx3fb->lock); 1428 spin_lock_init(&mx3fb->lock);
1429 1429
1430 mx3fb->reg_base = ioremap(sdc_reg->start, resource_size(sdc_reg)); 1430 mx3fb->reg_base = ioremap(sdc_reg->start, resource_size(sdc_reg));
1431 if (!mx3fb->reg_base) { 1431 if (!mx3fb->reg_base) {
1432 ret = -ENOMEM; 1432 ret = -ENOMEM;
1433 goto eremap; 1433 goto eremap;
1434 } 1434 }
1435 1435
1436 pr_debug("Remapped %x to %x at %p\n", sdc_reg->start, sdc_reg->end, 1436 pr_debug("Remapped %x to %x at %p\n", sdc_reg->start, sdc_reg->end,
1437 mx3fb->reg_base); 1437 mx3fb->reg_base);
1438 1438
1439 /* IDMAC interface */ 1439 /* IDMAC interface */
1440 dmaengine_get(); 1440 dmaengine_get();
1441 1441
1442 mx3fb->dev = dev; 1442 mx3fb->dev = dev;
1443 platform_set_drvdata(pdev, mx3fb); 1443 platform_set_drvdata(pdev, mx3fb);
1444 1444
1445 rq.mx3fb = mx3fb; 1445 rq.mx3fb = mx3fb;
1446 1446
1447 dma_cap_zero(mask); 1447 dma_cap_zero(mask);
1448 dma_cap_set(DMA_SLAVE, mask); 1448 dma_cap_set(DMA_SLAVE, mask);
1449 dma_cap_set(DMA_PRIVATE, mask); 1449 dma_cap_set(DMA_PRIVATE, mask);
1450 rq.id = IDMAC_SDC_0; 1450 rq.id = IDMAC_SDC_0;
1451 chan = dma_request_channel(mask, chan_filter, &rq); 1451 chan = dma_request_channel(mask, chan_filter, &rq);
1452 if (!chan) { 1452 if (!chan) {
1453 ret = -EBUSY; 1453 ret = -EBUSY;
1454 goto ersdc0; 1454 goto ersdc0;
1455 } 1455 }
1456 1456
1457 ret = init_fb_chan(mx3fb, to_idmac_chan(chan)); 1457 ret = init_fb_chan(mx3fb, to_idmac_chan(chan));
1458 if (ret < 0) 1458 if (ret < 0)
1459 goto eisdc0; 1459 goto eisdc0;
1460 1460
1461 mx3fb->backlight_level = 255; 1461 mx3fb->backlight_level = 255;
1462 1462
1463 return 0; 1463 return 0;
1464 1464
1465eisdc0: 1465eisdc0:
1466 dma_release_channel(chan); 1466 dma_release_channel(chan);
1467ersdc0: 1467ersdc0:
1468 dmaengine_put(); 1468 dmaengine_put();
1469 iounmap(mx3fb->reg_base); 1469 iounmap(mx3fb->reg_base);
1470eremap: 1470eremap:
1471 kfree(mx3fb); 1471 kfree(mx3fb);
1472 dev_err(dev, "mx3fb: failed to register fb\n"); 1472 dev_err(dev, "mx3fb: failed to register fb\n");
1473 return ret; 1473 return ret;
1474} 1474}
1475 1475
1476static int mx3fb_remove(struct platform_device *dev) 1476static int mx3fb_remove(struct platform_device *dev)
1477{ 1477{
1478 struct mx3fb_data *mx3fb = platform_get_drvdata(dev); 1478 struct mx3fb_data *mx3fb = platform_get_drvdata(dev);
1479 struct fb_info *fbi = mx3fb->fbi; 1479 struct fb_info *fbi = mx3fb->fbi;
1480 struct mx3fb_info *mx3_fbi = fbi->par; 1480 struct mx3fb_info *mx3_fbi = fbi->par;
1481 struct dma_chan *chan; 1481 struct dma_chan *chan;
1482 1482
1483 chan = &mx3_fbi->idmac_channel->dma_chan; 1483 chan = &mx3_fbi->idmac_channel->dma_chan;
1484 release_fbi(fbi); 1484 release_fbi(fbi);
1485 1485
1486 dma_release_channel(chan); 1486 dma_release_channel(chan);
1487 dmaengine_put(); 1487 dmaengine_put();
1488 1488
1489 iounmap(mx3fb->reg_base); 1489 iounmap(mx3fb->reg_base);
1490 kfree(mx3fb); 1490 kfree(mx3fb);
1491 return 0; 1491 return 0;
1492} 1492}
1493 1493
1494static struct platform_driver mx3fb_driver = { 1494static struct platform_driver mx3fb_driver = {
1495 .driver = { 1495 .driver = {
1496 .name = MX3FB_NAME, 1496 .name = MX3FB_NAME,
1497 }, 1497 },
1498 .probe = mx3fb_probe, 1498 .probe = mx3fb_probe,
1499 .remove = mx3fb_remove, 1499 .remove = mx3fb_remove,
1500 .suspend = mx3fb_suspend, 1500 .suspend = mx3fb_suspend,
1501 .resume = mx3fb_resume, 1501 .resume = mx3fb_resume,
1502}; 1502};
1503 1503
1504/* 1504/*
1505 * Parse user specified options (`video=mx3fb:') 1505 * Parse user specified options (`video=mx3fb:')
1506 * example: 1506 * example:
1507 * video=mx3fb:bpp=16 1507 * video=mx3fb:bpp=16
1508 */ 1508 */
1509static int mx3fb_setup(void) 1509static int mx3fb_setup(void)
1510{ 1510{
1511#ifndef MODULE 1511#ifndef MODULE
1512 char *opt, *options = NULL; 1512 char *opt, *options = NULL;
1513 1513
1514 if (fb_get_options("mx3fb", &options)) 1514 if (fb_get_options("mx3fb", &options))
1515 return -ENODEV; 1515 return -ENODEV;
1516 1516
1517 if (!options || !*options) 1517 if (!options || !*options)
1518 return 0; 1518 return 0;
1519 1519
1520 while ((opt = strsep(&options, ",")) != NULL) { 1520 while ((opt = strsep(&options, ",")) != NULL) {
1521 if (!*opt) 1521 if (!*opt)
1522 continue; 1522 continue;
1523 if (!strncmp(opt, "bpp=", 4)) 1523 if (!strncmp(opt, "bpp=", 4))
1524 default_bpp = simple_strtoul(opt + 4, NULL, 0); 1524 default_bpp = simple_strtoul(opt + 4, NULL, 0);
1525 else 1525 else
1526 fb_mode = opt; 1526 fb_mode = opt;
1527 } 1527 }
1528#endif 1528#endif
1529 1529
1530 return 0; 1530 return 0;
1531} 1531}
1532 1532
1533static int __init mx3fb_init(void) 1533static int __init mx3fb_init(void)
1534{ 1534{
1535 int ret = mx3fb_setup(); 1535 int ret = mx3fb_setup();
1536 1536
1537 if (ret < 0) 1537 if (ret < 0)
1538 return ret; 1538 return ret;
1539 1539
1540 ret = platform_driver_register(&mx3fb_driver); 1540 ret = platform_driver_register(&mx3fb_driver);
1541 return ret; 1541 return ret;
1542} 1542}
1543 1543
1544static void __exit mx3fb_exit(void) 1544static void __exit mx3fb_exit(void)
1545{ 1545{
1546 platform_driver_unregister(&mx3fb_driver); 1546 platform_driver_unregister(&mx3fb_driver);
1547} 1547}
1548 1548
1549module_init(mx3fb_init); 1549module_init(mx3fb_init);