[PATCH 4/4 v7] drm/pl111: Support handling bridge timings

Archit Taneja architt at codeaurora.org
Fri Jan 12 01:25:44 PST 2018



On 01/12/2018 01:18 PM, Linus Walleij wrote:
> If the bridge has a too strict setup time for the incoming
> signals, we may not be fast enough and then we need to
> compensate by outputting the signal on the inverse clock
> edge so it is for sure stable when the bridge samples it.
> 
> Since bridges in difference to panels does not expose their
> connectors, make the connector optional in the display
> setup code.
> 

Since Eric has already Ack'ed it, queued to drm-misc-next so that
the commits stay together.

Thanks,
Archit

> Acked-by: Laurent Pinchart <laurent.pinchart at ideasonboard.com>
> Reviewed-by: Eric Anholt <eric at anholt.net>
> Signed-off-by: Linus Walleij <linus.walleij at linaro.org>
> ---
> ChangeLog v6->v7:
> - Collect Eric's ACK.
> ChangeLog v5->v6:
> - Collect Laurent's ACK.
> ChangeLog v4->v5:
> - Use the new bridge timings setup method.
> ---
>   drivers/gpu/drm/pl111/Kconfig         |  1 +
>   drivers/gpu/drm/pl111/pl111_display.c | 35 +++++++++++++++++++++++++++++++----
>   drivers/gpu/drm/pl111/pl111_drv.c     | 20 +++++++++++---------
>   3 files changed, 43 insertions(+), 13 deletions(-)
> 
> diff --git a/drivers/gpu/drm/pl111/Kconfig b/drivers/gpu/drm/pl111/Kconfig
> index e5e2abd66491..82cb3e60ddc8 100644
> --- a/drivers/gpu/drm/pl111/Kconfig
> +++ b/drivers/gpu/drm/pl111/Kconfig
> @@ -8,6 +8,7 @@ config DRM_PL111
>   	select DRM_GEM_CMA_HELPER
>   	select DRM_BRIDGE
>   	select DRM_PANEL_BRIDGE
> +	select DRM_DUMB_VGA_DAC
>   	select VT_HW_CONSOLE_BINDING if FRAMEBUFFER_CONSOLE
>   	help
>   	  Choose this option for DRM support for the PL111 CLCD controller.
> diff --git a/drivers/gpu/drm/pl111/pl111_display.c b/drivers/gpu/drm/pl111/pl111_display.c
> index 06c4bf756b69..7fe4040aea46 100644
> --- a/drivers/gpu/drm/pl111/pl111_display.c
> +++ b/drivers/gpu/drm/pl111/pl111_display.c
> @@ -94,6 +94,7 @@ static void pl111_display_enable(struct drm_simple_display_pipe *pipe,
>   	const struct drm_display_mode *mode = &cstate->mode;
>   	struct drm_framebuffer *fb = plane->state->fb;
>   	struct drm_connector *connector = priv->connector;
> +	struct drm_bridge *bridge = priv->bridge;
>   	u32 cntl;
>   	u32 ppl, hsw, hfp, hbp;
>   	u32 lpp, vsw, vfp, vbp;
> @@ -143,11 +144,37 @@ static void pl111_display_enable(struct drm_simple_display_pipe *pipe,
>   	if (mode->flags & DRM_MODE_FLAG_NVSYNC)
>   		tim2 |= TIM2_IVS;
>   
> -	if (connector->display_info.bus_flags & DRM_BUS_FLAG_DE_LOW)
> -		tim2 |= TIM2_IOE;
> +	if (connector) {
> +		if (connector->display_info.bus_flags & DRM_BUS_FLAG_DE_LOW)
> +			tim2 |= TIM2_IOE;
>   
> -	if (connector->display_info.bus_flags & DRM_BUS_FLAG_PIXDATA_NEGEDGE)
> -		tim2 |= TIM2_IPC;
> +		if (connector->display_info.bus_flags &
> +		    DRM_BUS_FLAG_PIXDATA_NEGEDGE)
> +			tim2 |= TIM2_IPC;
> +	}
> +
> +	if (bridge) {
> +		const struct drm_bridge_timings *btimings = bridge->timings;
> +
> +		/*
> +		 * Here is when things get really fun. Sometimes the bridge
> +		 * timings are such that the signal out from PL11x is not
> +		 * stable before the receiving bridge (such as a dumb VGA DAC
> +		 * or similar) samples it. If that happens, we compensate by
> +		 * the only method we have: output the data on the opposite
> +		 * edge of the clock so it is for sure stable when it gets
> +		 * sampled.
> +		 *
> +		 * The PL111 manual does not contain proper timining diagrams
> +		 * or data for these details, but we know from experiments
> +		 * that the setup time is more than 3000 picoseconds (3 ns).
> +		 * If we have a bridge that requires the signal to be stable
> +		 * earlier than 3000 ps before the clock pulse, we have to
> +		 * output the data on the opposite edge to avoid flicker.
> +		 */
> +		if (btimings && btimings->setup_time_ps >= 3000)
> +			tim2 ^= TIM2_IPC;
> +	}
>   
>   	tim2 |= cpl << 16;
>   	writel(tim2, priv->regs + CLCD_TIM2);
> diff --git a/drivers/gpu/drm/pl111/pl111_drv.c b/drivers/gpu/drm/pl111/pl111_drv.c
> index 201d57d5cb54..101a9c7db6ff 100644
> --- a/drivers/gpu/drm/pl111/pl111_drv.c
> +++ b/drivers/gpu/drm/pl111/pl111_drv.c
> @@ -107,11 +107,17 @@ static int pl111_modeset_init(struct drm_device *dev)
>   			ret = PTR_ERR(bridge);
>   			goto out_config;
>   		}
> -		/*
> -		 * TODO: when we are using a different bridge than a panel
> -		 * (such as a dumb VGA connector) we need to devise a different
> -		 * method to get the connector out of the bridge.
> -		 */
> +	} else if (bridge) {
> +		dev_info(dev->dev, "Using non-panel bridge\n");
> +	} else {
> +		dev_err(dev->dev, "No bridge, exiting\n");
> +		return -ENODEV;
> +	}
> +
> +	priv->bridge = bridge;
> +	if (panel) {
> +		priv->panel = panel;
> +		priv->connector = panel->connector;
>   	}
>   
>   	ret = pl111_display_init(dev);
> @@ -125,10 +131,6 @@ static int pl111_modeset_init(struct drm_device *dev)
>   	if (ret)
>   		return ret;
>   
> -	priv->bridge = bridge;
> -	priv->panel = panel;
> -	priv->connector = panel->connector;
> -
>   	ret = drm_vblank_init(dev, 1);
>   	if (ret != 0) {
>   		dev_err(dev->dev, "Failed to init vblank\n");
> 

-- 
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project



More information about the linux-arm-kernel mailing list