aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu')
-rw-r--r--drivers/gpu/drm/drm_atomic_uapi.c8
-rw-r--r--drivers/gpu/drm/drm_blend.c13
-rw-r--r--drivers/gpu/drm/drm_crtc.c40
-rw-r--r--drivers/gpu/drm/drm_crtc_internal.h3
-rw-r--r--drivers/gpu/drm/drm_plane.c73
5 files changed, 137 insertions, 0 deletions
diff --git a/drivers/gpu/drm/drm_atomic_uapi.c b/drivers/gpu/drm/drm_atomic_uapi.c
index 25c269bc4681..ef82009035e6 100644
--- a/drivers/gpu/drm/drm_atomic_uapi.c
+++ b/drivers/gpu/drm/drm_atomic_uapi.c
@@ -469,6 +469,8 @@ static int drm_atomic_crtc_set_property(struct drm_crtc *crtc,
return -EFAULT;
set_out_fence_for_crtc(state->state, crtc, fence_ptr);
+ } else if (property == crtc->scaling_filter_property) {
+ state->scaling_filter = val;
} else if (crtc->funcs->atomic_set_property) {
return crtc->funcs->atomic_set_property(crtc, state, property, val);
} else {
@@ -503,6 +505,8 @@ drm_atomic_crtc_get_property(struct drm_crtc *crtc,
*val = (state->gamma_lut) ? state->gamma_lut->base.id : 0;
else if (property == config->prop_out_fence_ptr)
*val = 0;
+ else if (property == crtc->scaling_filter_property)
+ *val = state->scaling_filter;
else if (crtc->funcs->atomic_get_property)
return crtc->funcs->atomic_get_property(crtc, state, property, val);
else
@@ -585,6 +589,8 @@ static int drm_atomic_plane_set_property(struct drm_plane *plane,
sizeof(struct drm_rect),
&replaced);
return ret;
+ } else if (property == plane->scaling_filter_property) {
+ state->scaling_filter = val;
} else if (plane->funcs->atomic_set_property) {
return plane->funcs->atomic_set_property(plane, state,
property, val);
@@ -643,6 +649,8 @@ drm_atomic_plane_get_property(struct drm_plane *plane,
} else if (property == config->prop_fb_damage_clips) {
*val = (state->fb_damage_clips) ?
state->fb_damage_clips->base.id : 0;
+ } else if (property == plane->scaling_filter_property) {
+ *val = state->scaling_filter;
} else if (plane->funcs->atomic_get_property) {
return plane->funcs->atomic_get_property(plane, state, property, val);
} else {
diff --git a/drivers/gpu/drm/drm_blend.c b/drivers/gpu/drm/drm_blend.c
index f1dcad96f341..ae2234aae93d 100644
--- a/drivers/gpu/drm/drm_blend.c
+++ b/drivers/gpu/drm/drm_blend.c
@@ -194,6 +194,19 @@
* Note that all the property extensions described here apply either to the
* plane or the CRTC (e.g. for the background color, which currently is not
* exposed and assumed to be black).
+ *
+ * SCALING_FILTER:
+ *
+ * Indicates scaling filter to be used for plane scaler
+ *
+ * The value of this property can be one of the following:
+ * Default:
+ * Driver's default scaling filter
+ * Nearest Neighbor:
+ * Nearest Neighbor scaling filter
+ *
+ * Drivers can set up this property for a plane by calling
+ * drm_plane_create_scaling_filter_property
*/
/**
diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
index aecdd7ea26dc..f927976eca50 100644
--- a/drivers/gpu/drm/drm_crtc.c
+++ b/drivers/gpu/drm/drm_crtc.c
@@ -229,6 +229,15 @@ struct dma_fence *drm_crtc_create_fence(struct drm_crtc *crtc)
* user-space must set this property to 0.
*
* Setting MODE_ID to 0 will release reserved resources for the CRTC.
+ * SCALING_FILTER:
+ * Atomic property for setting the scaling filter for CRTC scaler
+ *
+ * The value of this property can be one of the following:
+ * Default:
+ * Driver's default scaling filter
+ * Nearest Neighbor:
+ * Nearest Neighbor scaling filter
+ *
*/
/**
@@ -774,3 +783,34 @@ int drm_mode_crtc_set_obj_prop(struct drm_mode_object *obj,
return ret;
}
+
+/**
+ * drm_crtc_create_scaling_filter_property - create a new scaling filter
+ * property
+ *
+ * @crtc: drm CRTC
+ * @supported_filters: bitmask of supported scaling filters, must include
+ * BIT(DRM_SCALING_FILTER_DEFAULT).
+ *
+ * This function lets driver to enable the scaling filter property on a given
+ * CRTC.
+ *
+ * RETURNS:
+ * Zero for success or -errno
+ */
+int drm_crtc_create_scaling_filter_property(struct drm_crtc *crtc,
+ unsigned int supported_filters)
+{
+ struct drm_property *prop =
+ drm_create_scaling_filter_prop(crtc->dev, supported_filters);
+
+ if (IS_ERR(prop))
+ return PTR_ERR(prop);
+
+ drm_object_attach_property(&crtc->base, prop,
+ DRM_SCALING_FILTER_DEFAULT);
+ crtc->scaling_filter_property = prop;
+
+ return 0;
+}
+EXPORT_SYMBOL(drm_crtc_create_scaling_filter_property);
diff --git a/drivers/gpu/drm/drm_crtc_internal.h b/drivers/gpu/drm/drm_crtc_internal.h
index da96b2f64d7e..54d4cf1233e9 100644
--- a/drivers/gpu/drm/drm_crtc_internal.h
+++ b/drivers/gpu/drm/drm_crtc_internal.h
@@ -72,6 +72,9 @@ int drm_crtc_force_disable(struct drm_crtc *crtc);
struct dma_fence *drm_crtc_create_fence(struct drm_crtc *crtc);
+struct drm_property *
+drm_create_scaling_filter_prop(struct drm_device *dev,
+ unsigned int supported_filters);
/* IOCTLs */
int drm_mode_getcrtc(struct drm_device *dev,
void *data, struct drm_file *file_priv);
diff --git a/drivers/gpu/drm/drm_plane.c b/drivers/gpu/drm/drm_plane.c
index affe1cfed009..e6231947f987 100644
--- a/drivers/gpu/drm/drm_plane.c
+++ b/drivers/gpu/drm/drm_plane.c
@@ -1231,3 +1231,76 @@ out:
return ret;
}
+
+struct drm_property *
+drm_create_scaling_filter_prop(struct drm_device *dev,
+ unsigned int supported_filters)
+{
+ struct drm_property *prop;
+ static const struct drm_prop_enum_list props[] = {
+ { DRM_SCALING_FILTER_DEFAULT, "Default" },
+ { DRM_SCALING_FILTER_NEAREST_NEIGHBOR, "Nearest Neighbor" },
+ };
+ unsigned int valid_mode_mask = BIT(DRM_SCALING_FILTER_DEFAULT) |
+ BIT(DRM_SCALING_FILTER_NEAREST_NEIGHBOR);
+ int i;
+
+ if (WARN_ON((supported_filters & ~valid_mode_mask) ||
+ ((supported_filters & BIT(DRM_SCALING_FILTER_DEFAULT)) == 0)))
+ return ERR_PTR(-EINVAL);
+
+ prop = drm_property_create(dev, DRM_MODE_PROP_ENUM,
+ "SCALING_FILTER",
+ hweight32(supported_filters));
+ if (!prop)
+ return ERR_PTR(-ENOMEM);
+
+ for (i = 0; i < ARRAY_SIZE(props); i++) {
+ int ret;
+
+ if (!(BIT(props[i].type) & supported_filters))
+ continue;
+
+ ret = drm_property_add_enum(prop, props[i].type,
+ props[i].name);
+
+ if (ret) {
+ drm_property_destroy(dev, prop);
+
+ return ERR_PTR(ret);
+ }
+ }
+
+ return prop;
+}
+
+/**
+ * drm_plane_create_scaling_filter_property - create a new scaling filter
+ * property
+ *
+ * @plane: drm plane
+ * @supported_filters: bitmask of supported scaling filters, must include
+ * BIT(DRM_SCALING_FILTER_DEFAULT).
+ *
+ * This function lets driver to enable the scaling filter property on a given
+ * plane.
+ *
+ * RETURNS:
+ * Zero for success or -errno
+ */
+int drm_plane_create_scaling_filter_property(struct drm_plane *plane,
+ unsigned int supported_filters)
+{
+ struct drm_property *prop =
+ drm_create_scaling_filter_prop(plane->dev, supported_filters);
+
+ if (IS_ERR(prop))
+ return PTR_ERR(prop);
+
+ drm_object_attach_property(&plane->base, prop,
+ DRM_SCALING_FILTER_DEFAULT);
+ plane->scaling_filter_property = prop;
+
+ return 0;
+}
+EXPORT_SYMBOL(drm_plane_create_scaling_filter_property);