aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlan Cox <alan@linux.intel.com>2011-07-15 12:35:49 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2011-07-15 13:05:08 -0400
commit3a970ac1b14cf1a49076d69369aa75a23d4ad2db (patch)
tree3127d9283a87f2f5d8cda61522de225b96b31e72
parent3caa89e933646263cb4efedd5660dba00a107b51 (diff)
gma500: Clean up the DPU config and make it runtime
We really don't want this all done by ifdeffery - and this isn't any need as it's fairly easy to sort out. Signed-off-by: Alan Cox <alan@linux.intel.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-rw-r--r--drivers/staging/gma500/Makefile1
-rw-r--r--drivers/staging/gma500/mdfld_dsi_dbi.c19
-rw-r--r--drivers/staging/gma500/mdfld_dsi_dbi_dpu.c778
-rw-r--r--drivers/staging/gma500/mdfld_dsi_output.c8
-rw-r--r--drivers/staging/gma500/mdfld_intel_display.c49
-rw-r--r--drivers/staging/gma500/mdfld_output.c42
-rw-r--r--drivers/staging/gma500/mdfld_output.h2
-rw-r--r--drivers/staging/gma500/mdfld_pyr_cmd.c7
-rw-r--r--drivers/staging/gma500/mdfld_tpo_cmd.c6
-rw-r--r--drivers/staging/gma500/psb_drv.c11
10 files changed, 845 insertions, 78 deletions
diff --git a/drivers/staging/gma500/Makefile b/drivers/staging/gma500/Makefile
index fe34f1831415..c729868b1b10 100644
--- a/drivers/staging/gma500/Makefile
+++ b/drivers/staging/gma500/Makefile
@@ -46,6 +46,7 @@ psb_gfx-$(CONFIG_DRM_PSB_MFLD) += mdfld_device.o \
46 mdfld_dsi_dpi.o \ 46 mdfld_dsi_dpi.o \
47 mdfld_dsi_output.o \ 47 mdfld_dsi_output.o \
48 mdfld_dsi_dbi.o \ 48 mdfld_dsi_dbi.o \
49 mdfld_dsi_dbi_dpu.o \
49 mdfld_intel_display.o 50 mdfld_intel_display.o
50 51
51obj-$(CONFIG_DRM_PSB) += psb_gfx.o 52obj-$(CONFIG_DRM_PSB) += psb_gfx.o
diff --git a/drivers/staging/gma500/mdfld_dsi_dbi.c b/drivers/staging/gma500/mdfld_dsi_dbi.c
index 06424f945bc8..02e17c9c8637 100644
--- a/drivers/staging/gma500/mdfld_dsi_dbi.c
+++ b/drivers/staging/gma500/mdfld_dsi_dbi.c
@@ -327,7 +327,6 @@ void mdfld_dsi_dbi_enter_dsr(struct mdfld_dsi_dbi_output *dbi_output, int pipe)
327 } 327 }
328} 328}
329 329
330#ifndef CONFIG_MDFLD_DSI_DPU
331static void mdfld_dbi_output_exit_dsr(struct mdfld_dsi_dbi_output *dbi_output, 330static void mdfld_dbi_output_exit_dsr(struct mdfld_dsi_dbi_output *dbi_output,
332 int pipe) 331 int pipe)
333{ 332{
@@ -562,7 +561,6 @@ void mdfld_dbi_dsr_exit(struct drm_device *dev)
562 dev_priv->dbi_dsr_info = NULL; 561 dev_priv->dbi_dsr_info = NULL;
563 } 562 }
564} 563}
565#endif
566 564
567void mdfld_dsi_controller_dbi_init(struct mdfld_dsi_config *dsi_config, 565void mdfld_dsi_controller_dbi_init(struct mdfld_dsi_config *dsi_config,
568 int pipe) 566 int pipe)
@@ -648,12 +646,8 @@ struct mdfld_dsi_encoder *mdfld_dsi_dbi_init(struct drm_device *dev,
648 struct drm_encoder *encoder = NULL; 646 struct drm_encoder *encoder = NULL;
649 struct drm_display_mode *fixed_mode = NULL; 647 struct drm_display_mode *fixed_mode = NULL;
650 struct psb_gtt *pg = dev_priv ? (&dev_priv->gtt) : NULL; 648 struct psb_gtt *pg = dev_priv ? (&dev_priv->gtt) : NULL;
651
652#ifdef CONFIG_MDFLD_DSI_DPU
653 struct mdfld_dbi_dpu_info *dpu_info = dev_priv ? (dev_priv->dbi_dpu_info) : NULL; 649 struct mdfld_dbi_dpu_info *dpu_info = dev_priv ? (dev_priv->dbi_dpu_info) : NULL;
654#else
655 struct mdfld_dbi_dsr_info *dsr_info = dev_priv ? (dev_priv->dbi_dsr_info) : NULL; 650 struct mdfld_dbi_dsr_info *dsr_info = dev_priv ? (dev_priv->dbi_dsr_info) : NULL;
656#endif
657 u32 data = 0; 651 u32 data = 0;
658 int pipe; 652 int pipe;
659 int ret; 653 int ret;
@@ -742,20 +736,16 @@ struct mdfld_dsi_encoder *mdfld_dsi_dbi_init(struct drm_device *dev,
742 dbi_output->first_boot = true; 736 dbi_output->first_boot = true;
743 dbi_output->mode_flags = MODE_SETTING_IN_ENCODER; 737 dbi_output->mode_flags = MODE_SETTING_IN_ENCODER;
744 738
745#ifdef CONFIG_MDFLD_DSI_DPU 739 /* Add this output to dpu_info if in DPU mode */
746 /* Add this output to dpu_info */ 740 if (dpu_info && dsi_connector->status == connector_status_connected) {
747 if (dsi_connector->status == connector_status_connected) {
748 if (dsi_connector->pipe == 0) 741 if (dsi_connector->pipe == 0)
749 dpu_info->dbi_outputs[0] = dbi_output; 742 dpu_info->dbi_outputs[0] = dbi_output;
750 else 743 else
751 dpu_info->dbi_outputs[1] = dbi_output; 744 dpu_info->dbi_outputs[1] = dbi_output;
752 745
753 dpu_info->dbi_output_num++; 746 dpu_info->dbi_output_num++;
754 } 747 } else if (dsi_connector->status == connector_status_connected) {
755 748 /* Add this output to dsr_info if not */
756#else /*CONFIG_MDFLD_DSI_DPU*/
757 if (dsi_connector->status == connector_status_connected) {
758 /* Add this output to dsr_info */
759 if (dsi_connector->pipe == 0) 749 if (dsi_connector->pipe == 0)
760 dsr_info->dbi_outputs[0] = dbi_output; 750 dsr_info->dbi_outputs[0] = dbi_output;
761 else 751 else
@@ -763,7 +753,6 @@ struct mdfld_dsi_encoder *mdfld_dsi_dbi_init(struct drm_device *dev,
763 753
764 dsr_info->dbi_output_num++; 754 dsr_info->dbi_output_num++;
765 } 755 }
766#endif
767 return &dbi_output->base; 756 return &dbi_output->base;
768out_err1: 757out_err1:
769 kfree(dbi_output); 758 kfree(dbi_output);
diff --git a/drivers/staging/gma500/mdfld_dsi_dbi_dpu.c b/drivers/staging/gma500/mdfld_dsi_dbi_dpu.c
new file mode 100644
index 000000000000..98ec990a23fc
--- /dev/null
+++ b/drivers/staging/gma500/mdfld_dsi_dbi_dpu.c
@@ -0,0 +1,778 @@
1/*
2 * Copyright © 2010-2011 Intel Corporation
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
13 * Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21 * DEALINGS IN THE SOFTWARE.
22 *
23 * Authors:
24 * Jim Liu <jim.liu@intel.com>
25 * Jackie Li<yaodong.li@intel.com>
26 */
27
28#include "mdfld_dsi_dbi_dpu.h"
29#include "mdfld_dsi_dbi.h"
30
31/*
32 * NOTE: all mdlfd_x_damage funcs should be called by holding dpu_update_lock
33 */
34
35static int mdfld_cursor_damage(struct mdfld_dbi_dpu_info *dpu_info,
36 mdfld_plane_t plane,
37 struct psb_drm_dpu_rect *damaged_rect)
38{
39 int x, y;
40 int new_x, new_y;
41 struct psb_drm_dpu_rect *rect;
42 struct psb_drm_dpu_rect *pipe_rect;
43 int cursor_size;
44 struct mdfld_cursor_info *cursor;
45 mdfld_plane_t fb_plane;
46
47 if (plane == MDFLD_CURSORA) {
48 cursor = &dpu_info->cursors[0];
49 x = dpu_info->cursors[0].x;
50 y = dpu_info->cursors[0].y;
51 cursor_size = dpu_info->cursors[0].size;
52 pipe_rect = &dpu_info->damage_pipea;
53 fb_plane = MDFLD_PLANEA;
54 } else {
55 cursor = &dpu_info->cursors[1];
56 x = dpu_info->cursors[1].x;
57 y = dpu_info->cursors[1].y;
58 cursor_size = dpu_info->cursors[1].size;
59 pipe_rect = &dpu_info->damage_pipec;
60 fb_plane = MDFLD_PLANEC;
61 }
62 new_x = damaged_rect->x;
63 new_y = damaged_rect->y;
64
65 if (x == new_x && y == new_y)
66 return 0;
67
68 rect = &dpu_info->damaged_rects[plane];
69 /* Move to right */
70 if (new_x >= x) {
71 if (new_y > y) {
72 rect->x = x;
73 rect->y = y;
74 rect->width = (new_x + cursor_size) - x;
75 rect->height = (new_y + cursor_size) - y;
76 goto cursor_out;
77 } else {
78 rect->x = x;
79 rect->y = new_y;
80 rect->width = (new_x + cursor_size) - x;
81 rect->height = (y - new_y);
82 goto cursor_out;
83 }
84 } else {
85 if (new_y > y) {
86 rect->x = new_x;
87 rect->y = y;
88 rect->width = (x + cursor_size) - new_x;
89 rect->height = new_y - y;
90 goto cursor_out;
91 } else {
92 rect->x = new_x;
93 rect->y = new_y;
94 rect->width = (x + cursor_size) - new_x;
95 rect->height = (y + cursor_size) - new_y;
96 }
97 }
98cursor_out:
99 if (new_x < 0)
100 cursor->x = 0;
101 else if (new_x > 864)
102 cursor->x = 864;
103 else
104 cursor->x = new_x;
105
106 if (new_y < 0)
107 cursor->y = 0;
108 else if (new_y > 480)
109 cursor->y = 480;
110 else
111 cursor->y = new_y;
112
113 /*
114 * FIXME: this is a workaround for cursor plane update,
115 * remove it later!
116 */
117 rect->x = 0;
118 rect->y = 0;
119 rect->width = 864;
120 rect->height = 480;
121
122 mdfld_check_boundary(dpu_info, rect);
123 mdfld_dpu_region_extent(pipe_rect, rect);
124
125 /* Update pending status of dpu_info */
126 dpu_info->pending |= (1 << plane);
127 /* Update fb panel as well */
128 dpu_info->pending |= (1 << fb_plane);
129 return 0;
130}
131
132static int mdfld_fb_damage(struct mdfld_dbi_dpu_info *dpu_info,
133 mdfld_plane_t plane,
134 struct psb_drm_dpu_rect *damaged_rect)
135{
136 struct psb_drm_dpu_rect *rect;
137
138 if (plane == MDFLD_PLANEA)
139 rect = &dpu_info->damage_pipea;
140 else
141 rect = &dpu_info->damage_pipec;
142
143 mdfld_check_boundary(dpu_info, damaged_rect);
144
145 /* Add fb damage area to this pipe */
146 mdfld_dpu_region_extent(rect, damaged_rect);
147
148 /* Update pending status of dpu_info */
149 dpu_info->pending |= (1 << plane);
150 return 0;
151}
152
153/* Do nothing here, right now */
154static int mdfld_overlay_damage(struct mdfld_dbi_dpu_info *dpu_info,
155 mdfld_plane_t plane,
156 struct psb_drm_dpu_rect *damaged_rect)
157{
158 return 0;
159}
160
161int mdfld_dbi_dpu_report_damage(struct drm_device *dev,
162 mdfld_plane_t plane,
163 struct psb_drm_dpu_rect *rect)
164{
165 struct drm_psb_private *dev_priv = dev->dev_private;
166 struct mdfld_dbi_dpu_info *dpu_info = dev_priv->dbi_dpu_info;
167 int ret = 0;
168
169 /* DPU not in use, no damage reporting needed */
170 if (dpu_info == NULL)
171 return 0;
172
173 spin_lock(&dpu_info->dpu_update_lock);
174
175 switch (plane) {
176 case MDFLD_PLANEA:
177 case MDFLD_PLANEC:
178 mdfld_fb_damage(dpu_info, plane, rect);
179 break;
180 case MDFLD_CURSORA:
181 case MDFLD_CURSORC:
182 mdfld_cursor_damage(dpu_info, plane, rect);
183 break;
184 case MDFLD_OVERLAYA:
185 case MDFLD_OVERLAYC:
186 mdfld_overlay_damage(dpu_info, plane, rect);
187 break;
188 default:
189 DRM_ERROR("Invalid plane type %d\n", plane);
190 ret = -EINVAL;
191 }
192 spin_unlock(&dpu_info->dpu_update_lock);
193 return ret;
194}
195
196int mdfld_dbi_dpu_report_fullscreen_damage(struct drm_device *dev)
197{
198 struct drm_psb_private *dev_priv;
199 struct mdfld_dbi_dpu_info *dpu_info;
200 struct mdfld_dsi_config *dsi_config;
201 struct psb_drm_dpu_rect rect;
202 int i;
203
204 if (!dev) {
205 DRM_ERROR("Invalid parameter\n");
206 return -EINVAL;
207 }
208
209 dev_priv = dev->dev_private;
210 dpu_info = dev_priv->dbi_dpu_info;
211
212 /* This is fine - we may be in non DPU mode */
213 if (!dpu_info)
214 return -EINVAL;
215
216 for (i = 0; i < dpu_info->dbi_output_num; i++) {
217 dsi_config = dev_priv->dsi_configs[i];
218 if (dsi_config) {
219 rect.x = rect.y = 0;
220 rect.width = dsi_config->fixed_mode->hdisplay;
221 rect.height = dsi_config->fixed_mode->vdisplay;
222 mdfld_dbi_dpu_report_damage(dev,
223 i ? (MDFLD_PLANEC) : (MDFLD_PLANEA),
224 &rect);
225 }
226 }
227 /* Exit DSR state */
228 mdfld_dpu_exit_dsr(dev);
229 return 0;
230}
231
232int mdfld_dsi_dbi_dsr_off(struct drm_device *dev,
233 struct psb_drm_dpu_rect *rect)
234{
235 struct drm_psb_private *dev_priv = dev->dev_private;
236 struct mdfld_dbi_dpu_info *dpu_info = dev_priv->dbi_dpu_info;
237
238 mdfld_dbi_dpu_report_damage(dev, MDFLD_PLANEA, rect);
239
240 /* If dual display mode */
241 if (dpu_info->dbi_output_num == 2)
242 mdfld_dbi_dpu_report_damage(dev, MDFLD_PLANEC, rect);
243
244 /* Force dsi to exit DSR mode */
245 mdfld_dpu_exit_dsr(dev);
246 return 0;
247}
248
249static void mdfld_dpu_cursor_plane_flush(struct mdfld_dbi_dpu_info *dpu_info,
250 mdfld_plane_t plane)
251{
252 struct drm_device *dev = dpu_info->dev;
253 u32 curpos_reg = CURAPOS;
254 u32 curbase_reg = CURABASE;
255 u32 curcntr_reg = CURACNTR;
256 struct mdfld_cursor_info *cursor = &dpu_info->cursors[0];
257
258 if (plane == MDFLD_CURSORC) {
259 curpos_reg = CURCPOS;
260 curbase_reg = CURCBASE;
261 curcntr_reg = CURCCNTR;
262 cursor = &dpu_info->cursors[1];
263 }
264
265 REG_WRITE(curcntr_reg, REG_READ(curcntr_reg));
266 REG_WRITE(curpos_reg,
267 (((cursor->x & CURSOR_POS_MASK) << CURSOR_X_SHIFT) |
268 ((cursor->y & CURSOR_POS_MASK) << CURSOR_Y_SHIFT)));
269 REG_WRITE(curbase_reg, REG_READ(curbase_reg));
270}
271
272static void mdfld_dpu_fb_plane_flush(struct mdfld_dbi_dpu_info *dpu_info,
273 mdfld_plane_t plane)
274{
275 u32 pipesrc_reg = PIPEASRC;
276 u32 dspsize_reg = DSPASIZE;
277 u32 dspoff_reg = DSPALINOFF;
278 u32 dspsurf_reg = DSPASURF;
279 u32 dspstride_reg = DSPASTRIDE;
280 u32 stride;
281 struct psb_drm_dpu_rect *rect = &dpu_info->damage_pipea;
282 struct drm_device *dev = dpu_info->dev;
283
284 if (plane == MDFLD_PLANEC) {
285 pipesrc_reg = PIPECSRC;
286 dspsize_reg = DSPCSIZE;
287 dspoff_reg = DSPCLINOFF;
288 dspsurf_reg = DSPCSURF;
289 dspstride_reg = DSPCSTRIDE;
290 rect = &dpu_info->damage_pipec;
291 }
292
293 stride = REG_READ(dspstride_reg);
294 /* FIXME: should I do the pipe src update here? */
295 REG_WRITE(pipesrc_reg, ((rect->width - 1) << 16) | (rect->height - 1));
296 /* Flush plane */
297 REG_WRITE(dspsize_reg, ((rect->height - 1) << 16) | (rect->width - 1));
298 REG_WRITE(dspoff_reg, ((rect->x * 4) + (rect->y * stride)));
299 REG_WRITE(dspsurf_reg, REG_READ(dspsurf_reg));
300
301 /*
302 * TODO: wait for flip finished and restore the pipesrc reg,
303 * or cursor will be show at a wrong position
304 */
305}
306
307static void mdfld_dpu_overlay_plane_flush(struct mdfld_dbi_dpu_info *dpu_info,
308 mdfld_plane_t plane)
309{
310}
311
312/*
313 * TODO: we are still in dbi normal mode now, we will try to use partial
314 * mode later.
315 */
316static int mdfld_dbi_prepare_cb(struct mdfld_dsi_dbi_output *dbi_output,
317 struct mdfld_dbi_dpu_info *dpu_info, int pipe)
318{
319 u8 *cb_addr = (u8 *)dbi_output->dbi_cb_addr;
320 u32 *index;
321 struct psb_drm_dpu_rect *rect = pipe ?
322 (&dpu_info->damage_pipec) : (&dpu_info->damage_pipea);
323
324 /* FIXME: lock command buffer, this may lead to a deadlock,
325 as we already hold the dpu_update_lock */
326 if (!spin_trylock(&dbi_output->cb_lock)) {
327 DRM_ERROR("lock command buffer failed, try again\n");
328 return -EAGAIN;
329 }
330
331 index = &dbi_output->cb_write;
332
333 if (*index) {
334 DRM_ERROR("DBI command buffer unclean\n");
335 return -EAGAIN;
336 }
337
338 /* Column address */
339 *(cb_addr + ((*index)++)) = set_column_address;
340 *(cb_addr + ((*index)++)) = rect->x >> 8;
341 *(cb_addr + ((*index)++)) = rect->x;
342 *(cb_addr + ((*index)++)) = (rect->x + rect->width - 1) >> 8;
343 *(cb_addr + ((*index)++)) = (rect->x + rect->width - 1);
344
345 *index = 8;
346
347 /* Page address */
348 *(cb_addr + ((*index)++)) = set_page_addr;
349 *(cb_addr + ((*index)++)) = rect->y >> 8;
350 *(cb_addr + ((*index)++)) = rect->y;
351 *(cb_addr + ((*index)++)) = (rect->y + rect->height - 1) >> 8;
352 *(cb_addr + ((*index)++)) = (rect->y + rect->height - 1);
353
354 *index = 16;
355
356 /*write memory*/
357 *(cb_addr + ((*index)++)) = write_mem_start;
358
359 return 0;
360}
361
362static int mdfld_dbi_flush_cb(struct mdfld_dsi_dbi_output *dbi_output, int pipe)
363{
364 u32 cmd_phy = dbi_output->dbi_cb_phy;
365 u32 *index = &dbi_output->cb_write;
366 int reg_offset = pipe ? MIPIC_REG_OFFSET : 0;
367 struct drm_device *dev = dbi_output->dev;
368
369 if (*index == 0 || !dbi_output)
370 return 0;
371
372 REG_WRITE((MIPIA_CMD_LEN_REG + reg_offset), 0x010505);
373 REG_WRITE((MIPIA_CMD_ADD_REG + reg_offset), cmd_phy | 3);
374
375 *index = 0;
376
377 /* FIXME: unlock command buffer */
378 spin_unlock(&dbi_output->cb_lock);
379 return 0;
380}
381
382static int mdfld_dpu_update_pipe(struct mdfld_dsi_dbi_output *dbi_output,
383 struct mdfld_dbi_dpu_info *dpu_info, int pipe)
384{
385 struct drm_device *dev = dbi_output->dev;
386 struct drm_psb_private *dev_priv = dev->dev_private;
387 mdfld_plane_t cursor_plane = MDFLD_CURSORA;
388 mdfld_plane_t fb_plane = MDFLD_PLANEA;
389 mdfld_plane_t overlay_plane = MDFLD_OVERLAYA;
390 int ret = 0;
391 u32 plane_mask = MDFLD_PIPEA_PLANE_MASK;
392
393 /* Damaged rects on this pipe */
394 if (pipe) {
395 cursor_plane = MDFLD_CURSORC;
396 fb_plane = MDFLD_PLANEC;
397 overlay_plane = MDFLD_OVERLAYC;
398 plane_mask = MDFLD_PIPEC_PLANE_MASK;
399 }
400
401 /*update cursor which assigned to @pipe*/
402 if (dpu_info->pending & (1 << cursor_plane))
403 mdfld_dpu_cursor_plane_flush(dpu_info, cursor_plane);
404
405 /*update fb which assigned to @pipe*/
406 if (dpu_info->pending & (1 << fb_plane))
407 mdfld_dpu_fb_plane_flush(dpu_info, fb_plane);
408
409 /* TODO: update overlay */
410 if (dpu_info->pending & (1 << overlay_plane))
411 mdfld_dpu_overlay_plane_flush(dpu_info, overlay_plane);
412
413 /* Flush damage area to panel fb */
414 if (dpu_info->pending & plane_mask) {
415 ret = mdfld_dbi_prepare_cb(dbi_output, dpu_info, pipe);
416 /*
417 * TODO: remove b_dsr_enable later,
418 * added it so that text console could boot smoothly
419 */
420 /* Clean pending flags on this pipe */
421 if (!ret && dev_priv->b_dsr_enable) {
422 dpu_info->pending &= ~plane_mask;
423 /* Reset overlay pipe damage rect */
424 mdfld_dpu_init_damage(dpu_info, pipe);
425 }
426 }
427 return ret;
428}
429
430static int mdfld_dpu_update_fb(struct drm_device *dev)
431{
432 struct drm_crtc *crtc;
433 struct psb_intel_crtc *psb_crtc;
434 struct mdfld_dsi_dbi_output **dbi_output;
435 struct drm_psb_private *dev_priv = dev->dev_private;
436 struct mdfld_dbi_dpu_info *dpu_info = dev_priv->dbi_dpu_info;
437 bool pipe_updated[2];
438 unsigned long irq_flags;
439 u32 dpll_reg = MRST_DPLL_A;
440 u32 dspcntr_reg = DSPACNTR;
441 u32 pipeconf_reg = PIPEACONF;
442 u32 dsplinoff_reg = DSPALINOFF;
443 u32 dspsurf_reg = DSPASURF;
444 u32 mipi_state_reg = MIPIA_INTR_STAT_REG;
445 u32 reg_offset = 0;
446 int pipe;
447 int i;
448 int ret;
449
450 dbi_output = dpu_info->dbi_outputs;
451 pipe_updated[0] = pipe_updated[1] = false;
452
453 if (!gma_power_begin(dev, true))
454 return -EAGAIN;
455
456 /* Try to prevent any new damage reports */
457 if (!spin_trylock_irqsave(&dpu_info->dpu_update_lock, irq_flags))
458 return -EAGAIN;
459
460 for (i = 0; i < dpu_info->dbi_output_num; i++) {
461 crtc = dbi_output[i]->base.base.crtc;
462 psb_crtc = (crtc) ? to_psb_intel_crtc(crtc) : NULL;
463
464 pipe = dbi_output[i]->channel_num ? 2 : 0;
465
466 if (pipe == 2) {
467 dspcntr_reg = DSPCCNTR;
468 pipeconf_reg = PIPECCONF;
469 dsplinoff_reg = DSPCLINOFF;
470 dspsurf_reg = DSPCSURF;
471 reg_offset = MIPIC_REG_OFFSET;
472 }
473
474 if (!(REG_READ((MIPIA_GEN_FIFO_STAT_REG + reg_offset))
475 & (1 << 27)) ||
476 !(REG_READ(dpll_reg) & DPLL_VCO_ENABLE) ||
477 !(REG_READ(dspcntr_reg) & DISPLAY_PLANE_ENABLE) ||
478 !(REG_READ(pipeconf_reg) & DISPLAY_PLANE_ENABLE)) {
479 dev_err(dev->dev,
480 "DBI FIFO is busy, DSI %d state %x\n",
481 pipe,
482 REG_READ(mipi_state_reg + reg_offset));
483 continue;
484 }
485
486 /*
487 * If DBI output is in a exclusive state then the pipe
488 * change won't be updated
489 */
490 if (dbi_output[i]->dbi_panel_on &&
491 !(dbi_output[i]->mode_flags & MODE_SETTING_ON_GOING) &&
492 !(psb_crtc &&
493 psb_crtc->mode_flags & MODE_SETTING_ON_GOING) &&
494 !(dbi_output[i]->mode_flags & MODE_SETTING_IN_DSR)) {
495 ret = mdfld_dpu_update_pipe(dbi_output[i],
496 dpu_info, dbi_output[i]->channel_num ? 2 : 0);
497 if (!ret)
498 pipe_updated[i] = true;
499 }
500 }
501
502 for (i = 0; i < dpu_info->dbi_output_num; i++)
503 if (pipe_updated[i])
504 mdfld_dbi_flush_cb(dbi_output[i],
505 dbi_output[i]->channel_num ? 2 : 0);
506
507 spin_unlock_irqrestore(&dpu_info->dpu_update_lock, irq_flags);
508 gma_power_end(dev);
509 return 0;
510}
511
512static int __mdfld_dbi_exit_dsr(struct mdfld_dsi_dbi_output *dbi_output,
513 int pipe)
514{
515 struct drm_device *dev = dbi_output->dev;
516 struct drm_crtc *crtc = dbi_output->base.base.crtc;
517 struct psb_intel_crtc *psb_crtc = (crtc) ? to_psb_intel_crtc(crtc)
518 : NULL;
519 u32 reg_val;
520 u32 dpll_reg = MRST_DPLL_A;
521 u32 pipeconf_reg = PIPEACONF;
522 u32 dspcntr_reg = DSPACNTR;
523 u32 dspbase_reg = DSPABASE;
524 u32 dspsurf_reg = DSPASURF;
525 u32 reg_offset = 0;
526
527 if (!dbi_output)
528 return 0;
529
530 /*if mode setting on-going, back off*/
531 if ((dbi_output->mode_flags & MODE_SETTING_ON_GOING) ||
532 (psb_crtc && psb_crtc->mode_flags & MODE_SETTING_ON_GOING))
533 return -EAGAIN;
534
535 if (pipe == 2) {
536 dpll_reg = MRST_DPLL_A;
537 pipeconf_reg = PIPECCONF;
538 dspcntr_reg = DSPCCNTR;
539 dspbase_reg = MDFLD_DSPCBASE;
540 dspsurf_reg = DSPCSURF;
541
542 reg_offset = MIPIC_REG_OFFSET;
543 }
544
545 if (!ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND, true))
546 return -EAGAIN;
547
548 /* Enable DPLL */
549 reg_val = REG_READ(dpll_reg);
550 if (!(reg_val & DPLL_VCO_ENABLE)) {
551
552 if (reg_val & MDFLD_PWR_GATE_EN) {
553 reg_val &= ~MDFLD_PWR_GATE_EN;
554 REG_WRITE(dpll_reg, reg_val);
555 REG_READ(dpll_reg);
556 udelay(500);
557 }
558
559 reg_val |= DPLL_VCO_ENABLE;
560 REG_WRITE(dpll_reg, reg_val);
561 REG_READ(dpll_reg);
562 udelay(500);
563
564 /* FIXME: add timeout */
565 while (!(REG_READ(pipeconf_reg) & PIPECONF_DSIPLL_LOCK))
566 cpu_relax();
567 }
568
569 /* Enable pipe */
570 reg_val = REG_READ(pipeconf_reg);
571 if (!(reg_val & PIPEACONF_ENABLE)) {
572 reg_val |= PIPEACONF_ENABLE;
573 REG_WRITE(pipeconf_reg, reg_val);
574 REG_READ(pipeconf_reg);
575 udelay(500);
576 mdfldWaitForPipeEnable(dev, pipe);
577 }
578
579 /* Enable plane */
580 reg_val = REG_READ(dspcntr_reg);
581 if (!(reg_val & DISPLAY_PLANE_ENABLE)) {
582 reg_val |= DISPLAY_PLANE_ENABLE;
583 REG_WRITE(dspcntr_reg, reg_val);
584 REG_READ(dspcntr_reg);
585 udelay(500);
586 }
587
588 ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND);
589
590 /*clean IN_DSR flag*/
591 dbi_output->mode_flags &= ~MODE_SETTING_IN_DSR;
592
593 return 0;
594}
595
596int mdfld_dpu_exit_dsr(struct drm_device *dev)
597{
598 struct mdfld_dsi_dbi_output **dbi_output;
599 struct drm_psb_private *dev_priv = dev->dev_private;
600 struct mdfld_dbi_dpu_info *dpu_info = dev_priv->dbi_dpu_info;
601 int i;
602 int pipe;
603
604 dbi_output = dpu_info->dbi_outputs;
605
606 for (i = 0; i < dpu_info->dbi_output_num; i++) {
607 /* If this output is not in DSR mode, don't call exit dsr */
608 if (dbi_output[i]->mode_flags & MODE_SETTING_IN_DSR)
609 __mdfld_dbi_exit_dsr(dbi_output[i],
610 dbi_output[i]->channel_num ? 2 : 0);
611 }
612
613 /* Enable TE interrupt */
614 for (i = 0; i < dpu_info->dbi_output_num; i++) {
615 /* If this output is not in DSR mode, don't call exit dsr */
616 pipe = dbi_output[i]->channel_num ? 2 : 0;
617 if (dbi_output[i]->dbi_panel_on && pipe) {
618 mdfld_disable_te(dev, 0);
619 mdfld_enable_te(dev, 2);
620 } else if (dbi_output[i]->dbi_panel_on && !pipe) {
621 mdfld_disable_te(dev, 2);
622 mdfld_enable_te(dev, 0);
623 }
624 }
625 return 0;
626}
627
628static int mdfld_dpu_enter_dsr(struct drm_device *dev)
629{
630 struct drm_psb_private *dev_priv = dev->dev_private;
631 struct mdfld_dbi_dpu_info *dpu_info = dev_priv->dbi_dpu_info;
632 struct mdfld_dsi_dbi_output **dbi_output;
633 int i;
634
635 dbi_output = dpu_info->dbi_outputs;
636
637 for (i = 0; i < dpu_info->dbi_output_num; i++) {
638 /* If output is off or already in DSR state, don't re-enter */
639 if (dbi_output[i]->dbi_panel_on &&
640 !(dbi_output[i]->mode_flags & MODE_SETTING_IN_DSR)) {
641 mdfld_dsi_dbi_enter_dsr(dbi_output[i],
642 dbi_output[i]->channel_num ? 2 : 0);
643 }
644 }
645
646 return 0;
647}
648
649static void mdfld_dbi_dpu_timer_func(unsigned long data)
650{
651 struct drm_device *dev = (struct drm_device *)data;
652 struct drm_psb_private *dev_priv = dev->dev_private;
653 struct mdfld_dbi_dpu_info *dpu_info = dev_priv->dbi_dpu_info;
654 struct timer_list *dpu_timer = &dpu_info->dpu_timer;
655 unsigned long flags;
656
657 if (dpu_info->pending) {
658 dpu_info->idle_count = 0;
659 /* Update panel fb with damaged area */
660 mdfld_dpu_update_fb(dev);
661 } else {
662 dpu_info->idle_count++;
663 }
664
665 if (dpu_info->idle_count >= MDFLD_MAX_IDLE_COUNT) {
666 mdfld_dpu_enter_dsr(dev);
667 /* Stop timer by return */
668 return;
669 }
670
671 spin_lock_irqsave(&dpu_info->dpu_timer_lock, flags);
672 if (!timer_pending(dpu_timer)) {
673 dpu_timer->expires = jiffies + MDFLD_DSR_DELAY;
674 add_timer(dpu_timer);
675 }
676 spin_unlock_irqrestore(&dpu_info->dpu_timer_lock, flags);
677}
678
679void mdfld_dpu_update_panel(struct drm_device *dev)
680{
681 struct drm_psb_private *dev_priv = dev->dev_private;
682 struct mdfld_dbi_dpu_info *dpu_info = dev_priv->dbi_dpu_info;
683
684 if (dpu_info->pending) {
685 dpu_info->idle_count = 0;
686
687 /*update panel fb with damaged area*/
688 mdfld_dpu_update_fb(dev);
689 } else {
690 dpu_info->idle_count++;
691 }
692
693 if (dpu_info->idle_count >= MDFLD_MAX_IDLE_COUNT) {
694 /*enter dsr*/
695 mdfld_dpu_enter_dsr(dev);
696 }
697}
698
699static int mdfld_dbi_dpu_timer_init(struct drm_device *dev,
700 struct mdfld_dbi_dpu_info *dpu_info)
701{
702 struct timer_list *dpu_timer = &dpu_info->dpu_timer;
703 unsigned long flags;
704
705 spin_lock_init(&dpu_info->dpu_timer_lock);
706 spin_lock_irqsave(&dpu_info->dpu_timer_lock, flags);
707
708 init_timer(dpu_timer);
709
710 dpu_timer->data = (unsigned long)dev;
711 dpu_timer->function = mdfld_dbi_dpu_timer_func;
712 dpu_timer->expires = jiffies + MDFLD_DSR_DELAY;
713
714 spin_unlock_irqrestore(&dpu_info->dpu_timer_lock, flags);
715
716 return 0;
717}
718
719void mdfld_dbi_dpu_timer_start(struct mdfld_dbi_dpu_info *dpu_info)
720{
721 struct timer_list *dpu_timer = &dpu_info->dpu_timer;
722 unsigned long flags;
723
724 spin_lock_irqsave(&dpu_info->dpu_timer_lock, flags);
725 if (!timer_pending(dpu_timer)) {
726 dpu_timer->expires = jiffies + MDFLD_DSR_DELAY;
727 add_timer(dpu_timer);
728 }
729 spin_unlock_irqrestore(&dpu_info->dpu_timer_lock, flags);
730}
731
732int mdfld_dbi_dpu_init(struct drm_device *dev)
733{
734 struct drm_psb_private *dev_priv = dev->dev_private;
735 struct mdfld_dbi_dpu_info *dpu_info = dev_priv->dbi_dpu_info;
736
737 if (!dpu_info || IS_ERR(dpu_info)) {
738 dpu_info = kzalloc(sizeof(struct mdfld_dbi_dpu_info),
739 GFP_KERNEL);
740 if (!dpu_info) {
741 DRM_ERROR("No memory\n");
742 return -ENOMEM;
743 }
744 dev_priv->dbi_dpu_info = dpu_info;
745 }
746
747 dpu_info->dev = dev;
748
749 dpu_info->cursors[0].size = MDFLD_CURSOR_SIZE;
750 dpu_info->cursors[1].size = MDFLD_CURSOR_SIZE;
751
752 /*init dpu_update_lock*/
753 spin_lock_init(&dpu_info->dpu_update_lock);
754
755 /*init dpu refresh timer*/
756 mdfld_dbi_dpu_timer_init(dev, dpu_info);
757
758 /*init pipe damage area*/
759 mdfld_dpu_init_damage(dpu_info, 0);
760 mdfld_dpu_init_damage(dpu_info, 2);
761
762 return 0;
763}
764
765void mdfld_dbi_dpu_exit(struct drm_device *dev)
766{
767 struct drm_psb_private *dev_priv = dev->dev_private;
768 struct mdfld_dbi_dpu_info *dpu_info = dev_priv->dbi_dpu_info;
769
770 if (!dpu_info)
771 return;
772
773 del_timer_sync(&dpu_info->dpu_timer);
774 kfree(dpu_info);
775 dev_priv->dbi_dpu_info = NULL;
776}
777
778
diff --git a/drivers/staging/gma500/mdfld_dsi_output.c b/drivers/staging/gma500/mdfld_dsi_output.c
index 3286c3da4d70..7536095c30a0 100644
--- a/drivers/staging/gma500/mdfld_dsi_output.c
+++ b/drivers/staging/gma500/mdfld_dsi_output.c
@@ -46,7 +46,7 @@ module_param (LABC_control, int, 0644);
46 * we don't need 'movl' everytime we send them. 46 * we don't need 'movl' everytime we send them.
47 * FIXME: these datas were provided by OEM, we should get them from GCT. 47 * FIXME: these datas were provided by OEM, we should get them from GCT.
48 **/ 48 **/
49static const u32 mdfld_dbi_mcs_hysteresis[] = { 49static u32 mdfld_dbi_mcs_hysteresis[] = {
50 0x42000f57, 0x8c006400, 0xff00bf00, 0xffffffff, 50 0x42000f57, 0x8c006400, 0xff00bf00, 0xffffffff,
51 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 51 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
52 0x38000aff, 0x82005000, 0xff00ab00, 0xffffffff, 52 0x38000aff, 0x82005000, 0xff00ab00, 0xffffffff,
@@ -54,16 +54,16 @@ static const u32 mdfld_dbi_mcs_hysteresis[] = {
54 0x000000ff, 54 0x000000ff,
55}; 55};
56 56
57static const u32 mdfld_dbi_mcs_display_profile[] = { 57static u32 mdfld_dbi_mcs_display_profile[] = {
58 0x50281450, 0x0000c882, 0x00000000, 0x00000000, 58 0x50281450, 0x0000c882, 0x00000000, 0x00000000,
59 0x00000000, 59 0x00000000,
60}; 60};
61 61
62static const u32 mdfld_dbi_mcs_kbbc_profile[] = { 62static u32 mdfld_dbi_mcs_kbbc_profile[] = {
63 0x00ffcc60, 0x00000000, 0x00000000, 0x00000000, 63 0x00ffcc60, 0x00000000, 0x00000000, 0x00000000,
64}; 64};
65 65
66static const u32 mdfld_dbi_mcs_gamma_profile[] = { 66static u32 mdfld_dbi_mcs_gamma_profile[] = {
67 0x81111158, 0x88888888, 0x88888888, 67 0x81111158, 0x88888888, 0x88888888,
68}; 68};
69 69
diff --git a/drivers/staging/gma500/mdfld_intel_display.c b/drivers/staging/gma500/mdfld_intel_display.c
index ac74a8d00b58..aa2ff559383d 100644
--- a/drivers/staging/gma500/mdfld_intel_display.c
+++ b/drivers/staging/gma500/mdfld_intel_display.c
@@ -28,10 +28,7 @@
28#include "psb_intel_display.h" 28#include "psb_intel_display.h"
29#include "mdfld_dsi_dbi.h" 29#include "mdfld_dsi_dbi.h"
30#include "mdfld_dsi_dpi.h" 30#include "mdfld_dsi_dpi.h"
31//#include "mdfld_dsi_output.h"
32#ifdef CONFIG_MDFLD_DSI_DPU
33#include "mdfld_dsi_dbi_dpu.h" 31#include "mdfld_dsi_dbi_dpu.h"
34#endif
35 32
36#include <linux/pm_runtime.h> 33#include <linux/pm_runtime.h>
37 34
@@ -232,25 +229,23 @@ static int mdfld_intel_crtc_cursor_set(struct drm_crtc *crtc,
232 REG_WRITE(base, addr); 229 REG_WRITE(base, addr);
233 gma_power_end(dev); 230 gma_power_end(dev);
234 } 231 }
235#if 0 232 /* unpin the old GEM object */
236 /* FIXME: COnvert to GEM */ 233 if (psb_intel_crtc->cursor_obj) {
237 /* unpin the old bo */ 234 gt = container_of(psb_intel_crtc->cursor_obj,
238 if (psb_intel_crtc->cursor_bo && psb_intel_crtc->cursor_bo != bo) { 235 struct gtt_range, gem);
239 mode_dev->bo_unpin_for_scanout(dev, psb_intel_crtc->cursor_bo); 236 psb_gtt_unpin(gt);
240 psb_intel_crtc->cursor_bo = bo; 237 drm_gem_object_unreference(psb_intel_crtc->cursor_obj);
238 psb_intel_crtc->cursor_obj = obj;
241 } 239 }
242#endif
243 return 0; 240 return 0;
244} 241}
245 242
246static int mdfld_intel_crtc_cursor_move(struct drm_crtc *crtc, int x, int y) 243static int mdfld_intel_crtc_cursor_move(struct drm_crtc *crtc, int x, int y)
247{ 244{
248 struct drm_device *dev = crtc->dev; 245 struct drm_device *dev = crtc->dev;
249#ifndef CONFIG_MDFLD_DSI_DPU
250 struct drm_psb_private * dev_priv = (struct drm_psb_private *)dev->dev_private; 246 struct drm_psb_private * dev_priv = (struct drm_psb_private *)dev->dev_private;
251#else 247 struct mdfld_dbi_dpu_info *dpu_info = dev_priv->dbi_dpu_info;
252 struct psb_drm_dpu_rect rect; 248 struct psb_drm_dpu_rect rect;
253#endif
254 struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc); 249 struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc);
255 int pipe = psb_intel_crtc->pipe; 250 int pipe = psb_intel_crtc->pipe;
256 uint32_t pos = CURAPOS; 251 uint32_t pos = CURAPOS;
@@ -260,29 +255,25 @@ static int mdfld_intel_crtc_cursor_move(struct drm_crtc *crtc, int x, int y)
260 255
261 switch (pipe) { 256 switch (pipe) {
262 case 0: 257 case 0:
263#ifndef CONFIG_MDFLD_DSI_DPU 258 if (dpu_info) {
264 if (!(dev_priv->dsr_fb_update & MDFLD_DSR_CURSOR_0)) 259 rect.x = x;
265 mdfld_dsi_dbi_exit_dsr (dev, MDFLD_DSR_CURSOR_0); 260 rect.y = y;
266#else /*CONFIG_MDFLD_DSI_DPU*/
267 rect.x = x;
268 rect.y = y;
269 261
270 mdfld_dbi_dpu_report_damage(dev, MDFLD_CURSORA, &rect); 262 mdfld_dbi_dpu_report_damage(dev, MDFLD_CURSORA, &rect);
271 mdfld_dpu_exit_dsr(dev); 263 mdfld_dpu_exit_dsr(dev);
272#endif 264 } else if (!(dev_priv->dsr_fb_update & MDFLD_DSR_CURSOR_0))
265 mdfld_dsi_dbi_exit_dsr(dev, MDFLD_DSR_CURSOR_0);
273 break; 266 break;
274 case 1: 267 case 1:
275 pos = CURBPOS; 268 pos = CURBPOS;
276 base = CURBBASE; 269 base = CURBBASE;
277 break; 270 break;
278 case 2: 271 case 2:
279#ifndef CONFIG_MDFLD_DSI_DPU 272 if (dpu_info) {
280 if (!(dev_priv->dsr_fb_update & MDFLD_DSR_CURSOR_2)) 273 mdfld_dbi_dpu_report_damage(dev, MDFLD_CURSORC, &rect);
281 mdfld_dsi_dbi_exit_dsr (dev, MDFLD_DSR_CURSOR_2); 274 mdfld_dpu_exit_dsr(dev);
282#else /*CONFIG_MDFLD_DSI_DPU*/ 275 } else if (!(dev_priv->dsr_fb_update & MDFLD_DSR_CURSOR_2))
283 mdfld_dbi_dpu_report_damage(dev, MDFLD_CURSORC, &rect); 276 mdfld_dsi_dbi_exit_dsr(dev, MDFLD_DSR_CURSOR_2);
284 mdfld_dpu_exit_dsr(dev);
285#endif
286 pos = CURCPOS; 277 pos = CURCPOS;
287 base = CURCBASE; 278 base = CURCBASE;
288 break; 279 break;
diff --git a/drivers/staging/gma500/mdfld_output.c b/drivers/staging/gma500/mdfld_output.c
index ffa2c1f0c192..ee55f87ba1fd 100644
--- a/drivers/staging/gma500/mdfld_output.c
+++ b/drivers/staging/gma500/mdfld_output.c
@@ -30,6 +30,7 @@
30#include "mdfld_dsi_dpi.h" 30#include "mdfld_dsi_dpi.h"
31#include "mdfld_dsi_output.h" 31#include "mdfld_dsi_output.h"
32#include "mdfld_output.h" 32#include "mdfld_output.h"
33#include "mdfld_dsi_dbi_dpu.h"
33 34
34#include "displays/tpo_cmd.h" 35#include "displays/tpo_cmd.h"
35#include "displays/tpo_vid.h" 36#include "displays/tpo_vid.h"
@@ -39,6 +40,17 @@
39#include "displays/pyr_vid.h" 40#include "displays/pyr_vid.h"
40/* #include "displays/hdmi.h" */ 41/* #include "displays/hdmi.h" */
41 42
43static int mdfld_dual_mipi;
44static int mdfld_hdmi;
45static int mdfld_dpu;
46
47module_param(mdfld_dual_mipi, int, 0600);
48MODULE_PARM_DESC(mdfld_dual_mipi, "Enable dual MIPI configuration");
49module_param(mdfld_hdmi, int, 0600);
50MODULE_PARM_DESC(mdfld_hdmi, "Enable Medfield HDMI");
51module_param(mdfld_dpu, int, 0600);
52MODULE_PARM_DESC(mdfld_dpu, "Enable Medfield DPU");
53
42/* For now a single type per device is all we cope with */ 54/* For now a single type per device is all we cope with */
43int mdfld_get_panel_type(struct drm_device *dev, int pipe) 55int mdfld_get_panel_type(struct drm_device *dev, int pipe)
44{ 56{
@@ -134,15 +146,25 @@ int mdfld_output_init(struct drm_device *dev)
134 dev_info(dev->dev, "panel 1: type is %d\n", type); 146 dev_info(dev->dev, "panel 1: type is %d\n", type);
135 init_panel(dev, 0, type); 147 init_panel(dev, 0, type);
136 148
137#ifdef CONFIG_MDFD_DUAL_MIPI 149 if (mdfld_dual_mipi) {
138 /* MIPI panel 2 */ 150 /* MIPI panel 2 */
139 type = mdfld_get_panel_type(dev, 2); 151 type = mdfld_get_panel_type(dev, 2);
140 dev_info(dev->dev, "panel 2: type is %d\n", type); 152 dev_info(dev->dev, "panel 2: type is %d\n", type);
141 init_panel(dev, 2, type); 153 init_panel(dev, 2, type);
142#endif 154 }
143#ifdef CONFIG_MDFD_HDMI 155 if (mdfld_hdmi)
144 /* HDMI panel */ 156 /* HDMI panel */
145 init_panel(dev, 0, HDMI); 157 init_panel(dev, 0, HDMI);
146#endif
147 return 0; 158 return 0;
148} 159}
160
161void mdfld_output_setup(struct drm_device *dev)
162{
163 /* FIXME: this is not the right place for this stuff ! */
164 if (IS_MFLD(dev)) {
165 if (mdfld_dpu)
166 mdfld_dbi_dpu_init(dev);
167 else
168 mdfld_dbi_dsr_init(dev);
169 }
170} \ No newline at end of file
diff --git a/drivers/staging/gma500/mdfld_output.h b/drivers/staging/gma500/mdfld_output.h
index e747fdb8913d..daf33e7df9d5 100644
--- a/drivers/staging/gma500/mdfld_output.h
+++ b/drivers/staging/gma500/mdfld_output.h
@@ -36,4 +36,6 @@ void mdfld_disable_crtc (struct drm_device *dev, int pipe);
36extern const struct drm_crtc_helper_funcs mdfld_helper_funcs; 36extern const struct drm_crtc_helper_funcs mdfld_helper_funcs;
37extern const struct drm_crtc_funcs mdfld_intel_crtc_funcs; 37extern const struct drm_crtc_funcs mdfld_intel_crtc_funcs;
38 38
39extern void mdfld_output_setup(struct drm_device *dev);
40
39#endif 41#endif
diff --git a/drivers/staging/gma500/mdfld_pyr_cmd.c b/drivers/staging/gma500/mdfld_pyr_cmd.c
index 5f38e8df3759..523f2d8fe4f1 100644
--- a/drivers/staging/gma500/mdfld_pyr_cmd.c
+++ b/drivers/staging/gma500/mdfld_pyr_cmd.c
@@ -29,7 +29,7 @@
29#include "mdfld_dsi_dpi.h" 29#include "mdfld_dsi_dpi.h"
30#include "mdfld_dsi_output.h" 30#include "mdfld_dsi_output.h"
31#include "mdfld_output.h" 31#include "mdfld_output.h"
32 32#include "mdfld_dsi_dbi_dpu.h"
33#include "mdfld_dsi_pkg_sender.h" 33#include "mdfld_dsi_pkg_sender.h"
34 34
35#include "displays/pyr_cmd.h" 35#include "displays/pyr_cmd.h"
@@ -374,16 +374,11 @@ static void pyr_dsi_dbi_commit(struct drm_encoder *encoder)
374 374
375 if (dbi_output->channel_num == 1) { 375 if (dbi_output->channel_num == 1) {
376 dev_priv->dsr_fb_update |= MDFLD_DSR_2D_3D_2; 376 dev_priv->dsr_fb_update |= MDFLD_DSR_2D_3D_2;
377#ifdef CONFIG_MDFLD_DSI_DPU
378 /* If DPU enabled report a fullscreen damage */ 377 /* If DPU enabled report a fullscreen damage */
379 mdfld_dbi_dpu_report_damage(dev, MDFLD_PLANEC, &rect); 378 mdfld_dbi_dpu_report_damage(dev, MDFLD_PLANEC, &rect);
380#endif
381 } else { 379 } else {
382 dev_priv->dsr_fb_update |= MDFLD_DSR_2D_3D_0; 380 dev_priv->dsr_fb_update |= MDFLD_DSR_2D_3D_0;
383
384#ifdef CONFIG_MDFLD_DSI_DPU
385 mdfld_dbi_dpu_report_damage(dev, MDFLD_PLANEA, &rect); 381 mdfld_dbi_dpu_report_damage(dev, MDFLD_PLANEA, &rect);
386#endif
387 } 382 }
388 dbi_output->mode_flags |= MODE_SETTING_ENCODER_DONE; 383 dbi_output->mode_flags |= MODE_SETTING_ENCODER_DONE;
389} 384}
diff --git a/drivers/staging/gma500/mdfld_tpo_cmd.c b/drivers/staging/gma500/mdfld_tpo_cmd.c
index 4cf7647257f9..c7f7c9c19bc1 100644
--- a/drivers/staging/gma500/mdfld_tpo_cmd.c
+++ b/drivers/staging/gma500/mdfld_tpo_cmd.c
@@ -29,7 +29,7 @@
29#include "mdfld_dsi_dpi.h" 29#include "mdfld_dsi_dpi.h"
30#include "mdfld_dsi_output.h" 30#include "mdfld_dsi_output.h"
31#include "mdfld_output.h" 31#include "mdfld_output.h"
32 32#include "mdfld_dsi_dbi_dpu.h"
33#include "mdfld_dsi_pkg_sender.h" 33#include "mdfld_dsi_pkg_sender.h"
34 34
35#include "displays/tpo_cmd.h" 35#include "displays/tpo_cmd.h"
@@ -359,15 +359,11 @@ static void mdfld_dsi_dbi_commit(struct drm_encoder *encoder)
359 359
360 if (dbi_output->channel_num == 1) { 360 if (dbi_output->channel_num == 1) {
361 dev_priv->dsr_fb_update |= MDFLD_DSR_2D_3D_2; 361 dev_priv->dsr_fb_update |= MDFLD_DSR_2D_3D_2;
362#ifdef CONFIG_MDFLD_DSI_DPU
363 /*if dpu enabled report a fullscreen damage*/ 362 /*if dpu enabled report a fullscreen damage*/
364 mdfld_dbi_dpu_report_damage(dev, MDFLD_PLANEC, &rect); 363 mdfld_dbi_dpu_report_damage(dev, MDFLD_PLANEC, &rect);
365#endif
366 } else { 364 } else {
367 dev_priv->dsr_fb_update |= MDFLD_DSR_2D_3D_0; 365 dev_priv->dsr_fb_update |= MDFLD_DSR_2D_3D_0;
368#ifdef CONFIG_MDFLD_DSI_DPU
369 mdfld_dbi_dpu_report_damage(dev, MDFLD_PLANEA, &rect); 366 mdfld_dbi_dpu_report_damage(dev, MDFLD_PLANEA, &rect);
370#endif
371 } 367 }
372 dbi_output->mode_flags |= MODE_SETTING_ENCODER_DONE; 368 dbi_output->mode_flags |= MODE_SETTING_ENCODER_DONE;
373} 369}
diff --git a/drivers/staging/gma500/psb_drv.c b/drivers/staging/gma500/psb_drv.c
index 4b740aac2a42..b2cdce7b97ef 100644
--- a/drivers/staging/gma500/psb_drv.c
+++ b/drivers/staging/gma500/psb_drv.c
@@ -421,15 +421,7 @@ static int psb_driver_load(struct drm_device *dev, unsigned long chipset)
421 421
422#if defined(CONFIG_DRM_PSB_MFLD) 422#if defined(CONFIG_DRM_PSB_MFLD)
423 /* FIXME: this is not the right place for this stuff ! */ 423 /* FIXME: this is not the right place for this stuff ! */
424 if (IS_MFLD(dev)) { 424 mdfld_output_setup(dev);
425#ifdef CONFIG_MDFLD_DSI_DPU
426 /*init dpu info*/
427 mdfld_dbi_dpu_init(dev);
428#else
429 mdfld_dbi_dsr_init(dev);
430#endif /*CONFIG_MDFLD_DSI_DPU*/
431 /* INIT_WORK(&dev_priv->te_work, mdfld_te_handler_work);*/
432 }
433#endif 425#endif
434 if (drm_psb_no_fb == 0) { 426 if (drm_psb_no_fb == 0) {
435 psb_modeset_init(dev); 427 psb_modeset_init(dev);
@@ -444,6 +436,7 @@ static int psb_driver_load(struct drm_device *dev, unsigned long chipset)
444 436
445 switch (psb_intel_output->type) { 437 switch (psb_intel_output->type) {
446 case INTEL_OUTPUT_LVDS: 438 case INTEL_OUTPUT_LVDS:
439 case INTEL_OUTPUT_MIPI:
447 ret = gma_backlight_init(dev); 440 ret = gma_backlight_init(dev);
448 break; 441 break;
449 } 442 }