/* * Determine various intel_device_info fields at runtime. * * Use it when either: * - it's judged too laborious to fill n static structures with the limit * when a simple if statement does the job, * - run-time checks (eg read fuse/strap registers) are needed. * * This function needs to be called: * - after the MMIO has been setup as we are reading registers, * - after the PCH has been detected, * - before the first usage of the fields it can tweak. */ static void intel_device_info_runtime_init(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; struct intel_device_info *info; enum pipe pipe; info = (struct intel_device_info *)&dev_priv->info; if (IS_VALLEYVIEW(dev) || INTEL_INFO(dev)->gen == 9) for_each_pipe(dev_priv, pipe) info->num_sprites[pipe] = 2; else for_each_pipe(dev_priv, pipe) info->num_sprites[pipe] = 1; if (i915.disable_display) { DRM_INFO("Display disabled (module parameter)\n"); info->num_pipes = 0; } else if (info->num_pipes > 0 && (INTEL_INFO(dev)->gen == 7 || INTEL_INFO(dev)->gen == 8) && !IS_VALLEYVIEW(dev)) { u32 fuse_strap = I915_READ(FUSE_STRAP); u32 sfuse_strap = I915_READ(SFUSE_STRAP); /* * SFUSE_STRAP is supposed to have a bit signalling the display * is fused off. Unfortunately it seems that, at least in * certain cases, fused off display means that PCH display * reads don't land anywhere. In that case, we read 0s. * * On CPT/PPT, we can detect this case as SFUSE_STRAP_FUSE_LOCK * should be set when taking over after the firmware. */ if (fuse_strap & ILK_INTERNAL_DISPLAY_DISABLE || sfuse_strap & SFUSE_STRAP_DISPLAY_DISABLED || (dev_priv->pch_type == PCH_CPT && !(sfuse_strap & SFUSE_STRAP_FUSE_LOCK))) { DRM_INFO("Display fused off, disabling\n"); info->num_pipes = 0; } } }
static bool intel_dp_create_fake_mst_encoders(struct intel_digital_port *intel_dig_port) { struct intel_dp *intel_dp = &intel_dig_port->dp; struct drm_i915_private *dev_priv = to_i915(intel_dig_port->base.base.dev); enum pipe pipe; for_each_pipe(dev_priv, pipe) intel_dp->mst_encoders[pipe] = intel_dp_create_fake_mst_encoder(intel_dig_port, pipe); return true; }
static int display_crc_ctl_show(struct seq_file *m, void *data) { struct drm_i915_private *dev_priv = m->private; enum pipe pipe; for_each_pipe(dev_priv, pipe) seq_printf(m, "%c %s\n", pipe_name(pipe), pipe_crc_source_name(dev_priv->pipe_crc[pipe].source)); return 0; }
static void vlv_dpio_cmn_power_well_disable(struct drm_i915_private *dev_priv, struct i915_power_well *power_well) { enum pipe pipe; WARN_ON_ONCE(power_well->data != PUNIT_POWER_WELL_DPIO_CMN_BC); for_each_pipe(dev_priv, pipe) assert_pll_disabled(dev_priv, pipe); /* Assert common reset */ I915_WRITE(DPIO_CTL, I915_READ(DPIO_CTL) & ~DPIO_CMNRST); vlv_set_power_well(dev_priv, power_well, false); }
void intel_hdmi_init(struct drm_device *dev, int sdvox_reg) { struct drm_i915_private *dev_priv = dev->dev_private; struct drm_connector *connector; struct intel_encoder *intel_encoder; struct intel_connector *intel_connector; struct intel_hdmi *intel_hdmi; int i; intel_hdmi = kzalloc(sizeof(struct intel_hdmi), GFP_KERNEL); if (!intel_hdmi) return; intel_connector = kzalloc(sizeof(struct intel_connector), GFP_KERNEL); if (!intel_connector) { kfree(intel_hdmi); return; } intel_encoder = &intel_hdmi->base; drm_encoder_init(dev, &intel_encoder->base, &intel_hdmi_enc_funcs, DRM_MODE_ENCODER_TMDS); connector = &intel_connector->base; drm_connector_init(dev, connector, &intel_hdmi_connector_funcs, DRM_MODE_CONNECTOR_HDMIA); drm_connector_helper_add(connector, &intel_hdmi_connector_helper_funcs); intel_encoder->type = INTEL_OUTPUT_HDMI; connector->polled = DRM_CONNECTOR_POLL_HPD; connector->interlace_allowed = 1; connector->doublescan_allowed = 0; intel_encoder->crtc_mask = (1 << 0) | (1 << 1) | (1 << 2); /* Set up the DDC bus. */ if (sdvox_reg == SDVOB) { intel_encoder->clone_mask = (1 << INTEL_HDMIB_CLONE_BIT); intel_hdmi->ddc_bus = GMBUS_PORT_DPB; dev_priv->hotplug_supported_mask |= HDMIB_HOTPLUG_INT_STATUS; } else if (sdvox_reg == SDVOC) { intel_encoder->clone_mask = (1 << INTEL_HDMIC_CLONE_BIT); intel_hdmi->ddc_bus = GMBUS_PORT_DPC; dev_priv->hotplug_supported_mask |= HDMIC_HOTPLUG_INT_STATUS; } else if (sdvox_reg == HDMIB) { intel_encoder->clone_mask = (1 << INTEL_HDMID_CLONE_BIT); intel_hdmi->ddc_bus = GMBUS_PORT_DPB; dev_priv->hotplug_supported_mask |= HDMIB_HOTPLUG_INT_STATUS; } else if (sdvox_reg == HDMIC) { intel_encoder->clone_mask = (1 << INTEL_HDMIE_CLONE_BIT); intel_hdmi->ddc_bus = GMBUS_PORT_DPC; dev_priv->hotplug_supported_mask |= HDMIC_HOTPLUG_INT_STATUS; } else if (sdvox_reg == HDMID) { intel_encoder->clone_mask = (1 << INTEL_HDMIF_CLONE_BIT); intel_hdmi->ddc_bus = GMBUS_PORT_DPD; dev_priv->hotplug_supported_mask |= HDMID_HOTPLUG_INT_STATUS; } else if (sdvox_reg == DDI_BUF_CTL(PORT_B)) { DRM_DEBUG_DRIVER("LPT: detected output on DDI B\n"); intel_encoder->clone_mask = (1 << INTEL_HDMIB_CLONE_BIT); intel_hdmi->ddc_bus = GMBUS_PORT_DPB; intel_hdmi->ddi_port = PORT_B; dev_priv->hotplug_supported_mask |= HDMIB_HOTPLUG_INT_STATUS; } else if (sdvox_reg == DDI_BUF_CTL(PORT_C)) { DRM_DEBUG_DRIVER("LPT: detected output on DDI C\n"); intel_encoder->clone_mask = (1 << INTEL_HDMIC_CLONE_BIT); intel_hdmi->ddc_bus = GMBUS_PORT_DPC; intel_hdmi->ddi_port = PORT_C; dev_priv->hotplug_supported_mask |= HDMIC_HOTPLUG_INT_STATUS; } else if (sdvox_reg == DDI_BUF_CTL(PORT_D)) { DRM_DEBUG_DRIVER("LPT: detected output on DDI D\n"); intel_encoder->clone_mask = (1 << INTEL_HDMID_CLONE_BIT); intel_hdmi->ddc_bus = GMBUS_PORT_DPD; intel_hdmi->ddi_port = PORT_D; dev_priv->hotplug_supported_mask |= HDMID_HOTPLUG_INT_STATUS; } else { /* If we got an unknown sdvox_reg, things are pretty much broken * in a way that we should let the kernel know about it */ BUG(); } intel_hdmi->sdvox_reg = sdvox_reg; if (!HAS_PCH_SPLIT(dev)) { intel_hdmi->write_infoframe = g4x_write_infoframe; I915_WRITE(VIDEO_DIP_CTL, 0); } else if (IS_VALLEYVIEW(dev)) { intel_hdmi->write_infoframe = vlv_write_infoframe; for_each_pipe(i) I915_WRITE(VLV_TVIDEO_DIP_CTL(i), 0); } else if (IS_HASWELL(dev)) { /* FIXME: Haswell has a new set of DIP frame registers, but we are * just doing the minimal required for HDMI to work at this stage. */ intel_hdmi->write_infoframe = hsw_write_infoframe; for_each_pipe(i) I915_WRITE(HSW_TVIDEO_DIP_CTL(i), 0); } else if (HAS_PCH_IBX(dev)) { intel_hdmi->write_infoframe = ibx_write_infoframe; for_each_pipe(i) I915_WRITE(TVIDEO_DIP_CTL(i), 0); } else { intel_hdmi->write_infoframe = cpt_write_infoframe; for_each_pipe(i) I915_WRITE(TVIDEO_DIP_CTL(i), 0); } if (IS_HASWELL(dev)) drm_encoder_helper_add(&intel_encoder->base, &intel_hdmi_helper_funcs_hsw); else drm_encoder_helper_add(&intel_encoder->base, &intel_hdmi_helper_funcs); intel_hdmi_add_properties(intel_hdmi, connector); intel_connector_attach_encoder(intel_connector, intel_encoder); drm_sysfs_connector_add(connector); /* For G4X desktop chip, PEG_BAND_GAP_DATA 3:0 must first be written * 0xd. Failure to do so will result in spurious interrupts being * generated on the port when a cable is not attached. */ if (IS_G4X(dev) && !IS_GM45(dev)) { u32 temp = I915_READ(PEG_BAND_GAP_DATA); I915_WRITE(PEG_BAND_GAP_DATA, (temp & ~0xf) | 0xd); } }