gma500: Medfield support
[linux-2.6/linux-acpi-2.6/ibm-acpi-2.6.git] / drivers / staging / gma500 / mdfld_tpo_cmd.c
blobd2e1818bb412635e290e022daf50168e42777ddb
1 /*
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
13 * Software.
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.
23 * Authors:
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"
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;
42 bool use_gct = false;
44 mode = kzalloc(sizeof(*mode), GFP_KERNEL);
45 if (!mode)
46 return NULL;
48 if (use_gct) {
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) | \
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;
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;
92 drm_mode_set_name(mode);
93 drm_mode_set_crtcinfo(mode, 0);
95 mode->type |= DRM_MODE_TYPE_PREFERRED;
97 return mode;
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);
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);
120 return true;
123 static void mdfld_dsi_dbi_set_power(struct drm_encoder *encoder, bool on)
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 drm_device *dev = dbi_output->dev;*/
130 struct drm_device *dev = encoder->dev;
131 struct drm_psb_private *dev_priv = dev->dev_private;
132 u32 reg_offset = 0;
133 int pipe = (dbi_output->channel_num == 0) ? 0 : 2;
135 dev_dbg(dev->dev, "pipe %d : %s, panel on: %s\n",
136 pipe, on ? "On" : "Off",
137 dbi_output->dbi_panel_on ? "True" : "False");
139 if (pipe == 2) {
140 if (on)
141 dev_priv->dual_mipi = true;
142 else
143 dev_priv->dual_mipi = false;
144 reg_offset = MIPIC_REG_OFFSET;
145 } else {
146 if (!on)
147 dev_priv->dual_mipi = false;
150 if (!gma_power_begin(dev, true)) {
151 dev_err(dev->dev, "hw begin failed\n");
152 return;
155 if (on) {
156 if (dbi_output->dbi_panel_on)
157 goto out_err;
159 ret = mdfld_dsi_dbi_update_power(dbi_output, DRM_MODE_DPMS_ON);
160 if (ret) {
161 dev_err(dev->dev, "power on error\n");
162 goto out_err;
165 dbi_output->dbi_panel_on = true;
167 if (pipe == 2)
168 dev_priv->dbi_panel_on2 = true;
169 else
170 dev_priv->dbi_panel_on = true;
171 mdfld_enable_te(dev, pipe);
172 } else {
173 if (!dbi_output->dbi_panel_on && !dbi_output->first_boot)
174 goto out_err;
176 dbi_output->dbi_panel_on = false;
177 dbi_output->first_boot = false;
179 if (pipe == 2)
180 dev_priv->dbi_panel_on2 = false;
181 else
182 dev_priv->dbi_panel_on = false;
184 mdfld_disable_te(dev, pipe);
186 ret = mdfld_dsi_dbi_update_power(dbi_output, DRM_MODE_DPMS_OFF);
187 if (ret) {
188 dev_err(dev->dev, "power on error\n");
189 goto out_err;
193 out_err:
194 gma_power_end(dev);
196 if (ret)
197 dev_err(dev->dev, "failed\n");
201 static void mdfld_dsi_dbi_mode_set(struct drm_encoder *encoder,
202 struct drm_display_mode *mode,
203 struct drm_display_mode *adjusted_mode)
205 int ret = 0;
206 struct drm_device *dev = encoder->dev;
207 struct drm_psb_private *dev_priv = dev->dev_private;
208 struct mdfld_dsi_encoder *dsi_encoder = MDFLD_DSI_ENCODER(encoder);
209 struct mdfld_dsi_dbi_output *dsi_output =
210 MDFLD_DSI_DBI_OUTPUT(dsi_encoder);
211 struct mdfld_dsi_config *dsi_config =
212 mdfld_dsi_encoder_get_config(dsi_encoder);
213 struct mdfld_dsi_connector *dsi_connector = dsi_config->connector;
214 int pipe = dsi_connector->pipe;
215 u8 param = 0;
217 /* Regs */
218 u32 mipi_reg = MIPI;
219 u32 dspcntr_reg = DSPACNTR;
220 u32 pipeconf_reg = PIPEACONF;
221 u32 reg_offset = 0;
223 /* Values */
224 u32 dspcntr_val = dev_priv->dspcntr;
225 u32 pipeconf_val = dev_priv->pipeconf;
226 u32 h_active_area = mode->hdisplay;
227 u32 v_active_area = mode->vdisplay;
228 u32 mipi_val;
230 mipi_val = (PASS_FROM_SPHY_TO_AFE | SEL_FLOPPED_HSTX |
231 TE_TRIGGER_GPIO_PIN);
233 dev_dbg(dev->dev, "mipi_val =0x%x\n", mipi_val);
235 dev_dbg(dev->dev, "type %s\n", (pipe == 2) ? "MIPI2" : "MIPI");
236 dev_dbg(dev->dev, "h %d v %d\n", mode->hdisplay, mode->vdisplay);
238 if (pipe == 2) {
239 mipi_reg = MIPI_C;
240 dspcntr_reg = DSPCCNTR;
241 pipeconf_reg = PIPECCONF;
243 reg_offset = MIPIC_REG_OFFSET;
245 dspcntr_val = dev_priv->dspcntr2;
246 pipeconf_val = dev_priv->pipeconf2;
247 } else {
248 mipi_val |= 0x2; /*two lanes for port A and C respectively*/
251 if (!gma_power_begin(dev, true)) {
252 dev_err(dev->dev, "hw begin failed\n");
253 return;
256 /* Set up pipe related registers */
257 REG_WRITE(mipi_reg, mipi_val);
258 REG_READ(mipi_reg);
260 mdfld_dsi_controller_dbi_init(dsi_config, pipe);
262 msleep(20);
264 REG_WRITE(dspcntr_reg, dspcntr_val);
265 REG_READ(dspcntr_reg);
267 /* 20ms delay before sending exit_sleep_mode */
268 msleep(20);
270 /* Send exit_sleep_mode DCS */
271 ret = mdfld_dsi_dbi_send_dcs(dsi_output, exit_sleep_mode,
272 NULL, 0, CMD_DATA_SRC_SYSTEM_MEM);
273 if (ret) {
274 dev_err(dev->dev, "sent exit_sleep_mode faild\n");
275 goto out_err;
278 /* Send set_tear_on DCS */
279 ret = mdfld_dsi_dbi_send_dcs(dsi_output, set_tear_on,
280 &param, 1, CMD_DATA_SRC_SYSTEM_MEM);
281 if (ret) {
282 dev_err(dev->dev, "%s - sent set_tear_on faild\n", __func__);
283 goto out_err;
286 /* Do some init stuff */
287 mdfld_dsi_brightness_init(dsi_config, pipe);
289 mdfld_dsi_gen_fifo_ready(dev, (MIPIA_GEN_FIFO_STAT_REG + reg_offset),
290 HS_CTRL_FIFO_EMPTY | HS_DATA_FIFO_EMPTY);
292 REG_WRITE(pipeconf_reg, pipeconf_val | PIPEACONF_DSR);
293 REG_READ(pipeconf_reg);
295 /* TODO: this looks ugly, try to move it to CRTC mode setting*/
296 if (pipe == 2)
297 dev_priv->pipeconf2 |= PIPEACONF_DSR;
298 else
299 dev_priv->pipeconf |= PIPEACONF_DSR;
301 dev_dbg(dev->dev, "pipeconf %x\n", REG_READ(pipeconf_reg));
303 ret = mdfld_dsi_dbi_update_area(dsi_output, 0, 0,
304 h_active_area - 1, v_active_area - 1);
305 if (ret) {
306 dev_err(dev->dev, "update area failed\n");
307 goto out_err;
310 out_err:
311 gma_power_end(dev);
313 if (ret)
314 dev_err(dev->dev, "mode set failed\n");
317 static void mdfld_dsi_dbi_prepare(struct drm_encoder *encoder)
319 struct mdfld_dsi_encoder *dsi_encoder = MDFLD_DSI_ENCODER(encoder);
320 struct mdfld_dsi_dbi_output *dbi_output
321 = MDFLD_DSI_DBI_OUTPUT(dsi_encoder);
323 dbi_output->mode_flags |= MODE_SETTING_IN_ENCODER;
324 dbi_output->mode_flags &= ~MODE_SETTING_ENCODER_DONE;
326 mdfld_dsi_dbi_set_power(encoder, false);
329 static void mdfld_dsi_dbi_commit(struct drm_encoder *encoder)
331 struct mdfld_dsi_encoder *dsi_encoder = MDFLD_DSI_ENCODER(encoder);
332 struct mdfld_dsi_dbi_output *dbi_output =
333 MDFLD_DSI_DBI_OUTPUT(dsi_encoder);
334 struct drm_device *dev = dbi_output->dev;
335 struct drm_psb_private *dev_priv = dev->dev_private;
336 struct psb_drm_dpu_rect rect;
338 mdfld_dsi_dbi_set_power(encoder, true);
339 dbi_output->mode_flags &= ~MODE_SETTING_IN_ENCODER;
341 rect.x = rect.y = 0;
342 rect.width = 864;
343 rect.height = 480;
345 if (dbi_output->channel_num == 1) {
346 dev_priv->dsr_fb_update |= MDFLD_DSR_2D_3D_2;
347 #ifdef CONFIG_MDFLD_DSI_DPU
348 /*if dpu enabled report a fullscreen damage*/
349 mdfld_dbi_dpu_report_damage(dev, MDFLD_PLANEC, &rect);
350 #endif
351 } else {
352 dev_priv->dsr_fb_update |= MDFLD_DSR_2D_3D_0;
353 #ifdef CONFIG_MDFLD_DSI_DPU
354 mdfld_dbi_dpu_report_damage(dev, MDFLD_PLANEA, &rect);
355 #endif
357 dbi_output->mode_flags |= MODE_SETTING_ENCODER_DONE;
360 static void mdfld_dsi_dbi_dpms(struct drm_encoder *encoder, int mode)
362 struct mdfld_dsi_encoder *dsi_encoder = MDFLD_DSI_ENCODER(encoder);
363 struct mdfld_dsi_dbi_output *dbi_output
364 = MDFLD_DSI_DBI_OUTPUT(dsi_encoder);
365 struct drm_device *dev = dbi_output->dev;
366 struct drm_psb_private *dev_priv = dev->dev_private;
367 static bool bdispoff;
369 dev_dbg(dev->dev, "%s\n", (mode == DRM_MODE_DPMS_ON ? "on" : "off"));
371 if (mode == DRM_MODE_DPMS_ON) {
373 * FIXME: in case I am wrong!
374 * we don't need to exit dsr here to wake up plane/pipe/pll
375 * if everything goes right, hw_begin will resume them all
376 * during set_power.
378 if (bdispoff)
379 mdfld_dsi_dbi_exit_dsr(dev, MDFLD_DSR_2D_3D, 0, 0);
381 mdfld_dsi_dbi_set_power(encoder, true);
382 /* FIXME if (gbgfxsuspended)
383 gbgfxsuspended = false; */
384 bdispoff = false;
385 dev_priv->dispstatus = true;
386 } else {
388 * I am not sure whether this is the perfect place to
389 * turn rpm on since we still have a lot of CRTC turnning
390 * on work to do.
392 mdfld_dsi_dbi_set_power(encoder, false);
393 bdispoff = true;
394 dev_priv->dispstatus = false;
400 * Update the DBI MIPI Panel Frame Buffer.
402 static void mdfld_dsi_dbi_update_fb(struct mdfld_dsi_dbi_output *dbi_output,
403 int pipe)
405 struct mdfld_dsi_pkg_sender *sender =
406 mdfld_dsi_encoder_get_pkg_sender(&dbi_output->base);
407 struct drm_device *dev = dbi_output->dev;
408 struct drm_crtc *crtc = dbi_output->base.base.crtc;
409 struct psb_intel_crtc *psb_crtc = (crtc) ?
410 to_psb_intel_crtc(crtc) : NULL;
411 u32 dpll_reg = MRST_DPLL_A;
412 u32 dspcntr_reg = DSPACNTR;
413 u32 pipeconf_reg = PIPEACONF;
414 u32 dsplinoff_reg = DSPALINOFF;
415 u32 dspsurf_reg = DSPASURF;
416 u32 reg_offset = 0;
418 /* If mode setting on-going, back off */
419 if ((dbi_output->mode_flags & MODE_SETTING_ON_GOING) ||
420 (psb_crtc && psb_crtc->mode_flags & MODE_SETTING_ON_GOING) ||
421 !(dbi_output->mode_flags & MODE_SETTING_ENCODER_DONE))
422 return;
424 if (pipe == 2) {
425 dspcntr_reg = DSPCCNTR;
426 pipeconf_reg = PIPECCONF;
427 dsplinoff_reg = DSPCLINOFF;
428 dspsurf_reg = DSPCSURF;
429 reg_offset = MIPIC_REG_OFFSET;
432 if (!gma_power_begin(dev, true)) {
433 dev_err(dev->dev, "hw begin failed\n");
434 return;
437 /* Check DBI FIFO status */
438 if (!(REG_READ(dpll_reg) & DPLL_VCO_ENABLE) ||
439 !(REG_READ(dspcntr_reg) & DISPLAY_PLANE_ENABLE) ||
440 !(REG_READ(pipeconf_reg) & DISPLAY_PLANE_ENABLE))
441 goto update_fb_out0;
443 /* Refresh plane changes */
444 REG_WRITE(dsplinoff_reg, REG_READ(dsplinoff_reg));
445 REG_WRITE(dspsurf_reg, REG_READ(dspsurf_reg));
446 REG_READ(dspsurf_reg);
448 mdfld_dsi_send_dcs(sender,
449 write_mem_start,
450 NULL,
452 CMD_DATA_SRC_PIPE,
453 MDFLD_DSI_SEND_PACKAGE);
455 dbi_output->dsr_fb_update_done = true;
456 update_fb_out0:
457 gma_power_end(dev);
460 static int tpo_cmd_get_panel_info(struct drm_device *dev,
461 int pipe,
462 struct panel_info *pi)
464 if (!dev || !pi)
465 return -EINVAL;
467 pi->width_mm = TPO_PANEL_WIDTH;
468 pi->height_mm = TPO_PANEL_HEIGHT;
470 return 0;
474 /* TPO DBI encoder helper funcs */
475 static const struct drm_encoder_helper_funcs mdfld_dsi_dbi_helper_funcs = {
476 .dpms = mdfld_dsi_dbi_dpms,
477 .mode_fixup = mdfld_dsi_dbi_mode_fixup,
478 .prepare = mdfld_dsi_dbi_prepare,
479 .mode_set = mdfld_dsi_dbi_mode_set,
480 .commit = mdfld_dsi_dbi_commit,
483 /* TPO DBI encoder funcs */
484 static const struct drm_encoder_funcs mdfld_dsi_dbi_encoder_funcs = {
485 .destroy = drm_encoder_cleanup,
488 void tpo_cmd_init(struct drm_device *dev, struct panel_funcs *p_funcs)
490 p_funcs->encoder_funcs = &mdfld_dsi_dbi_encoder_funcs;
491 p_funcs->encoder_helper_funcs = &mdfld_dsi_dbi_helper_funcs;
492 p_funcs->get_config_mode = &tpo_cmd_get_config_mode;
493 p_funcs->update_fb = mdfld_dsi_dbi_update_fb;
494 p_funcs->get_panel_info = tpo_cmd_get_panel_info;