int pl111_crtc_helper_mode_set(struct drm_crtc *crtc,
				struct drm_display_mode *mode,
				struct drm_display_mode *adjusted_mode,
				int x, int y, struct drm_framebuffer *old_fb)
{
	int ret;
	struct pl111_drm_crtc *pl111_crtc = to_pl111_crtc(crtc);
	struct drm_display_mode *duplicated_mode;

	DRM_DEBUG_KMS("DRM crtc_helper_mode_set, x=%d y=%d bpp=%d\n",
			adjusted_mode->hdisplay, adjusted_mode->vdisplay,
			crtc->fb->bits_per_pixel);

	duplicated_mode = drm_mode_duplicate(crtc->dev, adjusted_mode);
	if (!duplicated_mode)
		return -ENOMEM;

	pl111_crtc->new_mode = duplicated_mode;
	ret = show_framebuffer_on_crtc(crtc, crtc->fb, false, NULL);
	if (ret != 0) {
		pl111_crtc->new_mode = pl111_crtc->current_mode;
		drm_mode_destroy(crtc->dev, duplicated_mode);
	}

	return ret;
}
Пример #2
0
static int omap_connector_mode_valid(struct drm_connector *connector,
				 struct drm_display_mode *mode)
{
	struct omap_connector *omap_connector = to_omap_connector(connector);
	struct omap_dss_device *dssdev = omap_connector->dssdev;
	struct omap_dss_driver *dssdrv = dssdev->driver;
	struct omap_video_timings timings = {0};
	struct drm_device *dev = connector->dev;
	struct drm_display_mode *new_mode;
	int ret = MODE_BAD;

	copy_timings_drm_to_omap(&timings, mode);
	mode->vrefresh = drm_mode_vrefresh(mode);

	if (!dssdrv->check_timings(dssdev, &timings)) {
		/* check if vrefresh is still valid */
		new_mode = drm_mode_duplicate(dev, mode);
		new_mode->clock = timings.pixel_clock;
		new_mode->vrefresh = 0;
		if (mode->vrefresh == drm_mode_vrefresh(new_mode))
			ret = MODE_OK;
		drm_mode_destroy(dev, new_mode);
	}

	DBG("connector: mode %s: "
			"%d:\"%s\" %d %d %d %d %d %d %d %d %d %d 0x%x 0x%x",
			(ret == MODE_OK) ? "valid" : "invalid",
			mode->base.id, mode->name, mode->vrefresh, mode->clock,
			mode->hdisplay, mode->hsync_start,
			mode->hsync_end, mode->htotal,
			mode->vdisplay, mode->vsync_start,
			mode->vsync_end, mode->vtotal, mode->type, mode->flags);

	return ret;
}
static int intel_dsi_get_modes(struct drm_connector *connector)
{
	struct intel_connector *intel_connector = to_intel_connector(connector);
	struct intel_dsi *intel_dsi = intel_attached_dsi(connector);
	struct drm_display_mode *mode;
	struct drm_display_mode *input_mode = NULL;
	DRM_DEBUG_KMS("\n");

	if (!intel_connector->panel.fixed_mode) {
		DRM_DEBUG_KMS("no fixed mode\n");
		return 0;
	}

	input_mode = intel_connector->panel.fixed_mode;
	mode = drm_mode_duplicate(connector->dev,
				  input_mode);
	if (!mode) {
		DRM_DEBUG_KMS("drm_mode_duplicate failed\n");
		return 0;
	}

	drm_mode_probed_add(connector, mode);
	/*Fill the panel info here*/
	intel_dsi->dev.dev_ops->get_info(0, connector);
	return 1;
}
void
intel_dsi_set_drrs_state(struct intel_encoder *intel_encoder)
{
	struct drm_i915_private *dev_priv =
				intel_encoder->base.dev->dev_private;
	struct drm_display_mode *target_mode =
				dev_priv->drrs.connector->panel.target_mode;
	struct intel_mipi_drrs_work *work = dev_priv->drrs.mipi_drrs_work;
	unsigned int ret;

	ret = work_busy(&work->work.work);
	if (ret) {
		if (work->target_mode)
			if (work->target_mode->vrefresh ==
						target_mode->vrefresh) {
				DRM_DEBUG_KMS("Repeated request for %dHz\n",
							target_mode->vrefresh);
				return;
			}
		DRM_DEBUG_KMS("Cancelling an queued/executing work\n");
		atomic_set(&work->abort_wait_loop, 1);
		cancel_delayed_work_sync(&work->work);
		atomic_set(&work->abort_wait_loop, 0);
		if (ret & WORK_BUSY_PENDING)
			drm_mode_destroy(intel_encoder->base.dev,
							work->target_mode);

	}
	work->intel_encoder = intel_encoder;
	work->target_rr_type = dev_priv->drrs_state.target_rr_type;
	work->target_mode = drm_mode_duplicate(intel_encoder->base.dev,
								target_mode);

	schedule_delayed_work(&dev_priv->drrs.mipi_drrs_work->work, 0);
}
Пример #5
0
static int meson_connector_get_modes(struct drm_connector *connector)
{
	struct meson_connector *meson_connector = to_meson_connector(connector);
	struct drm_device *dev = connector->dev;
	drm_mode_probed_add(connector, drm_mode_duplicate(dev, meson_connector->mode));
	return 1;
}
Пример #6
0
static int omap_connector_mode_valid(struct drm_connector *connector,
				 struct drm_display_mode *mode)
{
	struct omap_connector *omap_connector = to_omap_connector(connector);
	struct omap_dss_device *dssdev = omap_connector->dssdev;
	struct omap_dss_driver *dssdrv = dssdev->driver;
	struct videomode vm = {0};
	struct drm_device *dev = connector->dev;
	struct drm_display_mode *new_mode;
	int r, ret = MODE_BAD;

	drm_display_mode_to_videomode(mode, &vm);
	vm.flags |= DISPLAY_FLAGS_DE_HIGH | DISPLAY_FLAGS_PIXDATA_POSEDGE |
		    DISPLAY_FLAGS_SYNC_NEGEDGE;
	mode->vrefresh = drm_mode_vrefresh(mode);

	/*
	 * if the panel driver doesn't have a check_timings, it's most likely
	 * a fixed resolution panel, check if the timings match with the
	 * panel's timings
	 */
	if (dssdrv->check_timings) {
		r = dssdrv->check_timings(dssdev, &vm);
	} else {
		struct videomode t = {0};

		dssdrv->get_timings(dssdev, &t);

		if (memcmp(&vm, &t, sizeof(struct videomode)))
			r = -EINVAL;
		else
			r = 0;
	}

	if (!r) {
		/* check if vrefresh is still valid */
		new_mode = drm_mode_duplicate(dev, mode);
		new_mode->clock = vm.pixelclock / 1000;
		new_mode->vrefresh = 0;
		if (mode->vrefresh == drm_mode_vrefresh(new_mode))
			ret = MODE_OK;
		drm_mode_destroy(dev, new_mode);
	}

	DBG("connector: mode %s: "
			"%d:\"%s\" %d %d %d %d %d %d %d %d %d %d 0x%x 0x%x",
			(ret == MODE_OK) ? "valid" : "invalid",
			mode->base.id, mode->name, mode->vrefresh, mode->clock,
			mode->hdisplay, mode->hsync_start,
			mode->hsync_end, mode->htotal,
			mode->vdisplay, mode->vsync_start,
			mode->vsync_end, mode->vtotal, mode->type, mode->flags);

	return ret;
}
Пример #7
0
/**
 * add_established_modes - get est. modes from EDID and add them
 * @edid: EDID block to scan
 *
 * Each EDID block contains a bitmap of the supported "established modes" list
 * (defined above).  Tease them out and add them to the global modes list.
 */
static int add_established_modes(struct drm_output *output, struct edid *edid)
{
	struct drm_device *dev = output->dev;
	unsigned long est_bits = edid->established_timings.t1 |
		(edid->established_timings.t2 << 8) |
		((edid->established_timings.mfg_rsvd & 0x80) << 9);
	int i, modes = 0;

	for (i = 0; i <= EDID_EST_TIMINGS; i++)
		if (est_bits & (1<<i)) {
			struct drm_display_mode *newmode;
			newmode = drm_mode_duplicate(dev, &edid_est_modes[i]);
			drm_mode_probed_add(output, newmode);
			modes++;
		}

	return modes;
}
static int ch7006_encoder_get_modes(struct drm_encoder *encoder,
				    struct drm_connector *connector)
{
	struct ch7006_priv *priv = to_ch7006_priv(encoder);
	struct ch7006_mode *mode;
	int n = 0;

	for (mode = ch7006_modes; mode->mode.clock; mode++) {
		if (~mode->valid_scales & 1<<priv->scale ||
		    ~mode->valid_norms & 1<<priv->norm)
			continue;

		drm_mode_probed_add(connector,
				drm_mode_duplicate(encoder->dev, &mode->mode));

		n++;
	}

	return n;
}
Пример #9
0
static int intel_dsi_get_modes(struct drm_connector *connector)
{
	struct intel_connector *intel_connector = to_intel_connector(connector);
	struct drm_display_mode *mode;

	DRM_DEBUG_KMS("\n");

	if (!intel_connector->panel.fixed_mode) {
		DRM_DEBUG_KMS("no fixed mode\n");
		return 0;
	}

	mode = drm_mode_duplicate(connector->dev,
				  intel_connector->panel.fixed_mode);
	if (!mode) {
		DRM_DEBUG_KMS("drm_mode_duplicate failed\n");
		return 0;
	}

	drm_mode_probed_add(connector, mode);
	return 1;
}
Пример #10
0
static int s6e3ha2_get_modes(struct drm_panel *panel)
{
	struct drm_connector *connector = panel->connector;
	struct s6e3ha2 *ctx = container_of(panel, struct s6e3ha2, panel);
	struct drm_display_mode *mode;

	mode = drm_mode_duplicate(panel->drm, ctx->desc->mode);
	if (!mode) {
		DRM_ERROR("failed to add mode %ux%ux@%u\n",
			ctx->desc->mode->hdisplay, ctx->desc->mode->vdisplay,
			ctx->desc->mode->vrefresh);
		return -ENOMEM;
	}

	drm_mode_set_name(mode);

	mode->type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED;
	drm_mode_probed_add(connector, mode);

	connector->display_info.width_mm = 71;
	connector->display_info.height_mm = 125;

	return 1;
}
static void intel_mipi_drrs_work_fn(struct work_struct *__work)
{
	struct intel_mipi_drrs_work *work =
		container_of(to_delayed_work(__work),
			struct intel_mipi_drrs_work, work);
	struct intel_encoder *intel_encoder = work->intel_encoder;
	struct drm_i915_private *dev_priv =
				intel_encoder->base.dev->dev_private;
	struct intel_dsi_mnp *intel_dsi_mnp;
	struct intel_dsi *intel_dsi = NULL;
	struct intel_crtc *intel_crtc = NULL;
	struct drm_display_mode *prev_mode = NULL;
	bool resume_idleness_detection = false, fallback_attempt = false;
	int ret, retry_cnt = 3;

	intel_dsi = enc_to_intel_dsi(&intel_encoder->base);
	intel_crtc = intel_encoder->new_crtc;

init:
	if (work->target_rr_type == DRRS_HIGH_RR) {
		intel_dsi_mnp = &intel_crtc->config.dsi_mnp;
	} else if (work->target_rr_type == DRRS_LOW_RR) {
		intel_dsi_mnp = &intel_crtc->config.dsi_mnp2;
	} else if (work->target_rr_type == DRRS_MEDIA_RR) {
		if (intel_calculate_dsi_pll_mnp(intel_dsi,
				work->target_mode,
				&intel_crtc->config.dsi_mnp3, 0) < 0)
			return;
		intel_dsi_mnp = &intel_crtc->config.dsi_mnp3;
	} else {
		DRM_ERROR("Unknown refreshrate_type\n");
		return;
	}

	if (dev_priv->drrs_state.refresh_rate_type == DRRS_MEDIA_RR &&
			work->target_rr_type == DRRS_HIGH_RR)
		resume_idleness_detection = true;

retry:
	ret = intel_drrs_configure_dsi_pll(intel_dsi, intel_dsi_mnp);
	if (ret == 0) {
		DRM_DEBUG_KMS("cur_rr_type: %d, cur_rr: %d, target_rr_type: %d, target_rr: %d\n",
				dev_priv->drrs_state.refresh_rate_type,
				intel_crtc->base.mode.vrefresh,
				work->target_rr_type, work->target_mode->vrefresh);

		mutex_lock(&dev_priv->drrs_state.mutex);
		dev_priv->drrs_state.refresh_rate_type =
						work->target_rr_type;
		mutex_unlock(&dev_priv->drrs_state.mutex);

		DRM_INFO("Refresh Rate set to : %dHz\n",
						work->target_mode->vrefresh);

		intel_crtc->base.mode.vrefresh = work->target_mode->vrefresh;
		intel_crtc->base.mode.clock = work->target_mode->clock;

		if (resume_idleness_detection)
			intel_update_drrs(intel_encoder->base.dev);
	} else if (ret == -ETIMEDOUT && retry_cnt) {
		retry_cnt--;
		DRM_DEBUG_KMS("Retry left ... <%d>\n", retry_cnt);
		goto retry;
	} else if (ret == -EACCES && !fallback_attempt) {
		DRM_ERROR("Falling back to the previous DRRS state. %d->%d\n",
				work->target_rr_type,
				dev_priv->drrs_state.refresh_rate_type);

		mutex_lock(&dev_priv->drrs_state.mutex);
		dev_priv->drrs_state.target_rr_type =
					dev_priv->drrs_state.refresh_rate_type;
		mutex_unlock(&dev_priv->drrs_state.mutex);

		work->target_rr_type = dev_priv->drrs_state.target_rr_type;
		drm_mode_destroy(intel_encoder->base.dev, work->target_mode);

		if (work->target_rr_type == DRRS_HIGH_RR) {
			prev_mode =
				dev_priv->drrs.connector->panel.fixed_mode;
			resume_idleness_detection = true;
		} else if (work->target_rr_type == DRRS_LOW_RR) {
			prev_mode =
				dev_priv->drrs.connector->panel.downclock_mode;
		} else if (work->target_rr_type == DRRS_MEDIA_RR) {
			prev_mode =
				dev_priv->drrs.connector->panel.target_mode;
		}

		work->target_mode = drm_mode_duplicate(intel_encoder->base.dev,
								prev_mode);
		if (!work->target_mode) {
			DRM_ERROR("target mode creation failed\n");
			return;
		}
		fallback_attempt = true;
		goto init;
	} else {
		if (fallback_attempt)
			DRM_ERROR("DRRS State Fallback attempt failed\n");
		if (ret == -ETIMEDOUT)
			DRM_ERROR("TIMEDOUT in all retry attempt\n");
	}

	drm_mode_destroy(intel_encoder->base.dev, work->target_mode);
}