Skip to content

Commit 8375311

Browse files
committed
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 <[email protected]> Link: http://patchwork.freedesktop.org/patch/msgid/[email protected] Acked-by: Dave Airlie <[email protected]>
1 parent 98830d9 commit 8375311

File tree

5 files changed

+147
-1
lines changed

5 files changed

+147
-1
lines changed

drivers/gpu/drm/vc4/vc4_bo.c

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -343,6 +343,7 @@ void vc4_free_object(struct drm_gem_object *gem_bo)
343343
bo->validated_shader = NULL;
344344
}
345345

346+
bo->t_format = false;
346347
bo->free_time = jiffies;
347348
list_add(&bo->size_head, cache_list);
348349
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,
568569
return ret;
569570
}
570571

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+
571654
void vc4_bo_cache_init(struct drm_device *dev)
572655
{
573656
struct vc4_dev *vc4 = to_vc4_dev(dev);

drivers/gpu/drm/vc4/vc4_drv.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,8 @@ static const struct drm_ioctl_desc vc4_drm_ioctls[] = {
138138
DRM_IOCTL_DEF_DRV(VC4_GET_HANG_STATE, vc4_get_hang_state_ioctl,
139139
DRM_ROOT_ONLY),
140140
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),
141143
};
142144

143145
static struct drm_driver vc4_drm_driver = {

drivers/gpu/drm/vc4/vc4_drv.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,8 @@ struct vc4_bo {
148148
*/
149149
uint64_t write_seqno;
150150

151+
bool t_format;
152+
151153
/* List entry for the BO's position in either
152154
* vc4_exec_info->unref_list or vc4_dev->bo_cache.time_list
153155
*/
@@ -470,6 +472,10 @@ int vc4_create_shader_bo_ioctl(struct drm_device *dev, void *data,
470472
struct drm_file *file_priv);
471473
int vc4_mmap_bo_ioctl(struct drm_device *dev, void *data,
472474
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);
473479
int vc4_get_hang_state_ioctl(struct drm_device *dev, void *data,
474480
struct drm_file *file_priv);
475481
int vc4_mmap(struct file *filp, struct vm_area_struct *vma);

drivers/gpu/drm/vc4/vc4_kms.c

Lines changed: 40 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -202,11 +202,50 @@ static int vc4_atomic_commit(struct drm_device *dev,
202202
return 0;
203203
}
204204

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+
205244
static const struct drm_mode_config_funcs vc4_mode_funcs = {
206245
.output_poll_changed = vc4_output_poll_changed,
207246
.atomic_check = drm_atomic_helper_check,
208247
.atomic_commit = vc4_atomic_commit,
209-
.fb_create = drm_fb_cma_create,
248+
.fb_create = vc4_fb_create,
210249
};
211250

212251
int vc4_kms_load(struct drm_device *dev)

include/uapi/drm/vc4_drm.h

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,8 @@ extern "C" {
3838
#define DRM_VC4_CREATE_SHADER_BO 0x05
3939
#define DRM_VC4_GET_HANG_STATE 0x06
4040
#define DRM_VC4_GET_PARAM 0x07
41+
#define DRM_VC4_SET_TILING 0x08
42+
#define DRM_VC4_GET_TILING 0x09
4143

4244
#define DRM_IOCTL_VC4_SUBMIT_CL DRM_IOWR(DRM_COMMAND_BASE + DRM_VC4_SUBMIT_CL, struct drm_vc4_submit_cl)
4345
#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" {
4749
#define DRM_IOCTL_VC4_CREATE_SHADER_BO DRM_IOWR(DRM_COMMAND_BASE + DRM_VC4_CREATE_SHADER_BO, struct drm_vc4_create_shader_bo)
4850
#define DRM_IOCTL_VC4_GET_HANG_STATE DRM_IOWR(DRM_COMMAND_BASE + DRM_VC4_GET_HANG_STATE, struct drm_vc4_get_hang_state)
4951
#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)
5054

5155
struct drm_vc4_submit_rcl_surface {
5256
__u32 hindex; /* Handle index, or ~0 if not present. */
@@ -295,6 +299,18 @@ struct drm_vc4_get_param {
295299
__u64 value;
296300
};
297301

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+
298314
#if defined(__cplusplus)
299315
}
300316
#endif

0 commit comments

Comments
 (0)