aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEric Anholt <eric@anholt.net>2017-06-07 20:13:36 -0400
committerEric Anholt <eric@anholt.net>2017-06-15 19:02:45 -0400
commit83753117f1de4f6ef7588fac9545065eed1e85e2 (patch)
tree1471f2539093b056b46311390fc8555869913352
parent98830d91da082b0285d35bdf5b5ae98decac7df6 (diff)
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>
-rw-r--r--drivers/gpu/drm/vc4/vc4_bo.c83
-rw-r--r--drivers/gpu/drm/vc4/vc4_drv.c2
-rw-r--r--drivers/gpu/drm/vc4/vc4_drv.h6
-rw-r--r--drivers/gpu/drm/vc4/vc4_kms.c41
-rw-r--r--include/uapi/drm/vc4_drm.h16
5 files changed, 147 insertions, 1 deletions
diff --git a/drivers/gpu/drm/vc4/vc4_bo.c b/drivers/gpu/drm/vc4/vc4_bo.c
index 590c0912afc1..487f96412d35 100644
--- a/drivers/gpu/drm/vc4/vc4_bo.c
+++ b/drivers/gpu/drm/vc4/vc4_bo.c
@@ -343,6 +343,7 @@ void vc4_free_object(struct drm_gem_object *gem_bo)
343 bo->validated_shader = NULL; 343 bo->validated_shader = NULL;
344 } 344 }
345 345
346 bo->t_format = false;
346 bo->free_time = jiffies; 347 bo->free_time = jiffies;
347 list_add(&bo->size_head, cache_list); 348 list_add(&bo->size_head, cache_list);
348 list_add(&bo->unref_head, &vc4->bo_cache.time_list); 349 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,
568 return ret; 569 return ret;
569} 570}
570 571
572/**
573 * vc4_set_tiling_ioctl() - Sets the tiling modifier for a BO.
574 * @dev: DRM device
575 * @data: ioctl argument
576 * @file_priv: DRM file for this fd
577 *
578 * The tiling state of the BO decides the default modifier of an fb if
579 * no specific modifier was set by userspace, and the return value of
580 * vc4_get_tiling_ioctl() (so that userspace can treat a BO it
581 * received from dmabuf as the same tiling format as the producer
582 * used).
583 */
584int vc4_set_tiling_ioctl(struct drm_device *dev, void *data,
585 struct drm_file *file_priv)
586{
587 struct drm_vc4_set_tiling *args = data;
588 struct drm_gem_object *gem_obj;
589 struct vc4_bo *bo;
590 bool t_format;
591
592 if (args->flags != 0)
593 return -EINVAL;
594
595 switch (args->modifier) {
596 case DRM_FORMAT_MOD_NONE:
597 t_format = false;
598 break;
599 case DRM_FORMAT_MOD_BROADCOM_VC4_T_TILED:
600 t_format = true;
601 break;
602 default:
603 return -EINVAL;
604 }
605
606 gem_obj = drm_gem_object_lookup(file_priv, args->handle);
607 if (!gem_obj) {
608 DRM_ERROR("Failed to look up GEM BO %d\n", args->handle);
609 return -ENOENT;
610 }
611 bo = to_vc4_bo(gem_obj);
612 bo->t_format = t_format;
613
614 drm_gem_object_unreference_unlocked(gem_obj);
615
616 return 0;
617}
618
619/**
620 * vc4_get_tiling_ioctl() - Gets the tiling modifier for a BO.
621 * @dev: DRM device
622 * @data: ioctl argument
623 * @file_priv: DRM file for this fd
624 *
625 * Returns the tiling modifier for a BO as set by vc4_set_tiling_ioctl().
626 */
627int vc4_get_tiling_ioctl(struct drm_device *dev, void *data,
628 struct drm_file *file_priv)
629{
630 struct drm_vc4_get_tiling *args = data;
631 struct drm_gem_object *gem_obj;
632 struct vc4_bo *bo;
633
634 if (args->flags != 0 || args->modifier != 0)
635 return -EINVAL;
636
637 gem_obj = drm_gem_object_lookup(file_priv, args->handle);
638 if (!gem_obj) {
639 DRM_ERROR("Failed to look up GEM BO %d\n", args->handle);
640 return -ENOENT;
641 }
642 bo = to_vc4_bo(gem_obj);
643
644 if (bo->t_format)
645 args->modifier = DRM_FORMAT_MOD_BROADCOM_VC4_T_TILED;
646 else
647 args->modifier = DRM_FORMAT_MOD_NONE;
648
649 drm_gem_object_unreference_unlocked(gem_obj);
650
651 return 0;
652}
653
571void vc4_bo_cache_init(struct drm_device *dev) 654void vc4_bo_cache_init(struct drm_device *dev)
572{ 655{
573 struct vc4_dev *vc4 = to_vc4_dev(dev); 656 struct vc4_dev *vc4 = to_vc4_dev(dev);
diff --git a/drivers/gpu/drm/vc4/vc4_drv.c b/drivers/gpu/drm/vc4/vc4_drv.c
index 136bb4213dc0..c6b487c3d2b7 100644
--- a/drivers/gpu/drm/vc4/vc4_drv.c
+++ b/drivers/gpu/drm/vc4/vc4_drv.c
@@ -138,6 +138,8 @@ static const struct drm_ioctl_desc vc4_drm_ioctls[] = {
138 DRM_IOCTL_DEF_DRV(VC4_GET_HANG_STATE, vc4_get_hang_state_ioctl, 138 DRM_IOCTL_DEF_DRV(VC4_GET_HANG_STATE, vc4_get_hang_state_ioctl,
139 DRM_ROOT_ONLY), 139 DRM_ROOT_ONLY),
140 DRM_IOCTL_DEF_DRV(VC4_GET_PARAM, vc4_get_param_ioctl, DRM_RENDER_ALLOW), 140 DRM_IOCTL_DEF_DRV(VC4_GET_PARAM, vc4_get_param_ioctl, DRM_RENDER_ALLOW),
141 DRM_IOCTL_DEF_DRV(VC4_SET_TILING, vc4_set_tiling_ioctl, DRM_RENDER_ALLOW),
142 DRM_IOCTL_DEF_DRV(VC4_GET_TILING, vc4_get_tiling_ioctl, DRM_RENDER_ALLOW),
141}; 143};
142 144
143static struct drm_driver vc4_drm_driver = { 145static struct drm_driver vc4_drm_driver = {
diff --git a/drivers/gpu/drm/vc4/vc4_drv.h b/drivers/gpu/drm/vc4/vc4_drv.h
index a5bf2e5e0b57..df22698d62ee 100644
--- a/drivers/gpu/drm/vc4/vc4_drv.h
+++ b/drivers/gpu/drm/vc4/vc4_drv.h
@@ -148,6 +148,8 @@ struct vc4_bo {
148 */ 148 */
149 uint64_t write_seqno; 149 uint64_t write_seqno;
150 150
151 bool t_format;
152
151 /* List entry for the BO's position in either 153 /* List entry for the BO's position in either
152 * vc4_exec_info->unref_list or vc4_dev->bo_cache.time_list 154 * vc4_exec_info->unref_list or vc4_dev->bo_cache.time_list
153 */ 155 */
@@ -470,6 +472,10 @@ int vc4_create_shader_bo_ioctl(struct drm_device *dev, void *data,
470 struct drm_file *file_priv); 472 struct drm_file *file_priv);
471int vc4_mmap_bo_ioctl(struct drm_device *dev, void *data, 473int vc4_mmap_bo_ioctl(struct drm_device *dev, void *data,
472 struct drm_file *file_priv); 474 struct drm_file *file_priv);
475int vc4_set_tiling_ioctl(struct drm_device *dev, void *data,
476 struct drm_file *file_priv);
477int vc4_get_tiling_ioctl(struct drm_device *dev, void *data,
478 struct drm_file *file_priv);
473int vc4_get_hang_state_ioctl(struct drm_device *dev, void *data, 479int vc4_get_hang_state_ioctl(struct drm_device *dev, void *data,
474 struct drm_file *file_priv); 480 struct drm_file *file_priv);
475int vc4_mmap(struct file *filp, struct vm_area_struct *vma); 481int vc4_mmap(struct file *filp, struct vm_area_struct *vma);
diff --git a/drivers/gpu/drm/vc4/vc4_kms.c b/drivers/gpu/drm/vc4/vc4_kms.c
index 928d191ef90f..202f7ebf5a7b 100644
--- a/drivers/gpu/drm/vc4/vc4_kms.c
+++ b/drivers/gpu/drm/vc4/vc4_kms.c
@@ -202,11 +202,50 @@ static int vc4_atomic_commit(struct drm_device *dev,
202 return 0; 202 return 0;
203} 203}
204 204
205static struct drm_framebuffer *vc4_fb_create(struct drm_device *dev,
206 struct drm_file *file_priv,
207 const struct drm_mode_fb_cmd2 *mode_cmd)
208{
209 struct drm_mode_fb_cmd2 mode_cmd_local;
210
211 /* If the user didn't specify a modifier, use the
212 * vc4_set_tiling_ioctl() state for the BO.
213 */
214 if (!(mode_cmd->flags & DRM_MODE_FB_MODIFIERS)) {
215 struct drm_gem_object *gem_obj;
216 struct vc4_bo *bo;
217
218 gem_obj = drm_gem_object_lookup(file_priv,
219 mode_cmd->handles[0]);
220 if (!gem_obj) {
221 DRM_ERROR("Failed to look up GEM BO %d\n",
222 mode_cmd->handles[0]);
223 return ERR_PTR(-ENOENT);
224 }
225 bo = to_vc4_bo(gem_obj);
226
227 mode_cmd_local = *mode_cmd;
228
229 if (bo->t_format) {
230 mode_cmd_local.modifier[0] =
231 DRM_FORMAT_MOD_BROADCOM_VC4_T_TILED;
232 } else {
233 mode_cmd_local.modifier[0] = DRM_FORMAT_MOD_NONE;
234 }
235
236 drm_gem_object_unreference_unlocked(gem_obj);
237
238 mode_cmd = &mode_cmd_local;
239 }
240
241 return drm_fb_cma_create(dev, file_priv, mode_cmd);
242}
243
205static const struct drm_mode_config_funcs vc4_mode_funcs = { 244static const struct drm_mode_config_funcs vc4_mode_funcs = {
206 .output_poll_changed = vc4_output_poll_changed, 245 .output_poll_changed = vc4_output_poll_changed,
207 .atomic_check = drm_atomic_helper_check, 246 .atomic_check = drm_atomic_helper_check,
208 .atomic_commit = vc4_atomic_commit, 247 .atomic_commit = vc4_atomic_commit,
209 .fb_create = drm_fb_cma_create, 248 .fb_create = vc4_fb_create,
210}; 249};
211 250
212int vc4_kms_load(struct drm_device *dev) 251int vc4_kms_load(struct drm_device *dev)
diff --git a/include/uapi/drm/vc4_drm.h b/include/uapi/drm/vc4_drm.h
index f07a09016726..6ac4c5c014cb 100644
--- a/include/uapi/drm/vc4_drm.h
+++ b/include/uapi/drm/vc4_drm.h
@@ -38,6 +38,8 @@ extern "C" {
38#define DRM_VC4_CREATE_SHADER_BO 0x05 38#define DRM_VC4_CREATE_SHADER_BO 0x05
39#define DRM_VC4_GET_HANG_STATE 0x06 39#define DRM_VC4_GET_HANG_STATE 0x06
40#define DRM_VC4_GET_PARAM 0x07 40#define DRM_VC4_GET_PARAM 0x07
41#define DRM_VC4_SET_TILING 0x08
42#define DRM_VC4_GET_TILING 0x09
41 43
42#define DRM_IOCTL_VC4_SUBMIT_CL DRM_IOWR(DRM_COMMAND_BASE + DRM_VC4_SUBMIT_CL, struct drm_vc4_submit_cl) 44#define DRM_IOCTL_VC4_SUBMIT_CL DRM_IOWR(DRM_COMMAND_BASE + DRM_VC4_SUBMIT_CL, struct drm_vc4_submit_cl)
43#define DRM_IOCTL_VC4_WAIT_SEQNO DRM_IOWR(DRM_COMMAND_BASE + DRM_VC4_WAIT_SEQNO, struct drm_vc4_wait_seqno) 45#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" {
47#define DRM_IOCTL_VC4_CREATE_SHADER_BO DRM_IOWR(DRM_COMMAND_BASE + DRM_VC4_CREATE_SHADER_BO, struct drm_vc4_create_shader_bo) 49#define DRM_IOCTL_VC4_CREATE_SHADER_BO DRM_IOWR(DRM_COMMAND_BASE + DRM_VC4_CREATE_SHADER_BO, struct drm_vc4_create_shader_bo)
48#define DRM_IOCTL_VC4_GET_HANG_STATE DRM_IOWR(DRM_COMMAND_BASE + DRM_VC4_GET_HANG_STATE, struct drm_vc4_get_hang_state) 50#define DRM_IOCTL_VC4_GET_HANG_STATE DRM_IOWR(DRM_COMMAND_BASE + DRM_VC4_GET_HANG_STATE, struct drm_vc4_get_hang_state)
49#define DRM_IOCTL_VC4_GET_PARAM DRM_IOWR(DRM_COMMAND_BASE + DRM_VC4_GET_PARAM, struct drm_vc4_get_param) 51#define DRM_IOCTL_VC4_GET_PARAM DRM_IOWR(DRM_COMMAND_BASE + DRM_VC4_GET_PARAM, struct drm_vc4_get_param)
52#define DRM_IOCTL_VC4_SET_TILING DRM_IOWR(DRM_COMMAND_BASE + DRM_VC4_SET_TILING, struct drm_vc4_set_tiling)
53#define DRM_IOCTL_VC4_GET_TILING DRM_IOWR(DRM_COMMAND_BASE + DRM_VC4_GET_TILING, struct drm_vc4_get_tiling)
50 54
51struct drm_vc4_submit_rcl_surface { 55struct drm_vc4_submit_rcl_surface {
52 __u32 hindex; /* Handle index, or ~0 if not present. */ 56 __u32 hindex; /* Handle index, or ~0 if not present. */
@@ -295,6 +299,18 @@ struct drm_vc4_get_param {
295 __u64 value; 299 __u64 value;
296}; 300};
297 301
302struct drm_vc4_get_tiling {
303 __u32 handle;
304 __u32 flags;
305 __u64 modifier;
306};
307
308struct drm_vc4_set_tiling {
309 __u32 handle;
310 __u32 flags;
311 __u64 modifier;
312};
313
298#if defined(__cplusplus) 314#if defined(__cplusplus)
299} 315}
300#endif 316#endif