diff options
author | Alan Cox <alan@linux.intel.com> | 2011-07-15 12:35:49 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2011-07-15 13:05:08 -0400 |
commit | 3a970ac1b14cf1a49076d69369aa75a23d4ad2db (patch) | |
tree | 3127d9283a87f2f5d8cda61522de225b96b31e72 | |
parent | 3caa89e933646263cb4efedd5660dba00a107b51 (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/Makefile | 1 | ||||
-rw-r--r-- | drivers/staging/gma500/mdfld_dsi_dbi.c | 19 | ||||
-rw-r--r-- | drivers/staging/gma500/mdfld_dsi_dbi_dpu.c | 778 | ||||
-rw-r--r-- | drivers/staging/gma500/mdfld_dsi_output.c | 8 | ||||
-rw-r--r-- | drivers/staging/gma500/mdfld_intel_display.c | 49 | ||||
-rw-r--r-- | drivers/staging/gma500/mdfld_output.c | 42 | ||||
-rw-r--r-- | drivers/staging/gma500/mdfld_output.h | 2 | ||||
-rw-r--r-- | drivers/staging/gma500/mdfld_pyr_cmd.c | 7 | ||||
-rw-r--r-- | drivers/staging/gma500/mdfld_tpo_cmd.c | 6 | ||||
-rw-r--r-- | drivers/staging/gma500/psb_drv.c | 11 |
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 | ||
51 | obj-$(CONFIG_DRM_PSB) += psb_gfx.o | 52 | obj-$(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 | ||
331 | static void mdfld_dbi_output_exit_dsr(struct mdfld_dsi_dbi_output *dbi_output, | 330 | static 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 | ||
567 | void mdfld_dsi_controller_dbi_init(struct mdfld_dsi_config *dsi_config, | 565 | void 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; |
768 | out_err1: | 757 | out_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 | |||
35 | static 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 | } | ||
98 | cursor_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 | |||
132 | static 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 */ | ||
154 | static 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 | |||
161 | int 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 | |||
196 | int 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 | |||
232 | int 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 | |||
249 | static 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 | |||
272 | static 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 | |||
307 | static 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 | */ | ||
316 | static 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 | |||
362 | static 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 | |||
382 | static 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 | |||
430 | static 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 | |||
512 | static 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 | |||
596 | int 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 | |||
628 | static 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 | |||
649 | static 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 | |||
679 | void 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 | |||
699 | static 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 | |||
719 | void 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 | |||
732 | int 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 | |||
765 | void 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 | **/ |
49 | static const u32 mdfld_dbi_mcs_hysteresis[] = { | 49 | static 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 | ||
57 | static const u32 mdfld_dbi_mcs_display_profile[] = { | 57 | static u32 mdfld_dbi_mcs_display_profile[] = { |
58 | 0x50281450, 0x0000c882, 0x00000000, 0x00000000, | 58 | 0x50281450, 0x0000c882, 0x00000000, 0x00000000, |
59 | 0x00000000, | 59 | 0x00000000, |
60 | }; | 60 | }; |
61 | 61 | ||
62 | static const u32 mdfld_dbi_mcs_kbbc_profile[] = { | 62 | static u32 mdfld_dbi_mcs_kbbc_profile[] = { |
63 | 0x00ffcc60, 0x00000000, 0x00000000, 0x00000000, | 63 | 0x00ffcc60, 0x00000000, 0x00000000, 0x00000000, |
64 | }; | 64 | }; |
65 | 65 | ||
66 | static const u32 mdfld_dbi_mcs_gamma_profile[] = { | 66 | static 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 | ||
246 | static int mdfld_intel_crtc_cursor_move(struct drm_crtc *crtc, int x, int y) | 243 | static 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 | ||
43 | static int mdfld_dual_mipi; | ||
44 | static int mdfld_hdmi; | ||
45 | static int mdfld_dpu; | ||
46 | |||
47 | module_param(mdfld_dual_mipi, int, 0600); | ||
48 | MODULE_PARM_DESC(mdfld_dual_mipi, "Enable dual MIPI configuration"); | ||
49 | module_param(mdfld_hdmi, int, 0600); | ||
50 | MODULE_PARM_DESC(mdfld_hdmi, "Enable Medfield HDMI"); | ||
51 | module_param(mdfld_dpu, int, 0600); | ||
52 | MODULE_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 */ |
43 | int mdfld_get_panel_type(struct drm_device *dev, int pipe) | 55 | int 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 | |||
161 | void 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); | |||
36 | extern const struct drm_crtc_helper_funcs mdfld_helper_funcs; | 36 | extern const struct drm_crtc_helper_funcs mdfld_helper_funcs; |
37 | extern const struct drm_crtc_funcs mdfld_intel_crtc_funcs; | 37 | extern const struct drm_crtc_funcs mdfld_intel_crtc_funcs; |
38 | 38 | ||
39 | extern 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 | } |