2 * Copyright (c) 2010 Intel Corporation
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:
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
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.
24 * Thomas Eaton <thomas.g.eaton@intel.com>
25 * Scott Rowe <scott.m.rowe@intel.com>
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"
35 #include "displays/tpo_cmd.h"
37 static struct drm_display_mode *tpo_cmd_get_config_mode(struct drm_device *dev)
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;
44 mode = kzalloc(sizeof(*mode), GFP_KERNEL);
49 dev_dbg(dev->dev, "gct find MIPI panel.\n");
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) | \
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) | \
62 mode->vdisplay + ((ti->vsync_offset_hi << 8) | \
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;
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);
83 mode->hsync_start = 872;
84 mode->hsync_end = 876;
86 mode->vsync_start = 482;
87 mode->vsync_end = 494;
92 drm_mode_set_name(mode);
93 drm_mode_set_crtcinfo(mode, 0);
95 mode->type |= DRM_MODE_TYPE_PREFERRED;
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)
104 struct drm_device *dev = encoder->dev;
105 struct drm_display_mode *fixed_mode = tpo_cmd_get_config_mode(dev);
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);
123 static void mdfld_dsi_dbi_set_power(struct drm_encoder *encoder, bool on)
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;
136 int pipe = (dbi_output->channel_num == 0) ? 0 : 2;
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");
145 dev_priv->dual_mipi = true;
147 dev_priv->dual_mipi = false;
148 reg_offset = MIPIC_REG_OFFSET;
151 dev_priv->dual_mipi = false;
154 if (!gma_power_begin(dev, true)) {
155 dev_err(dev->dev, "hw begin failed\n");
160 if (dbi_output->dbi_panel_on)
163 ret = mdfld_dsi_dbi_update_power(dbi_output, DRM_MODE_DPMS_ON);
165 dev_err(dev->dev, "power on error\n");
169 dbi_output->dbi_panel_on = true;
172 dev_priv->dbi_panel_on2 = true;
174 dev_priv->dbi_panel_on = true;
175 mdfld_enable_te(dev, pipe);
177 if (!dbi_output->dbi_panel_on && !dbi_output->first_boot)
180 dbi_output->dbi_panel_on = false;
181 dbi_output->first_boot = false;
184 dev_priv->dbi_panel_on2 = false;
186 dev_priv->dbi_panel_on = false;
188 mdfld_disable_te(dev, pipe);
190 ret = mdfld_dsi_dbi_update_power(dbi_output, DRM_MODE_DPMS_OFF);
192 dev_err(dev->dev, "power on error\n");
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
203 mdfld_dsi_get_power_mode(dsi_config,
205 MDFLD_DSI_HS_TRANSMISSION);
207 if (on && data && !(data & (1 << 7))) {
209 mdfld_dsi_send_dcs(sender,
214 MDFLD_DSI_SEND_PACKAGE);
217 if (dbi_output->p_funcs->drv_ic_init)
218 dbi_output->p_funcs->drv_ic_init(dsi_config,
225 dev_err(dev->dev, "failed\n");
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)
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;
247 u32 dspcntr_reg = DSPACNTR;
248 u32 pipeconf_reg = PIPEACONF;
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;
258 mipi_val = (PASS_FROM_SPHY_TO_AFE | SEL_FLOPPED_HSTX |
259 TE_TRIGGER_GPIO_PIN);
261 dev_dbg(dev->dev, "mipi_val =0x%x\n", mipi_val);
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);
268 dspcntr_reg = DSPCCNTR;
269 pipeconf_reg = PIPECCONF;
271 reg_offset = MIPIC_REG_OFFSET;
273 dspcntr_val = dev_priv->dspcntr2;
274 pipeconf_val = dev_priv->pipeconf2;
276 mipi_val |= 0x2; /*two lanes for port A and C respectively*/
279 if (!gma_power_begin(dev, true)) {
280 dev_err(dev->dev, "hw begin failed\n");
284 REG_WRITE(dspcntr_reg, dspcntr_val);
285 REG_READ(dspcntr_reg);
287 /* 20ms delay before sending exit_sleep_mode */
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);
294 dev_err(dev->dev, "sent exit_sleep_mode faild\n");
298 /* Send set_tear_on DCS */
299 ret = mdfld_dsi_dbi_send_dcs(dsi_output, DCS_SET_TEAR_ON,
300 ¶m, 1, CMD_DATA_SRC_SYSTEM_MEM);
302 dev_err(dev->dev, "%s - sent set_tear_on faild\n", __func__);
306 /* Do some init stuff */
307 REG_WRITE(pipeconf_reg, pipeconf_val | PIPEACONF_DSR);
308 REG_READ(pipeconf_reg);
310 /* TODO: this looks ugly, try to move it to CRTC mode setting*/
312 dev_priv->pipeconf2 |= PIPEACONF_DSR;
314 dev_priv->pipeconf |= PIPEACONF_DSR;
316 dev_dbg(dev->dev, "pipeconf %x\n", REG_READ(pipeconf_reg));
318 ret = mdfld_dsi_dbi_update_area(dsi_output, 0, 0,
319 h_active_area - 1, v_active_area - 1);
321 dev_err(dev->dev, "update area failed\n");
329 dev_err(dev->dev, "mode set failed\n");
332 static void mdfld_dsi_dbi_prepare(struct drm_encoder *encoder)
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);
338 dbi_output->mode_flags |= MODE_SETTING_IN_ENCODER;
339 dbi_output->mode_flags &= ~MODE_SETTING_ENCODER_DONE;
341 mdfld_dsi_dbi_set_power(encoder, false);
344 static void mdfld_dsi_dbi_commit(struct drm_encoder *encoder)
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;
353 mdfld_dsi_dbi_set_power(encoder, true);
354 dbi_output->mode_flags &= ~MODE_SETTING_IN_ENCODER;
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);
365 dev_priv->dsr_fb_update |= MDFLD_DSR_2D_3D_0;
366 mdfld_dbi_dpu_report_damage(dev, MDFLD_PLANEA, &rect);
368 dbi_output->mode_flags |= MODE_SETTING_ENCODER_DONE;
371 static void mdfld_dsi_dbi_dpms(struct drm_encoder *encoder, int mode)
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;
380 dev_dbg(dev->dev, "%s\n", (mode == DRM_MODE_DPMS_ON ? "on" : "off"));
382 if (mode == DRM_MODE_DPMS_ON) {
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
389 if (bdispoff /* FIXME && gbgfxsuspended */) {
390 mdfld_dsi_dbi_exit_dsr(dev, MDFLD_DSR_2D_3D);
392 dev_priv->dispstatus = true;
395 mdfld_dsi_dbi_set_power(encoder, true);
396 /* FIXME if (gbgfxsuspended)
397 gbgfxsuspended = false; */
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
405 dev_priv->dispstatus = false;
406 mdfld_dsi_dbi_set_power(encoder, false);
412 * Update the DBI MIPI Panel Frame Buffer.
414 static void mdfld_dsi_dbi_update_fb(struct mdfld_dsi_dbi_output *dbi_output,
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;
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))
437 dspcntr_reg = DSPCCNTR;
438 pipeconf_reg = PIPECCONF;
439 dsplinoff_reg = DSPCLINOFF;
440 dspsurf_reg = DSPCSURF;
441 reg_offset = MIPIC_REG_OFFSET;
444 if (!gma_power_begin(dev, true)) {
445 dev_err(dev->dev, "hw begin failed\n");
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))
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);
460 mdfld_dsi_send_dcs(sender,
465 MDFLD_DSI_SEND_PACKAGE);
467 dbi_output->dsr_fb_update_done = true;
472 static int tpo_cmd_get_panel_info(struct drm_device *dev,
474 struct panel_info *pi)
479 pi->width_mm = TPO_PANEL_WIDTH;
480 pi->height_mm = TPO_PANEL_HEIGHT;
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,
495 /* TPO DBI encoder funcs */
496 static const struct drm_encoder_funcs mdfld_dsi_dbi_encoder_funcs = {
497 .destroy = drm_encoder_cleanup,
500 void tpo_cmd_init(struct drm_device *dev, struct panel_funcs *p_funcs)
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;