gma500: Medfield support
[linux-2.6/linux-acpi-2.6/ibm-acpi-2.6.git] / drivers / staging / gma500 / mdfld_dsi_dbi.c
blob15055c85c1d47bf6a710440ae8f8e8c177e38732
1 /*
2 * Copyright © 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, 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:
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 * jim liu <jim.liu@intel.com>
25 * Jackie Li<yaodong.li@intel.com>
28 #include "mdfld_dsi_dbi.h"
29 #include "mdfld_dsi_dbi_dpu.h"
30 #include "mdfld_dsi_pkg_sender.h"
32 #include "psb_powermgmt.h"
33 #include <linux/pm_runtime.h>
35 int enable_gfx_rtpm;
37 extern struct drm_device *gpDrmDevice;
38 extern int gfxrtdelay;
39 int enter_dsr;
40 struct mdfld_dsi_dbi_output *gdbi_output;
41 extern bool gbgfxsuspended;
42 extern int gfxrtdelay;
44 #ifdef CONFIG_GFX_RTPM
45 static void psb_runtimepm_wq_handler(struct work_struct *work);
46 DECLARE_DELAYED_WORK(rtpm_work, psb_runtimepm_wq_handler);
48 void psb_runtimepm_wq_handler(struct work_struct *work)
50 struct drm_psb_private *dev_priv = gpDrmDevice->dev_private;
52 if (drm_psb_ospm && !enable_gfx_rtpm) {
53 pr_info("Enable GFX runtime_pm\n");
54 dev_priv->rpm_enabled = 1;
55 enable_gfx_rtpm = 1;
57 pm_runtime_enable(&gpDrmDevice->pdev->dev);
58 pm_runtime_set_active(&gpDrmDevice->pdev->dev);
60 pm_runtime_allow(&gpDrmDevice->pdev->dev);
63 #endif
67 * set refreshing area
69 int mdfld_dsi_dbi_update_area(struct mdfld_dsi_dbi_output *dbi_output,
70 u16 x1, u16 y1, u16 x2, u16 y2)
72 struct mdfld_dsi_pkg_sender *sender =
73 mdfld_dsi_encoder_get_pkg_sender(&dbi_output->base);
74 u8 param[4];
75 u8 cmd;
76 int err;
78 if (!sender) {
79 WARN_ON(1);
80 return -EINVAL;
83 /*set column*/
84 cmd = set_column_address;
85 param[0] = x1 >> 8;
86 param[1] = x1;
87 param[2] = x2 >> 8;
88 param[3] = x2;
90 err = mdfld_dsi_send_dcs(sender,
91 cmd,
92 param,
94 CMD_DATA_SRC_SYSTEM_MEM,
95 MDFLD_DSI_QUEUE_PACKAGE);
96 if (err) {
97 dev_err(sender->dev->dev, "DCS 0x%x sent failed\n", cmd);
98 goto err_out;
101 /*set page*/
102 cmd = set_page_addr;
103 param[0] = y1 >> 8;
104 param[1] = y1;
105 param[2] = y2 >> 8;
106 param[3] = y2;
108 err = mdfld_dsi_send_dcs(sender,
109 cmd,
110 param,
112 CMD_DATA_SRC_SYSTEM_MEM,
113 MDFLD_DSI_QUEUE_PACKAGE);
114 if (err) {
115 dev_err(sender->dev->dev, "DCS 0x%x sent failed\n", cmd);
116 goto err_out;
119 /*update screen*/
120 err = mdfld_dsi_send_dcs(sender,
121 write_mem_start,
122 NULL,
124 CMD_DATA_SRC_PIPE,
125 MDFLD_DSI_QUEUE_PACKAGE);
126 if (err) {
127 dev_err(sender->dev->dev, "DCS 0x%x sent failed\n", cmd);
128 goto err_out;
130 mdfld_dsi_cmds_kick_out(sender);
131 err_out:
132 return err;
136 * set panel's power state
138 int mdfld_dsi_dbi_update_power(struct mdfld_dsi_dbi_output *dbi_output,
139 int mode)
141 struct drm_device *dev = dbi_output->dev;
142 struct drm_psb_private *dev_priv = dev->dev_private;
143 struct mdfld_dsi_pkg_sender *sender =
144 mdfld_dsi_encoder_get_pkg_sender(&dbi_output->base);
145 u8 param = 0;
146 u32 err = 0;
148 if (!dev_priv->dispstatus && mode != DRM_MODE_DPMS_ON) {
149 dev_err(dev->dev, "%s: already OFF ignoring\n", __func__);
150 return 0;
152 if (dev_priv->dispstatus && mode == DRM_MODE_DPMS_ON) {
153 dev_err(dev->dev, "%s: already ON ignoring\n", __func__);
154 return 0;
157 if (!sender) {
158 WARN_ON(1);
159 return -EINVAL;
162 if (mode == DRM_MODE_DPMS_ON) {
163 /*exit sleep mode*/
164 err = mdfld_dsi_send_dcs(sender,
165 exit_sleep_mode,
166 NULL,
168 CMD_DATA_SRC_SYSTEM_MEM,
169 MDFLD_DSI_QUEUE_PACKAGE);
170 if (err) {
171 dev_err(dev->dev, "DCS 0x%x sent failed\n",
172 exit_sleep_mode);
173 goto power_err;
176 /*set display on*/
177 err = mdfld_dsi_send_dcs(sender,
178 set_display_on,
179 NULL,
181 CMD_DATA_SRC_SYSTEM_MEM,
182 MDFLD_DSI_QUEUE_PACKAGE);
183 if (err) {
184 dev_err(dev->dev, "DCS 0x%x sent failed\n",
185 set_display_on);
186 goto power_err;
189 /* set tear effect on */
190 err = mdfld_dsi_send_dcs(sender,
191 set_tear_on,
192 &param,
194 CMD_DATA_SRC_SYSTEM_MEM,
195 MDFLD_DSI_QUEUE_PACKAGE);
196 if (err) {
197 dev_err(dev->dev, "DCS 0x%x sent failed\n",
198 set_tear_on);
199 goto power_err;
203 * FIXME: remove this later
205 err = mdfld_dsi_send_dcs(sender,
206 write_mem_start,
207 NULL,
209 CMD_DATA_SRC_PIPE,
210 MDFLD_DSI_QUEUE_PACKAGE);
211 if (err) {
212 dev_err(dev->dev, "DCS 0x%x sent failed\n",
213 set_display_on);
214 goto power_err;
216 } else {
217 /*set tear effect off */
218 err = mdfld_dsi_send_dcs(sender,
219 set_tear_off,
220 NULL,
222 CMD_DATA_SRC_SYSTEM_MEM,
223 MDFLD_DSI_QUEUE_PACKAGE);
224 if (err) {
225 dev_err(dev->dev, "DCS 0x%x sent failed\n",
226 set_tear_off);
227 goto power_err;
230 /*set display off*/
231 err = mdfld_dsi_send_dcs(sender,
232 set_display_off,
233 NULL,
235 CMD_DATA_SRC_SYSTEM_MEM,
236 MDFLD_DSI_QUEUE_PACKAGE);
237 if (err) {
238 dev_err(dev->dev, "DCS 0x%x sent failed\n",
239 set_display_off);
240 goto power_err;
243 /*enter sleep mode*/
244 err = mdfld_dsi_send_dcs(sender,
245 enter_sleep_mode,
246 NULL,
248 CMD_DATA_SRC_SYSTEM_MEM,
249 MDFLD_DSI_QUEUE_PACKAGE);
250 if (err) {
251 dev_err(dev->dev, "DCS 0x%x sent failed\n",
252 enter_sleep_mode);
253 goto power_err;
256 mdfld_dsi_cmds_kick_out(sender);
257 power_err:
258 return err;
262 * send a generic DCS command with a parameter list
264 int mdfld_dsi_dbi_send_dcs(struct mdfld_dsi_dbi_output *dbi_output,
265 u8 dcs, u8 *param, u32 num, u8 data_src)
267 struct mdfld_dsi_pkg_sender *sender =
268 mdfld_dsi_encoder_get_pkg_sender(&dbi_output->base);
269 int ret;
271 if (!sender) {
272 WARN_ON(1);
273 return -EINVAL;
276 ret = mdfld_dsi_send_dcs(sender,
277 dcs,
278 param,
279 num,
280 data_src,
281 MDFLD_DSI_SEND_PACKAGE);
283 return ret;
288 * Enter DSR
290 void mdfld_dsi_dbi_enter_dsr(struct mdfld_dsi_dbi_output *dbi_output, int pipe)
292 u32 reg_val;
293 struct drm_device *dev = dbi_output->dev;
294 struct drm_psb_private *dev_priv = dev->dev_private;
295 struct drm_crtc *crtc = dbi_output->base.base.crtc;
296 struct psb_intel_crtc *psb_crtc = (crtc) ?
297 to_psb_intel_crtc(crtc) : NULL;
298 u32 dpll_reg = MRST_DPLL_A;
299 u32 pipeconf_reg = PIPEACONF;
300 u32 dspcntr_reg = DSPACNTR;
302 dev_priv->is_in_idle = true;
304 if (!dbi_output)
305 return;
307 gdbi_output = dbi_output;
308 if ((dbi_output->mode_flags & MODE_SETTING_ON_GOING) ||
309 (psb_crtc && psb_crtc->mode_flags & MODE_SETTING_ON_GOING))
310 return;
312 if (pipe == 2) {
313 dpll_reg = MRST_DPLL_A;
314 pipeconf_reg = PIPECCONF;
315 dspcntr_reg = DSPCCNTR;
318 if (!gma_power_begin(dev, true)) {
319 dev_err(dev->dev, "hw begin failed\n");
320 return;
322 /*disable te interrupts. */
323 mdfld_disable_te(dev, pipe);
325 /*disable plane*/
326 reg_val = REG_READ(dspcntr_reg);
327 if (!(reg_val & DISPLAY_PLANE_ENABLE)) {
328 REG_WRITE(dspcntr_reg, reg_val & ~DISPLAY_PLANE_ENABLE);
329 REG_READ(dspcntr_reg);
331 /*disable pipe*/
332 reg_val = REG_READ(pipeconf_reg);
333 if (!(reg_val & DISPLAY_PLANE_ENABLE)) {
334 reg_val &= ~DISPLAY_PLANE_ENABLE;
335 reg_val |= (PIPECONF_PLANE_OFF | PIPECONF_CURSOR_OFF);
336 REG_WRITE(pipeconf_reg, reg_val);
337 REG_READ(pipeconf_reg);
338 mdfldWaitForPipeDisable(dev, pipe);
341 /*disable DPLL*/
342 reg_val = REG_READ(dpll_reg);
343 if (!(reg_val & DPLL_VCO_ENABLE)) {
344 reg_val &= ~DPLL_VCO_ENABLE;
345 REG_WRITE(dpll_reg, reg_val);
346 REG_READ(dpll_reg);
347 udelay(500);
350 gma_power_end(dev);
351 dbi_output->mode_flags |= MODE_SETTING_IN_DSR;
352 if (pipe == 2) {
353 enter_dsr = 1;
354 /* pm_schedule_suspend(&dev->pdev->dev, gfxrtdelay); */
358 #ifndef CONFIG_MDFLD_DSI_DPU
359 static void mdfld_dbi_output_exit_dsr(struct mdfld_dsi_dbi_output *dbi_output,
360 int pipe, void *p_surfaceAddr, bool check_hw_on_only)
362 struct drm_device *dev = dbi_output->dev;
363 struct drm_psb_private *dev_priv = dev->dev_private;
364 struct drm_crtc *crtc = dbi_output->base.base.crtc;
365 struct psb_intel_crtc *psb_crtc = (crtc) ?
366 to_psb_intel_crtc(crtc) : NULL;
367 u32 reg_val;
368 u32 dpll_reg = MRST_DPLL_A;
369 u32 pipeconf_reg = PIPEACONF;
370 u32 dspcntr_reg = DSPACNTR;
371 u32 dspsurf_reg = DSPASURF;
372 u32 reg_offset = 0;
374 /*if mode setting on-going, back off*/
375 if ((dbi_output->mode_flags & MODE_SETTING_ON_GOING) ||
376 (psb_crtc && psb_crtc->mode_flags & MODE_SETTING_ON_GOING))
377 return;
379 if (pipe == 2) {
380 dpll_reg = MRST_DPLL_A;
381 pipeconf_reg = PIPECCONF;
382 dspcntr_reg = DSPCCNTR;
383 dspsurf_reg = DSPCSURF;
384 reg_offset = MIPIC_REG_OFFSET;
387 if (check_hw_on_only) {
388 if (0/* FIXME!ospm_power_is_hw_on(_DISPLAY_ISLAND)*/) {
389 dev_err(dev->dev, "hw begin failed\n");
390 return;
392 } else if (!gma_power_begin(dev, true)) {
393 dev_err(dev->dev, "hw begin failed\n");
394 return;
397 /*enable DPLL*/
398 reg_val = REG_READ(dpll_reg);
399 if (!(reg_val & DPLL_VCO_ENABLE)) {
401 if (reg_val & MDFLD_PWR_GATE_EN) {
402 reg_val &= ~MDFLD_PWR_GATE_EN;
403 REG_WRITE(dpll_reg, reg_val);
404 REG_READ(dpll_reg);
405 udelay(500);
408 reg_val |= DPLL_VCO_ENABLE;
409 REG_WRITE(dpll_reg, reg_val);
410 REG_READ(dpll_reg);
411 udelay(500);
413 /* Add timeout */
414 while (!(REG_READ(pipeconf_reg) & PIPECONF_DSIPLL_LOCK))
415 cpu_relax();
418 /*enable pipe*/
419 reg_val = REG_READ(pipeconf_reg);
420 if (!(reg_val & PIPEACONF_ENABLE)) {
421 reg_val |= PIPEACONF_ENABLE;
422 REG_WRITE(pipeconf_reg, reg_val);
423 REG_READ(pipeconf_reg);
424 udelay(500);
425 mdfldWaitForPipeEnable(dev, pipe);
428 /*enable plane*/
429 reg_val = REG_READ(dspcntr_reg);
430 if (!(reg_val & DISPLAY_PLANE_ENABLE)) {
431 reg_val |= DISPLAY_PLANE_ENABLE;
432 REG_WRITE(dspcntr_reg, reg_val);
433 REG_READ(dspcntr_reg);
434 udelay(500);
437 /* update the surface base address. */
438 if (p_surfaceAddr)
439 REG_WRITE(dspsurf_reg, *((u32 *)p_surfaceAddr));
441 if (!check_hw_on_only)
442 gma_power_end(dev);
444 /*enable TE interrupt on this pipe*/
445 mdfld_enable_te(dev, pipe);
447 /*clean IN_DSR flag*/
448 dbi_output->mode_flags &= ~MODE_SETTING_IN_DSR;
452 * Exit from DSR
454 void mdfld_dsi_dbi_exit_dsr(struct drm_device *dev, u32 update_src,
455 void *p_surfaceAddr, bool check_hw_on_only)
457 struct drm_psb_private *dev_priv = dev->dev_private;
458 struct mdfld_dbi_dsr_info *dsr_info = dev_priv->dbi_dsr_info;
459 struct mdfld_dsi_dbi_output **dbi_output;
460 int i;
462 dev_priv->is_in_idle = false;
463 dbi_output = dsr_info->dbi_outputs;
465 #ifdef CONFIG_PM_RUNTIME
466 if (!enable_gfx_rtpm) {
467 /* pm_runtime_allow(&gpDrmDevice->pdev->dev); */
468 /* schedule_delayed_work(&rtpm_work, 120 * 1000); */
470 #endif
472 /*for each output, exit dsr*/
473 for (i = 0; i < dsr_info->dbi_output_num; i++) {
474 /*if panel has been turned off, skip*/
475 if (!dbi_output[i]->dbi_panel_on)
476 continue;
477 if (dbi_output[i]->mode_flags & MODE_SETTING_IN_DSR) {
478 enter_dsr = 0;
479 mdfld_dbi_output_exit_dsr(dbi_output[i], dbi_output[i]->channel_num ? 2 : 0, p_surfaceAddr, check_hw_on_only);
482 dev_priv->dsr_fb_update |= update_src;
485 static bool mdfld_dbi_is_in_dsr(struct drm_device *dev)
487 if (REG_READ(MRST_DPLL_A) & DPLL_VCO_ENABLE)
488 return false;
489 if ((REG_READ(PIPEACONF) & PIPEACONF_ENABLE) ||
490 (REG_READ(PIPECCONF) & PIPEACONF_ENABLE))
491 return false;
492 if ((REG_READ(DSPACNTR) & DISPLAY_PLANE_ENABLE) ||
493 (REG_READ(DSPCCNTR) & DISPLAY_PLANE_ENABLE))
494 return false;
496 return true;
499 /* Perodically update dbi panel */
500 void mdfld_dbi_update_panel(struct drm_device *dev, int pipe)
502 struct drm_psb_private *dev_priv = dev->dev_private;
503 struct mdfld_dbi_dsr_info *dsr_info = dev_priv->dbi_dsr_info;
504 struct mdfld_dsi_dbi_output **dbi_outputs;
505 struct mdfld_dsi_dbi_output *dbi_output;
506 int i;
507 int enter_dsr = 0;
508 u32 damage_mask = 0;
510 dbi_outputs = dsr_info->dbi_outputs;
511 dbi_output = pipe ? dbi_outputs[1] : dbi_outputs[0];
513 if (!dbi_output)
514 return;
516 if (pipe == 0)
517 damage_mask = dev_priv->dsr_fb_update & (MDFLD_DSR_DAMAGE_MASK_0);
518 else if (pipe == 2)
519 damage_mask = dev_priv->dsr_fb_update & (MDFLD_DSR_DAMAGE_MASK_2);
520 else
521 return;
523 /*if FB is damaged and panel is on update on-panel FB*/
524 if (damage_mask && dbi_output->dbi_panel_on) {
525 dbi_output->dsr_fb_update_done = false;
527 if (dbi_output->p_funcs->update_fb)
528 dbi_output->p_funcs->update_fb(dbi_output, pipe);
530 if (dev_priv->dsr_enable && dbi_output->dsr_fb_update_done)
531 dev_priv->dsr_fb_update &= ~damage_mask;
533 /*clean IN_DSR flag*/
534 dbi_output->mode_flags &= ~MODE_SETTING_IN_DSR;
536 dbi_output->dsr_idle_count = 0;
537 } else {
538 dbi_output->dsr_idle_count++;
541 /*try to enter DSR*/
542 if (dbi_outputs[0]->dsr_idle_count > 1
543 && dbi_outputs[1]->dsr_idle_count > 1) {
544 for (i = 0; i < dsr_info->dbi_output_num; i++) {
545 if (!mdfld_dbi_is_in_dsr(dev) &&
546 !(dbi_outputs[i]->mode_flags & MODE_SETTING_ON_GOING)) {
547 mdfld_dsi_dbi_enter_dsr(dbi_outputs[i],
548 dbi_outputs[i]->channel_num ? 2 : 0);
549 #if 0
550 enter_dsr = 1;
551 pr_err("%s: enter_dsr = 1\n", __func__);
552 #endif
555 /*schedule rpm suspend after gfxrtdelay*/
556 #ifdef CONFIG_GFX_RTPM
557 if (!dev_priv->rpm_enabled
558 || !enter_dsr
559 /* || (REG_READ(HDMIB_CONTROL) & HDMIB_PORT_EN) */
560 || pm_schedule_suspend(&dev->pdev->dev, gfxrtdelay))
561 dev_warn(dev->dev,
562 "Runtime PM schedule suspend failed, rpm %d\n",
563 dev_priv->rpm_enabled);
564 #endif
568 /*timers for DSR*/
569 static void mdfld_dsi_dbi_dsr_timer_func(unsigned long data)
571 struct drm_device *dev = (struct drm_device *)data;
572 struct drm_psb_private *dev_priv = dev->dev_private;
573 struct mdfld_dbi_dsr_info *dsr_info = dev_priv->dbi_dsr_info;
574 struct timer_list *dsr_timer = &dsr_info->dsr_timer;
575 unsigned long flags;
577 mdfld_dbi_update_panel(dev, 0);
579 if (dsr_info->dsr_idle_count > 1)
580 return;
582 spin_lock_irqsave(&dsr_info->dsr_timer_lock, flags);
583 if (!timer_pending(dsr_timer)) {
584 dsr_timer->expires = jiffies + MDFLD_DSR_DELAY;
585 add_timer(dsr_timer);
587 spin_unlock_irqrestore(&dsr_info->dsr_timer_lock, flags);
590 static int mdfld_dsi_dbi_dsr_timer_init(struct drm_device *dev)
592 struct drm_psb_private *dev_priv = dev->dev_private;
593 struct mdfld_dbi_dsr_info *dsr_info = dev_priv->dbi_dsr_info;
594 struct timer_list *dsr_timer = &dsr_info->dsr_timer;
595 unsigned long flags;
597 spin_lock_init(&dsr_info->dsr_timer_lock);
598 spin_lock_irqsave(&dsr_info->dsr_timer_lock, flags);
600 init_timer(dsr_timer);
602 dsr_timer->data = (unsigned long)dev;
603 dsr_timer->function = mdfld_dsi_dbi_dsr_timer_func;
604 dsr_timer->expires = jiffies + MDFLD_DSR_DELAY;
606 spin_unlock_irqrestore(&dsr_info->dsr_timer_lock, flags);
607 return 0;
610 void mdfld_dbi_dsr_timer_start(struct mdfld_dbi_dsr_info *dsr_info)
612 struct timer_list *dsr_timer = &dsr_info->dsr_timer;
613 unsigned long flags;
615 spin_lock_irqsave(&dsr_info->dsr_timer_lock, flags);
616 if (!timer_pending(dsr_timer)) {
617 dsr_timer->expires = jiffies + MDFLD_DSR_DELAY;
618 add_timer(dsr_timer);
620 spin_unlock_irqrestore(&dsr_info->dsr_timer_lock, flags);
623 int mdfld_dbi_dsr_init(struct drm_device *dev)
625 struct drm_psb_private *dev_priv = dev->dev_private;
626 struct mdfld_dbi_dsr_info *dsr_info = dev_priv->dbi_dsr_info;
628 if (!dsr_info || IS_ERR(dsr_info)) {
629 dsr_info = kzalloc(sizeof(struct mdfld_dbi_dsr_info),
630 GFP_KERNEL);
631 if (!dsr_info) {
632 dev_err(dev->dev, "No memory\n");
633 return -ENOMEM;
635 dev_priv->dbi_dsr_info = dsr_info;
637 return 0;
640 void mdfld_dbi_dsr_exit(struct drm_device *dev)
642 struct drm_psb_private *dev_priv = dev->dev_private;
643 struct mdfld_dbi_dsr_info *dsr_info = dev_priv->dbi_dsr_info;
645 if (!dsr_info) {
646 del_timer_sync(&dsr_info->dsr_timer);
647 kfree(dsr_info);
648 dev_priv->dbi_dsr_info = NULL;
651 #endif
653 void mdfld_dsi_controller_dbi_init(struct mdfld_dsi_config *dsi_config,
654 int pipe)
656 struct drm_device *dev = dsi_config->dev;
657 u32 reg_offset = pipe ? MIPIC_REG_OFFSET : 0;
658 int lane_count = dsi_config->lane_count;
659 u32 val = 0;
661 dev_dbg(dev->dev, "Init DBI interface on pipe %d...\n", pipe);
663 /*un-ready device*/
664 REG_WRITE((MIPIA_DEVICE_READY_REG + reg_offset), 0x00000000);
666 /*init dsi adapter before kicking off*/
667 REG_WRITE((MIPIA_CONTROL_REG + reg_offset), 0x00000018);
669 /*TODO: figure out how to setup these registers*/
670 REG_WRITE((MIPIA_DPHY_PARAM_REG + reg_offset), 0x150c3408);
671 REG_WRITE((MIPIA_CLK_LANE_SWITCH_TIME_CNT_REG + reg_offset),
672 0x000a0014);
673 REG_WRITE((MIPIA_DBI_BW_CTRL_REG + reg_offset), 0x00000400);
674 REG_WRITE((MIPIA_DBI_FIFO_THROTTLE_REG + reg_offset), 0x00000001);
675 REG_WRITE((MIPIA_HS_LS_DBI_ENABLE_REG + reg_offset), 0x00000000);
677 /*enable all interrupts*/
678 REG_WRITE((MIPIA_INTR_EN_REG + reg_offset), 0xffffffff);
679 /*max value: 20 clock cycles of txclkesc*/
680 REG_WRITE((MIPIA_TURN_AROUND_TIMEOUT_REG + reg_offset), 0x0000001f);
681 /*min 21 txclkesc, max: ffffh*/
682 REG_WRITE((MIPIA_DEVICE_RESET_TIMER_REG + reg_offset), 0x0000ffff);
683 /*min: 7d0 max: 4e20*/
684 REG_WRITE((MIPIA_INIT_COUNT_REG + reg_offset), 0x00000fa0);
686 /*set up func_prg*/
687 val |= lane_count;
688 val |= (dsi_config->channel_num << DSI_DBI_VIRT_CHANNEL_OFFSET);
689 val |= DSI_DBI_COLOR_FORMAT_OPTION2;
690 REG_WRITE((MIPIA_DSI_FUNC_PRG_REG + reg_offset), val);
692 REG_WRITE((MIPIA_HS_TX_TIMEOUT_REG + reg_offset), 0x3fffff);
693 REG_WRITE((MIPIA_LP_RX_TIMEOUT_REG + reg_offset), 0xffff);
695 /*de-assert dbi_stall when half of DBI FIFO is empty*/
696 /* REG_WRITE((MIPIA_DBI_FIFO_THROTTLE_REG + reg_offset), 0x00000000); */
698 REG_WRITE((MIPIA_HIGH_LOW_SWITCH_COUNT_REG + reg_offset), 0x46);
699 REG_WRITE((MIPIA_EOT_DISABLE_REG + reg_offset), 0x00000000);
700 REG_WRITE((MIPIA_LP_BYTECLK_REG + reg_offset), 0x00000004);
701 REG_WRITE((MIPIA_DEVICE_READY_REG + reg_offset), 0x00000001);
704 #if 0
705 /*DBI encoder helper funcs*/
706 static const struct drm_encoder_helper_funcs mdfld_dsi_dbi_helper_funcs = {
707 .dpms = mdfld_dsi_dbi_dpms,
708 .mode_fixup = mdfld_dsi_dbi_mode_fixup,
709 .prepare = mdfld_dsi_dbi_prepare,
710 .mode_set = mdfld_dsi_dbi_mode_set,
711 .commit = mdfld_dsi_dbi_commit,
714 /*DBI encoder funcs*/
715 static const struct drm_encoder_funcs mdfld_dsi_dbi_encoder_funcs = {
716 .destroy = drm_encoder_cleanup,
719 #endif
721 static int mdfld_dbi_panel_reset(struct mdfld_dsi_dbi_output *output)
723 unsigned gpio;
724 int ret;
726 switch (output->channel_num) {
727 case 0:
728 gpio = 128;
729 break;
730 case 1:
731 gpio = 34;
732 break;
733 default:
734 pr_err("Invalid output\n");
735 return -EINVAL;
738 ret = gpio_request(gpio, "gfx");
739 if (ret) {
740 pr_err("gpio_rqueset failed\n");
741 return ret;
744 ret = gpio_direction_output(gpio, 1);
745 if (ret) {
746 pr_err("gpio_direction_output failed\n");
747 goto gpio_error;
749 gpio_get_value(128);
750 gpio_error:
751 if (gpio_is_valid(gpio))
752 gpio_free(gpio);
754 return ret;
758 * Init DSI DBI encoder.
759 * Allocate an mdfld_dsi_encoder and attach it to given @dsi_connector
760 * return pointer of newly allocated DBI encoder, NULL on error
762 struct mdfld_dsi_encoder *mdfld_dsi_dbi_init(struct drm_device *dev,
763 struct mdfld_dsi_connector *dsi_connector,
764 struct panel_funcs *p_funcs)
766 struct drm_psb_private *dev_priv = dev->dev_private;
767 struct mdfld_dsi_dbi_output *dbi_output = NULL;
768 struct mdfld_dsi_config *dsi_config;
769 struct drm_connector *connector = NULL;
770 struct drm_encoder *encoder = NULL;
771 struct drm_display_mode *fixed_mode = NULL;
772 struct psb_gtt *pg = dev_priv ? (dev_priv->pg) : NULL;
774 #ifdef CONFIG_MDFLD_DSI_DPU
775 struct mdfld_dbi_dpu_info *dpu_info = dev_priv ? (dev_priv->dbi_dpu_info) : NULL;
776 #else
777 struct mdfld_dbi_dsr_info *dsr_info = dev_priv ? (dev_priv->dbi_dsr_info) : NULL;
778 #endif
779 int ret;
781 if (!pg || !dsi_connector) {
782 WARN_ON(1);
783 return NULL;
786 dbi_output = kzalloc(sizeof(struct mdfld_dsi_dbi_output), GFP_KERNEL);
787 if (!dbi_output) {
788 dev_err(dev->dev, "No memory\n");
789 return NULL;
792 if (dsi_connector->pipe == 0) {
793 dbi_output->channel_num = 0;
794 dev_priv->dbi_output = dbi_output;
795 } else if (dsi_connector->pipe == 2) {
796 dbi_output->channel_num = 1;
797 dev_priv->dbi_output2 = dbi_output;
798 } else {
799 dev_err(dev->dev, "only support 2 DSI outputs\n");
800 goto out_err1;
803 dbi_output->dev = dev;
804 dbi_output->p_funcs = p_funcs;
806 /*panel reset*/
807 ret = mdfld_dbi_panel_reset(dbi_output);
808 if (ret) {
809 dev_err(dev->dev, "reset panel error\n");
810 goto out_err1;
813 /*TODO: get panel info from DDB*/
815 /*get fixed mode*/
816 dsi_config = mdfld_dsi_get_config(dsi_connector);
817 fixed_mode = dsi_config->fixed_mode;
819 dbi_output->panel_fixed_mode = fixed_mode;
821 /*create drm encoder object*/
822 connector = &dsi_connector->base.base;
823 encoder = &dbi_output->base.base;
824 drm_encoder_init(dev,
825 encoder,
826 p_funcs->encoder_funcs,
827 DRM_MODE_ENCODER_MIPI);
828 drm_encoder_helper_add(encoder, p_funcs->encoder_helper_funcs);
830 /*attach to given connector*/
831 drm_mode_connector_attach_encoder(connector, encoder);
833 /*set possible crtcs and clones*/
834 if (dsi_connector->pipe) {
835 encoder->possible_crtcs = (1 << 2);
836 encoder->possible_clones = (1 << 1);
837 } else {
838 encoder->possible_crtcs = (1 << 0);
839 encoder->possible_clones = (1 << 0);
842 dev_priv->dsr_fb_update = 0;
843 dev_priv->dsr_enable = false;
844 dev_priv->exit_idle = mdfld_dsi_dbi_exit_dsr;
845 #if defined(CONFIG_MDFLD_DSI_DPU) || defined(CONFIG_MDFLD_DSI_DSR)
846 dev_priv->dsr_enable_config = false;
847 #endif /*CONFIG_MDFLD_DSI_DSR*/
849 dbi_output->first_boot = true;
850 dbi_output->mode_flags = MODE_SETTING_IN_ENCODER;
852 #ifdef CONFIG_MDFLD_DSI_DPU
853 /*add this output to dpu_info*/
854 if (dsi_connector->pipe == 0)
855 dpu_info->dbi_outputs[0] = dbi_output;
856 } else {
857 dpu_info->dbi_outputs[1] = dbi_output;
859 dpu_info->dbi_output_num++;
860 #else /*CONFIG_MDFLD_DSI_DPU*/
861 /*add this output to dsr_info*/
862 if (dsi_connector->pipe == 0)
863 dsr_info->dbi_outputs[0] = dbi_output;
864 else
865 dsr_info->dbi_outputs[1] = dbi_output;
866 dsr_info->dbi_output_num++;
867 #endif
868 return &dbi_output->base;
869 out_err1:
870 kfree(dbi_output);
871 return NULL;