summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDhaval Patel <pdhaval@quicinc.com>2016-10-10 10:19:48 -0700
committerGerrit - the friendly Code Review server <code-review@localhost>2016-10-10 10:19:48 -0700
commit58420141bd4bacadc838fbe82450549f1bd9d4ff (patch)
tree9d1d657dc23bb26f63e692d6b7bca36b551a81f3
parentdcdf59950f5dc2a0e0d5e066188f205b71313721 (diff)
parent1f819168bd4460619d250e1053886ffa7175d724 (diff)
Merge "drm/msm/sde: update csc property definition and type" into dev/msm-4.4-drm_kms
-rw-r--r--drivers/gpu/drm/msm/msm_drv.h2
-rw-r--r--drivers/gpu/drm/msm/msm_prop.c37
-rw-r--r--drivers/gpu/drm/msm/msm_prop.h26
-rw-r--r--drivers/gpu/drm/msm/sde/sde_plane.c145
-rw-r--r--include/uapi/drm/sde_drm.h16
5 files changed, 129 insertions, 97 deletions
diff --git a/drivers/gpu/drm/msm/msm_drv.h b/drivers/gpu/drm/msm/msm_drv.h
index 30aea910bee8..2266d2ab2f00 100644
--- a/drivers/gpu/drm/msm/msm_drv.h
+++ b/drivers/gpu/drm/msm/msm_drv.h
@@ -81,7 +81,7 @@ struct msm_file_private {
enum msm_mdp_plane_property {
/* blob properties, always put these first */
PLANE_PROP_SCALER,
- PLANE_PROP_CSC,
+ PLANE_PROP_CSC_V1,
PLANE_PROP_INFO,
/* # of blob properties */
diff --git a/drivers/gpu/drm/msm/msm_prop.c b/drivers/gpu/drm/msm/msm_prop.c
index 90310fb6369e..5a9e472ea59b 100644
--- a/drivers/gpu/drm/msm/msm_prop.c
+++ b/drivers/gpu/drm/msm/msm_prop.c
@@ -134,9 +134,20 @@ static void _msm_property_set_dirty_no_lock(
&info->dirty_list);
}
-void msm_property_install_range(struct msm_property_info *info,
+/**
+ * _msm_property_install_integer - install standard drm range property
+ * @info: Pointer to property info container struct
+ * @name: Property name
+ * @flags: Other property type flags, e.g. DRM_MODE_PROP_IMMUTABLE
+ * @min: Min property value
+ * @max: Max property value
+ * @init: Default Property value
+ * @property_idx: Property index
+ * @force_dirty: Whether or not to filter 'dirty' status on unchanged values
+ */
+static void _msm_property_install_integer(struct msm_property_info *info,
const char *name, int flags, uint64_t min, uint64_t max,
- uint64_t init, uint32_t property_idx)
+ uint64_t init, uint32_t property_idx, bool force_dirty)
{
struct drm_property **prop;
@@ -162,6 +173,7 @@ void msm_property_install_range(struct msm_property_info *info,
/* save init value for later */
info->property_data[property_idx].default_value = init;
+ info->property_data[property_idx].force_dirty = force_dirty;
/* always attach property, if created */
if (*prop) {
@@ -171,6 +183,22 @@ void msm_property_install_range(struct msm_property_info *info,
}
}
+void msm_property_install_range(struct msm_property_info *info,
+ const char *name, int flags, uint64_t min, uint64_t max,
+ uint64_t init, uint32_t property_idx)
+{
+ _msm_property_install_integer(info, name, flags,
+ min, max, init, property_idx, false);
+}
+
+void msm_property_install_volatile_range(struct msm_property_info *info,
+ const char *name, int flags, uint64_t min, uint64_t max,
+ uint64_t init, uint32_t property_idx)
+{
+ _msm_property_install_integer(info, name, flags,
+ min, max, init, property_idx, true);
+}
+
void msm_property_install_rotation(struct msm_property_info *info,
unsigned int supported_rotations, uint32_t property_idx)
{
@@ -198,6 +226,7 @@ void msm_property_install_rotation(struct msm_property_info *info,
/* save init value for later */
info->property_data[property_idx].default_value = 0;
+ info->property_data[property_idx].force_dirty = false;
/* always attach property, if created */
if (*prop) {
@@ -244,6 +273,7 @@ void msm_property_install_enum(struct msm_property_info *info,
/* save init value for later */
info->property_data[property_idx].default_value = 0;
+ info->property_data[property_idx].force_dirty = false;
/* always attach property, if created */
if (*prop) {
@@ -281,6 +311,7 @@ void msm_property_install_blob(struct msm_property_info *info,
/* save init value for later */
info->property_data[property_idx].default_value = 0;
+ info->property_data[property_idx].force_dirty = true;
/* always attach property, if created */
if (*prop) {
@@ -377,7 +408,7 @@ int msm_property_atomic_set(struct msm_property_info *info,
/* update value and flag as dirty */
if (property_values[property_idx] != val ||
- property_idx < info->blob_count) {
+ info->property_data[property_idx].force_dirty) {
property_values[property_idx] = val;
_msm_property_set_dirty_no_lock(info, property_idx);
diff --git a/drivers/gpu/drm/msm/msm_prop.h b/drivers/gpu/drm/msm/msm_prop.h
index f065cbffda09..dbe28bdf5638 100644
--- a/drivers/gpu/drm/msm/msm_prop.h
+++ b/drivers/gpu/drm/msm/msm_prop.h
@@ -23,10 +23,13 @@
* drm-object per property stuff
* @default_value: Default property value for this drm object
* @dirty_node: Linked list node to track if property is dirty or not
+ * @force_dirty: Always dirty property on incoming sets, rather than checking
+ * for modified values
*/
struct msm_property_data {
uint64_t default_value;
struct list_head dirty_node;
+ bool force_dirty;
};
/**
@@ -172,7 +175,7 @@ void msm_property_destroy(struct msm_property_info *info);
* @flags: Other property type flags, e.g. DRM_MODE_PROP_IMMUTABLE
* @min: Min property value
* @max: Max property value
- * @init: Default property value
+ * @init: Default Property value
* @property_idx: Property index
*/
void msm_property_install_range(struct msm_property_info *info,
@@ -184,6 +187,27 @@ void msm_property_install_range(struct msm_property_info *info,
uint32_t property_idx);
/**
+ * msm_property_install_volatile_range - install drm range property
+ * This function is similar to msm_property_install_range, but assumes
+ * that the property is meant for holding user pointers or descriptors
+ * that may reference volatile data without having an updated value.
+ * @info: Pointer to property info container struct
+ * @name: Property name
+ * @flags: Other property type flags, e.g. DRM_MODE_PROP_IMMUTABLE
+ * @min: Min property value
+ * @max: Max property value
+ * @init: Default Property value
+ * @property_idx: Property index
+ */
+void msm_property_install_volatile_range(struct msm_property_info *info,
+ const char *name,
+ int flags,
+ uint64_t min,
+ uint64_t max,
+ uint64_t init,
+ uint32_t property_idx);
+
+/**
* msm_property_install_rotation - install standard drm rotation property
* @info: Pointer to property info container struct
* @supported_rotations: Bitmask of supported rotation values (see
diff --git a/drivers/gpu/drm/msm/sde/sde_plane.c b/drivers/gpu/drm/msm/sde/sde_plane.c
index dbc531b68d66..661695eaf72d 100644
--- a/drivers/gpu/drm/msm/sde/sde_plane.c
+++ b/drivers/gpu/drm/msm/sde/sde_plane.c
@@ -58,6 +58,12 @@ enum sde_plane_qos {
SDE_PLANE_QOS_PANIC_CTRL = BIT(2),
};
+/*
+ * struct sde_plane - local sde plane structure
+ * @csc_cfg: Decoded user configuration for csc
+ * @csc_usr_ptr: Points to csc_cfg if valid user config available
+ * @csc_ptr: Points to sde_csc_cfg structure to use for current
+ */
struct sde_plane {
struct drm_plane base;
@@ -81,6 +87,7 @@ struct sde_plane {
bool is_rt_pipe;
struct sde_csc_cfg csc_cfg;
+ struct sde_csc_cfg *csc_usr_ptr;
struct sde_csc_cfg *csc_ptr;
const struct sde_sspp_sub_blks *pipe_sblk;
@@ -736,9 +743,7 @@ static int _sde_plane_verify_blob(void *blob_ptr,
return -EINVAL;
}
-static void _sde_plane_setup_csc(struct sde_plane *psde,
- struct sde_plane_state *pstate,
- const struct sde_format *fmt)
+static inline void _sde_plane_setup_csc(struct sde_plane *psde)
{
static const struct sde_csc_cfg sde_csc_YUV2RGB_601L = {
{
@@ -754,78 +759,22 @@ static void _sde_plane_setup_csc(struct sde_plane *psde,
{ 0x10, 0xeb, 0x10, 0xf0, 0x10, 0xf0,},
{ 0x00, 0xff, 0x00, 0xff, 0x00, 0xff,},
};
- static const struct sde_csc_cfg sde_csc_NOP = {
- {
- /* identity matrix, S15.16 format */
- 0x10000, 0x00000, 0x00000,
- 0x00000, 0x10000, 0x00000,
- 0x00000, 0x00000, 0x10000,
- },
- /* signed bias */
- { 0x0, 0x0, 0x0,},
- { 0x0, 0x0, 0x0,},
- /* unsigned clamp */
- { 0x0, 0xff, 0x0, 0xff, 0x0, 0xff,},
- { 0x0, 0xff, 0x0, 0xff, 0x0, 0xff,},
- };
- struct sde_drm_csc *csc = NULL;
- size_t csc_size = 0;
- int i;
- if (!psde || !pstate || !fmt) {
- SDE_ERROR("invalid arguments\n");
- return;
- }
- if (!psde->pipe_hw || !psde->pipe_hw->ops.setup_csc)
+ if (!psde) {
+ SDE_ERROR("invalid plane\n");
return;
-
- /* check for user space override */
- psde->csc_ptr = NULL;
- csc = msm_property_get_blob(&psde->property_info,
- pstate->property_blobs,
- &csc_size,
- PLANE_PROP_CSC);
- if (csc) {
- /* user space override */
- memcpy(&psde->csc_cfg,
- &sde_csc_NOP,
- sizeof(struct sde_csc_cfg));
- switch (csc->version) {
- case SDE_DRM_CSC_V1:
- if (!_sde_plane_verify_blob(csc,
- csc_size,
- &csc->v1,
- sizeof(struct sde_drm_csc_v1))) {
- for (i = 0; i < SDE_CSC_MATRIX_COEFF_SIZE; ++i)
- psde->csc_cfg.csc_mv[i] =
- csc->v1.ctm_coeff[i] >> 16;
- for (i = 0; i < SDE_CSC_BIAS_SIZE; ++i) {
- psde->csc_cfg.csc_pre_bv[i] =
- csc->v1.pre_bias[i];
- psde->csc_cfg.csc_post_bv[i] =
- csc->v1.post_bias[i];
- }
- for (i = 0; i < SDE_CSC_CLAMP_SIZE; ++i) {
- psde->csc_cfg.csc_pre_lv[i] =
- csc->v1.pre_clamp[i];
- psde->csc_cfg.csc_post_lv[i] =
- csc->v1.post_clamp[i];
- }
- psde->csc_ptr = &psde->csc_cfg;
- }
- break;
- default:
- break;
- }
- if (!psde->csc_ptr)
- SDE_ERROR("invalid csc blob, v%lld\n", csc->version);
}
/* revert to kernel default if override not available */
- if (psde->csc_ptr)
- SDE_DEBUG("user blob override for csc\n");
- else if (SDE_FORMAT_IS_YUV(fmt))
+ if (psde->csc_usr_ptr)
+ psde->csc_ptr = psde->csc_usr_ptr;
+ else
psde->csc_ptr = (struct sde_csc_cfg *)&sde_csc_YUV2RGB_601L;
+
+ SDE_DEBUG("using 0x%X 0x%X 0x%X...\n",
+ psde->csc_ptr->csc_mv[0],
+ psde->csc_ptr->csc_mv[1],
+ psde->csc_ptr->csc_mv[2]);
}
static void _sde_plane_setup_scaler(struct sde_plane *psde,
@@ -1096,7 +1045,7 @@ static int _sde_plane_mode_set(struct drm_plane *plane,
case PLANE_PROP_SCALER:
pstate->dirty |= SDE_PLANE_DIRTY_RECTS;
break;
- case PLANE_PROP_CSC:
+ case PLANE_PROP_CSC_V1:
pstate->dirty |= SDE_PLANE_DIRTY_FORMAT;
break;
case PLANE_PROP_COLOR_FILL:
@@ -1203,7 +1152,7 @@ static int _sde_plane_mode_set(struct drm_plane *plane,
/* update csc */
if (SDE_FORMAT_IS_YUV(fmt))
- _sde_plane_setup_csc(psde, pstate, fmt);
+ _sde_plane_setup_csc(psde);
else
psde->csc_ptr = 0;
}
@@ -1587,6 +1536,11 @@ static void _sde_plane_install_properties(struct drm_plane *plane,
msm_property_install_range(&psde->property_info, "input_fence",
0x0, 0, INR_OPEN_MAX, 0, PLANE_PROP_INPUT_FENCE);
+ if (psde->features & BIT(SDE_SSPP_CSC)) {
+ msm_property_install_volatile_range(&psde->property_info,
+ "csc_v1", 0x0, 0, ~0, 0, PLANE_PROP_CSC_V1);
+ }
+
/* standard properties */
msm_property_install_rotation(&psde->property_info,
BIT(DRM_REFLECT_X) | BIT(DRM_REFLECT_Y), PLANE_PROP_ROTATION);
@@ -1605,10 +1559,6 @@ static void _sde_plane_install_properties(struct drm_plane *plane,
msm_property_install_blob(&psde->property_info, "scaler", 0,
PLANE_PROP_SCALER);
- if (psde->features & BIT(SDE_SSPP_CSC))
- msm_property_install_blob(&psde->property_info, "csc", 0,
- PLANE_PROP_CSC);
-
info = kzalloc(sizeof(struct sde_kms_info), GFP_KERNEL);
if (!info)
return;
@@ -1645,6 +1595,40 @@ static void _sde_plane_install_properties(struct drm_plane *plane,
kfree(info);
}
+static inline void _sde_plane_set_csc_v1(struct sde_plane *psde, void *usr_ptr)
+{
+ struct sde_drm_csc_v1 csc_v1;
+ int i;
+
+ if (!psde) {
+ SDE_ERROR("invalid plane\n");
+ return;
+ }
+
+ psde->csc_usr_ptr = NULL;
+ if (!usr_ptr) {
+ SDE_DEBUG("csc data removed\n");
+ return;
+ }
+
+ if (copy_from_user(&csc_v1, usr_ptr, sizeof(csc_v1))) {
+ SDE_ERROR("failed to copy csc data\n");
+ return;
+ }
+
+ for (i = 0; i < SDE_CSC_MATRIX_COEFF_SIZE; ++i)
+ psde->csc_cfg.csc_mv[i] = csc_v1.ctm_coeff[i] >> 16;
+ for (i = 0; i < SDE_CSC_BIAS_SIZE; ++i) {
+ psde->csc_cfg.csc_pre_bv[i] = csc_v1.pre_bias[i];
+ psde->csc_cfg.csc_post_bv[i] = csc_v1.post_bias[i];
+ }
+ for (i = 0; i < SDE_CSC_CLAMP_SIZE; ++i) {
+ psde->csc_cfg.csc_pre_lv[i] = csc_v1.pre_clamp[i];
+ psde->csc_cfg.csc_post_lv[i] = csc_v1.post_clamp[i];
+ }
+ psde->csc_usr_ptr = &psde->csc_cfg;
+}
+
static int sde_plane_atomic_set_property(struct drm_plane *plane,
struct drm_plane_state *state, struct drm_property *property,
uint64_t val)
@@ -1668,8 +1652,17 @@ static int sde_plane_atomic_set_property(struct drm_plane *plane,
if (!ret) {
idx = msm_property_index(&psde->property_info,
property);
- if (idx == PLANE_PROP_INPUT_FENCE)
+ switch (idx) {
+ case PLANE_PROP_INPUT_FENCE:
_sde_plane_set_input_fence(plane, pstate, val);
+ break;
+ case PLANE_PROP_CSC_V1:
+ _sde_plane_set_csc_v1(psde, (void *)val);
+ break;
+ default:
+ /* nothing to do */
+ break;
+ }
}
}
diff --git a/include/uapi/drm/sde_drm.h b/include/uapi/drm/sde_drm.h
index bcd64c23eb14..35b3bc782921 100644
--- a/include/uapi/drm/sde_drm.h
+++ b/include/uapi/drm/sde_drm.h
@@ -188,10 +188,6 @@ struct sde_drm_scaler {
#define SDE_CSC_CLAMP_SIZE 6
#define SDE_CSC_BIAS_SIZE 3
-/* CSC version definition, see top of file for guidelines */
-#define SDE_DRM_CSC_V1 0x1
-#define SDE_DRM_CSC_VERSION SDE_DRM_CSC_V1
-
/**
* struct sde_drm_csc_v1 - version 1 of struct sde_drm_csc
* @ctm_coeff: Matrix coefficients, in S31.32 format
@@ -208,18 +204,6 @@ struct sde_drm_csc_v1 {
uint32_t post_clamp[SDE_CSC_CLAMP_SIZE];
};
-/**
- * struct sde_drm_csc - CSC configuration structure
- * @version: Structure version, set to SDE_DRM_CSC_VERSION
- * @v1: Version 1 of csc structure
- */
-struct sde_drm_csc {
- uint64_t version;
- union {
- struct sde_drm_csc_v1 v1;
- };
-};
-
/* Writeback Config version definition */
#define SDE_DRM_WB_CFG 0x1