diff options
Diffstat (limited to 'drivers/gpu/drm/exynos/exynos_drm_fb.c')
| -rw-r--r-- | drivers/gpu/drm/exynos/exynos_drm_fb.c | 78 | 
1 files changed, 40 insertions, 38 deletions
| diff --git a/drivers/gpu/drm/exynos/exynos_drm_fb.c b/drivers/gpu/drm/exynos/exynos_drm_fb.c index 929cb03a8eab..2b6320e6eae2 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_fb.c +++ b/drivers/gpu/drm/exynos/exynos_drm_fb.c @@ -16,6 +16,8 @@  #include <drm/drm_crtc.h>  #include <drm/drm_crtc_helper.h>  #include <drm/drm_fb_helper.h> +#include <drm/drm_atomic.h> +#include <drm/drm_atomic_helper.h>  #include <uapi/drm/exynos_drm.h>  #include "exynos_drm_drv.h" @@ -171,43 +173,6 @@ exynos_drm_framebuffer_init(struct drm_device *dev,  	return &exynos_fb->fb;  } -static u32 exynos_drm_format_num_buffers(struct drm_mode_fb_cmd2 *mode_cmd) -{ -	unsigned int cnt = 0; - -	if (mode_cmd->pixel_format != DRM_FORMAT_NV12) -		return drm_format_num_planes(mode_cmd->pixel_format); - -	while (cnt != MAX_FB_BUFFER) { -		if (!mode_cmd->handles[cnt]) -			break; -		cnt++; -	} - -	/* -	 * check if NV12 or NV12M. -	 * -	 * NV12 -	 * handles[0] = base1, offsets[0] = 0 -	 * handles[1] = base1, offsets[1] = Y_size -	 * -	 * NV12M -	 * handles[0] = base1, offsets[0] = 0 -	 * handles[1] = base2, offsets[1] = 0 -	 */ -	if (cnt == 2) { -		/* -		 * in case of NV12 format, offsets[1] is not 0 and -		 * handles[0] is same as handles[1]. -		 */ -		if (mode_cmd->offsets[1] && -			mode_cmd->handles[0] == mode_cmd->handles[1]) -			cnt = 1; -	} - -	return cnt; -} -  static struct drm_framebuffer *  exynos_user_fb_create(struct drm_device *dev, struct drm_file *file_priv,  		      struct drm_mode_fb_cmd2 *mode_cmd) @@ -230,7 +195,7 @@ exynos_user_fb_create(struct drm_device *dev, struct drm_file *file_priv,  	drm_helper_mode_fill_fb_struct(&exynos_fb->fb, mode_cmd);  	exynos_fb->exynos_gem_obj[0] = to_exynos_gem_obj(obj); -	exynos_fb->buf_cnt = exynos_drm_format_num_buffers(mode_cmd); +	exynos_fb->buf_cnt = drm_format_num_planes(mode_cmd->pixel_format);  	DRM_DEBUG_KMS("buf_cnt = %d\n", exynos_fb->buf_cnt); @@ -302,9 +267,46 @@ static void exynos_drm_output_poll_changed(struct drm_device *dev)  		exynos_drm_fbdev_init(dev);  } +static int exynos_atomic_commit(struct drm_device *dev, +				struct drm_atomic_state *state, +				bool async) +{ +	int ret; + +	ret = drm_atomic_helper_prepare_planes(dev, state); +	if (ret) +		return ret; + +	/* This is the point of no return */ + +	drm_atomic_helper_swap_state(dev, state); + +	drm_atomic_helper_commit_modeset_disables(dev, state); + +	drm_atomic_helper_commit_modeset_enables(dev, state); + +	/* +	 * Exynos can't update planes with CRTCs and encoders disabled, +	 * its updates routines, specially for FIMD, requires the clocks +	 * to be enabled. So it is necessary to handle the modeset operations +	 * *before* the commit_planes() step, this way it will always +	 * have the relevant clocks enabled to perform the update. +	 */ + +	drm_atomic_helper_commit_planes(dev, state); + +	drm_atomic_helper_cleanup_planes(dev, state); + +	drm_atomic_state_free(state); + +	return 0; +} +  static const struct drm_mode_config_funcs exynos_drm_mode_config_funcs = {  	.fb_create = exynos_user_fb_create,  	.output_poll_changed = exynos_drm_output_poll_changed, +	.atomic_check = drm_atomic_helper_check, +	.atomic_commit = exynos_atomic_commit,  };  void exynos_drm_mode_config_init(struct drm_device *dev) | 
