diff options
author | Alan Cox <alan@linux.intel.com> | 2012-04-25 09:36:48 -0400 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2012-04-27 04:23:19 -0400 |
commit | acd7ef927e06510fbfeec8d307f4726a156b2733 (patch) | |
tree | 520e30b3622a0548324bd546080b2b695cb876ca /drivers/gpu/drm/gma500 | |
parent | 642c52fcc98aa441bda8c7d8252e8b9b563b370b (diff) |
gma500: Update the Cedarview clock handling
Signed-off-by: Dave Airlie <airlied@redhat.com>
Diffstat (limited to 'drivers/gpu/drm/gma500')
-rw-r--r-- | drivers/gpu/drm/gma500/cdv_intel_display.c | 331 | ||||
-rw-r--r-- | drivers/gpu/drm/gma500/psb_intel_drv.h | 3 | ||||
-rw-r--r-- | drivers/gpu/drm/gma500/psb_intel_reg.h | 25 |
3 files changed, 294 insertions, 65 deletions
diff --git a/drivers/gpu/drm/gma500/cdv_intel_display.c b/drivers/gpu/drm/gma500/cdv_intel_display.c index be8455919b33..07b37f570ad9 100644 --- a/drivers/gpu/drm/gma500/cdv_intel_display.c +++ b/drivers/gpu/drm/gma500/cdv_intel_display.c | |||
@@ -216,7 +216,7 @@ static void cdv_sb_reset(struct drm_device *dev) | |||
216 | */ | 216 | */ |
217 | static int | 217 | static int |
218 | cdv_dpll_set_clock_cdv(struct drm_device *dev, struct drm_crtc *crtc, | 218 | cdv_dpll_set_clock_cdv(struct drm_device *dev, struct drm_crtc *crtc, |
219 | struct cdv_intel_clock_t *clock) | 219 | struct cdv_intel_clock_t *clock, bool is_lvds) |
220 | { | 220 | { |
221 | struct psb_intel_crtc *psb_crtc = | 221 | struct psb_intel_crtc *psb_crtc = |
222 | to_psb_intel_crtc(crtc); | 222 | to_psb_intel_crtc(crtc); |
@@ -224,6 +224,7 @@ cdv_dpll_set_clock_cdv(struct drm_device *dev, struct drm_crtc *crtc, | |||
224 | u32 m, n_vco, p; | 224 | u32 m, n_vco, p; |
225 | int ret = 0; | 225 | int ret = 0; |
226 | int dpll_reg = (pipe == 0) ? DPLL_A : DPLL_B; | 226 | int dpll_reg = (pipe == 0) ? DPLL_A : DPLL_B; |
227 | int ref_sfr = (pipe == 0) ? SB_REF_DPLLA : SB_REF_DPLLB; | ||
227 | u32 ref_value; | 228 | u32 ref_value; |
228 | 229 | ||
229 | cdv_sb_reset(dev); | 230 | cdv_sb_reset(dev); |
@@ -241,6 +242,35 @@ cdv_dpll_set_clock_cdv(struct drm_device *dev, struct drm_crtc *crtc, | |||
241 | /* We don't know what the other fields of these regs are, so | 242 | /* We don't know what the other fields of these regs are, so |
242 | * leave them in place. | 243 | * leave them in place. |
243 | */ | 244 | */ |
245 | /* | ||
246 | * The BIT 14:13 of 0x8010/0x8030 is used to select the ref clk | ||
247 | * for the pipe A/B. Display spec 1.06 has wrong definition. | ||
248 | * Correct definition is like below: | ||
249 | * | ||
250 | * refclka mean use clock from same PLL | ||
251 | * | ||
252 | * if DPLLA sets 01 and DPLLB sets 01, they use clock from their pll | ||
253 | * | ||
254 | * if DPLLA sets 01 and DPLLB sets 02, both use clk from DPLLA | ||
255 | * | ||
256 | */ | ||
257 | ret = cdv_sb_read(dev, ref_sfr, &ref_value); | ||
258 | if (ret) | ||
259 | return ret; | ||
260 | ref_value &= ~(REF_CLK_MASK); | ||
261 | |||
262 | /* use DPLL_A for pipeB on CRT/HDMI */ | ||
263 | if (pipe == 1 && !is_lvds) { | ||
264 | DRM_DEBUG_KMS("use DPLLA for pipe B\n"); | ||
265 | ref_value |= REF_CLK_DPLLA; | ||
266 | } else { | ||
267 | DRM_DEBUG_KMS("use their DPLL for pipe A/B\n"); | ||
268 | ref_value |= REF_CLK_DPLL; | ||
269 | } | ||
270 | ret = cdv_sb_write(dev, ref_sfr, ref_value); | ||
271 | if (ret) | ||
272 | return ret; | ||
273 | |||
244 | ret = cdv_sb_read(dev, SB_M(pipe), &m); | 274 | ret = cdv_sb_read(dev, SB_M(pipe), &m); |
245 | if (ret) | 275 | if (ret) |
246 | return ret; | 276 | return ret; |
@@ -308,7 +338,7 @@ cdv_dpll_set_clock_cdv(struct drm_device *dev, struct drm_crtc *crtc, | |||
308 | return ret; | 338 | return ret; |
309 | 339 | ||
310 | /* always Program the Lane Register for the Pipe A*/ | 340 | /* always Program the Lane Register for the Pipe A*/ |
311 | if (pipe == 0) { | 341 | /* if (pipe == 0) */ { |
312 | /* Program the Lane0/1 for HDMI B */ | 342 | /* Program the Lane0/1 for HDMI B */ |
313 | u32 lane_reg, lane_value; | 343 | u32 lane_reg, lane_value; |
314 | 344 | ||
@@ -553,6 +583,200 @@ psb_intel_pipe_set_base_exit: | |||
553 | return ret; | 583 | return ret; |
554 | } | 584 | } |
555 | 585 | ||
586 | #define FIFO_PIPEA (1 << 0) | ||
587 | #define FIFO_PIPEB (1 << 1) | ||
588 | |||
589 | static bool cdv_intel_pipe_enabled(struct drm_device *dev, int pipe) | ||
590 | { | ||
591 | struct drm_crtc *crtc; | ||
592 | struct drm_psb_private *dev_priv = dev->dev_private; | ||
593 | struct psb_intel_crtc *psb_intel_crtc = NULL; | ||
594 | |||
595 | crtc = dev_priv->pipe_to_crtc_mapping[pipe]; | ||
596 | psb_intel_crtc = to_psb_intel_crtc(crtc); | ||
597 | |||
598 | if (crtc->fb == NULL || !psb_intel_crtc->active) | ||
599 | return false; | ||
600 | return true; | ||
601 | } | ||
602 | |||
603 | static bool cdv_intel_single_pipe_active (struct drm_device *dev) | ||
604 | { | ||
605 | uint32_t pipe_enabled = 0; | ||
606 | |||
607 | if (cdv_intel_pipe_enabled(dev, 0)) | ||
608 | pipe_enabled |= FIFO_PIPEA; | ||
609 | |||
610 | if (cdv_intel_pipe_enabled(dev, 1)) | ||
611 | pipe_enabled |= FIFO_PIPEB; | ||
612 | |||
613 | |||
614 | DRM_DEBUG_KMS("pipe enabled %x\n", pipe_enabled); | ||
615 | |||
616 | if (pipe_enabled == FIFO_PIPEA || pipe_enabled == FIFO_PIPEB) | ||
617 | return true; | ||
618 | else | ||
619 | return false; | ||
620 | } | ||
621 | |||
622 | static bool is_pipeb_lvds(struct drm_device *dev, struct drm_crtc *crtc) | ||
623 | { | ||
624 | struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc); | ||
625 | struct drm_mode_config *mode_config = &dev->mode_config; | ||
626 | struct drm_connector *connector; | ||
627 | |||
628 | if (psb_intel_crtc->pipe != 1) | ||
629 | return false; | ||
630 | |||
631 | list_for_each_entry(connector, &mode_config->connector_list, head) { | ||
632 | struct psb_intel_encoder *psb_intel_encoder = | ||
633 | psb_intel_attached_encoder(connector); | ||
634 | |||
635 | if (!connector->encoder | ||
636 | || connector->encoder->crtc != crtc) | ||
637 | continue; | ||
638 | |||
639 | if (psb_intel_encoder->type == INTEL_OUTPUT_LVDS) | ||
640 | return true; | ||
641 | } | ||
642 | |||
643 | return false; | ||
644 | } | ||
645 | |||
646 | static void cdv_intel_disable_self_refresh (struct drm_device *dev) | ||
647 | { | ||
648 | if (REG_READ(FW_BLC_SELF) & FW_BLC_SELF_EN) { | ||
649 | |||
650 | /* Disable self-refresh before adjust WM */ | ||
651 | REG_WRITE(FW_BLC_SELF, (REG_READ(FW_BLC_SELF) & ~FW_BLC_SELF_EN)); | ||
652 | REG_READ(FW_BLC_SELF); | ||
653 | |||
654 | cdv_intel_wait_for_vblank(dev); | ||
655 | |||
656 | /* Cedarview workaround to write ovelay plane, which force to leave | ||
657 | * MAX_FIFO state. | ||
658 | */ | ||
659 | REG_WRITE(OV_OVADD, 0/*dev_priv->ovl_offset*/); | ||
660 | REG_READ(OV_OVADD); | ||
661 | |||
662 | cdv_intel_wait_for_vblank(dev); | ||
663 | } | ||
664 | |||
665 | } | ||
666 | |||
667 | static void cdv_intel_update_watermark (struct drm_device *dev, struct drm_crtc *crtc) | ||
668 | { | ||
669 | |||
670 | if (cdv_intel_single_pipe_active(dev)) { | ||
671 | u32 fw; | ||
672 | |||
673 | fw = REG_READ(DSPFW1); | ||
674 | fw &= ~DSP_FIFO_SR_WM_MASK; | ||
675 | fw |= (0x7e << DSP_FIFO_SR_WM_SHIFT); | ||
676 | fw &= ~CURSOR_B_FIFO_WM_MASK; | ||
677 | fw |= (0x4 << CURSOR_B_FIFO_WM_SHIFT); | ||
678 | REG_WRITE(DSPFW1, fw); | ||
679 | |||
680 | fw = REG_READ(DSPFW2); | ||
681 | fw &= ~CURSOR_A_FIFO_WM_MASK; | ||
682 | fw |= (0x6 << CURSOR_A_FIFO_WM_SHIFT); | ||
683 | fw &= ~DSP_PLANE_C_FIFO_WM_MASK; | ||
684 | fw |= (0x8 << DSP_PLANE_C_FIFO_WM_SHIFT); | ||
685 | REG_WRITE(DSPFW2, fw); | ||
686 | |||
687 | REG_WRITE(DSPFW3, 0x36000000); | ||
688 | |||
689 | /* ignore FW4 */ | ||
690 | |||
691 | if (is_pipeb_lvds(dev, crtc)) { | ||
692 | REG_WRITE(DSPFW5, 0x00040330); | ||
693 | } else { | ||
694 | fw = (3 << DSP_PLANE_B_FIFO_WM1_SHIFT) | | ||
695 | (4 << DSP_PLANE_A_FIFO_WM1_SHIFT) | | ||
696 | (3 << CURSOR_B_FIFO_WM1_SHIFT) | | ||
697 | (4 << CURSOR_FIFO_SR_WM1_SHIFT); | ||
698 | REG_WRITE(DSPFW5, fw); | ||
699 | } | ||
700 | |||
701 | REG_WRITE(DSPFW6, 0x10); | ||
702 | |||
703 | cdv_intel_wait_for_vblank(dev); | ||
704 | |||
705 | /* enable self-refresh for single pipe active */ | ||
706 | REG_WRITE(FW_BLC_SELF, FW_BLC_SELF_EN); | ||
707 | REG_READ(FW_BLC_SELF); | ||
708 | cdv_intel_wait_for_vblank(dev); | ||
709 | |||
710 | } else { | ||
711 | |||
712 | /* HW team suggested values... */ | ||
713 | REG_WRITE(DSPFW1, 0x3f880808); | ||
714 | REG_WRITE(DSPFW2, 0x0b020202); | ||
715 | REG_WRITE(DSPFW3, 0x24000000); | ||
716 | REG_WRITE(DSPFW4, 0x08030202); | ||
717 | REG_WRITE(DSPFW5, 0x01010101); | ||
718 | REG_WRITE(DSPFW6, 0x1d0); | ||
719 | |||
720 | cdv_intel_wait_for_vblank(dev); | ||
721 | |||
722 | cdv_intel_disable_self_refresh(dev); | ||
723 | |||
724 | } | ||
725 | } | ||
726 | |||
727 | /** Loads the palette/gamma unit for the CRTC with the prepared values */ | ||
728 | static void cdv_intel_crtc_load_lut(struct drm_crtc *crtc) | ||
729 | { | ||
730 | struct drm_device *dev = crtc->dev; | ||
731 | struct drm_psb_private *dev_priv = | ||
732 | (struct drm_psb_private *)dev->dev_private; | ||
733 | struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc); | ||
734 | int palreg = PALETTE_A; | ||
735 | int i; | ||
736 | |||
737 | /* The clocks have to be on to load the palette. */ | ||
738 | if (!crtc->enabled) | ||
739 | return; | ||
740 | |||
741 | switch (psb_intel_crtc->pipe) { | ||
742 | case 0: | ||
743 | break; | ||
744 | case 1: | ||
745 | palreg = PALETTE_B; | ||
746 | break; | ||
747 | case 2: | ||
748 | palreg = PALETTE_C; | ||
749 | break; | ||
750 | default: | ||
751 | dev_err(dev->dev, "Illegal Pipe Number.\n"); | ||
752 | return; | ||
753 | } | ||
754 | |||
755 | if (gma_power_begin(dev, false)) { | ||
756 | for (i = 0; i < 256; i++) { | ||
757 | REG_WRITE(palreg + 4 * i, | ||
758 | ((psb_intel_crtc->lut_r[i] + | ||
759 | psb_intel_crtc->lut_adj[i]) << 16) | | ||
760 | ((psb_intel_crtc->lut_g[i] + | ||
761 | psb_intel_crtc->lut_adj[i]) << 8) | | ||
762 | (psb_intel_crtc->lut_b[i] + | ||
763 | psb_intel_crtc->lut_adj[i])); | ||
764 | } | ||
765 | gma_power_end(dev); | ||
766 | } else { | ||
767 | for (i = 0; i < 256; i++) { | ||
768 | dev_priv->regs.psb.save_palette_a[i] = | ||
769 | ((psb_intel_crtc->lut_r[i] + | ||
770 | psb_intel_crtc->lut_adj[i]) << 16) | | ||
771 | ((psb_intel_crtc->lut_g[i] + | ||
772 | psb_intel_crtc->lut_adj[i]) << 8) | | ||
773 | (psb_intel_crtc->lut_b[i] + | ||
774 | psb_intel_crtc->lut_adj[i]); | ||
775 | } | ||
776 | |||
777 | } | ||
778 | } | ||
779 | |||
556 | /** | 780 | /** |
557 | * Sets the power management mode of the pipe and plane. | 781 | * Sets the power management mode of the pipe and plane. |
558 | * | 782 | * |
@@ -568,15 +792,23 @@ static void cdv_intel_crtc_dpms(struct drm_crtc *crtc, int mode) | |||
568 | int dspcntr_reg = (pipe == 0) ? DSPACNTR : DSPBCNTR; | 792 | int dspcntr_reg = (pipe == 0) ? DSPACNTR : DSPBCNTR; |
569 | int dspbase_reg = (pipe == 0) ? DSPABASE : DSPBBASE; | 793 | int dspbase_reg = (pipe == 0) ? DSPABASE : DSPBBASE; |
570 | int pipeconf_reg = (pipe == 0) ? PIPEACONF : PIPEBCONF; | 794 | int pipeconf_reg = (pipe == 0) ? PIPEACONF : PIPEBCONF; |
795 | int pipestat_reg = (pipe == 0) ? PIPEASTAT : PIPEBSTAT; | ||
571 | u32 temp; | 796 | u32 temp; |
572 | 797 | ||
573 | /* XXX: When our outputs are all unaware of DPMS modes other than off | 798 | /* XXX: When our outputs are all unaware of DPMS modes other than off |
574 | * and on, we should map those modes to DRM_MODE_DPMS_OFF in the CRTC. | 799 | * and on, we should map those modes to DRM_MODE_DPMS_OFF in the CRTC. |
575 | */ | 800 | */ |
801 | cdv_intel_disable_self_refresh(dev); | ||
802 | |||
576 | switch (mode) { | 803 | switch (mode) { |
577 | case DRM_MODE_DPMS_ON: | 804 | case DRM_MODE_DPMS_ON: |
578 | case DRM_MODE_DPMS_STANDBY: | 805 | case DRM_MODE_DPMS_STANDBY: |
579 | case DRM_MODE_DPMS_SUSPEND: | 806 | case DRM_MODE_DPMS_SUSPEND: |
807 | if (psb_intel_crtc->active) | ||
808 | return; | ||
809 | |||
810 | psb_intel_crtc->active = true; | ||
811 | |||
580 | /* Enable the DPLL */ | 812 | /* Enable the DPLL */ |
581 | temp = REG_READ(dpll_reg); | 813 | temp = REG_READ(dpll_reg); |
582 | if ((temp & DPLL_VCO_ENABLE) == 0) { | 814 | if ((temp & DPLL_VCO_ENABLE) == 0) { |
@@ -611,13 +843,26 @@ static void cdv_intel_crtc_dpms(struct drm_crtc *crtc, int mode) | |||
611 | if ((temp & PIPEACONF_ENABLE) == 0) | 843 | if ((temp & PIPEACONF_ENABLE) == 0) |
612 | REG_WRITE(pipeconf_reg, temp | PIPEACONF_ENABLE); | 844 | REG_WRITE(pipeconf_reg, temp | PIPEACONF_ENABLE); |
613 | 845 | ||
614 | psb_intel_crtc_load_lut(crtc); | 846 | temp = REG_READ(pipestat_reg); |
847 | temp &= ~(0xFFFF); | ||
848 | temp |= PIPE_FIFO_UNDERRUN; | ||
849 | REG_WRITE(pipestat_reg, temp); | ||
850 | REG_READ(pipestat_reg); | ||
851 | |||
852 | cdv_intel_update_watermark(dev, crtc); | ||
853 | cdv_intel_crtc_load_lut(crtc); | ||
615 | 854 | ||
616 | /* Give the overlay scaler a chance to enable | 855 | /* Give the overlay scaler a chance to enable |
617 | * if it's on this pipe */ | 856 | * if it's on this pipe */ |
618 | /* psb_intel_crtc_dpms_video(crtc, true); TODO */ | 857 | /* psb_intel_crtc_dpms_video(crtc, true); TODO */ |
858 | psb_intel_crtc->crtc_enable = true; | ||
619 | break; | 859 | break; |
620 | case DRM_MODE_DPMS_OFF: | 860 | case DRM_MODE_DPMS_OFF: |
861 | if (!psb_intel_crtc->active) | ||
862 | return; | ||
863 | |||
864 | psb_intel_crtc->active = false; | ||
865 | |||
621 | /* Give the overlay scaler a chance to disable | 866 | /* Give the overlay scaler a chance to disable |
622 | * if it's on this pipe */ | 867 | * if it's on this pipe */ |
623 | /* psb_intel_crtc_dpms_video(crtc, FALSE); TODO */ | 868 | /* psb_intel_crtc_dpms_video(crtc, FALSE); TODO */ |
@@ -627,6 +872,7 @@ static void cdv_intel_crtc_dpms(struct drm_crtc *crtc, int mode) | |||
627 | 872 | ||
628 | /* Jim Bish - changed pipe/plane here as well. */ | 873 | /* Jim Bish - changed pipe/plane here as well. */ |
629 | 874 | ||
875 | drm_vblank_off(dev, pipe); | ||
630 | /* Wait for vblank for the disable to take effect */ | 876 | /* Wait for vblank for the disable to take effect */ |
631 | cdv_intel_wait_for_vblank(dev); | 877 | cdv_intel_wait_for_vblank(dev); |
632 | 878 | ||
@@ -660,6 +906,8 @@ static void cdv_intel_crtc_dpms(struct drm_crtc *crtc, int mode) | |||
660 | 906 | ||
661 | /* Wait for the clocks to turn off. */ | 907 | /* Wait for the clocks to turn off. */ |
662 | udelay(150); | 908 | udelay(150); |
909 | cdv_intel_update_watermark(dev, crtc); | ||
910 | psb_intel_crtc->crtc_enable = false; | ||
663 | break; | 911 | break; |
664 | } | 912 | } |
665 | /*Set FIFO Watermarks*/ | 913 | /*Set FIFO Watermarks*/ |
@@ -709,6 +957,7 @@ static int cdv_intel_crtc_mode_set(struct drm_crtc *crtc, | |||
709 | struct drm_framebuffer *old_fb) | 957 | struct drm_framebuffer *old_fb) |
710 | { | 958 | { |
711 | struct drm_device *dev = crtc->dev; | 959 | struct drm_device *dev = crtc->dev; |
960 | struct drm_psb_private *dev_priv = dev->dev_private; | ||
712 | struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc); | 961 | struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc); |
713 | int pipe = psb_intel_crtc->pipe; | 962 | int pipe = psb_intel_crtc->pipe; |
714 | int dpll_reg = (pipe == 0) ? DPLL_A : DPLL_B; | 963 | int dpll_reg = (pipe == 0) ? DPLL_A : DPLL_B; |
@@ -757,13 +1006,18 @@ static int cdv_intel_crtc_mode_set(struct drm_crtc *crtc, | |||
757 | } | 1006 | } |
758 | } | 1007 | } |
759 | 1008 | ||
760 | refclk = 96000; | 1009 | if (dev_priv->dplla_96mhz) |
761 | 1010 | /* low-end sku, 96/100 mhz */ | |
762 | /* Hack selection about ref clk for CRT */ | 1011 | refclk = 96000; |
763 | /* Select 27MHz as the reference clk for HDMI */ | 1012 | else |
764 | if (is_crt || is_hdmi) | 1013 | /* high-end sku, 27/100 mhz */ |
765 | refclk = 27000; | 1014 | refclk = 27000; |
766 | 1015 | ||
1016 | if (is_lvds && dev_priv->lvds_use_ssc) { | ||
1017 | refclk = dev_priv->lvds_ssc_freq * 1000; | ||
1018 | DRM_DEBUG_KMS("Use SSC reference clock %d Mhz\n", dev_priv->lvds_ssc_freq); | ||
1019 | } | ||
1020 | |||
767 | drm_mode_debug_printmodeline(adjusted_mode); | 1021 | drm_mode_debug_printmodeline(adjusted_mode); |
768 | 1022 | ||
769 | ok = cdv_intel_find_best_PLL(crtc, adjusted_mode->clock, refclk, | 1023 | ok = cdv_intel_find_best_PLL(crtc, adjusted_mode->clock, refclk, |
@@ -779,14 +1033,13 @@ static int cdv_intel_crtc_mode_set(struct drm_crtc *crtc, | |||
779 | /* dpll |= PLL_REF_INPUT_TVCLKINBC; */ | 1033 | /* dpll |= PLL_REF_INPUT_TVCLKINBC; */ |
780 | dpll |= 3; | 1034 | dpll |= 3; |
781 | } | 1035 | } |
782 | dpll |= PLL_REF_INPUT_DREFCLK; | 1036 | /* dpll |= PLL_REF_INPUT_DREFCLK; */ |
783 | 1037 | ||
784 | dpll |= DPLL_SYNCLOCK_ENABLE; | 1038 | dpll |= DPLL_SYNCLOCK_ENABLE; |
785 | dpll |= DPLL_VGA_MODE_DIS; | 1039 | /* if (is_lvds) |
786 | if (is_lvds) | ||
787 | dpll |= DPLLB_MODE_LVDS; | 1040 | dpll |= DPLLB_MODE_LVDS; |
788 | else | 1041 | else |
789 | dpll |= DPLLB_MODE_DAC_SERIAL; | 1042 | dpll |= DPLLB_MODE_DAC_SERIAL; */ |
790 | /* dpll |= (2 << 11); */ | 1043 | /* dpll |= (2 << 11); */ |
791 | 1044 | ||
792 | /* setup pipeconf */ | 1045 | /* setup pipeconf */ |
@@ -806,7 +1059,7 @@ static int cdv_intel_crtc_mode_set(struct drm_crtc *crtc, | |||
806 | REG_WRITE(dpll_reg, dpll | DPLL_VGA_MODE_DIS | DPLL_SYNCLOCK_ENABLE); | 1059 | REG_WRITE(dpll_reg, dpll | DPLL_VGA_MODE_DIS | DPLL_SYNCLOCK_ENABLE); |
807 | REG_READ(dpll_reg); | 1060 | REG_READ(dpll_reg); |
808 | 1061 | ||
809 | cdv_dpll_set_clock_cdv(dev, crtc, &clock); | 1062 | cdv_dpll_set_clock_cdv(dev, crtc, &clock, is_lvds); |
810 | 1063 | ||
811 | udelay(150); | 1064 | udelay(150); |
812 | 1065 | ||
@@ -903,58 +1156,6 @@ static int cdv_intel_crtc_mode_set(struct drm_crtc *crtc, | |||
903 | return 0; | 1156 | return 0; |
904 | } | 1157 | } |
905 | 1158 | ||
906 | /** Loads the palette/gamma unit for the CRTC with the prepared values */ | ||
907 | static void cdv_intel_crtc_load_lut(struct drm_crtc *crtc) | ||
908 | { | ||
909 | struct drm_device *dev = crtc->dev; | ||
910 | struct drm_psb_private *dev_priv = | ||
911 | (struct drm_psb_private *)dev->dev_private; | ||
912 | struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc); | ||
913 | int palreg = PALETTE_A; | ||
914 | int i; | ||
915 | |||
916 | /* The clocks have to be on to load the palette. */ | ||
917 | if (!crtc->enabled) | ||
918 | return; | ||
919 | |||
920 | switch (psb_intel_crtc->pipe) { | ||
921 | case 0: | ||
922 | break; | ||
923 | case 1: | ||
924 | palreg = PALETTE_B; | ||
925 | break; | ||
926 | case 2: | ||
927 | palreg = PALETTE_C; | ||
928 | break; | ||
929 | default: | ||
930 | dev_err(dev->dev, "Illegal Pipe Number.\n"); | ||
931 | return; | ||
932 | } | ||
933 | |||
934 | if (gma_power_begin(dev, false)) { | ||
935 | for (i = 0; i < 256; i++) { | ||
936 | REG_WRITE(palreg + 4 * i, | ||
937 | ((psb_intel_crtc->lut_r[i] + | ||
938 | psb_intel_crtc->lut_adj[i]) << 16) | | ||
939 | ((psb_intel_crtc->lut_g[i] + | ||
940 | psb_intel_crtc->lut_adj[i]) << 8) | | ||
941 | (psb_intel_crtc->lut_b[i] + | ||
942 | psb_intel_crtc->lut_adj[i])); | ||
943 | } | ||
944 | gma_power_end(dev); | ||
945 | } else { | ||
946 | for (i = 0; i < 256; i++) { | ||
947 | dev_priv->regs.psb.save_palette_a[i] = | ||
948 | ((psb_intel_crtc->lut_r[i] + | ||
949 | psb_intel_crtc->lut_adj[i]) << 16) | | ||
950 | ((psb_intel_crtc->lut_g[i] + | ||
951 | psb_intel_crtc->lut_adj[i]) << 8) | | ||
952 | (psb_intel_crtc->lut_b[i] + | ||
953 | psb_intel_crtc->lut_adj[i]); | ||
954 | } | ||
955 | |||
956 | } | ||
957 | } | ||
958 | 1159 | ||
959 | /** | 1160 | /** |
960 | * Save HW states of giving crtc | 1161 | * Save HW states of giving crtc |
diff --git a/drivers/gpu/drm/gma500/psb_intel_drv.h b/drivers/gpu/drm/gma500/psb_intel_drv.h index f40535e56689..81852b48654c 100644 --- a/drivers/gpu/drm/gma500/psb_intel_drv.h +++ b/drivers/gpu/drm/gma500/psb_intel_drv.h | |||
@@ -193,6 +193,9 @@ struct psb_intel_crtc { | |||
193 | /*crtc mode setting flags*/ | 193 | /*crtc mode setting flags*/ |
194 | u32 mode_flags; | 194 | u32 mode_flags; |
195 | 195 | ||
196 | bool active; | ||
197 | bool crtc_enable; | ||
198 | |||
196 | /* Saved Crtc HW states */ | 199 | /* Saved Crtc HW states */ |
197 | struct psb_intel_crtc_state *crtc_state; | 200 | struct psb_intel_crtc_state *crtc_state; |
198 | }; | 201 | }; |
diff --git a/drivers/gpu/drm/gma500/psb_intel_reg.h b/drivers/gpu/drm/gma500/psb_intel_reg.h index e89d3a2e8fdc..46792fc7d0d0 100644 --- a/drivers/gpu/drm/gma500/psb_intel_reg.h +++ b/drivers/gpu/drm/gma500/psb_intel_reg.h | |||
@@ -505,6 +505,7 @@ | |||
505 | #define PIPE_VSYNC_ENABL (1UL << 25) | 505 | #define PIPE_VSYNC_ENABL (1UL << 25) |
506 | #define PIPE_HDMI_AUDIO_UNDERRUN (1UL << 26) | 506 | #define PIPE_HDMI_AUDIO_UNDERRUN (1UL << 26) |
507 | #define PIPE_HDMI_AUDIO_BUFFER_DONE (1UL << 27) | 507 | #define PIPE_HDMI_AUDIO_BUFFER_DONE (1UL << 27) |
508 | #define PIPE_FIFO_UNDERRUN (1UL << 31) | ||
508 | #define PIPE_HDMI_AUDIO_INT_MASK (PIPE_HDMI_AUDIO_UNDERRUN | \ | 509 | #define PIPE_HDMI_AUDIO_INT_MASK (PIPE_HDMI_AUDIO_UNDERRUN | \ |
509 | PIPE_HDMI_AUDIO_BUFFER_DONE) | 510 | PIPE_HDMI_AUDIO_BUFFER_DONE) |
510 | #define PIPE_EVENT_MASK ((1 << 29)|(1 << 28)|(1 << 27)|(1 << 26)|(1 << 24)|(1 << 23)|(1 << 22)|(1 << 21)|(1 << 20)|(1 << 16)) | 511 | #define PIPE_EVENT_MASK ((1 << 29)|(1 << 28)|(1 << 27)|(1 << 26)|(1 << 24)|(1 << 23)|(1 << 22)|(1 << 21)|(1 << 20)|(1 << 16)) |
@@ -569,12 +570,27 @@ struct dpst_guardband { | |||
569 | #define PIPE_PIXEL_MASK 0x00ffffff | 570 | #define PIPE_PIXEL_MASK 0x00ffffff |
570 | #define PIPE_PIXEL_SHIFT 0 | 571 | #define PIPE_PIXEL_SHIFT 0 |
571 | 572 | ||
573 | #define FW_BLC_SELF 0x20e0 | ||
574 | #define FW_BLC_SELF_EN (1<<15) | ||
575 | |||
572 | #define DSPARB 0x70030 | 576 | #define DSPARB 0x70030 |
573 | #define DSPFW1 0x70034 | 577 | #define DSPFW1 0x70034 |
578 | #define DSP_FIFO_SR_WM_MASK 0xFF800000 | ||
579 | #define DSP_FIFO_SR_WM_SHIFT 23 | ||
580 | #define CURSOR_B_FIFO_WM_MASK 0x003F0000 | ||
581 | #define CURSOR_B_FIFO_WM_SHIFT 16 | ||
574 | #define DSPFW2 0x70038 | 582 | #define DSPFW2 0x70038 |
583 | #define CURSOR_A_FIFO_WM_MASK 0x3F00 | ||
584 | #define CURSOR_A_FIFO_WM_SHIFT 8 | ||
585 | #define DSP_PLANE_C_FIFO_WM_MASK 0x7F | ||
586 | #define DSP_PLANE_C_FIFO_WM_SHIFT 0 | ||
575 | #define DSPFW3 0x7003c | 587 | #define DSPFW3 0x7003c |
576 | #define DSPFW4 0x70050 | 588 | #define DSPFW4 0x70050 |
577 | #define DSPFW5 0x70054 | 589 | #define DSPFW5 0x70054 |
590 | #define DSP_PLANE_B_FIFO_WM1_SHIFT 24 | ||
591 | #define DSP_PLANE_A_FIFO_WM1_SHIFT 16 | ||
592 | #define CURSOR_B_FIFO_WM1_SHIFT 8 | ||
593 | #define CURSOR_FIFO_SR_WM1_SHIFT 0 | ||
578 | #define DSPFW6 0x70058 | 594 | #define DSPFW6 0x70058 |
579 | #define DSPCHICKENBIT 0x70400 | 595 | #define DSPCHICKENBIT 0x70400 |
580 | #define DSPACNTR 0x70180 | 596 | #define DSPACNTR 0x70180 |
@@ -1290,6 +1306,15 @@ No status bits are changed. | |||
1290 | #define SB_N_CB_TUNE_MASK PSB_MASK(25, 24) | 1306 | #define SB_N_CB_TUNE_MASK PSB_MASK(25, 24) |
1291 | #define SB_N_CB_TUNE_SHIFT 24 | 1307 | #define SB_N_CB_TUNE_SHIFT 24 |
1292 | 1308 | ||
1309 | /* the bit 14:13 is used to select between the different reference clock for Pipe A/B */ | ||
1310 | #define SB_REF_DPLLA 0x8010 | ||
1311 | #define SB_REF_DPLLB 0x8030 | ||
1312 | #define REF_CLK_MASK (0x3 << 13) | ||
1313 | #define REF_CLK_CORE (0 << 13) | ||
1314 | #define REF_CLK_DPLL (1 << 13) | ||
1315 | #define REF_CLK_DPLLA (2 << 13) | ||
1316 | /* For the DPLL B, it will use the reference clk from DPLL A when using (2 << 13) */ | ||
1317 | |||
1293 | #define _SB_REF_A 0x8018 | 1318 | #define _SB_REF_A 0x8018 |
1294 | #define _SB_REF_B 0x8038 | 1319 | #define _SB_REF_B 0x8038 |
1295 | #define SB_REF_SFR(pipe) _PIPE(pipe, _SB_REF_A, _SB_REF_B) | 1320 | #define SB_REF_SFR(pipe) _PIPE(pipe, _SB_REF_A, _SB_REF_B) |