diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/gpu/drm/tegra/drm.c | 95 |
1 files changed, 95 insertions, 0 deletions
diff --git a/drivers/gpu/drm/tegra/drm.c b/drivers/gpu/drm/tegra/drm.c index fd736efd14bd..a029525b598f 100644 --- a/drivers/gpu/drm/tegra/drm.c +++ b/drivers/gpu/drm/tegra/drm.c @@ -455,6 +455,99 @@ static int tegra_get_syncpt_base(struct drm_device *drm, void *data, return 0; } + +static int tegra_gem_set_tiling(struct drm_device *drm, void *data, + struct drm_file *file) +{ + struct drm_tegra_gem_set_tiling *args = data; + enum tegra_bo_tiling_mode mode; + struct drm_gem_object *gem; + unsigned long value = 0; + struct tegra_bo *bo; + + switch (args->mode) { + case DRM_TEGRA_GEM_TILING_MODE_PITCH: + mode = TEGRA_BO_TILING_MODE_PITCH; + + if (args->value != 0) + return -EINVAL; + + break; + + case DRM_TEGRA_GEM_TILING_MODE_TILED: + mode = TEGRA_BO_TILING_MODE_TILED; + + if (args->value != 0) + return -EINVAL; + + break; + + case DRM_TEGRA_GEM_TILING_MODE_BLOCK: + mode = TEGRA_BO_TILING_MODE_BLOCK; + + if (args->value > 5) + return -EINVAL; + + value = args->value; + break; + + default: + return -EINVAL; + } + + gem = drm_gem_object_lookup(drm, file, args->handle); + if (!gem) + return -ENOENT; + + bo = to_tegra_bo(gem); + + bo->tiling.mode = mode; + bo->tiling.value = value; + + drm_gem_object_unreference(gem); + + return 0; +} + +static int tegra_gem_get_tiling(struct drm_device *drm, void *data, + struct drm_file *file) +{ + struct drm_tegra_gem_get_tiling *args = data; + struct drm_gem_object *gem; + struct tegra_bo *bo; + int err = 0; + + gem = drm_gem_object_lookup(drm, file, args->handle); + if (!gem) + return -ENOENT; + + bo = to_tegra_bo(gem); + + switch (bo->tiling.mode) { + case TEGRA_BO_TILING_MODE_PITCH: + args->mode = DRM_TEGRA_GEM_TILING_MODE_PITCH; + args->value = 0; + break; + + case TEGRA_BO_TILING_MODE_TILED: + args->mode = DRM_TEGRA_GEM_TILING_MODE_TILED; + args->value = 0; + break; + + case TEGRA_BO_TILING_MODE_BLOCK: + args->mode = DRM_TEGRA_GEM_TILING_MODE_BLOCK; + args->value = bo->tiling.value; + break; + + default: + err = -EINVAL; + break; + } + + drm_gem_object_unreference(gem); + + return err; +} #endif static const struct drm_ioctl_desc tegra_drm_ioctls[] = { @@ -469,6 +562,8 @@ static const struct drm_ioctl_desc tegra_drm_ioctls[] = { DRM_IOCTL_DEF_DRV(TEGRA_GET_SYNCPT, tegra_get_syncpt, DRM_UNLOCKED), DRM_IOCTL_DEF_DRV(TEGRA_SUBMIT, tegra_submit, DRM_UNLOCKED), DRM_IOCTL_DEF_DRV(TEGRA_GET_SYNCPT_BASE, tegra_get_syncpt_base, DRM_UNLOCKED), + DRM_IOCTL_DEF_DRV(TEGRA_GEM_SET_TILING, tegra_gem_set_tiling, DRM_UNLOCKED), + DRM_IOCTL_DEF_DRV(TEGRA_GEM_GET_TILING, tegra_gem_get_tiling, DRM_UNLOCKED), #endif }; |