mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 10:40:15 +02:00 
			
		
		
		
	drm/omap: Call dispc timings check operation directly
Instead of call the dispc timings check function dispc_mgr_timings_ok() from the internal encoders .check_timings() operation, expose it through the dispc ops (after renaming it to check_timings) and call it directly from omapdrm. This allows removal of now empty omap_dss_device .check_timings() operations. Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Sebastian Reichel <sebastian.reichel@collabora.co.uk> Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
This commit is contained in:
		
							parent
							
								
									3fbda31e81
								
							
						
					
					
						commit
						7c27fa57ef
					
				
					 9 changed files with 32 additions and 50 deletions
				
			
		| 
						 | 
				
			
			@ -3113,28 +3113,29 @@ static bool _dispc_mgr_pclk_ok(struct dispc_device *dispc,
 | 
			
		|||
		return pclk <= dispc->feat->max_tv_pclk;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool dispc_mgr_timings_ok(struct dispc_device *dispc, enum omap_channel channel,
 | 
			
		||||
			  const struct videomode *vm)
 | 
			
		||||
static int dispc_mgr_check_timings(struct dispc_device *dispc,
 | 
			
		||||
				   enum omap_channel channel,
 | 
			
		||||
				   const struct videomode *vm)
 | 
			
		||||
{
 | 
			
		||||
	if (!_dispc_mgr_size_ok(dispc, vm->hactive, vm->vactive))
 | 
			
		||||
		return false;
 | 
			
		||||
		return MODE_BAD;
 | 
			
		||||
 | 
			
		||||
	if (!_dispc_mgr_pclk_ok(dispc, channel, vm->pixelclock))
 | 
			
		||||
		return false;
 | 
			
		||||
		return MODE_BAD;
 | 
			
		||||
 | 
			
		||||
	if (dss_mgr_is_lcd(channel)) {
 | 
			
		||||
		/* TODO: OMAP4+ supports interlace for LCD outputs */
 | 
			
		||||
		if (vm->flags & DISPLAY_FLAGS_INTERLACED)
 | 
			
		||||
			return false;
 | 
			
		||||
			return MODE_BAD;
 | 
			
		||||
 | 
			
		||||
		if (!_dispc_lcd_timings_ok(dispc, vm->hsync_len,
 | 
			
		||||
				vm->hfront_porch, vm->hback_porch,
 | 
			
		||||
				vm->vsync_len, vm->vfront_porch,
 | 
			
		||||
				vm->vback_porch))
 | 
			
		||||
			return false;
 | 
			
		||||
			return MODE_BAD;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return true;
 | 
			
		||||
	return MODE_OK;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void _dispc_mgr_set_lcd_timings(struct dispc_device *dispc,
 | 
			
		||||
| 
						 | 
				
			
			@ -3236,7 +3237,7 @@ static void dispc_mgr_set_timings(struct dispc_device *dispc,
 | 
			
		|||
 | 
			
		||||
	DSSDBG("channel %d xres %u yres %u\n", channel, t.hactive, t.vactive);
 | 
			
		||||
 | 
			
		||||
	if (!dispc_mgr_timings_ok(dispc, channel, &t)) {
 | 
			
		||||
	if (dispc_mgr_check_timings(dispc, channel, &t)) {
 | 
			
		||||
		BUG();
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			@ -4733,6 +4734,7 @@ static const struct dispc_ops dispc_ops = {
 | 
			
		|||
	.mgr_go_busy = dispc_mgr_go_busy,
 | 
			
		||||
	.mgr_go = dispc_mgr_go,
 | 
			
		||||
	.mgr_set_lcd_config = dispc_mgr_set_lcd_config,
 | 
			
		||||
	.mgr_check_timings = dispc_mgr_check_timings,
 | 
			
		||||
	.mgr_set_timings = dispc_mgr_set_timings,
 | 
			
		||||
	.mgr_setup = dispc_mgr_setup,
 | 
			
		||||
	.mgr_gamma_size = dispc_mgr_gamma_size,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -496,7 +496,6 @@ static int dpi_check_timings(struct omap_dss_device *dssdev,
 | 
			
		|||
			     struct videomode *vm)
 | 
			
		||||
{
 | 
			
		||||
	struct dpi_data *dpi = dpi_get_data_from_dssdev(dssdev);
 | 
			
		||||
	enum omap_channel channel = dpi->output.dispc_channel;
 | 
			
		||||
	int lck_div, pck_div;
 | 
			
		||||
	unsigned long fck;
 | 
			
		||||
	unsigned long pck;
 | 
			
		||||
| 
						 | 
				
			
			@ -506,9 +505,6 @@ static int dpi_check_timings(struct omap_dss_device *dssdev,
 | 
			
		|||
	if (vm->hactive % 8 != 0)
 | 
			
		||||
		return -EINVAL;
 | 
			
		||||
 | 
			
		||||
	if (!dispc_mgr_timings_ok(dpi->dss->dispc, channel, vm))
 | 
			
		||||
		return -EINVAL;
 | 
			
		||||
 | 
			
		||||
	if (vm->pixelclock == 0)
 | 
			
		||||
		return -EINVAL;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -417,9 +417,6 @@ bool dispc_div_calc(struct dispc_device *dispc, unsigned long dispc_freq,
 | 
			
		|||
		    unsigned long pck_min, unsigned long pck_max,
 | 
			
		||||
		    dispc_div_calc_func func, void *data);
 | 
			
		||||
 | 
			
		||||
bool dispc_mgr_timings_ok(struct dispc_device *dispc,
 | 
			
		||||
			  enum omap_channel channel,
 | 
			
		||||
			  const struct videomode *vm);
 | 
			
		||||
int dispc_calc_clock_rates(struct dispc_device *dispc,
 | 
			
		||||
			   unsigned long dispc_fclk_rate,
 | 
			
		||||
			   struct dispc_clock_info *cinfo);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -251,17 +251,6 @@ static void hdmi_power_off_full(struct omap_hdmi *hdmi)
 | 
			
		|||
	hdmi_power_off_core(hdmi);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int hdmi_display_check_timings(struct omap_dss_device *dssdev,
 | 
			
		||||
				      struct videomode *vm)
 | 
			
		||||
{
 | 
			
		||||
	struct omap_hdmi *hdmi = dssdev_to_hdmi(dssdev);
 | 
			
		||||
 | 
			
		||||
	if (!dispc_mgr_timings_ok(hdmi->dss->dispc, dssdev->dispc_channel, vm))
 | 
			
		||||
		return -EINVAL;
 | 
			
		||||
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void hdmi_display_set_timings(struct omap_dss_device *dssdev,
 | 
			
		||||
				     const struct videomode *vm)
 | 
			
		||||
{
 | 
			
		||||
| 
						 | 
				
			
			@ -508,7 +497,6 @@ static const struct omap_dss_device_ops hdmi_ops = {
 | 
			
		|||
	.enable			= hdmi_display_enable,
 | 
			
		||||
	.disable		= hdmi_display_disable,
 | 
			
		||||
 | 
			
		||||
	.check_timings		= hdmi_display_check_timings,
 | 
			
		||||
	.set_timings		= hdmi_display_set_timings,
 | 
			
		||||
 | 
			
		||||
	.read_edid		= hdmi_read_edid,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -250,17 +250,6 @@ static void hdmi_power_off_full(struct omap_hdmi *hdmi)
 | 
			
		|||
	hdmi_power_off_core(hdmi);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int hdmi_display_check_timings(struct omap_dss_device *dssdev,
 | 
			
		||||
				      struct videomode *vm)
 | 
			
		||||
{
 | 
			
		||||
	struct omap_hdmi *hdmi = dssdev_to_hdmi(dssdev);
 | 
			
		||||
 | 
			
		||||
	if (!dispc_mgr_timings_ok(hdmi->dss->dispc, dssdev->dispc_channel, vm))
 | 
			
		||||
		return -EINVAL;
 | 
			
		||||
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void hdmi_display_set_timings(struct omap_dss_device *dssdev,
 | 
			
		||||
				     const struct videomode *vm)
 | 
			
		||||
{
 | 
			
		||||
| 
						 | 
				
			
			@ -502,7 +491,6 @@ static const struct omap_dss_device_ops hdmi_ops = {
 | 
			
		|||
	.enable			= hdmi_display_enable,
 | 
			
		||||
	.disable		= hdmi_display_disable,
 | 
			
		||||
 | 
			
		||||
	.check_timings		= hdmi_display_check_timings,
 | 
			
		||||
	.set_timings		= hdmi_display_set_timings,
 | 
			
		||||
 | 
			
		||||
	.read_edid		= hdmi_read_edid,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -608,6 +608,9 @@ struct dispc_ops {
 | 
			
		|||
	void (*mgr_set_lcd_config)(struct dispc_device *dispc,
 | 
			
		||||
				   enum omap_channel channel,
 | 
			
		||||
				   const struct dss_lcd_mgr_config *config);
 | 
			
		||||
	int (*mgr_check_timings)(struct dispc_device *dispc,
 | 
			
		||||
				 enum omap_channel channel,
 | 
			
		||||
				 const struct videomode *vm);
 | 
			
		||||
	void (*mgr_set_timings)(struct dispc_device *dispc,
 | 
			
		||||
				enum omap_channel channel,
 | 
			
		||||
				const struct videomode *vm);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -237,12 +237,6 @@ static void sdi_set_timings(struct omap_dss_device *dssdev,
 | 
			
		|||
static int sdi_check_timings(struct omap_dss_device *dssdev,
 | 
			
		||||
			     struct videomode *vm)
 | 
			
		||||
{
 | 
			
		||||
	struct sdi_device *sdi = dssdev_to_sdi(dssdev);
 | 
			
		||||
	enum omap_channel channel = dssdev->dispc_channel;
 | 
			
		||||
 | 
			
		||||
	if (!dispc_mgr_timings_ok(sdi->dss->dispc, channel, vm))
 | 
			
		||||
		return -EINVAL;
 | 
			
		||||
 | 
			
		||||
	if (vm->pixelclock == 0)
 | 
			
		||||
		return -EINVAL;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -268,6 +268,8 @@ static int omap_connector_mode_valid(struct drm_connector *connector,
 | 
			
		|||
				 struct drm_display_mode *mode)
 | 
			
		||||
{
 | 
			
		||||
	struct omap_connector *omap_connector = to_omap_connector(connector);
 | 
			
		||||
	enum omap_channel channel = omap_connector->output->dispc_channel;
 | 
			
		||||
	struct omap_drm_private *priv = connector->dev->dev_private;
 | 
			
		||||
	struct omap_dss_device *dssdev;
 | 
			
		||||
	struct videomode vm = {0};
 | 
			
		||||
	struct drm_device *dev = connector->dev;
 | 
			
		||||
| 
						 | 
				
			
			@ -277,6 +279,10 @@ static int omap_connector_mode_valid(struct drm_connector *connector,
 | 
			
		|||
	drm_display_mode_to_videomode(mode, &vm);
 | 
			
		||||
	mode->vrefresh = drm_mode_vrefresh(mode);
 | 
			
		||||
 | 
			
		||||
	r = priv->dispc_ops->mgr_check_timings(priv->dispc, channel, &vm);
 | 
			
		||||
	if (r)
 | 
			
		||||
		goto done;
 | 
			
		||||
 | 
			
		||||
	for (dssdev = omap_connector->output; dssdev; dssdev = dssdev->next) {
 | 
			
		||||
		if (!dssdev->ops->check_timings)
 | 
			
		||||
			continue;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -165,27 +165,35 @@ static int omap_encoder_atomic_check(struct drm_encoder *encoder,
 | 
			
		|||
				     struct drm_connector_state *conn_state)
 | 
			
		||||
{
 | 
			
		||||
	struct omap_encoder *omap_encoder = to_omap_encoder(encoder);
 | 
			
		||||
	enum omap_channel channel = omap_encoder->output->dispc_channel;
 | 
			
		||||
	struct drm_device *dev = encoder->dev;
 | 
			
		||||
	struct omap_drm_private *priv = dev->dev_private;
 | 
			
		||||
	struct omap_dss_device *dssdev;
 | 
			
		||||
	struct videomode vm = { 0 };
 | 
			
		||||
	int ret;
 | 
			
		||||
 | 
			
		||||
	drm_display_mode_to_videomode(&crtc_state->mode, &vm);
 | 
			
		||||
 | 
			
		||||
	ret = priv->dispc_ops->mgr_check_timings(priv->dispc, channel, &vm);
 | 
			
		||||
	if (ret)
 | 
			
		||||
		goto done;
 | 
			
		||||
 | 
			
		||||
	for (dssdev = omap_encoder->output; dssdev; dssdev = dssdev->next) {
 | 
			
		||||
		if (!dssdev->ops->check_timings)
 | 
			
		||||
			continue;
 | 
			
		||||
 | 
			
		||||
		ret = dssdev->ops->check_timings(dssdev, &vm);
 | 
			
		||||
		if (ret) {
 | 
			
		||||
			dev_err(dev->dev, "invalid timings: %d\n", ret);
 | 
			
		||||
			return ret;
 | 
			
		||||
		}
 | 
			
		||||
		if (ret)
 | 
			
		||||
			goto done;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	drm_display_mode_from_videomode(&vm, &crtc_state->adjusted_mode);
 | 
			
		||||
 | 
			
		||||
	return 0;
 | 
			
		||||
done:
 | 
			
		||||
	if (ret)
 | 
			
		||||
		dev_err(dev->dev, "invalid timings: %d\n", ret);
 | 
			
		||||
 | 
			
		||||
	return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static const struct drm_encoder_helper_funcs omap_encoder_helper_funcs = {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in a new issue