devicetree.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Stefan Agner <stefan@agner.ch>
To: Robert Chiras <robert.chiras@nxp.com>
Cc: "Marek Vasut" <marex@denx.de>,
	"Mark Rutland" <mark.rutland@arm.com>,
	"Pengutronix Kernel Team" <kernel@pengutronix.de>,
	devicetree@vger.kernel.org, "David Airlie" <airlied@linux.ie>,
	"Guido Günther" <agx@sigxcpu.org>,
	linux-kernel@vger.kernel.org, dri-devel@lists.freedesktop.org,
	"Rob Herring" <robh+dt@kernel.org>,
	"NXP Linux Team" <linux-imx@nxp.com>,
	"Shawn Guo" <shawnguo@kernel.org>,
	"Sascha Hauer" <s.hauer@pengutronix.de>,
	linux-arm-kernel@lists.infradead.org
Subject: Re: [PATCH v4 01/14] drm/mxsfb: Update mxsfb to support a bridge
Date: Mon, 14 Oct 2019 22:23:20 +0200	[thread overview]
Message-ID: <4138bd0cea847abb60888a50236c2aa4@agner.ch> (raw)
In-Reply-To: <1567078215-31601-2-git-send-email-robert.chiras@nxp.com>

On 2019-08-29 13:30, Robert Chiras wrote:
> Currently, the MXSFB DRM driver only supports a panel. But, its output
> display signal can also be redirected to another encoder, like a DSI
> controller. In this case, that DSI controller may act like a drm_bridge.
> In order support this use-case too, this patch adds support for drm_bridge
> in mxsfb.
> 
> Signed-off-by: Robert Chiras <robert.chiras@nxp.com>
> Tested-by: Guido Günther <agx@sigxcpu.org>

Applied to the drm-misc-next branch.

--
Stefan

> ---
>  drivers/gpu/drm/mxsfb/mxsfb_crtc.c | 17 +++++++++++---
>  drivers/gpu/drm/mxsfb/mxsfb_drv.c  | 46 +++++++++++++++++++++++++++++++++-----
>  drivers/gpu/drm/mxsfb/mxsfb_drv.h  |  4 +++-
>  drivers/gpu/drm/mxsfb/mxsfb_out.c  | 26 +++++++++++----------
>  4 files changed, 72 insertions(+), 21 deletions(-)
> 
> diff --git a/drivers/gpu/drm/mxsfb/mxsfb_crtc.c
> b/drivers/gpu/drm/mxsfb/mxsfb_crtc.c
> index 1242156..de09b93 100644
> --- a/drivers/gpu/drm/mxsfb/mxsfb_crtc.c
> +++ b/drivers/gpu/drm/mxsfb/mxsfb_crtc.c
> @@ -95,8 +95,11 @@ static void mxsfb_set_bus_fmt(struct
> mxsfb_drm_private *mxsfb)
>  
>  	reg = readl(mxsfb->base + LCDC_CTRL);
>  
> -	if (mxsfb->connector.display_info.num_bus_formats)
> -		bus_format = mxsfb->connector.display_info.bus_formats[0];
> +	if (mxsfb->connector->display_info.num_bus_formats)
> +		bus_format = mxsfb->connector->display_info.bus_formats[0];
> +
> +	DRM_DEV_DEBUG_DRIVER(drm->dev, "Using bus_format: 0x%08X\n",
> +			     bus_format);
>  
>  	reg &= ~CTRL_BUS_WIDTH_MASK;
>  	switch (bus_format) {
> @@ -204,8 +207,9 @@ static dma_addr_t mxsfb_get_fb_paddr(struct
> mxsfb_drm_private *mxsfb)
>  
>  static void mxsfb_crtc_mode_set_nofb(struct mxsfb_drm_private *mxsfb)
>  {
> +	struct drm_device *drm = mxsfb->pipe.crtc.dev;
>  	struct drm_display_mode *m = &mxsfb->pipe.crtc.state->adjusted_mode;
> -	const u32 bus_flags = mxsfb->connector.display_info.bus_flags;
> +	const u32 bus_flags = mxsfb->connector->display_info.bus_flags;
>  	u32 vdctrl0, vsync_pulse_len, hsync_pulse_len;
>  	int err;
>  
> @@ -229,6 +233,13 @@ static void mxsfb_crtc_mode_set_nofb(struct
> mxsfb_drm_private *mxsfb)
>  
>  	clk_set_rate(mxsfb->clk, m->crtc_clock * 1000);
>  
> +	DRM_DEV_DEBUG_DRIVER(drm->dev, "Pixel clock: %dkHz (actual: %dkHz)\n",
> +			     m->crtc_clock,
> +			     (int)(clk_get_rate(mxsfb->clk) / 1000));
> +	DRM_DEV_DEBUG_DRIVER(drm->dev, "Connector bus_flags: 0x%08X\n",
> +			     bus_flags);
> +	DRM_DEV_DEBUG_DRIVER(drm->dev, "Mode flags: 0x%08X\n", m->flags);
> +
>  	writel(TRANSFER_COUNT_SET_VCOUNT(m->crtc_vdisplay) |
>  	       TRANSFER_COUNT_SET_HCOUNT(m->crtc_hdisplay),
>  	       mxsfb->base + mxsfb->devdata->transfer_count);
> diff --git a/drivers/gpu/drm/mxsfb/mxsfb_drv.c
> b/drivers/gpu/drm/mxsfb/mxsfb_drv.c
> index e850633..497cf44 100644
> --- a/drivers/gpu/drm/mxsfb/mxsfb_drv.c
> +++ b/drivers/gpu/drm/mxsfb/mxsfb_drv.c
> @@ -101,9 +101,25 @@ static void mxsfb_pipe_enable(struct
> drm_simple_display_pipe *pipe,
>  			      struct drm_crtc_state *crtc_state,
>  			      struct drm_plane_state *plane_state)
>  {
> +	struct drm_connector *connector;
>  	struct mxsfb_drm_private *mxsfb = drm_pipe_to_mxsfb_drm_private(pipe);
>  	struct drm_device *drm = pipe->plane.dev;
>  
> +	if (!mxsfb->connector) {
> +		list_for_each_entry(connector,
> +				    &drm->mode_config.connector_list,
> +				    head)
> +			if (connector->encoder == &mxsfb->pipe.encoder) {
> +				mxsfb->connector = connector;
> +				break;
> +			}
> +	}
> +
> +	if (!mxsfb->connector) {
> +		dev_warn(drm->dev, "No connector attached, using default\n");
> +		mxsfb->connector = &mxsfb->panel_connector;
> +	}
> +
>  	pm_runtime_get_sync(drm->dev);
>  	drm_panel_prepare(mxsfb->panel);
>  	mxsfb_crtc_enable(mxsfb);
> @@ -129,6 +145,9 @@ static void mxsfb_pipe_disable(struct
> drm_simple_display_pipe *pipe)
>  		drm_crtc_send_vblank_event(crtc, event);
>  	}
>  	spin_unlock_irq(&drm->event_lock);
> +
> +	if (mxsfb->connector != &mxsfb->panel_connector)
> +		mxsfb->connector = NULL;
>  }
>  
>  static void mxsfb_pipe_update(struct drm_simple_display_pipe *pipe,
> @@ -226,16 +245,33 @@ static int mxsfb_load(struct drm_device *drm,
> unsigned long flags)
>  
>  	ret = drm_simple_display_pipe_init(drm, &mxsfb->pipe, &mxsfb_funcs,
>  			mxsfb_formats, ARRAY_SIZE(mxsfb_formats), NULL,
> -			&mxsfb->connector);
> +			mxsfb->connector);
>  	if (ret < 0) {
>  		dev_err(drm->dev, "Cannot setup simple display pipe\n");
>  		goto err_vblank;
>  	}
>  
> -	ret = drm_panel_attach(mxsfb->panel, &mxsfb->connector);
> -	if (ret) {
> -		dev_err(drm->dev, "Cannot connect panel\n");
> -		goto err_vblank;
> +	/*
> +	 * Attach panel only if there is one.
> +	 * If there is no panel attach, it must be a bridge. In this case, we
> +	 * need a reference to its connector for a proper initialization.
> +	 * We will do this check in pipe->enable(), since the connector won't
> +	 * be attached to an encoder until then.
> +	 */
> +
> +	if (mxsfb->panel) {
> +		ret = drm_panel_attach(mxsfb->panel, mxsfb->connector);
> +		if (ret) {
> +			dev_err(drm->dev, "Cannot connect panel: %d\n", ret);
> +			goto err_vblank;
> +		}
> +	} else if (mxsfb->bridge) {
> +		ret = drm_simple_display_pipe_attach_bridge(&mxsfb->pipe,
> +							    mxsfb->bridge);
> +		if (ret) {
> +			dev_err(drm->dev, "Cannot connect bridge: %d\n", ret);
> +			goto err_vblank;
> +		}
>  	}
>  
>  	drm->mode_config.min_width	= MXSFB_MIN_XRES;
> diff --git a/drivers/gpu/drm/mxsfb/mxsfb_drv.h
> b/drivers/gpu/drm/mxsfb/mxsfb_drv.h
> index d975300..0b65b51 100644
> --- a/drivers/gpu/drm/mxsfb/mxsfb_drv.h
> +++ b/drivers/gpu/drm/mxsfb/mxsfb_drv.h
> @@ -27,8 +27,10 @@ struct mxsfb_drm_private {
>  	struct clk			*clk_disp_axi;
>  
>  	struct drm_simple_display_pipe	pipe;
> -	struct drm_connector		connector;
> +	struct drm_connector		panel_connector;
> +	struct drm_connector		*connector;
>  	struct drm_panel		*panel;
> +	struct drm_bridge		*bridge;
>  };
>  
>  int mxsfb_setup_crtc(struct drm_device *dev);
> diff --git a/drivers/gpu/drm/mxsfb/mxsfb_out.c
> b/drivers/gpu/drm/mxsfb/mxsfb_out.c
> index be36f4d..4eb9474 100644
> --- a/drivers/gpu/drm/mxsfb/mxsfb_out.c
> +++ b/drivers/gpu/drm/mxsfb/mxsfb_out.c
> @@ -21,7 +21,8 @@
>  static struct mxsfb_drm_private *
>  drm_connector_to_mxsfb_drm_private(struct drm_connector *connector)
>  {
> -	return container_of(connector, struct mxsfb_drm_private, connector);
> +	return container_of(connector, struct mxsfb_drm_private,
> +			    panel_connector);
>  }
>  
>  static int mxsfb_panel_get_modes(struct drm_connector *connector)
> @@ -76,22 +77,23 @@ static const struct drm_connector_funcs
> mxsfb_panel_connector_funcs = {
>  int mxsfb_create_output(struct drm_device *drm)
>  {
>  	struct mxsfb_drm_private *mxsfb = drm->dev_private;
> -	struct drm_panel *panel;
>  	int ret;
>  
> -	ret = drm_of_find_panel_or_bridge(drm->dev->of_node, 0, 0, &panel, NULL);
> +	ret = drm_of_find_panel_or_bridge(drm->dev->of_node, 0, 0,
> +					  &mxsfb->panel, &mxsfb->bridge);
>  	if (ret)
>  		return ret;
>  
> -	mxsfb->connector.dpms = DRM_MODE_DPMS_OFF;
> -	mxsfb->connector.polled = 0;
> -	drm_connector_helper_add(&mxsfb->connector,
> -			&mxsfb_panel_connector_helper_funcs);
> -	ret = drm_connector_init(drm, &mxsfb->connector,
> -				 &mxsfb_panel_connector_funcs,
> -				 DRM_MODE_CONNECTOR_Unknown);
> -	if (!ret)
> -		mxsfb->panel = panel;
> +	if (mxsfb->panel) {
> +		mxsfb->connector = &mxsfb->panel_connector;
> +		mxsfb->connector->dpms = DRM_MODE_DPMS_OFF;
> +		mxsfb->connector->polled = 0;
> +		drm_connector_helper_add(mxsfb->connector,
> +					 &mxsfb_panel_connector_helper_funcs);
> +		ret = drm_connector_init(drm, mxsfb->connector,
> +					 &mxsfb_panel_connector_funcs,
> +					 DRM_MODE_CONNECTOR_Unknown);
> +	}
>  
>  	return ret;
>  }
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

  reply	other threads:[~2019-10-14 20:23 UTC|newest]

Thread overview: 22+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-08-29 11:30 [PATCH v4 00/14] Improvements and fixes for mxsfb DRM driver Robert Chiras
2019-08-29 11:30 ` [PATCH v4 01/14] drm/mxsfb: Update mxsfb to support a bridge Robert Chiras
2019-10-14 20:23   ` Stefan Agner [this message]
2019-08-29 11:30 ` [PATCH v4 02/14] drm/mxsfb: Read bus flags from bridge if present Robert Chiras
2019-10-14 20:24   ` Stefan Agner
2019-08-29 11:30 ` [PATCH v4 03/14] drm/mxsfb: Add defines for the rest of registers Robert Chiras
2019-08-29 11:30 ` [PATCH v4 04/14] drm/mxsfb: Reset vital registers for a proper initialization Robert Chiras
2019-10-14 12:59   ` Stefan Agner
2019-08-29 11:30 ` [PATCH v4 05/14] drm/mxsfb: Update register definitions using bit manipulation defines Robert Chiras
2019-10-14 13:05   ` Stefan Agner
2019-08-29 11:30 ` [PATCH v4 06/14] drm/mxsfb: Update mxsfb with additional pixel formats Robert Chiras
2019-11-05 21:42   ` Laurent Pinchart
2019-08-29 11:30 ` [PATCH v4 07/14] drm/mxsfb: Signal mode changed when bpp changed Robert Chiras
2019-08-29 11:30 ` [PATCH v4 08/14] drm/mxsfb: Add max-memory-bandwidth property for MXSFB Robert Chiras
2019-08-29 11:30 ` [PATCH v4 09/14] dt-bindings: display: Add max-memory-bandwidth property for mxsfb Robert Chiras
2019-08-29 11:30 ` [PATCH v4 10/14] drm/mxsfb: Update mxsfb to support LCD reset Robert Chiras
2019-08-29 11:30 ` [PATCH v4 11/14] drm/mxsfb: Improve the axi clock usage Robert Chiras
2019-08-29 11:30 ` [PATCH v4 12/14] drm/mxsfb: Clear OUTSTANDING_REQS bits Robert Chiras
2019-08-29 11:30 ` [PATCH v4 13/14] drm/mxsfb: Add support for horizontal stride Robert Chiras
2019-10-14 12:40   ` Stefan Agner
2019-11-05 22:12     ` Laurent Pinchart
2019-08-29 11:30 ` [PATCH v4 14/14] drm/mxsfb: Add support for live pixel format change Robert Chiras

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=4138bd0cea847abb60888a50236c2aa4@agner.ch \
    --to=stefan@agner.ch \
    --cc=agx@sigxcpu.org \
    --cc=airlied@linux.ie \
    --cc=devicetree@vger.kernel.org \
    --cc=dri-devel@lists.freedesktop.org \
    --cc=kernel@pengutronix.de \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-imx@nxp.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=marex@denx.de \
    --cc=mark.rutland@arm.com \
    --cc=robert.chiras@nxp.com \
    --cc=robh+dt@kernel.org \
    --cc=s.hauer@pengutronix.de \
    --cc=shawnguo@kernel.org \
    /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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).