forked from mirrors/linux
		
	drm/pl111: Support variants with broken clock divider
The early Integrator CLCD synthesized in the Integrator CP and IM-PD1 FPGAs are broken: their clock dividers do not work properly. Support disabling the clock divider and drive the clock directly from the parent under these circumstances. Reviewed-by: Eric Anholt <eric@anholt.net> Signed-off-by: Linus Walleij <linus.walleij@linaro.org> Link: https://patchwork.freedesktop.org/patch/msgid/20180206093540.8147-3-linus.walleij@linaro.org
This commit is contained in:
		
							parent
							
								
									6470b7ddec
								
							
						
					
					
						commit
						eedd6033b4
					
				
					 3 changed files with 12 additions and 0 deletions
				
			
		|  | @ -138,6 +138,9 @@ static void pl111_display_enable(struct drm_simple_display_pipe *pipe, | ||||||
| 	tim2 = readl(priv->regs + CLCD_TIM2); | 	tim2 = readl(priv->regs + CLCD_TIM2); | ||||||
| 	tim2 &= (TIM2_BCD | TIM2_PCD_LO_MASK | TIM2_PCD_HI_MASK); | 	tim2 &= (TIM2_BCD | TIM2_PCD_LO_MASK | TIM2_PCD_HI_MASK); | ||||||
| 
 | 
 | ||||||
|  | 	if (priv->variant->broken_clockdivider) | ||||||
|  | 		tim2 |= TIM2_BCD; | ||||||
|  | 
 | ||||||
| 	if (mode->flags & DRM_MODE_FLAG_NHSYNC) | 	if (mode->flags & DRM_MODE_FLAG_NHSYNC) | ||||||
| 		tim2 |= TIM2_IHS; | 		tim2 |= TIM2_IHS; | ||||||
| 
 | 
 | ||||||
|  | @ -455,6 +458,11 @@ pl111_init_clock_divider(struct drm_device *drm) | ||||||
| 		dev_err(drm->dev, "CLCD: unable to get clcdclk.\n"); | 		dev_err(drm->dev, "CLCD: unable to get clcdclk.\n"); | ||||||
| 		return PTR_ERR(parent); | 		return PTR_ERR(parent); | ||||||
| 	} | 	} | ||||||
|  | 	/* If the clock divider is broken, use the parent directly */ | ||||||
|  | 	if (priv->variant->broken_clockdivider) { | ||||||
|  | 		priv->clk = parent; | ||||||
|  | 		return 0; | ||||||
|  | 	} | ||||||
| 	parent_name = __clk_get_name(parent); | 	parent_name = __clk_get_name(parent); | ||||||
| 
 | 
 | ||||||
| 	spin_lock_init(&priv->tim2_lock); | 	spin_lock_init(&priv->tim2_lock); | ||||||
|  |  | ||||||
|  | @ -38,6 +38,8 @@ struct drm_minor; | ||||||
|  * @is_pl110: this is the early PL110 variant |  * @is_pl110: this is the early PL110 variant | ||||||
|  * @external_bgr: this is the Versatile Pl110 variant with external |  * @external_bgr: this is the Versatile Pl110 variant with external | ||||||
|  *	BGR/RGB routing |  *	BGR/RGB routing | ||||||
|  |  * @broken_clockdivider: the clock divider is broken and we need to | ||||||
|  |  *	use the supplied clock directly | ||||||
|  * @formats: array of supported pixel formats on this variant |  * @formats: array of supported pixel formats on this variant | ||||||
|  * @nformats: the length of the array of supported pixel formats |  * @nformats: the length of the array of supported pixel formats | ||||||
|  */ |  */ | ||||||
|  | @ -45,6 +47,7 @@ struct pl111_variant_data { | ||||||
| 	const char *name; | 	const char *name; | ||||||
| 	bool is_pl110; | 	bool is_pl110; | ||||||
| 	bool external_bgr; | 	bool external_bgr; | ||||||
|  | 	bool broken_clockdivider; | ||||||
| 	const u32 *formats; | 	const u32 *formats; | ||||||
| 	unsigned int nformats; | 	unsigned int nformats; | ||||||
| }; | }; | ||||||
|  |  | ||||||
|  | @ -237,6 +237,7 @@ static const u32 pl110_versatile_pixel_formats[] = { | ||||||
| static const struct pl111_variant_data pl110_integrator = { | static const struct pl111_variant_data pl110_integrator = { | ||||||
| 	.name = "PL110 Integrator", | 	.name = "PL110 Integrator", | ||||||
| 	.is_pl110 = true, | 	.is_pl110 = true, | ||||||
|  | 	.broken_clockdivider = true, | ||||||
| 	.formats = pl110_integrator_pixel_formats, | 	.formats = pl110_integrator_pixel_formats, | ||||||
| 	.nformats = ARRAY_SIZE(pl110_integrator_pixel_formats), | 	.nformats = ARRAY_SIZE(pl110_integrator_pixel_formats), | ||||||
| }; | }; | ||||||
|  |  | ||||||
		Loading…
	
		Reference in a new issue
	
	 Linus Walleij
						Linus Walleij