mirror of
				https://github.com/torvalds/linux.git
				synced 2025-10-31 16:48:26 +02:00 
			
		
		
		
	drm/vc4: Add get/set tiling ioctls.
This allows mesa to set the tiling format for a BO and have that tiling format be respected by mesa on the other side of an import/export (and by vc4 scanout in the kernel), without defining a protocol to pass the tiling through userspace. Signed-off-by: Eric Anholt <eric@anholt.net> Link: http://patchwork.freedesktop.org/patch/msgid/20170608001336.12842-2-eric@anholt.net Acked-by: Dave Airlie <airlied@redhat.com>
This commit is contained in:
		
							parent
							
								
									98830d91da
								
							
						
					
					
						commit
						83753117f1
					
				
					 5 changed files with 147 additions and 1 deletions
				
			
		|  | @ -343,6 +343,7 @@ void vc4_free_object(struct drm_gem_object *gem_bo) | |||
| 		bo->validated_shader = NULL; | ||||
| 	} | ||||
| 
 | ||||
| 	bo->t_format = false; | ||||
| 	bo->free_time = jiffies; | ||||
| 	list_add(&bo->size_head, cache_list); | ||||
| 	list_add(&bo->unref_head, &vc4->bo_cache.time_list); | ||||
|  | @ -568,6 +569,88 @@ vc4_create_shader_bo_ioctl(struct drm_device *dev, void *data, | |||
| 	return ret; | ||||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  * vc4_set_tiling_ioctl() - Sets the tiling modifier for a BO. | ||||
|  * @dev: DRM device | ||||
|  * @data: ioctl argument | ||||
|  * @file_priv: DRM file for this fd | ||||
|  * | ||||
|  * The tiling state of the BO decides the default modifier of an fb if | ||||
|  * no specific modifier was set by userspace, and the return value of | ||||
|  * vc4_get_tiling_ioctl() (so that userspace can treat a BO it | ||||
|  * received from dmabuf as the same tiling format as the producer | ||||
|  * used). | ||||
|  */ | ||||
| int vc4_set_tiling_ioctl(struct drm_device *dev, void *data, | ||||
| 			 struct drm_file *file_priv) | ||||
| { | ||||
| 	struct drm_vc4_set_tiling *args = data; | ||||
| 	struct drm_gem_object *gem_obj; | ||||
| 	struct vc4_bo *bo; | ||||
| 	bool t_format; | ||||
| 
 | ||||
| 	if (args->flags != 0) | ||||
| 		return -EINVAL; | ||||
| 
 | ||||
| 	switch (args->modifier) { | ||||
| 	case DRM_FORMAT_MOD_NONE: | ||||
| 		t_format = false; | ||||
| 		break; | ||||
| 	case DRM_FORMAT_MOD_BROADCOM_VC4_T_TILED: | ||||
| 		t_format = true; | ||||
| 		break; | ||||
| 	default: | ||||
| 		return -EINVAL; | ||||
| 	} | ||||
| 
 | ||||
| 	gem_obj = drm_gem_object_lookup(file_priv, args->handle); | ||||
| 	if (!gem_obj) { | ||||
| 		DRM_ERROR("Failed to look up GEM BO %d\n", args->handle); | ||||
| 		return -ENOENT; | ||||
| 	} | ||||
| 	bo = to_vc4_bo(gem_obj); | ||||
| 	bo->t_format = t_format; | ||||
| 
 | ||||
| 	drm_gem_object_unreference_unlocked(gem_obj); | ||||
| 
 | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  * vc4_get_tiling_ioctl() - Gets the tiling modifier for a BO. | ||||
|  * @dev: DRM device | ||||
|  * @data: ioctl argument | ||||
|  * @file_priv: DRM file for this fd | ||||
|  * | ||||
|  * Returns the tiling modifier for a BO as set by vc4_set_tiling_ioctl(). | ||||
|  */ | ||||
| int vc4_get_tiling_ioctl(struct drm_device *dev, void *data, | ||||
| 			 struct drm_file *file_priv) | ||||
| { | ||||
| 	struct drm_vc4_get_tiling *args = data; | ||||
| 	struct drm_gem_object *gem_obj; | ||||
| 	struct vc4_bo *bo; | ||||
| 
 | ||||
| 	if (args->flags != 0 || args->modifier != 0) | ||||
| 		return -EINVAL; | ||||
| 
 | ||||
| 	gem_obj = drm_gem_object_lookup(file_priv, args->handle); | ||||
| 	if (!gem_obj) { | ||||
| 		DRM_ERROR("Failed to look up GEM BO %d\n", args->handle); | ||||
| 		return -ENOENT; | ||||
| 	} | ||||
| 	bo = to_vc4_bo(gem_obj); | ||||
| 
 | ||||
| 	if (bo->t_format) | ||||
| 		args->modifier = DRM_FORMAT_MOD_BROADCOM_VC4_T_TILED; | ||||
| 	else | ||||
| 		args->modifier = DRM_FORMAT_MOD_NONE; | ||||
| 
 | ||||
| 	drm_gem_object_unreference_unlocked(gem_obj); | ||||
| 
 | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| void vc4_bo_cache_init(struct drm_device *dev) | ||||
| { | ||||
| 	struct vc4_dev *vc4 = to_vc4_dev(dev); | ||||
|  |  | |||
|  | @ -138,6 +138,8 @@ static const struct drm_ioctl_desc vc4_drm_ioctls[] = { | |||
| 	DRM_IOCTL_DEF_DRV(VC4_GET_HANG_STATE, vc4_get_hang_state_ioctl, | ||||
| 			  DRM_ROOT_ONLY), | ||||
| 	DRM_IOCTL_DEF_DRV(VC4_GET_PARAM, vc4_get_param_ioctl, DRM_RENDER_ALLOW), | ||||
| 	DRM_IOCTL_DEF_DRV(VC4_SET_TILING, vc4_set_tiling_ioctl, DRM_RENDER_ALLOW), | ||||
| 	DRM_IOCTL_DEF_DRV(VC4_GET_TILING, vc4_get_tiling_ioctl, DRM_RENDER_ALLOW), | ||||
| }; | ||||
| 
 | ||||
| static struct drm_driver vc4_drm_driver = { | ||||
|  |  | |||
|  | @ -148,6 +148,8 @@ struct vc4_bo { | |||
| 	 */ | ||||
| 	uint64_t write_seqno; | ||||
| 
 | ||||
| 	bool t_format; | ||||
| 
 | ||||
| 	/* List entry for the BO's position in either
 | ||||
| 	 * vc4_exec_info->unref_list or vc4_dev->bo_cache.time_list | ||||
| 	 */ | ||||
|  | @ -470,6 +472,10 @@ int vc4_create_shader_bo_ioctl(struct drm_device *dev, void *data, | |||
| 			       struct drm_file *file_priv); | ||||
| int vc4_mmap_bo_ioctl(struct drm_device *dev, void *data, | ||||
| 		      struct drm_file *file_priv); | ||||
| int vc4_set_tiling_ioctl(struct drm_device *dev, void *data, | ||||
| 			 struct drm_file *file_priv); | ||||
| int vc4_get_tiling_ioctl(struct drm_device *dev, void *data, | ||||
| 			 struct drm_file *file_priv); | ||||
| int vc4_get_hang_state_ioctl(struct drm_device *dev, void *data, | ||||
| 			     struct drm_file *file_priv); | ||||
| int vc4_mmap(struct file *filp, struct vm_area_struct *vma); | ||||
|  |  | |||
|  | @ -202,11 +202,50 @@ static int vc4_atomic_commit(struct drm_device *dev, | |||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| static struct drm_framebuffer *vc4_fb_create(struct drm_device *dev, | ||||
| 					     struct drm_file *file_priv, | ||||
| 					     const struct drm_mode_fb_cmd2 *mode_cmd) | ||||
| { | ||||
| 	struct drm_mode_fb_cmd2 mode_cmd_local; | ||||
| 
 | ||||
| 	/* If the user didn't specify a modifier, use the
 | ||||
| 	 * vc4_set_tiling_ioctl() state for the BO. | ||||
| 	 */ | ||||
| 	if (!(mode_cmd->flags & DRM_MODE_FB_MODIFIERS)) { | ||||
| 		struct drm_gem_object *gem_obj; | ||||
| 		struct vc4_bo *bo; | ||||
| 
 | ||||
| 		gem_obj = drm_gem_object_lookup(file_priv, | ||||
| 						mode_cmd->handles[0]); | ||||
| 		if (!gem_obj) { | ||||
| 			DRM_ERROR("Failed to look up GEM BO %d\n", | ||||
| 				  mode_cmd->handles[0]); | ||||
| 			return ERR_PTR(-ENOENT); | ||||
| 		} | ||||
| 		bo = to_vc4_bo(gem_obj); | ||||
| 
 | ||||
| 		mode_cmd_local = *mode_cmd; | ||||
| 
 | ||||
| 		if (bo->t_format) { | ||||
| 			mode_cmd_local.modifier[0] = | ||||
| 				DRM_FORMAT_MOD_BROADCOM_VC4_T_TILED; | ||||
| 		} else { | ||||
| 			mode_cmd_local.modifier[0] = DRM_FORMAT_MOD_NONE; | ||||
| 		} | ||||
| 
 | ||||
| 		drm_gem_object_unreference_unlocked(gem_obj); | ||||
| 
 | ||||
| 		mode_cmd = &mode_cmd_local; | ||||
| 	} | ||||
| 
 | ||||
| 	return drm_fb_cma_create(dev, file_priv, mode_cmd); | ||||
| } | ||||
| 
 | ||||
| static const struct drm_mode_config_funcs vc4_mode_funcs = { | ||||
| 	.output_poll_changed = vc4_output_poll_changed, | ||||
| 	.atomic_check = drm_atomic_helper_check, | ||||
| 	.atomic_commit = vc4_atomic_commit, | ||||
| 	.fb_create = drm_fb_cma_create, | ||||
| 	.fb_create = vc4_fb_create, | ||||
| }; | ||||
| 
 | ||||
| int vc4_kms_load(struct drm_device *dev) | ||||
|  |  | |||
|  | @ -38,6 +38,8 @@ extern "C" { | |||
| #define DRM_VC4_CREATE_SHADER_BO                  0x05 | ||||
| #define DRM_VC4_GET_HANG_STATE                    0x06 | ||||
| #define DRM_VC4_GET_PARAM                         0x07 | ||||
| #define DRM_VC4_SET_TILING                        0x08 | ||||
| #define DRM_VC4_GET_TILING                        0x09 | ||||
| 
 | ||||
| #define DRM_IOCTL_VC4_SUBMIT_CL           DRM_IOWR(DRM_COMMAND_BASE + DRM_VC4_SUBMIT_CL, struct drm_vc4_submit_cl) | ||||
| #define DRM_IOCTL_VC4_WAIT_SEQNO          DRM_IOWR(DRM_COMMAND_BASE + DRM_VC4_WAIT_SEQNO, struct drm_vc4_wait_seqno) | ||||
|  | @ -47,6 +49,8 @@ extern "C" { | |||
| #define DRM_IOCTL_VC4_CREATE_SHADER_BO    DRM_IOWR(DRM_COMMAND_BASE + DRM_VC4_CREATE_SHADER_BO, struct drm_vc4_create_shader_bo) | ||||
| #define DRM_IOCTL_VC4_GET_HANG_STATE      DRM_IOWR(DRM_COMMAND_BASE + DRM_VC4_GET_HANG_STATE, struct drm_vc4_get_hang_state) | ||||
| #define DRM_IOCTL_VC4_GET_PARAM           DRM_IOWR(DRM_COMMAND_BASE + DRM_VC4_GET_PARAM, struct drm_vc4_get_param) | ||||
| #define DRM_IOCTL_VC4_SET_TILING          DRM_IOWR(DRM_COMMAND_BASE + DRM_VC4_SET_TILING, struct drm_vc4_set_tiling) | ||||
| #define DRM_IOCTL_VC4_GET_TILING          DRM_IOWR(DRM_COMMAND_BASE + DRM_VC4_GET_TILING, struct drm_vc4_get_tiling) | ||||
| 
 | ||||
| struct drm_vc4_submit_rcl_surface { | ||||
| 	__u32 hindex; /* Handle index, or ~0 if not present. */ | ||||
|  | @ -295,6 +299,18 @@ struct drm_vc4_get_param { | |||
| 	__u64 value; | ||||
| }; | ||||
| 
 | ||||
| struct drm_vc4_get_tiling { | ||||
| 	__u32 handle; | ||||
| 	__u32 flags; | ||||
| 	__u64 modifier; | ||||
| }; | ||||
| 
 | ||||
| struct drm_vc4_set_tiling { | ||||
| 	__u32 handle; | ||||
| 	__u32 flags; | ||||
| 	__u64 modifier; | ||||
| }; | ||||
| 
 | ||||
| #if defined(__cplusplus) | ||||
| } | ||||
| #endif | ||||
|  |  | |||
		Loading…
	
		Reference in a new issue
	
	 Eric Anholt
						Eric Anholt