コード例 #1
0
ファイル: evdi_painter.c プロジェクト: DisplayLink/evdi
void evdi_painter_mode_changed_notify(struct evdi_device *evdi,
				      struct drm_framebuffer *fb,
				      struct drm_display_mode *new_mode)
{
	struct evdi_painter *painter = evdi->painter;

	if (evdi_painter_replace_mode(painter, new_mode)) {
		EVDI_DEBUG(
		"(dev=%d) Notifying mode changed: %dx%d@%d; bpp %d; ",
		     evdi->dev_index, new_mode->hdisplay, new_mode->vdisplay,
		     drm_mode_vrefresh(new_mode), fb->bits_per_pixel);
		EVDI_DEBUG("pixel format %d\n", fb->pixel_format);

		evdi_painter_send_mode_changed(painter,
					       fb->bits_per_pixel,
					       fb->pixel_format);
	} else {
		EVDI_WARN("(dev=%d) Change mode duplicated - ignoring\n",
			  evdi->dev_index);
	}
}
コード例 #2
0
ファイル: evdi_painter.c プロジェクト: DisplayLink/evdi
void evdi_painter_crtc_state_notify(struct evdi_device *evdi, int state)
{
	struct evdi_painter *painter = evdi->painter;

	if (painter) {
		EVDI_DEBUG("(dev=%d) Notifying crtc state: %d\n",
			   evdi->dev_index, state);
		evdi_painter_send_crtc_state(painter, state);
	} else {
		EVDI_WARN("Painter does not exist!");
	}
}
コード例 #3
0
ファイル: evdi_painter.c プロジェクト: DisplayLink/evdi
void evdi_painter_dpms_notify(struct evdi_device *evdi, int mode)
{
	struct evdi_painter *painter = evdi->painter;

	if (painter) {
		EVDI_DEBUG("(dev=%d) Notifying dpms mode: %d\n",
			   evdi->dev_index, mode);
		evdi_painter_send_dpms(painter, mode);
	} else {
		EVDI_WARN("Painter does not exist!");
	}
}
コード例 #4
0
ファイル: evdi_encoder.c プロジェクト: ajbogh/evdi
struct drm_encoder *evdi_encoder_init(struct drm_device *dev)
{
  struct drm_encoder *encoder;
  int status = 0;

  encoder = kzalloc(sizeof(struct drm_encoder), GFP_KERNEL);
  if (!encoder) {
    return NULL;
  }

  status = drm_encoder_init(dev, encoder, &evdi_enc_funcs, DRM_MODE_ENCODER_TMDS);
  EVDI_DEBUG("drm_encoder_init: %d\n", status);
  drm_encoder_helper_add(encoder, &evdi_helper_funcs);
  encoder->possible_crtcs = 1;
  return encoder;
}
コード例 #5
0
ファイル: evdi_painter.c プロジェクト: DisplayLink/evdi
void evdi_painter_disconnect(struct evdi_device *evdi, struct drm_file *file)
{
	struct evdi_painter *painter = evdi->painter;

	EVDI_CHECKPT();

	painter_lock(painter);

	if (file != painter->drm_filp) {
		EVDI_WARN
		    ("(dev=%d) An unknown connection to %p tries to close us",
		     evdi->dev_index, file);
		EVDI_WARN(" - ignoring\n");


		painter_unlock(painter);
		return;
	}

	if (painter->new_scanout_fb) {
		drm_framebuffer_unreference(&painter->new_scanout_fb->base);
		painter->new_scanout_fb = NULL;
	}

	if (painter->scanout_fb) {
		drm_framebuffer_unreference(&painter->scanout_fb->base);
		painter->scanout_fb = NULL;
	}

	painter->is_connected = false;

	EVDI_DEBUG("(dev=%d) Disconnected from %p\n", evdi->dev_index,
		   painter->drm_filp);
	painter->drm_filp = NULL;
	evdi->dev_index = -1;

	memset(&painter->current_mode, '\0', sizeof(struct drm_display_mode));
	painter->was_update_requested = false;

	painter_unlock(painter);

	drm_helper_hpd_irq_event(evdi->ddev);
}
コード例 #6
0
ファイル: evdi_painter.c プロジェクト: DisplayLink/evdi
u8 *evdi_painter_get_edid_copy(struct evdi_device *evdi)
{
	u8 *block = NULL;

	EVDI_CHECKPT();

	painter_lock(evdi->painter);
	if (evdi_painter_is_connected(evdi) &&
		evdi->painter->edid &&
		evdi->painter->edid_length) {
		block = kmalloc(evdi->painter->edid_length, GFP_KERNEL);
		if (block) {
			memcpy(block,
			       evdi->painter->edid,
			       evdi->painter->edid_length);
			EVDI_DEBUG("(dev=%d) %02x %02x %02x\n", evdi->dev_index,
				   block[0], block[1], block[2]);
		}
	}
	painter_unlock(evdi->painter);
	return block;
}
コード例 #7
0
ファイル: evdi_painter.c プロジェクト: DisplayLink/evdi
int
evdi_painter_connect(struct evdi_device *evdi,
		     void const __user *edid_data, unsigned int edid_length,
		     struct drm_file *file, int dev_index)
{
	struct evdi_painter *painter = evdi->painter;
	struct edid *new_edid = NULL;
	int expected_edid_size = 0;

	EVDI_CHECKPT();

	if (edid_length < sizeof(struct edid)) {
		EVDI_ERROR("Edid length too small\n");
		return -EINVAL;
	}

	if (edid_length > MAX_EDID_SIZE) {
		EVDI_ERROR("Edid length too large\n");
		return -EINVAL;
	}

	new_edid = kzalloc(edid_length, GFP_KERNEL);
	if (!new_edid)
		return -ENOMEM;

	if (copy_from_user(new_edid, edid_data, edid_length)) {
		EVDI_ERROR("(dev=%d) LSP Failed to read edid\n", dev_index);
		kfree(new_edid);
		return -EFAULT;
	}

	expected_edid_size = sizeof(struct edid) +
			     new_edid->extensions * EDID_EXT_BLOCK_SIZE;
	if (expected_edid_size != edid_length) {
		EVDI_ERROR("Wrong edid size. Expected %d but is %d\n",
			   expected_edid_size, edid_length);
		kfree(new_edid);
		return -EINVAL;
	}

	if (painter->drm_filp)
		EVDI_WARN("(dev=%d) Double connect - replacing %p with %p\n",
			  dev_index, painter->drm_filp, file);

	EVDI_DEBUG("(dev=%d) Connected with %p\n", evdi->dev_index,
		   painter->drm_filp);

	painter_lock(painter);

	evdi->dev_index = dev_index;
	painter->drm_filp = file;
	kfree(painter->edid);
	painter->edid_length = edid_length;
	painter->edid = new_edid;
	painter->is_connected = true;

	painter_unlock(painter);

	drm_helper_hpd_irq_event(evdi->ddev);
	drm_helper_resume_force_mode(evdi->ddev);

	return 0;
}