[PATCH 1/5 v2] drm/pl111: Properly detect the ARM PL110 variants

Eric Anholt eric at anholt.net
Fri Feb 2 12:51:41 PST 2018


Linus Walleij <linus.walleij at linaro.org> writes:

> With a bit of refactoring we can contain the variant data for
> the strange PL110 versions that is feature-incomplete PL110 for
> the ARM Integrator/CP and somewhere inbetween PL110 and PL111
> for the ARM Versatile AB and Versatile PB.
>
> We also accomodate for the custom duct-taped RGB565/BGR565 support
> in the Versatile variant.
>
> Signed-off-by: Linus Walleij <linus.walleij at linaro.org>
> ---
> ChangeLog v1->v2:
> - Push more logic into the pl111_versatile file and keep the
>   driver core neutral.
> - Pave the way better for the Integrator/CP variant as well.
> ---
>  drivers/gpu/drm/pl111/pl111_drm.h       |  3 ++
>  drivers/gpu/drm/pl111/pl111_drv.c       | 37 ++++----------
>  drivers/gpu/drm/pl111/pl111_versatile.c | 85 +++++++++++++++++++++++++--------
>  3 files changed, 79 insertions(+), 46 deletions(-)
>
> diff --git a/drivers/gpu/drm/pl111/pl111_drm.h b/drivers/gpu/drm/pl111/pl111_drm.h
> index 440f53ebee8c..c2f410f0b12e 100644
> --- a/drivers/gpu/drm/pl111/pl111_drm.h
> +++ b/drivers/gpu/drm/pl111/pl111_drm.h
> @@ -36,12 +36,15 @@ struct drm_minor;
>   * struct pl111_variant_data - encodes IP differences
>   * @name: the name of this variant
>   * @is_pl110: this is the early PL110 variant
> + * @external_bgr: this is the Versatile Pl110 variant with external
> + *	BGR/RGB routing
>   * @formats: array of supported pixel formats on this variant
>   * @nformats: the length of the array of supported pixel formats
>   */
>  struct pl111_variant_data {
>  	const char *name;
>  	bool is_pl110;
> +	bool external_bgr;
>  	const u32 *formats;
>  	unsigned int nformats;
>  };
> diff --git a/drivers/gpu/drm/pl111/pl111_drv.c b/drivers/gpu/drm/pl111/pl111_drv.c
> index 31a0c4268cc6..6967cd5428b2 100644
> --- a/drivers/gpu/drm/pl111/pl111_drv.c
> +++ b/drivers/gpu/drm/pl111/pl111_drv.c
> @@ -205,7 +205,7 @@ static int pl111_amba_probe(struct amba_device *amba_dev,
>  {
>  	struct device *dev = &amba_dev->dev;
>  	struct pl111_drm_dev_private *priv;
> -	struct pl111_variant_data *variant = id->data;
> +	const struct pl111_variant_data *variant = id->data;
>  	struct drm_device *drm;
>  	int ret;
>  
> @@ -221,27 +221,10 @@ static int pl111_amba_probe(struct amba_device *amba_dev,
>  	drm->dev_private = priv;
>  	priv->variant = variant;
>  
> -	/*
> -	 * The PL110 and PL111 variants have two registers
> -	 * swapped: interrupt enable and control. For this reason
> -	 * we use offsets that we can change per variant.
> -	 */
> +	/* The two variants swap this register */
>  	if (variant->is_pl110) {
> -		/*
> -		 * The ARM Versatile boards are even more special:
> -		 * their PrimeCell ID say they are PL110 but the
> -		 * control and interrupt enable registers are anyway
> -		 * swapped to the PL111 order so they are not following
> -		 * the PL110 datasheet.
> -		 */
> -		if (of_machine_is_compatible("arm,versatile-ab") ||
> -		    of_machine_is_compatible("arm,versatile-pb")) {
> -			priv->ienb = CLCD_PL111_IENB;
> -			priv->ctrl = CLCD_PL111_CNTL;
> -		} else {
> -			priv->ienb = CLCD_PL110_IENB;
> -			priv->ctrl = CLCD_PL110_CNTL;
> -		}
> +		priv->ienb = CLCD_PL110_IENB;
> +		priv->ctrl = CLCD_PL110_CNTL;
>  	} else {
>  		priv->ienb = CLCD_PL111_IENB;
>  		priv->ctrl = CLCD_PL111_CNTL;
> @@ -253,6 +236,11 @@ static int pl111_amba_probe(struct amba_device *amba_dev,
>  		return PTR_ERR(priv->regs);
>  	}
>  
> +	/* This may override some variant settings */
> +	ret = pl111_versatile_init(dev, priv);
> +	if (ret)
> +		goto dev_unref;
> +
>  	/* turn off interrupts before requesting the irq */
>  	writel(0, priv->regs + priv->ienb);
>  
> @@ -263,10 +251,6 @@ static int pl111_amba_probe(struct amba_device *amba_dev,
>  		return ret;
>  	}
>  
> -	ret = pl111_versatile_init(dev, priv);
> -	if (ret)
> -		goto dev_unref;
> -
>  	ret = pl111_modeset_init(drm);
>  	if (ret != 0)
>  		goto dev_unref;
> @@ -299,8 +283,7 @@ static int pl111_amba_remove(struct amba_device *amba_dev)
>  }
>  
>  /*
> - * This variant exist in early versions like the ARM Integrator
> - * and this version lacks the 565 and 444 pixel formats.
> + * This early variant lacks the 565 and 444 pixel formats.
>   */
>  static const u32 pl110_pixel_formats[] = {
>  	DRM_FORMAT_ABGR8888,
> diff --git a/drivers/gpu/drm/pl111/pl111_versatile.c b/drivers/gpu/drm/pl111/pl111_versatile.c
> index 97d4af6925a3..893d527fb42f 100644
> --- a/drivers/gpu/drm/pl111/pl111_versatile.c
> +++ b/drivers/gpu/drm/pl111/pl111_versatile.c
> @@ -1,3 +1,4 @@
> +#include <linux/amba/clcd-regs.h>
>  #include <linux/device.h>
>  #include <linux/of.h>
>  #include <linux/regmap.h>
> @@ -64,10 +65,8 @@ static const struct of_device_id versatile_clcd_of_match[] = {
>  #define INTEGRATOR_CLCD_LCDBIASEN	BIT(8)
>  #define INTEGRATOR_CLCD_LCDBIASUP	BIT(9)
>  #define INTEGRATOR_CLCD_LCDBIASDN	BIT(10)
> -/* Bits 11,12,13 controls the LCD type */
> -#define INTEGRATOR_CLCD_LCDMUX_MASK	(BIT(11)|BIT(12)|BIT(13))
> +/* Bits 11,12,13 controls the LCD or VGA bridge type */
>  #define INTEGRATOR_CLCD_LCDMUX_LCD24	BIT(11)
> -#define INTEGRATOR_CLCD_LCDMUX_VGA565	BIT(12)
>  #define INTEGRATOR_CLCD_LCDMUX_SHARP	(BIT(11)|BIT(12))
>  #define INTEGRATOR_CLCD_LCDMUX_VGA555	BIT(13)
>  #define INTEGRATOR_CLCD_LCDMUX_VGA24	(BIT(11)|BIT(12)|BIT(13))
> @@ -82,16 +81,7 @@ static const struct of_device_id versatile_clcd_of_match[] = {
>  /* 0 = 24bit VGA, 1 = 18bit VGA */
>  #define INTEGRATOR_CLCD_LCD_N24BITEN	BIT(19)
>  
> -#define INTEGRATOR_CLCD_MASK		(INTEGRATOR_CLCD_LCDBIASEN | \
> -					 INTEGRATOR_CLCD_LCDBIASUP | \
> -					 INTEGRATOR_CLCD_LCDBIASDN | \
> -					 INTEGRATOR_CLCD_LCDMUX_MASK | \
> -					 INTEGRATOR_CLCD_LCD0_EN | \
> -					 INTEGRATOR_CLCD_LCD1_EN | \
> -					 INTEGRATOR_CLCD_LCD_STATIC1 | \
> -					 INTEGRATOR_CLCD_LCD_STATIC2 | \
> -					 INTEGRATOR_CLCD_LCD_STATIC | \
> -					 INTEGRATOR_CLCD_LCD_N24BITEN)
> +#define INTEGRATOR_CLCD_MASK		GENMASK(19,8)
>  
>  static void pl111_integrator_enable(struct drm_device *drm, u32 format)
>  {
> @@ -106,11 +96,8 @@ static void pl111_integrator_enable(struct drm_device *drm, u32 format)
>  	switch (format) {
>  	case DRM_FORMAT_XBGR8888:
>  	case DRM_FORMAT_XRGB8888:
> -		break;
> -	case DRM_FORMAT_BGR565:
> -	case DRM_FORMAT_RGB565:
> -		/* truecolor RGB565 */
> -		val |= INTEGRATOR_CLCD_LCDMUX_VGA565;
> +		/* 24bit formats */
> +		val |= INTEGRATOR_CLCD_LCDMUX_VGA24;
>  		break;
>  	case DRM_FORMAT_XBGR1555:
>  	case DRM_FORMAT_XRGB1555:
> @@ -217,6 +204,55 @@ static void pl111_realview_clcd_enable(struct drm_device *drm, u32 format)
>  			   SYS_CLCD_NLCDIOON | SYS_CLCD_PWR3V5SWITCH);
>  }
>  
> +/* PL110 pixel formats for Integrator, vanilla PL110 */
> +static const u32 pl110_integrator_pixel_formats[] = {
> +	DRM_FORMAT_ABGR8888,
> +	DRM_FORMAT_XBGR8888,
> +	DRM_FORMAT_ARGB8888,
> +	DRM_FORMAT_XRGB8888,
> +	DRM_FORMAT_ABGR1555,
> +	DRM_FORMAT_XBGR1555,
> +	DRM_FORMAT_ARGB1555,
> +	DRM_FORMAT_XRGB1555,
> +};
> +
> +/* Extended PL110 pixel formats for Integrator and Versatile */
> +static const u32 pl110_versatile_pixel_formats[] = {
> +	DRM_FORMAT_ABGR8888,
> +	DRM_FORMAT_XBGR8888,
> +	DRM_FORMAT_ARGB8888,
> +	DRM_FORMAT_XRGB8888,
> +	DRM_FORMAT_BGR565, /* Uses external PLD */
> +	DRM_FORMAT_RGB565, /* Uses external PLD */
> +	DRM_FORMAT_ABGR1555,
> +	DRM_FORMAT_XBGR1555,
> +	DRM_FORMAT_ARGB1555,
> +	DRM_FORMAT_XRGB1555,
> +};
> +
> +/*
> + * The Integrator variant is a PL110 with a bunch of broken, or not
> + * yet implemented features
> + */
> +static const struct pl111_variant_data pl110_integrator = {
> +	.name = "PL110 Integrator",
> +	.is_pl110 = true,
> +	.formats = pl110_integrator_pixel_formats,
> +	.nformats = ARRAY_SIZE(pl110_integrator_pixel_formats),
> +};
> +
> +/*
> + * This is the in-between PL110 variant found in the ARM Versatile,
> + * supporting RGB565/BGR565
> + */
> +static const struct pl111_variant_data pl110_versatile = {
> +	.name = "PL110 Versatile",
> +	.is_pl110 = true,
> +	.external_bgr = true,
> +	.formats = pl110_versatile_pixel_formats,
> +	.nformats = ARRAY_SIZE(pl110_versatile_pixel_formats),
> +};
> +
>  int pl111_versatile_init(struct device *dev, struct pl111_drm_dev_private *priv)
>  {
>  	const struct of_device_id *clcd_id;
> @@ -241,14 +277,25 @@ int pl111_versatile_init(struct device *dev, struct pl111_drm_dev_private *priv)
>  	switch (versatile_clcd_type) {
>  	case INTEGRATOR_CLCD_CM:
>  		versatile_syscon_map = map;
> +		/* This can do RGB565 with external PLD */

I don't think you meant to have this comment here, since RGB565 isn't in
integrator's format lits.  Other than that, the patch gets my r-b.

> +		priv->variant = &pl110_integrator;
>  		priv->variant_display_enable = pl111_integrator_enable;
>  		dev_info(dev, "set up callbacks for Integrator PL110\n");
>  		break;
>  	case VERSATILE_CLCD:
>  		versatile_syscon_map = map;
> +		/* This can do RGB565 with external PLD */
> +		priv->variant = &pl110_versatile;
>  		priv->variant_display_enable = pl111_versatile_enable;
>  		priv->variant_display_disable = pl111_versatile_disable;
> -		dev_info(dev, "set up callbacks for Versatile PL110+\n");
> +		/*
> +		 * The Versatile has a variant halfway between PL110
> +		 * and PL111 where these two registers have already been
> +		 * swapped.
> +		 */
> +		priv->ienb = CLCD_PL111_IENB;
> +		priv->ctrl = CLCD_PL111_CNTL;
> +		dev_info(dev, "set up callbacks for Versatile PL110\n");
>  		break;
>  	case REALVIEW_CLCD_EB:
>  	case REALVIEW_CLCD_PB1176:
> -- 
> 2.14.3
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 832 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20180202/9704ba2e/attachment.sig>


More information about the linux-arm-kernel mailing list