2 * Copyright © 2006-2011 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
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 * Eric Anholt <eric@anholt.net>
28 #include "psb_intel_display.h"
29 #include "mdfld_dsi_dbi.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"
36 #include <linux/pm_runtime.h>
42 #define MIN(x, y) (((x) < (y)) ? (x) : (y))
44 /* Hardcoded currently */
45 static int ksel
= KSEL_CRYSTAL_19
;
47 extern void mdfld_save_display(struct drm_device
*dev
);
48 extern bool gbgfxsuspended
;
50 struct psb_intel_range_t
{
54 struct mdfld_limit_t
{
55 struct psb_intel_range_t dot
, m
, p1
;
58 struct mdfld_intel_clock_t
{
72 #define COUNT_MAX 0x10000000
74 void mdfldWaitForPipeDisable(struct drm_device
*dev
, int pipe
)
77 u32 pipeconf_reg
= PIPEACONF
;
83 pipeconf_reg
= PIPEBCONF
;
86 pipeconf_reg
= PIPECCONF
;
89 DRM_ERROR("Illegal Pipe Number. \n");
94 psb_intel_wait_for_vblank(dev
);
97 /* Wait for for the pipe disable to take effect. */
98 for (count
= 0; count
< COUNT_MAX
; count
++) {
99 temp
= REG_READ(pipeconf_reg
);
100 if ((temp
& PIPEACONF_PIPE_STATE
) == 0)
105 void mdfldWaitForPipeEnable(struct drm_device
*dev
, int pipe
)
108 u32 pipeconf_reg
= PIPEACONF
;
114 pipeconf_reg
= PIPEBCONF
;
117 pipeconf_reg
= PIPECCONF
;
120 dev_err(dev
->dev
, "Illegal Pipe Number.\n");
125 psb_intel_wait_for_vblank(dev
);
128 /* Wait for for the pipe enable to take effect. */
129 for (count
= 0; count
< COUNT_MAX
; count
++) {
130 temp
= REG_READ(pipeconf_reg
);
131 if ((temp
& PIPEACONF_PIPE_STATE
) == 1)
137 static int mdfld_intel_crtc_cursor_set(struct drm_crtc
*crtc
,
138 struct drm_file
*file_priv
,
140 uint32_t width
, uint32_t height
)
142 struct drm_device
*dev
= crtc
->dev
;
143 struct drm_psb_private
* dev_priv
= (struct drm_psb_private
*)dev
->dev_private
;
144 struct psb_intel_crtc
*psb_intel_crtc
= to_psb_intel_crtc(crtc
);
145 int pipe
= psb_intel_crtc
->pipe
;
146 uint32_t control
= CURACNTR
;
147 uint32_t base
= CURABASE
;
150 struct gtt_range
*gt
;
151 struct drm_gem_object
*obj
;
166 dev_err(dev
->dev
, "Illegal Pipe Number. \n");
170 #if 1 /* FIXME_JLIU7 can't enalbe cursorB/C HW issue. need to remove after HW fix */
174 /* if we want to turn of the cursor ignore width and height */
176 dev_dbg(dev
->dev
, "cursor off\n");
177 /* turn off the cursor */
179 temp
|= CURSOR_MODE_DISABLE
;
181 if (gma_power_begin(dev
, true)) {
182 REG_WRITE(control
, temp
);
186 /* Unpin the old GEM object */
187 if (psb_intel_crtc
->cursor_obj
) {
188 gt
= container_of(psb_intel_crtc
->cursor_obj
,
189 struct gtt_range
, gem
);
191 drm_gem_object_unreference(psb_intel_crtc
->cursor_obj
);
192 psb_intel_crtc
->cursor_obj
= NULL
;
197 /* Currently we only support 64x64 cursors */
198 if (width
!= 64 || height
!= 64) {
199 DRM_ERROR("we currently only support 64x64 cursors\n");
203 obj
= drm_gem_object_lookup(dev
, file_priv
, handle
);
207 if (obj
->size
< width
* height
* 4) {
208 dev_dbg(dev
->dev
, "buffer is to small\n");
212 gt
= container_of(obj
, struct gtt_range
, gem
);
214 /* Pin the memory into the GTT */
215 ret
= psb_gtt_pin(gt
);
217 dev_err(dev
->dev
, "Can not pin down handle 0x%x\n", handle
);
222 addr
= gt
->offset
; /* Or resource.start ??? */
224 psb_intel_crtc
->cursor_addr
= addr
;
227 /* set the pipe for the cursor */
228 temp
|= (pipe
<< 28);
229 temp
|= CURSOR_MODE_64_ARGB_AX
| MCURSOR_GAMMA_ENABLE
;
231 if (gma_power_begin(dev
, true)) {
232 REG_WRITE(control
, temp
);
233 REG_WRITE(base
, addr
);
237 /* FIXME: COnvert to GEM */
238 /* unpin the old bo */
239 if (psb_intel_crtc
->cursor_bo
&& psb_intel_crtc
->cursor_bo
!= bo
) {
240 mode_dev
->bo_unpin_for_scanout(dev
, psb_intel_crtc
->cursor_bo
);
241 psb_intel_crtc
->cursor_bo
= bo
;
247 static int mdfld_intel_crtc_cursor_move(struct drm_crtc
*crtc
, int x
, int y
)
249 struct drm_device
*dev
= crtc
->dev
;
250 #ifndef CONFIG_MDFLD_DSI_DPU
251 struct drm_psb_private
* dev_priv
= (struct drm_psb_private
*)dev
->dev_private
;
253 struct psb_drm_dpu_rect rect
;
255 struct psb_intel_crtc
*psb_intel_crtc
= to_psb_intel_crtc(crtc
);
256 int pipe
= psb_intel_crtc
->pipe
;
257 uint32_t pos
= CURAPOS
;
258 uint32_t base
= CURABASE
;
264 #ifndef CONFIG_MDFLD_DSI_DPU
265 if (!(dev_priv
->dsr_fb_update
& MDFLD_DSR_CURSOR_0
))
266 mdfld_dsi_dbi_exit_dsr (dev
, MDFLD_DSR_CURSOR_0
, 0, 0);
267 #else /*CONFIG_MDFLD_DSI_DPU*/
271 mdfld_dbi_dpu_report_damage(dev
, MDFLD_CURSORA
, &rect
);
272 mdfld_dpu_exit_dsr(dev
);
280 #ifndef CONFIG_MDFLD_DSI_DPU
281 if (!(dev_priv
->dsr_fb_update
& MDFLD_DSR_CURSOR_2
))
282 mdfld_dsi_dbi_exit_dsr (dev
, MDFLD_DSR_CURSOR_2
, 0, 0);
283 #else /*CONFIG_MDFLD_DSI_DPU*/
284 mdfld_dbi_dpu_report_damage(dev
, MDFLD_CURSORC
, &rect
);
285 mdfld_dpu_exit_dsr(dev
);
291 DRM_ERROR("Illegal Pipe Number. \n");
295 #if 1 /* FIXME_JLIU7 can't enalbe cursorB/C HW issue. need to remove after HW fix */
300 temp
|= (CURSOR_POS_SIGN
<< CURSOR_X_SHIFT
);
304 temp
|= (CURSOR_POS_SIGN
<< CURSOR_Y_SHIFT
);
308 temp
|= ((x
& CURSOR_POS_MASK
) << CURSOR_X_SHIFT
);
309 temp
|= ((y
& CURSOR_POS_MASK
) << CURSOR_Y_SHIFT
);
311 addr
= psb_intel_crtc
->cursor_addr
;
313 if (gma_power_begin(dev
, true)) {
314 REG_WRITE(pos
, temp
);
315 REG_WRITE(base
, addr
);
322 const struct drm_crtc_funcs mdfld_intel_crtc_funcs
= {
323 .cursor_set
= mdfld_intel_crtc_cursor_set
,
324 .cursor_move
= mdfld_intel_crtc_cursor_move
,
325 .gamma_set
= psb_intel_crtc_gamma_set
,
326 .set_config
= drm_crtc_helper_set_config
,
327 .destroy
= psb_intel_crtc_destroy
,
330 static struct drm_device globle_dev
;
332 void mdfld__intel_plane_set_alpha(int enable
)
334 struct drm_device
*dev
= &globle_dev
;
335 int dspcntr_reg
= DSPACNTR
;
338 dspcntr
= REG_READ(dspcntr_reg
);
341 dspcntr
&= ~DISPPLANE_32BPP_NO_ALPHA
;
342 dspcntr
|= DISPPLANE_32BPP
;
344 dspcntr
&= ~DISPPLANE_32BPP
;
345 dspcntr
|= DISPPLANE_32BPP_NO_ALPHA
;
348 REG_WRITE(dspcntr_reg
, dspcntr
);
351 int mdfld__intel_pipe_set_base(struct drm_crtc
*crtc
, int x
, int y
, struct drm_framebuffer
*old_fb
)
353 struct drm_device
*dev
= crtc
->dev
;
354 /* struct drm_i915_master_private *master_priv; */
355 struct psb_intel_crtc
*psb_intel_crtc
= to_psb_intel_crtc(crtc
);
356 struct psb_framebuffer
*psbfb
= to_psb_fb(crtc
->fb
);
357 struct psb_intel_mode_device
*mode_dev
= psb_intel_crtc
->mode_dev
;
358 int pipe
= psb_intel_crtc
->pipe
;
359 unsigned long start
, offset
;
360 int dsplinoff
= DSPALINOFF
;
361 int dspsurf
= DSPASURF
;
362 int dspstride
= DSPASTRIDE
;
363 int dspcntr_reg
= DSPACNTR
;
367 memcpy(&globle_dev
, dev
, sizeof(struct drm_device
));
369 if (!gma_power_begin(dev
, true))
374 dev_err(dev
->dev
, "No FB bound\n");
375 goto psb_intel_pipe_cleaner
;
380 dsplinoff
= DSPALINOFF
;
383 dsplinoff
= DSPBLINOFF
;
385 dspstride
= DSPBSTRIDE
;
386 dspcntr_reg
= DSPBCNTR
;
389 dsplinoff
= DSPCLINOFF
;
391 dspstride
= DSPCSTRIDE
;
392 dspcntr_reg
= DSPCCNTR
;
395 dev_err(dev
->dev
, "Illegal Pipe Number.\n");
399 ret
= psb_gtt_pin(psbfb
->gtt
);
401 goto psb_intel_pipe_set_base_exit
;
403 start
= psbfb
->gtt
->offset
;
404 offset
= y
* crtc
->fb
->pitch
+ x
* (crtc
->fb
->bits_per_pixel
/ 8);
406 REG_WRITE(dspstride
, crtc
->fb
->pitch
);
407 dspcntr
= REG_READ(dspcntr_reg
);
408 dspcntr
&= ~DISPPLANE_PIXFORMAT_MASK
;
410 switch (crtc
->fb
->bits_per_pixel
) {
412 dspcntr
|= DISPPLANE_8BPP
;
415 if (crtc
->fb
->depth
== 15)
416 dspcntr
|= DISPPLANE_15_16BPP
;
418 dspcntr
|= DISPPLANE_16BPP
;
422 dspcntr
|= DISPPLANE_32BPP_NO_ALPHA
;
425 dev_err(dev
->dev
, "Unknown color depth\n");
427 goto psb_intel_pipe_set_base_exit
;
429 REG_WRITE(dspcntr_reg
, dspcntr
);
431 dev_dbg(dev
->dev
, "Writing base %08lX %08lX %d %d\n",
432 start
, offset
, x
, y
);
434 REG_WRITE(dsplinoff
, offset
);
436 REG_WRITE(dspsurf
, start
);
439 psb_intel_pipe_cleaner
:
440 /* If there was a previous display we can now unpin it */
442 psb_gtt_unpin(to_psb_fb(old_fb
)->gtt
);
444 psb_intel_pipe_set_base_exit
:
450 * Disable the pipe, plane and pll.
453 void mdfld_disable_crtc (struct drm_device
*dev
, int pipe
)
455 int dpll_reg
= MRST_DPLL_A
;
456 int dspcntr_reg
= DSPACNTR
;
457 int dspbase_reg
= MRST_DSPABASE
;
458 int pipeconf_reg
= PIPEACONF
;
459 u32 gen_fifo_stat_reg
= GEN_FIFO_STAT_REG
;
466 dpll_reg
= MDFLD_DPLL_B
;
467 dspcntr_reg
= DSPBCNTR
;
468 dspbase_reg
= DSPBSURF
;
469 pipeconf_reg
= PIPEBCONF
;
472 dpll_reg
= MRST_DPLL_A
;
473 dspcntr_reg
= DSPCCNTR
;
474 dspbase_reg
= MDFLD_DSPCBASE
;
475 pipeconf_reg
= PIPECCONF
;
476 gen_fifo_stat_reg
= GEN_FIFO_STAT_REG
+ MIPIC_REG_OFFSET
;
479 dev_err(dev
->dev
, "Illegal Pipe Number. \n");
484 mdfld_dsi_gen_fifo_ready (dev
, gen_fifo_stat_reg
, HS_CTRL_FIFO_EMPTY
| HS_DATA_FIFO_EMPTY
);
486 /* Disable display plane */
487 temp
= REG_READ(dspcntr_reg
);
488 if ((temp
& DISPLAY_PLANE_ENABLE
) != 0) {
489 REG_WRITE(dspcntr_reg
,
490 temp
& ~DISPLAY_PLANE_ENABLE
);
491 /* Flush the plane changes */
492 REG_WRITE(dspbase_reg
, REG_READ(dspbase_reg
));
493 REG_READ(dspbase_reg
);
496 /* FIXME_JLIU7 MDFLD_PO revisit */
497 /* Wait for vblank for the disable to take effect */
498 // MDFLD_PO_JLIU7 psb_intel_wait_for_vblank(dev);
500 /* Next, disable display pipes */
501 temp
= REG_READ(pipeconf_reg
);
502 if ((temp
& PIPEACONF_ENABLE
) != 0) {
503 temp
&= ~PIPEACONF_ENABLE
;
504 temp
|= PIPECONF_PLANE_OFF
| PIPECONF_CURSOR_OFF
;
505 REG_WRITE(pipeconf_reg
, temp
);
506 REG_READ(pipeconf_reg
);
508 /* Wait for for the pipe disable to take effect. */
509 mdfldWaitForPipeDisable(dev
, pipe
);
512 temp
= REG_READ(dpll_reg
);
513 if (temp
& DPLL_VCO_ENABLE
) {
514 if (((pipe
!= 1) && !((REG_READ(PIPEACONF
) | REG_READ(PIPECCONF
)) & PIPEACONF_ENABLE
))
516 temp
&= ~(DPLL_VCO_ENABLE
);
517 REG_WRITE(dpll_reg
, temp
);
519 /* Wait for the clocks to turn off. */
520 /* FIXME_MDFLD PO may need more delay */
523 if (!(temp
& MDFLD_PWR_GATE_EN
)) {
524 /* gating power of DPLL */
525 REG_WRITE(dpll_reg
, temp
| MDFLD_PWR_GATE_EN
);
526 /* FIXME_MDFLD PO - change 500 to 1 after PO */
535 * Sets the power management mode of the pipe and plane.
537 * This code should probably grow support for turning the cursor off and back
538 * on appropriately at the same time as we're turning the pipe off/on.
540 static void mdfld_crtc_dpms(struct drm_crtc
*crtc
, int mode
)
542 struct drm_device
*dev
= crtc
->dev
;
543 struct drm_psb_private
*dev_priv
= dev
->dev_private
;
544 struct psb_intel_crtc
*psb_intel_crtc
= to_psb_intel_crtc(crtc
);
545 int pipe
= psb_intel_crtc
->pipe
;
546 int dpll_reg
= MRST_DPLL_A
;
547 int dspcntr_reg
= DSPACNTR
;
548 int dspbase_reg
= MRST_DSPABASE
;
549 int pipeconf_reg
= PIPEACONF
;
550 u32 pipestat_reg
= PIPEASTAT
;
551 u32 gen_fifo_stat_reg
= GEN_FIFO_STAT_REG
;
552 u32 pipeconf
= dev_priv
->pipeconf
;
553 u32 dspcntr
= dev_priv
->dspcntr
;
554 u32 mipi_enable_reg
= MIPIA_DEVICE_READY_REG
;
559 if (!gma_power_begin(dev
, true))
562 /* Ignore if system is already in DSR and in suspended state. */
563 if(/*gbgfxsuspended */0 && dev_priv
->dispstatus
== false && mode
== 3){
564 if(dev_priv
->rpm_enabled
&& pipe
== 1){
565 // dev_priv->is_mipi_on = false;
566 pm_request_idle(&dev
->pdev
->dev
);
569 }else if(mode
== 0) {
570 //do not need to set gbdispstatus=true in crtc.
571 //this will be set in encoder such as mdfld_dsi_dbi_dpms
572 //gbdispstatus = true;
576 /* FIXME_JLIU7 MDFLD_PO replaced w/ the following function */
577 /* mdfld_dbi_dpms (struct drm_device *dev, int pipe, bool enabled) */
584 dspcntr_reg
= DSPBCNTR
;
585 dspbase_reg
= MRST_DSPBBASE
;
586 pipeconf_reg
= PIPEBCONF
;
587 pipeconf
= dev_priv
->pipeconf1
;
588 dspcntr
= dev_priv
->dspcntr1
;
589 dpll_reg
= MDFLD_DPLL_B
;
592 dpll_reg
= MRST_DPLL_A
;
593 dspcntr_reg
= DSPCCNTR
;
594 dspbase_reg
= MDFLD_DSPCBASE
;
595 pipeconf_reg
= PIPECCONF
;
596 pipestat_reg
= PIPECSTAT
;
597 pipeconf
= dev_priv
->pipeconf2
;
598 dspcntr
= dev_priv
->dspcntr2
;
599 gen_fifo_stat_reg
= GEN_FIFO_STAT_REG
+ MIPIC_REG_OFFSET
;
600 mipi_enable_reg
= MIPIA_DEVICE_READY_REG
+ MIPIC_REG_OFFSET
;
603 dev_err(dev
->dev
, "Illegal Pipe Number.\n");
607 /* XXX: When our outputs are all unaware of DPMS modes other than off
608 * and on, we should map those modes to DRM_MODE_DPMS_OFF in the CRTC.
611 case DRM_MODE_DPMS_ON
:
612 case DRM_MODE_DPMS_STANDBY
:
613 case DRM_MODE_DPMS_SUSPEND
:
614 /* Enable the DPLL */
615 temp
= REG_READ(dpll_reg
);
617 if ((temp
& DPLL_VCO_ENABLE
) == 0) {
618 /* When ungating power of DPLL, needs to wait 0.5us before enable the VCO */
619 if (temp
& MDFLD_PWR_GATE_EN
) {
620 temp
&= ~MDFLD_PWR_GATE_EN
;
621 REG_WRITE(dpll_reg
, temp
);
622 /* FIXME_MDFLD PO - change 500 to 1 after PO */
626 REG_WRITE(dpll_reg
, temp
);
628 /* FIXME_MDFLD PO - change 500 to 1 after PO */
631 REG_WRITE(dpll_reg
, temp
| DPLL_VCO_ENABLE
);
635 * wait for DSI PLL to lock
636 * NOTE: only need to poll status of pipe 0 and pipe 1,
637 * since both MIPI pipes share the same PLL.
639 while ((pipe
!= 2) && (timeout
< 20000) && !(REG_READ(pipeconf_reg
) & PIPECONF_DSIPLL_LOCK
)) {
645 /* Enable the plane */
646 temp
= REG_READ(dspcntr_reg
);
647 if ((temp
& DISPLAY_PLANE_ENABLE
) == 0) {
648 REG_WRITE(dspcntr_reg
,
649 temp
| DISPLAY_PLANE_ENABLE
);
650 /* Flush the plane changes */
651 REG_WRITE(dspbase_reg
, REG_READ(dspbase_reg
));
654 /* Enable the pipe */
655 temp
= REG_READ(pipeconf_reg
);
656 if ((temp
& PIPEACONF_ENABLE
) == 0) {
657 REG_WRITE(pipeconf_reg
, pipeconf
);
659 /* Wait for for the pipe enable to take effect. */
660 mdfldWaitForPipeEnable(dev
, pipe
);
663 /*workaround for sighting 3741701 Random X blank display*/
664 /*perform w/a in video mode only on pipe A or C*/
665 if ((pipe
== 0 || pipe
== 2) &&
666 (mdfld_panel_dpi(dev
) == true)) {
667 REG_WRITE(pipestat_reg
, REG_READ(pipestat_reg
));
669 if(PIPE_VBLANK_STATUS
& REG_READ(pipestat_reg
)) {
670 printk(KERN_ALERT
"OK");
672 printk(KERN_ALERT
"STUCK!!!!");
673 /*shutdown controller*/
674 temp
= REG_READ(dspcntr_reg
);
675 REG_WRITE(dspcntr_reg
, temp
& ~DISPLAY_PLANE_ENABLE
);
676 REG_WRITE(dspbase_reg
, REG_READ(dspbase_reg
));
677 /*mdfld_dsi_dpi_shut_down(dev, pipe);*/
678 REG_WRITE(0xb048, 1);
680 temp
= REG_READ(pipeconf_reg
);
681 temp
&= ~PIPEACONF_ENABLE
;
682 REG_WRITE(pipeconf_reg
, temp
);
683 msleep(100); /*wait for pipe disable*/
684 /*printk(KERN_ALERT "70008 is %x\n", REG_READ(0x70008));
685 printk(KERN_ALERT "b074 is %x\n", REG_READ(0xb074));*/
686 REG_WRITE(mipi_enable_reg
, 0);
688 printk(KERN_ALERT
"70008 is %x\n", REG_READ(0x70008));
689 printk(KERN_ALERT
"b074 is %x\n", REG_READ(0xb074));
690 REG_WRITE(0xb004, REG_READ(0xb004));
691 /* try to bring the controller back up again*/
692 REG_WRITE(mipi_enable_reg
, 1);
693 temp
= REG_READ(dspcntr_reg
);
694 REG_WRITE(dspcntr_reg
, temp
| DISPLAY_PLANE_ENABLE
);
695 REG_WRITE(dspbase_reg
, REG_READ(dspbase_reg
));
696 /*mdfld_dsi_dpi_turn_on(dev, pipe);*/
697 REG_WRITE(0xb048, 2);
699 temp
= REG_READ(pipeconf_reg
);
700 temp
|= PIPEACONF_ENABLE
;
701 REG_WRITE(pipeconf_reg
, temp
);
705 psb_intel_crtc_load_lut(crtc
);
707 /* Give the overlay scaler a chance to enable
708 if it's on this pipe */
709 /* psb_intel_crtc_dpms_video(crtc, true); TODO */
712 case DRM_MODE_DPMS_OFF
:
713 /* Give the overlay scaler a chance to disable
714 * if it's on this pipe */
715 /* psb_intel_crtc_dpms_video(crtc, FALSE); TODO */
717 mdfld_dsi_gen_fifo_ready (dev
, gen_fifo_stat_reg
, HS_CTRL_FIFO_EMPTY
| HS_DATA_FIFO_EMPTY
);
719 /* Disable the VGA plane that we never use */
720 REG_WRITE(VGACNTRL
, VGA_DISP_DISABLE
);
722 /* Disable display plane */
723 temp
= REG_READ(dspcntr_reg
);
724 if ((temp
& DISPLAY_PLANE_ENABLE
) != 0) {
725 REG_WRITE(dspcntr_reg
,
726 temp
& ~DISPLAY_PLANE_ENABLE
);
727 /* Flush the plane changes */
728 REG_WRITE(dspbase_reg
, REG_READ(dspbase_reg
));
729 REG_READ(dspbase_reg
);
732 /* FIXME_JLIU7 MDFLD_PO revisit */
733 /* Wait for vblank for the disable to take effect */
734 // MDFLD_PO_JLIU7 psb_intel_wait_for_vblank(dev);
736 /* Next, disable display pipes */
737 temp
= REG_READ(pipeconf_reg
);
738 if ((temp
& PIPEACONF_ENABLE
) != 0) {
739 temp
&= ~PIPEACONF_ENABLE
;
740 temp
|= PIPECONF_PLANE_OFF
| PIPECONF_CURSOR_OFF
;
741 REG_WRITE(pipeconf_reg
, temp
);
742 // REG_WRITE(pipeconf_reg, 0);
743 REG_READ(pipeconf_reg
);
745 /* Wait for for the pipe disable to take effect. */
746 mdfldWaitForPipeDisable(dev
, pipe
);
749 temp
= REG_READ(dpll_reg
);
750 if (temp
& DPLL_VCO_ENABLE
) {
751 if (((pipe
!= 1) && !((REG_READ(PIPEACONF
) | REG_READ(PIPECCONF
)) & PIPEACONF_ENABLE
))
753 temp
&= ~(DPLL_VCO_ENABLE
);
754 REG_WRITE(dpll_reg
, temp
);
756 /* Wait for the clocks to turn off. */
757 /* FIXME_MDFLD PO may need more delay */
759 #if 0 /* MDFLD_PO_JLIU7 */
760 if (!(temp
& MDFLD_PWR_GATE_EN
)) {
761 /* gating power of DPLL */
762 REG_WRITE(dpll_reg
, temp
| MDFLD_PWR_GATE_EN
);
763 /* FIXME_MDFLD PO - change 500 to 1 after PO */
766 #endif /* MDFLD_PO_JLIU7 */
772 enabled
= crtc
->enabled
&& mode
!= DRM_MODE_DPMS_OFF
;
774 #if 0 /* JB: Add vblank support later */
776 dev_priv
->vblank_pipe
|= (1 << pipe
);
778 dev_priv
->vblank_pipe
&= ~(1 << pipe
);
785 #define MDFLD_LIMT_DPLL_19 0
786 #define MDFLD_LIMT_DPLL_25 1
787 #define MDFLD_LIMT_DPLL_83 2
788 #define MDFLD_LIMT_DPLL_100 3
789 #define MDFLD_LIMT_DSIPLL_19 4
790 #define MDFLD_LIMT_DSIPLL_25 5
791 #define MDFLD_LIMT_DSIPLL_83 6
792 #define MDFLD_LIMT_DSIPLL_100 7
794 #define MDFLD_DOT_MIN 19750 /* FIXME_MDFLD JLIU7 need to find out min & max for MDFLD */
795 #define MDFLD_DOT_MAX 120000
796 #define MDFLD_DPLL_M_MIN_19 113
797 #define MDFLD_DPLL_M_MAX_19 155
798 #define MDFLD_DPLL_P1_MIN_19 2
799 #define MDFLD_DPLL_P1_MAX_19 10
800 #define MDFLD_DPLL_M_MIN_25 101
801 #define MDFLD_DPLL_M_MAX_25 130
802 #define MDFLD_DPLL_P1_MIN_25 2
803 #define MDFLD_DPLL_P1_MAX_25 10
804 #define MDFLD_DPLL_M_MIN_83 64
805 #define MDFLD_DPLL_M_MAX_83 64
806 #define MDFLD_DPLL_P1_MIN_83 2
807 #define MDFLD_DPLL_P1_MAX_83 2
808 #define MDFLD_DPLL_M_MIN_100 64
809 #define MDFLD_DPLL_M_MAX_100 64
810 #define MDFLD_DPLL_P1_MIN_100 2
811 #define MDFLD_DPLL_P1_MAX_100 2
812 #define MDFLD_DSIPLL_M_MIN_19 131
813 #define MDFLD_DSIPLL_M_MAX_19 175
814 #define MDFLD_DSIPLL_P1_MIN_19 3
815 #define MDFLD_DSIPLL_P1_MAX_19 8
816 #define MDFLD_DSIPLL_M_MIN_25 97
817 #define MDFLD_DSIPLL_M_MAX_25 140
818 #define MDFLD_DSIPLL_P1_MIN_25 3
819 #define MDFLD_DSIPLL_P1_MAX_25 9
820 #define MDFLD_DSIPLL_M_MIN_83 33
821 #define MDFLD_DSIPLL_M_MAX_83 92
822 #define MDFLD_DSIPLL_P1_MIN_83 2
823 #define MDFLD_DSIPLL_P1_MAX_83 3
824 #define MDFLD_DSIPLL_M_MIN_100 97
825 #define MDFLD_DSIPLL_M_MAX_100 140
826 #define MDFLD_DSIPLL_P1_MIN_100 3
827 #define MDFLD_DSIPLL_P1_MAX_100 9
829 static const struct mdfld_limit_t mdfld_limits
[] = {
830 { /* MDFLD_LIMT_DPLL_19 */
831 .dot
= {.min
= MDFLD_DOT_MIN
, .max
= MDFLD_DOT_MAX
},
832 .m
= {.min
= MDFLD_DPLL_M_MIN_19
, .max
= MDFLD_DPLL_M_MAX_19
},
833 .p1
= {.min
= MDFLD_DPLL_P1_MIN_19
, .max
= MDFLD_DPLL_P1_MAX_19
},
835 { /* MDFLD_LIMT_DPLL_25 */
836 .dot
= {.min
= MDFLD_DOT_MIN
, .max
= MDFLD_DOT_MAX
},
837 .m
= {.min
= MDFLD_DPLL_M_MIN_25
, .max
= MDFLD_DPLL_M_MAX_25
},
838 .p1
= {.min
= MDFLD_DPLL_P1_MIN_25
, .max
= MDFLD_DPLL_P1_MAX_25
},
840 { /* MDFLD_LIMT_DPLL_83 */
841 .dot
= {.min
= MDFLD_DOT_MIN
, .max
= MDFLD_DOT_MAX
},
842 .m
= {.min
= MDFLD_DPLL_M_MIN_83
, .max
= MDFLD_DPLL_M_MAX_83
},
843 .p1
= {.min
= MDFLD_DPLL_P1_MIN_83
, .max
= MDFLD_DPLL_P1_MAX_83
},
845 { /* MDFLD_LIMT_DPLL_100 */
846 .dot
= {.min
= MDFLD_DOT_MIN
, .max
= MDFLD_DOT_MAX
},
847 .m
= {.min
= MDFLD_DPLL_M_MIN_100
, .max
= MDFLD_DPLL_M_MAX_100
},
848 .p1
= {.min
= MDFLD_DPLL_P1_MIN_100
, .max
= MDFLD_DPLL_P1_MAX_100
},
850 { /* MDFLD_LIMT_DSIPLL_19 */
851 .dot
= {.min
= MDFLD_DOT_MIN
, .max
= MDFLD_DOT_MAX
},
852 .m
= {.min
= MDFLD_DSIPLL_M_MIN_19
, .max
= MDFLD_DSIPLL_M_MAX_19
},
853 .p1
= {.min
= MDFLD_DSIPLL_P1_MIN_19
, .max
= MDFLD_DSIPLL_P1_MAX_19
},
855 { /* MDFLD_LIMT_DSIPLL_25 */
856 .dot
= {.min
= MDFLD_DOT_MIN
, .max
= MDFLD_DOT_MAX
},
857 .m
= {.min
= MDFLD_DSIPLL_M_MIN_25
, .max
= MDFLD_DSIPLL_M_MAX_25
},
858 .p1
= {.min
= MDFLD_DSIPLL_P1_MIN_25
, .max
= MDFLD_DSIPLL_P1_MAX_25
},
860 { /* MDFLD_LIMT_DSIPLL_83 */
861 .dot
= {.min
= MDFLD_DOT_MIN
, .max
= MDFLD_DOT_MAX
},
862 .m
= {.min
= MDFLD_DSIPLL_M_MIN_83
, .max
= MDFLD_DSIPLL_M_MAX_83
},
863 .p1
= {.min
= MDFLD_DSIPLL_P1_MIN_83
, .max
= MDFLD_DSIPLL_P1_MAX_83
},
865 { /* MDFLD_LIMT_DSIPLL_100 */
866 .dot
= {.min
= MDFLD_DOT_MIN
, .max
= MDFLD_DOT_MAX
},
867 .m
= {.min
= MDFLD_DSIPLL_M_MIN_100
, .max
= MDFLD_DSIPLL_M_MAX_100
},
868 .p1
= {.min
= MDFLD_DSIPLL_P1_MIN_100
, .max
= MDFLD_DSIPLL_P1_MAX_100
},
872 #define MDFLD_M_MIN 21
873 #define MDFLD_M_MAX 180
874 static const u32 mdfld_m_converts
[] = {
875 /* M configuration table from 9-bit LFSR table */
876 224, 368, 440, 220, 366, 439, 219, 365, 182, 347, /* 21 - 30 */
877 173, 342, 171, 85, 298, 149, 74, 37, 18, 265, /* 31 - 40 */
878 388, 194, 353, 432, 216, 108, 310, 155, 333, 166, /* 41 - 50 */
879 83, 41, 276, 138, 325, 162, 337, 168, 340, 170, /* 51 - 60 */
880 341, 426, 469, 234, 373, 442, 221, 110, 311, 411, /* 61 - 70 */
881 461, 486, 243, 377, 188, 350, 175, 343, 427, 213, /* 71 - 80 */
882 106, 53, 282, 397, 354, 227, 113, 56, 284, 142, /* 81 - 90 */
883 71, 35, 273, 136, 324, 418, 465, 488, 500, 506, /* 91 - 100 */
884 253, 126, 63, 287, 399, 455, 483, 241, 376, 444, /* 101 - 110 */
885 478, 495, 503, 251, 381, 446, 479, 239, 375, 443, /* 111 - 120 */
886 477, 238, 119, 315, 157, 78, 295, 147, 329, 420, /* 121 - 130 */
887 210, 105, 308, 154, 77, 38, 275, 137, 68, 290, /* 131 - 140 */
888 145, 328, 164, 82, 297, 404, 458, 485, 498, 249, /* 141 - 150 */
889 380, 190, 351, 431, 471, 235, 117, 314, 413, 206, /* 151 - 160 */
890 103, 51, 25, 12, 262, 387, 193, 96, 48, 280, /* 161 - 170 */
891 396, 198, 99, 305, 152, 76, 294, 403, 457, 228, /* 171 - 180 */
894 static const struct mdfld_limit_t
*mdfld_limit(struct drm_crtc
*crtc
)
896 const struct mdfld_limit_t
*limit
= NULL
;
897 struct drm_device
*dev
= crtc
->dev
;
898 struct drm_psb_private
*dev_priv
= dev
->dev_private
;
900 if (psb_intel_pipe_has_type(crtc
, INTEL_OUTPUT_MIPI
)
901 || psb_intel_pipe_has_type(crtc
, INTEL_OUTPUT_MIPI2
)) {
902 if ((ksel
== KSEL_CRYSTAL_19
) || (ksel
== KSEL_BYPASS_19
))
903 limit
= &mdfld_limits
[MDFLD_LIMT_DSIPLL_19
];
904 else if (ksel
== KSEL_BYPASS_25
)
905 limit
= &mdfld_limits
[MDFLD_LIMT_DSIPLL_25
];
906 else if ((ksel
== KSEL_BYPASS_83_100
) && (dev_priv
->core_freq
== 166))
907 limit
= &mdfld_limits
[MDFLD_LIMT_DSIPLL_83
];
908 else if ((ksel
== KSEL_BYPASS_83_100
) &&
909 (dev_priv
->core_freq
== 100 || dev_priv
->core_freq
== 200))
910 limit
= &mdfld_limits
[MDFLD_LIMT_DSIPLL_100
];
911 } else if (psb_intel_pipe_has_type(crtc
, INTEL_OUTPUT_HDMI
)) {
912 if ((ksel
== KSEL_CRYSTAL_19
) || (ksel
== KSEL_BYPASS_19
))
913 limit
= &mdfld_limits
[MDFLD_LIMT_DPLL_19
];
914 else if (ksel
== KSEL_BYPASS_25
)
915 limit
= &mdfld_limits
[MDFLD_LIMT_DPLL_25
];
916 else if ((ksel
== KSEL_BYPASS_83_100
) && (dev_priv
->core_freq
== 166))
917 limit
= &mdfld_limits
[MDFLD_LIMT_DPLL_83
];
918 else if ((ksel
== KSEL_BYPASS_83_100
) &&
919 (dev_priv
->core_freq
== 100 || dev_priv
->core_freq
== 200))
920 limit
= &mdfld_limits
[MDFLD_LIMT_DPLL_100
];
923 dev_err(dev
->dev
, "mdfld_limit Wrong display type.\n");
929 /** Derive the pixel clock for the given refclk and divisors for 8xx chips. */
930 static void mdfld_clock(int refclk
, struct mdfld_intel_clock_t
*clock
)
932 clock
->dot
= (refclk
* clock
->m
) / clock
->p1
;
936 * Returns a set of divisors for the desired target clock with the given refclk,
937 * or FALSE. Divisor values are the actual divisors for
940 mdfldFindBestPLL(struct drm_crtc
*crtc
, int target
, int refclk
,
941 struct mdfld_intel_clock_t
*best_clock
)
943 struct mdfld_intel_clock_t clock
;
944 const struct mdfld_limit_t
*limit
= mdfld_limit(crtc
);
947 memset(best_clock
, 0, sizeof(*best_clock
));
949 for (clock
.m
= limit
->m
.min
; clock
.m
<= limit
->m
.max
; clock
.m
++) {
950 for (clock
.p1
= limit
->p1
.min
; clock
.p1
<= limit
->p1
.max
;
954 mdfld_clock(refclk
, &clock
);
956 this_err
= abs(clock
.dot
- target
);
957 if (this_err
< err
) {
963 return err
!= target
;
967 * Return the pipe currently connected to the panel fitter,
968 * or -1 if the panel fitter is not present or not in use
970 static int mdfld_panel_fitter_pipe(struct drm_device
*dev
)
974 pfit_control
= REG_READ(PFIT_CONTROL
);
976 /* See if the panel fitter is in use */
977 if ((pfit_control
& PFIT_ENABLE
) == 0)
979 return (pfit_control
>> 29) & 3;
982 static int mdfld_crtc_mode_set(struct drm_crtc
*crtc
,
983 struct drm_display_mode
*mode
,
984 struct drm_display_mode
*adjusted_mode
,
986 struct drm_framebuffer
*old_fb
)
988 struct drm_device
*dev
= crtc
->dev
;
989 struct psb_intel_crtc
*psb_intel_crtc
= to_psb_intel_crtc(crtc
);
990 struct drm_psb_private
*dev_priv
= dev
->dev_private
;
991 int pipe
= psb_intel_crtc
->pipe
;
992 int fp_reg
= MRST_FPA0
;
993 int dpll_reg
= MRST_DPLL_A
;
994 int dspcntr_reg
= DSPACNTR
;
995 int pipeconf_reg
= PIPEACONF
;
996 int htot_reg
= HTOTAL_A
;
997 int hblank_reg
= HBLANK_A
;
998 int hsync_reg
= HSYNC_A
;
999 int vtot_reg
= VTOTAL_A
;
1000 int vblank_reg
= VBLANK_A
;
1001 int vsync_reg
= VSYNC_A
;
1002 int dspsize_reg
= DSPASIZE
;
1003 int dsppos_reg
= DSPAPOS
;
1004 int pipesrc_reg
= PIPEASRC
;
1005 u32
*pipeconf
= &dev_priv
->pipeconf
;
1006 u32
*dspcntr
= &dev_priv
->dspcntr
;
1008 int clk_n
= 0, clk_p2
= 0, clk_byte
= 1, clk
= 0, m_conv
= 0, clk_tmp
= 0;
1009 struct mdfld_intel_clock_t clock
;
1011 u32 dpll
= 0, fp
= 0;
1012 bool is_crt
= false, is_lvds
= false, is_tv
= false;
1013 bool is_mipi
= false, is_mipi2
= false, is_hdmi
= false;
1014 struct drm_mode_config
*mode_config
= &dev
->mode_config
;
1015 struct psb_intel_output
*psb_intel_output
= NULL
;
1016 uint64_t scalingType
= DRM_MODE_SCALE_FULLSCREEN
;
1017 struct drm_encoder
*encoder
;
1018 struct drm_connector
*connector
;
1021 dev_dbg(dev
->dev
, "pipe = 0x%x \n", pipe
);
1029 dspcntr_reg
= DSPBCNTR
;
1030 pipeconf_reg
= PIPEBCONF
;
1031 htot_reg
= HTOTAL_B
;
1032 hblank_reg
= HBLANK_B
;
1033 hsync_reg
= HSYNC_B
;
1034 vtot_reg
= VTOTAL_B
;
1035 vblank_reg
= VBLANK_B
;
1036 vsync_reg
= VSYNC_B
;
1037 dspsize_reg
= DSPBSIZE
;
1038 dsppos_reg
= DSPBPOS
;
1039 pipesrc_reg
= PIPEBSRC
;
1040 pipeconf
= &dev_priv
->pipeconf1
;
1041 dspcntr
= &dev_priv
->dspcntr1
;
1042 fp_reg
= MDFLD_DPLL_DIV0
;
1043 dpll_reg
= MDFLD_DPLL_B
;
1046 dpll_reg
= MRST_DPLL_A
;
1047 dspcntr_reg
= DSPCCNTR
;
1048 pipeconf_reg
= PIPECCONF
;
1049 htot_reg
= HTOTAL_C
;
1050 hblank_reg
= HBLANK_C
;
1051 hsync_reg
= HSYNC_C
;
1052 vtot_reg
= VTOTAL_C
;
1053 vblank_reg
= VBLANK_C
;
1054 vsync_reg
= VSYNC_C
;
1055 dspsize_reg
= DSPCSIZE
;
1056 dsppos_reg
= DSPCPOS
;
1057 pipesrc_reg
= PIPECSRC
;
1058 pipeconf
= &dev_priv
->pipeconf2
;
1059 dspcntr
= &dev_priv
->dspcntr2
;
1062 DRM_ERROR("Illegal Pipe Number. \n");
1066 dev_dbg(dev
->dev
, "adjusted_hdisplay = %d\n",
1067 adjusted_mode
->hdisplay
);
1068 dev_dbg(dev
->dev
, "adjusted_vdisplay = %d\n",
1069 adjusted_mode
->vdisplay
);
1070 dev_dbg(dev
->dev
, "adjusted_hsync_start = %d\n",
1071 adjusted_mode
->hsync_start
);
1072 dev_dbg(dev
->dev
, "adjusted_hsync_end = %d\n",
1073 adjusted_mode
->hsync_end
);
1074 dev_dbg(dev
->dev
, "adjusted_htotal = %d\n",
1075 adjusted_mode
->htotal
);
1076 dev_dbg(dev
->dev
, "adjusted_vsync_start = %d\n",
1077 adjusted_mode
->vsync_start
);
1078 dev_dbg(dev
->dev
, "adjusted_vsync_end = %d\n",
1079 adjusted_mode
->vsync_end
);
1080 dev_dbg(dev
->dev
, "adjusted_vtotal = %d\n",
1081 adjusted_mode
->vtotal
);
1082 dev_dbg(dev
->dev
, "adjusted_clock = %d\n",
1083 adjusted_mode
->clock
);
1084 dev_dbg(dev
->dev
, "hdisplay = %d\n",
1086 dev_dbg(dev
->dev
, "vdisplay = %d\n",
1089 if (!gma_power_begin(dev
, true))
1092 memcpy(&psb_intel_crtc
->saved_mode
, mode
, sizeof(struct drm_display_mode
));
1093 memcpy(&psb_intel_crtc
->saved_adjusted_mode
, adjusted_mode
, sizeof(struct drm_display_mode
));
1095 list_for_each_entry(connector
, &mode_config
->connector_list
, head
) {
1099 encoder
= connector
->encoder
;
1104 if (encoder
->crtc
!= crtc
)
1107 psb_intel_output
= to_psb_intel_output(connector
);
1109 dev_dbg(dev
->dev
, "output->type = 0x%x \n", psb_intel_output
->type
);
1111 switch (psb_intel_output
->type
) {
1112 case INTEL_OUTPUT_LVDS
:
1115 case INTEL_OUTPUT_TVOUT
:
1118 case INTEL_OUTPUT_ANALOG
:
1121 case INTEL_OUTPUT_MIPI
:
1124 case INTEL_OUTPUT_MIPI2
:
1127 case INTEL_OUTPUT_HDMI
:
1133 /* Disable the VGA plane that we never use */
1134 REG_WRITE(VGACNTRL
, VGA_DISP_DISABLE
);
1136 /* Disable the panel fitter if it was on our pipe */
1137 if (mdfld_panel_fitter_pipe(dev
) == pipe
)
1138 REG_WRITE(PFIT_CONTROL
, 0);
1140 /* pipesrc and dspsize control the size that is scaled from,
1141 * which should always be the user's requested size.
1144 /* FIXME: To make HDMI display with 864x480 (TPO), 480x864 (PYR) or 480x854 (TMD), set the sprite
1145 * width/height and souce image size registers with the adjusted mode for pipe B. */
1147 /* The defined sprite rectangle must always be completely contained within the displayable
1148 * area of the screen image (frame buffer). */
1149 REG_WRITE(dspsize_reg
, ((MIN(mode
->crtc_vdisplay
, adjusted_mode
->crtc_vdisplay
) - 1) << 16)
1150 | (MIN(mode
->crtc_hdisplay
, adjusted_mode
->crtc_hdisplay
) - 1));
1151 /* Set the CRTC with encoder mode. */
1152 REG_WRITE(pipesrc_reg
, ((mode
->crtc_hdisplay
- 1) << 16)
1153 | (mode
->crtc_vdisplay
- 1));
1155 REG_WRITE(dspsize_reg
, ((mode
->crtc_vdisplay
- 1) << 16) | (mode
->crtc_hdisplay
- 1));
1156 REG_WRITE(pipesrc_reg
, ((mode
->crtc_hdisplay
- 1) << 16) | (mode
->crtc_vdisplay
- 1));
1159 REG_WRITE(dsppos_reg
, 0);
1161 if (psb_intel_output
)
1162 drm_connector_property_get_value(&psb_intel_output
->base
,
1163 dev
->mode_config
.scaling_mode_property
, &scalingType
);
1165 if (scalingType
== DRM_MODE_SCALE_NO_SCALE
) {
1166 /*Moorestown doesn't have register support for centering so we need to
1167 mess with the h/vblank and h/vsync start and ends to get centering*/
1168 int offsetX
= 0, offsetY
= 0;
1170 offsetX
= (adjusted_mode
->crtc_hdisplay
- mode
->crtc_hdisplay
) / 2;
1171 offsetY
= (adjusted_mode
->crtc_vdisplay
- mode
->crtc_vdisplay
) / 2;
1173 REG_WRITE(htot_reg
, (mode
->crtc_hdisplay
- 1) |
1174 ((adjusted_mode
->crtc_htotal
- 1) << 16));
1175 REG_WRITE(vtot_reg
, (mode
->crtc_vdisplay
- 1) |
1176 ((adjusted_mode
->crtc_vtotal
- 1) << 16));
1177 REG_WRITE(hblank_reg
, (adjusted_mode
->crtc_hblank_start
- offsetX
- 1) |
1178 ((adjusted_mode
->crtc_hblank_end
- offsetX
- 1) << 16));
1179 REG_WRITE(hsync_reg
, (adjusted_mode
->crtc_hsync_start
- offsetX
- 1) |
1180 ((adjusted_mode
->crtc_hsync_end
- offsetX
- 1) << 16));
1181 REG_WRITE(vblank_reg
, (adjusted_mode
->crtc_vblank_start
- offsetY
- 1) |
1182 ((adjusted_mode
->crtc_vblank_end
- offsetY
- 1) << 16));
1183 REG_WRITE(vsync_reg
, (adjusted_mode
->crtc_vsync_start
- offsetY
- 1) |
1184 ((adjusted_mode
->crtc_vsync_end
- offsetY
- 1) << 16));
1186 REG_WRITE(htot_reg
, (adjusted_mode
->crtc_hdisplay
- 1) |
1187 ((adjusted_mode
->crtc_htotal
- 1) << 16));
1188 REG_WRITE(vtot_reg
, (adjusted_mode
->crtc_vdisplay
- 1) |
1189 ((adjusted_mode
->crtc_vtotal
- 1) << 16));
1190 REG_WRITE(hblank_reg
, (adjusted_mode
->crtc_hblank_start
- 1) |
1191 ((adjusted_mode
->crtc_hblank_end
- 1) << 16));
1192 REG_WRITE(hsync_reg
, (adjusted_mode
->crtc_hsync_start
- 1) |
1193 ((adjusted_mode
->crtc_hsync_end
- 1) << 16));
1194 REG_WRITE(vblank_reg
, (adjusted_mode
->crtc_vblank_start
- 1) |
1195 ((adjusted_mode
->crtc_vblank_end
- 1) << 16));
1196 REG_WRITE(vsync_reg
, (adjusted_mode
->crtc_vsync_start
- 1) |
1197 ((adjusted_mode
->crtc_vsync_end
- 1) << 16));
1200 /* Flush the plane changes */
1202 struct drm_crtc_helper_funcs
*crtc_funcs
=
1203 crtc
->helper_private
;
1204 crtc_funcs
->mode_set_base(crtc
, x
, y
, old_fb
);
1207 /* setup pipeconf */
1208 *pipeconf
= PIPEACONF_ENABLE
; /* FIXME_JLIU7 REG_READ(pipeconf_reg); */
1210 /* Set up the display plane register */
1211 *dspcntr
= REG_READ(dspcntr_reg
);
1212 *dspcntr
|= pipe
<< DISPPLANE_SEL_PIPE_POS
;
1213 *dspcntr
|= DISPLAY_PLANE_ENABLE
;
1214 /* MDFLD_PO_JLIU7 dspcntr |= DISPPLANE_BOTTOM; */
1215 /* MDFLD_PO_JLIU7 dspcntr |= DISPPLANE_GAMMA_ENABLE; */
1219 goto mrst_crtc_mode_set_exit
;
1221 /* FIXME JLIU7 Add MDFLD HDMI supports */
1222 /* FIXME_MDFLD JLIU7 DSIPLL clock *= 8? */
1223 /* FIXME_MDFLD JLIU7 need to revist for dual MIPI supports */
1224 clk
= adjusted_mode
->clock
;
1227 if ((ksel
== KSEL_CRYSTAL_19
) || (ksel
== KSEL_BYPASS_19
))
1231 if (is_mipi
|| is_mipi2
)
1233 clk_n
= 1, clk_p2
= 8;
1234 } else if (is_hdmi
) {
1235 clk_n
= 1, clk_p2
= 10;
1237 } else if (ksel
== KSEL_BYPASS_25
) {
1240 if (is_mipi
|| is_mipi2
)
1242 clk_n
= 1, clk_p2
= 8;
1243 } else if (is_hdmi
) {
1244 clk_n
= 1, clk_p2
= 10;
1246 } else if ((ksel
== KSEL_BYPASS_83_100
) && (dev_priv
->core_freq
== 166)) {
1249 if (is_mipi
|| is_mipi2
)
1251 clk_n
= 4, clk_p2
= 8;
1252 } else if (is_hdmi
) {
1253 clk_n
= 4, clk_p2
= 10;
1255 } else if ((ksel
== KSEL_BYPASS_83_100
) &&
1256 (dev_priv
->core_freq
== 100 || dev_priv
->core_freq
== 200)) {
1258 if (is_mipi
|| is_mipi2
)
1260 clk_n
= 4, clk_p2
= 8;
1261 } else if (is_hdmi
) {
1262 clk_n
= 4, clk_p2
= 10;
1267 clk_byte
= dev_priv
->bpp
/ 8;
1269 clk_byte
= dev_priv
->bpp2
/ 8;
1271 clk_tmp
= clk
* clk_n
* clk_p2
* clk_byte
;
1273 dev_dbg(dev
->dev
, "clk = %d, clk_n = %d, clk_p2 = %d. \n", clk
, clk_n
, clk_p2
);
1274 dev_dbg(dev
->dev
, "adjusted_mode->clock = %d, clk_tmp = %d. \n", adjusted_mode
->clock
, clk_tmp
);
1276 ok
= mdfldFindBestPLL(crtc
, clk_tmp
, refclk
, &clock
);
1280 "mdfldFindBestPLL fail in mdfld_crtc_mode_set. \n");
1282 m_conv
= mdfld_m_converts
[(clock
.m
- MDFLD_M_MIN
)];
1284 dev_dbg(dev
->dev
, "dot clock = %d,"
1285 "m = %d, p1 = %d, m_conv = %d. \n", clock
.dot
, clock
.m
,
1289 dpll
= REG_READ(dpll_reg
);
1291 if (dpll
& DPLL_VCO_ENABLE
) {
1292 dpll
&= ~DPLL_VCO_ENABLE
;
1293 REG_WRITE(dpll_reg
, dpll
);
1296 /* FIXME jliu7 check the DPLL lock bit PIPEACONF[29] */
1297 /* FIXME_MDFLD PO - change 500 to 1 after PO */
1300 /* reset M1, N1 & P1 */
1301 REG_WRITE(fp_reg
, 0);
1302 dpll
&= ~MDFLD_P1_MASK
;
1303 REG_WRITE(dpll_reg
, dpll
);
1304 /* FIXME_MDFLD PO - change 500 to 1 after PO */
1308 /* When ungating power of DPLL, needs to wait 0.5us before enable the VCO */
1309 if (dpll
& MDFLD_PWR_GATE_EN
) {
1310 dpll
&= ~MDFLD_PWR_GATE_EN
;
1311 REG_WRITE(dpll_reg
, dpll
);
1312 /* FIXME_MDFLD PO - change 500 to 1 after PO */
1318 #if 0 /* FIXME revisit later */
1319 if ((ksel
== KSEL_CRYSTAL_19
) || (ksel
== KSEL_BYPASS_19
) || (ksel
== KSEL_BYPASS_25
)) {
1320 dpll
&= ~MDFLD_INPUT_REF_SEL
;
1321 } else if (ksel
== KSEL_BYPASS_83_100
) {
1322 dpll
|= MDFLD_INPUT_REF_SEL
;
1324 #endif /* FIXME revisit later */
1327 dpll
|= MDFLD_VCO_SEL
;
1329 fp
= (clk_n
/ 2) << 16;
1332 /* compute bitmask from p1 value */
1333 dpll
|= (1 << (clock
.p1
- 2)) << 17;
1335 #if 0 /* 1080p30 & 720p */
1344 #if 0 /*DBI_TPO_480x864*/
1347 #endif /* DBI_TPO_480x864 */ /* get from spec. */
1353 REG_WRITE(fp_reg
, fp
);
1354 REG_WRITE(dpll_reg
, dpll
);
1355 /* FIXME_MDFLD PO - change 500 to 1 after PO */
1358 dpll
|= DPLL_VCO_ENABLE
;
1359 REG_WRITE(dpll_reg
, dpll
);
1362 /* wait for DSI PLL to lock */
1363 while ((timeout
< 20000) && !(REG_READ(pipeconf_reg
) & PIPECONF_DSIPLL_LOCK
)) {
1369 goto mrst_crtc_mode_set_exit
;
1371 dev_dbg(dev
->dev
, "is_mipi = 0x%x \n", is_mipi
);
1373 REG_WRITE(pipeconf_reg
, *pipeconf
);
1374 REG_READ(pipeconf_reg
);
1376 /* Wait for for the pipe enable to take effect. */
1377 //FIXME_JLIU7 HDMI mrstWaitForPipeEnable(dev);
1379 REG_WRITE(dspcntr_reg
, *dspcntr
);
1380 psb_intel_wait_for_vblank(dev
);
1382 mrst_crtc_mode_set_exit
:
1389 static void mdfld_crtc_prepare(struct drm_crtc
*crtc
)
1391 struct drm_crtc_helper_funcs
*crtc_funcs
= crtc
->helper_private
;
1392 crtc_funcs
->dpms(crtc
, DRM_MODE_DPMS_OFF
);
1395 static void mdfld_crtc_commit(struct drm_crtc
*crtc
)
1397 struct drm_crtc_helper_funcs
*crtc_funcs
= crtc
->helper_private
;
1398 crtc_funcs
->dpms(crtc
, DRM_MODE_DPMS_ON
);
1401 static bool mdfld_crtc_mode_fixup(struct drm_crtc
*crtc
,
1402 struct drm_display_mode
*mode
,
1403 struct drm_display_mode
*adjusted_mode
)
1408 const struct drm_crtc_helper_funcs mdfld_helper_funcs
= {
1409 .dpms
= mdfld_crtc_dpms
,
1410 .mode_fixup
= mdfld_crtc_mode_fixup
,
1411 .mode_set
= mdfld_crtc_mode_set
,
1412 .mode_set_base
= mdfld__intel_pipe_set_base
,
1413 .prepare
= mdfld_crtc_prepare
,
1414 .commit
= mdfld_crtc_commit
,