All of lore.kernel.org
 help / color / mirror / Atom feed
From: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
To: Tomi Valkeinen <tomi.valkeinen@ti.com>
Cc: Sebastian Reichel <sre@kernel.org>,
	Nikhil Devshatwar <nikhil.nd@ti.com>,
	linux-omap@vger.kernel.org, dri-devel@lists.freedesktop.org,
	Sekhar Nori <nsekhar@ti.com>, Tony Lindgren <tony@atomide.com>,
	"H . Nikolaus Schaller" <hns@goldelico.com>,
	Sebastian Reichel <sebastian.reichel@collabora.com>
Subject: Re: [PATCH v3 25/56] drm/omap: dsi: move TE GPIO handling into core
Date: Mon, 9 Nov 2020 11:19:02 +0200	[thread overview]
Message-ID: <20201109091902.GV6029@pendragon.ideasonboard.com> (raw)
In-Reply-To: <20201105120333.947408-26-tomi.valkeinen@ti.com>

Hi Tomi and Sebastian,

Thank you for the patch.

On Thu, Nov 05, 2020 at 02:03:02PM +0200, Tomi Valkeinen wrote:
> From: Sebastian Reichel <sebastian.reichel@collabora.com>
> 
> In preparation for removing custom DSS calls from the DSI
> panel driver, this moves support for external tearing event
> GPIOs into the DSI host driver. This way tearing events are
> always handled in the core resulting in simplification of
> the panel drivers.
> 
> The TE GPIO acquisition follows works in the same way as the
> exynos DSI implementation.
> 
> Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
> Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
> ---
>  .../gpu/drm/omapdrm/displays/panel-dsi-cm.c   | 101 +------------
>  drivers/gpu/drm/omapdrm/dss/dsi.c             | 138 ++++++++++++++++--
>  2 files changed, 133 insertions(+), 106 deletions(-)
> 
> diff --git a/drivers/gpu/drm/omapdrm/displays/panel-dsi-cm.c b/drivers/gpu/drm/omapdrm/displays/panel-dsi-cm.c
> index 8890ee2ba830..43f63b5a120b 100644
> --- a/drivers/gpu/drm/omapdrm/displays/panel-dsi-cm.c
> +++ b/drivers/gpu/drm/omapdrm/displays/panel-dsi-cm.c
> @@ -54,7 +54,6 @@ struct panel_drv_data {
>  
>  	/* panel HW configuration from DT or platform data */
>  	struct gpio_desc *reset_gpio;
> -	struct gpio_desc *ext_te_gpio;
>  
>  	struct regulator_bulk_data supplies[DCS_REGULATOR_SUPPLY_NUM];
>  
> @@ -68,10 +67,6 @@ struct panel_drv_data {
>  
>  	bool te_enabled;
>  
> -	atomic_t do_update;
> -
> -	struct delayed_work te_timeout_work;
> -
>  	bool intro_printed;
>  
>  	struct workqueue_struct *workqueue;
> @@ -83,8 +78,6 @@ struct panel_drv_data {
>  
>  #define to_panel_data(p) container_of(p, struct panel_drv_data, dssdev)
>  
> -static irqreturn_t dsicm_te_isr(int irq, void *data);
> -static void dsicm_te_timeout_work_callback(struct work_struct *work);
>  static int _dsicm_enable_te(struct panel_drv_data *ddata, bool enable);
>  
>  static int dsicm_panel_reset(struct panel_drv_data *ddata);
> @@ -240,9 +233,6 @@ static int dsicm_enter_ulps(struct panel_drv_data *ddata)
>  	if (r)
>  		goto err;
>  
> -	if (ddata->ext_te_gpio)
> -		disable_irq(gpiod_to_irq(ddata->ext_te_gpio));
> -
>  	src->ops->dsi.disable(src, false, true);
>  
>  	ddata->ulps_enabled = true;
> @@ -271,15 +261,12 @@ static int dsicm_exit_ulps(struct panel_drv_data *ddata)
>  	src->ops->enable(src);
>  	ddata->dsi->mode_flags &= ~MIPI_DSI_MODE_LPM;
>  
> -	r = _dsicm_enable_te(ddata, true);
> +	r = _dsicm_enable_te(ddata, ddata->te_enabled);
>  	if (r) {
>  		dev_err(&ddata->dsi->dev, "failed to re-enable TE");
>  		goto err2;
>  	}
>  
> -	if (ddata->ext_te_gpio)
> -		enable_irq(gpiod_to_irq(ddata->ext_te_gpio));
> -
>  	dsicm_queue_ulps_work(ddata);
>  
>  	ddata->ulps_enabled = false;
> @@ -290,11 +277,8 @@ static int dsicm_exit_ulps(struct panel_drv_data *ddata)
>  	dev_err(&ddata->dsi->dev, "failed to exit ULPS");
>  
>  	r = dsicm_panel_reset(ddata);
> -	if (!r) {
> -		if (ddata->ext_te_gpio)
> -			enable_irq(gpiod_to_irq(ddata->ext_te_gpio));
> +	if (!r)
>  		ddata->ulps_enabled = false;
> -	}
>  
>  	dsicm_queue_ulps_work(ddata);
>  
> @@ -745,43 +729,6 @@ static void dsicm_framedone_cb(int err, void *data)
>  	src->ops->dsi.bus_unlock(src);
>  }
>  
> -static irqreturn_t dsicm_te_isr(int irq, void *data)
> -{
> -	struct panel_drv_data *ddata = data;
> -	struct omap_dss_device *src = ddata->src;
> -	int old;
> -	int r;
> -
> -	old = atomic_cmpxchg(&ddata->do_update, 1, 0);
> -
> -	if (old) {
> -		cancel_delayed_work(&ddata->te_timeout_work);
> -
> -		r = src->ops->dsi.update(src, ddata->dsi->channel, dsicm_framedone_cb,
> -				ddata);
> -		if (r)
> -			goto err;
> -	}
> -
> -	return IRQ_HANDLED;
> -err:
> -	dev_err(&ddata->dsi->dev, "start update failed\n");
> -	src->ops->dsi.bus_unlock(src);
> -	return IRQ_HANDLED;
> -}
> -
> -static void dsicm_te_timeout_work_callback(struct work_struct *work)
> -{
> -	struct panel_drv_data *ddata = container_of(work, struct panel_drv_data,
> -					te_timeout_work.work);
> -	struct omap_dss_device *src = ddata->src;
> -
> -	dev_err(&ddata->dsi->dev, "TE not received for 250ms!\n");
> -
> -	atomic_set(&ddata->do_update, 0);
> -	src->ops->dsi.bus_unlock(src);
> -}
> -
>  static int dsicm_update(struct omap_dss_device *dssdev,
>  				    u16 x, u16 y, u16 w, u16 h)
>  {
> @@ -809,16 +756,10 @@ static int dsicm_update(struct omap_dss_device *dssdev,
>  	if (r)
>  		goto err;
>  
> -	if (ddata->te_enabled && ddata->ext_te_gpio) {
> -		schedule_delayed_work(&ddata->te_timeout_work,
> -				msecs_to_jiffies(250));
> -		atomic_set(&ddata->do_update, 1);
> -	} else {
> -		r = src->ops->dsi.update(src, ddata->dsi->channel, dsicm_framedone_cb,
> -				ddata);
> -		if (r)
> -			goto err;
> -	}
> +	r = src->ops->dsi.update(src, ddata->dsi->channel, dsicm_framedone_cb,
> +			ddata);
> +	if (r)
> +		goto err;
>  
>  	/* note: no bus_unlock here. unlock is src framedone_cb */
>  	mutex_unlock(&ddata->lock);
> @@ -840,8 +781,7 @@ static int _dsicm_enable_te(struct panel_drv_data *ddata, bool enable)
>  	else
>  		r = mipi_dsi_dcs_set_tear_off(dsi);
>  
> -	if (!ddata->ext_te_gpio)
> -		src->ops->dsi.enable_te(src, enable);
> +	src->ops->dsi.enable_te(src, enable);
>  
>  	/* possible panel bug */
>  	msleep(100);
> @@ -934,14 +874,6 @@ static int dsicm_probe_of(struct mipi_dsi_device *dsi)
>  		return err;
>  	}
>  
> -	ddata->ext_te_gpio = devm_gpiod_get_optional(&dsi->dev, "te",
> -						     GPIOD_IN);
> -	if (IS_ERR(ddata->ext_te_gpio)) {
> -		err = PTR_ERR(ddata->ext_te_gpio);
> -		dev_err(&dsi->dev, "TE gpio request failed: %d", err);
> -		return err;
> -	}
> -
>  	err = of_get_display_timing(node, "panel-timing", &timing);
>  	if (!err) {
>  		videomode_from_timing(&timing, &ddata->vm);
> @@ -1024,25 +956,6 @@ static int dsicm_probe(struct mipi_dsi_device *dsi)
>  
>  	mutex_init(&ddata->lock);
>  
> -	atomic_set(&ddata->do_update, 0);
> -
> -	if (ddata->ext_te_gpio) {
> -		r = devm_request_irq(dev, gpiod_to_irq(ddata->ext_te_gpio),
> -				dsicm_te_isr,
> -				IRQF_TRIGGER_RISING,
> -				"taal vsync", ddata);
> -
> -		if (r) {
> -			dev_err(dev, "IRQ request failed\n");
> -			goto err_reg;
> -		}
> -
> -		INIT_DEFERRABLE_WORK(&ddata->te_timeout_work,
> -					dsicm_te_timeout_work_callback);
> -
> -		dev_dbg(dev, "Using GPIO TE\n");
> -	}
> -
>  	ddata->workqueue = create_singlethread_workqueue("dsicm_wq");
>  	if (!ddata->workqueue) {
>  		r = -ENOMEM;
> diff --git a/drivers/gpu/drm/omapdrm/dss/dsi.c b/drivers/gpu/drm/omapdrm/dss/dsi.c
> index 003d26cead5a..921e7a1e1014 100644
> --- a/drivers/gpu/drm/omapdrm/dss/dsi.c
> +++ b/drivers/gpu/drm/omapdrm/dss/dsi.c
> @@ -14,7 +14,9 @@
>  #include <linux/device.h>
>  #include <linux/err.h>
>  #include <linux/interrupt.h>
> +#include <linux/irq.h>
>  #include <linux/delay.h>
> +#include <linux/gpio/consumer.h>

You could sort the headers while at it :-)

>  #include <linux/mutex.h>
>  #include <linux/module.h>
>  #include <linux/semaphore.h>
> @@ -368,6 +370,11 @@ struct dsi_data {
>  	unsigned int update_bytes;
>  #endif
>  
> +	/* external TE GPIO */
> +	struct gpio_desc *te_gpio;
> +	struct delayed_work te_timeout_work;
> +	atomic_t do_ext_te_update;
> +
>  	bool te_enabled;
>  	bool ulps_enabled;
>  
> @@ -3827,19 +3834,12 @@ static void dsi_framedone_irq_callback(void *data)
>  	dsi_handle_framedone(dsi, 0);
>  }
>  
> -static int dsi_update(struct omap_dss_device *dssdev, int channel,
> -		void (*callback)(int, void *), void *data)
> +static int _dsi_update(struct dsi_data *dsi)
>  {
> -	struct dsi_data *dsi = to_dsi_data(dssdev);
>  	u16 dw, dh;
>  
>  	dsi_perf_mark_setup(dsi);
>  
> -	dsi->update_channel = channel;
> -
> -	dsi->framedone_callback = callback;
> -	dsi->framedone_data = data;
> -
>  	dw = dsi->vm.hactive;
>  	dh = dsi->vm.vactive;
>  
> @@ -3852,6 +3852,26 @@ static int dsi_update(struct omap_dss_device *dssdev, int channel,
>  	return 0;
>  }
>  
> +static int dsi_update(struct omap_dss_device *dssdev, int channel,
> +		void (*callback)(int, void *), void *data)
> +{
> +	struct dsi_data *dsi = to_dsi_data(dssdev);
> +
> +	dsi->update_channel = channel;
> +	dsi->framedone_callback = callback;
> +	dsi->framedone_data = data;
> +
> +	if (dsi->te_enabled && dsi->te_gpio) {
> +		schedule_delayed_work(&dsi->te_timeout_work,
> +				      msecs_to_jiffies(250));
> +		atomic_set(&dsi->do_ext_te_update, 1);
> +	} else {
> +		_dsi_update(dsi);
> +	}
> +
> +	return 0;
> +}
> +
>  /* Display funcs */
>  
>  static int dsi_configure_dispc_clocks(struct dsi_data *dsi)
> @@ -4095,6 +4115,14 @@ static int dsi_enable_te(struct omap_dss_device *dssdev, bool enable)
>  	struct dsi_data *dsi = to_dsi_data(dssdev);
>  
>  	dsi->te_enabled = enable;
> +
> +	if (dsi->te_gpio) {
> +		if (enable)
> +			enable_irq(gpiod_to_irq(dsi->te_gpio));
> +		else
> +			disable_irq(gpiod_to_irq(dsi->te_gpio));
> +	}
> +
>  	return 0;
>  }
>  
> @@ -4772,11 +4800,89 @@ static const struct omap_dss_device_ops dsi_ops = {
>  	},
>  };
>  
> +static irqreturn_t omap_dsi_te_irq_handler(int irq, void *dev_id)
> +{
> +	struct dsi_data *dsi = (struct dsi_data *)dev_id;
> +	int old;
> +
> +	old = atomic_cmpxchg(&dsi->do_ext_te_update, 1, 0);
> +	if (old) {
> +		cancel_delayed_work(&dsi->te_timeout_work);
> +		_dsi_update(dsi);
> +	}
> +
> +	return IRQ_HANDLED;
> +}
> +
> +static void omap_dsi_te_timeout_work_callback(struct work_struct *work)
> +{
> +	struct dsi_data *dsi = container_of(work, struct dsi_data,
> +					te_timeout_work.work);

Strange indentation.

> +	int old;
> +
> +	old = atomic_cmpxchg(&dsi->do_ext_te_update, 1, 0);
> +	if (old) {
> +		dev_err(dsi->dev, "TE not received for 250ms!\n");
> +		_dsi_update(dsi);
> +	}
> +}
> +
> +static int omap_dsi_register_te_irq(struct dsi_data *dsi,
> +				    struct mipi_dsi_device *client)
> +{
> +	int err;
> +	int te_irq;
> +
> +	dsi->te_gpio = gpiod_get_from_of_node(client->dev.of_node,

Could we call gpiod_get(&client->dev, "te", ...) instead ?

> +					      "te-gpios", 0, GPIOD_IN,
> +					      "dsi-tearing-effect");
> +	if (IS_ERR(dsi->te_gpio)) {
> +		err = PTR_ERR(dsi->te_gpio);
> +
> +		if (err == -ENOENT) {
> +			dsi->te_gpio = NULL;
> +			return 0;
> +		}
> +
> +		dev_err(dsi->dev, "Could not get TE gpio: %d\n", err);
> +		return err;
> +	}
> +
> +	te_irq = gpiod_to_irq(dsi->te_gpio);

Could this fail ?

> +	irq_set_status_flags(te_irq, IRQ_NOAUTOEN);
> +
> +	err = request_threaded_irq(te_irq, omap_dsi_te_irq_handler, NULL,
> +				   IRQF_TRIGGER_RISING, "TE", dsi);

What's the reason to request a threaded IRQ instead of a regular IRQ if
the threaded handler is NULL ?

> +	if (err) {
> +		dev_err(dsi->dev, "request irq failed with %d\n", err);
> +		gpiod_put(dsi->te_gpio);
> +		return err;
> +	}
> +
> +	INIT_DEFERRABLE_WORK(&dsi->te_timeout_work,
> +			     omap_dsi_te_timeout_work_callback);
> +
> +	dev_dbg(dsi->dev, "Using GPIO TE\n");
> +
> +	return 0;
> +}
> +
> +static void omap_dsi_unregister_te_irq(struct dsi_data *dsi)
> +{
> +	if (dsi->te_gpio) {
> +		free_irq(gpiod_to_irq(dsi->te_gpio), dsi);

You could store the IRQ number in dsi_data to avoid recomputing it.

> +		cancel_delayed_work(&dsi->te_timeout_work);
> +		gpiod_put(dsi->te_gpio);
> +		dsi->te_gpio = NULL;
> +	}
> +}
> +
>  static int omap_dsi_host_attach(struct mipi_dsi_host *host,
>  				struct mipi_dsi_device *client)
>  {
>  	struct dsi_data *dsi = host_to_omap(host);
>  	unsigned int channel = client->channel;
> +	int r;
>  
>  	if (channel > 3)
>  		return -EINVAL;
> @@ -4791,13 +4897,20 @@ static int omap_dsi_host_attach(struct mipi_dsi_host *host,
>  		return -EINVAL;
>  	}
>  
> -	dsi->vc[channel].dest = client;
> +	atomic_set(&dsi->do_ext_te_update, 0);
>  
> -	dsi->pix_fmt = client->format;
> -	if (client->mode_flags & MIPI_DSI_MODE_VIDEO)
> +	if (client->mode_flags & MIPI_DSI_MODE_VIDEO) {
>  		dsi->mode = OMAP_DSS_DSI_VIDEO_MODE;
> -	else
> +	} else {
> +		r = omap_dsi_register_te_irq(dsi, client);
> +		if (r)
> +			return r;
> +
>  		dsi->mode = OMAP_DSS_DSI_CMD_MODE;
> +	}
> +
> +	dsi->vc[channel].dest = client;
> +	dsi->pix_fmt = client->format;
>  
>  	return 0;
>  }
> @@ -4814,6 +4927,7 @@ static int omap_dsi_host_detach(struct mipi_dsi_host *host,
>  	if (dsi->vc[channel].dest != client)
>  		return -EINVAL;
>  
> +	omap_dsi_unregister_te_irq(dsi);
>  	dsi->vc[channel].dest = NULL;
>  	return 0;
>  }

-- 
Regards,

Laurent Pinchart

WARNING: multiple messages have this Message-ID (diff)
From: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
To: Tomi Valkeinen <tomi.valkeinen@ti.com>
Cc: Tony Lindgren <tony@atomide.com>,
	"H . Nikolaus Schaller" <hns@goldelico.com>,
	Sekhar Nori <nsekhar@ti.com>, Sebastian Reichel <sre@kernel.org>,
	dri-devel@lists.freedesktop.org,
	Sebastian Reichel <sebastian.reichel@collabora.com>,
	linux-omap@vger.kernel.org, Nikhil Devshatwar <nikhil.nd@ti.com>
Subject: Re: [PATCH v3 25/56] drm/omap: dsi: move TE GPIO handling into core
Date: Mon, 9 Nov 2020 11:19:02 +0200	[thread overview]
Message-ID: <20201109091902.GV6029@pendragon.ideasonboard.com> (raw)
In-Reply-To: <20201105120333.947408-26-tomi.valkeinen@ti.com>

Hi Tomi and Sebastian,

Thank you for the patch.

On Thu, Nov 05, 2020 at 02:03:02PM +0200, Tomi Valkeinen wrote:
> From: Sebastian Reichel <sebastian.reichel@collabora.com>
> 
> In preparation for removing custom DSS calls from the DSI
> panel driver, this moves support for external tearing event
> GPIOs into the DSI host driver. This way tearing events are
> always handled in the core resulting in simplification of
> the panel drivers.
> 
> The TE GPIO acquisition follows works in the same way as the
> exynos DSI implementation.
> 
> Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
> Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
> ---
>  .../gpu/drm/omapdrm/displays/panel-dsi-cm.c   | 101 +------------
>  drivers/gpu/drm/omapdrm/dss/dsi.c             | 138 ++++++++++++++++--
>  2 files changed, 133 insertions(+), 106 deletions(-)
> 
> diff --git a/drivers/gpu/drm/omapdrm/displays/panel-dsi-cm.c b/drivers/gpu/drm/omapdrm/displays/panel-dsi-cm.c
> index 8890ee2ba830..43f63b5a120b 100644
> --- a/drivers/gpu/drm/omapdrm/displays/panel-dsi-cm.c
> +++ b/drivers/gpu/drm/omapdrm/displays/panel-dsi-cm.c
> @@ -54,7 +54,6 @@ struct panel_drv_data {
>  
>  	/* panel HW configuration from DT or platform data */
>  	struct gpio_desc *reset_gpio;
> -	struct gpio_desc *ext_te_gpio;
>  
>  	struct regulator_bulk_data supplies[DCS_REGULATOR_SUPPLY_NUM];
>  
> @@ -68,10 +67,6 @@ struct panel_drv_data {
>  
>  	bool te_enabled;
>  
> -	atomic_t do_update;
> -
> -	struct delayed_work te_timeout_work;
> -
>  	bool intro_printed;
>  
>  	struct workqueue_struct *workqueue;
> @@ -83,8 +78,6 @@ struct panel_drv_data {
>  
>  #define to_panel_data(p) container_of(p, struct panel_drv_data, dssdev)
>  
> -static irqreturn_t dsicm_te_isr(int irq, void *data);
> -static void dsicm_te_timeout_work_callback(struct work_struct *work);
>  static int _dsicm_enable_te(struct panel_drv_data *ddata, bool enable);
>  
>  static int dsicm_panel_reset(struct panel_drv_data *ddata);
> @@ -240,9 +233,6 @@ static int dsicm_enter_ulps(struct panel_drv_data *ddata)
>  	if (r)
>  		goto err;
>  
> -	if (ddata->ext_te_gpio)
> -		disable_irq(gpiod_to_irq(ddata->ext_te_gpio));
> -
>  	src->ops->dsi.disable(src, false, true);
>  
>  	ddata->ulps_enabled = true;
> @@ -271,15 +261,12 @@ static int dsicm_exit_ulps(struct panel_drv_data *ddata)
>  	src->ops->enable(src);
>  	ddata->dsi->mode_flags &= ~MIPI_DSI_MODE_LPM;
>  
> -	r = _dsicm_enable_te(ddata, true);
> +	r = _dsicm_enable_te(ddata, ddata->te_enabled);
>  	if (r) {
>  		dev_err(&ddata->dsi->dev, "failed to re-enable TE");
>  		goto err2;
>  	}
>  
> -	if (ddata->ext_te_gpio)
> -		enable_irq(gpiod_to_irq(ddata->ext_te_gpio));
> -
>  	dsicm_queue_ulps_work(ddata);
>  
>  	ddata->ulps_enabled = false;
> @@ -290,11 +277,8 @@ static int dsicm_exit_ulps(struct panel_drv_data *ddata)
>  	dev_err(&ddata->dsi->dev, "failed to exit ULPS");
>  
>  	r = dsicm_panel_reset(ddata);
> -	if (!r) {
> -		if (ddata->ext_te_gpio)
> -			enable_irq(gpiod_to_irq(ddata->ext_te_gpio));
> +	if (!r)
>  		ddata->ulps_enabled = false;
> -	}
>  
>  	dsicm_queue_ulps_work(ddata);
>  
> @@ -745,43 +729,6 @@ static void dsicm_framedone_cb(int err, void *data)
>  	src->ops->dsi.bus_unlock(src);
>  }
>  
> -static irqreturn_t dsicm_te_isr(int irq, void *data)
> -{
> -	struct panel_drv_data *ddata = data;
> -	struct omap_dss_device *src = ddata->src;
> -	int old;
> -	int r;
> -
> -	old = atomic_cmpxchg(&ddata->do_update, 1, 0);
> -
> -	if (old) {
> -		cancel_delayed_work(&ddata->te_timeout_work);
> -
> -		r = src->ops->dsi.update(src, ddata->dsi->channel, dsicm_framedone_cb,
> -				ddata);
> -		if (r)
> -			goto err;
> -	}
> -
> -	return IRQ_HANDLED;
> -err:
> -	dev_err(&ddata->dsi->dev, "start update failed\n");
> -	src->ops->dsi.bus_unlock(src);
> -	return IRQ_HANDLED;
> -}
> -
> -static void dsicm_te_timeout_work_callback(struct work_struct *work)
> -{
> -	struct panel_drv_data *ddata = container_of(work, struct panel_drv_data,
> -					te_timeout_work.work);
> -	struct omap_dss_device *src = ddata->src;
> -
> -	dev_err(&ddata->dsi->dev, "TE not received for 250ms!\n");
> -
> -	atomic_set(&ddata->do_update, 0);
> -	src->ops->dsi.bus_unlock(src);
> -}
> -
>  static int dsicm_update(struct omap_dss_device *dssdev,
>  				    u16 x, u16 y, u16 w, u16 h)
>  {
> @@ -809,16 +756,10 @@ static int dsicm_update(struct omap_dss_device *dssdev,
>  	if (r)
>  		goto err;
>  
> -	if (ddata->te_enabled && ddata->ext_te_gpio) {
> -		schedule_delayed_work(&ddata->te_timeout_work,
> -				msecs_to_jiffies(250));
> -		atomic_set(&ddata->do_update, 1);
> -	} else {
> -		r = src->ops->dsi.update(src, ddata->dsi->channel, dsicm_framedone_cb,
> -				ddata);
> -		if (r)
> -			goto err;
> -	}
> +	r = src->ops->dsi.update(src, ddata->dsi->channel, dsicm_framedone_cb,
> +			ddata);
> +	if (r)
> +		goto err;
>  
>  	/* note: no bus_unlock here. unlock is src framedone_cb */
>  	mutex_unlock(&ddata->lock);
> @@ -840,8 +781,7 @@ static int _dsicm_enable_te(struct panel_drv_data *ddata, bool enable)
>  	else
>  		r = mipi_dsi_dcs_set_tear_off(dsi);
>  
> -	if (!ddata->ext_te_gpio)
> -		src->ops->dsi.enable_te(src, enable);
> +	src->ops->dsi.enable_te(src, enable);
>  
>  	/* possible panel bug */
>  	msleep(100);
> @@ -934,14 +874,6 @@ static int dsicm_probe_of(struct mipi_dsi_device *dsi)
>  		return err;
>  	}
>  
> -	ddata->ext_te_gpio = devm_gpiod_get_optional(&dsi->dev, "te",
> -						     GPIOD_IN);
> -	if (IS_ERR(ddata->ext_te_gpio)) {
> -		err = PTR_ERR(ddata->ext_te_gpio);
> -		dev_err(&dsi->dev, "TE gpio request failed: %d", err);
> -		return err;
> -	}
> -
>  	err = of_get_display_timing(node, "panel-timing", &timing);
>  	if (!err) {
>  		videomode_from_timing(&timing, &ddata->vm);
> @@ -1024,25 +956,6 @@ static int dsicm_probe(struct mipi_dsi_device *dsi)
>  
>  	mutex_init(&ddata->lock);
>  
> -	atomic_set(&ddata->do_update, 0);
> -
> -	if (ddata->ext_te_gpio) {
> -		r = devm_request_irq(dev, gpiod_to_irq(ddata->ext_te_gpio),
> -				dsicm_te_isr,
> -				IRQF_TRIGGER_RISING,
> -				"taal vsync", ddata);
> -
> -		if (r) {
> -			dev_err(dev, "IRQ request failed\n");
> -			goto err_reg;
> -		}
> -
> -		INIT_DEFERRABLE_WORK(&ddata->te_timeout_work,
> -					dsicm_te_timeout_work_callback);
> -
> -		dev_dbg(dev, "Using GPIO TE\n");
> -	}
> -
>  	ddata->workqueue = create_singlethread_workqueue("dsicm_wq");
>  	if (!ddata->workqueue) {
>  		r = -ENOMEM;
> diff --git a/drivers/gpu/drm/omapdrm/dss/dsi.c b/drivers/gpu/drm/omapdrm/dss/dsi.c
> index 003d26cead5a..921e7a1e1014 100644
> --- a/drivers/gpu/drm/omapdrm/dss/dsi.c
> +++ b/drivers/gpu/drm/omapdrm/dss/dsi.c
> @@ -14,7 +14,9 @@
>  #include <linux/device.h>
>  #include <linux/err.h>
>  #include <linux/interrupt.h>
> +#include <linux/irq.h>
>  #include <linux/delay.h>
> +#include <linux/gpio/consumer.h>

You could sort the headers while at it :-)

>  #include <linux/mutex.h>
>  #include <linux/module.h>
>  #include <linux/semaphore.h>
> @@ -368,6 +370,11 @@ struct dsi_data {
>  	unsigned int update_bytes;
>  #endif
>  
> +	/* external TE GPIO */
> +	struct gpio_desc *te_gpio;
> +	struct delayed_work te_timeout_work;
> +	atomic_t do_ext_te_update;
> +
>  	bool te_enabled;
>  	bool ulps_enabled;
>  
> @@ -3827,19 +3834,12 @@ static void dsi_framedone_irq_callback(void *data)
>  	dsi_handle_framedone(dsi, 0);
>  }
>  
> -static int dsi_update(struct omap_dss_device *dssdev, int channel,
> -		void (*callback)(int, void *), void *data)
> +static int _dsi_update(struct dsi_data *dsi)
>  {
> -	struct dsi_data *dsi = to_dsi_data(dssdev);
>  	u16 dw, dh;
>  
>  	dsi_perf_mark_setup(dsi);
>  
> -	dsi->update_channel = channel;
> -
> -	dsi->framedone_callback = callback;
> -	dsi->framedone_data = data;
> -
>  	dw = dsi->vm.hactive;
>  	dh = dsi->vm.vactive;
>  
> @@ -3852,6 +3852,26 @@ static int dsi_update(struct omap_dss_device *dssdev, int channel,
>  	return 0;
>  }
>  
> +static int dsi_update(struct omap_dss_device *dssdev, int channel,
> +		void (*callback)(int, void *), void *data)
> +{
> +	struct dsi_data *dsi = to_dsi_data(dssdev);
> +
> +	dsi->update_channel = channel;
> +	dsi->framedone_callback = callback;
> +	dsi->framedone_data = data;
> +
> +	if (dsi->te_enabled && dsi->te_gpio) {
> +		schedule_delayed_work(&dsi->te_timeout_work,
> +				      msecs_to_jiffies(250));
> +		atomic_set(&dsi->do_ext_te_update, 1);
> +	} else {
> +		_dsi_update(dsi);
> +	}
> +
> +	return 0;
> +}
> +
>  /* Display funcs */
>  
>  static int dsi_configure_dispc_clocks(struct dsi_data *dsi)
> @@ -4095,6 +4115,14 @@ static int dsi_enable_te(struct omap_dss_device *dssdev, bool enable)
>  	struct dsi_data *dsi = to_dsi_data(dssdev);
>  
>  	dsi->te_enabled = enable;
> +
> +	if (dsi->te_gpio) {
> +		if (enable)
> +			enable_irq(gpiod_to_irq(dsi->te_gpio));
> +		else
> +			disable_irq(gpiod_to_irq(dsi->te_gpio));
> +	}
> +
>  	return 0;
>  }
>  
> @@ -4772,11 +4800,89 @@ static const struct omap_dss_device_ops dsi_ops = {
>  	},
>  };
>  
> +static irqreturn_t omap_dsi_te_irq_handler(int irq, void *dev_id)
> +{
> +	struct dsi_data *dsi = (struct dsi_data *)dev_id;
> +	int old;
> +
> +	old = atomic_cmpxchg(&dsi->do_ext_te_update, 1, 0);
> +	if (old) {
> +		cancel_delayed_work(&dsi->te_timeout_work);
> +		_dsi_update(dsi);
> +	}
> +
> +	return IRQ_HANDLED;
> +}
> +
> +static void omap_dsi_te_timeout_work_callback(struct work_struct *work)
> +{
> +	struct dsi_data *dsi = container_of(work, struct dsi_data,
> +					te_timeout_work.work);

Strange indentation.

> +	int old;
> +
> +	old = atomic_cmpxchg(&dsi->do_ext_te_update, 1, 0);
> +	if (old) {
> +		dev_err(dsi->dev, "TE not received for 250ms!\n");
> +		_dsi_update(dsi);
> +	}
> +}
> +
> +static int omap_dsi_register_te_irq(struct dsi_data *dsi,
> +				    struct mipi_dsi_device *client)
> +{
> +	int err;
> +	int te_irq;
> +
> +	dsi->te_gpio = gpiod_get_from_of_node(client->dev.of_node,

Could we call gpiod_get(&client->dev, "te", ...) instead ?

> +					      "te-gpios", 0, GPIOD_IN,
> +					      "dsi-tearing-effect");
> +	if (IS_ERR(dsi->te_gpio)) {
> +		err = PTR_ERR(dsi->te_gpio);
> +
> +		if (err == -ENOENT) {
> +			dsi->te_gpio = NULL;
> +			return 0;
> +		}
> +
> +		dev_err(dsi->dev, "Could not get TE gpio: %d\n", err);
> +		return err;
> +	}
> +
> +	te_irq = gpiod_to_irq(dsi->te_gpio);

Could this fail ?

> +	irq_set_status_flags(te_irq, IRQ_NOAUTOEN);
> +
> +	err = request_threaded_irq(te_irq, omap_dsi_te_irq_handler, NULL,
> +				   IRQF_TRIGGER_RISING, "TE", dsi);

What's the reason to request a threaded IRQ instead of a regular IRQ if
the threaded handler is NULL ?

> +	if (err) {
> +		dev_err(dsi->dev, "request irq failed with %d\n", err);
> +		gpiod_put(dsi->te_gpio);
> +		return err;
> +	}
> +
> +	INIT_DEFERRABLE_WORK(&dsi->te_timeout_work,
> +			     omap_dsi_te_timeout_work_callback);
> +
> +	dev_dbg(dsi->dev, "Using GPIO TE\n");
> +
> +	return 0;
> +}
> +
> +static void omap_dsi_unregister_te_irq(struct dsi_data *dsi)
> +{
> +	if (dsi->te_gpio) {
> +		free_irq(gpiod_to_irq(dsi->te_gpio), dsi);

You could store the IRQ number in dsi_data to avoid recomputing it.

> +		cancel_delayed_work(&dsi->te_timeout_work);
> +		gpiod_put(dsi->te_gpio);
> +		dsi->te_gpio = NULL;
> +	}
> +}
> +
>  static int omap_dsi_host_attach(struct mipi_dsi_host *host,
>  				struct mipi_dsi_device *client)
>  {
>  	struct dsi_data *dsi = host_to_omap(host);
>  	unsigned int channel = client->channel;
> +	int r;
>  
>  	if (channel > 3)
>  		return -EINVAL;
> @@ -4791,13 +4897,20 @@ static int omap_dsi_host_attach(struct mipi_dsi_host *host,
>  		return -EINVAL;
>  	}
>  
> -	dsi->vc[channel].dest = client;
> +	atomic_set(&dsi->do_ext_te_update, 0);
>  
> -	dsi->pix_fmt = client->format;
> -	if (client->mode_flags & MIPI_DSI_MODE_VIDEO)
> +	if (client->mode_flags & MIPI_DSI_MODE_VIDEO) {
>  		dsi->mode = OMAP_DSS_DSI_VIDEO_MODE;
> -	else
> +	} else {
> +		r = omap_dsi_register_te_irq(dsi, client);
> +		if (r)
> +			return r;
> +
>  		dsi->mode = OMAP_DSS_DSI_CMD_MODE;
> +	}
> +
> +	dsi->vc[channel].dest = client;
> +	dsi->pix_fmt = client->format;
>  
>  	return 0;
>  }
> @@ -4814,6 +4927,7 @@ static int omap_dsi_host_detach(struct mipi_dsi_host *host,
>  	if (dsi->vc[channel].dest != client)
>  		return -EINVAL;
>  
> +	omap_dsi_unregister_te_irq(dsi);
>  	dsi->vc[channel].dest = NULL;
>  	return 0;
>  }

-- 
Regards,

Laurent Pinchart
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

  reply	other threads:[~2020-11-09  9:19 UTC|newest]

Thread overview: 328+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-11-05 12:02 [PATCH v3 00/56] Convert DSI code to use drm_mipi_dsi and drm_panel Tomi Valkeinen
2020-11-05 12:02 ` Tomi Valkeinen
2020-11-05 12:02 ` [PATCH v3 01/56] drm/dsi: add MIPI_DSI_MODE_ULPS_IDLE Tomi Valkeinen
2020-11-05 12:02   ` Tomi Valkeinen
2020-11-06  4:41   ` Laurent Pinchart
2020-11-06  4:41     ` Laurent Pinchart
2020-11-05 12:02 ` [PATCH v3 02/56] Revert "drm/omap: dss: Remove unused omap_dss_device operations" Tomi Valkeinen
2020-11-05 12:02   ` Tomi Valkeinen
2020-11-05 21:27   ` Sam Ravnborg
2020-11-05 21:27     ` Sam Ravnborg
2020-11-06  4:50   ` Laurent Pinchart
2020-11-06  4:50     ` Laurent Pinchart
2020-11-05 12:02 ` [PATCH v3 03/56] drm/omap: drop unused dsi.configure_pins Tomi Valkeinen
2020-11-05 12:02   ` Tomi Valkeinen
2020-11-06  4:50   ` Laurent Pinchart
2020-11-06  4:50     ` Laurent Pinchart
2020-11-05 12:02 ` [PATCH v3 04/56] drm/omap: dsi: use MIPI_DSI_FMT_* instead of OMAP_DSS_DSI_FMT_* Tomi Valkeinen
2020-11-05 12:02   ` Tomi Valkeinen
2020-11-06  4:56   ` Laurent Pinchart
2020-11-06  4:56     ` Laurent Pinchart
2020-11-05 12:02 ` [PATCH v3 05/56] drm/omap: constify write buffers Tomi Valkeinen
2020-11-05 12:02   ` Tomi Valkeinen
2020-11-06  4:57   ` Laurent Pinchart
2020-11-06  4:57     ` Laurent Pinchart
2020-11-05 12:02 ` [PATCH v3 06/56] drm/omap: dsi: add generic transfer function Tomi Valkeinen
2020-11-05 12:02   ` Tomi Valkeinen
2020-11-06  5:05   ` Laurent Pinchart
2020-11-06  5:05     ` Laurent Pinchart
2020-11-05 12:02 ` [PATCH v3 07/56] drm/omap: panel-dsi-cm: convert to transfer API Tomi Valkeinen
2020-11-05 12:02   ` Tomi Valkeinen
2020-11-06  5:08   ` Laurent Pinchart
2020-11-06  5:08     ` Laurent Pinchart
2020-11-05 12:02 ` [PATCH v3 08/56] drm/omap: dsi: unexport specific data transfer functions Tomi Valkeinen
2020-11-05 12:02   ` Tomi Valkeinen
2020-11-09  8:10   ` Laurent Pinchart
2020-11-09  8:10     ` Laurent Pinchart
2020-11-05 12:02 ` [PATCH v3 09/56] drm/omap: dsi: drop virtual channel logic Tomi Valkeinen
2020-11-05 12:02   ` Tomi Valkeinen
2020-11-09  8:14   ` Laurent Pinchart
2020-11-09  8:14     ` Laurent Pinchart
2020-11-09  8:20     ` Tomi Valkeinen
2020-11-09  8:20       ` Tomi Valkeinen
2020-11-09  8:18   ` Tomi Valkeinen
2020-11-09  8:18     ` Tomi Valkeinen
2020-11-05 12:02 ` [PATCH v3 10/56] drm/omap: dsi: simplify write function Tomi Valkeinen
2020-11-05 12:02   ` Tomi Valkeinen
2020-11-09  8:21   ` Laurent Pinchart
2020-11-09  8:21     ` Laurent Pinchart
2020-11-05 12:02 ` [PATCH v3 11/56] drm/omap: dsi: simplify read functions Tomi Valkeinen
2020-11-05 12:02   ` Tomi Valkeinen
2020-11-09  8:28   ` Laurent Pinchart
2020-11-09  8:28     ` Laurent Pinchart
2020-11-05 12:02 ` [PATCH v3 12/56] drm/omap: dsi: switch dsi_vc_send_long/short to mipi_dsi_msg Tomi Valkeinen
2020-11-05 12:02   ` Tomi Valkeinen
2020-11-09  8:33   ` Laurent Pinchart
2020-11-09  8:33     ` Laurent Pinchart
2020-11-05 12:02 ` [PATCH v3 13/56] drm/omap: dsi: introduce mipi_dsi_host Tomi Valkeinen
2020-11-05 12:02   ` Tomi Valkeinen
2020-11-09  8:38   ` Laurent Pinchart
2020-11-09  8:38     ` Laurent Pinchart
2020-11-05 12:02 ` [PATCH v3 14/56] drm/omap: panel-dsi-cm: use DSI helpers Tomi Valkeinen
2020-11-05 12:02   ` Tomi Valkeinen
2020-11-09  8:40   ` Laurent Pinchart
2020-11-09  8:40     ` Laurent Pinchart
2020-11-05 12:02 ` [PATCH v3 15/56] drm/omap: dsi: request VC via mipi_dsi_attach Tomi Valkeinen
2020-11-05 12:02   ` Tomi Valkeinen
2020-11-09  8:42   ` Laurent Pinchart
2020-11-09  8:42     ` Laurent Pinchart
2020-11-09 11:16     ` Tomi Valkeinen
2020-11-09 11:16       ` Tomi Valkeinen
2020-11-05 12:02 ` [PATCH v3 16/56] drm/omap: panel-dsi-cm: drop hardcoded VC Tomi Valkeinen
2020-11-05 12:02   ` Tomi Valkeinen
2020-11-09  8:43   ` Laurent Pinchart
2020-11-09  8:43     ` Laurent Pinchart
2020-11-05 12:02 ` [PATCH v3 17/56] drm/omap: panel-dsi-cm: use common MIPI DCS 1.3 defines Tomi Valkeinen
2020-11-05 12:02   ` Tomi Valkeinen
2020-11-09  8:44   ` Laurent Pinchart
2020-11-09  8:44     ` Laurent Pinchart
2020-11-05 12:02 ` [PATCH v3 18/56] drm/omap: dsi: drop unused memory_read() Tomi Valkeinen
2020-11-05 12:02   ` Tomi Valkeinen
2020-11-09  8:45   ` Laurent Pinchart
2020-11-09  8:45     ` Laurent Pinchart
2020-11-05 12:02 ` [PATCH v3 19/56] drm/omap: dsi: drop unused get_te() Tomi Valkeinen
2020-11-05 12:02   ` Tomi Valkeinen
2020-11-09  8:45   ` Laurent Pinchart
2020-11-09  8:45     ` Laurent Pinchart
2020-11-09  9:49     ` Tomi Valkeinen
2020-11-09  9:49       ` Tomi Valkeinen
2020-11-05 12:02 ` [PATCH v3 20/56] drm/omap: dsi: drop unused enable_te() Tomi Valkeinen
2020-11-05 12:02   ` Tomi Valkeinen
2020-11-09  8:46   ` Laurent Pinchart
2020-11-09  8:46     ` Laurent Pinchart
2020-11-05 12:02 ` [PATCH v3 21/56] drm/omap: dsi: drop useless sync() Tomi Valkeinen
2020-11-05 12:02   ` Tomi Valkeinen
2020-11-09  8:46   ` Laurent Pinchart
2020-11-09  8:46     ` Laurent Pinchart
2020-11-05 12:02 ` [PATCH v3 22/56] drm/omap: dsi: use pixel-format and mode from attach Tomi Valkeinen
2020-11-05 12:02   ` Tomi Valkeinen
2020-11-09  8:49   ` Laurent Pinchart
2020-11-09  8:49     ` Laurent Pinchart
2020-11-09  9:45     ` Tomi Valkeinen
2020-11-09  9:45       ` Tomi Valkeinen
2020-11-05 12:03 ` [PATCH v3 23/56] drm/omap: panel-dsi-cm: use bulk regulator API Tomi Valkeinen
2020-11-05 12:03   ` Tomi Valkeinen
2020-11-09  8:51   ` Laurent Pinchart
2020-11-09  8:51     ` Laurent Pinchart
2020-11-05 12:03 ` [PATCH v3 24/56] drm/omap: dsi: lp/hs switching support for transfer() Tomi Valkeinen
2020-11-05 12:03   ` Tomi Valkeinen
2020-11-09  8:53   ` Laurent Pinchart
2020-11-09  8:53     ` Laurent Pinchart
2020-11-05 12:03 ` [PATCH v3 25/56] drm/omap: dsi: move TE GPIO handling into core Tomi Valkeinen
2020-11-05 12:03   ` Tomi Valkeinen
2020-11-09  9:19   ` Laurent Pinchart [this message]
2020-11-09  9:19     ` Laurent Pinchart
2020-11-11 13:26     ` Tomi Valkeinen
2020-11-11 13:26       ` Tomi Valkeinen
2020-11-05 12:03 ` [PATCH v3 26/56] drm/omap: dsi: drop custom enable_te() API Tomi Valkeinen
2020-11-05 12:03   ` Tomi Valkeinen
2020-11-09  9:32   ` Laurent Pinchart
2020-11-09  9:32     ` Laurent Pinchart
2020-11-05 12:03 ` [PATCH v3 27/56] drm/omap: dsi: do bus locking in host driver Tomi Valkeinen
2020-11-05 12:03   ` Tomi Valkeinen
2020-11-09  9:52   ` Laurent Pinchart
2020-11-09  9:52     ` Laurent Pinchart
2020-11-09 10:08     ` Tomi Valkeinen
2020-11-09 10:08       ` Tomi Valkeinen
2020-11-09 13:27       ` Sebastian Reichel
2020-11-09 13:27         ` Sebastian Reichel
2020-11-09 14:25         ` Tomi Valkeinen
2020-11-09 14:25           ` Tomi Valkeinen
2020-11-11 13:35         ` Tomi Valkeinen
2020-11-11 13:35           ` Tomi Valkeinen
2020-11-05 12:03 ` [PATCH v3 28/56] drm/omap: dsi: untangle ulps ops from enable/disable Tomi Valkeinen
2020-11-05 12:03   ` Tomi Valkeinen
2020-11-09  9:57   ` Laurent Pinchart
2020-11-09  9:57     ` Laurent Pinchart
2020-11-11 14:05     ` Tomi Valkeinen
2020-11-11 14:05       ` Tomi Valkeinen
2020-11-05 12:03 ` [PATCH v3 29/56] drm/omap: dsi: do ULPS in host driver Tomi Valkeinen
2020-11-05 12:03   ` Tomi Valkeinen
2020-11-09 10:03   ` Laurent Pinchart
2020-11-09 10:03     ` Laurent Pinchart
2020-11-11 15:29     ` Tomi Valkeinen
2020-11-11 15:29       ` Tomi Valkeinen
2020-11-05 12:03 ` [PATCH v3 30/56] drm/omap: dsi: move panel refresh function to host Tomi Valkeinen
2020-11-05 12:03   ` Tomi Valkeinen
2020-11-09 10:10   ` Laurent Pinchart
2020-11-09 10:10     ` Laurent Pinchart
2020-11-11 15:34     ` Tomi Valkeinen
2020-11-11 15:34       ` Tomi Valkeinen
2020-11-11 15:58       ` Laurent Pinchart
2020-11-11 15:58         ` Laurent Pinchart
2020-11-12  8:08         ` Tomi Valkeinen
2020-11-12  8:08           ` Tomi Valkeinen
2020-11-16  9:22           ` Laurent Pinchart
2020-11-16  9:22             ` Laurent Pinchart
2020-11-17 10:04             ` Sebastian Reichel
2020-11-17 10:04               ` Sebastian Reichel
2020-11-05 12:03 ` [PATCH v3 31/56] drm/omap: dsi: Reverse direction of the DSS device enable/disable operations Tomi Valkeinen
2020-11-05 12:03   ` Tomi Valkeinen
2020-11-09 10:17   ` Laurent Pinchart
2020-11-09 10:17     ` Laurent Pinchart
2020-11-05 12:03 ` [PATCH v3 32/56] drm/omap: dsi: drop custom panel capability support Tomi Valkeinen
2020-11-05 12:03   ` Tomi Valkeinen
2020-11-09 10:20   ` Laurent Pinchart
2020-11-09 10:20     ` Laurent Pinchart
2020-11-05 12:03 ` [PATCH v3 33/56] drm/omap: dsi: convert to drm_panel Tomi Valkeinen
2020-11-05 12:03   ` Tomi Valkeinen
2020-11-09 10:39   ` Laurent Pinchart
2020-11-09 10:39     ` Laurent Pinchart
2020-11-11 15:54     ` Tomi Valkeinen
2020-11-11 15:54       ` Tomi Valkeinen
2020-11-05 12:03 ` [PATCH v3 34/56] drm/omap: drop omapdss-boot-init Tomi Valkeinen
2020-11-05 12:03   ` Tomi Valkeinen
2020-11-09 10:40   ` Laurent Pinchart
2020-11-09 10:40     ` Laurent Pinchart
2020-11-05 12:03 ` [PATCH v3 35/56] drm/omap: dsi: implement check timings Tomi Valkeinen
2020-11-05 12:03   ` Tomi Valkeinen
2020-11-09 10:47   ` Laurent Pinchart
2020-11-09 10:47     ` Laurent Pinchart
2020-11-11 12:36     ` Tomi Valkeinen
2020-11-11 12:36       ` Tomi Valkeinen
2020-11-05 12:03 ` [PATCH v3 36/56] drm/omap: panel-dsi-cm: use DEVICE_ATTR_RO Tomi Valkeinen
2020-11-05 12:03   ` Tomi Valkeinen
2020-11-09 10:48   ` Laurent Pinchart
2020-11-09 10:48     ` Laurent Pinchart
2020-11-05 12:03 ` [PATCH v3 37/56] drm/omap: panel-dsi-cm: support unbinding Tomi Valkeinen
2020-11-05 12:03   ` Tomi Valkeinen
2020-11-09 10:49   ` Laurent Pinchart
2020-11-09 10:49     ` Laurent Pinchart
2020-11-11 12:03     ` Tomi Valkeinen
2020-11-11 12:03       ` Tomi Valkeinen
2020-11-05 12:03 ` [PATCH v3 38/56] drm/omap: panel-dsi-cm: fix remove() Tomi Valkeinen
2020-11-05 12:03   ` Tomi Valkeinen
2020-11-09 10:50   ` Laurent Pinchart
2020-11-09 10:50     ` Laurent Pinchart
2020-11-05 12:03 ` [PATCH v3 39/56] drm/omap: remove global dss_device variable Tomi Valkeinen
2020-11-05 12:03   ` Tomi Valkeinen
2020-11-09 10:51   ` Laurent Pinchart
2020-11-09 10:51     ` Laurent Pinchart
2020-11-05 12:03 ` [PATCH v3 40/56] drm/panel: Move OMAP's DSI command mode panel driver Tomi Valkeinen
2020-11-05 12:03   ` Tomi Valkeinen
2020-11-05 15:16   ` Sam Ravnborg
2020-11-05 15:16     ` Sam Ravnborg
2020-11-05 15:27   ` Tomi Valkeinen
2020-11-05 15:27     ` Tomi Valkeinen
2020-11-09 10:53   ` Laurent Pinchart
2020-11-09 10:53     ` Laurent Pinchart
2020-11-05 12:03 ` [PATCH v3 41/56] drm/omap: dsi: Register a drm_bridge Tomi Valkeinen
2020-11-05 12:03   ` Tomi Valkeinen
2020-11-09 10:54   ` Laurent Pinchart
2020-11-09 10:54     ` Laurent Pinchart
2020-11-05 12:03 ` [PATCH v3 42/56] drm/omap: remove legacy DSS device operations Tomi Valkeinen
2020-11-05 12:03   ` Tomi Valkeinen
2020-11-09 11:01   ` Laurent Pinchart
2020-11-09 11:01     ` Laurent Pinchart
2020-11-05 12:03 ` [PATCH v3 43/56] drm/omap: remove unused omap_connector Tomi Valkeinen
2020-11-05 12:03   ` Tomi Valkeinen
2020-11-09 11:02   ` Laurent Pinchart
2020-11-09 11:02     ` Laurent Pinchart
2020-11-05 12:03 ` [PATCH v3 44/56] drm/omap: simplify omap_display_id Tomi Valkeinen
2020-11-05 12:03   ` Tomi Valkeinen
2020-11-09 11:03   ` Laurent Pinchart
2020-11-09 11:03     ` Laurent Pinchart
2020-11-05 12:03 ` [PATCH v3 45/56] drm/omap: drop unused DSS next pointer Tomi Valkeinen
2020-11-05 12:03   ` Tomi Valkeinen
2020-11-09 11:04   ` Laurent Pinchart
2020-11-09 11:04     ` Laurent Pinchart
2020-11-05 12:03 ` [PATCH v3 46/56] drm/omap: drop empty omap_encoder helper functions Tomi Valkeinen
2020-11-05 12:03   ` Tomi Valkeinen
2020-11-09 11:05   ` Laurent Pinchart
2020-11-09 11:05     ` Laurent Pinchart
2020-11-05 12:03 ` [PATCH v3 47/56] drm/omap: drop DSS ops_flags Tomi Valkeinen
2020-11-05 12:03   ` Tomi Valkeinen
2020-11-09 11:05   ` Laurent Pinchart
2020-11-09 11:05     ` Laurent Pinchart
2020-11-05 12:03 ` [PATCH v3 48/56] drm/omap: drop dssdev display field Tomi Valkeinen
2020-11-05 12:03   ` Tomi Valkeinen
2020-11-09 11:06   ` Laurent Pinchart
2020-11-09 11:06     ` Laurent Pinchart
2020-11-05 12:03 ` [PATCH v3 49/56] drm/omap: simplify DSI manual update code Tomi Valkeinen
2020-11-05 12:03   ` Tomi Valkeinen
2020-11-09 11:07   ` Laurent Pinchart
2020-11-09 11:07     ` Laurent Pinchart
2020-11-05 12:03 ` [PATCH v3 50/56] drm/omap: dsi: simplify pin config Tomi Valkeinen
2020-11-05 12:03   ` Tomi Valkeinen
2020-11-09 11:09   ` Laurent Pinchart
2020-11-09 11:09     ` Laurent Pinchart
2020-11-11 12:24     ` Tomi Valkeinen
2020-11-11 12:24       ` Tomi Valkeinen
2020-11-05 12:03 ` [PATCH v3 51/56] ARM: omap2plus_defconfig: Update for moved DSI command mode panel Tomi Valkeinen
2020-11-05 12:03   ` Tomi Valkeinen
2020-11-09 11:10   ` Laurent Pinchart
2020-11-09 11:10     ` Laurent Pinchart
2020-11-05 12:03 ` [PATCH v3 52/56] drm/omap: squash omapdrm sub-modules into one Tomi Valkeinen
2020-11-05 12:03   ` Tomi Valkeinen
2020-11-09 11:15   ` Laurent Pinchart
2020-11-09 11:15     ` Laurent Pinchart
2020-11-05 12:03 ` [PATCH v3 53/56] drm/omap: remove unused display.c Tomi Valkeinen
2020-11-05 12:03   ` Tomi Valkeinen
2020-11-09 11:16   ` Laurent Pinchart
2020-11-09 11:16     ` Laurent Pinchart
2020-11-05 12:03 ` [PATCH v3 54/56] drm/omap: drop unused owner field Tomi Valkeinen
2020-11-05 12:03   ` Tomi Valkeinen
2020-11-09 11:16   ` Laurent Pinchart
2020-11-09 11:16     ` Laurent Pinchart
2020-11-05 12:03 ` [PATCH v3 55/56] drm/omap: remove dispc_ops Tomi Valkeinen
2020-11-05 12:03   ` Tomi Valkeinen
2020-11-09 11:17   ` Laurent Pinchart
2020-11-09 11:17     ` Laurent Pinchart
2020-11-05 12:03 ` [PATCH v3 56/56] drm/omap: remove dss_mgr_ops Tomi Valkeinen
2020-11-05 12:03   ` Tomi Valkeinen
2020-11-09 11:18   ` Laurent Pinchart
2020-11-09 11:18     ` Laurent Pinchart
2020-11-05 17:15 ` [PATCH v3 00/56] Convert DSI code to use drm_mipi_dsi and drm_panel H. Nikolaus Schaller
2020-11-05 17:15   ` H. Nikolaus Schaller
2020-11-05 17:36   ` Tomi Valkeinen
2020-11-05 17:36     ` Tomi Valkeinen
2020-11-05 18:14     ` H. Nikolaus Schaller
2020-11-05 18:14       ` H. Nikolaus Schaller
2020-11-05 18:28       ` Tomi Valkeinen
2020-11-05 18:28         ` Tomi Valkeinen
2020-11-05 18:56         ` H. Nikolaus Schaller
2020-11-05 18:56           ` H. Nikolaus Schaller
2020-11-06 14:37           ` Tomi Valkeinen
2020-11-06 14:37             ` Tomi Valkeinen
2020-11-06 15:04             ` Tomi Valkeinen
2020-11-06 15:04               ` Tomi Valkeinen
2020-11-07 12:19               ` H. Nikolaus Schaller
2020-11-07 12:19                 ` H. Nikolaus Schaller
2020-11-09  8:04                 ` Tomi Valkeinen
2020-11-09  8:04                   ` Tomi Valkeinen
2020-11-09  9:30                   ` H. Nikolaus Schaller
2020-11-09  9:30                     ` H. Nikolaus Schaller
2020-11-09 10:22                     ` Tomi Valkeinen
2020-11-09 10:22                       ` Tomi Valkeinen
2020-11-09 10:31                       ` H. Nikolaus Schaller
2020-11-09 10:31                         ` H. Nikolaus Schaller
2020-11-09 10:34                         ` Tomi Valkeinen
2020-11-09 10:34                           ` Tomi Valkeinen
2020-11-09 11:09                           ` H. Nikolaus Schaller
2020-11-09 11:09                             ` H. Nikolaus Schaller
2020-11-09 11:33                             ` Tomi Valkeinen
2020-11-09 11:33                               ` Tomi Valkeinen
2020-11-10 13:49                               ` H. Nikolaus Schaller
2020-11-10 13:49                                 ` H. Nikolaus Schaller
2020-11-10 15:25                                 ` Tomi Valkeinen
2020-11-10 15:25                                   ` Tomi Valkeinen
2020-11-10 16:49                                 ` H. Nikolaus Schaller
2020-11-10 16:49                                   ` H. Nikolaus Schaller
2020-11-10 16:52                                   ` Tomi Valkeinen
2020-11-10 16:52                                     ` Tomi Valkeinen
2020-11-10 21:04                                     ` H. Nikolaus Schaller
2020-11-10 21:04                                       ` H. Nikolaus Schaller
2020-11-11  6:40                                       ` Tomi Valkeinen
2020-11-11  6:40                                         ` Tomi Valkeinen
2020-11-11  7:48                                         ` H. Nikolaus Schaller
2020-11-11  7:48                                           ` H. Nikolaus Schaller
2020-11-11 10:11                                           ` Tomi Valkeinen
2020-11-11 10:11                                             ` Tomi Valkeinen
2020-11-11 19:27                                             ` H. Nikolaus Schaller
2020-11-11 19:27                                               ` H. Nikolaus Schaller
2020-11-05 21:31 ` Sam Ravnborg
2020-11-05 21:31   ` Sam Ravnborg
2020-11-08 16:33 ` Nikhil Devshatwar
2020-11-08 16:33   ` Nikhil Devshatwar
     [not found] ` <BAFBC885-9BBE-46D1-B4C4-79910705864A@goldelico.com>
     [not found]   ` <74abbdc4-cc1e-9caf-d4ee-0a5cdb557643@ti.com>
     [not found]     ` <b0677958-02ad-1d2f-d755-! 25a9d384eddc@ti.com>
     [not found]       ` <1A09B4DA-F726-4F37-8CF4-BC192C659950@goldelico.com>
     [not found]         ` <9a4e373e-9092-6d82-937a-bc663d2376b4@ti.com>
     [not found]           ` <09ebc3e3-72c7-41fb-fb21-bf28c! f883d3f@ti.com>
     [not found]             ` <E738362A-8ECE-4ED5-8057-2ABB6F5C3056@goldelico.com>
     [not found]               ` <9a21b475-eff0-9882-8d65-d1f! dd2139dc4@ti.com>
     [not found]                 ` <A1DEB54D-FEC0-493A-858C-E5C0DB24B35E@goldelico.com>
     [not found]                   ` <1150ba22-1ae2-39f3-0924-7! a1f1b468597@ti.com>
     [not found]                     ` <2999ED77-B9F7-4197-81B8-F1AFF329A1E9@goldelico.com>
     [not found]                       ` <cbc147d2-af41-2bed-5670-530d45cfb24e@ti.com>
     [not found]                         ` <106bfbee-c472-c04c-0f7b-db108a090a63@ti.com>
     [not found]                           ` <420b81bd-fc95-e294-fcbe-f34db1ef! f9e7@ti.c om>
     [not found]                             ` <B2FBCAE4-FAD9-4C0D-9C75-63A701215886@goldelico.com>
     [not found]                               ` <826B2E97-8B77-412A-8093-753BF7A65EE1@goldelico.com>
     [not found]                                 ` <acad2006-53a2-6587-b8e6-787e358! 8932a@ti.com>
     [not found]                                   ` <AF87C7B4-DCD2-4207-A300-567DB65B08ED@goldelico.com>
     [not found]                                     ` <27cfb13a-62e3-0a53-153f-92641c437cee@ti. com>
     [not found]                                       ` <27cfb13a-62e3-0a53-153f-92641c437cee@ti.com>
2020-11-16  9:16                                         ` H. Nikolaus Schaller
2020-11-16  9:16                                           ` H. Nikolaus Schaller

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20201109091902.GV6029@pendragon.ideasonboard.com \
    --to=laurent.pinchart@ideasonboard.com \
    --cc=dri-devel@lists.freedesktop.org \
    --cc=hns@goldelico.com \
    --cc=linux-omap@vger.kernel.org \
    --cc=nikhil.nd@ti.com \
    --cc=nsekhar@ti.com \
    --cc=sebastian.reichel@collabora.com \
    --cc=sre@kernel.org \
    --cc=tomi.valkeinen@ti.com \
    --cc=tony@atomide.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.