aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/video/mx3fb.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/video/mx3fb.c')
-rw-r--r--drivers/video/mx3fb.c2300
1 files changed, 1150 insertions, 1150 deletions
diff --git a/drivers/video/mx3fb.c b/drivers/video/mx3fb.c
index 8a75d05f4334..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, "ipu_clk"); 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);