diff options
| author | Eric Anholt <eric@anholt.net> | 2017-06-07 20:13:36 -0400 |
|---|---|---|
| committer | Eric Anholt <eric@anholt.net> | 2017-06-15 19:02:45 -0400 |
| commit | 83753117f1de4f6ef7588fac9545065eed1e85e2 (patch) | |
| tree | 1471f2539093b056b46311390fc8555869913352 | |
| parent | 98830d91da082b0285d35bdf5b5ae98decac7df6 (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.c | 83 | ||||
| -rw-r--r-- | drivers/gpu/drm/vc4/vc4_drv.c | 2 | ||||
| -rw-r--r-- | drivers/gpu/drm/vc4/vc4_drv.h | 6 | ||||
| -rw-r--r-- | drivers/gpu/drm/vc4/vc4_kms.c | 41 | ||||
| -rw-r--r-- | include/uapi/drm/vc4_drm.h | 16 |
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 | */ | ||
| 584 | int 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 | */ | ||
| 627 | int 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 | |||
| 571 | void vc4_bo_cache_init(struct drm_device *dev) | 654 | void 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 | ||
| 143 | static struct drm_driver vc4_drm_driver = { | 145 | static 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); |
| 471 | int vc4_mmap_bo_ioctl(struct drm_device *dev, void *data, | 473 | int vc4_mmap_bo_ioctl(struct drm_device *dev, void *data, |
| 472 | struct drm_file *file_priv); | 474 | struct drm_file *file_priv); |
| 475 | int vc4_set_tiling_ioctl(struct drm_device *dev, void *data, | ||
| 476 | struct drm_file *file_priv); | ||
| 477 | int vc4_get_tiling_ioctl(struct drm_device *dev, void *data, | ||
| 478 | struct drm_file *file_priv); | ||
| 473 | int vc4_get_hang_state_ioctl(struct drm_device *dev, void *data, | 479 | int vc4_get_hang_state_ioctl(struct drm_device *dev, void *data, |
| 474 | struct drm_file *file_priv); | 480 | struct drm_file *file_priv); |
| 475 | int vc4_mmap(struct file *filp, struct vm_area_struct *vma); | 481 | int 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 | ||
| 205 | static 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 | |||
| 205 | static const struct drm_mode_config_funcs vc4_mode_funcs = { | 244 | static 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 | ||
| 212 | int vc4_kms_load(struct drm_device *dev) | 251 | int 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 | ||
| 51 | struct drm_vc4_submit_rcl_surface { | 55 | struct 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 | ||
| 302 | struct drm_vc4_get_tiling { | ||
| 303 | __u32 handle; | ||
| 304 | __u32 flags; | ||
| 305 | __u64 modifier; | ||
| 306 | }; | ||
| 307 | |||
| 308 | struct 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 |
