Beispiel #1
0
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;
}