Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 866f0956 authored by Tomi Valkeinen's avatar Tomi Valkeinen
Browse files

Merge branch 'archit/outputs-for-3.7'

Merge omapdss output work, that creates a new entity "output" to represent the
outputs (DPI, DSI, HDMI, ...) from DSS. An output sits in between an overlay
manager and a panel, and helps us to remove references to panel devices from
the omapdss core.

* archit/outputs-for-3.7: (23 commits)
  OMAPDSS: Remove old way of setting manager and device links
  OMAPDSS: APPLY: Remove omap_dss_device references from dss_ovl_enable/disable
  OMAPDSS: OVERLAY/MANAGER: Get device via output
  OMAPDSS: MANAGER: Update display sysfs store
  OMAPFB: Change dssdev->manager references
  OMAPDSS: HDMI: Replace dssdev->manager with dssdev->output->manager references
  OMAPDSS: VENC: Replace dssdev->manager with dssdev->output->manager references
  OMAPDSS: RFBI: Replace dssdev->manager with dssdev->output->manager references
  OMAPDSS: SDI: Replace dssdev->manager with dssdev->output->manager references
  OMAPDSS: DSI: Replace dssdev->manager with dssdev->output->manager references
  OMAPDSS: DSI: Remove dsi_pdev_map global struct
  OMAPDSS: DPI: Replace dssdev->manager with dssdev->output->manager references
  OMAPDSS: Create links between managers, outputs and devices
  OMAPDRM: Remove manager->device references
  OMAPFB: remove manager->device references
  OMAP_VOUT: Remove manager->device references
  OMAPDSS: Remove manager->device references
  OMAPDSS: APPLY: Add manager set/unset output ops for omap_overlay_manager
  OMAPDSS: output: Add set/unset device ops for omap_dss_output
  OMAPDSS: outputs: Create and register output instances
  ...
parents e84dc1cc 3c2995ac
Loading
Loading
Loading
Loading
+50 −25
Original line number Diff line number Diff line
@@ -454,11 +454,15 @@ static int omapvid_init(struct omap_vout_device *vout, u32 addr)

	win = &vout->win;
	for (i = 0; i < ovid->num_overlays; i++) {
		struct omap_dss_device *dssdev;

		ovl = ovid->overlays[i];
		if (!ovl->manager || !ovl->manager->device)
		dssdev = ovl->get_device(ovl);

		if (!dssdev)
			return -EINVAL;

		timing = &ovl->manager->device->panel.timings;
		timing = &dssdev->panel.timings;

		outw = win->w.width;
		outh = win->w.height;
@@ -515,8 +519,11 @@ static int omapvid_apply_changes(struct omap_vout_device *vout)
	struct omapvideo_info *ovid = &vout->vid_info;

	for (i = 0; i < ovid->num_overlays; i++) {
		struct omap_dss_device *dssdev;

		ovl = ovid->overlays[i];
		if (!ovl->manager || !ovl->manager->device)
		dssdev = ovl->get_device(ovl);
		if (!dssdev)
			return -EINVAL;
		ovl->manager->apply(ovl->manager);
	}
@@ -579,12 +586,14 @@ static void omap_vout_isr(void *arg, unsigned int irqstatus)

	ovid = &vout->vid_info;
	ovl = ovid->overlays[0];
	/* get the display device attached to the overlay */
	if (!ovl->manager || !ovl->manager->device)
		return;

	mgr_id = ovl->manager->id;
	cur_display = ovl->manager->device;

	/* get the display device attached to the overlay */
	cur_display = ovl->get_device(ovl);

	if (!cur_display)
		return;

	spin_lock(&vout->vbq_lock);
	do_gettimeofday(&timevalue);
@@ -948,7 +957,9 @@ static int omap_vout_release(struct file *file)
	/* Disable all the overlay managers connected with this interface */
	for (i = 0; i < ovid->num_overlays; i++) {
		struct omap_overlay *ovl = ovid->overlays[i];
		if (ovl->manager && ovl->manager->device)
		struct omap_dss_device *dssdev = ovl->get_device(ovl);

		if (dssdev)
			ovl->disable(ovl);
	}
	/* Turn off the pipeline */
@@ -1081,14 +1092,17 @@ static int vidioc_try_fmt_vid_out(struct file *file, void *fh,
	struct omapvideo_info *ovid;
	struct omap_video_timings *timing;
	struct omap_vout_device *vout = fh;
	struct omap_dss_device *dssdev;

	ovid = &vout->vid_info;
	ovl = ovid->overlays[0];
	/* get the display device attached to the overlay */
	dssdev = ovl->get_device(ovl);

	if (!ovl->manager || !ovl->manager->device)
	if (!dssdev)
		return -EINVAL;
	/* get the display device attached to the overlay */
	timing = &ovl->manager->device->panel.timings;

	timing = &dssdev->panel.timings;

	vout->fbuf.fmt.height = timing->y_res;
	vout->fbuf.fmt.width = timing->x_res;
@@ -1105,6 +1119,7 @@ static int vidioc_s_fmt_vid_out(struct file *file, void *fh,
	struct omapvideo_info *ovid;
	struct omap_video_timings *timing;
	struct omap_vout_device *vout = fh;
	struct omap_dss_device *dssdev;

	if (vout->streaming)
		return -EBUSY;
@@ -1113,13 +1128,14 @@ static int vidioc_s_fmt_vid_out(struct file *file, void *fh,

	ovid = &vout->vid_info;
	ovl = ovid->overlays[0];
	dssdev = ovl->get_device(ovl);

	/* get the display device attached to the overlay */
	if (!ovl->manager || !ovl->manager->device) {
	if (!dssdev) {
		ret = -EINVAL;
		goto s_fmt_vid_out_exit;
	}
	timing = &ovl->manager->device->panel.timings;
	timing = &dssdev->panel.timings;

	/* We dont support RGB24-packed mode if vrfb rotation
	 * is enabled*/
@@ -1298,6 +1314,7 @@ static int vidioc_s_crop(struct file *file, void *fh, struct v4l2_crop *crop)
	struct omapvideo_info *ovid;
	struct omap_overlay *ovl;
	struct omap_video_timings *timing;
	struct omap_dss_device *dssdev;

	if (vout->streaming)
		return -EBUSY;
@@ -1305,13 +1322,15 @@ static int vidioc_s_crop(struct file *file, void *fh, struct v4l2_crop *crop)
	mutex_lock(&vout->lock);
	ovid = &vout->vid_info;
	ovl = ovid->overlays[0];
	/* get the display device attached to the overlay */
	dssdev = ovl->get_device(ovl);

	if (!ovl->manager || !ovl->manager->device) {
	if (!dssdev) {
		ret = -EINVAL;
		goto s_crop_err;
	}
	/* get the display device attached to the overlay */
	timing = &ovl->manager->device->panel.timings;

	timing = &dssdev->panel.timings;

	if (is_rotation_90_or_270(vout)) {
		vout->fbuf.fmt.height = timing->x_res;
@@ -1667,7 +1686,7 @@ static int vidioc_streamon(struct file *file, void *fh, enum v4l2_buf_type i)
	for (j = 0; j < ovid->num_overlays; j++) {
		struct omap_overlay *ovl = ovid->overlays[j];

		if (ovl->manager && ovl->manager->device) {
		if (ovl->get_device(ovl)) {
			struct omap_overlay_info info;
			ovl->get_overlay_info(ovl, &info);
			info.paddr = addr;
@@ -1690,8 +1709,9 @@ static int vidioc_streamon(struct file *file, void *fh, enum v4l2_buf_type i)

	for (j = 0; j < ovid->num_overlays; j++) {
		struct omap_overlay *ovl = ovid->overlays[j];
		struct omap_dss_device *dssdev = ovl->get_device(ovl);

		if (ovl->manager && ovl->manager->device) {
		if (dssdev) {
			ret = ovl->enable(ovl);
			if (ret)
				goto streamon_err1;
@@ -1726,8 +1746,9 @@ static int vidioc_streamoff(struct file *file, void *fh, enum v4l2_buf_type i)

	for (j = 0; j < ovid->num_overlays; j++) {
		struct omap_overlay *ovl = ovid->overlays[j];
		struct omap_dss_device *dssdev = ovl->get_device(ovl);

		if (ovl->manager && ovl->manager->device)
		if (dssdev)
			ovl->disable(ovl);
	}

@@ -1890,8 +1911,8 @@ static int __init omap_vout_setup_video_data(struct omap_vout_device *vout)
	struct video_device *vfd;
	struct v4l2_pix_format *pix;
	struct v4l2_control *control;
	struct omap_dss_device *display =
		vout->vid_info.overlays[0]->manager->device;
	struct omap_overlay *ovl = vout->vid_info.overlays[0];
	struct omap_dss_device *display = ovl->get_device(ovl);

	/* set the default pix */
	pix = &vout->pix;
@@ -2205,8 +2226,10 @@ static int __init omap_vout_probe(struct platform_device *pdev)
	 */
	for (i = 1; i < vid_dev->num_overlays; i++) {
		ovl = omap_dss_get_overlay(i);
		if (ovl->manager && ovl->manager->device) {
			def_display = ovl->manager->device;
		dssdev = ovl->get_device(ovl);

		if (dssdev) {
			def_display = dssdev;
		} else {
			dev_warn(&pdev->dev, "cannot find display\n");
			def_display = NULL;
@@ -2253,8 +2276,10 @@ static int __init omap_vout_probe(struct platform_device *pdev)
	for (i = 1; i < vid_dev->num_overlays; i++) {
		def_display = NULL;
		ovl = omap_dss_get_overlay(i);
		if (ovl->manager && ovl->manager->device)
			def_display = ovl->manager->device;
		dssdev = ovl->get_device(ovl);

		if (dssdev)
			def_display = dssdev;

		if (def_display && def_display->driver)
			def_display->driver->disable(def_display);
+3 −2
Original line number Diff line number Diff line
@@ -106,7 +106,8 @@ static void dump_video_chains(void)
	for (i = 0; i < omap_dss_get_num_overlays(); i++) {
		struct omap_overlay *ovl = omap_dss_get_overlay(i);
		struct omap_overlay_manager *mgr = ovl->manager;
		struct omap_dss_device *dssdev = mgr ? mgr->device : NULL;
		struct omap_dss_device *dssdev = mgr ?
					mgr->get_device(mgr) : NULL;
		if (dssdev) {
			DBG("%d: %s -> %s -> %s", i, ovl->name, mgr->name,
						dssdev->name);
@@ -185,7 +186,7 @@ static int create_connector(struct drm_device *dev,
	for (j = 0; j < priv->num_encoders; j++) {
		struct omap_overlay_manager *mgr =
			omap_encoder_get_manager(priv->encoders[j]);
		if (mgr->device == dssdev) {
		if (mgr->get_device(mgr) == dssdev) {
			drm_mode_connector_attach_encoder(connector,
					priv->encoders[j]);
		}
+1 −1
Original line number Diff line number Diff line
obj-$(CONFIG_OMAP2_DSS) += omapdss.o
omapdss-y := core.o dss.o dss_features.o dispc.o dispc_coefs.o display.o \
	manager.o manager-sysfs.o overlay.o overlay-sysfs.o apply.o
	manager.o manager-sysfs.o overlay.o overlay-sysfs.o output.o apply.o
omapdss-$(CONFIG_OMAP2_DSS_DPI) += dpi.o
omapdss-$(CONFIG_OMAP2_DSS_RFBI) += rfbi.o
omapdss-$(CONFIG_OMAP2_DSS_VENC) += venc.o venc_panel.o
+54 −34
Original line number Diff line number Diff line
@@ -421,17 +421,25 @@ static void wait_pending_extra_info_updates(void)
int dss_mgr_wait_for_go(struct omap_overlay_manager *mgr)
{
	unsigned long timeout = msecs_to_jiffies(500);
	struct mgr_priv_data *mp;
	struct mgr_priv_data *mp = get_mgr_priv(mgr);
	u32 irq;
	unsigned long flags;
	int r;
	int i;
	struct omap_dss_device *dssdev = mgr->device;

	if (!dssdev || dssdev->state != OMAP_DSS_DISPLAY_ACTIVE)
	spin_lock_irqsave(&data_lock, flags);

	if (mgr_manual_update(mgr)) {
		spin_unlock_irqrestore(&data_lock, flags);
		return 0;
	}

	if (mgr_manual_update(mgr))
	if (!mp->enabled) {
		spin_unlock_irqrestore(&data_lock, flags);
		return 0;
	}

	spin_unlock_irqrestore(&data_lock, flags);

	r = dispc_runtime_get();
	if (r)
@@ -439,10 +447,8 @@ int dss_mgr_wait_for_go(struct omap_overlay_manager *mgr)

	irq = dispc_mgr_get_vsync_irq(mgr->id);

	mp = get_mgr_priv(mgr);
	i = 0;
	while (1) {
		unsigned long flags;
		bool shadow_dirty, dirty;

		spin_lock_irqsave(&data_lock, flags);
@@ -486,21 +492,30 @@ int dss_mgr_wait_for_go_ovl(struct omap_overlay *ovl)
{
	unsigned long timeout = msecs_to_jiffies(500);
	struct ovl_priv_data *op;
	struct omap_dss_device *dssdev;
	struct mgr_priv_data *mp;
	u32 irq;
	unsigned long flags;
	int r;
	int i;

	if (!ovl->manager)
		return 0;

	dssdev = ovl->manager->device;
	mp = get_mgr_priv(ovl->manager);

	spin_lock_irqsave(&data_lock, flags);

	if (!dssdev || dssdev->state != OMAP_DSS_DISPLAY_ACTIVE)
	if (ovl_manual_update(ovl)) {
		spin_unlock_irqrestore(&data_lock, flags);
		return 0;
	}

	if (ovl_manual_update(ovl))
	if (!mp->enabled) {
		spin_unlock_irqrestore(&data_lock, flags);
		return 0;
	}

	spin_unlock_irqrestore(&data_lock, flags);

	r = dispc_runtime_get();
	if (r)
@@ -511,7 +526,6 @@ int dss_mgr_wait_for_go_ovl(struct omap_overlay *ovl)
	op = get_ovl_priv(ovl);
	i = 0;
	while (1) {
		unsigned long flags;
		bool shadow_dirty, dirty;

		spin_lock_irqsave(&data_lock, flags);
@@ -1096,29 +1110,29 @@ void dss_mgr_get_info(struct omap_overlay_manager *mgr,
	spin_unlock_irqrestore(&data_lock, flags);
}

int dss_mgr_set_device(struct omap_overlay_manager *mgr,
		struct omap_dss_device *dssdev)
int dss_mgr_set_output(struct omap_overlay_manager *mgr,
		struct omap_dss_output *output)
{
	int r;

	mutex_lock(&apply_lock);

	if (dssdev->manager) {
		DSSERR("display '%s' already has a manager '%s'\n",
			       dssdev->name, dssdev->manager->name);
	if (mgr->output) {
		DSSERR("manager %s is already connected to an output\n",
			mgr->name);
		r = -EINVAL;
		goto err;
	}

	if ((mgr->supported_displays & dssdev->type) == 0) {
		DSSERR("display '%s' does not support manager '%s'\n",
			       dssdev->name, mgr->name);
	if ((mgr->supported_outputs & output->id) == 0) {
		DSSERR("output does not support manager %s\n",
			mgr->name);
		r = -EINVAL;
		goto err;
	}

	dssdev->manager = mgr;
	mgr->device = dssdev;
	output->manager = mgr;
	mgr->output = output;

	mutex_unlock(&apply_lock);

@@ -1128,35 +1142,41 @@ int dss_mgr_set_device(struct omap_overlay_manager *mgr,
	return r;
}

int dss_mgr_unset_device(struct omap_overlay_manager *mgr)
int dss_mgr_unset_output(struct omap_overlay_manager *mgr)
{
	int r;
	struct mgr_priv_data *mp = get_mgr_priv(mgr);
	unsigned long flags;

	mutex_lock(&apply_lock);

	if (!mgr->device) {
		DSSERR("failed to unset display, display not set.\n");
	if (!mgr->output) {
		DSSERR("failed to unset output, output not set\n");
		r = -EINVAL;
		goto err;
	}

	/*
	 * Don't allow currently enabled displays to have the overlay manager
	 * pulled out from underneath them
	 */
	if (mgr->device->state != OMAP_DSS_DISPLAY_DISABLED) {
	spin_lock_irqsave(&data_lock, flags);

	if (mp->enabled) {
		DSSERR("output can't be unset when manager is enabled\n");
		r = -EINVAL;
		goto err;
		goto err1;
	}

	mgr->device->manager = NULL;
	mgr->device = NULL;
	spin_unlock_irqrestore(&data_lock, flags);

	mgr->output->manager = NULL;
	mgr->output = NULL;

	mutex_unlock(&apply_lock);

	return 0;
err1:
	spin_unlock_irqrestore(&data_lock, flags);
err:
	mutex_unlock(&apply_lock);

	return r;
}

@@ -1380,7 +1400,7 @@ int dss_ovl_enable(struct omap_overlay *ovl)
		goto err1;
	}

	if (ovl->manager == NULL || ovl->manager->device == NULL) {
	if (ovl->manager == NULL || ovl->manager->output == NULL) {
		r = -EINVAL;
		goto err1;
	}
@@ -1430,7 +1450,7 @@ int dss_ovl_disable(struct omap_overlay *ovl)
		goto err;
	}

	if (ovl->manager == NULL || ovl->manager->device == NULL) {
	if (ovl->manager == NULL || ovl->manager->output == NULL) {
		r = -EINVAL;
		goto err;
	}
+7 −3
Original line number Diff line number Diff line
@@ -3595,7 +3595,7 @@ static void dispc_error_worker(struct work_struct *work)
		bit = mgr_desc[i].sync_lost_irq;

		if (bit & errors) {
			struct omap_dss_device *dssdev = mgr->device;
			struct omap_dss_device *dssdev = mgr->get_device(mgr);
			bool enable;

			DSSERR("SYNC_LOST on channel %s, restarting the output "
@@ -3626,9 +3626,13 @@ static void dispc_error_worker(struct work_struct *work)
		DSSERR("OCP_ERR\n");
		for (i = 0; i < omap_dss_get_num_overlay_managers(); ++i) {
			struct omap_overlay_manager *mgr;
			struct omap_dss_device *dssdev;

			mgr = omap_dss_get_overlay_manager(i);
			if (mgr->device && mgr->device->driver)
				mgr->device->driver->disable(mgr->device);
			dssdev = mgr->get_device(mgr);

			if (dssdev && dssdev->driver)
				dssdev->driver->disable(dssdev);
		}
	}

Loading