Skip to content

Commit

Permalink
drm/i915 Add ctm_post_offset
Browse files Browse the repository at this point in the history
Add ctm_post_offset property drm ioctl
interface and color post offset setting
for color adjustment

Signed-off-by: Lin Jia <[email protected]>
  • Loading branch information
ljia5 committed Feb 26, 2024
1 parent 61185da commit df73277
Show file tree
Hide file tree
Showing 12 changed files with 79 additions and 3 deletions.
3 changes: 3 additions & 0 deletions drivers/gpu/drm/drm_atomic_state_helper.c
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,8 @@ void __drm_atomic_helper_crtc_duplicate_state(struct drm_crtc *crtc,
drm_property_blob_get(state->degamma_lut);
if (state->ctm)
drm_property_blob_get(state->ctm);
if (state->ctm_post_offset)
drm_property_blob_get(state->ctm_post_offset);
if (state->gamma_lut)
drm_property_blob_get(state->gamma_lut);
state->mode_changed = false;
Expand Down Expand Up @@ -214,6 +216,7 @@ void __drm_atomic_helper_crtc_destroy_state(struct drm_crtc_state *state)
drm_property_blob_put(state->mode_blob);
drm_property_blob_put(state->degamma_lut);
drm_property_blob_put(state->ctm);
drm_property_blob_put(state->ctm_post_offset);
drm_property_blob_put(state->gamma_lut);
}
EXPORT_SYMBOL(__drm_atomic_helper_crtc_destroy_state);
Expand Down
10 changes: 10 additions & 0 deletions drivers/gpu/drm/drm_atomic_uapi.c
Original file line number Diff line number Diff line change
Expand Up @@ -430,6 +430,14 @@ static int drm_atomic_crtc_set_property(struct drm_crtc *crtc,
&replaced);
state->color_mgmt_changed |= replaced;
return ret;
} else if (property == config->ctm_post_offset_property) {
ret = drm_atomic_replace_property_blob_from_id(dev,
&state->ctm_post_offset,
val,
sizeof(struct drm_color_ctm_post_offset), -1,
&replaced);
state->color_mgmt_changed |= replaced;
return ret;
} else if (property == config->gamma_lut_property) {
ret = drm_atomic_replace_property_blob_from_id(dev,
&state->gamma_lut,
Expand Down Expand Up @@ -481,6 +489,8 @@ drm_atomic_crtc_get_property(struct drm_crtc *crtc,
*val = (state->degamma_lut) ? state->degamma_lut->base.id : 0;
else if (property == config->ctm_property)
*val = (state->ctm) ? state->ctm->base.id : 0;
else if (property == config->ctm_post_offset_property)
*val = (state->ctm) ? state->ctm_post_offset->base.id : 0;
else if (property == config->gamma_lut_property)
*val = (state->gamma_lut) ? state->gamma_lut->base.id : 0;
else if (property == config->prop_out_fence_ptr)
Expand Down
6 changes: 5 additions & 1 deletion drivers/gpu/drm/drm_color_mgmt.c
Original file line number Diff line number Diff line change
Expand Up @@ -177,9 +177,12 @@ void drm_crtc_enable_color_mgmt(struct drm_crtc *crtc,
degamma_lut_size);
}

if (has_ctm)
if (has_ctm) {
drm_object_attach_property(&crtc->base,
config->ctm_property, 0);
drm_object_attach_property(&crtc->base,
config->ctm_post_offset_property, 0);
}

if (gamma_lut_size) {
drm_object_attach_property(&crtc->base,
Expand Down Expand Up @@ -330,6 +333,7 @@ static int drm_crtc_legacy_gamma_set(struct drm_crtc *crtc,
replaced = drm_property_replace_blob(&crtc_state->degamma_lut,
use_gamma_lut ? NULL : blob);
replaced |= drm_property_replace_blob(&crtc_state->ctm, NULL);
replaced |= drm_property_replace_blob(&crtc_state->ctm_post_offset, NULL);
replaced |= drm_property_replace_blob(&crtc_state->gamma_lut,
use_gamma_lut ? blob : NULL);
crtc_state->color_mgmt_changed |= replaced;
Expand Down
7 changes: 7 additions & 0 deletions drivers/gpu/drm/drm_mode_config.c
Original file line number Diff line number Diff line change
Expand Up @@ -354,6 +354,13 @@ static int drm_mode_create_standard_properties(struct drm_device *dev)
return -ENOMEM;
dev->mode_config.ctm_property = prop;

prop = drm_property_create(dev,
DRM_MODE_PROP_BLOB,
"CTM_POST_OFFSET", 0);
if (!prop)
return -ENOMEM;
dev->mode_config.ctm_post_offset_property = prop;

prop = drm_property_create(dev,
DRM_MODE_PROP_BLOB,
"GAMMA_LUT", 0);
Expand Down
3 changes: 3 additions & 0 deletions drivers/gpu/drm/i915/display/intel_atomic.c
Original file line number Diff line number Diff line change
Expand Up @@ -249,6 +249,8 @@ intel_crtc_duplicate_state(struct drm_crtc *crtc)
drm_property_blob_get(crtc_state->hw.degamma_lut);
if (crtc_state->hw.ctm)
drm_property_blob_get(crtc_state->hw.ctm);
if (crtc_state->hw.ctm_post_offset)
drm_property_blob_get(crtc_state->hw.ctm_post_offset);
if (crtc_state->hw.gamma_lut)
drm_property_blob_get(crtc_state->hw.gamma_lut);

Expand All @@ -274,6 +276,7 @@ static void intel_crtc_put_color_blobs(struct intel_crtc_state *crtc_state)
drm_property_blob_put(crtc_state->hw.degamma_lut);
drm_property_blob_put(crtc_state->hw.gamma_lut);
drm_property_blob_put(crtc_state->hw.ctm);
drm_property_blob_put(crtc_state->hw.ctm_post_offset);
}

void intel_crtc_free_hw_state(struct intel_crtc_state *crtc_state)
Expand Down
23 changes: 22 additions & 1 deletion drivers/gpu/drm/i915/display/intel_color.c
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,7 @@ static bool crtc_state_is_legacy_gamma(const struct intel_crtc_state *crtc_state
{
return !crtc_state->hw.degamma_lut &&
!crtc_state->hw.ctm &&
!crtc_state->hw.ctm_post_offset &&
crtc_state->hw.gamma_lut &&
lut_is_legacy(crtc_state->hw.gamma_lut);
}
Expand Down Expand Up @@ -352,13 +353,33 @@ static void ilk_load_csc_matrix(const struct intel_crtc_state *crtc_state)
static void icl_load_csc_matrix(const struct intel_crtc_state *crtc_state)
{
struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev);

if (crtc_state->hw.ctm) {
u16 coeff[9];

ilk_csc_convert_ctm(crtc_state, coeff);
ilk_update_pipe_csc(crtc, ilk_csc_off_zero,
if (crtc_state->hw.ctm_post_offset) {
const struct drm_color_ctm_post_offset *ctm_post_offset = crtc_state->hw.ctm_post_offset->data;
/* Nop pre/post offsets */
u16 csc_off[3] = {};
csc_off[0] = ctm_post_offset->red;
csc_off[1] = ctm_post_offset->green;
csc_off[2] = ctm_post_offset->blue;
drm_dbg_kms(&dev_priv->drm,
"csc_off[0] = %d\n", csc_off[0]);
drm_dbg_kms(&dev_priv->drm,
"csc_off[1] = %d\n", csc_off[1]);
drm_dbg_kms(&dev_priv->drm,
"csc_off[2] = %d\n", csc_off[2]);
ilk_update_pipe_csc(crtc, ilk_csc_off_zero,
coeff, csc_off);
} else {
drm_dbg_kms(&dev_priv->drm,
"csc_off_zero\n");
ilk_update_pipe_csc(crtc, ilk_csc_off_zero,
coeff, ilk_csc_off_zero);
}
}

if (crtc_state->output_format != INTEL_OUTPUT_FORMAT_RGB) {
Expand Down
4 changes: 4 additions & 0 deletions drivers/gpu/drm/i915/display/intel_display.c
Original file line number Diff line number Diff line change
Expand Up @@ -5065,6 +5065,8 @@ intel_crtc_copy_uapi_to_hw_state_nomodeset(struct intel_atomic_state *state,
crtc_state->uapi.gamma_lut);
drm_property_replace_blob(&crtc_state->hw.ctm,
crtc_state->uapi.ctm);
drm_property_replace_blob(&crtc_state->hw.ctm_post_offset,
crtc_state->uapi.ctm_post_offset);
}

static void
Expand Down Expand Up @@ -5103,6 +5105,8 @@ copy_bigjoiner_crtc_state_nomodeset(struct intel_atomic_state *state,
master_crtc_state->hw.gamma_lut);
drm_property_replace_blob(&slave_crtc_state->hw.ctm,
master_crtc_state->hw.ctm);
drm_property_replace_blob(&slave_crtc_state->hw.ctm_post_offset,
master_crtc_state->hw.ctm_post_offset);

slave_crtc_state->uapi.color_mgmt_changed = master_crtc_state->uapi.color_mgmt_changed;
}
Expand Down
2 changes: 1 addition & 1 deletion drivers/gpu/drm/i915/display/intel_display_types.h
Original file line number Diff line number Diff line change
Expand Up @@ -1001,7 +1001,7 @@ struct intel_crtc_state {
*/
struct {
bool active, enable;
struct drm_property_blob *degamma_lut, *gamma_lut, *ctm;
struct drm_property_blob *degamma_lut, *gamma_lut, *ctm, *ctm_post_offset;
struct drm_display_mode mode, pipe_mode, adjusted_mode;
enum drm_scaling_filter scaling_filter;
} hw;
Expand Down
3 changes: 3 additions & 0 deletions drivers/gpu/drm/i915/display/intel_modeset_setup.c
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,9 @@ static void intel_crtc_copy_hw_to_uapi_state(struct intel_crtc_state *crtc_state
crtc_state->hw.gamma_lut);
drm_property_replace_blob(&crtc_state->uapi.ctm,
crtc_state->hw.ctm);
drm_property_replace_blob(&crtc_state->uapi.ctm_post_offset,
crtc_state->hw.ctm_post_offset);

}

static void
Expand Down
8 changes: 8 additions & 0 deletions include/drm/drm_crtc.h
Original file line number Diff line number Diff line change
Expand Up @@ -267,6 +267,14 @@ struct drm_crtc_state {
*/
struct drm_property_blob *ctm;

/**
* @ctm_post_offset:
*
* Color transformation matrix. See drm_crtc_enable_color_mgmt(). The
* blob (if not NULL) is a &struct drm_color_ctm.
*/
struct drm_property_blob *ctm_post_offset;

/**
* @gamma_lut:
*
Expand Down
6 changes: 6 additions & 0 deletions include/drm/drm_mode_config.h
Original file line number Diff line number Diff line change
Expand Up @@ -800,6 +800,12 @@ struct drm_mode_config {
* degamma LUT.
*/
struct drm_property *ctm_property;
/**
* @ctm_post_offset_property: Optional CRTC property to set the
* matrix used to convert colors after the lookup in the
* degamma LUT.
*/
struct drm_property *ctm_post_offset_property;
/**
* @gamma_lut_property: Optional CRTC property to set the LUT used to
* convert the colors, after the CTM matrix, to the gamma space of the
Expand Down
7 changes: 7 additions & 0 deletions include/uapi/drm/drm_mode.h
Original file line number Diff line number Diff line change
Expand Up @@ -840,6 +840,13 @@ struct drm_color_ctm {
__u64 matrix[9];
};

struct drm_color_ctm_post_offset {
/* Data is U0.16 fixed point format. */
__u16 red;
__u16 green;
__u16 blue;
};

struct drm_color_lut {
/*
* Values are mapped linearly to 0.0 - 1.0 range, with 0x0 == 0.0 and
Expand Down

0 comments on commit df73277

Please sign in to comment.