Commit 97096527 authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/anholt/drm-intel

* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/anholt/drm-intel:
  drm/i915: Select CONFIG_SHMEM
  drm/i915: Fix CRT hotplug detect by checking really no channels attached
  agp/intel: new host bridge support
  drm/i915: Add more registers save/restore for Ironlake suspend
  drm/i915: Fix IRQ stall issue on Ironlake
  drm/i915: HDMI hardware workaround for Ironlake
  drm/i915: Fix and cleanup DPLL calculation for Ironlake
  drm/i915: Avoid potential sleep whilst holding spinlock
parents b54eb179 ca9ab100
...@@ -62,6 +62,7 @@ ...@@ -62,6 +62,7 @@
#define PCI_DEVICE_ID_INTEL_IGDNG_D_IG 0x0042 #define PCI_DEVICE_ID_INTEL_IGDNG_D_IG 0x0042
#define PCI_DEVICE_ID_INTEL_IGDNG_M_HB 0x0044 #define PCI_DEVICE_ID_INTEL_IGDNG_M_HB 0x0044
#define PCI_DEVICE_ID_INTEL_IGDNG_MA_HB 0x0062 #define PCI_DEVICE_ID_INTEL_IGDNG_MA_HB 0x0062
#define PCI_DEVICE_ID_INTEL_IGDNG_MC2_HB 0x006a
#define PCI_DEVICE_ID_INTEL_IGDNG_M_IG 0x0046 #define PCI_DEVICE_ID_INTEL_IGDNG_M_IG 0x0046
/* cover 915 and 945 variants */ /* cover 915 and 945 variants */
...@@ -96,7 +97,8 @@ ...@@ -96,7 +97,8 @@
agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_B43_HB || \ agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_B43_HB || \
agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_IGDNG_D_HB || \ agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_IGDNG_D_HB || \
agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_IGDNG_M_HB || \ agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_IGDNG_M_HB || \
agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_IGDNG_MA_HB) agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_IGDNG_MA_HB || \
agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_IGDNG_MC2_HB)
extern int agp_memory_reserved; extern int agp_memory_reserved;
...@@ -1358,6 +1360,7 @@ static void intel_i965_get_gtt_range(int *gtt_offset, int *gtt_size) ...@@ -1358,6 +1360,7 @@ static void intel_i965_get_gtt_range(int *gtt_offset, int *gtt_size)
case PCI_DEVICE_ID_INTEL_IGDNG_D_HB: case PCI_DEVICE_ID_INTEL_IGDNG_D_HB:
case PCI_DEVICE_ID_INTEL_IGDNG_M_HB: case PCI_DEVICE_ID_INTEL_IGDNG_M_HB:
case PCI_DEVICE_ID_INTEL_IGDNG_MA_HB: case PCI_DEVICE_ID_INTEL_IGDNG_MA_HB:
case PCI_DEVICE_ID_INTEL_IGDNG_MC2_HB:
*gtt_offset = *gtt_size = MB(2); *gtt_offset = *gtt_size = MB(2);
break; break;
default: default:
...@@ -2359,6 +2362,8 @@ static const struct intel_driver_description { ...@@ -2359,6 +2362,8 @@ static const struct intel_driver_description {
"IGDNG/M", NULL, &intel_i965_driver }, "IGDNG/M", NULL, &intel_i965_driver },
{ PCI_DEVICE_ID_INTEL_IGDNG_MA_HB, PCI_DEVICE_ID_INTEL_IGDNG_M_IG, 0, { PCI_DEVICE_ID_INTEL_IGDNG_MA_HB, PCI_DEVICE_ID_INTEL_IGDNG_M_IG, 0,
"IGDNG/MA", NULL, &intel_i965_driver }, "IGDNG/MA", NULL, &intel_i965_driver },
{ PCI_DEVICE_ID_INTEL_IGDNG_MC2_HB, PCI_DEVICE_ID_INTEL_IGDNG_M_IG, 0,
"IGDNG/MC2", NULL, &intel_i965_driver },
{ 0, 0, 0, NULL, NULL, NULL } { 0, 0, 0, NULL, NULL, NULL }
}; };
...@@ -2560,6 +2565,7 @@ static struct pci_device_id agp_intel_pci_table[] = { ...@@ -2560,6 +2565,7 @@ static struct pci_device_id agp_intel_pci_table[] = {
ID(PCI_DEVICE_ID_INTEL_IGDNG_D_HB), ID(PCI_DEVICE_ID_INTEL_IGDNG_D_HB),
ID(PCI_DEVICE_ID_INTEL_IGDNG_M_HB), ID(PCI_DEVICE_ID_INTEL_IGDNG_M_HB),
ID(PCI_DEVICE_ID_INTEL_IGDNG_MA_HB), ID(PCI_DEVICE_ID_INTEL_IGDNG_MA_HB),
ID(PCI_DEVICE_ID_INTEL_IGDNG_MC2_HB),
{ } { }
}; };
......
...@@ -92,6 +92,7 @@ config DRM_I830 ...@@ -92,6 +92,7 @@ config DRM_I830
config DRM_I915 config DRM_I915
tristate "i915 driver" tristate "i915 driver"
depends on AGP_INTEL depends on AGP_INTEL
select SHMEM
select DRM_KMS_HELPER select DRM_KMS_HELPER
select FB_CFB_FILLRECT select FB_CFB_FILLRECT
select FB_CFB_COPYAREA select FB_CFB_COPYAREA
......
...@@ -267,10 +267,10 @@ static void i915_dump_pages(struct seq_file *m, struct page **pages, int page_co ...@@ -267,10 +267,10 @@ static void i915_dump_pages(struct seq_file *m, struct page **pages, int page_co
uint32_t *mem; uint32_t *mem;
for (page = 0; page < page_count; page++) { for (page = 0; page < page_count; page++) {
mem = kmap(pages[page]); mem = kmap_atomic(pages[page], KM_USER0);
for (i = 0; i < PAGE_SIZE; i += 4) for (i = 0; i < PAGE_SIZE; i += 4)
seq_printf(m, "%08x : %08x\n", i, mem[i / 4]); seq_printf(m, "%08x : %08x\n", i, mem[i / 4]);
kunmap(pages[page]); kunmap_atomic(pages[page], KM_USER0);
} }
} }
......
...@@ -296,6 +296,7 @@ typedef struct drm_i915_private { ...@@ -296,6 +296,7 @@ typedef struct drm_i915_private {
u32 saveVBLANK_A; u32 saveVBLANK_A;
u32 saveVSYNC_A; u32 saveVSYNC_A;
u32 saveBCLRPAT_A; u32 saveBCLRPAT_A;
u32 saveTRANSACONF;
u32 saveTRANS_HTOTAL_A; u32 saveTRANS_HTOTAL_A;
u32 saveTRANS_HBLANK_A; u32 saveTRANS_HBLANK_A;
u32 saveTRANS_HSYNC_A; u32 saveTRANS_HSYNC_A;
...@@ -326,6 +327,7 @@ typedef struct drm_i915_private { ...@@ -326,6 +327,7 @@ typedef struct drm_i915_private {
u32 saveVBLANK_B; u32 saveVBLANK_B;
u32 saveVSYNC_B; u32 saveVSYNC_B;
u32 saveBCLRPAT_B; u32 saveBCLRPAT_B;
u32 saveTRANSBCONF;
u32 saveTRANS_HTOTAL_B; u32 saveTRANS_HTOTAL_B;
u32 saveTRANS_HBLANK_B; u32 saveTRANS_HBLANK_B;
u32 saveTRANS_HSYNC_B; u32 saveTRANS_HSYNC_B;
...@@ -414,6 +416,16 @@ typedef struct drm_i915_private { ...@@ -414,6 +416,16 @@ typedef struct drm_i915_private {
u32 savePFB_WIN_SZ; u32 savePFB_WIN_SZ;
u32 savePFA_WIN_POS; u32 savePFA_WIN_POS;
u32 savePFB_WIN_POS; u32 savePFB_WIN_POS;
u32 savePCH_DREF_CONTROL;
u32 saveDISP_ARB_CTL;
u32 savePIPEA_DATA_M1;
u32 savePIPEA_DATA_N1;
u32 savePIPEA_LINK_M1;
u32 savePIPEA_LINK_N1;
u32 savePIPEB_DATA_M1;
u32 savePIPEB_DATA_N1;
u32 savePIPEB_LINK_M1;
u32 savePIPEB_LINK_N1;
struct { struct {
struct drm_mm gtt_space; struct drm_mm gtt_space;
......
...@@ -254,10 +254,15 @@ irqreturn_t igdng_irq_handler(struct drm_device *dev) ...@@ -254,10 +254,15 @@ irqreturn_t igdng_irq_handler(struct drm_device *dev)
{ {
drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
int ret = IRQ_NONE; int ret = IRQ_NONE;
u32 de_iir, gt_iir; u32 de_iir, gt_iir, de_ier;
u32 new_de_iir, new_gt_iir; u32 new_de_iir, new_gt_iir;
struct drm_i915_master_private *master_priv; struct drm_i915_master_private *master_priv;
/* disable master interrupt before clearing iir */
de_ier = I915_READ(DEIER);
I915_WRITE(DEIER, de_ier & ~DE_MASTER_IRQ_CONTROL);
(void)I915_READ(DEIER);
de_iir = I915_READ(DEIIR); de_iir = I915_READ(DEIIR);
gt_iir = I915_READ(GTIIR); gt_iir = I915_READ(GTIIR);
...@@ -290,6 +295,9 @@ irqreturn_t igdng_irq_handler(struct drm_device *dev) ...@@ -290,6 +295,9 @@ irqreturn_t igdng_irq_handler(struct drm_device *dev)
gt_iir = new_gt_iir; gt_iir = new_gt_iir;
} }
I915_WRITE(DEIER, de_ier);
(void)I915_READ(DEIER);
return ret; return ret;
} }
......
...@@ -239,6 +239,11 @@ static void i915_save_modeset_reg(struct drm_device *dev) ...@@ -239,6 +239,11 @@ static void i915_save_modeset_reg(struct drm_device *dev)
if (drm_core_check_feature(dev, DRIVER_MODESET)) if (drm_core_check_feature(dev, DRIVER_MODESET))
return; return;
if (IS_IGDNG(dev)) {
dev_priv->savePCH_DREF_CONTROL = I915_READ(PCH_DREF_CONTROL);
dev_priv->saveDISP_ARB_CTL = I915_READ(DISP_ARB_CTL);
}
/* Pipe & plane A info */ /* Pipe & plane A info */
dev_priv->savePIPEACONF = I915_READ(PIPEACONF); dev_priv->savePIPEACONF = I915_READ(PIPEACONF);
dev_priv->savePIPEASRC = I915_READ(PIPEASRC); dev_priv->savePIPEASRC = I915_READ(PIPEASRC);
...@@ -263,6 +268,11 @@ static void i915_save_modeset_reg(struct drm_device *dev) ...@@ -263,6 +268,11 @@ static void i915_save_modeset_reg(struct drm_device *dev)
dev_priv->saveBCLRPAT_A = I915_READ(BCLRPAT_A); dev_priv->saveBCLRPAT_A = I915_READ(BCLRPAT_A);
if (IS_IGDNG(dev)) { if (IS_IGDNG(dev)) {
dev_priv->savePIPEA_DATA_M1 = I915_READ(PIPEA_DATA_M1);
dev_priv->savePIPEA_DATA_N1 = I915_READ(PIPEA_DATA_N1);
dev_priv->savePIPEA_LINK_M1 = I915_READ(PIPEA_LINK_M1);
dev_priv->savePIPEA_LINK_N1 = I915_READ(PIPEA_LINK_N1);
dev_priv->saveFDI_TXA_CTL = I915_READ(FDI_TXA_CTL); dev_priv->saveFDI_TXA_CTL = I915_READ(FDI_TXA_CTL);
dev_priv->saveFDI_RXA_CTL = I915_READ(FDI_RXA_CTL); dev_priv->saveFDI_RXA_CTL = I915_READ(FDI_RXA_CTL);
...@@ -270,6 +280,7 @@ static void i915_save_modeset_reg(struct drm_device *dev) ...@@ -270,6 +280,7 @@ static void i915_save_modeset_reg(struct drm_device *dev)
dev_priv->savePFA_WIN_SZ = I915_READ(PFA_WIN_SZ); dev_priv->savePFA_WIN_SZ = I915_READ(PFA_WIN_SZ);
dev_priv->savePFA_WIN_POS = I915_READ(PFA_WIN_POS); dev_priv->savePFA_WIN_POS = I915_READ(PFA_WIN_POS);
dev_priv->saveTRANSACONF = I915_READ(TRANSACONF);
dev_priv->saveTRANS_HTOTAL_A = I915_READ(TRANS_HTOTAL_A); dev_priv->saveTRANS_HTOTAL_A = I915_READ(TRANS_HTOTAL_A);
dev_priv->saveTRANS_HBLANK_A = I915_READ(TRANS_HBLANK_A); dev_priv->saveTRANS_HBLANK_A = I915_READ(TRANS_HBLANK_A);
dev_priv->saveTRANS_HSYNC_A = I915_READ(TRANS_HSYNC_A); dev_priv->saveTRANS_HSYNC_A = I915_READ(TRANS_HSYNC_A);
...@@ -314,6 +325,11 @@ static void i915_save_modeset_reg(struct drm_device *dev) ...@@ -314,6 +325,11 @@ static void i915_save_modeset_reg(struct drm_device *dev)
dev_priv->saveBCLRPAT_B = I915_READ(BCLRPAT_B); dev_priv->saveBCLRPAT_B = I915_READ(BCLRPAT_B);
if (IS_IGDNG(dev)) { if (IS_IGDNG(dev)) {
dev_priv->savePIPEB_DATA_M1 = I915_READ(PIPEB_DATA_M1);
dev_priv->savePIPEB_DATA_N1 = I915_READ(PIPEB_DATA_N1);
dev_priv->savePIPEB_LINK_M1 = I915_READ(PIPEB_LINK_M1);
dev_priv->savePIPEB_LINK_N1 = I915_READ(PIPEB_LINK_N1);
dev_priv->saveFDI_TXB_CTL = I915_READ(FDI_TXB_CTL); dev_priv->saveFDI_TXB_CTL = I915_READ(FDI_TXB_CTL);
dev_priv->saveFDI_RXB_CTL = I915_READ(FDI_RXB_CTL); dev_priv->saveFDI_RXB_CTL = I915_READ(FDI_RXB_CTL);
...@@ -321,6 +337,7 @@ static void i915_save_modeset_reg(struct drm_device *dev) ...@@ -321,6 +337,7 @@ static void i915_save_modeset_reg(struct drm_device *dev)
dev_priv->savePFB_WIN_SZ = I915_READ(PFB_WIN_SZ); dev_priv->savePFB_WIN_SZ = I915_READ(PFB_WIN_SZ);
dev_priv->savePFB_WIN_POS = I915_READ(PFB_WIN_POS); dev_priv->savePFB_WIN_POS = I915_READ(PFB_WIN_POS);
dev_priv->saveTRANSBCONF = I915_READ(TRANSBCONF);
dev_priv->saveTRANS_HTOTAL_B = I915_READ(TRANS_HTOTAL_B); dev_priv->saveTRANS_HTOTAL_B = I915_READ(TRANS_HTOTAL_B);
dev_priv->saveTRANS_HBLANK_B = I915_READ(TRANS_HBLANK_B); dev_priv->saveTRANS_HBLANK_B = I915_READ(TRANS_HBLANK_B);
dev_priv->saveTRANS_HSYNC_B = I915_READ(TRANS_HSYNC_B); dev_priv->saveTRANS_HSYNC_B = I915_READ(TRANS_HSYNC_B);
...@@ -368,6 +385,11 @@ static void i915_restore_modeset_reg(struct drm_device *dev) ...@@ -368,6 +385,11 @@ static void i915_restore_modeset_reg(struct drm_device *dev)
fpb1_reg = FPB1; fpb1_reg = FPB1;
} }
if (IS_IGDNG(dev)) {
I915_WRITE(PCH_DREF_CONTROL, dev_priv->savePCH_DREF_CONTROL);
I915_WRITE(DISP_ARB_CTL, dev_priv->saveDISP_ARB_CTL);
}
/* Pipe & plane A info */ /* Pipe & plane A info */
/* Prime the clock */ /* Prime the clock */
if (dev_priv->saveDPLL_A & DPLL_VCO_ENABLE) { if (dev_priv->saveDPLL_A & DPLL_VCO_ENABLE) {
...@@ -395,6 +417,11 @@ static void i915_restore_modeset_reg(struct drm_device *dev) ...@@ -395,6 +417,11 @@ static void i915_restore_modeset_reg(struct drm_device *dev)
I915_WRITE(BCLRPAT_A, dev_priv->saveBCLRPAT_A); I915_WRITE(BCLRPAT_A, dev_priv->saveBCLRPAT_A);
if (IS_IGDNG(dev)) { if (IS_IGDNG(dev)) {
I915_WRITE(PIPEA_DATA_M1, dev_priv->savePIPEA_DATA_M1);
I915_WRITE(PIPEA_DATA_N1, dev_priv->savePIPEA_DATA_N1);
I915_WRITE(PIPEA_LINK_M1, dev_priv->savePIPEA_LINK_M1);
I915_WRITE(PIPEA_LINK_N1, dev_priv->savePIPEA_LINK_N1);
I915_WRITE(FDI_RXA_CTL, dev_priv->saveFDI_RXA_CTL); I915_WRITE(FDI_RXA_CTL, dev_priv->saveFDI_RXA_CTL);
I915_WRITE(FDI_TXA_CTL, dev_priv->saveFDI_TXA_CTL); I915_WRITE(FDI_TXA_CTL, dev_priv->saveFDI_TXA_CTL);
...@@ -402,6 +429,7 @@ static void i915_restore_modeset_reg(struct drm_device *dev) ...@@ -402,6 +429,7 @@ static void i915_restore_modeset_reg(struct drm_device *dev)
I915_WRITE(PFA_WIN_SZ, dev_priv->savePFA_WIN_SZ); I915_WRITE(PFA_WIN_SZ, dev_priv->savePFA_WIN_SZ);
I915_WRITE(PFA_WIN_POS, dev_priv->savePFA_WIN_POS); I915_WRITE(PFA_WIN_POS, dev_priv->savePFA_WIN_POS);
I915_WRITE(TRANSACONF, dev_priv->saveTRANSACONF);
I915_WRITE(TRANS_HTOTAL_A, dev_priv->saveTRANS_HTOTAL_A); I915_WRITE(TRANS_HTOTAL_A, dev_priv->saveTRANS_HTOTAL_A);
I915_WRITE(TRANS_HBLANK_A, dev_priv->saveTRANS_HBLANK_A); I915_WRITE(TRANS_HBLANK_A, dev_priv->saveTRANS_HBLANK_A);
I915_WRITE(TRANS_HSYNC_A, dev_priv->saveTRANS_HSYNC_A); I915_WRITE(TRANS_HSYNC_A, dev_priv->saveTRANS_HSYNC_A);
...@@ -439,7 +467,7 @@ static void i915_restore_modeset_reg(struct drm_device *dev) ...@@ -439,7 +467,7 @@ static void i915_restore_modeset_reg(struct drm_device *dev)
/* Actually enable it */ /* Actually enable it */
I915_WRITE(dpll_b_reg, dev_priv->saveDPLL_B); I915_WRITE(dpll_b_reg, dev_priv->saveDPLL_B);
DRM_UDELAY(150); DRM_UDELAY(150);
if (IS_I965G(dev)) if (IS_I965G(dev) && !IS_IGDNG(dev))
I915_WRITE(DPLL_B_MD, dev_priv->saveDPLL_B_MD); I915_WRITE(DPLL_B_MD, dev_priv->saveDPLL_B_MD);
DRM_UDELAY(150); DRM_UDELAY(150);
...@@ -454,6 +482,11 @@ static void i915_restore_modeset_reg(struct drm_device *dev) ...@@ -454,6 +482,11 @@ static void i915_restore_modeset_reg(struct drm_device *dev)
I915_WRITE(BCLRPAT_B, dev_priv->saveBCLRPAT_B); I915_WRITE(BCLRPAT_B, dev_priv->saveBCLRPAT_B);
if (IS_IGDNG(dev)) { if (IS_IGDNG(dev)) {
I915_WRITE(PIPEB_DATA_M1, dev_priv->savePIPEB_DATA_M1);
I915_WRITE(PIPEB_DATA_N1, dev_priv->savePIPEB_DATA_N1);
I915_WRITE(PIPEB_LINK_M1, dev_priv->savePIPEB_LINK_M1);
I915_WRITE(PIPEB_LINK_N1, dev_priv->savePIPEB_LINK_N1);
I915_WRITE(FDI_RXB_CTL, dev_priv->saveFDI_RXB_CTL); I915_WRITE(FDI_RXB_CTL, dev_priv->saveFDI_RXB_CTL);
I915_WRITE(FDI_TXB_CTL, dev_priv->saveFDI_TXB_CTL); I915_WRITE(FDI_TXB_CTL, dev_priv->saveFDI_TXB_CTL);
...@@ -461,6 +494,7 @@ static void i915_restore_modeset_reg(struct drm_device *dev) ...@@ -461,6 +494,7 @@ static void i915_restore_modeset_reg(struct drm_device *dev)
I915_WRITE(PFB_WIN_SZ, dev_priv->savePFB_WIN_SZ); I915_WRITE(PFB_WIN_SZ, dev_priv->savePFB_WIN_SZ);
I915_WRITE(PFB_WIN_POS, dev_priv->savePFB_WIN_POS); I915_WRITE(PFB_WIN_POS, dev_priv->savePFB_WIN_POS);
I915_WRITE(TRANSBCONF, dev_priv->saveTRANSBCONF);
I915_WRITE(TRANS_HTOTAL_B, dev_priv->saveTRANS_HTOTAL_B); I915_WRITE(TRANS_HTOTAL_B, dev_priv->saveTRANS_HTOTAL_B);
I915_WRITE(TRANS_HBLANK_B, dev_priv->saveTRANS_HBLANK_B); I915_WRITE(TRANS_HBLANK_B, dev_priv->saveTRANS_HBLANK_B);
I915_WRITE(TRANS_HSYNC_B, dev_priv->saveTRANS_HSYNC_B); I915_WRITE(TRANS_HSYNC_B, dev_priv->saveTRANS_HSYNC_B);
......
...@@ -262,8 +262,8 @@ static bool intel_crt_detect_hotplug(struct drm_connector *connector) ...@@ -262,8 +262,8 @@ static bool intel_crt_detect_hotplug(struct drm_connector *connector)
} while (time_after(timeout, jiffies)); } while (time_after(timeout, jiffies));
} }
if ((I915_READ(PORT_HOTPLUG_STAT) & CRT_HOTPLUG_MONITOR_MASK) == if ((I915_READ(PORT_HOTPLUG_STAT) & CRT_HOTPLUG_MONITOR_MASK) !=
CRT_HOTPLUG_MONITOR_COLOR) CRT_HOTPLUG_MONITOR_NONE)
return true; return true;
return false; return false;
......
...@@ -863,10 +863,8 @@ intel_igdng_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc, ...@@ -863,10 +863,8 @@ intel_igdng_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc,
struct drm_device *dev = crtc->dev; struct drm_device *dev = crtc->dev;
struct drm_i915_private *dev_priv = dev->dev_private; struct drm_i915_private *dev_priv = dev->dev_private;
intel_clock_t clock; intel_clock_t clock;
int max_n;
bool found;
int err_most = 47; int err_most = 47;
found = false; int err_min = 10000;
/* eDP has only 2 clock choice, no n/m/p setting */ /* eDP has only 2 clock choice, no n/m/p setting */
if (HAS_eDP) if (HAS_eDP)
...@@ -890,10 +888,9 @@ intel_igdng_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc, ...@@ -890,10 +888,9 @@ intel_igdng_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc,
} }
memset(best_clock, 0, sizeof(*best_clock)); memset(best_clock, 0, sizeof(*best_clock));
max_n = limit->n.max;
for (clock.p1 = limit->p1.max; clock.p1 >= limit->p1.min; clock.p1--) { for (clock.p1 = limit->p1.max; clock.p1 >= limit->p1.min; clock.p1--) {
/* based on hardware requriment prefer smaller n to precision */ /* based on hardware requriment prefer smaller n to precision */
for (clock.n = limit->n.min; clock.n <= max_n; clock.n++) { for (clock.n = limit->n.min; clock.n <= limit->n.max; clock.n++) {
/* based on hardware requirment prefere larger m1,m2 */ /* based on hardware requirment prefere larger m1,m2 */
for (clock.m1 = limit->m1.max; for (clock.m1 = limit->m1.max;
clock.m1 >= limit->m1.min; clock.m1--) { clock.m1 >= limit->m1.min; clock.m1--) {
...@@ -907,18 +904,18 @@ intel_igdng_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc, ...@@ -907,18 +904,18 @@ intel_igdng_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc,
this_err = abs((10000 - (target*10000/clock.dot))); this_err = abs((10000 - (target*10000/clock.dot)));
if (this_err < err_most) { if (this_err < err_most) {
*best_clock = clock; *best_clock = clock;
err_most = this_err;
max_n = clock.n;
found = true;
/* found on first matching */ /* found on first matching */
goto out; goto out;
} else if (this_err < err_min) {
*best_clock = clock;
err_min = this_err;
} }
} }
} }
} }
} }
out: out:
return found; return true;
} }
/* DisplayPort has only two frequencies, 162MHz and 270MHz */ /* DisplayPort has only two frequencies, 162MHz and 270MHz */
......
...@@ -77,14 +77,32 @@ static void intel_hdmi_dpms(struct drm_encoder *encoder, int mode) ...@@ -77,14 +77,32 @@ static void intel_hdmi_dpms(struct drm_encoder *encoder, int mode)
struct intel_hdmi_priv *hdmi_priv = intel_output->dev_priv; struct intel_hdmi_priv *hdmi_priv = intel_output->dev_priv;
u32 temp; u32 temp;
if (mode != DRM_MODE_DPMS_ON) { temp = I915_READ(hdmi_priv->sdvox_reg);
temp = I915_READ(hdmi_priv->sdvox_reg);
/* HW workaround, need to toggle enable bit off and on for 12bpc, but
* we do this anyway which shows more stable in testing.
*/
if (IS_IGDNG(dev)) {
I915_WRITE(hdmi_priv->sdvox_reg, temp & ~SDVO_ENABLE); I915_WRITE(hdmi_priv->sdvox_reg, temp & ~SDVO_ENABLE);
POSTING_READ(hdmi_priv->sdvox_reg);
}
if (mode != DRM_MODE_DPMS_ON) {
temp &= ~SDVO_ENABLE;
} else { } else {
temp = I915_READ(hdmi_priv->sdvox_reg); temp |= SDVO_ENABLE;
I915_WRITE(hdmi_priv->sdvox_reg, temp | SDVO_ENABLE);
} }
I915_WRITE(hdmi_priv->sdvox_reg, temp);
POSTING_READ(hdmi_priv->sdvox_reg); POSTING_READ(hdmi_priv->sdvox_reg);
/* HW workaround, need to write this twice for issue that may result
* in first write getting masked.
*/
if (IS_IGDNG(dev)) {
I915_WRITE(hdmi_priv->sdvox_reg, temp);
POSTING_READ(hdmi_priv->sdvox_reg);
}
} }
static void intel_hdmi_save(struct drm_connector *connector) static void intel_hdmi_save(struct drm_connector *connector)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment