static void mrst_lvds_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode, struct drm_display_mode *adjusted_mode) { struct psb_intel_mode_device *mode_dev = enc_to_psb_intel_output(encoder)->mode_dev; struct drm_device *dev = encoder->dev; struct drm_psb_private *dev_priv = dev->dev_private; u32 lvds_port; uint64_t v = DRM_MODE_SCALE_FULLSCREEN; if (!gma_power_begin(dev, true)) return; /* * The LVDS pin pair will already have been turned on in the * psb_intel_crtc_mode_set since it has a large impact on the DPLL * settings. */ lvds_port = (REG_READ(LVDS) & (~LVDS_PIPEB_SELECT)) | LVDS_PORT_EN | LVDS_BORDER_EN; /* If the firmware says dither on Moorestown, or the BIOS does on Oaktrail then enable dithering */ if (mode_dev->panel_wants_dither || dev_priv->lvds_dither) lvds_port |= MRST_PANEL_8TO6_DITHER_ENABLE; REG_WRITE(LVDS, lvds_port); drm_connector_property_get_value( &enc_to_psb_intel_output(encoder)->base, dev->mode_config.scaling_mode_property, &v); if (v == DRM_MODE_SCALE_NO_SCALE) REG_WRITE(PFIT_CONTROL, 0); else if (v == DRM_MODE_SCALE_ASPECT) { if ((mode->vdisplay != adjusted_mode->crtc_vdisplay) || (mode->hdisplay != adjusted_mode->crtc_hdisplay)) { if ((adjusted_mode->crtc_hdisplay * mode->vdisplay) == (mode->hdisplay * adjusted_mode->crtc_vdisplay)) REG_WRITE(PFIT_CONTROL, PFIT_ENABLE); else if ((adjusted_mode->crtc_hdisplay * mode->vdisplay) > (mode->hdisplay * adjusted_mode->crtc_vdisplay)) REG_WRITE(PFIT_CONTROL, PFIT_ENABLE | PFIT_SCALING_MODE_PILLARBOX); else REG_WRITE(PFIT_CONTROL, PFIT_ENABLE | PFIT_SCALING_MODE_LETTERBOX); } else REG_WRITE(PFIT_CONTROL, PFIT_ENABLE); } else /*(v == DRM_MODE_SCALE_FULLSCREEN)*/ REG_WRITE(PFIT_CONTROL, PFIT_ENABLE); gma_power_end(dev); }
static int cdv_hdmi_set_property(struct drm_connector *connector, struct drm_property *property, uint64_t value) { struct drm_encoder *encoder = connector->encoder; if (!strcmp(property->name, "scaling mode") && encoder) { struct psb_intel_crtc *crtc = to_psb_intel_crtc(encoder->crtc); bool centre; uint64_t curValue; if (!crtc) return -1; switch (value) { case DRM_MODE_SCALE_FULLSCREEN: break; case DRM_MODE_SCALE_NO_SCALE: break; case DRM_MODE_SCALE_ASPECT: break; default: return -1; } if (drm_connector_property_get_value(connector, property, &curValue)) return -1; if (curValue == value) return 0; if (drm_connector_property_set_value(connector, property, value)) return -1; centre = (curValue == DRM_MODE_SCALE_NO_SCALE) || (value == DRM_MODE_SCALE_NO_SCALE); if (crtc->saved_mode.hdisplay != 0 && crtc->saved_mode.vdisplay != 0) { if (centre) { if (!drm_crtc_helper_set_mode(encoder->crtc, &crtc->saved_mode, encoder->crtc->x, encoder->crtc->y, encoder->crtc->fb)) return -1; } else { struct drm_encoder_helper_funcs *helpers = encoder->helper_private; helpers->mode_set(encoder, &crtc->saved_mode, &crtc->saved_adjusted_mode); } } } return 0; }