Merge branch 'for-linus' of git://git.kernel.dk/linux-block
[pandora-kernel.git] / drivers / staging / gma500 / mdfld_tpo_cmd.c
1 /*
2  * Copyright (c)  2010 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, sublicensen
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  * Thomas Eaton <thomas.g.eaton@intel.com>
25  * Scott Rowe <scott.m.rowe@intel.com>
26  */
27
28 #include "mdfld_dsi_dbi.h"
29 #include "mdfld_dsi_dpi.h"
30 #include "mdfld_dsi_output.h"
31 #include "mdfld_output.h"
32 #include "mdfld_dsi_dbi_dpu.h"
33 #include "mdfld_dsi_pkg_sender.h"
34
35 #include "displays/tpo_cmd.h"
36
37 static struct drm_display_mode *tpo_cmd_get_config_mode(struct drm_device *dev)
38 {
39         struct drm_display_mode *mode;
40         struct drm_psb_private *dev_priv = dev->dev_private;
41         struct mrst_timing_info *ti = &dev_priv->gct_data.DTD;
42         bool use_gct = false;
43
44         mode = kzalloc(sizeof(*mode), GFP_KERNEL);
45         if (!mode)
46                 return NULL;
47
48         if (use_gct) {
49                 dev_dbg(dev->dev, "gct find MIPI panel.\n");
50
51                 mode->hdisplay = (ti->hactive_hi << 8) | ti->hactive_lo;
52                 mode->vdisplay = (ti->vactive_hi << 8) | ti->vactive_lo;
53                 mode->hsync_start = mode->hdisplay + \
54                                 ((ti->hsync_offset_hi << 8) | \
55                                 ti->hsync_offset_lo);
56                 mode->hsync_end = mode->hsync_start + \
57                                 ((ti->hsync_pulse_width_hi << 8) | \
58                                 ti->hsync_pulse_width_lo);
59                 mode->htotal = mode->hdisplay + ((ti->hblank_hi << 8) | \
60                                                                 ti->hblank_lo);
61                 mode->vsync_start = \
62                         mode->vdisplay + ((ti->vsync_offset_hi << 8) | \
63                                                 ti->vsync_offset_lo);
64                 mode->vsync_end = \
65                         mode->vsync_start + ((ti->vsync_pulse_width_hi << 8) | \
66                                                 ti->vsync_pulse_width_lo);
67                 mode->vtotal = mode->vdisplay + \
68                                 ((ti->vblank_hi << 8) | ti->vblank_lo);
69                 mode->clock = ti->pixel_clock * 10;
70
71                 dev_dbg(dev->dev, "hdisplay is %d\n", mode->hdisplay);
72                 dev_dbg(dev->dev, "vdisplay is %d\n", mode->vdisplay);
73                 dev_dbg(dev->dev, "HSS is %d\n", mode->hsync_start);
74                 dev_dbg(dev->dev, "HSE is %d\n", mode->hsync_end);
75                 dev_dbg(dev->dev, "htotal is %d\n", mode->htotal);
76                 dev_dbg(dev->dev, "VSS is %d\n", mode->vsync_start);
77                 dev_dbg(dev->dev, "VSE is %d\n", mode->vsync_end);
78                 dev_dbg(dev->dev, "vtotal is %d\n", mode->vtotal);
79                 dev_dbg(dev->dev, "clock is %d\n", mode->clock);
80         } else {
81                 mode->hdisplay = 864;
82                 mode->vdisplay = 480;
83                 mode->hsync_start = 872;
84                 mode->hsync_end = 876;
85                 mode->htotal = 884;
86                 mode->vsync_start = 482;
87                 mode->vsync_end = 494;
88                 mode->vtotal = 486;
89                 mode->clock = 25777;
90         }
91
92         drm_mode_set_name(mode);
93         drm_mode_set_crtcinfo(mode, 0);
94
95         mode->type |= DRM_MODE_TYPE_PREFERRED;
96
97         return mode;
98 }
99
100 static bool mdfld_dsi_dbi_mode_fixup(struct drm_encoder *encoder,
101                                      struct drm_display_mode *mode,
102                                      struct drm_display_mode *adjusted_mode)
103 {
104         struct drm_device *dev = encoder->dev;
105         struct drm_display_mode *fixed_mode = tpo_cmd_get_config_mode(dev);
106
107         if (fixed_mode) {
108                 adjusted_mode->hdisplay = fixed_mode->hdisplay;
109                 adjusted_mode->hsync_start = fixed_mode->hsync_start;
110                 adjusted_mode->hsync_end = fixed_mode->hsync_end;
111                 adjusted_mode->htotal = fixed_mode->htotal;
112                 adjusted_mode->vdisplay = fixed_mode->vdisplay;
113                 adjusted_mode->vsync_start = fixed_mode->vsync_start;
114                 adjusted_mode->vsync_end = fixed_mode->vsync_end;
115                 adjusted_mode->vtotal = fixed_mode->vtotal;
116                 adjusted_mode->clock = fixed_mode->clock;
117                 drm_mode_set_crtcinfo(adjusted_mode, CRTC_INTERLACE_HALVE_V);
118                 kfree(fixed_mode);
119         }
120         return true;
121 }
122
123 static void mdfld_dsi_dbi_set_power(struct drm_encoder *encoder, bool on)
124 {
125         int ret = 0;
126         struct mdfld_dsi_encoder *dsi_encoder = MDFLD_DSI_ENCODER(encoder);
127         struct mdfld_dsi_dbi_output *dbi_output =
128                                 MDFLD_DSI_DBI_OUTPUT(dsi_encoder);
129         struct mdfld_dsi_config *dsi_config =
130                 mdfld_dsi_encoder_get_config(dsi_encoder);
131         struct mdfld_dsi_pkg_sender *sender =
132                 mdfld_dsi_encoder_get_pkg_sender(dsi_encoder);
133         struct drm_device *dev = encoder->dev;
134         struct drm_psb_private *dev_priv = dev->dev_private;
135         u32 reg_offset = 0;
136         int pipe = (dbi_output->channel_num == 0) ? 0 : 2;
137         u32 data = 0;
138
139         dev_dbg(dev->dev, "pipe %d : %s, panel on: %s\n",
140                         pipe, on ? "On" : "Off",
141                         dbi_output->dbi_panel_on ? "True" : "False");
142
143         if (pipe == 2) {
144                 if (on)
145                         dev_priv->dual_mipi = true;
146                 else
147                         dev_priv->dual_mipi = false;
148                 reg_offset = MIPIC_REG_OFFSET;
149         } else {
150                 if (!on)
151                         dev_priv->dual_mipi = false;
152         }
153
154         if (!gma_power_begin(dev, true)) {
155                 dev_err(dev->dev, "hw begin failed\n");
156                 return;
157         }
158
159         if (on) {
160                 if (dbi_output->dbi_panel_on)
161                         goto out_err;
162
163                 ret = mdfld_dsi_dbi_update_power(dbi_output, DRM_MODE_DPMS_ON);
164                 if (ret) {
165                         dev_err(dev->dev, "power on error\n");
166                         goto out_err;
167                 }
168
169                 dbi_output->dbi_panel_on = true;
170
171                 if (pipe == 2)
172                         dev_priv->dbi_panel_on2 = true;
173                 else
174                         dev_priv->dbi_panel_on = true;
175                 mdfld_enable_te(dev, pipe);
176         } else {
177                 if (!dbi_output->dbi_panel_on && !dbi_output->first_boot)
178                         goto out_err;
179
180                 dbi_output->dbi_panel_on = false;
181                 dbi_output->first_boot = false;
182
183                 if (pipe == 2)
184                         dev_priv->dbi_panel_on2 = false;
185                 else
186                         dev_priv->dbi_panel_on = false;
187
188                 mdfld_disable_te(dev, pipe);
189
190                 ret = mdfld_dsi_dbi_update_power(dbi_output, DRM_MODE_DPMS_OFF);
191                 if (ret) {
192                         dev_err(dev->dev, "power on error\n");
193                         goto out_err;
194                 }
195         }
196
197         /*
198          * FIXME: this is a WA for TPO panel crash on DPMS on & off around
199          * 83 times. the root cause of this issue is that Booster in
200          * drvIC crashed. Add this WA so that we can resume the driver IC
201          * once we found that booster has a fault
202          */
203         mdfld_dsi_get_power_mode(dsi_config,
204                                 &data,
205                                 MDFLD_DSI_HS_TRANSMISSION);
206
207         if (on && data && !(data & (1 << 7))) {
208                 /* Soft reset */
209                 mdfld_dsi_send_dcs(sender,
210                                    DCS_SOFT_RESET,
211                                    NULL,
212                                    0,
213                                    CMD_DATA_SRC_PIPE,
214                                    MDFLD_DSI_SEND_PACKAGE);
215
216                 /* Init drvIC */
217                 if (dbi_output->p_funcs->drv_ic_init)
218                         dbi_output->p_funcs->drv_ic_init(dsi_config,
219                                                          pipe);
220         }
221  
222 out_err:
223         gma_power_end(dev);
224         if (ret)
225                 dev_err(dev->dev, "failed\n");
226 }
227
228
229 static void mdfld_dsi_dbi_mode_set(struct drm_encoder *encoder,
230                                    struct drm_display_mode *mode,
231                                    struct drm_display_mode *adjusted_mode)
232 {
233         int ret = 0;
234         struct drm_device *dev = encoder->dev;
235         struct drm_psb_private *dev_priv = dev->dev_private;
236         struct mdfld_dsi_encoder *dsi_encoder = MDFLD_DSI_ENCODER(encoder);
237         struct mdfld_dsi_dbi_output *dsi_output =
238                                         MDFLD_DSI_DBI_OUTPUT(dsi_encoder);
239         struct mdfld_dsi_config *dsi_config =
240                                 mdfld_dsi_encoder_get_config(dsi_encoder);
241         struct mdfld_dsi_connector *dsi_connector = dsi_config->connector;
242         int pipe = dsi_connector->pipe;
243         u8 param = 0;
244
245         /* Regs */
246         u32 mipi_reg = MIPI;
247         u32 dspcntr_reg = DSPACNTR;
248         u32 pipeconf_reg = PIPEACONF;
249         u32 reg_offset = 0;
250
251         /* Values */
252         u32 dspcntr_val = dev_priv->dspcntr;
253         u32 pipeconf_val = dev_priv->pipeconf;
254         u32 h_active_area = mode->hdisplay;
255         u32 v_active_area = mode->vdisplay;
256         u32 mipi_val;
257
258         mipi_val = (PASS_FROM_SPHY_TO_AFE | SEL_FLOPPED_HSTX |
259                                                 TE_TRIGGER_GPIO_PIN);
260
261         dev_dbg(dev->dev, "mipi_val =0x%x\n", mipi_val);
262
263         dev_dbg(dev->dev, "type %s\n", (pipe == 2) ? "MIPI2" : "MIPI");
264         dev_dbg(dev->dev, "h %d v %d\n", mode->hdisplay, mode->vdisplay);
265
266         if (pipe == 2) {
267                 mipi_reg = MIPI_C;
268                 dspcntr_reg = DSPCCNTR;
269                 pipeconf_reg = PIPECCONF;
270
271                 reg_offset = MIPIC_REG_OFFSET;
272
273                 dspcntr_val = dev_priv->dspcntr2;
274                 pipeconf_val = dev_priv->pipeconf2;
275         } else {
276                 mipi_val |= 0x2; /*two lanes for port A and C respectively*/
277         }
278
279         if (!gma_power_begin(dev, true)) {
280                 dev_err(dev->dev, "hw begin failed\n");
281                 return;
282         }
283
284         REG_WRITE(dspcntr_reg, dspcntr_val);
285         REG_READ(dspcntr_reg);
286
287         /* 20ms delay before sending exit_sleep_mode */
288         msleep(20);
289
290         /* Send exit_sleep_mode DCS */
291         ret = mdfld_dsi_dbi_send_dcs(dsi_output, DCS_EXIT_SLEEP_MODE,
292                                         NULL, 0, CMD_DATA_SRC_SYSTEM_MEM);
293         if (ret) {
294                 dev_err(dev->dev, "sent exit_sleep_mode faild\n");
295                 goto out_err;
296         }
297
298         /* Send set_tear_on DCS */
299         ret = mdfld_dsi_dbi_send_dcs(dsi_output, DCS_SET_TEAR_ON,
300                                         &param, 1, CMD_DATA_SRC_SYSTEM_MEM);
301         if (ret) {
302                 dev_err(dev->dev, "%s - sent set_tear_on faild\n", __func__);
303                 goto out_err;
304         }
305
306         /* Do some init stuff */
307         REG_WRITE(pipeconf_reg, pipeconf_val | PIPEACONF_DSR);
308         REG_READ(pipeconf_reg);
309
310         /* TODO: this looks ugly, try to move it to CRTC mode setting*/
311         if (pipe == 2)
312                 dev_priv->pipeconf2 |= PIPEACONF_DSR;
313         else
314                 dev_priv->pipeconf |= PIPEACONF_DSR;
315
316         dev_dbg(dev->dev, "pipeconf %x\n",  REG_READ(pipeconf_reg));
317
318         ret = mdfld_dsi_dbi_update_area(dsi_output, 0, 0,
319                                 h_active_area - 1, v_active_area - 1);
320         if (ret) {
321                 dev_err(dev->dev, "update area failed\n");
322                 goto out_err;
323         }
324
325 out_err:
326         gma_power_end(dev);
327
328         if (ret)
329                 dev_err(dev->dev, "mode set failed\n");
330 }
331
332 static void mdfld_dsi_dbi_prepare(struct drm_encoder *encoder)
333 {
334         struct mdfld_dsi_encoder *dsi_encoder = MDFLD_DSI_ENCODER(encoder);
335         struct mdfld_dsi_dbi_output *dbi_output
336                                 = MDFLD_DSI_DBI_OUTPUT(dsi_encoder);
337
338         dbi_output->mode_flags |= MODE_SETTING_IN_ENCODER;
339         dbi_output->mode_flags &= ~MODE_SETTING_ENCODER_DONE;
340
341         mdfld_dsi_dbi_set_power(encoder, false);
342 }
343
344 static void mdfld_dsi_dbi_commit(struct drm_encoder *encoder)
345 {
346         struct mdfld_dsi_encoder *dsi_encoder = MDFLD_DSI_ENCODER(encoder);
347         struct mdfld_dsi_dbi_output *dbi_output =
348                                         MDFLD_DSI_DBI_OUTPUT(dsi_encoder);
349         struct drm_device *dev = dbi_output->dev;
350         struct drm_psb_private *dev_priv = dev->dev_private;
351         struct psb_drm_dpu_rect rect;
352
353         mdfld_dsi_dbi_set_power(encoder, true);
354         dbi_output->mode_flags &= ~MODE_SETTING_IN_ENCODER;
355
356         rect.x = rect.y = 0;
357         rect.width = 864;
358         rect.height = 480;
359
360         if (dbi_output->channel_num == 1) {
361                 dev_priv->dsr_fb_update |= MDFLD_DSR_2D_3D_2;
362                 /*if dpu enabled report a fullscreen damage*/
363                 mdfld_dbi_dpu_report_damage(dev, MDFLD_PLANEC, &rect);
364         } else {
365                 dev_priv->dsr_fb_update |= MDFLD_DSR_2D_3D_0;
366                 mdfld_dbi_dpu_report_damage(dev, MDFLD_PLANEA, &rect);
367         }
368         dbi_output->mode_flags |= MODE_SETTING_ENCODER_DONE;
369 }
370
371 static void mdfld_dsi_dbi_dpms(struct drm_encoder *encoder, int mode)
372 {
373         struct mdfld_dsi_encoder *dsi_encoder = MDFLD_DSI_ENCODER(encoder);
374         struct mdfld_dsi_dbi_output *dbi_output
375                                 = MDFLD_DSI_DBI_OUTPUT(dsi_encoder);
376         struct drm_device *dev = dbi_output->dev;
377         struct drm_psb_private *dev_priv = dev->dev_private;
378         static bool bdispoff;
379
380         dev_dbg(dev->dev, "%s\n", (mode == DRM_MODE_DPMS_ON ? "on" : "off"));
381
382         if (mode == DRM_MODE_DPMS_ON) {
383                 /*
384                  * FIXME: in case I am wrong!
385                  * we don't need to exit dsr here to wake up plane/pipe/pll
386                  * if everything goes right, hw_begin will resume them all
387                  * during set_power.
388                  */
389                 if (bdispoff /* FIXME && gbgfxsuspended */) {
390                         mdfld_dsi_dbi_exit_dsr(dev, MDFLD_DSR_2D_3D);
391                         bdispoff = false;
392                         dev_priv->dispstatus = true;
393                 }
394
395                 mdfld_dsi_dbi_set_power(encoder, true);
396                 /* FIXME if (gbgfxsuspended)
397                         gbgfxsuspended = false; */
398         } else {
399                 /*
400                  * I am not sure whether this is the perfect place to
401                  * turn rpm on since we still have a lot of CRTC turnning
402                  * on work to do.
403                  */
404                 bdispoff = true;
405                 dev_priv->dispstatus = false;
406                 mdfld_dsi_dbi_set_power(encoder, false);
407         }
408 }
409
410
411 /*
412  * Update the DBI MIPI Panel Frame Buffer.
413  */
414 static void mdfld_dsi_dbi_update_fb(struct mdfld_dsi_dbi_output *dbi_output,
415                                                                 int pipe)
416 {
417         struct mdfld_dsi_pkg_sender *sender =
418                 mdfld_dsi_encoder_get_pkg_sender(&dbi_output->base);
419         struct drm_device *dev = dbi_output->dev;
420         struct drm_crtc *crtc = dbi_output->base.base.crtc;
421         struct psb_intel_crtc *psb_crtc = (crtc) ?
422                                         to_psb_intel_crtc(crtc) : NULL;
423         u32 dpll_reg = MRST_DPLL_A;
424         u32 dspcntr_reg = DSPACNTR;
425         u32 pipeconf_reg = PIPEACONF;
426         u32 dsplinoff_reg = DSPALINOFF;
427         u32 dspsurf_reg = DSPASURF;
428         u32 reg_offset = 0;
429
430         /* If mode setting on-going, back off */
431         if ((dbi_output->mode_flags & MODE_SETTING_ON_GOING) ||
432                 (psb_crtc && psb_crtc->mode_flags & MODE_SETTING_ON_GOING) ||
433                 !(dbi_output->mode_flags & MODE_SETTING_ENCODER_DONE))
434                 return;
435
436         if (pipe == 2) {
437                 dspcntr_reg = DSPCCNTR;
438                 pipeconf_reg = PIPECCONF;
439                 dsplinoff_reg = DSPCLINOFF;
440                 dspsurf_reg = DSPCSURF;
441                 reg_offset = MIPIC_REG_OFFSET;
442         }
443
444         if (!gma_power_begin(dev, true)) {
445                 dev_err(dev->dev, "hw begin failed\n");
446                 return;
447         }
448
449         /* Check DBI FIFO status */
450         if (!(REG_READ(dpll_reg) & DPLL_VCO_ENABLE) ||
451            !(REG_READ(dspcntr_reg) & DISPLAY_PLANE_ENABLE) ||
452            !(REG_READ(pipeconf_reg) & DISPLAY_PLANE_ENABLE))
453                 goto update_fb_out0;
454
455         /* Refresh plane changes */
456         REG_WRITE(dsplinoff_reg, REG_READ(dsplinoff_reg));
457         REG_WRITE(dspsurf_reg, REG_READ(dspsurf_reg));
458         REG_READ(dspsurf_reg);
459
460         mdfld_dsi_send_dcs(sender,
461                            DCS_WRITE_MEM_START,
462                            NULL,
463                            0,
464                            CMD_DATA_SRC_PIPE,
465                            MDFLD_DSI_SEND_PACKAGE);
466
467         dbi_output->dsr_fb_update_done = true;
468 update_fb_out0:
469         gma_power_end(dev);
470 }
471
472 static int tpo_cmd_get_panel_info(struct drm_device *dev,
473                                 int pipe,
474                                 struct panel_info *pi)
475 {
476         if (!dev || !pi)
477                 return -EINVAL;
478
479         pi->width_mm = TPO_PANEL_WIDTH;
480         pi->height_mm = TPO_PANEL_HEIGHT;
481
482         return 0;
483 }
484
485
486 /* TPO DBI encoder helper funcs */
487 static const struct drm_encoder_helper_funcs mdfld_dsi_dbi_helper_funcs = {
488         .dpms = mdfld_dsi_dbi_dpms,
489         .mode_fixup = mdfld_dsi_dbi_mode_fixup,
490         .prepare = mdfld_dsi_dbi_prepare,
491         .mode_set = mdfld_dsi_dbi_mode_set,
492         .commit = mdfld_dsi_dbi_commit,
493 };
494
495 /* TPO DBI encoder funcs */
496 static const struct drm_encoder_funcs mdfld_dsi_dbi_encoder_funcs = {
497         .destroy = drm_encoder_cleanup,
498 };
499
500 void tpo_cmd_init(struct drm_device *dev, struct panel_funcs *p_funcs)
501 {
502         p_funcs->encoder_funcs = &mdfld_dsi_dbi_encoder_funcs;
503         p_funcs->encoder_helper_funcs = &mdfld_dsi_dbi_helper_funcs;
504         p_funcs->get_config_mode = &tpo_cmd_get_config_mode;
505         p_funcs->update_fb = mdfld_dsi_dbi_update_fb;
506         p_funcs->get_panel_info = tpo_cmd_get_panel_info;
507         p_funcs->reset = mdfld_dsi_panel_reset;
508         p_funcs->drv_ic_init = mdfld_dsi_brightness_init;
509 }