On Thu, Jun 04, 2015 at 07:12:41PM +0530, Kausal Malladi wrote:
From: Kausal Malladi Kausal.Malladi@intel.com
This patch does the following:
- Adds the core function to program CSC correction values for CHV/BSW platform
- Adds CSC correction macros/defines
- Adds a pointer to hold blob for CSC property in drm_crtc
Signed-off-by: Shashank Sharma shashank.sharma@intel.com Signed-off-by: Kausal Malladi Kausal.Malladi@intel.com
drivers/gpu/drm/i915/intel_atomic.c | 3 +- drivers/gpu/drm/i915/intel_color_manager.c | 115 +++++++++++++++++++++++++++++ drivers/gpu/drm/i915/intel_color_manager.h | 26 +++++++ 3 files changed, 143 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/i915/intel_atomic.c b/drivers/gpu/drm/i915/intel_atomic.c index 4726847..dcf4694 100644 --- a/drivers/gpu/drm/i915/intel_atomic.c +++ b/drivers/gpu/drm/i915/intel_atomic.c @@ -433,7 +433,8 @@ intel_crtc_atomic_set_property(struct drm_crtc *crtc,
if (property == config->gamma_property) return intel_color_manager_set_gamma(dev, &crtc->base, val);
- if (property == config->csc_property)
return intel_color_manager_set_csc(dev, &crtc->base, val);
- DRM_DEBUG_KMS("Unknown crtc property '%s'\n", property->name); return -EINVAL;
} diff --git a/drivers/gpu/drm/i915/intel_color_manager.c b/drivers/gpu/drm/i915/intel_color_manager.c index 421c267..d904050 100644 --- a/drivers/gpu/drm/i915/intel_color_manager.c +++ b/drivers/gpu/drm/i915/intel_color_manager.c @@ -27,6 +27,108 @@
#include "intel_color_manager.h"
+int chv_set_csc(struct drm_device *dev, uint64_t blob_id,
struct drm_crtc *crtc)
+{
- struct drm_csc *csc_data;
- struct drm_i915_private *dev_priv = dev->dev_private;
- struct drm_property_blob *blob;
- struct drm_mode_config *config = &dev->mode_config;
- u32 reg;
- enum pipe pipe;
- s16 csc_value;
- s32 word, temp;
- int ret, count = 0;
- blob = drm_property_lookup_blob(dev, blob_id);
- if (!blob) {
DRM_ERROR("Invalid Blob ID\n");
return -EINVAL;
- }
- csc_data = (struct drm_csc *)blob->data;
- pipe = to_intel_crtc(crtc)->pipe;
- if (csc_data->csc_format == I915_CSC_COEFF_FORMAT_UNKNOWN) {
/* Disable CSC functionality */
reg = _PIPE_CGM_CONTROL(pipe);
I915_WRITE(reg, I915_READ(reg) & (~CGM_CSC_EN));
DRM_DEBUG_DRIVER("Disabled CSC Functionality on Pipe %c\n",
pipe_name(pipe));
ret = 0;
Same remarks here I did for the gamma property. i915 specific defines for an interface that looks like it want to be generic, UNKNOWN Vs DISABLED, DRM_ERROR, ...
And I haven't actually looked at the CHV details in this pass.
- } else if (csc_data->csc_format == I915_CSC_COEFF_FORMAT_S2_29) {
/* Disable CSC functionality in case it was set earlier */
reg = _PIPE_CGM_CONTROL(pipe);
I915_WRITE(reg, I915_READ(reg) & (~CGM_CSC_EN));
DRM_DEBUG_DRIVER("Disabled CSC Functionality on Pipe %c\n",
pipe_name(pipe));
reg = _PIPE_CSC_BASE(pipe);
while (count < CSC_MAX_VALS) {
/* Rounding off, to decrease loss of precision */
if (csc_data->csc_matrix[count] < 0) {
temp = csc_data->csc_matrix[count];
temp -= CHV_CSC_ROUNDOFF;
if (temp < CHV_CSC_MIN)
temp = CHV_CSC_MIN;
} else {
temp = csc_data->csc_matrix[count];
temp += CHV_CSC_ROUNDOFF;
if (temp > CHV_CSC_MAX)
temp = CHV_CSC_MIN;
}
csc_value = temp >> S2_29_CSC_COEFF_SHIFT;
word = csc_value;
/*
* Last value to be written in 1 register.
* Otherwise, each pair of CSC values go
* into 1 register
*/
if (count != (CSC_MAX_VALS - 1)) {
count++;
csc_value = temp >> S2_29_CSC_COEFF_SHIFT;
temp = csc_value;
temp <<= CHV_CSC_SHIFT;
word |= temp;
}
I915_WRITE(reg, word);
reg += 4;
count++;
}
DRM_DEBUG_DRIVER("All CSC values written to registers\n");
/* Enable CSC functionality */
reg = _PIPE_CGM_CONTROL(pipe);
I915_WRITE(reg, I915_READ(reg) | CGM_CSC_EN);
DRM_DEBUG_DRIVER("CSC enabled on Pipe %c\n",
pipe_name(pipe));
ret = 0;
- } else {
DRM_ERROR("Invalid CSC COEFF Format\n");
return -EINVAL;
- }
- ret = drm_mode_crtc_update_color_property(&blob,
sizeof(struct drm_csc), (void *) csc_data,
&crtc->base, config->csc_property);
- if (ret) {
DRM_ERROR("Error updating CSC blob\n");
crtc->csc_blob_id = INVALID_BLOB_ID;
return -EFAULT;
- }
- /* Save blob ID for future reference */
- crtc->csc_blob_id = blob->base.id;
- return ret;
+}
int chv_set_gamma(struct drm_device *dev, uint32_t blob_id, struct drm_crtc *crtc) { @@ -175,6 +277,19 @@ int chv_set_gamma(struct drm_device *dev, uint32_t blob_id, return ret; }
+int intel_color_manager_set_csc(struct drm_device *dev,
struct drm_mode_object *obj, uint64_t blob_id)
+{
- struct drm_crtc *crtc = obj_to_crtc(obj);
- DRM_DEBUG_DRIVER("\n");
- if (IS_CHERRYVIEW(dev))
return chv_set_csc(dev, blob_id, crtc);
- return -EINVAL;
+}
int intel_color_manager_set_gamma(struct drm_device *dev, struct drm_mode_object *obj, uint32_t blob_id) { diff --git a/drivers/gpu/drm/i915/intel_color_manager.h b/drivers/gpu/drm/i915/intel_color_manager.h index 0acf8e9..8a3e76a 100644 --- a/drivers/gpu/drm/i915/intel_color_manager.h +++ b/drivers/gpu/drm/i915/intel_color_manager.h @@ -41,6 +41,14 @@ #define I915_GAMMA_PRECISION_14BIT (1 << 3) #define I915_GAMMA_PRECISION_16BIT (1 << 4)
+/* Color Management macros for CSC */ +#define I915_PIPE_CSC (1 << 0) +#define I915_PLANE_CSC (1 << 1) +#define I915_CSC_COEFF_FORMAT_UNKNOWN 0 +#define I915_CSC_COEFF_FORMAT_CURRENT 0xFFFFFFFF +#define I915_CSC_COEFF_FORMAT_S1_30 (1 << 0) +#define I915_CSC_COEFF_FORMAT_S2_29 (1 << 1)
#define CHV_MAX_PIPES 3 #define CHV_DISPLAY_BASE 0x180000 #define INVALID_BLOB_ID 9999 @@ -52,6 +60,8 @@ struct rgb_pixel { };
/* CHV CGM Block */ +/* Bit 1 to be enabled */ +#define CGM_CSC_EN 2 /* Bit 2 to be enabled in CGM block for CHV */ #define CGM_GAMMA_EN 4
@@ -74,15 +84,27 @@ struct rgb_pixel { #define CHV_8BIT_GAMMA_SHIFT_GREEN_REG 8 #define CHV_8BIT_GAMMA_SHIFT_RED_REG 16
+/* CSC */ +#define CSC_MAX_VALS 9 +#define CHV_CSC_SHIFT 16 +#define CHV_CSC_ROUNDOFF (1 << 15) +#define CHV_CSC_MAX 0x7FFF +#define CHV_CSC_MIN 0x8000 +#define S2_29_CSC_COEFF_SHIFT 16
/* CGM Registers */ #define CGM_OFFSET 0x2000 #define GAMMA_OFFSET 0x2000 +#define CGM_CSC_OFFSET 0x2000 #define PIPEA_CGM_CONTROL (CHV_DISPLAY_BASE + 0x67A00) #define PIPEA_CGM_GAMMA_MIN (CHV_DISPLAY_BASE + 0x67000) +#define PIPEA_CGM_CSC_MIN (CHV_DISPLAY_BASE + 0x67900) #define _PIPE_CGM_CONTROL(pipe) \ (PIPEA_CGM_CONTROL + (pipe * CGM_OFFSET)) #define _PIPE_GAMMA_BASE(pipe) \ (PIPEA_CGM_GAMMA_MIN + (pipe * GAMMA_OFFSET)) +#define _PIPE_CSC_BASE(pipe) \
- (PIPEA_CGM_CSC_MIN + (pipe * CGM_CSC_OFFSET))
/* Generic Function prototypes */ void intel_color_manager_init(struct drm_device *dev); @@ -90,7 +112,11 @@ void intel_color_manager_attach(struct drm_device *dev, struct drm_mode_object *mode_obj); extern int intel_color_manager_set_gamma(struct drm_device *dev, struct drm_mode_object *obj, uint32_t blob_id); +extern int intel_color_manager_set_csc(struct drm_device *dev,
struct drm_mode_object *obj, uint64_t blob_id);
/* Platform specific function prototypes */ extern int chv_set_gamma(struct drm_device *dev, uint32_t blob_id, struct drm_crtc *crtc); +extern int chv_set_csc(struct drm_device *dev,
uint64_t blob_id, struct drm_crtc *crtc);
-- 2.4.2