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
This commit is contained in:
commit
9709652703
|
@ -62,6 +62,7 @@
|
|||
#define PCI_DEVICE_ID_INTEL_IGDNG_D_IG 0x0042
|
||||
#define PCI_DEVICE_ID_INTEL_IGDNG_M_HB 0x0044
|
||||
#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
|
||||
|
||||
/* cover 915 and 945 variants */
|
||||
|
@ -96,7 +97,8 @@
|
|||
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_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;
|
||||
|
||||
|
@ -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_M_HB:
|
||||
case PCI_DEVICE_ID_INTEL_IGDNG_MA_HB:
|
||||
case PCI_DEVICE_ID_INTEL_IGDNG_MC2_HB:
|
||||
*gtt_offset = *gtt_size = MB(2);
|
||||
break;
|
||||
default:
|
||||
|
@ -2359,6 +2362,8 @@ static const struct intel_driver_description {
|
|||
"IGDNG/M", NULL, &intel_i965_driver },
|
||||
{ PCI_DEVICE_ID_INTEL_IGDNG_MA_HB, PCI_DEVICE_ID_INTEL_IGDNG_M_IG, 0,
|
||||
"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 }
|
||||
};
|
||||
|
||||
|
@ -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_M_HB),
|
||||
ID(PCI_DEVICE_ID_INTEL_IGDNG_MA_HB),
|
||||
ID(PCI_DEVICE_ID_INTEL_IGDNG_MC2_HB),
|
||||
{ }
|
||||
};
|
||||
|
||||
|
|
|
@ -92,6 +92,7 @@ config DRM_I830
|
|||
config DRM_I915
|
||||
tristate "i915 driver"
|
||||
depends on AGP_INTEL
|
||||
select SHMEM
|
||||
select DRM_KMS_HELPER
|
||||
select FB_CFB_FILLRECT
|
||||
select FB_CFB_COPYAREA
|
||||
|
|
|
@ -267,10 +267,10 @@ static void i915_dump_pages(struct seq_file *m, struct page **pages, int page_co
|
|||
uint32_t *mem;
|
||||
|
||||
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)
|
||||
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 {
|
|||
u32 saveVBLANK_A;
|
||||
u32 saveVSYNC_A;
|
||||
u32 saveBCLRPAT_A;
|
||||
u32 saveTRANSACONF;
|
||||
u32 saveTRANS_HTOTAL_A;
|
||||
u32 saveTRANS_HBLANK_A;
|
||||
u32 saveTRANS_HSYNC_A;
|
||||
|
@ -326,6 +327,7 @@ typedef struct drm_i915_private {
|
|||
u32 saveVBLANK_B;
|
||||
u32 saveVSYNC_B;
|
||||
u32 saveBCLRPAT_B;
|
||||
u32 saveTRANSBCONF;
|
||||
u32 saveTRANS_HTOTAL_B;
|
||||
u32 saveTRANS_HBLANK_B;
|
||||
u32 saveTRANS_HSYNC_B;
|
||||
|
@ -414,6 +416,16 @@ typedef struct drm_i915_private {
|
|||
u32 savePFB_WIN_SZ;
|
||||
u32 savePFA_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 drm_mm gtt_space;
|
||||
|
|
|
@ -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;
|
||||
int ret = IRQ_NONE;
|
||||
u32 de_iir, gt_iir;
|
||||
u32 de_iir, gt_iir, de_ier;
|
||||
u32 new_de_iir, new_gt_iir;
|
||||
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);
|
||||
gt_iir = I915_READ(GTIIR);
|
||||
|
||||
|
@ -290,6 +295,9 @@ irqreturn_t igdng_irq_handler(struct drm_device *dev)
|
|||
gt_iir = new_gt_iir;
|
||||
}
|
||||
|
||||
I915_WRITE(DEIER, de_ier);
|
||||
(void)I915_READ(DEIER);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
|
@ -239,6 +239,11 @@ static void i915_save_modeset_reg(struct drm_device *dev)
|
|||
if (drm_core_check_feature(dev, DRIVER_MODESET))
|
||||
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 */
|
||||
dev_priv->savePIPEACONF = I915_READ(PIPEACONF);
|
||||
dev_priv->savePIPEASRC = I915_READ(PIPEASRC);
|
||||
|
@ -263,6 +268,11 @@ static void i915_save_modeset_reg(struct drm_device *dev)
|
|||
dev_priv->saveBCLRPAT_A = I915_READ(BCLRPAT_A);
|
||||
|
||||
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_RXA_CTL = I915_READ(FDI_RXA_CTL);
|
||||
|
||||
|
@ -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_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_HBLANK_A = I915_READ(TRANS_HBLANK_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)
|
|||
dev_priv->saveBCLRPAT_B = I915_READ(BCLRPAT_B);
|
||||
|
||||
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_RXB_CTL = I915_READ(FDI_RXB_CTL);
|
||||
|
||||
|
@ -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_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_HBLANK_B = I915_READ(TRANS_HBLANK_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)
|
|||
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 */
|
||||
/* Prime the clock */
|
||||
if (dev_priv->saveDPLL_A & DPLL_VCO_ENABLE) {
|
||||
|
@ -395,6 +417,11 @@ static void i915_restore_modeset_reg(struct drm_device *dev)
|
|||
I915_WRITE(BCLRPAT_A, dev_priv->saveBCLRPAT_A);
|
||||
|
||||
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_TXA_CTL, dev_priv->saveFDI_TXA_CTL);
|
||||
|
||||
|
@ -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_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_HBLANK_A, dev_priv->saveTRANS_HBLANK_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)
|
|||
/* Actually enable it */
|
||||
I915_WRITE(dpll_b_reg, dev_priv->saveDPLL_B);
|
||||
DRM_UDELAY(150);
|
||||
if (IS_I965G(dev))
|
||||
if (IS_I965G(dev) && !IS_IGDNG(dev))
|
||||
I915_WRITE(DPLL_B_MD, dev_priv->saveDPLL_B_MD);
|
||||
DRM_UDELAY(150);
|
||||
|
||||
|
@ -454,6 +482,11 @@ static void i915_restore_modeset_reg(struct drm_device *dev)
|
|||
I915_WRITE(BCLRPAT_B, dev_priv->saveBCLRPAT_B);
|
||||
|
||||
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_TXB_CTL, dev_priv->saveFDI_TXB_CTL);
|
||||
|
||||
|
@ -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_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_HBLANK_B, dev_priv->saveTRANS_HBLANK_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)
|
|||
} while (time_after(timeout, jiffies));
|
||||
}
|
||||
|
||||
if ((I915_READ(PORT_HOTPLUG_STAT) & CRT_HOTPLUG_MONITOR_MASK) ==
|
||||
CRT_HOTPLUG_MONITOR_COLOR)
|
||||
if ((I915_READ(PORT_HOTPLUG_STAT) & CRT_HOTPLUG_MONITOR_MASK) !=
|
||||
CRT_HOTPLUG_MONITOR_NONE)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
|
|
|
@ -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_i915_private *dev_priv = dev->dev_private;
|
||||
intel_clock_t clock;
|
||||
int max_n;
|
||||
bool found;
|
||||
int err_most = 47;
|
||||
found = false;
|
||||
int err_min = 10000;
|
||||
|
||||
/* eDP has only 2 clock choice, no n/m/p setting */
|
||||
if (HAS_eDP)
|
||||
|
@ -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));
|
||||
max_n = limit->n.max;
|
||||
for (clock.p1 = limit->p1.max; clock.p1 >= limit->p1.min; clock.p1--) {
|
||||
/* 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 */
|
||||
for (clock.m1 = limit->m1.max;
|
||||
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,
|
|||
this_err = abs((10000 - (target*10000/clock.dot)));
|
||||
if (this_err < err_most) {
|
||||
*best_clock = clock;
|
||||
err_most = this_err;
|
||||
max_n = clock.n;
|
||||
found = true;
|
||||
/* found on first matching */
|
||||
goto out;
|
||||
} else if (this_err < err_min) {
|
||||
*best_clock = clock;
|
||||
err_min = this_err;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
out:
|
||||
return found;
|
||||
return true;
|
||||
}
|
||||
|
||||
/* DisplayPort has only two frequencies, 162MHz and 270MHz */
|
||||
|
|
|
@ -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;
|
||||
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);
|
||||
} else {
|
||||
temp = I915_READ(hdmi_priv->sdvox_reg);
|
||||
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 {
|
||||
temp |= SDVO_ENABLE;
|
||||
}
|
||||
|
||||
I915_WRITE(hdmi_priv->sdvox_reg, temp);
|
||||
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)
|
||||
|
|
Loading…
Reference in New Issue