Implement i.MX specific ioctl to set gamma directly using slope and y-intercept values that define the piecewise linear gamma correction curve. Signed-off-by: Steve Longerbeam <steve_longerbeam@xxxxxxxxxx> --- drivers/staging/imx-drm/imx-drm-core.c | 40 +++++++++++++++++++++++++++++++- drivers/staging/imx-drm/imx-drm.h | 3 +-- drivers/staging/imx-drm/ipuv3-crtc.c | 9 +++++++ include/uapi/drm/imx_drm.h | 30 ++++++++++++++++++++++++ 4 files changed, 79 insertions(+), 3 deletions(-) create mode 100644 include/uapi/drm/imx_drm.h diff --git a/drivers/staging/imx-drm/imx-drm-core.c b/drivers/staging/imx-drm/imx-drm-core.c index 084ed53..4c85fd3 100644 --- a/drivers/staging/imx-drm/imx-drm-core.c +++ b/drivers/staging/imx-drm/imx-drm-core.c @@ -24,6 +24,7 @@ #include <drm/drm_crtc_helper.h> #include <drm/drm_gem_cma_helper.h> #include <drm/drm_fb_cma_helper.h> +#include <drm/imx_drm.h> #include "imx-drm.h" @@ -122,6 +123,18 @@ static struct imx_drm_crtc *imx_drm_find_crtc(struct drm_crtc *crtc) return NULL; } +static struct imx_drm_crtc *imx_drm_find_crtc_by_id(struct drm_device *drm, + u32 crtc_id) +{ + struct drm_crtc *crtc; + + crtc = drm_crtc_find(drm, crtc_id); + if (!crtc) + return NULL; + + return imx_drm_find_crtc(crtc); +} + int imx_drm_panel_format_pins(struct drm_encoder *encoder, u32 interface_pix_fmt, int hsync_pin, int vsync_pin) { @@ -537,8 +550,33 @@ int imx_drm_encoder_get_mux_id(struct device_node *node, } EXPORT_SYMBOL_GPL(imx_drm_encoder_get_mux_id); +static int drm_imx_set_gamma_ioctl(struct drm_device *drm, void *data, + struct drm_file *file_priv) +{ + struct drm_imx_gamma *g = data; + struct imx_drm_crtc_helper_funcs *helper; + struct imx_drm_crtc *imx_crtc; + int ret = -EINVAL; + + if (!drm_core_check_feature(drm, DRIVER_MODESET)) + return -ENODEV; + + drm_modeset_lock_all(drm); + + imx_crtc = imx_drm_find_crtc_by_id(drm, g->crtc_id); + if (!imx_crtc) + goto out_unlock; + + helper = &imx_crtc->imx_drm_helper_funcs; + ret = helper->gamma_set(imx_crtc->crtc, g->enable, g->m, g->b); + +out_unlock: + drm_modeset_unlock_all(drm); + return ret; +} + static const struct drm_ioctl_desc imx_drm_ioctls[] = { - /* none so far */ + DRM_IOCTL_DEF_DRV(IMX_SET_GAMMA, drm_imx_set_gamma_ioctl, DRM_AUTH), }; static struct drm_driver imx_drm_driver = { diff --git a/drivers/staging/imx-drm/imx-drm.h b/drivers/staging/imx-drm/imx-drm.h index bf6b06b..0bb4735 100644 --- a/drivers/staging/imx-drm/imx-drm.h +++ b/drivers/staging/imx-drm/imx-drm.h @@ -21,6 +21,7 @@ struct imx_drm_crtc_helper_funcs { void (*disable_vblank)(struct drm_crtc *crtc, int pipe); int (*set_interface_pix_fmt)(struct drm_crtc *crtc, u32 encoder_type, u32 pix_fmt, int hsync_pin, int vsync_pin); + int (*gamma_set)(struct drm_crtc *crtc, bool enable, u32 *m, u32 *b); const struct drm_crtc_helper_funcs *crtc_helper_funcs; const struct drm_crtc_funcs *crtc_funcs; }; @@ -52,6 +53,4 @@ int imx_drm_encoder_parse_of(struct drm_device *drm, void imx_drm_connector_destroy(struct drm_connector *connector); void imx_drm_encoder_destroy(struct drm_encoder *encoder); -#define DRM_IMX_GAMMA_SIZE 16 - #endif /* _IMX_DRM_H_ */ diff --git a/drivers/staging/imx-drm/ipuv3-crtc.c b/drivers/staging/imx-drm/ipuv3-crtc.c index 4f2ba40..8d7c998 100644 --- a/drivers/staging/imx-drm/ipuv3-crtc.c +++ b/drivers/staging/imx-drm/ipuv3-crtc.c @@ -29,6 +29,7 @@ #include <linux/errno.h> #include <drm/drm_gem_cma_helper.h> #include <drm/drm_fb_cma_helper.h> +#include <drm/imx_drm.h> #include <video/imx-ipu-v3.h> #include "imx-drm.h" @@ -405,10 +406,18 @@ static int ipu_set_interface_pix_fmt(struct drm_crtc *crtc, u32 encoder_type, return 0; } +static int ipu_gamma_set(struct drm_crtc *crtc, bool enable, u32 *m, u32 *b) +{ + struct ipu_crtc *ipu_crtc = to_ipu_crtc(crtc); + + return ipu_plane_gamma_set(&ipu_crtc->plane[0], true, m, b); +} + static const struct imx_drm_crtc_helper_funcs ipu_crtc_helper_funcs = { .enable_vblank = ipu_enable_vblank, .disable_vblank = ipu_disable_vblank, .set_interface_pix_fmt = ipu_set_interface_pix_fmt, + .gamma_set = ipu_gamma_set, .crtc_funcs = &ipu_crtc_funcs, .crtc_helper_funcs = &ipu_helper_funcs, }; diff --git a/include/uapi/drm/imx_drm.h b/include/uapi/drm/imx_drm.h new file mode 100644 index 0000000..b0a03d6 --- /dev/null +++ b/include/uapi/drm/imx_drm.h @@ -0,0 +1,30 @@ +/* + * include/uapi/drm/imx_drm.h + * + * Copyright (C) 2013-2014 Mentor Graphics + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + */ + +#ifndef __IMX_DRM_H__ +#define __IMX_DRM_H__ + +#include <drm/drm.h> + +#define DRM_IMX_GAMMA_SIZE 16 +struct drm_imx_gamma { + bool enable; + uint32_t crtc_id; + uint32_t m[DRM_IMX_GAMMA_SIZE]; + uint32_t b[DRM_IMX_GAMMA_SIZE]; +}; + +#define DRM_IMX_SET_GAMMA 0x00 + +#define DRM_IOCTL_IMX_SET_GAMMA \ + DRM_IOW(DRM_COMMAND_BASE + DRM_IMX_SET_GAMMA, struct drm_imx_gamma) + +#endif /* __IMX_DRM_H__ */ -- 1.7.9.5 _______________________________________________ dri-devel mailing list dri-devel@xxxxxxxxxxxxxxxxxxxxx http://lists.freedesktop.org/mailman/listinfo/dri-devel