[RFC PATCH 40/40] drm/amd/display: allow newer DC hardware to use degamma ROM for PQ/HLG

2023-04-23 Thread Melissa Wen
From: Joshua Ashton 

Need to funnel the color caps through to these functions so it can check
that the hardware is capable.

Signed-off-by: Joshua Ashton 
---
 .../amd/display/amdgpu_dm/amdgpu_dm_color.c   | 34 ---
 1 file changed, 21 insertions(+), 13 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
index a034c0c0d383..f0b5f09b9146 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
@@ -336,6 +336,7 @@ static int amdgpu_dm_set_atomic_regamma(struct 
dc_stream_state *stream,
 /**
  * __set_input_tf - calculates the input transfer function based on expected
  * input space.
+ * @caps: dc color capabilities
  * @func: transfer function
  * @lut: lookup table that defines the color space
  * @lut_size: size of respective lut.
@@ -343,7 +344,7 @@ static int amdgpu_dm_set_atomic_regamma(struct 
dc_stream_state *stream,
  * Returns:
  * 0 in case of success. -ENOMEM if fails.
  */
-static int __set_input_tf(struct dc_transfer_func *func,
+static int __set_input_tf(struct dc_color_caps *caps, struct dc_transfer_func 
*func,
  const struct drm_color_lut *lut, uint32_t lut_size)
 {
struct dc_gamma *gamma = NULL;
@@ -360,7 +361,7 @@ static int __set_input_tf(struct dc_transfer_func *func,
__drm_lut_to_dc_gamma(lut, gamma, false);
}
 
-   res = mod_color_calculate_degamma_params(NULL, func, gamma, gamma != 
NULL);
+   res = mod_color_calculate_degamma_params(caps, func, gamma, gamma != 
NULL);
 
if (gamma)
dc_gamma_release();
@@ -512,7 +513,7 @@ static int amdgpu_dm_atomic_blend_lut(const struct 
drm_color_lut *blend_lut,
func_blend->tf = tf;
func_blend->sdr_ref_white_level = 80; /* hardcoded for now */
 
-   ret = __set_input_tf(func_blend, blend_lut, blend_size);
+   ret = __set_input_tf(NULL, func_blend, blend_lut, blend_size);
} else {
func_blend->type = TF_TYPE_BYPASS;
func_blend->tf = TRANSFER_FUNCTION_LINEAR;
@@ -819,7 +820,8 @@ int amdgpu_dm_update_crtc_color_mgmt(struct dm_crtc_state 
*crtc,
 }
 
 static int map_crtc_degamma_to_dc_plane(struct dm_crtc_state *crtc,
-   struct dc_plane_state *dc_plane_state)
+   struct dc_plane_state *dc_plane_state,
+   struct dc_color_caps *caps)
 {
const struct drm_color_lut *degamma_lut;
enum dc_transfer_func_predefined tf = TRANSFER_FUNCTION_SRGB;
@@ -874,7 +876,7 @@ static int map_crtc_degamma_to_dc_plane(struct 
dm_crtc_state *crtc,
dc_plane_state->in_transfer_func->tf =
TRANSFER_FUNCTION_LINEAR;
 
-   r = __set_input_tf(dc_plane_state->in_transfer_func,
+   r = __set_input_tf(caps, dc_plane_state->in_transfer_func,
   degamma_lut, degamma_size);
if (r)
return r;
@@ -887,7 +889,7 @@ static int map_crtc_degamma_to_dc_plane(struct 
dm_crtc_state *crtc,
dc_plane_state->in_transfer_func->tf = tf;
 
if (tf != TRANSFER_FUNCTION_SRGB &&
-   !mod_color_calculate_degamma_params(NULL,
+   !mod_color_calculate_degamma_params(caps,
dc_plane_state->in_transfer_func, NULL, false))
return -ENOMEM;
}
@@ -898,7 +900,8 @@ static int map_crtc_degamma_to_dc_plane(struct 
dm_crtc_state *crtc,
 #ifdef CONFIG_STEAM_DECK
 static int
 __set_dm_plane_degamma(struct drm_plane_state *plane_state,
-  struct dc_plane_state *dc_plane_state)
+  struct dc_plane_state *dc_plane_state,
+  struct dc_color_caps *color_caps)
 {
struct dm_plane_state *dm_plane_state = to_dm_plane_state(plane_state);
const struct drm_color_lut *degamma_lut;
@@ -907,6 +910,9 @@ __set_dm_plane_degamma(struct drm_plane_state *plane_state,
bool has_degamma_lut;
int ret;
 
+   if (dc_plane_state->ctx && dc_plane_state->ctx->dc)
+   color_caps = _plane_state->ctx->dc->caps.color;
+
degamma_lut = __extract_blob_lut(dm_plane_state->degamma_lut, 
_size);
 
has_degamma_lut = degamma_lut &&
@@ -928,8 +934,8 @@ __set_dm_plane_degamma(struct drm_plane_state *plane_state,
dc_plane_state->in_transfer_func->type =
TF_TYPE_DISTRIBUTED_POINTS;
 
-   ret = __set_input_tf(dc_plane_state->in_transfer_func,
-  degamma_lut, degamma_size);
+   ret = __set_input_tf(color_caps, 
dc_plane_state->in_transfer_func,
+degamma_lut, degamma_size);
 

[RFC PATCH 39/40] drm/amd/display: copy dc_plane color settings to surface_updates

2023-04-23 Thread Melissa Wen
As per previous code, copy shaper, 3d and blend settings from dc_plane
to surface_updates before commit.

Signed-off-by: Melissa Wen 
---
 drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
index 0e3b6d414ec4..cdaaec1b2a3a 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -7987,11 +7987,13 @@ static void amdgpu_dm_commit_planes(struct 
drm_atomic_state *state,
continue;
 
bundle->surface_updates[planes_count].surface = dc_plane;
-   if (new_pcrtc_state->color_mgmt_changed) {
+   if (new_pcrtc_state->color_mgmt_changed || 
new_plane_state->color_mgmt_changed) {
bundle->surface_updates[planes_count].gamma = 
dc_plane->gamma_correction;
bundle->surface_updates[planes_count].in_transfer_func 
= dc_plane->in_transfer_func;

bundle->surface_updates[planes_count].gamut_remap_matrix = 
_plane->gamut_remap_matrix;
bundle->surface_updates[planes_count].hdr_mult = 
dc_plane->hdr_mult;
+   bundle->surface_updates[planes_count].func_shaper = 
dc_plane->in_shaper_func;
+   bundle->surface_updates[planes_count].lut3d_func = 
dc_plane->lut3d_func;
}
 
amdgpu_dm_plane_fill_dc_scaling_info(dm->adev, new_plane_state,
-- 
2.39.2



[RFC PATCH 38/40] drm/amd/display: add DRM plane blend LUT and TF support

2023-04-23 Thread Melissa Wen
From: Joshua Ashton 

Map DRM plane blend properties to DPP blend gamma. Plane blend is a
post-3D LUT curve that linearizes color space for blending. It may be
defined by a user-blob LUT and/or predefined transfer function. As
hardcoded curve (ROM) is not supported on blend gamma, we use AMD color
module to fill parameters when setting non-linear TF with empty LUT.

Signed-off-by: Joshua Ashton 
---
 .../amd/display/amdgpu_dm/amdgpu_dm_color.c   | 60 +--
 1 file changed, 56 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
index baa7fea9ebae..a034c0c0d383 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
@@ -493,6 +493,34 @@ static int amdgpu_dm_atomic_shaper_lut(const struct 
drm_color_lut *shaper_lut,
return ret;
 }
 
+static int amdgpu_dm_atomic_blend_lut(const struct drm_color_lut *blend_lut,
+  bool has_rom,
+  enum dc_transfer_func_predefined tf,
+  uint32_t blend_size,
+  struct dc_transfer_func *func_blend)
+{
+   int ret = 0;
+
+   if (blend_size || tf != TRANSFER_FUNCTION_LINEAR) {
+   /* DRM plane gamma LUT or TF means we are linearizing color
+* space before blending (similar to degamma programming). As
+* we don't have hardcoded curve support, or we use AMD color
+* module to fill the parameters that will be translated to HW
+* points.
+*/
+   func_blend->type = TF_TYPE_DISTRIBUTED_POINTS;
+   func_blend->tf = tf;
+   func_blend->sdr_ref_white_level = 80; /* hardcoded for now */
+
+   ret = __set_input_tf(func_blend, blend_lut, blend_size);
+   } else {
+   func_blend->type = TF_TYPE_BYPASS;
+   func_blend->tf = TRANSFER_FUNCTION_LINEAR;
+   }
+
+   return ret;
+}
+
 /* amdgpu_dm_atomic_shaper_lut3d - set DRM CRTC shaper LUT and 3D LUT to DC
  * interface
  * @dc: Display Core control structure
@@ -921,9 +949,11 @@ amdgpu_dm_plane_set_color_properties(struct 
drm_plane_state *plane_state,
 {
struct dm_plane_state *dm_plane_state = to_dm_plane_state(plane_state);
enum drm_transfer_function shaper_tf = DRM_TRANSFER_FUNCTION_DEFAULT;
-   const struct drm_color_lut *shaper_lut, *lut3d;
-   uint32_t lut3d_size, shaper_size;
-
+   enum drm_transfer_function blend_tf = DRM_TRANSFER_FUNCTION_DEFAULT;
+   const struct drm_color_lut *shaper_lut, *lut3d, *blend_lut;
+   uint32_t lut3d_size, shaper_size, blend_size;
+   int ret;
+   
/* We have nothing to do here, return */
if (!plane_state->color_mgmt_changed)
return 0;
@@ -940,8 +970,30 @@ amdgpu_dm_plane_set_color_properties(struct 
drm_plane_state *plane_state,
ret = amdgpu_dm_atomic_shaper_lut(shaper_lut, false,
  drm_tf_to_dc_tf(shaper_tf),
  shaper_size, 
dc_plane_state->in_shaper_func);
+   if (ret) {
+   drm_dbg_kms(plane_state->plane->dev,
+   "setting plane %d shaper/3d lut failed.\n",
+   plane_state->plane->index);
 
-   return ret;
+   return ret;
+   }
+
+   blend_tf = dm_plane_state->blend_tf;
+   blend_lut = __extract_blob_lut(dm_plane_state->blend_lut, _size);
+   blend_size = blend_lut != NULL ? blend_size : 0;
+
+   ret = amdgpu_dm_atomic_blend_lut(blend_lut, false,
+drm_tf_to_dc_tf(blend_tf),
+blend_size, dc_plane_state->blend_tf);
+   if (ret) {
+   drm_dbg_kms(plane_state->plane->dev,
+   "setting plane %d gamma lut failed.\n",
+   plane_state->plane->index);
+
+   return ret;
+   }
+
+   return 0;
 }
 #endif
 
-- 
2.39.2



[RFC PATCH 37/40] drm/amd/display: handle empty LUTs in __set_input_tf

2023-04-23 Thread Melissa Wen
From: Joshua Ashton 

Unlike degamma, blend gamma doesn't support hardcoded curve
(predefined/ROM), but we can use AMD color module to fill blend gamma
parameters when we have non-linear plane gamma TF without plane gamma
LUT. The regular degamma path doesn't hit this.

Signed-off-by: Joshua Ashton 
---
 .../amd/display/amdgpu_dm/amdgpu_dm_color.c   | 21 ---
 1 file changed, 13 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
index e17141fc8d12..baa7fea9ebae 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
@@ -349,21 +349,26 @@ static int __set_input_tf(struct dc_transfer_func *func,
struct dc_gamma *gamma = NULL;
bool res;
 
-   gamma = dc_create_gamma();
-   if (!gamma)
-   return -ENOMEM;
+   if (lut_size) {
+   gamma = dc_create_gamma();
+   if (!gamma)
+   return -ENOMEM;
 
-   gamma->type = GAMMA_CUSTOM;
-   gamma->num_entries = lut_size;
+   gamma->type = GAMMA_CUSTOM;
+   gamma->num_entries = lut_size;
 
-   __drm_lut_to_dc_gamma(lut, gamma, false);
+   __drm_lut_to_dc_gamma(lut, gamma, false);
+   }
 
-   res = mod_color_calculate_degamma_params(NULL, func, gamma, true);
-   dc_gamma_release();
+   res = mod_color_calculate_degamma_params(NULL, func, gamma, gamma != 
NULL);
+
+   if (gamma)
+   dc_gamma_release();
 
return res ? 0 : -ENOMEM;
 }
 
+
 #ifdef CONFIG_STEAM_DECK
 static enum dc_transfer_func_predefined drm_tf_to_dc_tf(enum 
drm_transfer_function drm_tf)
 {
-- 
2.39.2



[RFC PATCH 36/40] drm/amd/display: add plane shaper/3D LUT and shaper TF support

2023-04-23 Thread Melissa Wen
We already have the steps to program post-blending shaper/3D LUT on AMD
display driver, so that we can reuse them and map plane properties to DC
plane for pre-blending (plane) shaper/3D LUT setup.

Signed-off-by: Melissa Wen 
---
 .../amd/display/amdgpu_dm/amdgpu_dm_color.c   | 34 +--
 .../drm/amd/display/dc/dcn20/dcn20_hwseq.c|  5 +--
 2 files changed, 35 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
index 854510b05194..e17141fc8d12 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
@@ -909,6 +909,35 @@ __set_dm_plane_degamma(struct drm_plane_state *plane_state,
}
return 0;
 }
+
+static int
+amdgpu_dm_plane_set_color_properties(struct drm_plane_state *plane_state,
+struct dc_plane_state *dc_plane_state)
+{
+   struct dm_plane_state *dm_plane_state = to_dm_plane_state(plane_state);
+   enum drm_transfer_function shaper_tf = DRM_TRANSFER_FUNCTION_DEFAULT;
+   const struct drm_color_lut *shaper_lut, *lut3d;
+   uint32_t lut3d_size, shaper_size;
+
+   /* We have nothing to do here, return */
+   if (!plane_state->color_mgmt_changed)
+   return 0;
+
+   dc_plane_state->hdr_mult = 
dc_fixpt_from_s3132(dm_plane_state->hdr_mult);
+
+   shaper_tf = dm_plane_state->shaper_tf;
+   shaper_lut = __extract_blob_lut(dm_plane_state->shaper_lut, 
_size);
+   lut3d = __extract_blob_lut(dm_plane_state->lut3d, _size);
+   lut3d_size = lut3d != NULL ? lut3d_size : 0;
+   shaper_size = shaper_lut != NULL ? shaper_size : 0;
+
+   amdgpu_dm_atomic_lut3d(lut3d, lut3d_size, dc_plane_state->lut3d_func);
+   ret = amdgpu_dm_atomic_shaper_lut(shaper_lut, false,
+ drm_tf_to_dc_tf(shaper_tf),
+ shaper_size, 
dc_plane_state->in_shaper_func);
+
+   return ret;
+}
 #endif
 
 /**
@@ -939,7 +968,9 @@ int amdgpu_dm_update_plane_color_mgmt(struct dm_crtc_state 
*crtc,
has_crtc_cm_degamma = (crtc->cm_has_degamma || 
crtc->cm_is_degamma_srgb);
 
 #ifdef CONFIG_STEAM_DECK
-   dc_plane_state->hdr_mult = 
dc_fixpt_from_s3132(dm_plane_state->hdr_mult);
+   ret = amdgpu_dm_plane_set_color_properties(plane_state, dc_plane_state);
+   if(ret)
+   return ret;
 
ret = __set_dm_plane_degamma(plane_state, dc_plane_state);
if (ret != -EINVAL)
@@ -971,6 +1002,5 @@ int amdgpu_dm_update_plane_color_mgmt(struct dm_crtc_state 
*crtc,
return ret;
}
 
-
return 0;
 }
diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c 
b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c
index 5800acf6aae1..91fee60410f4 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c
@@ -1759,8 +1759,9 @@ static void dcn20_program_pipe(
hws->funcs.set_hdr_multiplier(pipe_ctx);
 
if (pipe_ctx->update_flags.bits.enable ||
-   
pipe_ctx->plane_state->update_flags.bits.in_transfer_func_change ||
-   pipe_ctx->plane_state->update_flags.bits.gamma_change)
+   pipe_ctx->plane_state->update_flags.bits.in_transfer_func_change ||
+   pipe_ctx->plane_state->update_flags.bits.gamma_change ||
+   pipe_ctx->plane_state->update_flags.bits.lut_3d)
hws->funcs.set_input_transfer_func(dc, pipe_ctx, 
pipe_ctx->plane_state);
 
/* dcn10_translate_regamma_to_hw_format takes 750us to finish
-- 
2.39.2



[RFC PATCH 35/40] drm/adm/display: add HDR multiplier support

2023-04-23 Thread Melissa Wen
From: Joshua Ashton 

With `dc_fixpt_from_s3132()` translation, we can just use it to set
hdr_mult.

Signed-off-by: Joshua Ashton 
---
 drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c   | 1 +
 drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c | 3 +++
 2 files changed, 4 insertions(+)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
index c0321272c129..0e3b6d414ec4 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -7991,6 +7991,7 @@ static void amdgpu_dm_commit_planes(struct 
drm_atomic_state *state,
bundle->surface_updates[planes_count].gamma = 
dc_plane->gamma_correction;
bundle->surface_updates[planes_count].in_transfer_func 
= dc_plane->in_transfer_func;

bundle->surface_updates[planes_count].gamut_remap_matrix = 
_plane->gamut_remap_matrix;
+   bundle->surface_updates[planes_count].hdr_mult = 
dc_plane->hdr_mult;
}
 
amdgpu_dm_plane_fill_dc_scaling_info(dm->adev, new_plane_state,
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
index d714728ca143..854510b05194 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
@@ -939,6 +939,8 @@ int amdgpu_dm_update_plane_color_mgmt(struct dm_crtc_state 
*crtc,
has_crtc_cm_degamma = (crtc->cm_has_degamma || 
crtc->cm_is_degamma_srgb);
 
 #ifdef CONFIG_STEAM_DECK
+   dc_plane_state->hdr_mult = 
dc_fixpt_from_s3132(dm_plane_state->hdr_mult);
+
ret = __set_dm_plane_degamma(plane_state, dc_plane_state);
if (ret != -EINVAL)
return ret;
@@ -969,5 +971,6 @@ int amdgpu_dm_update_plane_color_mgmt(struct dm_crtc_state 
*crtc,
return ret;
}
 
+
return 0;
 }
-- 
2.39.2



[RFC PATCH 33/40] drm/amd/display: reject atomic commit if setting both plane and CRTC degamma

2023-04-23 Thread Melissa Wen
DC only has pre-blending degamma caps (pre-blending/DPP) that is
currently in use for CRTC/post-blending degamma, so that we don't have
HW caps to perform plane and CRTC degamma at the same time. Reject
atomic updates when serspace sets both plane and CRTC degamma
properties.

Signed-off-by: Melissa Wen 
---
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c   | 11 +++
 1 file changed, 11 insertions(+)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
index 693168cc1d9c..07303c9f3618 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
@@ -949,6 +949,17 @@ int amdgpu_dm_update_plane_color_mgmt(struct dm_crtc_state 
*crtc,
if (ret != -EINVAL)
return ret;
 
+   /* We only have one degamma block available (pre-blending) for the
+* whole color correction pipeline, so that we can't actually perform
+* plane and CRTC degamma at the same time. Reject atomic updates when
+* userspace sets both plane and CRTC degamma properties.
+*/
+   if (has_crtc_cm_degamma && ret == -EINVAL){
+   drm_dbg_kms(crtc->base.crtc->dev,
+   "doesn't support plane and CRTC degamma at the same 
time\n");
+   return -EINVAL;
+   }
+
/* As we don't have plane degamma, check if we have CRTC degamma
 * waiting for mapping to pre-blending degamma block */
 #endif
-- 
2.39.2



[RFC PATCH 34/40] drm/amd/display: add dc_fixpt_from_s3132 helper

2023-04-23 Thread Melissa Wen
From: Joshua Ashton 

Detach value translation from CTM to reuse it for programming HDR
multiplier property.

Signed-off-by: Joshua Ashton 
---
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c  |  8 +---
 drivers/gpu/drm/amd/display/include/fixed31_32.h | 12 
 2 files changed, 13 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
index 07303c9f3618..d714728ca143 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
@@ -182,7 +182,6 @@ static void __drm_lut_to_dc_gamma(const struct 
drm_color_lut *lut,
 static void __drm_ctm_to_dc_matrix(const struct drm_color_ctm *ctm,
   struct fixed31_32 *matrix)
 {
-   int64_t val;
int i;
 
/*
@@ -201,12 +200,7 @@ static void __drm_ctm_to_dc_matrix(const struct 
drm_color_ctm *ctm,
}
 
/* gamut_remap_matrix[i] = ctm[i - floor(i/4)] */
-   val = ctm->matrix[i - (i / 4)];
-   /* If negative, convert to 2's complement. */
-   if (val & (1ULL << 63))
-   val = -(val & ~(1ULL << 63));
-
-   matrix[i].value = val;
+   matrix[i] = dc_fixpt_from_s3132(ctm->matrix[i - (i / 4)]);
}
 }
 
diff --git a/drivers/gpu/drm/amd/display/include/fixed31_32.h 
b/drivers/gpu/drm/amd/display/include/fixed31_32.h
index ece97ae0e826..f4cc7f97329f 100644
--- a/drivers/gpu/drm/amd/display/include/fixed31_32.h
+++ b/drivers/gpu/drm/amd/display/include/fixed31_32.h
@@ -69,6 +69,18 @@ static const struct fixed31_32 dc_fixpt_epsilon = { 1LL };
 static const struct fixed31_32 dc_fixpt_half = { 0x8000LL };
 static const struct fixed31_32 dc_fixpt_one = { 0x1LL };
 
+static inline struct fixed31_32 dc_fixpt_from_s3132(__u64 x)
+{
+   struct fixed31_32 val;
+
+   /* If negative, convert to 2's complement. */
+   if (x & (1ULL << 63))
+   x = -(x & ~(1ULL << 63));
+
+   val.value = x;
+   return val;
+}
+
 /*
  * @brief
  * Initialization routines
-- 
2.39.2



[RFC PATCH 32/40] drm/amd/display: add support for plane degamma TF and LUT properties

2023-04-23 Thread Melissa Wen
From: Joshua Ashton 

We only set CRTC degamma if we don't have plane degamma LUT or TF to
configure. We return -EINVAL if we don't have plane degamma settings, so
we can continue and check CRTC degamma.

Signed-off-by: Joshua Ashton 
---
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c |  4 +-
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h |  1 +
 .../amd/display/amdgpu_dm/amdgpu_dm_color.c   | 71 +--
 3 files changed, 70 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
index 1dac311cab67..c0321272c129 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -5043,7 +5043,9 @@ static int fill_dc_plane_attributes(struct amdgpu_device 
*adev,
 * Always set input transfer function, since plane state is refreshed
 * every time.
 */
-   ret = amdgpu_dm_update_plane_color_mgmt(dm_crtc_state, dc_plane_state);
+   ret = amdgpu_dm_update_plane_color_mgmt(dm_crtc_state,
+   plane_state,
+   dc_plane_state);
if (ret)
return ret;
 
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
index b9840c1f3cdf..bcf74b7391c9 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
@@ -912,6 +912,7 @@ int amdgpu_dm_verify_lut_sizes(const struct drm_crtc_state 
*crtc_state);
 int amdgpu_dm_update_crtc_color_mgmt(struct dm_crtc_state *crtc,
 struct dc_state *ctx);
 int amdgpu_dm_update_plane_color_mgmt(struct dm_crtc_state *crtc,
+ struct drm_plane_state *plane_state,
  struct dc_plane_state *dc_plane_state);
 
 void amdgpu_dm_update_connector_after_detect(
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
index 51808fff..693168cc1d9c 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
@@ -868,9 +868,59 @@ static int map_crtc_degamma_to_dc_plane(struct 
dm_crtc_state *crtc,
return 0;
 }
 
+#ifdef CONFIG_STEAM_DECK
+static int
+__set_dm_plane_degamma(struct drm_plane_state *plane_state,
+  struct dc_plane_state *dc_plane_state)
+{
+   struct dm_plane_state *dm_plane_state = to_dm_plane_state(plane_state);
+   const struct drm_color_lut *degamma_lut;
+   enum drm_transfer_function drm_tf = DRM_TRANSFER_FUNCTION_DEFAULT;
+   uint32_t degamma_size;
+   bool has_degamma_lut;
+   int ret;
+
+   degamma_lut = __extract_blob_lut(dm_plane_state->degamma_lut, 
_size);
+
+   has_degamma_lut = degamma_lut &&
+ !__is_lut_linear(degamma_lut, degamma_size);
+
+   drm_tf = dm_plane_state->degamma_tf;
+
+   /* If we don't have plane degamma LUT nor TF to set on DC, we have
+* nothing to do here, return.
+*/
+   if (!has_degamma_lut && drm_tf == DRM_TRANSFER_FUNCTION_DEFAULT)
+   return -EINVAL;
+
+   dc_plane_state->in_transfer_func->tf = drm_tf_to_dc_tf(drm_tf);
+
+   if (has_degamma_lut) {
+   ASSERT(degamma_size == MAX_COLOR_LUT_ENTRIES);
+
+   dc_plane_state->in_transfer_func->type =
+   TF_TYPE_DISTRIBUTED_POINTS;
+
+   ret = __set_input_tf(dc_plane_state->in_transfer_func,
+  degamma_lut, degamma_size);
+   if (ret)
+   return ret;
+   } else {
+   dc_plane_state->in_transfer_func->type =
+   TF_TYPE_PREDEFINED;
+
+   if (!mod_color_calculate_degamma_params(NULL,
+   dc_plane_state->in_transfer_func, NULL, false))
+   return -ENOMEM;
+   }
+   return 0;
+}
+#endif
+
 /**
  * amdgpu_dm_update_plane_color_mgmt: Maps DRM color management to DC plane.
  * @crtc: amdgpu_dm crtc state
+ * @plane_state: DRM plane state
  * @dc_plane_state: target DC surface
  *
  * Update the underlying dc_stream_state's input transfer function (ITF) in
@@ -881,13 +931,28 @@ static int map_crtc_degamma_to_dc_plane(struct 
dm_crtc_state *crtc,
  * 0 on success. -ENOMEM if mem allocation fails.
  */
 int amdgpu_dm_update_plane_color_mgmt(struct dm_crtc_state *crtc,
+ struct drm_plane_state *plane_state,
  struct dc_plane_state *dc_plane_state)
 {
bool has_crtc_cm_degamma;
int ret;
 
+   /* Initially, we can just bypass the DGM block. */
+   dc_plane_state->in_transfer_func->type = TF_TYPE_BYPASS;
+   

[RFC PATCH 31/40] drm/amd/display: decouple steps for mapping CRTC degamma to DC plane

2023-04-23 Thread Melissa Wen
The next patch adds pre-blending degamma to AMD color mgmt pipeline, but
pre-blending degamma caps (DPP) is currently in use to provide DRM CRTC
atomic degamma or implict degamma on legacy gamma. Detach degamma usage
regarging CRTC color properties to manage plane and CRTC color
correction combinations.

Signed-off-by: Melissa Wen 
---
 .../amd/display/amdgpu_dm/amdgpu_dm_color.c   | 55 +--
 1 file changed, 38 insertions(+), 17 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
index 6a233380f284..51808fff 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
@@ -791,20 +791,8 @@ int amdgpu_dm_update_crtc_color_mgmt(struct dm_crtc_state 
*crtc,
return 0;
 }
 
-/**
- * amdgpu_dm_update_plane_color_mgmt: Maps DRM color management to DC plane.
- * @crtc: amdgpu_dm crtc state
- * @dc_plane_state: target DC surface
- *
- * Update the underlying dc_stream_state's input transfer function (ITF) in
- * preparation for hardware commit. The transfer function used depends on
- * the preparation done on the stream for color management.
- *
- * Returns:
- * 0 on success. -ENOMEM if mem allocation fails.
- */
-int amdgpu_dm_update_plane_color_mgmt(struct dm_crtc_state *crtc,
- struct dc_plane_state *dc_plane_state)
+static int map_crtc_degamma_to_dc_plane(struct dm_crtc_state *crtc,
+   struct dc_plane_state *dc_plane_state)
 {
const struct drm_color_lut *degamma_lut;
enum dc_transfer_func_predefined tf = TRANSFER_FUNCTION_SRGB;
@@ -827,8 +815,7 @@ int amdgpu_dm_update_plane_color_mgmt(struct dm_crtc_state 
*crtc,
 _size);
ASSERT(degamma_size == MAX_COLOR_LUT_ENTRIES);
 
-   dc_plane_state->in_transfer_func->type =
-   TF_TYPE_DISTRIBUTED_POINTS;
+   dc_plane_state->in_transfer_func->type = 
TF_TYPE_DISTRIBUTED_POINTS;
 
/*
 * This case isn't fully correct, but also fairly
@@ -864,7 +851,7 @@ int amdgpu_dm_update_plane_color_mgmt(struct dm_crtc_state 
*crtc,
   degamma_lut, degamma_size);
if (r)
return r;
-   } else if (crtc->cm_is_degamma_srgb) {
+   } else {
/*
 * For legacy gamma support we need the regamma input
 * in linear space. Assume that the input is sRGB.
@@ -876,6 +863,40 @@ int amdgpu_dm_update_plane_color_mgmt(struct dm_crtc_state 
*crtc,
!mod_color_calculate_degamma_params(NULL,
dc_plane_state->in_transfer_func, NULL, false))
return -ENOMEM;
+   }
+
+   return 0;
+}
+
+/**
+ * amdgpu_dm_update_plane_color_mgmt: Maps DRM color management to DC plane.
+ * @crtc: amdgpu_dm crtc state
+ * @dc_plane_state: target DC surface
+ *
+ * Update the underlying dc_stream_state's input transfer function (ITF) in
+ * preparation for hardware commit. The transfer function used depends on
+ * the preparation done on the stream for color management.
+ *
+ * Returns:
+ * 0 on success. -ENOMEM if mem allocation fails.
+ */
+int amdgpu_dm_update_plane_color_mgmt(struct dm_crtc_state *crtc,
+ struct dc_plane_state *dc_plane_state)
+{
+   bool has_crtc_cm_degamma;
+   int ret;
+
+   has_crtc_cm_degamma = (crtc->cm_has_degamma || 
crtc->cm_is_degamma_srgb);
+   if (has_crtc_cm_degamma){
+   /* AMD HW doesn't have post-blending degamma caps. When DRM
+* CRTC atomic degamma is set, we maps it to DPP degamma block
+* (pre-blending) or, on legacy gamma, we use DPP degamma to
+* linearize (implicit degamma) from sRGB/BT709 according to
+* the input space.
+*/
+   ret = map_crtc_degamma_to_dc_plane(crtc, dc_plane_state);
+   if (ret)
+   return ret;
} else {
/* ...Otherwise we can just bypass the DGM block. */
dc_plane_state->in_transfer_func->type = TF_TYPE_BYPASS;
-- 
2.39.2



[RFC PATCH 30/40] drm/amd/display: mark plane as needing reset if plane color mgmt changes

2023-04-23 Thread Melissa Wen
We took a similar path for CRTC color mgmt changes, since we remap CRTC
degamma to plane/DPP block. Here we can use the status of
`plane->color_mgmt_changed` to detect when a plane color property
changed and recreate the plane accordingly.

Co-developed-by: Joshua Ashton 
Signed-off-by: Joshua Ashton 
Signed-off-by: Melissa Wen 
---
 drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
index 760080e4a4da..1dac311cab67 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -9441,6 +9441,9 @@ static bool should_reset_plane(struct drm_atomic_state 
*state,
if (drm_atomic_crtc_needs_modeset(new_crtc_state))
return true;
 
+   if (new_plane_state->color_mgmt_changed)
+   return true;
+
/*
 * If there are any new primary or overlay planes being added or
 * removed then the z-order can potentially change. To ensure
-- 
2.39.2



[RFC PATCH 29/40] drm/amd/display: add CRTC shaper TF support

2023-04-23 Thread Melissa Wen
Inspired by regamma TF, follow similar steps to add TF + 1D LUT for
shaper func. Reuse gamma_tf property, since the driver doesn't support
shaper and out gamma at the same time. We could rename gamma_tf, if
necessary to avoid misunderstandings, or add a specific property for
shaper lut.

Signed-off-by: Melissa Wen 
---
 .../drm/amd/display/amdgpu_dm/amdgpu_dm_color.c  | 16 +++-
 1 file changed, 11 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
index 6e7271065a56..6a233380f284 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
@@ -470,19 +470,22 @@ static void amdgpu_dm_atomic_lut3d(const struct 
drm_color_lut *drm_lut,
 }
 
 static int amdgpu_dm_atomic_shaper_lut(const struct drm_color_lut *shaper_lut,
+  bool has_rom,
+  enum dc_transfer_func_predefined tf,
   uint32_t shaper_size,
   struct dc_transfer_func *func_shaper)
 {
int ret = 0;
 
-   if (shaper_size) {
+   if (shaper_size || tf != TRANSFER_FUNCTION_LINEAR) {
/* If DRM shaper LUT is set, we assume a linear color space
 * (linearized by DRM degamma 1D LUT or not)
 */
func_shaper->type = TF_TYPE_DISTRIBUTED_POINTS;
-   func_shaper->tf = TRANSFER_FUNCTION_LINEAR;
+   func_shaper->tf = tf;
+   func_shaper->sdr_ref_white_level = 80; /* hardcoded for now */
 
-   ret = __set_output_tf(func_shaper, shaper_lut, shaper_size, 
false);
+   ret = __set_output_tf(func_shaper, shaper_lut, shaper_size, 
has_rom);
} else {
func_shaper->type = TF_TYPE_BYPASS;
func_shaper->tf = TRANSFER_FUNCTION_LINEAR;
@@ -509,12 +512,14 @@ static int amdgpu_dm_atomic_shaper_lut3d(struct dc *dc,
 struct dc_stream_state *stream,
 const struct drm_color_lut 
*drm_shaper_lut,
 uint32_t drm_shaper_size,
+bool has_rom,
+enum dc_transfer_func_predefined tf,
 const struct drm_color_lut *drm_lut3d,
 uint32_t drm_lut3d_size)
 {
struct dc_3dlut *lut3d_func;
struct dc_transfer_func *func_shaper;
-   bool acquire = drm_shaper_size || drm_lut3d_size;
+   bool acquire = drm_shaper_size || drm_lut3d_size || tf != 
TRANSFER_FUNCTION_LINEAR;
 
lut3d_func = (struct dc_3dlut *)stream->lut3d_func;
func_shaper = (struct dc_transfer_func *)stream->func_shaper;
@@ -536,7 +541,7 @@ static int amdgpu_dm_atomic_shaper_lut3d(struct dc *dc,
 
amdgpu_dm_atomic_lut3d(drm_lut3d, drm_lut3d_size, lut3d_func);
 
-   return amdgpu_dm_atomic_shaper_lut(drm_shaper_lut,
+   return amdgpu_dm_atomic_shaper_lut(drm_shaper_lut, has_rom, tf,
   drm_shaper_size, func_shaper);
 }
 
@@ -735,6 +740,7 @@ int amdgpu_dm_update_crtc_color_mgmt(struct dm_crtc_state 
*crtc,
shaper_size = shaper_lut != NULL ? shaper_size : 0;
r = amdgpu_dm_atomic_shaper_lut3d(adev->dm.dc, ctx, stream,
  shaper_lut, shaper_size,
+ has_rom, tf,
  lut3d, lut3d_size);
if (r) {
DRM_DEBUG_DRIVER("Failed on shaper/3D LUTs setup\n");
-- 
2.39.2



[RFC PATCH 26/40] drm/amd/display: add CRTC shaper LUT support to amd color pipeline

2023-04-23 Thread Melissa Wen
Now, we can use DRM CRTC shaper LUT to delinearize and/or normalize the
color space for a more efficient 3D LUT support (so far, only for DRM
atomic color mgmt). If a degamma 1D LUT is passed to linearize the color
space, a custom shaper 1D LUT can be used before applying 3D LUT.

NOTE: although DRM CRTC shaper and 3D LUTs are optional properties, from
our tests, AMD HW doesn't allow 3D LUT when shaper LUT is set to BYPASS
(without user shaper LUT)

Signed-off-by: Melissa Wen 
---
 .../amd/display/amdgpu_dm/amdgpu_dm_color.c   | 81 +--
 1 file changed, 38 insertions(+), 43 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
index 672ca5e9e59c..ff29be3929af 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
@@ -443,46 +443,26 @@ static void amdgpu_dm_atomic_lut3d(const struct 
drm_color_lut *drm_lut,
}
 }
 
-/**
- * __set_input_tf - calculates the input transfer function based on expected
- * input space.
- * @func: transfer function
- * @lut: lookup table that defines the color space
- * @lut_size: size of respective lut.
- *
- * Returns:
- * 0 in case of success. -ENOMEM if fails.
- */
-static int __set_input_tf(struct dc_transfer_func *func,
- const struct drm_color_lut *lut, uint32_t lut_size)
+static int amdgpu_dm_atomic_shaper_lut(const struct drm_color_lut *shaper_lut,
+  uint32_t shaper_size,
+  struct dc_transfer_func *func_shaper)
 {
-   struct dc_gamma *gamma = NULL;
-   bool res;
-
-   gamma = dc_create_gamma();
-   if (!gamma)
-   return -ENOMEM;
-
-   gamma->type = GAMMA_CUSTOM;
-   gamma->num_entries = lut_size;
-
-   __drm_lut_to_dc_gamma(lut, gamma, false);
-
-   res = mod_color_calculate_degamma_params(NULL, func, gamma, true);
-   dc_gamma_release();
+   int ret = 0;
 
-   return res ? 0 : -ENOMEM;
-}
+   if (shaper_size) {
+   /* If DRM shaper LUT is set, we assume a linear color space
+* (linearized by DRM degamma 1D LUT or not)
+*/
+   func_shaper->type = TF_TYPE_DISTRIBUTED_POINTS;
+   func_shaper->tf = TRANSFER_FUNCTION_LINEAR;
 
-static int amdgpu_dm_atomic_shaper_lut(struct dc_transfer_func *func_shaper)
-{
-   /* We don't get DRM shaper LUT yet. We assume the input color space is 
already
-* delinearized, so we don't need a shaper LUT and we can just BYPASS
-*/
-   func_shaper->type = TF_TYPE_BYPASS;
-   func_shaper->tf = TRANSFER_FUNCTION_LINEAR;
+   ret = __set_output_tf(func_shaper, shaper_lut, shaper_size, 
false);
+   } else {
+   func_shaper->type = TF_TYPE_BYPASS;
+   func_shaper->tf = TRANSFER_FUNCTION_LINEAR;
+   }
 
-   return 0;
+   return ret;
 }
 
 /* amdgpu_dm_atomic_shaper_lut3d - set DRM CRTC shaper LUT and 3D LUT to DC
@@ -530,7 +510,8 @@ static int amdgpu_dm_atomic_shaper_lut3d(struct dc *dc,
 
amdgpu_dm_atomic_lut3d(drm_lut3d, drm_lut3d_size, lut3d_func);
 
-   return amdgpu_dm_atomic_shaper_lut(func_shaper);
+   return amdgpu_dm_atomic_shaper_lut(drm_shaper_lut,
+  drm_shaper_size, func_shaper);
 }
 
 /**
@@ -562,12 +543,22 @@ static uint32_t amdgpu_dm_get_lut3d_size(struct 
amdgpu_device *adev,
 int amdgpu_dm_verify_lut3d_size(struct amdgpu_device *adev,
const struct drm_crtc_state *crtc_state)
 {
-   const struct drm_color_lut *lut3d = NULL;
struct dm_crtc_state *acrtc_state = to_dm_crtc_state(crtc_state);
+   const struct drm_color_lut *shaper = NULL, *lut3d = NULL;
uint32_t exp_size, size;
 
-   exp_size = amdgpu_dm_get_lut3d_size(adev, MAX_COLOR_3DLUT_ENTRIES);
+   /* shaper LUT is only available if 3D LUT color caps*/
+   exp_size = amdgpu_dm_get_lut3d_size(adev, MAX_COLOR_LUT_ENTRIES);
+   shaper = __extract_blob_lut(acrtc_state->shaper_lut, );
 
+   if (shaper && size != exp_size) {
+   DRM_DEBUG_DRIVER(
+   "Invalid Shaper LUT size. Should be %u but got %u.\n",
+   exp_size, size);
+   return -EINVAL;
+   }
+
+   exp_size = amdgpu_dm_get_lut3d_size(adev, MAX_COLOR_3DLUT_ENTRIES);
lut3d = __extract_blob_lut(acrtc_state->lut3d, );
 
if (lut3d && size != exp_size) {
@@ -652,14 +643,15 @@ int amdgpu_dm_update_crtc_color_mgmt(struct dm_crtc_state 
*crtc,
bool is_legacy;
int r;
 #ifdef CONFIG_STEAM_DECK
-   const struct drm_color_lut *lut3d;
-   uint32_t lut3d_size;
+   const struct drm_color_lut *shaper_lut, *lut3d;
+   uint32_t shaper_size, lut3d_size

[RFC PATCH 28/40] drm/amd/display: set sdr_ref_white_level to 80 for out_transfer_func

2023-04-23 Thread Melissa Wen
From: Joshua Ashton 

Otherwise this is just initialized to 0.

This needs to actually have a value so that compute_curve can work
for PQ EOTF.

Signed-off-by: Joshua Ashton 
---
 drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
index 55aa876a5008..6e7271065a56 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
@@ -323,6 +323,7 @@ static int amdgpu_dm_set_atomic_regamma(struct 
dc_stream_state *stream,
 */
stream->out_transfer_func->type = TF_TYPE_DISTRIBUTED_POINTS;
stream->out_transfer_func->tf = tf;
+   stream->out_transfer_func->sdr_ref_white_level = 80;
 
ret = __set_output_tf(stream->out_transfer_func,
  regamma_lut, regamma_size, has_rom);
-- 
2.39.2



[RFC PATCH 27/40] drm/amd/display: add CRTC regamma TF support

2023-04-23 Thread Melissa Wen
From: Joshua Ashton 

Add predefined transfer function programming. There is no out gamma ROM,
but we can use AMD color modules to program LUT parameters from a
predefined TF and an empty regamma LUT (or power LUT parameters with
predefined TF setup).

Signed-off-by: Joshua Ashton 
---
 .../amd/display/amdgpu_dm/amdgpu_dm_color.c   | 60 ++-
 1 file changed, 44 insertions(+), 16 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
index ff29be3929af..55aa876a5008 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
@@ -268,16 +268,18 @@ static int __set_output_tf(struct dc_transfer_func *func,
struct calculate_buffer cal_buffer = {0};
bool res;
 
-   ASSERT(lut && lut_size == MAX_COLOR_LUT_ENTRIES);
-
cal_buffer.buffer_index = -1;
 
-   gamma = dc_create_gamma();
-   if (!gamma)
-   return -ENOMEM;
+   if (lut_size) {
+   ASSERT(lut && lut_size == MAX_COLOR_LUT_ENTRIES);
 
-   gamma->num_entries = lut_size;
-   __drm_lut_to_dc_gamma(lut, gamma, false);
+   gamma = dc_create_gamma();
+   if (!gamma)
+   return -ENOMEM;
+
+   gamma->num_entries = lut_size;
+   __drm_lut_to_dc_gamma(lut, gamma, false);
+   }
 
if (func->tf == TRANSFER_FUNCTION_LINEAR) {
/*
@@ -285,30 +287,34 @@ static int __set_output_tf(struct dc_transfer_func *func,
 * on top of a linear input. But degamma params can be used
 * instead to simulate this.
 */
-   gamma->type = GAMMA_CUSTOM;
+   if (gamma)
+   gamma->type = GAMMA_CUSTOM;
res = mod_color_calculate_degamma_params(NULL, func,
-   gamma, true);
+gamma, gamma != NULL);
} else {
/*
 * Assume sRGB. The actual mapping will depend on whether the
 * input was legacy or not.
 */
-   gamma->type = GAMMA_CS_TFM_1D;
-   res = mod_color_calculate_regamma_params(func, gamma, false,
+   if (gamma)
+   gamma->type = GAMMA_CS_TFM_1D;
+   res = mod_color_calculate_regamma_params(func, gamma, gamma != 
NULL,
 has_rom, NULL, 
_buffer);
}
 
-   dc_gamma_release();
+   if (gamma)
+   dc_gamma_release();
 
return res ? 0 : -ENOMEM;
 }
 
 static int amdgpu_dm_set_atomic_regamma(struct dc_stream_state *stream,
const struct drm_color_lut *regamma_lut,
-   uint32_t regamma_size, bool has_rom)
+   uint32_t regamma_size, bool has_rom,
+   enum dc_transfer_func_predefined tf)
 {
int ret = 0;
-   if (regamma_size) {
+   if (regamma_size || tf != TRANSFER_FUNCTION_LINEAR) {
/* CRTC RGM goes into RGM LUT.
 *
 * Note: there is no implicit sRGB regamma here. We are using
@@ -316,7 +322,7 @@ static int amdgpu_dm_set_atomic_regamma(struct 
dc_stream_state *stream,
 * from a linear base.
 */
stream->out_transfer_func->type = TF_TYPE_DISTRIBUTED_POINTS;
-   stream->out_transfer_func->tf = TRANSFER_FUNCTION_LINEAR;
+   stream->out_transfer_func->tf = tf;
 
ret = __set_output_tf(stream->out_transfer_func,
  regamma_lut, regamma_size, has_rom);
@@ -364,6 +370,25 @@ static int __set_input_tf(struct dc_transfer_func *func,
 }
 
 #ifdef CONFIG_STEAM_DECK
+static enum dc_transfer_func_predefined drm_tf_to_dc_tf(enum 
drm_transfer_function drm_tf)
+{
+   switch (drm_tf)
+   {
+   default:
+   case DRM_TRANSFER_FUNCTION_DEFAULT: return TRANSFER_FUNCTION_LINEAR;
+   case DRM_TRANSFER_FUNCTION_SRGB:return TRANSFER_FUNCTION_SRGB;
+
+   case DRM_TRANSFER_FUNCTION_BT709:   return TRANSFER_FUNCTION_BT709;
+   case DRM_TRANSFER_FUNCTION_PQ:  return TRANSFER_FUNCTION_PQ;
+   case DRM_TRANSFER_FUNCTION_LINEAR:  return TRANSFER_FUNCTION_LINEAR;
+   case DRM_TRANSFER_FUNCTION_UNITY:   return TRANSFER_FUNCTION_UNITY;
+   case DRM_TRANSFER_FUNCTION_HLG: return TRANSFER_FUNCTION_HLG;
+   case DRM_TRANSFER_FUNCTION_GAMMA22: return 
TRANSFER_FUNCTION_GAMMA22;
+   case DRM_TRANSFER_FUNCTION_GAMMA24: return 
TRANSFER_FUNCTION_GAMMA24;
+   case DRM_TRANSFER_FUNCTION_GAMMA26: return 
TRANSFER_FUNCTION_GAMMA26;
+   }
+}
+
 

[RFC PATCH 24/40] drm/amd/display: add CRTC 3D LUT support to amd color pipeline

2023-04-23 Thread Melissa Wen
Map DRM CRTC 3D LUT in the atomic color mgmt pipeline to DC
(post-blending). 3D LUT works better in a non-linear color space,
therefore using a degamma to linearize the input space may produce
unexpected results. The next patch introduces shaper LUT support that
can be used to delinearize the color space before applying 3D LUT
conversion.

Signed-off-by: Melissa Wen 
---
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c |   8 +-
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h |   5 +
 .../amd/display/amdgpu_dm/amdgpu_dm_color.c   | 185 +++---
 3 files changed, 174 insertions(+), 24 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
index 6b40e17892e5..760080e4a4da 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -9945,7 +9945,13 @@ static int amdgpu_dm_atomic_check(struct drm_device *dev,
DRM_DEBUG_DRIVER("amdgpu_dm_verify_lut_sizes() 
failed\n");
goto fail;
}
-
+#ifdef CONFIG_STEAM_DECK
+   ret = amdgpu_dm_verify_lut3d_size(adev, new_crtc_state);
+   if (ret) {
+   DRM_DEBUG_DRIVER("amdgpu_dm_verify_lut_sizes() 
failed\n");
+   goto fail;
+   }
+#endif
if (!new_crtc_state->enable)
continue;
 
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
index 5faf4fc87701..b9840c1f3cdf 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
@@ -894,9 +894,14 @@ void amdgpu_dm_update_freesync_caps(struct drm_connector 
*connector,
 
 void amdgpu_dm_trigger_timing_sync(struct drm_device *dev);
 
+#ifdef CONFIG_STEAM_DECK
 /* 3D LUT max size is 17x17x17 */
 #define MAX_COLOR_3DLUT_ENTRIES 4913
 #define MAX_COLOR_3DLUT_BITDEPTH 12
+int amdgpu_dm_verify_lut3d_size(struct amdgpu_device *adev,
+   const struct drm_crtc_state *crtc_state);
+#endif
+
 /* 1D LUT degamma, regamma and shaper*/
 #define MAX_COLOR_LUT_ENTRIES 4096
 /* Legacy gamm LUT users such as X doesn't like large LUT sizes */
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
index 99b1738c98d3..25010fa19bc8 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
@@ -332,6 +332,117 @@ static int amdgpu_dm_set_atomic_regamma(struct 
dc_stream_state *stream,
return ret;
 }
 
+/**
+ * __set_input_tf - calculates the input transfer function based on expected
+ * input space.
+ * @func: transfer function
+ * @lut: lookup table that defines the color space
+ * @lut_size: size of respective lut.
+ *
+ * Returns:
+ * 0 in case of success. -ENOMEM if fails.
+ */
+static int __set_input_tf(struct dc_transfer_func *func,
+ const struct drm_color_lut *lut, uint32_t lut_size)
+{
+   struct dc_gamma *gamma = NULL;
+   bool res;
+
+   gamma = dc_create_gamma();
+   if (!gamma)
+   return -ENOMEM;
+
+   gamma->type = GAMMA_CUSTOM;
+   gamma->num_entries = lut_size;
+
+   __drm_lut_to_dc_gamma(lut, gamma, false);
+
+   res = mod_color_calculate_degamma_params(NULL, func, gamma, true);
+   dc_gamma_release();
+
+   return res ? 0 : -ENOMEM;
+}
+
+#ifdef CONFIG_STEAM_DECK
+static void __to_dc_lut3d_color(struct dc_rgb *rgb,
+   const struct drm_color_lut lut,
+   int bit_precision)
+{
+   rgb->red = drm_color_lut_extract(lut.red, bit_precision);
+   rgb->green = drm_color_lut_extract(lut.green, bit_precision);
+   rgb->blue  = drm_color_lut_extract(lut.blue, bit_precision);
+}
+
+static void __drm_3dlut_to_dc_3dlut(const struct drm_color_lut *lut,
+   uint32_t lut3d_size,
+   struct tetrahedral_params *params,
+   bool use_tetrahedral_9,
+   int bit_depth)
+{
+   struct dc_rgb *lut0;
+   struct dc_rgb *lut1;
+   struct dc_rgb *lut2;
+   struct dc_rgb *lut3;
+   int lut_i, i;
+
+
+   if (use_tetrahedral_9) {
+   lut0 = params->tetrahedral_9.lut0;
+   lut1 = params->tetrahedral_9.lut1;
+   lut2 = params->tetrahedral_9.lut2;
+   lut3 = params->tetrahedral_9.lut3;
+   } else {
+   lut0 = params->tetrahedral_17.lut0;
+   lut1 = params->tetrahedral_17.lut1;
+   lut2 = params->tetrahedral_17.lut2;
+   lut3 = params->tetrahedral_17.lut3;
+   }
+
+   for (lut_i = 0, i = 0; i <

[RFC PATCH 25/40] drm/amd/display: decouple steps to reuse in CRTC shaper LUT support

2023-04-23 Thread Melissa Wen
Decouple steps of post-blending shaper LUT setup and LUT size validation
according to HW caps as a preparation for DRM CRTC shaper LUT support.

Signed-off-by: Melissa Wen 
---
 .../amd/display/amdgpu_dm/amdgpu_dm_color.c   | 67 ---
 1 file changed, 58 insertions(+), 9 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
index 25010fa19bc8..672ca5e9e59c 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
@@ -443,6 +443,48 @@ static void amdgpu_dm_atomic_lut3d(const struct 
drm_color_lut *drm_lut,
}
 }
 
+/**
+ * __set_input_tf - calculates the input transfer function based on expected
+ * input space.
+ * @func: transfer function
+ * @lut: lookup table that defines the color space
+ * @lut_size: size of respective lut.
+ *
+ * Returns:
+ * 0 in case of success. -ENOMEM if fails.
+ */
+static int __set_input_tf(struct dc_transfer_func *func,
+ const struct drm_color_lut *lut, uint32_t lut_size)
+{
+   struct dc_gamma *gamma = NULL;
+   bool res;
+
+   gamma = dc_create_gamma();
+   if (!gamma)
+   return -ENOMEM;
+
+   gamma->type = GAMMA_CUSTOM;
+   gamma->num_entries = lut_size;
+
+   __drm_lut_to_dc_gamma(lut, gamma, false);
+
+   res = mod_color_calculate_degamma_params(NULL, func, gamma, true);
+   dc_gamma_release();
+
+   return res ? 0 : -ENOMEM;
+}
+
+static int amdgpu_dm_atomic_shaper_lut(struct dc_transfer_func *func_shaper)
+{
+   /* We don't get DRM shaper LUT yet. We assume the input color space is 
already
+* delinearized, so we don't need a shaper LUT and we can just BYPASS
+*/
+   func_shaper->type = TF_TYPE_BYPASS;
+   func_shaper->tf = TRANSFER_FUNCTION_LINEAR;
+
+   return 0;
+}
+
 /* amdgpu_dm_atomic_shaper_lut3d - set DRM CRTC shaper LUT and 3D LUT to DC
  * interface
  * @dc: Display Core control structure
@@ -486,15 +528,23 @@ static int amdgpu_dm_atomic_shaper_lut3d(struct dc *dc,
if (!acquire)
return 0;
 
-   /* We don't get DRM shaper LUT yet. We assume the input color
-* space is already delinearized, so we don't need a shaper LUT
-* and we can just BYPASS.
-*/
-   func_shaper->type = TF_TYPE_BYPASS;
-   func_shaper->tf = TRANSFER_FUNCTION_LINEAR;
amdgpu_dm_atomic_lut3d(drm_lut3d, drm_lut3d_size, lut3d_func);
 
-   return 0;
+   return amdgpu_dm_atomic_shaper_lut(func_shaper);
+}
+
+/**
+ * amdgpu_dm_lut3d_size - get expected size according to hw color caps
+ * @adev: amdgpu device
+ * @lut_size: default size
+ *
+ * Return:
+ * lut_size if DC 3D LUT is supported, zero otherwise.
+ */
+static uint32_t amdgpu_dm_get_lut3d_size(struct amdgpu_device *adev,
+uint32_t lut_size)
+{
+   return adev->dm.dc->caps.color.mpc.num_3dluts ? lut_size : 0;
 }
 
 /**
@@ -516,8 +566,7 @@ int amdgpu_dm_verify_lut3d_size(struct amdgpu_device *adev,
struct dm_crtc_state *acrtc_state = to_dm_crtc_state(crtc_state);
uint32_t exp_size, size;
 
-   exp_size = adev->dm.dc->caps.color.mpc.num_3dluts ?
-  MAX_COLOR_3DLUT_ENTRIES : 0;
+   exp_size = amdgpu_dm_get_lut3d_size(adev, MAX_COLOR_3DLUT_ENTRIES);
 
lut3d = __extract_blob_lut(acrtc_state->lut3d, );
 
-- 
2.39.2



[RFC PATCH 23/40] drm/amd/display: dynamically acquire 3DLUT resources for color changes

2023-04-23 Thread Melissa Wen
From: Joshua Ashton 

dc_acquire_release_mpc_3dlut_for_ctx initializes the bits required to
program 3DLUT in DC MPC hw block, applied in set_output_transfer_func().
Since acquire/release can fail, we should check resources availability
during atomic check considering the new context created. We dynamically
acquire 3D LUT resources when we actually use them, so we don't limit
ourselves with the stream count.

Co-developed-by: Melissa Wen 
Signed-off-by: Melissa Wen 
Signed-off-by: Joshua Ashton 
---
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c |  7 ++-
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h |  3 +-
 .../amd/display/amdgpu_dm/amdgpu_dm_color.c   | 55 ++-
 .../amd/display/dc/dcn301/dcn301_resource.c   | 26 -
 4 files changed, 87 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
index 729e37fa1873..6b40e17892e5 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -9380,7 +9380,12 @@ static int dm_update_crtc_state(struct 
amdgpu_display_manager *dm,
 */
if (dm_new_crtc_state->base.color_mgmt_changed ||
drm_atomic_crtc_needs_modeset(new_crtc_state)) {
-   ret = amdgpu_dm_update_crtc_color_mgmt(dm_new_crtc_state);
+   if (!dm_state) {
+   ret = dm_atomic_get_state(state, _state);
+   if (ret)
+   goto fail;
+   }
+   ret = amdgpu_dm_update_crtc_color_mgmt(dm_new_crtc_state, 
dm_state->context);
if (ret)
goto fail;
}
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
index 54121c3fa040..5faf4fc87701 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
@@ -904,7 +904,8 @@ void amdgpu_dm_trigger_timing_sync(struct drm_device *dev);
 
 void amdgpu_dm_init_color_mod(void);
 int amdgpu_dm_verify_lut_sizes(const struct drm_crtc_state *crtc_state);
-int amdgpu_dm_update_crtc_color_mgmt(struct dm_crtc_state *crtc);
+int amdgpu_dm_update_crtc_color_mgmt(struct dm_crtc_state *crtc,
+struct dc_state *ctx);
 int amdgpu_dm_update_plane_color_mgmt(struct dm_crtc_state *crtc,
  struct dc_plane_state *dc_plane_state);
 
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
index f1885e9c614d..99b1738c98d3 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
@@ -332,6 +332,49 @@ static int amdgpu_dm_set_atomic_regamma(struct 
dc_stream_state *stream,
return ret;
 }
 
+/* amdgpu_dm_atomic_shaper_lut3d - set DRM CRTC shaper LUT and 3D LUT to DC
+ * interface
+ * @dc: Display Core control structure
+ * @ctx: 
+ * @stream: DC stream state to set shaper LUT and 3D LUT
+ * @drm_shaper_lut: DRM CRTC (user) shaper LUT
+ * @drm_shaper_size: size of shaper LUT
+ * @drm_lut3d: DRM CRTC (user) 3D LUT
+ * @drm_lut3d_size: size of 3D LUT
+ *
+ * Returns:
+ * 0 on success.
+ */
+static int amdgpu_dm_atomic_shaper_lut3d(struct dc *dc,
+struct dc_state *ctx,
+struct dc_stream_state *stream,
+const struct drm_color_lut 
*drm_shaper_lut,
+uint32_t drm_shaper_size,
+const struct drm_color_lut *drm_lut3d,
+uint32_t drm_lut3d_size)
+{
+   struct dc_3dlut *lut3d_func;
+   struct dc_transfer_func *func_shaper;
+   bool acquire = drm_shaper_size && drm_lut3d_size;
+
+   lut3d_func = (struct dc_3dlut *)stream->lut3d_func;
+   func_shaper = (struct dc_transfer_func *)stream->func_shaper;
+
+   ASSERT((lut3d_func && func_shaper) || (!lut3d_func && !func_shaper));
+   if ((acquire && !lut3d_func && !func_shaper) ||
+   (!acquire && lut3d_func && func_shaper))
+   {
+   if (!dc_acquire_release_mpc_3dlut_for_ctx(dc, acquire, ctx, 
stream,
+ _func, 
_shaper))
+   return DC_ERROR_UNEXPECTED;
+   }
+
+   stream->lut3d_func = lut3d_func;
+   stream->func_shaper = func_shaper;
+
+   return 0;
+}
+
 /**
  * __set_input_tf - calculates the input transfer function based on expected
  * input space.
@@ -402,6 +445,7 @@ int amdgpu_dm_verify_lut_sizes(const struct drm_crtc_state 
*crtc_state)
 /**
  * amdgpu_dm_update_crtc_color_mgmt: Maps DRM color management to DC stream.
  

[RFC PATCH 22/40] drm/amd/display: handle MPC 3D LUT resources for a given context

2023-04-23 Thread Melissa Wen
In the original dc_acquire_release_mpc_3dlut(), only current ctx is
considered, which doesn't fit the steps for atomic checking new ctx.
Therefore, create a function to handle 3D LUT resource for a given
context, so that we can check resources availability in atomic_check
time and handle failures properly.

Signed-off-by: Melissa Wen 
---
 drivers/gpu/drm/amd/display/dc/core/dc.c | 39 
 drivers/gpu/drm/amd/display/dc/dc.h  |  8 +
 2 files changed, 47 insertions(+)

diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c 
b/drivers/gpu/drm/amd/display/dc/core/dc.c
index 9230c122d77e..ee3fe4eae22e 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc.c
@@ -2101,6 +2101,45 @@ bool dc_acquire_release_mpc_3dlut(
return ret;
 }
 
+bool
+dc_acquire_release_mpc_3dlut_for_ctx(struct dc *dc,
+bool acquire,
+struct dc_state *state,
+struct dc_stream_state *stream,
+struct dc_3dlut **lut,
+struct dc_transfer_func **shaper)
+{
+   int pipe_idx;
+   bool ret = false;
+   bool found_pipe_idx = false;
+   const struct resource_pool *pool = dc->res_pool;
+   struct resource_context *res_ctx = >res_ctx;
+   int mpcc_id = 0;
+
+   if (pool && res_ctx) {
+   if (acquire) {
+   /*find pipe idx for the given stream*/
+   for (pipe_idx = 0; pipe_idx < pool->pipe_count; 
pipe_idx++) {
+   if (res_ctx->pipe_ctx[pipe_idx].stream == 
stream) {
+   found_pipe_idx = true;
+   mpcc_id = 
res_ctx->pipe_ctx[pipe_idx].plane_res.hubp->inst;
+   break;
+   }
+   }
+   } else
+   found_pipe_idx = true;/*for release pipe_idx is not 
required*/
+
+   if (found_pipe_idx) {
+   if (acquire && pool->funcs->acquire_post_bldn_3dlut)
+   ret = 
pool->funcs->acquire_post_bldn_3dlut(res_ctx, pool, mpcc_id, lut, shaper);
+   else if (!acquire && 
pool->funcs->release_post_bldn_3dlut)
+   ret = 
pool->funcs->release_post_bldn_3dlut(res_ctx, pool, lut, shaper);
+   }
+   }
+   return ret;
+}
+
+
 static bool is_flip_pending_in_pipes(struct dc *dc, struct dc_state *context)
 {
int i;
diff --git a/drivers/gpu/drm/amd/display/dc/dc.h 
b/drivers/gpu/drm/amd/display/dc/dc.h
index b45974a2dec3..7fdb0bbb2df9 100644
--- a/drivers/gpu/drm/amd/display/dc/dc.h
+++ b/drivers/gpu/drm/amd/display/dc/dc.h
@@ -1350,6 +1350,14 @@ bool dc_acquire_release_mpc_3dlut(
struct dc_3dlut **lut,
struct dc_transfer_func **shaper);
 
+bool
+dc_acquire_release_mpc_3dlut_for_ctx(struct dc *dc,
+bool acquire,
+struct dc_state *state,
+struct dc_stream_state *stream,
+struct dc_3dlut **lut,
+struct dc_transfer_func **shaper);
+
 void dc_resource_state_copy_construct(
const struct dc_state *src_ctx,
struct dc_state *dst_ctx);
-- 
2.39.2



[RFC PATCH 21/40] drm/amd/display: allow BYPASS 3D LUT but keep shaper LUT settings

2023-04-23 Thread Melissa Wen
HW allows us to program shaper LUT without 3D LUT settings and it is
also good for testing shaper LUT behavior, therefore, DC driver should
allow acquiring both 3D and shaper LUT, but programing shaper LUT
without 3D LUT (not initialized).

Signed-off-by: Melissa Wen 
---
 drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.c | 9 ++---
 1 file changed, 6 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.c 
b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.c
index 3303c9aae068..bacb0a001d68 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.c
@@ -113,7 +113,6 @@ static bool dcn30_set_mpc_shaper_3dlut(struct pipe_ctx 
*pipe_ctx,
}
 
if (stream->lut3d_func &&
-   stream->lut3d_func->state.bits.initialized == 1 &&
stream->lut3d_func->state.bits.rmu_idx_valid == 1) {
if (stream->lut3d_func->state.bits.rmu_mux_num == 0)
mpcc_id_projected = 
stream->lut3d_func->state.bits.mpc_rmu0_mux;
@@ -131,8 +130,12 @@ static bool dcn30_set_mpc_shaper_3dlut(struct pipe_ctx 
*pipe_ctx,
if (acquired_rmu != stream->lut3d_func->state.bits.rmu_mux_num)
BREAK_TO_DEBUGGER();
 
-   result = mpc->funcs->program_3dlut(mpc, 
>lut3d_func->lut_3d,
-  
stream->lut3d_func->state.bits.rmu_mux_num);
+   if (stream->lut3d_func->state.bits.initialized == 1)
+   result = mpc->funcs->program_3dlut(mpc, 
>lut3d_func->lut_3d,
+  
stream->lut3d_func->state.bits.rmu_mux_num);
+   else
+   result = mpc->funcs->program_3dlut(mpc, NULL,
+  
stream->lut3d_func->state.bits.rmu_mux_num);
result = mpc->funcs->program_shaper(mpc, shaper_lut,

stream->lut3d_func->state.bits.rmu_mux_num);
} else {
-- 
2.39.2



[RFC PATCH 20/40] drm/amd/display: copy 3D LUT settings from crtc state to stream_update

2023-04-23 Thread Melissa Wen
From: Joshua Ashton 

When commiting planes, we copy color mgmt resources to the stream state.
Do the same for shaper and 3D LUTs.

Co-developed-by: Melissa Wen 
Signed-off-by: Melissa Wen 
Signed-off-by: Joshua Ashton 
---
 drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 4 
 1 file changed, 4 insertions(+)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
index 76a776fd8437..729e37fa1873 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -8190,6 +8190,10 @@ static void amdgpu_dm_commit_planes(struct 
drm_atomic_state *state,
_state->stream->csc_color_matrix;
bundle->stream_update.out_transfer_func =
acrtc_state->stream->out_transfer_func;
+   bundle->stream_update.lut3d_func =
+   (struct dc_3dlut *) 
acrtc_state->stream->lut3d_func;
+   bundle->stream_update.func_shaper =
+   (struct dc_transfer_func *) 
acrtc_state->stream->func_shaper;
}
 
acrtc_state->stream->abm_level = acrtc_state->abm_level;
-- 
2.39.2



[RFC PATCH 18/40] drm/amd/display: encapsulate atomic regamma operation

2023-04-23 Thread Melissa Wen
We are introducing DRM 3D LUT property to DM color pipeline in the next
patch, but so far, only for atomic interface. By checking
set_output_transfer_func in DC drivers with MPC 3D LUT support, we can
verify that regamma is only programmed when 3D LUT programming fails. As
a groundwork to introduce 3D LUT programming and better understand each
step, detach atomic regamma programming from the crtc colocr updating
code.

Signed-off-by: Melissa Wen 
---
 .../amd/display/amdgpu_dm/amdgpu_dm_color.c   | 52 ---
 1 file changed, 33 insertions(+), 19 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
index fe779d10834e..f1885e9c614d 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
@@ -303,6 +303,35 @@ static int __set_output_tf(struct dc_transfer_func *func,
return res ? 0 : -ENOMEM;
 }
 
+static int amdgpu_dm_set_atomic_regamma(struct dc_stream_state *stream,
+   const struct drm_color_lut *regamma_lut,
+   uint32_t regamma_size, bool has_rom)
+{
+   int ret = 0;
+   if (regamma_size) {
+   /* CRTC RGM goes into RGM LUT.
+*
+* Note: there is no implicit sRGB regamma here. We are using
+* degamma calculation from color module to calculate the curve
+* from a linear base.
+*/
+   stream->out_transfer_func->type = TF_TYPE_DISTRIBUTED_POINTS;
+   stream->out_transfer_func->tf = TRANSFER_FUNCTION_LINEAR;
+
+   ret = __set_output_tf(stream->out_transfer_func,
+ regamma_lut, regamma_size, has_rom);
+   } else {
+   /*
+* No CRTC RGM means we can just put the block into bypass
+* since we don't have any plane level adjustments using it.
+*/
+   stream->out_transfer_func->type = TF_TYPE_BYPASS;
+   stream->out_transfer_func->tf = TRANSFER_FUNCTION_LINEAR;
+   }
+
+   return ret;
+}
+
 /**
  * __set_input_tf - calculates the input transfer function based on expected
  * input space.
@@ -450,27 +479,12 @@ int amdgpu_dm_update_crtc_color_mgmt(struct dm_crtc_state 
*crtc)
regamma_size, has_rom);
if (r)
return r;
-   } else if (has_regamma) {
-   /* CRTC RGM goes into RGM LUT.
-*
-* Note: there is no implicit sRGB regamma here. We are using
-* degamma calculation from color module to calculate the curve
-* from a linear base.
-*/
-   stream->out_transfer_func->type = TF_TYPE_DISTRIBUTED_POINTS;
-   stream->out_transfer_func->tf = TRANSFER_FUNCTION_LINEAR;
-
-   r = __set_output_tf(stream->out_transfer_func, regamma_lut,
-   regamma_size, has_rom);
+   } else {
+   regamma_size = has_regamma ? regamma_size : 0;
+   r = amdgpu_dm_set_atomic_regamma(stream, regamma_lut,
+regamma_size, has_rom);
if (r)
return r;
-   } else {
-   /*
-* No CRTC RGM means we can just put the block into bypass
-* since we don't have any plane level adjustments using it.
-*/
-   stream->out_transfer_func->type = TF_TYPE_BYPASS;
-   stream->out_transfer_func->tf = TRANSFER_FUNCTION_LINEAR;
}
 
/*
-- 
2.39.2



[RFC PATCH 19/40] drm/amd/display: update lut3d and shaper lut to stream

2023-04-23 Thread Melissa Wen
It follows the same path of out_transfer_func for stream updates, since
shaper LUT and 3D LUT is programmed in funcs.set_output_transfer_func()
and this function is called in the atomic commit_tail when
update_flags.bits.out_tf is set.

Signed-off-by: Melissa Wen 
---
 drivers/gpu/drm/amd/display/dc/core/dc.c | 10 +-
 1 file changed, 9 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c 
b/drivers/gpu/drm/amd/display/dc/core/dc.c
index e65ba87ee2c5..9230c122d77e 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc.c
@@ -2581,7 +2581,7 @@ static enum surface_update_type 
check_update_surfaces_for_stream(
stream_update->integer_scaling_update)
su_flags->bits.scaling = 1;
 
-   if (stream_update->out_transfer_func)
+   if (stream_update->out_transfer_func || 
stream_update->lut3d_func)
su_flags->bits.out_tf = 1;
 
if (stream_update->abm_level)
@@ -2936,6 +2936,14 @@ static void copy_stream_update_to_stream(struct dc *dc,
   sizeof(struct dc_transfer_func_distributed_points));
}
 
+   if (update->func_shaper &&
+   stream->func_shaper != update->func_shaper)
+   stream->func_shaper = update->func_shaper;
+
+   if (update->lut3d_func &&
+   stream->lut3d_func != update->lut3d_func)
+   stream->lut3d_func = update->lut3d_func;
+
if (update->hdr_static_metadata)
stream->hdr_static_metadata = *update->hdr_static_metadata;
 
-- 
2.39.2



[RFC PATCH 17/40] drm/amd/display: add comments to describe DM crtc color mgmt behavior

2023-04-23 Thread Melissa Wen
Describe some expected behavior of the AMD DM color mgmt programming.

Signed-off-by: Melissa Wen 
---
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c | 13 -
 1 file changed, 12 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
index a4cb23d059bd..fe779d10834e 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
@@ -440,12 +440,23 @@ int amdgpu_dm_update_crtc_color_mgmt(struct dm_crtc_state 
*crtc)
stream->out_transfer_func->type = TF_TYPE_DISTRIBUTED_POINTS;
stream->out_transfer_func->tf = TRANSFER_FUNCTION_SRGB;
 
+   /* Note: although we pass has_rom as parameter here, we never
+* actually use ROM because the color module only takes the ROM
+* path if transfer_func->type == PREDEFINED.
+*
+* See more in mod_color_calculate_regamma_params()
+*/
r = __set_legacy_tf(stream->out_transfer_func, regamma_lut,
regamma_size, has_rom);
if (r)
return r;
} else if (has_regamma) {
-   /* If atomic regamma, CRTC RGM goes into RGM LUT. */
+   /* CRTC RGM goes into RGM LUT.
+*
+* Note: there is no implicit sRGB regamma here. We are using
+* degamma calculation from color module to calculate the curve
+* from a linear base.
+*/
stream->out_transfer_func->type = TF_TYPE_DISTRIBUTED_POINTS;
stream->out_transfer_func->tf = TRANSFER_FUNCTION_LINEAR;
 
-- 
2.39.2



[RFC PATCH 16/40] drm/amd/display: add plane blend LUT and TF driver-private properties

2023-04-23 Thread Melissa Wen
From: Joshua Ashton 

Blend 1D LUT or a predefined transfer function can be set to linearize
content before blending, so that it's positioned just before blending
planes, and after 3D LUT (non-linear space). Shaper and Blend LUTs are
1D LUTs that sandwich 3D LUT. Drivers should advertize blend properties
according to HW caps.

Signed-off-by: Joshua Ashton 
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_display.c   | 23 +
 drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h  | 18 ++
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h | 12 +++
 .../amd/display/amdgpu_dm/amdgpu_dm_plane.c   | 34 +++
 4 files changed, 87 insertions(+)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
index 2bf8b19feae4..0bcf0bc6baff 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
@@ -1369,6 +1369,29 @@ amdgpu_display_create_color_properties(struct 
amdgpu_device *adev)
return -ENOMEM;
adev->mode_info.plane_lut3d_size_property = prop;
 
+   prop = drm_property_create(adev_to_drm(adev),
+  DRM_MODE_PROP_BLOB,
+  "AMD_PLANE_BLEND_LUT", 0);
+   if (!prop)
+   return -ENOMEM;
+   adev->mode_info.plane_blend_lut_property = prop;
+
+   prop = drm_property_create_range(adev_to_drm(adev),
+DRM_MODE_PROP_IMMUTABLE,
+"AMD_PLANE_BLEND_LUT_SIZE", 0, 
UINT_MAX);
+   if (!prop)
+   return -ENOMEM;
+   adev->mode_info.plane_blend_lut_size_property = prop;
+
+   prop = drm_property_create_enum(adev_to_drm(adev),
+   DRM_MODE_PROP_ENUM,
+   "AMD_PLANE_BLEND_TF",
+   drm_transfer_function_enum_list,
+   
ARRAY_SIZE(drm_transfer_function_enum_list));
+   if (!prop)
+   return -ENOMEM;
+   adev->mode_info.plane_blend_tf_property = prop;
+
return 0;
 }
 #endif
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
index 17c7669ad9ab..f640dbd53b8c 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
@@ -417,6 +417,24 @@ struct amdgpu_mode_info {
 * size of 3D LUT as supported by the driver (read-only).
 */
struct drm_property *plane_lut3d_size_property;
+   /**
+* @plane_blend_lut_property: Plane property for output gamma before
+* blending. Userspace set a blend LUT to convert colors after 3D LUT
+* conversion. It works as a post-3D LUT 1D LUT, with shaper LUT, they
+* are sandwiching 3D LUT with two 1D LUT.
+*/
+   struct drm_property *plane_blend_lut_property;
+   /**
+* @plane_blend_lut_size_property: Plane property to define the max
+* size of blend LUT as supported by the driver (read-only).
+*/
+   struct drm_property *plane_blend_lut_size_property;
+   /**
+* @plane_blend_tf_property: Plane property to set a predefined
+* transfer function for pre-blending blend (before applying 3D LUT)
+* with or without LUT.
+*/
+   struct drm_property *plane_blend_tf_property;
 #endif
 };
 
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
index 8a425e7a7e89..54121c3fa040 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
@@ -764,6 +764,18 @@ struct dm_plane_state {
 *  drm_color_lut.
 */
struct drm_property_blob *lut3d;
+   /**
+* @blend_lut: blend lut lookup table blob. The blob (if not NULL) is an
+* array of  drm_color_lut.
+*/
+   struct drm_property_blob *blend_lut;
+   /**
+* @blend_tf:
+*
+* Pre-defined transfer function for converting plane pixel data before
+* applying blend LUT.
+*/
+   enum drm_transfer_function blend_tf;
 #endif
 };
 
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c
index e4f28fbf6613..cdbd11f3be20 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c
@@ -1325,6 +1325,7 @@ static void dm_drm_plane_reset(struct drm_plane *plane)
amdgpu_state->degamma_tf = DRM_TRANSFER_FUNCTION_DEFAULT;
amdgpu_state->hdr_mult = AMDGPU_HDR_MULT_DEFAULT;
amdgpu_state->shaper_tf = DRM_TRANSFER_FUNCTION_DEFAULT;
+   amdgpu_state->blend_tf = DRM_TRANSFER_FUNCTION_DEFAULT;
}
 #endif
 }
@@ -1352,6 +1353,8 @@ dm_drm_plane_duplicate_state(struct 

[RFC PATCH 15/40] drm/amd/display: add plane shaper TF driver-private property

2023-04-23 Thread Melissa Wen
Add property to set predefined transfer function to enable delinearizing
content with or without shaper LUT. Drivers should advertize this
property acoording to HW caps.

Signed-off-by: Melissa Wen 
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_display.c   |  9 +
 drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h  |  6 ++
 drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h |  6 ++
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c   | 11 +++
 4 files changed, 32 insertions(+)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
index f41406ee96ad..2bf8b19feae4 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
@@ -1346,6 +1346,15 @@ amdgpu_display_create_color_properties(struct 
amdgpu_device *adev)
return -ENOMEM;
adev->mode_info.plane_shaper_lut_size_property = prop;
 
+   prop = drm_property_create_enum(adev_to_drm(adev),
+   DRM_MODE_PROP_ENUM,
+   "AMD_PLANE_SHAPER_TF",
+   drm_transfer_function_enum_list,
+   
ARRAY_SIZE(drm_transfer_function_enum_list));
+   if (!prop)
+   return -ENOMEM;
+   adev->mode_info.plane_shaper_tf_property = prop;
+
prop = drm_property_create(adev_to_drm(adev),
   DRM_MODE_PROP_BLOB,
   "AMD_PLANE_LUT3D", 0);
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
index 756d5f70be0a..17c7669ad9ab 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
@@ -401,6 +401,12 @@ struct amdgpu_mode_info {
 * pre-blending shaper LUT as supported by the driver (read-only).
 */
struct drm_property *plane_shaper_lut_size_property;
+   /**
+* @plane_shaper_tf_property: Plane property to set a predefined
+* transfer function for pre-blending shaper (before applying 3D LUT)
+* with or without LUT.
+*/
+   struct drm_property *plane_shaper_tf_property;
/**
 * @plane_lut3d_property: Plane property for gamma correction using a
 * 3D LUT (pre-blending).
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
index d3ecc73129ff..8a425e7a7e89 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
@@ -753,6 +753,12 @@ struct dm_plane_state {
 * array of  drm_color_lut.
 */
struct drm_property_blob *shaper_lut;
+   /**
+* @shaper_tf:
+*
+* Predefined transfer function to delinearize color space.
+*/
+   enum drm_transfer_function shaper_tf;
/**
 * @lut3d: 3D lookup table blob. The blob (if not NULL) is an array of
 *  drm_color_lut.
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c
index 69e2f1f86cce..e4f28fbf6613 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c
@@ -1324,6 +1324,7 @@ static void dm_drm_plane_reset(struct drm_plane *plane)
if (amdgpu_state) {
amdgpu_state->degamma_tf = DRM_TRANSFER_FUNCTION_DEFAULT;
amdgpu_state->hdr_mult = AMDGPU_HDR_MULT_DEFAULT;
+   amdgpu_state->shaper_tf = DRM_TRANSFER_FUNCTION_DEFAULT;
}
 #endif
 }
@@ -1503,6 +1504,9 @@ dm_plane_attach_color_mgmt_properties(struct 
amdgpu_display_manager *dm,
drm_object_attach_property(>base,
   
dm->adev->mode_info.plane_shaper_lut_size_property,
   MAX_COLOR_LUT_ENTRIES);
+   drm_object_attach_property(>base,
+  
dm->adev->mode_info.plane_shaper_tf_property,
+  DRM_TRANSFER_FUNCTION_DEFAULT);
drm_object_attach_property(>base,
   
dm->adev->mode_info.plane_lut3d_property, 0);
drm_object_attach_property(>base,
@@ -1547,6 +1551,11 @@ dm_atomic_plane_set_property(struct drm_plane *plane,
);
dm_plane_state->base.color_mgmt_changed |= replaced;
return ret;
+   } else if (property == adev->mode_info.plane_shaper_tf_property) {
+   if (dm_plane_state->shaper_tf != val) {
+   dm_plane_state->shaper_tf = val;
+   dm_plane_state->base.color_mgmt_changed = 1;
+

[RFC PATCH 13/40] drm/amd/display: add plane 3D LUT driver-private properties

2023-04-23 Thread Melissa Wen
Add 3D LUT property for plane gamma correction using a 3D lookup table.
3D LUT is more effective when applying in non-linear space, therefore,
userpace may need one 1D LUT (shaper) before it to delinearize content
and another 1D LUT after 3D LUT (blend) to linearize content again for
blending. The next patches add these 1D LUTs to the plane color mgmt
pipeline.

Signed-off-by: Melissa Wen 
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_display.c   | 14 +++
 drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h  | 10 
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h |  5 
 .../amd/display/amdgpu_dm/amdgpu_dm_plane.c   | 24 +++
 4 files changed, 53 insertions(+)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
index dd658f162f6f..8d4726978c6e 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
@@ -1332,6 +1332,20 @@ amdgpu_display_create_color_properties(struct 
amdgpu_device *adev)
return -ENOMEM;
adev->mode_info.plane_hdr_mult_property = prop;
 
+   prop = drm_property_create(adev_to_drm(adev),
+  DRM_MODE_PROP_BLOB,
+  "AMD_PLANE_LUT3D", 0);
+   if (!prop)
+   return -ENOMEM;
+   adev->mode_info.plane_lut3d_property = prop;
+
+   prop = drm_property_create_range(adev_to_drm(adev),
+DRM_MODE_PROP_IMMUTABLE,
+"AMD_PLANE_LUT3D_SIZE", 0, UINT_MAX);
+   if (!prop)
+   return -ENOMEM;
+   adev->mode_info.plane_lut3d_size_property = prop;
+
return 0;
 }
 #endif
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
index 65a9d62ffbe4..9d9dac26edfc 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
@@ -391,6 +391,16 @@ struct amdgpu_mode_info {
 * @plane_hdr_mult_property:
 */
struct drm_property *plane_hdr_mult_property;
+   /**
+* @plane_lut3d_property: Plane property for gamma correction using a
+* 3D LUT (pre-blending).
+*/
+   struct drm_property *plane_lut3d_property;
+   /**
+* @plane_degamma_lut_size_property: Plane property to define the max
+* size of 3D LUT as supported by the driver (read-only).
+*/
+   struct drm_property *plane_lut3d_size_property;
 #endif
 };
 
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
index bb7307b9cfd5..b0ba0279dc25 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
@@ -748,6 +748,11 @@ struct dm_plane_state {
 * S31.32 sign-magnitude.
 */
__u64 hdr_mult;
+   /**
+* @lut3d: 3D lookup table blob. The blob (if not NULL) is an array of
+*  drm_color_lut.
+*/
+   struct drm_property_blob *lut3d;
 #endif
 };
 
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c
index 57169dae8b3d..0e418e161b0b 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c
@@ -1347,7 +1347,10 @@ dm_drm_plane_duplicate_state(struct drm_plane *plane)
 #ifdef CONFIG_STEAM_DECK
if (dm_plane_state->degamma_lut)
drm_property_blob_get(dm_plane_state->degamma_lut);
+   if (dm_plane_state->lut3d)
+   drm_property_blob_get(dm_plane_state->lut3d);
 #endif
+
return _plane_state->base;
 }
 
@@ -1416,7 +1419,9 @@ static void dm_drm_plane_destroy_state(struct drm_plane 
*plane,
struct dm_plane_state *dm_plane_state = to_dm_plane_state(state);
 #ifdef CONFIG_STEAM_DECK
drm_property_blob_put(dm_plane_state->degamma_lut);
+   drm_property_blob_put(dm_plane_state->lut3d);
 #endif
+
if (dm_plane_state->dc_state)
dc_plane_state_release(dm_plane_state->dc_state);
 
@@ -1488,6 +1493,14 @@ dm_plane_attach_color_mgmt_properties(struct 
amdgpu_display_manager *dm,
drm_object_attach_property(>base,
   dm->adev->mode_info.plane_hdr_mult_property,
   AMDGPU_HDR_MULT_DEFAULT);
+
+   if (dm->dc->caps.color.dpp.hw_3d_lut) {
+   drm_object_attach_property(>base,
+  
dm->adev->mode_info.plane_lut3d_property, 0);
+   drm_object_attach_property(>base,
+  
dm->adev->mode_info.plane_lut3d_size_property,
+  MAX_COLOR_3DLUT_ENTRIES);
+   }
 }
 
 static int
@@ -1518,6 +1531,14 @@ dm_

[RFC PATCH 14/40] drm/amd/display: add plane shaper LUT driver-private properties

2023-04-23 Thread Melissa Wen
Shaper 1D LUT delinearizes content before applying 3D LUT so that, it
comes before 3D LUT. It's an optional property and drivers should attach
it according to HW caps.

Signed-off-by: Melissa Wen 
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_display.c   | 14 ++
 drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h  | 10 ++
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h |  5 +
 .../amd/display/amdgpu_dm/amdgpu_dm_plane.c   | 19 +++
 4 files changed, 48 insertions(+)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
index 8d4726978c6e..f41406ee96ad 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
@@ -1332,6 +1332,20 @@ amdgpu_display_create_color_properties(struct 
amdgpu_device *adev)
return -ENOMEM;
adev->mode_info.plane_hdr_mult_property = prop;
 
+   prop = drm_property_create(adev_to_drm(adev),
+  DRM_MODE_PROP_BLOB,
+  "AMD_PLANE_SHAPER_LUT", 0);
+   if (!prop)
+   return -ENOMEM;
+   adev->mode_info.plane_shaper_lut_property = prop;
+
+   prop = drm_property_create_range(adev_to_drm(adev),
+DRM_MODE_PROP_IMMUTABLE,
+"AMD_PLANE_SHAPER_LUT_SIZE", 0, 
UINT_MAX);
+   if (!prop)
+   return -ENOMEM;
+   adev->mode_info.plane_shaper_lut_size_property = prop;
+
prop = drm_property_create(adev_to_drm(adev),
   DRM_MODE_PROP_BLOB,
   "AMD_PLANE_LUT3D", 0);
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
index 9d9dac26edfc..756d5f70be0a 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
@@ -391,6 +391,16 @@ struct amdgpu_mode_info {
 * @plane_hdr_mult_property:
 */
struct drm_property *plane_hdr_mult_property;
+   /**
+* @shaper_lut_property: Plane property to set pre-blending shaper LUT
+* that converts color content before 3D LUT.
+*/
+   struct drm_property *plane_shaper_lut_property;
+   /**
+* @shaper_lut_size_property: Plane property for the size of
+* pre-blending shaper LUT as supported by the driver (read-only).
+*/
+   struct drm_property *plane_shaper_lut_size_property;
/**
 * @plane_lut3d_property: Plane property for gamma correction using a
 * 3D LUT (pre-blending).
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
index b0ba0279dc25..d3ecc73129ff 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
@@ -748,6 +748,11 @@ struct dm_plane_state {
 * S31.32 sign-magnitude.
 */
__u64 hdr_mult;
+   /**
+* @shaper_lut: shaper lookup table blob. The blob (if not NULL) is an
+* array of  drm_color_lut.
+*/
+   struct drm_property_blob *shaper_lut;
/**
 * @lut3d: 3D lookup table blob. The blob (if not NULL) is an array of
 *  drm_color_lut.
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c
index 0e418e161b0b..69e2f1f86cce 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c
@@ -1347,6 +1347,8 @@ dm_drm_plane_duplicate_state(struct drm_plane *plane)
 #ifdef CONFIG_STEAM_DECK
if (dm_plane_state->degamma_lut)
drm_property_blob_get(dm_plane_state->degamma_lut);
+   if (dm_plane_state->shaper_lut)
+   drm_property_blob_get(dm_plane_state->shaper_lut);
if (dm_plane_state->lut3d)
drm_property_blob_get(dm_plane_state->lut3d);
 #endif
@@ -1419,6 +1421,7 @@ static void dm_drm_plane_destroy_state(struct drm_plane 
*plane,
struct dm_plane_state *dm_plane_state = to_dm_plane_state(state);
 #ifdef CONFIG_STEAM_DECK
drm_property_blob_put(dm_plane_state->degamma_lut);
+   drm_property_blob_put(dm_plane_state->shaper_lut);
drm_property_blob_put(dm_plane_state->lut3d);
 #endif
 
@@ -1495,6 +1498,11 @@ dm_plane_attach_color_mgmt_properties(struct 
amdgpu_display_manager *dm,
   AMDGPU_HDR_MULT_DEFAULT);
 
if (dm->dc->caps.color.dpp.hw_3d_lut) {
+   drm_object_attach_property(>base,
+  
dm->adev->mode_info.plane_shaper_lut_property, 0);
+   drm_object_attach_property(>base,
+  
dm->adev->mode_info.plane_

[RFC PATCH 12/40] drm/amd/display: add plane HDR multiplier driver-private property

2023-04-23 Thread Melissa Wen
From: Joshua Ashton 

Multiplier to 'gain' the plane. When PQ is decoded using the fixed func
transfer function to the internal FP16 fb, 1.0 -> 80 nits (on AMD at
least) When sRGB is decoded, 1.0 -> 1.0.  Therefore, 1.0 multiplier = 80
nits for SDR content. So if you want, 203 nits for SDR content, pass in
(203.0 / 80.0).

Co-developed-by: Melissa Wen 
Signed-off-by: Melissa Wen 
Signed-off-by: Joshua Ashton 
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_display.c   |  6 +
 drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h  |  4 +++
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h | 12 +
 .../amd/display/amdgpu_dm/amdgpu_dm_plane.c   | 25 ++-
 4 files changed, 41 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
index 24595906dab1..dd658f162f6f 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
@@ -1326,6 +1326,12 @@ amdgpu_display_create_color_properties(struct 
amdgpu_device *adev)
return -ENOMEM;
adev->mode_info.plane_degamma_tf_property = prop;
 
+   prop = drm_property_create_range(adev_to_drm(adev),
+0, "AMD_PLANE_HDR_MULT", 0, UINT_MAX);
+   if (!prop)
+   return -ENOMEM;
+   adev->mode_info.plane_hdr_mult_property = prop;
+
return 0;
 }
 #endif
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
index ab9ce6f26c90..65a9d62ffbe4 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
@@ -387,6 +387,10 @@ struct amdgpu_mode_info {
 * linearize content with or without LUT.
 */
struct drm_property *plane_degamma_tf_property;
+   /**
+* @plane_hdr_mult_property:
+*/
+   struct drm_property *plane_hdr_mult_property;
 #endif
 };
 
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
index 005632c1c9ec..bb7307b9cfd5 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
@@ -51,6 +51,7 @@
 
 #define AMDGPU_DMUB_NOTIFICATION_MAX 5
 
+#define AMDGPU_HDR_MULT_DEFAULT (0x1LL)
 /*
 #include "include/amdgpu_dal_power_if.h"
 #include "amdgpu_dm_irq.h"
@@ -736,6 +737,17 @@ struct dm_plane_state {
 * linearize.
 */
enum drm_transfer_function degamma_tf;
+   /**
+* @hdr_mult:
+*
+* Multiplier to 'gain' the plane.  When PQ is decoded using the fixed
+* func transfer function to the internal FP16 fb, 1.0 -> 80 nits (on
+* AMD at least). When sRGB is decoded, 1.0 -> 1.0, obviously.
+* Therefore, 1.0 multiplier = 80 nits for SDR content.  So if you
+* want, 203 nits for SDR content, pass in (203.0 / 80.0).  Format is
+* S31.32 sign-magnitude.
+*/
+   __u64 hdr_mult;
 #endif
 };
 
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c
index 5b458cc0781c..57169dae8b3d 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c
@@ -1321,8 +1321,10 @@ static void dm_drm_plane_reset(struct drm_plane *plane)
__drm_atomic_helper_plane_reset(plane, _state->base);
 
 #ifdef CONFIG_STEAM_DECK
-   if (amdgpu_state)
+   if (amdgpu_state) {
amdgpu_state->degamma_tf = DRM_TRANSFER_FUNCTION_DEFAULT;
+   amdgpu_state->hdr_mult = AMDGPU_HDR_MULT_DEFAULT;
+   }
 #endif
 }
 
@@ -1424,11 +1426,11 @@ static void dm_drm_plane_destroy_state(struct drm_plane 
*plane,
 #ifdef CONFIG_STEAM_DECK
 int
 amdgpu_dm_replace_property_blob_from_id(struct drm_device *dev,
-  struct drm_property_blob **blob,
-  uint64_t blob_id,
-  ssize_t expected_size,
-  ssize_t expected_elem_size,
-  bool *replaced)
+   struct drm_property_blob **blob,
+   uint64_t blob_id,
+   ssize_t expected_size,
+   ssize_t expected_elem_size,
+   bool *replaced)
 {
struct drm_property_blob *new_blob = NULL;
 
@@ -1482,6 +1484,10 @@ dm_plane_attach_color_mgmt_properties(struct 
amdgpu_display_manager *dm,
   
dm->adev->mode_info.plane_degamma_tf_property,
   DRM_TRANSFER_FUNCTION_DEFAULT);
}
+   /* HDR MULT 

[RFC PATCH 10/40] drm/amd/display: add plane degamma LUT driver-private props

2023-04-23 Thread Melissa Wen
From: Joshua Ashton 

Create driver-private properties (not DRM KMS generic) for plane degamma
LUT (user-blob and its size).

Co-developed-by: Melissa Wen 
Signed-off-by: Melissa Wen 
Signed-off-by: Joshua Ashton 
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_display.c   | 14 
 drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h  | 10 +++
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h | 11 +++
 .../amd/display/amdgpu_dm/amdgpu_dm_plane.c   | 78 ++-
 4 files changed, 111 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
index 1913903cab88..996c9c3fd471 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
@@ -1303,6 +1303,20 @@ amdgpu_display_create_color_properties(struct 
amdgpu_device *adev)
return -ENOMEM;
adev->mode_info.gamma_tf_property = prop;
 
+   prop = drm_property_create(adev_to_drm(adev),
+  DRM_MODE_PROP_BLOB,
+  "AMD_PLANE_DEGAMMA_LUT", 0);
+   if (!prop)
+   return -ENOMEM;
+   adev->mode_info.plane_degamma_lut_property = prop;
+
+   prop = drm_property_create_range(adev_to_drm(adev),
+DRM_MODE_PROP_IMMUTABLE,
+"AMD_PLANE_DEGAMMA_LUT_SIZE", 0, 
UINT_MAX);
+   if (!prop)
+   return -ENOMEM;
+   adev->mode_info.plane_degamma_lut_size_property = prop;
+
return 0;
 }
 #endif
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
index 76337e18c728..d4e609a8b67e 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
@@ -372,6 +372,16 @@ struct amdgpu_mode_info {
 * @gamma_tf_property: Transfer function for CRTC regamma.
 */
struct drm_property *gamma_tf_property;
+   /**
+* @plane_degamma_lut_property: Plane property to set a degamma LUT to
+* convert color space before blending.
+*/
+   struct drm_property *plane_degamma_lut_property;
+   /**
+* @plane_degamma_lut_size_property: Plane property to define the max
+* size of degamma LUT as supported by the driver (read-only).
+*/
+   struct drm_property *plane_degamma_lut_size_property;
 #endif
 };
 
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
index 1e90a2dd445e..b1d0c65d821d 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
@@ -719,6 +719,17 @@ enum drm_transfer_function {
 struct dm_plane_state {
struct drm_plane_state base;
struct dc_plane_state *dc_state;
+
+#ifdef CONFIG_STEAM_DECK
+   /* Plane color mgmt */
+   /**
+* @degamma_lut:
+*
+* LUT for converting plane pixel data before going into plane merger.
+* The blob (if not NULL) is an array of  drm_color_lut.
+*/
+   struct drm_property_blob *degamma_lut;
+#endif
 };
 
 struct dm_crtc_state {
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c
index 4e5498153be2..7b9d62c70b30 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c
@@ -1337,7 +1337,10 @@ dm_drm_plane_duplicate_state(struct drm_plane *plane)
dm_plane_state->dc_state = old_dm_plane_state->dc_state;
dc_plane_state_retain(dm_plane_state->dc_state);
}
-
+#ifdef CONFIG_STEAM_DECK
+   if (dm_plane_state->degamma_lut)
+   drm_property_blob_get(dm_plane_state->degamma_lut);
+#endif
return _plane_state->base;
 }
 
@@ -1404,7 +1407,9 @@ static void dm_drm_plane_destroy_state(struct drm_plane 
*plane,
struct drm_plane_state *state)
 {
struct dm_plane_state *dm_plane_state = to_dm_plane_state(state);
-
+#ifdef CONFIG_STEAM_DECK
+   drm_property_blob_put(dm_plane_state->degamma_lut);
+#endif
if (dm_plane_state->dc_state)
dc_plane_state_release(dm_plane_state->dc_state);
 
@@ -1444,6 +1449,68 @@ amdgpu_dm_replace_property_blob_from_id(struct 
drm_device *dev,
 
return 0;
 }
+
+static void
+dm_plane_attach_color_mgmt_properties(struct amdgpu_display_manager *dm,
+ struct drm_plane *plane)
+{
+   if (dm->dc->caps.color.dpp.dgam_ram || 
dm->dc->caps.color.dpp.gamma_corr ) {
+   drm_object_attach_property(>base,
+  
dm->adev->mode_info.plane_degamma_lut_property, 0);
+   drm_object_attach_property(>base,
+  

[RFC PATCH 11/40] drm/amd/display: add plane degamma TF driver-private property

2023-04-23 Thread Melissa Wen
From: Joshua Ashton 

Allow userspace to tell the kernel driver the input space and,
therefore, uses correct predefined transfer function (TF) to delinearize
content with or without LUT (using hardcoded curve caps).

Signed-off-by: Joshua Ashton 
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_display.c   |  9 ++
 drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h  |  5 
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h |  7 +
 .../amd/display/amdgpu_dm/amdgpu_dm_plane.c   | 28 +++
 4 files changed, 49 insertions(+)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
index 996c9c3fd471..24595906dab1 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
@@ -1317,6 +1317,15 @@ amdgpu_display_create_color_properties(struct 
amdgpu_device *adev)
return -ENOMEM;
adev->mode_info.plane_degamma_lut_size_property = prop;
 
+   prop = drm_property_create_enum(adev_to_drm(adev),
+   DRM_MODE_PROP_ENUM,
+   "AMD_PLANE_DEGAMMA_TF",
+   drm_transfer_function_enum_list,
+   
ARRAY_SIZE(drm_transfer_function_enum_list));
+   if (!prop)
+   return -ENOMEM;
+   adev->mode_info.plane_degamma_tf_property = prop;
+
return 0;
 }
 #endif
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
index d4e609a8b67e..ab9ce6f26c90 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
@@ -382,6 +382,11 @@ struct amdgpu_mode_info {
 * size of degamma LUT as supported by the driver (read-only).
 */
struct drm_property *plane_degamma_lut_size_property;
+   /**
+* @plane_degamma_tf_property: Predefined transfer function to
+* linearize content with or without LUT.
+*/
+   struct drm_property *plane_degamma_tf_property;
 #endif
 };
 
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
index b1d0c65d821d..005632c1c9ec 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
@@ -729,6 +729,13 @@ struct dm_plane_state {
 * The blob (if not NULL) is an array of  drm_color_lut.
 */
struct drm_property_blob *degamma_lut;
+   /**
+* @degamma_tf:
+*
+* Predefined transfer function to tell DC driver the input space to
+* linearize.
+*/
+   enum drm_transfer_function degamma_tf;
 #endif
 };
 
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c
index 7b9d62c70b30..5b458cc0781c 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c
@@ -1319,6 +1319,11 @@ static void dm_drm_plane_reset(struct drm_plane *plane)
 
if (amdgpu_state)
__drm_atomic_helper_plane_reset(plane, _state->base);
+
+#ifdef CONFIG_STEAM_DECK
+   if (amdgpu_state)
+   amdgpu_state->degamma_tf = DRM_TRANSFER_FUNCTION_DEFAULT;
+#endif
 }
 
 static struct drm_plane_state *
@@ -1450,6 +1455,19 @@ amdgpu_dm_replace_property_blob_from_id(struct 
drm_device *dev,
return 0;
 }
 
+static const struct drm_prop_enum_list drm_transfer_function_enum_list[] = {
+   { DRM_TRANSFER_FUNCTION_DEFAULT, "Default" },
+   { DRM_TRANSFER_FUNCTION_SRGB, "sRGB" },
+   { DRM_TRANSFER_FUNCTION_BT709, "BT.709" },
+   { DRM_TRANSFER_FUNCTION_PQ, "PQ (Perceptual Quantizer)" },
+   { DRM_TRANSFER_FUNCTION_LINEAR, "Linear" },
+   { DRM_TRANSFER_FUNCTION_UNITY, "Unity" },
+   { DRM_TRANSFER_FUNCTION_HLG, "HLG (Hybrid Log Gamma)" },
+   { DRM_TRANSFER_FUNCTION_GAMMA22, "Gamma 2.2" },
+   { DRM_TRANSFER_FUNCTION_GAMMA24, "Gamma 2.4" },
+   { DRM_TRANSFER_FUNCTION_GAMMA26, "Gamma 2.6" },
+};
+
 static void
 dm_plane_attach_color_mgmt_properties(struct amdgpu_display_manager *dm,
  struct drm_plane *plane)
@@ -1460,6 +1478,9 @@ dm_plane_attach_color_mgmt_properties(struct 
amdgpu_display_manager *dm,
drm_object_attach_property(>base,
   
dm->adev->mode_info.plane_degamma_lut_size_property,
   MAX_COLOR_LUT_ENTRIES);
+   drm_object_attach_property(>base,
+  
dm->adev->mode_info.plane_degamma_tf_property,
+  DRM_TRANSFER_FUNCTION_DEFAULT);
}
 }
 
@@ -1481,6 +1502,11 @@ dm_atomic_plane_set_property(struct drm_plane *plane,
);

[RFC PATCH 09/40] drm/amd/display: move replace blob func to dm plane

2023-04-23 Thread Melissa Wen
>From amdgpu_dm_plane we can get it for both CRTC and plane color
properties. We are adding new plane properties for AMD driver-private
color mgmt.

Signed-off-by: Melissa Wen 
---
 .../amd/display/amdgpu_dm/amdgpu_dm_crtc.c| 37 +--
 .../amd/display/amdgpu_dm/amdgpu_dm_plane.c   | 35 ++
 .../amd/display/amdgpu_dm/amdgpu_dm_plane.h   |  7 
 3 files changed, 44 insertions(+), 35 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c
index 79324fbab1f1..27d7a8b18013 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c
@@ -344,39 +344,6 @@ dm_crtc_additional_color_mgmt(struct drm_crtc *crtc)
   DRM_TRANSFER_FUNCTION_DEFAULT);
 }
 
-static int
-atomic_replace_property_blob_from_id(struct drm_device *dev,
-struct drm_property_blob **blob,
-uint64_t blob_id,
-ssize_t expected_size,
-ssize_t expected_elem_size,
-bool *replaced)
-{
-   struct drm_property_blob *new_blob = NULL;
-
-   if (blob_id != 0) {
-   new_blob = drm_property_lookup_blob(dev, blob_id);
-   if (new_blob == NULL)
-   return -EINVAL;
-
-   if (expected_size > 0 &&
-   new_blob->length != expected_size) {
-   drm_property_blob_put(new_blob);
-   return -EINVAL;
-   }
-   if (expected_elem_size > 0 &&
-   new_blob->length % expected_elem_size != 0) {
-   drm_property_blob_put(new_blob);
-   return -EINVAL;
-   }
-   }
-
-   *replaced |= drm_property_replace_blob(blob, new_blob);
-   drm_property_blob_put(new_blob);
-
-   return 0;
-}
-
 static int
 amdgpu_dm_atomic_crtc_set_property(struct drm_crtc *crtc,
   struct drm_crtc_state *state,
@@ -389,7 +356,7 @@ amdgpu_dm_atomic_crtc_set_property(struct drm_crtc *crtc,
int ret;
 
if (property == adev->mode_info.shaper_lut_property) {
-   ret = atomic_replace_property_blob_from_id(crtc->dev,
+   ret = amdgpu_dm_replace_property_blob_from_id(crtc->dev,
_state->shaper_lut,
val,
-1, sizeof(struct drm_color_lut),
@@ -397,7 +364,7 @@ amdgpu_dm_atomic_crtc_set_property(struct drm_crtc *crtc,
acrtc_state->base.color_mgmt_changed |= replaced;
return ret;
} else if (property == adev->mode_info.lut3d_property) {
-   ret = atomic_replace_property_blob_from_id(crtc->dev,
+   ret = amdgpu_dm_replace_property_blob_from_id(crtc->dev,
_state->lut3d,
val,
-1, sizeof(struct drm_color_lut),
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c
index 322668973747..4e5498153be2 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c
@@ -1411,6 +1411,41 @@ static void dm_drm_plane_destroy_state(struct drm_plane 
*plane,
drm_atomic_helper_plane_destroy_state(plane, state);
 }
 
+#ifdef CONFIG_STEAM_DECK
+int
+amdgpu_dm_replace_property_blob_from_id(struct drm_device *dev,
+  struct drm_property_blob **blob,
+  uint64_t blob_id,
+  ssize_t expected_size,
+  ssize_t expected_elem_size,
+  bool *replaced)
+{
+   struct drm_property_blob *new_blob = NULL;
+
+   if (blob_id != 0) {
+   new_blob = drm_property_lookup_blob(dev, blob_id);
+   if (new_blob == NULL)
+   return -EINVAL;
+
+   if (expected_size > 0 &&
+   new_blob->length != expected_size) {
+   drm_property_blob_put(new_blob);
+   return -EINVAL;
+   }
+   if (expected_elem_size > 0 &&
+   new_blob->length % expected_elem_size != 0) {
+   drm_property_blob_put(new_blob);
+   return -EINVAL;
+   }
+   }
+
+   *replaced |= drm_property_replace_blob(blob, new_blob);
+   

[RFC PATCH 07/40] drm/amd/display: add CRTC gamma TF to driver-private props

2023-04-23 Thread Melissa Wen
From: Joshua Ashton 

Add predefined transfer function property to DRM CRTC gamma to convert
to wire encoding with or without gamma LUT.

Co-developed-by: Melissa Wen 
Signed-off-by: Melissa Wen 
Signed-off-by: Joshua Ashton 
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_display.c   | 22 ++
 drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h  |  4 
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h | 23 +++
 .../amd/display/amdgpu_dm/amdgpu_dm_crtc.c| 13 +++
 4 files changed, 62 insertions(+)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
index 2abe5fe87c10..1913903cab88 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
@@ -1248,6 +1248,19 @@ amdgpu_display_user_framebuffer_create(struct drm_device 
*dev,
 }
 
 #ifdef CONFIG_STEAM_DECK
+static const struct drm_prop_enum_list drm_transfer_function_enum_list[] = {
+   { DRM_TRANSFER_FUNCTION_DEFAULT, "Default" },
+   { DRM_TRANSFER_FUNCTION_SRGB, "sRGB" },
+   { DRM_TRANSFER_FUNCTION_BT709, "BT.709" },
+   { DRM_TRANSFER_FUNCTION_PQ, "PQ (Perceptual Quantizer)" },
+   { DRM_TRANSFER_FUNCTION_LINEAR, "Linear" },
+   { DRM_TRANSFER_FUNCTION_UNITY, "Unity" },
+   { DRM_TRANSFER_FUNCTION_HLG, "HLG (Hybrid Log Gamma)" },
+   { DRM_TRANSFER_FUNCTION_GAMMA22, "Gamma 2.2" },
+   { DRM_TRANSFER_FUNCTION_GAMMA24, "Gamma 2.4" },
+   { DRM_TRANSFER_FUNCTION_GAMMA26, "Gamma 2.6" },
+};
+
 static int
 amdgpu_display_create_color_properties(struct amdgpu_device *adev)
 {
@@ -1281,6 +1294,15 @@ amdgpu_display_create_color_properties(struct 
amdgpu_device *adev)
return -ENOMEM;
adev->mode_info.lut3d_size_property = prop;
 
+   prop = drm_property_create_enum(adev_to_drm(adev),
+   DRM_MODE_PROP_ENUM,
+   "GAMMA_TF",
+   drm_transfer_function_enum_list,
+   
ARRAY_SIZE(drm_transfer_function_enum_list));
+   if (!prop)
+   return -ENOMEM;
+   adev->mode_info.gamma_tf_property = prop;
+
return 0;
 }
 #endif
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
index 205fa4f5bea7..76337e18c728 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
@@ -368,6 +368,10 @@ struct amdgpu_mode_info {
 * LUT as supported by the driver (read-only).
 */
struct drm_property *lut3d_size_property;
+   /**
+* @gamma_tf_property: Transfer function for CRTC regamma.
+*/
+   struct drm_property *gamma_tf_property;
 #endif
 };
 
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
index 09c3e1858b56..1e90a2dd445e 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
@@ -699,6 +699,23 @@ static inline void amdgpu_dm_set_mst_status(uint8_t 
*status,
 
 extern const struct amdgpu_ip_block_version dm_ip_block;
 
+#ifdef CONFIG_STEAM_DECK
+enum drm_transfer_function {
+   DRM_TRANSFER_FUNCTION_DEFAULT,
+
+   DRM_TRANSFER_FUNCTION_SRGB,
+   DRM_TRANSFER_FUNCTION_BT709,
+   DRM_TRANSFER_FUNCTION_PQ,
+   DRM_TRANSFER_FUNCTION_LINEAR,
+   DRM_TRANSFER_FUNCTION_UNITY,
+   DRM_TRANSFER_FUNCTION_HLG,
+   DRM_TRANSFER_FUNCTION_GAMMA22,
+   DRM_TRANSFER_FUNCTION_GAMMA24,
+   DRM_TRANSFER_FUNCTION_GAMMA26,
+   DRM_TRANSFER_FUNCTION_MAX,
+};
+#endif
+
 struct dm_plane_state {
struct drm_plane_state base;
struct dc_plane_state *dc_state;
@@ -751,6 +768,12 @@ struct dm_crtc_state {
 *  drm_color_lut.
 */
struct drm_property_blob *lut3d;
+/**
+* @gamma_tf:
+*
+* Pre-defined transfer function for converting internal FB -> wire 
encoding.
+*/
+   enum drm_transfer_function gamma_tf;
 #endif
 };
 
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c
index 0e1280228e6e..79324fbab1f1 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c
@@ -272,6 +272,7 @@ static struct drm_crtc_state 
*dm_crtc_duplicate_state(struct drm_crtc *crtc)
 #ifdef CONFIG_STEAM_DECK
state->shaper_lut = cur->shaper_lut;
state->lut3d = cur->lut3d;
+   state->gamma_tf = cur->gamma_tf;
 
if (state->shaper_lut)
drm_property_blob_get(state->shaper_lut);
@@ -336,6 +337,11 @@ dm_crtc_additional_color_mgmt(struct drm_crtc *crtc)
   

[RFC PATCH 08/40] drm/drm_plane: track color mgmt changes per plane

2023-04-23 Thread Melissa Wen
We will add color mgmt properties to DRM planes in the text patches and
we want to track when one of this properties change to define atomic
commit behaviors. Using a similar approach from CRTC color props, we set
a color_mgmt_changed boolean whenever a plane color prop changes.

Signed-off-by: Melissa Wen 
---
 drivers/gpu/drm/drm_atomic.c  | 1 +
 drivers/gpu/drm/drm_atomic_state_helper.c | 1 +
 include/drm/drm_plane.h   | 7 +++
 3 files changed, 9 insertions(+)

diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c
index c0dc5858a723..da2429470c4f 100644
--- a/drivers/gpu/drm/drm_atomic.c
+++ b/drivers/gpu/drm/drm_atomic.c
@@ -724,6 +724,7 @@ static void drm_atomic_plane_print_state(struct drm_printer 
*p,
   drm_get_color_encoding_name(state->color_encoding));
drm_printf(p, "\tcolor-range=%s\n",
   drm_get_color_range_name(state->color_range));
+   drm_printf(p, "\tcolor_mgmt_changed=%d\n", state->color_mgmt_changed);
 
if (plane->funcs->atomic_print_state)
plane->funcs->atomic_print_state(p, state);
diff --git a/drivers/gpu/drm/drm_atomic_state_helper.c 
b/drivers/gpu/drm/drm_atomic_state_helper.c
index dfb57217253b..3df4c96a902e 100644
--- a/drivers/gpu/drm/drm_atomic_state_helper.c
+++ b/drivers/gpu/drm/drm_atomic_state_helper.c
@@ -338,6 +338,7 @@ void __drm_atomic_helper_plane_duplicate_state(struct 
drm_plane *plane,
state->fence = NULL;
state->commit = NULL;
state->fb_damage_clips = NULL;
+   state->color_mgmt_changed = false;
 }
 EXPORT_SYMBOL(__drm_atomic_helper_plane_duplicate_state);
 
diff --git a/include/drm/drm_plane.h b/include/drm/drm_plane.h
index 447e664e49d5..6c97380b8c76 100644
--- a/include/drm/drm_plane.h
+++ b/include/drm/drm_plane.h
@@ -237,6 +237,13 @@ struct drm_plane_state {
 
/** @state: backpointer to global drm_atomic_state */
struct drm_atomic_state *state;
+
+   /**
+* @color_mgmt_changed: Color management properties have changed. Used
+* by the atomic helpers and drivers to steer the atomic commit control
+* flow.
+*/
+   bool color_mgmt_changed : 1;
 };
 
 static inline struct drm_rect
-- 
2.39.2



[RFC PATCH 04/40] drm/drm_mode_object: increase max objects to accommodate new color props

2023-04-23 Thread Melissa Wen
In the next patches we are adding 17 new properties for color
correction:
- CRTC: 3D LUT+size, shaper LUT+size, regamma TF (5)
- Plane: Degamma LUT+size+TF, HDR multiplier, shaper LUT+size+TF, 3D LUT+size, 
blend
  LUT+size+TF (12)
We still need to detach driver-private counter from DRM/KMS-generic, by
now, increase max objs to 41.

Signed-off-by: Melissa Wen 
---
 include/drm/drm_mode_object.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/include/drm/drm_mode_object.h b/include/drm/drm_mode_object.h
index 912f1e415685..7e4fb7536c6a 100644
--- a/include/drm/drm_mode_object.h
+++ b/include/drm/drm_mode_object.h
@@ -60,7 +60,7 @@ struct drm_mode_object {
void (*free_cb)(struct kref *kref);
 };
 
-#define DRM_OBJECT_MAX_PROPERTY 24
+#define DRM_OBJECT_MAX_PROPERTY 47
 /**
  * struct drm_object_properties - property tracking for _mode_object
  */
-- 
2.39.2



[RFC PATCH 06/40] drm/amd/display: add 3D LUT driver-private props

2023-04-23 Thread Melissa Wen
Add CRTC 3D LUT for gamma correction using a 3D lookup table. A shaper
lut must be set to shape the content for a non-linear space. That
details should be handled by the driver according to HW color
capabilities.

Signed-off-by: Melissa Wen 
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_display.c   | 14 +
 drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h  | 11 ++
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h | 13 
 .../amd/display/amdgpu_dm/amdgpu_dm_crtc.c| 20 +++
 4 files changed, 58 insertions(+)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
index 44c22cb87dde..2abe5fe87c10 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
@@ -1267,6 +1267,20 @@ amdgpu_display_create_color_properties(struct 
amdgpu_device *adev)
return -ENOMEM;
adev->mode_info.shaper_lut_size_property = prop;
 
+   prop = drm_property_create(adev_to_drm(adev),
+  DRM_MODE_PROP_BLOB,
+  "AMD_LUT3D", 0);
+   if (!prop)
+   return -ENOMEM;
+   adev->mode_info.lut3d_property = prop;
+
+   prop = drm_property_create_range(adev_to_drm(adev),
+DRM_MODE_PROP_IMMUTABLE,
+"AMD_LUT3D_SIZE", 0, UINT_MAX);
+   if (!prop)
+   return -ENOMEM;
+   adev->mode_info.lut3d_size_property = prop;
+
return 0;
 }
 #endif
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
index 1fd3497af3b5..205fa4f5bea7 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
@@ -357,6 +357,17 @@ struct amdgpu_mode_info {
 * post-blending shaper LUT as supported by the driver (read-only).
 */
struct drm_property *shaper_lut_size_property;
+   /**
+* lut3d_property: CRTC property to set post-blending 3D LUT gamma
+* correction; a shaper LUT can be used before applying 3D LUT to
+* delinearize content.
+*/
+   struct drm_property *lut3d_property;
+   /**
+* @lut3d_size_property: CRTC property for the size of post-blending 3D
+* LUT as supported by the driver (read-only).
+*/
+   struct drm_property *lut3d_size_property;
 #endif
 };
 
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
index de63455896cc..09c3e1858b56 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
@@ -742,6 +742,15 @@ struct dm_crtc_state {
 * of  drm_color_lut.
 */
struct drm_property_blob *shaper_lut;
+   /**
+* @lut3d:
+*
+* 3D Lookup table for converting pixel data. Position where it takes
+* place depends on hw design, after @ctm or @gamma_lut. See
+* drm_crtc_enable_color_mgmt(). The blob (if not NULL) is an array of
+*  drm_color_lut.
+*/
+   struct drm_property_blob *lut3d;
 #endif
 };
 
@@ -804,6 +813,10 @@ void amdgpu_dm_update_freesync_caps(struct drm_connector 
*connector,
 
 void amdgpu_dm_trigger_timing_sync(struct drm_device *dev);
 
+/* 3D LUT max size is 17x17x17 */
+#define MAX_COLOR_3DLUT_ENTRIES 4913
+#define MAX_COLOR_3DLUT_BITDEPTH 12
+/* 1D LUT degamma, regamma and shaper*/
 #define MAX_COLOR_LUT_ENTRIES 4096
 /* Legacy gamm LUT users such as X doesn't like large LUT sizes */
 #define MAX_COLOR_LEGACY_LUT_ENTRIES 256
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c
index 503433e5cb38..0e1280228e6e 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c
@@ -231,6 +231,7 @@ static void dm_crtc_destroy_state(struct drm_crtc *crtc,
 
 #ifdef CONFIG_STEAM_DECK
drm_property_blob_put(cur->shaper_lut);
+   drm_property_blob_put(cur->lut3d);
 #endif
__drm_atomic_helper_crtc_destroy_state(state);
 
@@ -270,9 +271,12 @@ static struct drm_crtc_state 
*dm_crtc_duplicate_state(struct drm_crtc *crtc)
/* TODO Duplicate dc_stream after objects are stream object is 
flattened */
 #ifdef CONFIG_STEAM_DECK
state->shaper_lut = cur->shaper_lut;
+   state->lut3d = cur->lut3d;
 
if (state->shaper_lut)
drm_property_blob_get(state->shaper_lut);
+   if (state->lut3d)
+   drm_property_blob_get(state->lut3d);
 #endif
return >base;
 }
@@ -326,6 +330,11 @@ dm_crtc_additional_color_mgmt(struct drm_crtc *crtc)
drm_object_attach_property(>base,
   
adev->mode_info.shaper_lut_size_proper

[RFC PATCH 05/40] drm/amd/display: add shaper LUT driver-private props

2023-04-23 Thread Melissa Wen
CRTC shaper LUT shapes the content after blending, i.e., de-linearizes
or normalizes space before applying a 3D LUT color correction. In the
next patch, we add CRTC 3D LUT property to DRM color management after
this shaper LUT and before the current CRTC gamma LUT.

Signed-off-by: Melissa Wen 
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_display.c   |  28 
 drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h  |  14 ++
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h |  17 +++
 .../amd/display/amdgpu_dm/amdgpu_dm_crtc.c| 122 +-
 4 files changed, 179 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
index 8632ab695a6c..44c22cb87dde 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
@@ -1247,6 +1247,30 @@ amdgpu_display_user_framebuffer_create(struct drm_device 
*dev,
return _fb->base;
 }
 
+#ifdef CONFIG_STEAM_DECK
+static int
+amdgpu_display_create_color_properties(struct amdgpu_device *adev)
+{
+   struct drm_property *prop;
+
+   prop = drm_property_create(adev_to_drm(adev),
+  DRM_MODE_PROP_BLOB,
+  "AMD_SHAPER_LUT", 0);
+   if (!prop)
+   return -ENOMEM;
+   adev->mode_info.shaper_lut_property = prop;
+
+   prop = drm_property_create_range(adev_to_drm(adev),
+DRM_MODE_PROP_IMMUTABLE,
+"AMD_SHAPER_LUT_SIZE", 0, UINT_MAX);
+   if (!prop)
+   return -ENOMEM;
+   adev->mode_info.shaper_lut_size_property = prop;
+
+   return 0;
+}
+#endif
+
 const struct drm_mode_config_funcs amdgpu_mode_funcs = {
.fb_create = amdgpu_display_user_framebuffer_create,
 };
@@ -1323,6 +1347,10 @@ int amdgpu_display_modeset_create_props(struct 
amdgpu_device *adev)
return -ENOMEM;
}
 
+#ifdef CONFIG_STEAM_DECK
+   if (amdgpu_display_create_color_properties(adev))
+   return -ENOMEM;
+#endif
return 0;
 }
 
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
index b8633df418d4..1fd3497af3b5 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
@@ -344,6 +344,20 @@ struct amdgpu_mode_info {
int disp_priority;
const struct amdgpu_display_funcs *funcs;
const enum drm_plane_type *plane_type;
+
+   /* Driver-private color mgmt props */
+#ifdef CONFIG_STEAM_DECK
+   /**
+* @shaper_lut_property: CRTC property to set post-blending shaper LUT
+* that converts content before 3D LUT gamma correction.
+*/
+   struct drm_property *shaper_lut_property;
+   /**
+* @shaper_lut_size_property: CRTC property for the size of
+* post-blending shaper LUT as supported by the driver (read-only).
+*/
+   struct drm_property *shaper_lut_size_property;
+#endif
 };
 
 #define AMDGPU_MAX_BL_LEVEL 0xFF
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
index 2e2413fd73a4..de63455896cc 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
@@ -726,6 +726,23 @@ struct dm_crtc_state {
struct dc_info_packet vrr_infopacket;
 
int abm_level;
+
+#ifdef CONFIG_STEAM_DECK
+   /* AMD driver-private color mgmt pipeline
+*
+* DRM provides CRTC degamma/ctm/gamma color mgmt features, but AMD HW
+* has a larger set of post-blending color calibration features, as
+* below:
+*/
+   /**
+* @shaper_lut:
+*
+* Lookup table used to de-linearize pixel data for gamma correction.
+* See drm_crtc_enable_color_mgmt(). The blob (if not NULL) is an array
+* of  drm_color_lut.
+*/
+   struct drm_property_blob *shaper_lut;
+#endif
 };
 
 #define to_dm_crtc_state(x) container_of(x, struct dm_crtc_state, base)
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c
index e3762e806617..503433e5cb38 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c
@@ -229,7 +229,9 @@ static void dm_crtc_destroy_state(struct drm_crtc *crtc,
if (cur->stream)
dc_stream_release(cur->stream);
 
-
+#ifdef CONFIG_STEAM_DECK
+   drm_property_blob_put(cur->shaper_lut);
+#endif
__drm_atomic_helper_crtc_destroy_state(state);
 
 
@@ -266,7 +268,12 @@ static struct drm_crtc_state 
*dm_crtc_duplicate_state(struct drm_crtc *crtc)
state->crc_skip_count = cur->crc_skip_count;
state->mpo_requested = cur->mpo_requested;

[RFC PATCH 03/40] drm/amd/display: introduce Steam Deck color features to AMD display driver

2023-04-23 Thread Melissa Wen
We are enabling a large set of color calibration features to enhance KMS
color mgmt but these properties are specific of AMD display HW, and
cannot be provided by other vendors. Therefore, set a config option to
enable AMD driver-private properties used on Steam Deck color mgmt
pipeline.

Co-developed-by: Joshua Ashton 
Signed-off-by: Joshua Ashton 
Signed-off-by: Melissa Wen 
---
 drivers/gpu/drm/amd/display/Kconfig | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/drivers/gpu/drm/amd/display/Kconfig 
b/drivers/gpu/drm/amd/display/Kconfig
index 06b438217c61..c45a8deb1098 100644
--- a/drivers/gpu/drm/amd/display/Kconfig
+++ b/drivers/gpu/drm/amd/display/Kconfig
@@ -53,5 +53,11 @@ config DRM_AMD_SECURE_DISPLAY
 of crc of specific region via debugfs.
 Cooperate with specific DMCU FW.
 
+config STEAM_DECK
+   bool "Enable color calibration features for Steam Deck"
+   depends on DRM_AMD_DC
+   help
+ Choose this option if you want to use AMDGPU features for broader
+ color management support on Steam Deck.
 
 endmenu
-- 
2.39.2



[RFC PATCH 02/40] drm/amd/display: fix the delta clamping for shaper LUT

2023-04-23 Thread Melissa Wen
From: Harry Wentland 

The shaper LUT requires a 10-bit value of the delta between
segments. We were using dc_fixpt_clamp_u0d10() to do that
but it doesn't do what we want it to do. It will preserve
10-bit precision after the decimal point, but that's not
quite what we want. We want 14-bit precision and discard
the 4 most-significant bytes.

To do that we'll do dc_fixpt_clamp_u0d14() & 0x3ff instead.

Signed-off-by: Harry Wentland 
---
 .../gpu/drm/amd/display/dc/dcn10/dcn10_cm_common.c | 14 +++---
 1 file changed, 11 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_cm_common.c 
b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_cm_common.c
index f27413e94280..efa6cee649d0 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_cm_common.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_cm_common.c
@@ -539,10 +539,18 @@ bool cm_helper_translate_curve_to_hw_format(
rgb->delta_green = dc_fixpt_sub(rgb_plus_1->green, rgb->green);
rgb->delta_blue  = dc_fixpt_sub(rgb_plus_1->blue,  rgb->blue);
 
+
if (fixpoint == true) {
-   rgb->delta_red_reg   = 
dc_fixpt_clamp_u0d10(rgb->delta_red);
-   rgb->delta_green_reg = 
dc_fixpt_clamp_u0d10(rgb->delta_green);
-   rgb->delta_blue_reg  = 
dc_fixpt_clamp_u0d10(rgb->delta_blue);
+   uint32_t red_clamp = 
dc_fixpt_clamp_u0d14(rgb->delta_red);
+   uint32_t green_clamp = 
dc_fixpt_clamp_u0d14(rgb->delta_green);
+   uint32_t blue_clamp = 
dc_fixpt_clamp_u0d14(rgb->delta_blue);
+
+   if (red_clamp >> 10 || green_clamp >> 10 || blue_clamp 
>> 10)
+   DC_LOG_WARNING("Losing delta precision while 
programming shaper LUT.");
+
+   rgb->delta_red_reg   = red_clamp & 0x3ff;
+   rgb->delta_green_reg = green_clamp & 0x3ff;
+   rgb->delta_blue_reg  = blue_clamp & 0x3ff;
rgb->red_reg = dc_fixpt_clamp_u0d14(rgb->red);
rgb->green_reg   = dc_fixpt_clamp_u0d14(rgb->green);
rgb->blue_reg= dc_fixpt_clamp_u0d14(rgb->blue);
-- 
2.39.2



[RFC PATCH 01/40] drm/amd/display: fix segment distribution for linear LUTs

2023-04-23 Thread Melissa Wen
From: Harry Wentland 

The region and segment calculation was incapable of dealing
with regions of more than 16 segments. We first fix this.

Now that we can support regions up to 256 elements we can
define a better segment distribution for near-linear LUTs
for our maximum of 256 HW-supported points.

With these changes an "identity" LUT looks visually
indistinguishable from bypass and allows us to use
our 3DLUT.

Signed-off-by: Harry Wentland 
---
 .../amd/display/dc/dcn10/dcn10_cm_common.c| 95 +++
 1 file changed, 76 insertions(+), 19 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_cm_common.c 
b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_cm_common.c
index 7a00fe525dfb..f27413e94280 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_cm_common.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_cm_common.c
@@ -346,20 +346,37 @@ bool cm_helper_translate_curve_to_hw_format(
 * segment is from 2^-10 to 2^1
 * There are less than 256 points, for optimization
 */
-   seg_distr[0] = 3;
-   seg_distr[1] = 4;
-   seg_distr[2] = 4;
-   seg_distr[3] = 4;
-   seg_distr[4] = 4;
-   seg_distr[5] = 4;
-   seg_distr[6] = 4;
-   seg_distr[7] = 4;
-   seg_distr[8] = 4;
-   seg_distr[9] = 4;
-   seg_distr[10] = 1;
-
-   region_start = -10;
-   region_end = 1;
+   if (output_tf->tf == TRANSFER_FUNCTION_LINEAR) {
+   seg_distr[0] = 0; /* 2 */
+   seg_distr[1] = 1; /* 4 */
+   seg_distr[2] = 2; /* 4 */
+   seg_distr[3] = 3; /* 8 */
+   seg_distr[4] = 4; /* 16 */
+   seg_distr[5] = 5; /* 32 */
+   seg_distr[6] = 6; /* 64 */
+   seg_distr[7] = 7; /* 128 */
+
+   region_start = -8;
+   region_end = 1;
+   } else {
+   seg_distr[0] = 3; /* 8 */
+   seg_distr[1] = 4; /* 16 */
+   seg_distr[2] = 4;
+   seg_distr[3] = 4;
+   seg_distr[4] = 4;
+   seg_distr[5] = 4;
+   seg_distr[6] = 4;
+   seg_distr[7] = 4;
+   seg_distr[8] = 4;
+   seg_distr[9] = 4;
+   seg_distr[10] = 1; /* 2 */
+   /* total = 8*16 + 8 + 64 + 2 = */
+
+   region_start = -10;
+   region_end = 1;
+   }
+
+
}
 
for (i = region_end - region_start; i < MAX_REGIONS_NUMBER ; i++)
@@ -372,16 +389,56 @@ bool cm_helper_translate_curve_to_hw_format(
 
j = 0;
for (k = 0; k < (region_end - region_start); k++) {
-   increment = NUMBER_SW_SEGMENTS / (1 << seg_distr[k]);
+   /*
+* We're using an ugly-ish hack here. Our HW allows for
+* 256 segments per region but SW_SEGMENTS is 16.
+* SW_SEGMENTS has some undocumented relationship to
+* the number of points in the tf_pts struct, which
+* is 512, unlike what's suggested TRANSFER_FUNC_POINTS.
+*
+* In order to work past this dilemma we'll scale our
+* increment by (1 << 4) and then do the inverse (1 >> 4)
+* when accessing the elements in tf_pts.
+*
+* TODO: find a better way using SW_SEGMENTS and
+*   TRANSFER_FUNC_POINTS definitions
+*/
+   increment = (NUMBER_SW_SEGMENTS << 4) / (1 << seg_distr[k]);
start_index = (region_start + k + MAX_LOW_POINT) *
NUMBER_SW_SEGMENTS;
-   for (i = start_index; i < start_index + NUMBER_SW_SEGMENTS;
+   for (i = (start_index << 4); i < (start_index << 4) + 
(NUMBER_SW_SEGMENTS << 4);
i += increment) {
+   struct fixed31_32 in_plus_one, in;
+   struct fixed31_32 value, red_value, green_value, 
blue_value;
+   uint32_t t = i & 0xf;
+
if (j == hw_points - 1)
break;
-   rgb_resulted[j].red = output_tf->tf_pts.red[i];
-   rgb_resulted[j].green = output_tf->tf_pts.green[i];
-   rgb_resulted[j].blue = output_tf->tf_pts.blue[i];
+
+   in_plus_one = output_tf->tf_pts.red[(i >> 4) + 1];
+   in = output_tf->tf_pts.red[i >> 4];
+   value = dc_fixpt_sub(in_plus_one, in);
+   value = dc_fixpt_shr(dc_fixpt_mul_int(value, t),  4);
+ 

[RFC PATCH 00/40] drm/amd/display: add AMD driver-specific properties for color mgmt

2023-04-23 Thread Melissa Wen
Hi all,

Joshua Ashton and I (with the great collaboration of Harry Wentland -
thanks) have been working on KMS color pipeline enhancement for Steam
Deck/SteamOS by exposing the large set of color caps available in AMD
display HW.

This patchset results from this full-stack work, including pre-blending
and post-blending new color properties. The first two patches fix
quantization issues on shaper LUT programming. Just after, we have one
patch that adds a config option to restrict AMD colo feature usage. The
following 13 patches implement AMD driver-private color properties
(pending detachment of property counter and plane color_mgmt_changed
from DRM). Finally, the last 24 patches rework the AMD display manager
and color management to support the properties exposed.

In short, for pre-blending, we added the following:
- plane degamma LUT and predefined transfer function;
- plane HDR multiplier
- plane shaper LUT/transfer function;
- plane 3D LUT; and finally,
- plane blend LUT/transfer function, just before blending.

After blending, we already have DRM CRTC degamma/gamma LUTs and CTM,
therefore, we extend CRTC color pipeline with the following:
- CRTC shaper LUT/transfer function;
- CRTC 3D LUT; and
- CRTC gamma transfer function.

You can already find the AMD color capabilities and color management
pipeline documented here:
https://dri.freedesktop.org/docs/drm/gpu/amdgpu/display/display-manager.html#color-management-properties

In previous iterations, we tried to provide a generic solution for
post-blending shaper and 3D LUT [1][2][3], and also Alex Hung worked on
a pre-blending 3D LUT solution[4] extending plane color mgmt proposal
from Uma Shankar [5]. However, we identified during our work [6] that
AMD provides many other valuable capabilities that we don't find in
other vendors, so we started to work on AMD driver-private color
properties that better describe its color pipeline, enabling us to
expose full AMD color capabilities on Deck HW.

Our primary purpose is to avoid usage limitations of color calibration
features provided by HW just because we don't have an interface for
that. At the same time, a generic solution doesn't fit well since some
of these capabilities seem AMD HW specific, such as hardcoded
curve/predefined transfer function and shaper 1D LUTs sandwiching 3D
LUT.

So far, we keep these properties' usage under an AMD display config
option (STEAM_DECK). However, we are fine with having them fully
available to other DCN HW generations. In the current proposal, we are
already checking ASICs before exposing a color feature. We can work on
3D LUT resource acquisition details to fit them to DCN 3+ families that
support them. Indeed, before moving to these config boundaries, we
started working on an open solution for any AMD HW [7].

The userspace case here is Gamescope which is the compositor for
SteamOS. It's already using all of this functionality (although with a
VALVE1_ prefix instead of AMD) to implement its color management
pipeline right now:
https://github.com/ValveSoftware/gamescope

We are planning on shipping our color management support with gamut
mapping, HDR, SDR on HDR, HDR on SDR, and much more in Steam OS 3.5. A
brief overview of our color pipeline can be found here:
https://github.com/ValveSoftware/gamescope/blob/master/src/docs/Steam%20Deck%20Display%20Pipeline.png

We have also had some other userspace interests from Xaver Hugl (KDE) in
experimenting with these properties for their HDR/color bring-up before
a generic interface is settled on also.

It still needs AMD-specific IGT tests; we are working on documentation
and adding plane CTM support too. 

We decided first to share our work to collect thoughts and open for
discussion, even with missing refinements, since driver-private
properties are not the usual DMR/KMS color management approach.

Please, let us know your thoughts.

Best Regards,

Signed-off-by: Joshua Ashton 
Signed-off-by: Melissa Wen

[1] https://lore.kernel.org/dri-devel/20220619223104.667413-1-m...@igalia.com/
[2] https://lore.kernel.org/amd-gfx/20220906164628.2361811-1-m...@igalia.com/
[3] https://lore.kernel.org/dri-devel/20230109143846.1966301-1-m...@igalia.com/
[4] 
https://lore.kernel.org/dri-devel/20221004211451.1475215-1-alex.h...@amd.com/
[5] 
https://lore.kernel.org/dri-devel/20210906213904.27918-1-uma.shan...@intel.com/
[6] https://gitlab.freedesktop.org/mwen/linux-amd/-/commits/amd-color-mgmt
[7] 
https://gitlab.freedesktop.org/mwen/linux-amd/-/commits/amd-private-color-mgmt

Harry Wentland (2):
  drm/amd/display: fix segment distribution for linear LUTs
  drm/amd/display: fix the delta clamping for shaper LUT

Joshua Ashton (15):
  drm/amd/display: add CRTC gamma TF to driver-private props
  drm/amd/display: add plane degamma LUT driver-private props
  drm/amd/display: add plane degamma TF driver-private property
  drm/amd/display: add plane HDR multiplier driver-private property
  drm/amd/display: add plane blend LUT and TF driver-private

Re: [PATCH] drm/amd/display: Set MPC_SPLIT_DYNAMIC for DCN301

2023-03-11 Thread Melissa Wen
On 03/09, Rodrigo Siqueira wrote:
> Since DC version 3.2.226, DC started to use a new internal commit
> sequence that better deals with hardware limitations. Usually, DC adopts
> split pipe dynamics to improve the display bandwidth and, in some cases,
> to save power. This commit sets MPC_SPLIT_DYNAMIC for DCN301, improving
> the bandwidth and fixing the cursor bug on KDE when it tries hardware
> rotation.

Hi Siqueira,

Thanks for the work on allowing this pipe split policy change. I've
tested SteamDeck system behavior with this change and overall LGTM.

From my previous tests on HW rotation, I don't see glitches when
splitting pipe, the issue only appears on one-pipe setup, but Xaver is
the best person to validate this on KDE environment.

Thanks,
Reviewed-by: Melissa Wen 

> 
> Bug: https://gitlab.freedesktop.org/drm/amd/-/issues/2247
> Cc: Melissa Wen 
> Cc: Xaver Hugl 
> Signed-off-by: Rodrigo Siqueira 
> ---
>  drivers/gpu/drm/amd/display/dc/dcn301/dcn301_resource.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/gpu/drm/amd/display/dc/dcn301/dcn301_resource.c 
> b/drivers/gpu/drm/amd/display/dc/dcn301/dcn301_resource.c
> index b93b4498dba4..5ac2a272c380 100644
> --- a/drivers/gpu/drm/amd/display/dc/dcn301/dcn301_resource.c
> +++ b/drivers/gpu/drm/amd/display/dc/dcn301/dcn301_resource.c
> @@ -687,7 +687,7 @@ static const struct dc_debug_options debug_defaults_drv = 
> {
>   .disable_clock_gate = true,
>   .disable_pplib_clock_request = true,
>   .disable_pplib_wm_range = true,
> - .pipe_split_policy = MPC_SPLIT_AVOID,
> + .pipe_split_policy = MPC_SPLIT_DYNAMIC,
>   .force_single_disp_pipe_split = false,
>   .disable_dcc = DCC_ENABLE,
>   .vsr_support = true,
> -- 
> 2.39.2
> 


signature.asc
Description: PGP signature


[PATCH 6/6] drm/amd/display: remove unused _calculate_degamma_curve function

2023-02-14 Thread Melissa Wen
We don't use this function anywhere, therefore, remove it.

Signed-off-by: Melissa Wen 
---
 .../amd/display/modules/color/color_gamma.c   | 86 ---
 .../amd/display/modules/color/color_gamma.h   |  3 -
 2 files changed, 89 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/modules/color/color_gamma.c 
b/drivers/gpu/drm/amd/display/modules/color/color_gamma.c
index 6e606b11286a..67a062af3ab0 100644
--- a/drivers/gpu/drm/amd/display/modules/color/color_gamma.c
+++ b/drivers/gpu/drm/amd/display/modules/color/color_gamma.c
@@ -2217,89 +2217,3 @@ bool mod_color_calculate_regamma_params(struct 
dc_transfer_func *output_tf,
 rgb_user_alloc_fail:
return ret;
 }
-
-bool  mod_color_calculate_degamma_curve(enum dc_transfer_func_predefined trans,
-   struct dc_transfer_func_distributed_points 
*points)
-{
-   uint32_t i;
-   bool ret = false;
-   struct pwl_float_data_ex *rgb_degamma = NULL;
-
-   if (trans == TRANSFER_FUNCTION_UNITY ||
-   trans == TRANSFER_FUNCTION_LINEAR) {
-
-   for (i = 0; i <= MAX_HW_POINTS ; i++) {
-   points->red[i]= coordinates_x[i].x;
-   points->green[i]  = coordinates_x[i].x;
-   points->blue[i]   = coordinates_x[i].x;
-   }
-   ret = true;
-   } else if (trans == TRANSFER_FUNCTION_PQ) {
-   rgb_degamma = kvcalloc(MAX_HW_POINTS + _EXTRA_POINTS,
-  sizeof(*rgb_degamma),
-  GFP_KERNEL);
-   if (!rgb_degamma)
-   goto rgb_degamma_alloc_fail;
-
-
-   build_de_pq(rgb_degamma,
-   MAX_HW_POINTS,
-   coordinates_x);
-   for (i = 0; i <= MAX_HW_POINTS ; i++) {
-   points->red[i]= rgb_degamma[i].r;
-   points->green[i]  = rgb_degamma[i].g;
-   points->blue[i]   = rgb_degamma[i].b;
-   }
-   ret = true;
-
-   kvfree(rgb_degamma);
-   } else if (trans == TRANSFER_FUNCTION_SRGB ||
-   trans == TRANSFER_FUNCTION_BT709 ||
-   trans == TRANSFER_FUNCTION_GAMMA22 ||
-   trans == TRANSFER_FUNCTION_GAMMA24 ||
-   trans == TRANSFER_FUNCTION_GAMMA26) {
-   rgb_degamma = kvcalloc(MAX_HW_POINTS + _EXTRA_POINTS,
-  sizeof(*rgb_degamma),
-  GFP_KERNEL);
-   if (!rgb_degamma)
-   goto rgb_degamma_alloc_fail;
-
-   build_degamma(rgb_degamma,
-   MAX_HW_POINTS,
-   coordinates_x,
-   trans);
-   for (i = 0; i <= MAX_HW_POINTS ; i++) {
-   points->red[i]= rgb_degamma[i].r;
-   points->green[i]  = rgb_degamma[i].g;
-   points->blue[i]   = rgb_degamma[i].b;
-   }
-   ret = true;
-
-   kvfree(rgb_degamma);
-   } else if (trans == TRANSFER_FUNCTION_HLG) {
-   rgb_degamma = kvcalloc(MAX_HW_POINTS + _EXTRA_POINTS,
-  sizeof(*rgb_degamma),
-  GFP_KERNEL);
-   if (!rgb_degamma)
-   goto rgb_degamma_alloc_fail;
-
-   build_hlg_degamma(rgb_degamma,
-   MAX_HW_POINTS,
-   coordinates_x,
-   80, 1000);
-   for (i = 0; i <= MAX_HW_POINTS ; i++) {
-   points->red[i]= rgb_degamma[i].r;
-   points->green[i]  = rgb_degamma[i].g;
-   points->blue[i]   = rgb_degamma[i].b;
-   }
-   ret = true;
-   kvfree(rgb_degamma);
-   }
-   points->end_exponent = 0;
-   points->x_point_at_y1_red = 1;
-   points->x_point_at_y1_green = 1;
-   points->x_point_at_y1_blue = 1;
-
-rgb_degamma_alloc_fail:
-   return ret;
-}
diff --git a/drivers/gpu/drm/amd/display/modules/color/color_gamma.h 
b/drivers/gpu/drm/amd/display/modules/color/color_gamma.h
index 2893abf48208..ee5c466613de 100644
--- a/drivers/gpu/drm/amd/display/modules/color/color_gamma.h
+++ b/drivers/gpu/drm/amd/display/modules/color/color_gamma.h
@@ -115,9 +115,6 @@ bool mod_color_calculate_degamma_params(struct 
dc_color_caps *dc_caps,
struct dc_transfer_func *output_tf,
const struct dc_gamma *ramp, bool mapUserRamp);
 
-bool mod_color_calculate_degamma_curve(enum dc_transfer_func_predefined trans,
-   struct dc_transfer_func_distributed_points 
*points);
-
 bool cal

[PATCH 2/6] drm/amd/display: clean code-style issues in dcn30_set_mpc_shaper_3dlut

2023-02-14 Thread Melissa Wen
This function has many conditions and all code style issues (identation,
missing braces, etc.) make reading it really annoying.

Signed-off-by: Melissa Wen 
---
 .../drm/amd/display/dc/dcn30/dcn30_hwseq.c| 37 ++-
 1 file changed, 19 insertions(+), 18 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.c 
b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.c
index 9ce86f288130..df787fcf8e86 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.c
@@ -90,8 +90,8 @@ bool dcn30_set_blend_lut(
return result;
 }
 
-static bool dcn30_set_mpc_shaper_3dlut(
-   struct pipe_ctx *pipe_ctx, const struct dc_stream_state *stream)
+static bool dcn30_set_mpc_shaper_3dlut(struct pipe_ctx *pipe_ctx,
+  const struct dc_stream_state *stream)
 {
struct dpp *dpp_base = pipe_ctx->plane_res.dpp;
int mpcc_id = pipe_ctx->plane_res.hubp->inst;
@@ -103,19 +103,18 @@ static bool dcn30_set_mpc_shaper_3dlut(
const struct pwl_params *shaper_lut = NULL;
//get the shaper lut params
if (stream->func_shaper) {
-   if (stream->func_shaper->type == TF_TYPE_HWPWL)
+   if (stream->func_shaper->type == TF_TYPE_HWPWL) {
shaper_lut = >func_shaper->pwl;
-   else if (stream->func_shaper->type == 
TF_TYPE_DISTRIBUTED_POINTS) {
-   cm_helper_translate_curve_to_hw_format(
-   stream->func_shaper,
-   _base->shaper_params, true);
+   } else if (stream->func_shaper->type == 
TF_TYPE_DISTRIBUTED_POINTS) {
+   
cm_helper_translate_curve_to_hw_format(stream->func_shaper,
+  
_base->shaper_params, true);
shaper_lut = _base->shaper_params;
}
}
 
if (stream->lut3d_func &&
-   stream->lut3d_func->state.bits.initialized == 1 &&
-   stream->lut3d_func->state.bits.rmu_idx_valid == 1) {
+   stream->lut3d_func->state.bits.initialized == 1 &&
+   stream->lut3d_func->state.bits.rmu_idx_valid == 1) {
if (stream->lut3d_func->state.bits.rmu_mux_num == 0)
mpcc_id_projected = 
stream->lut3d_func->state.bits.mpc_rmu0_mux;
else if (stream->lut3d_func->state.bits.rmu_mux_num == 1)
@@ -124,20 +123,22 @@ static bool dcn30_set_mpc_shaper_3dlut(
mpcc_id_projected = 
stream->lut3d_func->state.bits.mpc_rmu2_mux;
if (mpcc_id_projected != mpcc_id)
BREAK_TO_DEBUGGER();
-   /*find the reason why logical layer assigned a differant 
mpcc_id into acquire_post_bldn_3dlut*/
+   /* find the reason why logical layer assigned a different
+* mpcc_id into acquire_post_bldn_3dlut
+*/
acquired_rmu = mpc->funcs->acquire_rmu(mpc, mpcc_id,
-   stream->lut3d_func->state.bits.rmu_mux_num);
+  
stream->lut3d_func->state.bits.rmu_mux_num);
if (acquired_rmu != stream->lut3d_func->state.bits.rmu_mux_num)
BREAK_TO_DEBUGGER();
-   result = mpc->funcs->program_3dlut(mpc,
-   
>lut3d_func->lut_3d,
-   
stream->lut3d_func->state.bits.rmu_mux_num);
+
+   result = mpc->funcs->program_3dlut(mpc, 
>lut3d_func->lut_3d,
+  
stream->lut3d_func->state.bits.rmu_mux_num);
result = mpc->funcs->program_shaper(mpc, shaper_lut,
-   stream->lut3d_func->state.bits.rmu_mux_num);
-   } else
-   /*loop through the available mux and release the requested 
mpcc_id*/
+   
stream->lut3d_func->state.bits.rmu_mux_num);
+   } else {
+   // loop through the available mux and release the requested 
mpcc_id
mpc->funcs->release_rmu(mpc, mpcc_id);
-
+   }
 
return result;
 }
-- 
2.39.0



[PATCH 4/6] drm/amd/display: unset initial value for tf since it's never used

2023-02-14 Thread Melissa Wen
In mod_color_calculate_{degamma/regamma}_params(), a tf variable is
initialized as TRANSFER_FUNCTION_SRGB but tf is only used after tf =
input->tf, therefore, better to just remove this initial value and avoid
misleading interpretations.

Signed-off-by: Melissa Wen 
---
 drivers/gpu/drm/amd/display/modules/color/color_gamma.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/modules/color/color_gamma.c 
b/drivers/gpu/drm/amd/display/modules/color/color_gamma.c
index fdb20dfc70c9..6e606b11286a 100644
--- a/drivers/gpu/drm/amd/display/modules/color/color_gamma.c
+++ b/drivers/gpu/drm/amd/display/modules/color/color_gamma.c
@@ -1883,7 +1883,7 @@ bool mod_color_calculate_degamma_params(struct 
dc_color_caps *dc_caps,
struct pwl_float_data_ex *curve = NULL;
struct gamma_pixel *axis_x = NULL;
struct pixel_gamma_point *coeff = NULL;
-   enum dc_transfer_func_predefined tf = TRANSFER_FUNCTION_SRGB;
+   enum dc_transfer_func_predefined tf;
uint32_t i;
bool ret = false;
 
@@ -2125,7 +2125,7 @@ bool mod_color_calculate_regamma_params(struct 
dc_transfer_func *output_tf,
struct pwl_float_data_ex *rgb_regamma = NULL;
struct gamma_pixel *axis_x = NULL;
struct pixel_gamma_point *coeff = NULL;
-   enum dc_transfer_func_predefined tf = TRANSFER_FUNCTION_SRGB;
+   enum dc_transfer_func_predefined tf;
bool do_clamping = true;
bool ret = false;
 
-- 
2.39.0



[PATCH 5/6] drm/amd/display: remove unused func declaration from resource headers

2023-02-14 Thread Melissa Wen
The function resource_validate_ctx_update_pointer_after_copy() is
declared in resource.h but never defined, therefore, remove its
declaration from headers.

Signed-off-by: Melissa Wen 
---
 drivers/gpu/drm/amd/display/dc/inc/resource.h | 4 
 1 file changed, 4 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/inc/resource.h 
b/drivers/gpu/drm/amd/display/dc/inc/resource.h
index 4ab029e3326d..fa6da93caa88 100644
--- a/drivers/gpu/drm/amd/display/dc/inc/resource.h
+++ b/drivers/gpu/drm/amd/display/dc/inc/resource.h
@@ -165,10 +165,6 @@ bool resource_validate_attach_surfaces(
struct dc_state *context,
const struct resource_pool *pool);
 
-void resource_validate_ctx_update_pointer_after_copy(
-   const struct dc_state *src_ctx,
-   struct dc_state *dst_ctx);
-
 enum dc_status resource_map_clock_resources(
const struct dc *dc,
struct dc_state *context,
-- 
2.39.0



[PATCH 3/6] drm/amd/display: camel case cleanup in color_gamma file

2023-02-14 Thread Melissa Wen
Rename mapUserRamp to map_user_ramp and doClamping to do_clamping

Signed-off-by: Melissa Wen 
---
 .../amd/display/modules/color/color_gamma.c   | 50 ++-
 1 file changed, 26 insertions(+), 24 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/modules/color/color_gamma.c 
b/drivers/gpu/drm/amd/display/modules/color/color_gamma.c
index f6034213c700..fdb20dfc70c9 100644
--- a/drivers/gpu/drm/amd/display/modules/color/color_gamma.c
+++ b/drivers/gpu/drm/amd/display/modules/color/color_gamma.c
@@ -1715,8 +1715,8 @@ static bool map_regamma_hw_to_x_user(
const struct pwl_float_data_ex *rgb_regamma,
uint32_t hw_points_num,
struct dc_transfer_func_distributed_points *tf_pts,
-   bool mapUserRamp,
-   bool doClamping)
+   bool map_user_ramp,
+   bool do_clamping)
 {
/* setup to spare calculated ideal regamma values */
 
@@ -1724,7 +1724,7 @@ static bool map_regamma_hw_to_x_user(
struct hw_x_point *coords = coords_x;
const struct pwl_float_data_ex *regamma = rgb_regamma;
 
-   if (ramp && mapUserRamp) {
+   if (ramp && map_user_ramp) {
copy_rgb_regamma_to_coordinates_x(coords,
hw_points_num,
rgb_regamma);
@@ -1744,7 +1744,7 @@ static bool map_regamma_hw_to_x_user(
}
}
 
-   if (doClamping) {
+   if (do_clamping) {
/* this should be named differently, all it does is clamp to 
0-1 */
build_new_custom_resulted_curve(hw_points_num, tf_pts);
}
@@ -1875,7 +1875,7 @@ bool calculate_user_regamma_ramp(struct dc_transfer_func 
*output_tf,
 
 bool mod_color_calculate_degamma_params(struct dc_color_caps *dc_caps,
struct dc_transfer_func *input_tf,
-   const struct dc_gamma *ramp, bool mapUserRamp)
+   const struct dc_gamma *ramp, bool map_user_ramp)
 {
struct dc_transfer_func_distributed_points *tf_pts = _tf->tf_pts;
struct dividers dividers;
@@ -1891,12 +1891,12 @@ bool mod_color_calculate_degamma_params(struct 
dc_color_caps *dc_caps,
return false;
 
/* we can use hardcoded curve for plain SRGB TF
-* If linear, it's bypass if on user ramp
+* If linear, it's bypass if no user ramp
 */
if (input_tf->type == TF_TYPE_PREDEFINED) {
if ((input_tf->tf == TRANSFER_FUNCTION_SRGB ||
input_tf->tf == TRANSFER_FUNCTION_LINEAR) &&
-   !mapUserRamp)
+   !map_user_ramp)
return true;
 
if (dc_caps != NULL &&
@@ -1919,7 +1919,7 @@ bool mod_color_calculate_degamma_params(struct 
dc_color_caps *dc_caps,
 
input_tf->type = TF_TYPE_DISTRIBUTED_POINTS;
 
-   if (mapUserRamp && ramp && ramp->type == GAMMA_RGB_256) {
+   if (map_user_ramp && ramp && ramp->type == GAMMA_RGB_256) {
rgb_user = kvcalloc(ramp->num_entries + _EXTRA_POINTS,
sizeof(*rgb_user),
GFP_KERNEL);
@@ -2007,7 +2007,7 @@ bool mod_color_calculate_degamma_params(struct 
dc_color_caps *dc_caps,
map_regamma_hw_to_x_user(ramp, coeff, rgb_user,
coordinates_x, axis_x, curve,
MAX_HW_POINTS, tf_pts,
-   mapUserRamp && ramp && ramp->type == 
GAMMA_RGB_256,
+   map_user_ramp && ramp && ramp->type == 
GAMMA_RGB_256,
true);
}
 
@@ -2112,9 +2112,11 @@ static bool calculate_curve(enum 
dc_transfer_func_predefined trans,
 }
 
 bool mod_color_calculate_regamma_params(struct dc_transfer_func *output_tf,
-   const struct dc_gamma *ramp, bool mapUserRamp, bool 
canRomBeUsed,
-   const struct hdr_tm_params *fs_params,
-   struct calculate_buffer *cal_buffer)
+   const struct dc_gamma *ramp,
+   bool map_user_ramp,
+   bool can_rom_be_used,
+   const struct hdr_tm_params *fs_params,
+   struct calculate_buffer *cal_buffer)
 {
struct dc_transfer_func_distributed_points *tf_pts = _tf->tf_pts;
struct dividers dividers;
@@ -2124,26 +2126,26 @@ bool mod_color_calculate_regamma_params(struct 
dc_transfer_func *output_tf,
struct gamma_pixel *axis_x = NULL;
struct pixel_gamma_point *coeff = NULL;
enum dc_transfer_func_predefined tf = TRANSFER_FUNCTION_SRGB;
-   bool doClamping = true;
+   bool do_clamping = true;
bool ret = false;
 
if (output_tf->type

[PATCH 1/6] drm/amd/display: ident braces in dcn30_acquire_post_bldn_3dlut correctly

2023-02-14 Thread Melissa Wen
Signed-off-by: Melissa Wen 
---
 drivers/gpu/drm/amd/display/dc/dcn30/dcn30_resource.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_resource.c 
b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_resource.c
index feb4bb491525..60bb5634b6e2 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_resource.c
@@ -1477,8 +1477,8 @@ bool dcn30_acquire_post_bldn_3dlut(
state->bits.mpc_rmu2_mux = mpcc_id;
ret = true;
break;
-   }
}
+   }
return ret;
 }
 
-- 
2.39.0



[PATCH 0/6] Trivial code cleanup around color resources

2023-02-14 Thread Melissa Wen
Hi,

Sorry for the noise, but while I've been working on wiring 3D LUT
support to AMD display driver [1] I found some annoying code style
issues in the shared-code part. So I'm just sending what I've been
cleaning to better examine the code.

Most seem trivial, except the last one "remove unused
_calculate_degamma_curve" since this could just be a matter of missing
parts. If so, happy to remove the patch and include a comment describing
the situation (or the potential usage of it).

Thanks,

Melissa

[1] https://lore.kernel.org/dri-devel/20230109143846.1966301-1-m...@igalia.com/

Melissa Wen (6):
  drm/amd/display: ident braces in dcn30_acquire_post_bldn_3dlut
correctly
  drm/amd/display: clean code-style issues in dcn30_set_mpc_shaper_3dlut
  drm/amd/display: camel case cleanup in color_gamma file
  drm/amd/display: unset initial value for tf since it's never used
  drm/amd/display: remove unused func declaration from resource headers
  drm/amd/display: remove unused _calculate_degamma_curve function

 .../drm/amd/display/dc/dcn30/dcn30_hwseq.c|  37 ++---
 .../drm/amd/display/dc/dcn30/dcn30_resource.c |   2 +-
 drivers/gpu/drm/amd/display/dc/inc/resource.h |   4 -
 .../amd/display/modules/color/color_gamma.c   | 140 --
 .../amd/display/modules/color/color_gamma.h   |   3 -
 5 files changed, 48 insertions(+), 138 deletions(-)

-- 
2.39.0



Re: [RFC PATCH v2 00/18] Add DRM CRTC 3D LUT interface

2023-02-13 Thread Melissa Wen
On 02/13, Ville Syrjälä wrote:
> On Mon, Feb 13, 2023 at 11:01:31AM +0200, Pekka Paalanen wrote:
> > On Fri, 10 Feb 2023 14:47:50 -0500
> > Harry Wentland  wrote:
> > 
> > > On 2/10/23 04:28, Pekka Paalanen wrote:
> > > > On Thu, 9 Feb 2023 13:27:02 -0100
> > > > Melissa Wen  wrote:
> > > >   
> > > >> On 01/31, Pekka Paalanen wrote:  
> > > >>> On Mon, 9 Jan 2023 14:38:09 -0100
> > > >>> Melissa Wen  wrote:
> > > >>> 
> > > >>>> On 01/09, Melissa Wen wrote:
> > > >>>>> Hi,
> > > >>>>>
> > > >>>>> After collecting comments in different places, here is a second 
> > > >>>>> version
> > > >>>>> of the work on adding DRM CRTC 3D LUT support to the current DRM 
> > > >>>>> color
> > > >>>>> mgmt interface. In comparison to previous proposals [1][2][3], here 
> > > >>>>> we
> > > >>>>> add 3D LUT before gamma 1D LUT, but also a shaper 1D LUT before 3D 
> > > >>>>> LUT,
> > > >>>>> that means the following DRM CRTC color correction pipeline:
> > > >>>>>
> > > >>>>> Blend -> Degamma 1D LUT -> CTM -> Shaper 1D LUT -> 3D LUT -> Gamma 
> > > >>>>> 1D LUT
> > 
> > ...
> > 
> > > >>> +/*
> > > >>> + * struct drm_mode_lut3d_mode - 3D LUT mode information.
> > > >>> + * @lut_size: number of valid points on every dimension of 3D LUT.
> > > >>> + * @lut_stride: number of points on every dimension of 3D LUT.
> > > >>> + * @bit_depth: number of bits of RGB. If color_mode defines entries 
> > > >>> with higher
> > > >>> + * bit_depth the least significant bits will be 
> > > >>> truncated.
> > > >>> + * @color_format: fourcc values, ex. DRM_FORMAT_XRGB16161616 or 
> > > >>> DRM_FORMAT_XBGR16161616.
> > > >>> + * @flags: flags for hardware-sepcific features
> > > >>> + */
> > > >>> +struct drm_mode_lut3d_mode {
> > > >>> + __u16 lut_size;
> > > >>> + __u16 lut_stride[3];
> > > >>> + __u16 bit_depth;
> > > >>> + __u32 color_format;
> > > >>> + __u32 flags;
> > > >>> +};
> > 
> > ...
> > 
> > > >>> What is "number of bits of RGB"? Input precision? Output precision?
> > > >>> Integer or floating point?
> > > >>
> > > >> It's the bit depth of the 3D LUT values, the same for every channels. 
> > > >> In
> > > >> the AMD case, it's supports 10-bit and 12-bit, for example.  
> > > > 
> > > > Ok. So e.g. r5g6b5 is not a possible 3D LUT element type on any
> > > > hardware ever?
> > > >   
> > > 
> > > I haven't had a chance to go through all patches yet but if this is
> > > modeled after Alex Hung's work this should be covered by color_format.
> > > The idea is that color_format takes a FOURCC value and defines the
> > > format of the entries in the 3DLUT blob.
> > > 
> > > The bit_depth describes the actual bit depth that the HW supports.
> > > E.g., color_format could be DRM_FORMAT_XRGB16161616 but HW might only
> > > support 12-bit precision. In that case the least significant bits get
> > > truncated.
> > > 
> > > One could define the bit_depth per color, but I'm not sure that'll be
> > > necessary.
> > 
> > Exactly. I just have no idea how sure we should be about that.
> > 
> > > > What exactly is the truncation the comment refers to?
> > > > 
> > > > It sounds like if input has higher precision than the LUT elements,
> > > > then "truncation" occurs. I can kind of see that, but I also think it
> > > > is a false characterisation. The LUT input precision affects the
> > > > precision of LUT indexing and the precision of interpolation between
> > > > the LUT elements. I would not expect those two precisions to be
> > > > truncated to the LUT element precision (but they could be truncated to
> > > > something else hardware specific). Instead, I do expect the
> > > > interpolation result to be truncated t

Re: [RFC PATCH v2 00/18] Add DRM CRTC 3D LUT interface

2023-02-13 Thread Melissa Wen
On 02/10, Pekka Paalanen wrote:
> On Thu, 9 Feb 2023 13:27:02 -0100
> Melissa Wen  wrote:
> 
> > On 01/31, Pekka Paalanen wrote:
> > > On Mon, 9 Jan 2023 14:38:09 -0100
> > > Melissa Wen  wrote:
> > >   
> > > > On 01/09, Melissa Wen wrote:  
> > > > > Hi,
> > > > > 
> > > > > After collecting comments in different places, here is a second 
> > > > > version
> > > > > of the work on adding DRM CRTC 3D LUT support to the current DRM color
> > > > > mgmt interface. In comparison to previous proposals [1][2][3], here we
> > > > > add 3D LUT before gamma 1D LUT, but also a shaper 1D LUT before 3D 
> > > > > LUT,
> > > > > that means the following DRM CRTC color correction pipeline:
> > > > > 
> > > > > Blend -> Degamma 1D LUT -> CTM -> Shaper 1D LUT -> 3D LUT -> Gamma 1D 
> > > > > LUT  
> > > 
> > > Hi Melissa,
> > > 
> > > that makes sense to me, for CRTCs. It would be really good to have that
> > > as a diagram in the KMS UAPI documentation.
> > >   
> > 
> > Hi Pekka,
> > 
> > Thanks for your feedbacks and your time reviewing this proposal.
> 
> No problem, and sorry it took so long!
> 
> I'm just finishing the catch-up with everything that happened during
> winter holidays.
> 
> > > If someone wants to add a 3D LUT to KMS planes as well, then I'm not
> > > sure if it should be this order or swapped. I will probably have an
> > > opinion about that once Weston is fully HDR capable and has been tried
> > > in the wild for a while with the HDR color operations fine-tuned based
> > > on community feedback. IOW, not for a long time. The YUV to RGB
> > > conversion factors in there as well.
> > >   
> > I see, this is also the reason I reuse here Alex Hung's proposal for
> > pre-blending API. I'll work on better documentation.
> > 
> > >   
> > > > > 
> > > > > and we also add a DRM CRTC LUT3D_MODE property, based on Alex Hung
> > > > > proposal for pre-blending 3D LUT [4] (Thanks!), instead of just a
> > > > > LUT3D_SIZE, that allows userspace to use different supported settings 
> > > > > of
> > > > > 3D LUT, fitting VA-API and new color API better. In this sense, I
> > > > > adjusted the pre-blending proposal for post-blending usage.
> > > > > 
> > > > > Patches 1-6 targets the addition of shaper LUT and 3D LUT properties 
> > > > > to
> > > > > the current DRM CRTC color mgmt pipeline. Patch 6 can be considered an
> > > > > extra/optional patch to define a default value for LUT3D_MODE, 
> > > > > inspired
> > > > > by what we do for the plane blend mode property (pre-multiplied).
> > > > > 
> > > > > Patches 7-18 targets AMD display code to enable shaper and 3D LUT 
> > > > > usage
> > > > > on DCN 301 (our HW case). Patches 7-9 performs code cleanups on 
> > > > > current
> > > > > AMD DM colors code, patch 10 updates AMD stream in case of user 3D LUT
> > > > > changes, patch 11/12 rework AMD MPC 3D LUT resource handling by 
> > > > > context
> > > > > for DCN 301 (easily extendible to other DCN families). Finally, from
> > > > > 13-18, we wire up SHAPER LUT, LUT3D and LUT3D MODE to AMD display
> > > > > driver, exposing modes supported by HW and programming user shaper and
> > > > > 3D LUT accordingly.
> > > > > 
> > > > > Our target userspace is Gamescope/SteamOS.
> > > > > 
> > > > > Basic IGT tests were based on [5][6] and are available here 
> > > > > (in-progress):
> > > > > https://gitlab.freedesktop.org/mwen/igt-gpu-tools/-/commits/crtc-lut3d-api
> > > > > 
> > > > > [1] 
> > > > > https://lore.kernel.org/all/20201221015730.28333-1-laurent.pinchart+rene...@ideasonboard.com/
> > > > > [2] 
> > > > > https://github.com/vsyrjala/linux/commit/4d28e8ddf2a076f30f9e5bdc17cbb4656fe23e69
> > > > > [3] 
> > > > > https://lore.kernel.org/amd-gfx/20220619223104.667413-1-m...@igalia.com/
> > > > > [4] 
> > > > > https://lore.kernel.org/dri-devel/20221004211451.1475215-1-alex.h...@amd.com/
> > > > > [5] https://patchwork.freedesktop.org/series/90165/
> > 

Re: [RFC PATCH v2 00/18] Add DRM CRTC 3D LUT interface

2023-02-09 Thread Melissa Wen
On 01/31, Pekka Paalanen wrote:
> On Mon, 9 Jan 2023 14:38:09 -0100
> Melissa Wen  wrote:
> 
> > On 01/09, Melissa Wen wrote:
> > > Hi,
> > > 
> > > After collecting comments in different places, here is a second version
> > > of the work on adding DRM CRTC 3D LUT support to the current DRM color
> > > mgmt interface. In comparison to previous proposals [1][2][3], here we
> > > add 3D LUT before gamma 1D LUT, but also a shaper 1D LUT before 3D LUT,
> > > that means the following DRM CRTC color correction pipeline:
> > > 
> > > Blend -> Degamma 1D LUT -> CTM -> Shaper 1D LUT -> 3D LUT -> Gamma 1D LUT
> 
> Hi Melissa,
> 
> that makes sense to me, for CRTCs. It would be really good to have that
> as a diagram in the KMS UAPI documentation.
> 

Hi Pekka,

Thanks for your feedbacks and your time reviewing this proposal.

> If someone wants to add a 3D LUT to KMS planes as well, then I'm not
> sure if it should be this order or swapped. I will probably have an
> opinion about that once Weston is fully HDR capable and has been tried
> in the wild for a while with the HDR color operations fine-tuned based
> on community feedback. IOW, not for a long time. The YUV to RGB
> conversion factors in there as well.
> 
I see, this is also the reason I reuse here Alex Hung's proposal for
pre-blending API. I'll work on better documentation.

> 
> > > 
> > > and we also add a DRM CRTC LUT3D_MODE property, based on Alex Hung
> > > proposal for pre-blending 3D LUT [4] (Thanks!), instead of just a
> > > LUT3D_SIZE, that allows userspace to use different supported settings of
> > > 3D LUT, fitting VA-API and new color API better. In this sense, I
> > > adjusted the pre-blending proposal for post-blending usage.
> > > 
> > > Patches 1-6 targets the addition of shaper LUT and 3D LUT properties to
> > > the current DRM CRTC color mgmt pipeline. Patch 6 can be considered an
> > > extra/optional patch to define a default value for LUT3D_MODE, inspired
> > > by what we do for the plane blend mode property (pre-multiplied).
> > > 
> > > Patches 7-18 targets AMD display code to enable shaper and 3D LUT usage
> > > on DCN 301 (our HW case). Patches 7-9 performs code cleanups on current
> > > AMD DM colors code, patch 10 updates AMD stream in case of user 3D LUT
> > > changes, patch 11/12 rework AMD MPC 3D LUT resource handling by context
> > > for DCN 301 (easily extendible to other DCN families). Finally, from
> > > 13-18, we wire up SHAPER LUT, LUT3D and LUT3D MODE to AMD display
> > > driver, exposing modes supported by HW and programming user shaper and
> > > 3D LUT accordingly.
> > > 
> > > Our target userspace is Gamescope/SteamOS.
> > > 
> > > Basic IGT tests were based on [5][6] and are available here (in-progress):
> > > https://gitlab.freedesktop.org/mwen/igt-gpu-tools/-/commits/crtc-lut3d-api
> > > 
> > > [1] 
> > > https://lore.kernel.org/all/20201221015730.28333-1-laurent.pinchart+rene...@ideasonboard.com/
> > > [2] 
> > > https://github.com/vsyrjala/linux/commit/4d28e8ddf2a076f30f9e5bdc17cbb4656fe23e69
> > > [3] 
> > > https://lore.kernel.org/amd-gfx/20220619223104.667413-1-m...@igalia.com/
> > > [4] 
> > > https://lore.kernel.org/dri-devel/20221004211451.1475215-1-alex.h...@amd.com/
> > > [5] https://patchwork.freedesktop.org/series/90165/
> > > [6] https://patchwork.freedesktop.org/series/109402/
> > > [VA_API] 
> > > http://intel.github.io/libva/structVAProcFilterParameterBuffer3DLUT.html
> > > [KMS_pipe_API] https://gitlab.freedesktop.org/pq/color-and-hdr/-/issues/11
> > > 
> > > Let me know your thoughts.  
> > 
> > +Simon Ser, +Pekka Paalanen who might also be interested in this series.
> 
> Unfortunately I don't have the patch emails to reply to, so here's a
> messy bunch of comments. I'll concentrate on the UAPI design as always.

Sorry, the patchset is here: 
https://lore.kernel.org/dri-devel/20230109143846.1966301-1-m...@igalia.com/
In the next version, I won't forget cc'ing you at first.
> 
> +/*
> + * struct drm_mode_lut3d_mode - 3D LUT mode information.
> + * @lut_size: number of valid points on every dimension of 3D LUT.
> + * @lut_stride: number of points on every dimension of 3D LUT.
> + * @bit_depth: number of bits of RGB. If color_mode defines entries with 
> higher
> + * bit_depth the least significant bits will be truncated.
> + * @color_format: fourcc values, ex. DRM_FORMAT_XRGB16161616 or 
> DRM_FORMAT_XBGR16161616.
&

[PATCH] drm/amd/display: fix glitches on hw rotation without pipe split

2023-02-07 Thread Melissa Wen
Fix glitches when moving cursor close to the edge on a rotated screen
for drivers with one pipe (without pipe split) by halving dst_x_offset.

Reported-by: Xaver Hugl 
Signed-off-by: Melissa Wen 
---

Hi,

I'm not sure if having dst_x_offset (or only for the one pipe case) is
the right solution, but it solves the issue on different devices when
the pipe split policy is AVOID.

Context:

Some artifacts appear on HW rotated screen when moving the cursor close
to the edge, as reported in:
https://gitlab.freedesktop.org/drm/amd/-/issues/2247

This issue was initially reported on DCN 3.0.1 and it's not present in
DCN 2.1 by default, for example. These two drivers follow different
pipe_split_policy, where there is no pipe split on DCN 3.0.1 (AVOID),
but we see pipe splitting on DCN 2.1 (MPC_SPLIT_AVOID_MULT_DISP).

Splitting (or not) the pipe changes the way DC calculates cursor
movements and its position, as we can see in
dcn10_set_cursor_position(). In addition, it's possible to reproduce the
same issue found on DCN 3.0.1 by setting DCN 2.1 to avoid pipe splitting
plus rotating the screen to any angle different from zero. However, from
my experiments, setting DCN 3.0.1 to a different pipe split policy makes
the system unstable and causes GPU reset (even though DYNAMIC seems to
be the default policy for DC).

I see that plugging/unplugging the charger changed the intensity of
these artifacts and also see some temporary changes with different power
performance settings. Keeping that in mind, I verified calculations and
register updates related to cursor movements
(dcn10_set_cursor_position(), hubp2_cursor_set_position()), and we can
see that some clk values participates in the final result of
dst_x_offset. After halving dst_x_offset, the artifacts no longer appear
and it solves the problem when pipe splitting is not allowed.

This change doesn't affect the correct behavior with more than one pipe,
but may affect the optimal setup of bandwidth and clocks. Perhaps, the
current values doesn't deliver the right performance when the pipe is
not split and halving dst_x_offset is exactly the right step for only
one pipe, but not for pipe split. 

Finally, if this is not the right solution, I appreciate any feedback to
address this problem correctly.

Thanks,

Melissa

 drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hubp.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hubp.c 
b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hubp.c
index 4566bc7abf17..1ff85d81237e 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hubp.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hubp.c
@@ -1018,7 +1018,7 @@ void hubp2_cursor_set_position(
src_y_offset = y_pos - (cursor_height - y_hotspot);
}
 
-   dst_x_offset = (src_x_offset >= 0) ? src_x_offset : 0;
+   dst_x_offset = (src_x_offset >= 0) ? src_x_offset / 2 : 0;
dst_x_offset *= param->ref_clk_khz;
dst_x_offset /= param->pixel_clk_khz;
 
-- 
2.39.0



[PATCH] drm/amd/display: fix cursor offset on rotation 180

2023-01-31 Thread Melissa Wen
Cursor gets clipped off in the middle of the screen with hw rotation
180. Fix a miscalculation of cursor offset when it's placed near the
edges in the pipe split case.

Cursor bugs with hw rotation were reported on AMD issue tracker:
https://gitlab.freedesktop.org/drm/amd/-/issues/2247

The issues on rotation 270 was fixed by:
https://lore.kernel.org/amd-gfx/20221118125935.4013669-22-brian.ch...@amd.com/
that partially addressed the rotation 180 too. So, this patch is the
final bits for rotation 180.

Reported-by: Xaver Hugl 
Fixes: 9d84c7ef8a87 ("drm/amd/display: Correct cursor position on horizontal 
mirror")
Signed-off-by: Melissa Wen 
---
 drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c 
b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c
index bb155734ac93..480c0b3b51fc 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c
@@ -3624,7 +3624,7 @@ void dcn10_set_cursor_position(struct pipe_ctx *pipe_ctx)
(int)hubp->curs_attr.width || 
pos_cpy.x
<= (int)hubp->curs_attr.width +

pipe_ctx->plane_state->src_rect.x) {
-   pos_cpy.x = temp_x + 
viewport_width;
+   pos_cpy.x = 2 * viewport_width 
- temp_x;
}
}
} else {
-- 
2.39.0



Re: [PATCH 2/2] drm/amd/display: Remove unused display_content_support

2023-01-19 Thread Melissa Wen
On 01/17, Joshua Ashton wrote:
> This was never filled in and thus never truly used.
> 
> Checking the EDID for content_type support is not required for sending
> the avi infoframe packet.
> 
> Signed-off-by: Joshua Ashton 
> ---
>  drivers/gpu/drm/amd/display/dc/dc_stream.h |  1 -
>  drivers/gpu/drm/amd/display/dc/dc_types.h  | 14 --
>  2 files changed, 15 deletions(-)
> 
> diff --git a/drivers/gpu/drm/amd/display/dc/dc_stream.h 
> b/drivers/gpu/drm/amd/display/dc/dc_stream.h
> index 51dc30706e43..a499c0952ea0 100644
> --- a/drivers/gpu/drm/amd/display/dc/dc_stream.h
> +++ b/drivers/gpu/drm/amd/display/dc/dc_stream.h
> @@ -182,7 +182,6 @@ struct dc_stream_state {
>*/
>   struct link_encoder *link_enc;
>   struct dc_panel_patch sink_patches;
> - union display_content_support content_support;
>   struct dc_crtc_timing timing;
>   struct dc_crtc_timing_adjust adjust;
>   struct dc_info_packet vrr_infopacket;
> diff --git a/drivers/gpu/drm/amd/display/dc/dc_types.h 
> b/drivers/gpu/drm/amd/display/dc/dc_types.h
> index c73a655bd687..862af36027e7 100644
> --- a/drivers/gpu/drm/amd/display/dc/dc_types.h
> +++ b/drivers/gpu/drm/amd/display/dc/dc_types.h
> @@ -175,18 +175,6 @@ struct dc_edid {
>  
>  #define AUDIO_INFO_DISPLAY_NAME_SIZE_IN_CHARS 20
>  
> -union display_content_support {
> - unsigned int raw;
> - struct {
> - unsigned int valid_content_type :1;
> - unsigned int game_content :1;
> - unsigned int cinema_content :1;
> - unsigned int photo_content :1;
> - unsigned int graphics_content :1;
> - unsigned int reserved :27;
> - } bits;
> -};
> -
>  struct dc_panel_patch {
>   unsigned int dppowerup_delay;
>   unsigned int extra_t12_ms;
> @@ -219,8 +207,6 @@ struct dc_edid_caps {
>   uint32_t audio_latency;
>   uint32_t video_latency;
>  
> - union display_content_support content_support;
> -
LGTM.

It depends on the previous patch, but if the first patch are fine, they
are both:

Reviewed-by: Melissa Wen 

CC'ing AMD DC folks again since I don't know if it's in use by other
platforms. But it'd be nice to get rid of this or have a
comment/explanation, if not.

>   uint8_t qs_bit;
>   uint8_t qy_bit;
>  
> -- 
> 2.39.0
> 


signature.asc
Description: PGP signature


Re: [PATCH 1/2] drm/amd/display: Hook up 'content type' property for HDMI

2023-01-19 Thread Melissa Wen
On 01/17, Joshua Ashton wrote:
> Implements the 'content type' property for HDMI connectors.
> Verified by checking the avi infoframe on a connected TV.
> 
> This also simplifies a lot of the code in that area as well, there were
> a lot of temp variables doing very little and unnecessary logic
> that was quite confusing.
> 
> It is not necessary to check for support in the EDID before sending a
> 'content type' value in the avi infoframe also.
> 
> Signed-off-by: Joshua Ashton 
> ---
>  .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 24 +++
>  .../gpu/drm/amd/display/dc/core/dc_resource.c | 69 ++-
>  drivers/gpu/drm/amd/display/dc/dc_stream.h|  1 +
>  3 files changed, 46 insertions(+), 48 deletions(-)
> 
> diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c 
> b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
> index 9547037857b6..65fe3de9 100644
> --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
> +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
> @@ -5216,6 +5216,24 @@ get_output_color_space(const struct dc_crtc_timing 
> *dc_crtc_timing)
>   return color_space;
>  }
>  
> +static enum display_content_type
> +get_output_content_type(const struct drm_connector_state *connector_state)
> +{
> + switch (connector_state->content_type) {
> + default:
> + case DRM_MODE_CONTENT_TYPE_NO_DATA:
> + return DISPLAY_CONTENT_TYPE_NO_DATA;
> + case DRM_MODE_CONTENT_TYPE_GRAPHICS:
> + return DISPLAY_CONTENT_TYPE_GRAPHICS;
> + case DRM_MODE_CONTENT_TYPE_PHOTO:
> + return DISPLAY_CONTENT_TYPE_PHOTO;
> + case DRM_MODE_CONTENT_TYPE_CINEMA:
> + return DISPLAY_CONTENT_TYPE_CINEMA;
> + case DRM_MODE_CONTENT_TYPE_GAME:
> + return DISPLAY_CONTENT_TYPE_GAME;
> + }
> +}
> +
>  static bool adjust_colour_depth_from_display_info(
>   struct dc_crtc_timing *timing_out,
>   const struct drm_display_info *info)
> @@ -5349,6 +5367,7 @@ static void 
> fill_stream_properties_from_drm_display_mode(
>   }
>  
>   stream->output_color_space = get_output_color_space(timing_out);
> + stream->content_type = get_output_content_type(connector_state);
>  }
>  
>  static void fill_audio_info(struct audio_info *audio_info,
> @@ -7123,6 +7142,11 @@ void amdgpu_dm_connector_init_helper(struct 
> amdgpu_display_manager *dm,
>   adev->mode_info.abm_level_property, 0);
>   }
>  
> + if (connector_type == DRM_MODE_CONNECTOR_HDMIA) {
> + /* Content Type is currently only implemented for HDMI. */
> + drm_connector_attach_content_type_property(>base);
> + }
> +
>   if (connector_type == DRM_MODE_CONNECTOR_HDMIA ||
>   connector_type == DRM_MODE_CONNECTOR_DisplayPort ||
>   connector_type == DRM_MODE_CONNECTOR_eDP) {
> diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_resource.c 
> b/drivers/gpu/drm/amd/display/dc/core/dc_resource.c
> index a5b5f8592c1b..39ceccdb6586 100644
> --- a/drivers/gpu/drm/amd/display/dc/core/dc_resource.c
> +++ b/drivers/gpu/drm/amd/display/dc/core/dc_resource.c
> @@ -2944,14 +2944,9 @@ static void set_avi_info_frame(
>   uint32_t pixel_encoding = 0;
>   enum scanning_type scan_type = SCANNING_TYPE_NODATA;
>   enum dc_aspect_ratio aspect = ASPECT_RATIO_NO_DATA;
> - bool itc = false;
> - uint8_t itc_value = 0;
> - uint8_t cn0_cn1 = 0;
> - unsigned int cn0_cn1_value = 0;
>   uint8_t *check_sum = NULL;
>   uint8_t byte_index = 0;
>   union hdmi_info_packet hdmi_info;
> - union display_content_support support = {0};
>   unsigned int vic = pipe_ctx->stream->timing.vic;
>   unsigned int rid = pipe_ctx->stream->timing.rid;
>   unsigned int fr_ind = pipe_ctx->stream->timing.fr_index;
> @@ -3055,49 +3050,27 @@ static void set_avi_info_frame(
>   /* Active Format Aspect ratio - same as Picture Aspect Ratio. */
>   hdmi_info.bits.R0_R3 = ACTIVE_FORMAT_ASPECT_RATIO_SAME_AS_PICTURE;
>  
> - /* TODO: un-hardcode cn0_cn1 and itc */
> -
> - cn0_cn1 = 0;
> - cn0_cn1_value = 0;
> -
> - itc = true;
> - itc_value = 1;
> -
> - support = stream->content_support;
> -
> - if (itc) {
> - if (!support.bits.valid_content_type) {
> - cn0_cn1_value = 0;
> - } else {
> - if (cn0_cn1 == DISPLAY_CONTENT_TYPE_GRAPHICS) {
> - if (support.bits.graphics_content == 1) {
> - cn0_cn1_value = 0;
> - }
> - } else if (cn0_cn1 == DISPLAY_CONTENT_TYPE_PHOTO) {
> - if (support.bits.photo_content == 1) {
> - cn0_cn1_value = 1;
> - } else {
> - cn0_cn1_value = 0;
> - itc_value = 0;
> -

Re: [PATCH] drm/amd/display: Fix COLOR_SPACE_YCBCR2020_TYPE matrix

2023-01-16 Thread Melissa Wen

On 01/10, Joshua Ashton wrote:

The YCC conversion matrix for RGB -> COLOR_SPACE_YCBCR2020_TYPE is
missing the values for the fourth column of the matrix.

The fourth column of the matrix is essentially just a value that is
added given that the color is 3 components in size.
These values are needed to bias the chroma from the [-1, 1] -> [0, 1]
range.

This fixes color being very green when using Gamescope HDR on HDMI
output which prefers YCC 4:4:4.

Signed-off-by: Joshua Ashton 
---
 drivers/gpu/drm/amd/display/dc/core/dc_hw_sequencer.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_hw_sequencer.c 
b/drivers/gpu/drm/amd/display/dc/core/dc_hw_sequencer.c
index 471078fc3900..652270a0b498 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_hw_sequencer.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_hw_sequencer.c
@@ -90,8 +90,8 @@ static const struct out_csc_color_matrix_type 
output_csc_matrix[] = {
{ 0xE00, 0xF349, 0xFEB7, 0x1000, 0x6CE, 0x16E3,
0x24F, 0x200, 0xFCCB, 0xF535, 0xE00, 0x1000} },
{ COLOR_SPACE_YCBCR2020_TYPE,
-   { 0x1000, 0xF149, 0xFEB7, 0x, 0x0868, 0x15B2,
-   0x01E6, 0x, 0xFB88, 0xF478, 0x1000, 0x} 
},
+   { 0x1000, 0xF149, 0xFEB7, 0x1004, 0x0868, 0x15B2,
+   0x01E6, 0x201, 0xFB88, 0xF478, 0x1000, 0x1004} 
},


LGTM.

I'd also add a fixes tag here to:

Fixes: 40df2f809e8f ("drm/amd/display: color space ycbcr709 support")

Thanks,

Reviewed-by: Melissa Wen 


{ COLOR_SPACE_YCBCR709_BLACK_TYPE,
{ 0x, 0x, 0x, 0x1000, 0x, 0x,
0x, 0x0200, 0x, 0x, 0x, 0x1000} 
},
--
2.39.0





Re: [PATCH v2] drm/amd/display: Calculate output_color_space after pixel encoding adjustment

2023-01-16 Thread Melissa Wen
On 01/16, Melissa Wen wrote:
> On 01/10, Joshua Ashton wrote:
> > Code in get_output_color_space depends on knowing the pixel encoding to
> > determine whether to pick between eg. COLOR_SPACE_SRGB or
> > COLOR_SPACE_YCBCR709 for transparent RGB -> YCbCr 4:4:4 in the driver.
> > 
> > v2: Fixed patch being accidentally based on a personal feature branch, oops!
> > 
> > Signed-off-by: Joshua Ashton 
> > ---
> >  drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 4 ++--
> >  1 file changed, 2 insertions(+), 2 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c 
> > b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
> > index b4d60eedbcbf..9da71ee8fcc4 100644
> > --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
> > +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
> > @@ -5341,8 +5341,6 @@ static void 
> > fill_stream_properties_from_drm_display_mode(
> >  
> > timing_out->aspect_ratio = get_aspect_ratio(mode_in);
> >  
> > -   stream->output_color_space = get_output_color_space(timing_out);
> > -
> > stream->out_transfer_func->type = TF_TYPE_PREDEFINED;
> > stream->out_transfer_func->tf = TRANSFER_FUNCTION_SRGB;
> > if (stream->signal == SIGNAL_TYPE_HDMI_TYPE_A) {
> > @@ -5353,6 +5351,8 @@ static void 
> > fill_stream_properties_from_drm_display_mode(
> > adjust_colour_depth_from_display_info(timing_out, info);
> > }
> > }
> > +
> > +   stream->output_color_space = get_output_color_space(timing_out);
> 
> LGTM.
> 
> I see that we were ignoring the updated value of pixel_encoding in the
> previous point. Nice catch!
> 
> Reviewed-by: Melissa Wen 

BTW, I think it deserves a fixes tag to:

Fixes: ea117312ea9f ("drm/amd/display: Reduce HDMI pixel encoding if max clock 
is exceeded")

> 
> >  }
> >  
> >  static void fill_audio_info(struct audio_info *audio_info,
> > -- 
> > 2.39.0
> > 




signature.asc
Description: PGP signature


Re: [PATCH v2] drm/amd/display: Calculate output_color_space after pixel encoding adjustment

2023-01-16 Thread Melissa Wen
On 01/10, Joshua Ashton wrote:
> Code in get_output_color_space depends on knowing the pixel encoding to
> determine whether to pick between eg. COLOR_SPACE_SRGB or
> COLOR_SPACE_YCBCR709 for transparent RGB -> YCbCr 4:4:4 in the driver.
> 
> v2: Fixed patch being accidentally based on a personal feature branch, oops!
> 
> Signed-off-by: Joshua Ashton 
> ---
>  drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c 
> b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
> index b4d60eedbcbf..9da71ee8fcc4 100644
> --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
> +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
> @@ -5341,8 +5341,6 @@ static void 
> fill_stream_properties_from_drm_display_mode(
>  
>   timing_out->aspect_ratio = get_aspect_ratio(mode_in);
>  
> - stream->output_color_space = get_output_color_space(timing_out);
> -
>   stream->out_transfer_func->type = TF_TYPE_PREDEFINED;
>   stream->out_transfer_func->tf = TRANSFER_FUNCTION_SRGB;
>   if (stream->signal == SIGNAL_TYPE_HDMI_TYPE_A) {
> @@ -5353,6 +5351,8 @@ static void 
> fill_stream_properties_from_drm_display_mode(
>   adjust_colour_depth_from_display_info(timing_out, info);
>   }
>   }
> +
> + stream->output_color_space = get_output_color_space(timing_out);

LGTM.

I see that we were ignoring the updated value of pixel_encoding in the
previous point. Nice catch!

Reviewed-by: Melissa Wen 

>  }
>  
>  static void fill_audio_info(struct audio_info *audio_info,
> -- 
> 2.39.0
> 


signature.asc
Description: PGP signature


Re: [RFC PATCH v2 00/18] Add DRM CRTC 3D LUT interface

2023-01-09 Thread Melissa Wen
On 01/09, Melissa Wen wrote:
> Hi,
> 
> After collecting comments in different places, here is a second version
> of the work on adding DRM CRTC 3D LUT support to the current DRM color
> mgmt interface. In comparison to previous proposals [1][2][3], here we
> add 3D LUT before gamma 1D LUT, but also a shaper 1D LUT before 3D LUT,
> that means the following DRM CRTC color correction pipeline:
> 
> Blend -> Degamma 1D LUT -> CTM -> Shaper 1D LUT -> 3D LUT -> Gamma 1D LUT
> 
> and we also add a DRM CRTC LUT3D_MODE property, based on Alex Hung
> proposal for pre-blending 3D LUT [4] (Thanks!), instead of just a
> LUT3D_SIZE, that allows userspace to use different supported settings of
> 3D LUT, fitting VA-API and new color API better. In this sense, I
> adjusted the pre-blending proposal for post-blending usage.
> 
> Patches 1-6 targets the addition of shaper LUT and 3D LUT properties to
> the current DRM CRTC color mgmt pipeline. Patch 6 can be considered an
> extra/optional patch to define a default value for LUT3D_MODE, inspired
> by what we do for the plane blend mode property (pre-multiplied).
> 
> Patches 7-18 targets AMD display code to enable shaper and 3D LUT usage
> on DCN 301 (our HW case). Patches 7-9 performs code cleanups on current
> AMD DM colors code, patch 10 updates AMD stream in case of user 3D LUT
> changes, patch 11/12 rework AMD MPC 3D LUT resource handling by context
> for DCN 301 (easily extendible to other DCN families). Finally, from
> 13-18, we wire up SHAPER LUT, LUT3D and LUT3D MODE to AMD display
> driver, exposing modes supported by HW and programming user shaper and
> 3D LUT accordingly.
> 
> Our target userspace is Gamescope/SteamOS.
> 
> Basic IGT tests were based on [5][6] and are available here (in-progress):
> https://gitlab.freedesktop.org/mwen/igt-gpu-tools/-/commits/crtc-lut3d-api
> 
> [1] 
> https://lore.kernel.org/all/20201221015730.28333-1-laurent.pinchart+rene...@ideasonboard.com/
> [2] 
> https://github.com/vsyrjala/linux/commit/4d28e8ddf2a076f30f9e5bdc17cbb4656fe23e69
> [3] https://lore.kernel.org/amd-gfx/20220619223104.667413-1-m...@igalia.com/
> [4] 
> https://lore.kernel.org/dri-devel/20221004211451.1475215-1-alex.h...@amd.com/
> [5] https://patchwork.freedesktop.org/series/90165/
> [6] https://patchwork.freedesktop.org/series/109402/
> [VA_API] 
> http://intel.github.io/libva/structVAProcFilterParameterBuffer3DLUT.html
> [KMS_pipe_API] https://gitlab.freedesktop.org/pq/color-and-hdr/-/issues/11
> 
> Let me know your thoughts.

+Simon Ser, +Pekka Paalanen who might also be interested in this series.

Also please let me know if I forgot to address any comments.

Melissa

> 
> Thanks,
> 
> Melissa
> 
> Alex Hung (2):
>   drm: Add 3D LUT mode and its attributes
>   drm/amd/display: Define 3D LUT struct for HDR planes
> 
> Melissa Wen (16):
>   drm/drm_color_mgmt: add shaper LUT to color mgmt properties
>   drm/drm_color_mgmt: add 3D LUT props to DRM color mgmt
>   drm/drm_color_mgmt: add function to create 3D LUT modes supported
>   drm/drm_color_mgmt: add function to attach 3D LUT props
>   drm/drm_color_mgmt: set first lut3d mode as default
>   drm/amd/display: remove unused regamma condition
>   drm/amd/display: add comments to describe DM crtc color mgmt behavior
>   drm/amd/display: encapsulate atomic regamma operation
>   drm/amd/display: update lut3d and shaper lut to stream
>   drm/amd/display: handle MPC 3D LUT resources for a given context
>   drm/amd/display: acquire/release 3D LUT resources for ctx on DCN301
>   drm/amd/display: expand array of supported 3D LUT modes
>   drm/amd/display: enable 3D-LUT DRM properties if supported
>   drm/amd/display: add user 3D LUT support to the amdgpu_dm color
> pipeline
>   drm/amd/display: decouple steps to reuse in shaper LUT support
>   drm/amd/display: add user shaper LUT support to amdgpu_dm color
> pipeline
> 
>  .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c |   6 +
>  .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h |   3 +
>  .../amd/display/amdgpu_dm/amdgpu_dm_color.c   | 370 --
>  .../amd/display/amdgpu_dm/amdgpu_dm_crtc.c|   2 +
>  drivers/gpu/drm/amd/display/dc/core/dc.c  |  49 ++-
>  drivers/gpu/drm/amd/display/dc/dc.h   |   8 +
>  .../amd/display/dc/dcn301/dcn301_resource.c   |  47 ++-
>  .../amd/display/modules/color/color_gamma.h   |  43 ++
>  drivers/gpu/drm/drm_atomic_state_helper.c |   7 +
>  drivers/gpu/drm/drm_atomic_uapi.c |  24 ++
>  drivers/gpu/drm/drm_color_mgmt.c  | 127 ++
>  drivers/gpu/drm/drm_fb_helper.c   |   5 +
>  drivers/gpu/drm/drm_mode_config.c |  21 +
>  include/drm/drm_color_mgmt.h  

[RFC PATCH v2 16/18] drm/amd/display: add user 3D LUT support to the amdgpu_dm color pipeline

2023-01-09 Thread Melissa Wen
Map DRM 3D LUT in the atomic color mgmt pipeline to DC. 3D LUT works
better in a non-linear color space, therefore using a degamma to
linearize the input space may produce unexpected results. The next patch
introduces shaper LUT support that can be used to delinearize the color
space before applying 3D LUT conversion.

Note that there is no implicit sRGB degamma/regamma in the current
implementation for DRM atomic color mgmt. Atomic degamma/regamma 1D LUT
is applied considering a linear base.

For reference, see IGT test amdgpu/amd_color and commit
cf020d49b3c4 ("drm/amd/display: Rework CRTC color management")

dc_acquire_release_mpc_3dlut initializes the bits required to program
3DLUT in DC MPC hw block, that is applied by set_output_transfer_func().
I still need to double check the timing to acquire and release shaper
and 3D LUTs from the resource pool.

Signed-off-by: Melissa Wen 
---
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c |   6 +
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h |   2 +
 .../amd/display/amdgpu_dm/amdgpu_dm_color.c   | 189 ++
 3 files changed, 197 insertions(+)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
index b8638f0508b0..7aa41dd2143b 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -9704,6 +9704,12 @@ static int amdgpu_dm_atomic_check(struct drm_device *dev,
goto fail;
}
 
+   ret = amdgpu_dm_verify_lut3d_size(adev, new_crtc_state);
+   if (ret) {
+   DRM_DEBUG_DRIVER("amdgpu_dm_verify_lut_sizes() 
failed\n");
+   goto fail;
+   }
+
if (!new_crtc_state->enable)
continue;
 
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
index 6f04719d0c1f..59ab1b8f7b05 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
@@ -786,6 +786,8 @@ void amdgpu_dm_trigger_timing_sync(struct drm_device *dev);
 
 void amdgpu_dm_init_color_mod(void);
 int amdgpu_dm_verify_lut_sizes(const struct drm_crtc_state *crtc_state);
+int amdgpu_dm_verify_lut3d_size(struct amdgpu_device *adev,
+   const struct drm_crtc_state *crtc_state);
 void amdgpu_dm_enable_lut3d_prop(struct amdgpu_display_manager *dm, struct 
drm_crtc *crtc);
 int amdgpu_dm_update_crtc_color_mgmt(struct dm_crtc_state *crtc);
 int amdgpu_dm_update_plane_color_mgmt(struct dm_crtc_state *crtc,
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
index c547957acd73..0fb1244c8aef 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
@@ -413,6 +413,175 @@ void amdgpu_dm_enable_lut3d_prop(struct 
amdgpu_display_manager *dm, struct drm_c
drm_crtc_enable_lut3d(crtc, MAX_COLOR_LUT_ENTRIES, true);
 }
 
+static void __to_dc_lut3d_color(struct dc_rgb *rgb,
+   const struct drm_color_lut lut,
+   int bit_precision)
+{
+   rgb->red = drm_color_lut_extract(lut.red, bit_precision);
+   rgb->green = drm_color_lut_extract(lut.green, bit_precision);
+   rgb->blue  = drm_color_lut_extract(lut.blue, bit_precision);
+}
+
+static void __drm_3dlut_to_dc_3dlut(const struct drm_color_lut *lut,
+   uint32_t lut3d_size,
+   struct tetrahedral_params *params,
+   bool use_tetrahedral_9,
+   int bit_depth)
+{
+   struct dc_rgb *lut0;
+   struct dc_rgb *lut1;
+   struct dc_rgb *lut2;
+   struct dc_rgb *lut3;
+   int lut_i, i;
+
+
+   if (use_tetrahedral_9) {
+   lut0 = params->tetrahedral_9.lut0;
+   lut1 = params->tetrahedral_9.lut1;
+   lut2 = params->tetrahedral_9.lut2;
+   lut3 = params->tetrahedral_9.lut3;
+   } else {
+   lut0 = params->tetrahedral_17.lut0;
+   lut1 = params->tetrahedral_17.lut1;
+   lut2 = params->tetrahedral_17.lut2;
+   lut3 = params->tetrahedral_17.lut3;
+   }
+
+   for (lut_i = 0, i = 0; i < lut3d_size - 4; lut_i++, i += 4) {
+   /* We should consider the 3dlut RGB values are distributed
+* along four arrays lut0-3 where the first sizes 1229 and the
+* other 1228. The bit depth supported for 3dlut channel is
+* 12-bit, but DC also supports 10-bit.
+*
+* TODO: improve color pipeline API to enable the userspace set
+   

[RFC PATCH v2 18/18] drm/amd/display: add user shaper LUT support to amdgpu_dm color pipeline

2023-01-09 Thread Melissa Wen
Now, we can use shaper LUT to delinearize and/or normalize the color
space for a more efficient 3D LUT support (so far, only for DRM atomic
color mgmt). If a degamma 1D LUT is passed to linearize the color space,
a custom shaper 1D LUT can be used before applying 3D LUT.

Signed-off-by: Melissa Wen 
---
 .../amd/display/amdgpu_dm/amdgpu_dm_color.c   | 95 ---
 1 file changed, 83 insertions(+), 12 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
index 8a930f9bce60..81b20ac9ff19 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
@@ -497,14 +497,62 @@ static void amdgpu_dm_atomic_lut3d(struct dc_stream_state 
*stream,
stream->lut3d_func = lut;
 }
 
+static int __set_func_shaper(struct dc_transfer_func *shaper_func,
+const struct drm_color_lut *lut, uint32_t lut_size)
+{
+   struct dc_gamma *gamma = NULL;
+   struct calculate_buffer cal_buffer = {0};
+   bool res;
+
+   ASSERT(lut && lut_size == MAX_COLOR_LUT_ENTRIES);
+
+   cal_buffer.buffer_index = -1;
+
+   gamma = dc_create_gamma();
+   if (!gamma)
+   return -ENOMEM;
+
+   gamma->num_entries = lut_size;
+   __drm_lut_to_dc_gamma(lut, gamma, false);
+
+   /*
+* Color module doesn't like calculating gamma params
+* on top of a linear input. But degamma params can be used
+* instead to simulate this.
+*/
+   gamma->type = GAMMA_CUSTOM;
+   res = mod_color_calculate_degamma_params(NULL, shaper_func, gamma, 
true);
+
+   dc_gamma_release();
+
+   return res ? 0 : -ENOMEM;
+}
+
 static int amdgpu_dm_atomic_shaper_lut(struct dc_stream_state *stream,
+  const struct drm_color_lut *shaper_lut,
+  uint32_t shaper_size,
   struct dc_transfer_func *func_shaper_new)
 {
-   /* We don't get DRM shaper LUT yet. We assume the input color space is 
already
+   /* If no DRM shaper LUT, we assume the input color space is already
 * delinearized, so we don't need a shaper LUT and we can just BYPASS
 */
-   func_shaper_new->type = TF_TYPE_BYPASS;
-   func_shaper_new->tf = TRANSFER_FUNCTION_LINEAR;
+   if (!shaper_size) {
+   func_shaper_new->type = TF_TYPE_BYPASS;
+   func_shaper_new->tf = TRANSFER_FUNCTION_LINEAR;
+   } else {
+   int r;
+
+   /* If DRM shaper LUT is set, we assume a linear color space
+* (linearized by DRM degamma 1D LUT or not)
+*/
+   func_shaper_new->type = TF_TYPE_DISTRIBUTED_POINTS;
+   func_shaper_new->tf = TRANSFER_FUNCTION_LINEAR;
+
+   r = __set_func_shaper(func_shaper_new, shaper_lut, shaper_size);
+   if (r)
+   return r;
+   }
+
stream->func_shaper = func_shaper_new;
 
return 0;
@@ -514,6 +562,8 @@ static int amdgpu_dm_atomic_shaper_lut(struct 
dc_stream_state *stream,
  * interface
  * @dc: Display Core control structure
  * @stream: DC stream state to set shaper LUT and 3D LUT
+ * @drm_shaper_lut: DRM CRTC (user) shaper LUT
+ * @drm_shaper_size: size of shaper LUT
  * @drm_lut3d: DRM CRTC (user) 3D LUT
  * @drm_lut3d_size: size of 3D LUT
  *
@@ -522,6 +572,8 @@ static int amdgpu_dm_atomic_shaper_lut(struct 
dc_stream_state *stream,
  */
 static int amdgpu_dm_atomic_shaper_lut3d(struct dc *dc,
 struct dc_stream_state *stream,
+const struct drm_color_lut 
*drm_shaper_lut,
+uint32_t drm_shaper_size,
 const struct drm_color_lut *drm_lut3d,
 uint32_t drm_lut3d_size,
 const struct drm_mode_lut3d_mode *mode)
@@ -532,11 +584,11 @@ static int amdgpu_dm_atomic_shaper_lut3d(struct dc *dc,
lut3d_func_new = (struct dc_3dlut *) stream->lut3d_func;
func_shaper_new = (struct dc_transfer_func *) stream->func_shaper;
 
-
amdgpu_dm_atomic_lut3d(stream, drm_lut3d, drm_lut3d_size,
   mode, lut3d_func_new);
 
-   return amdgpu_dm_atomic_shaper_lut(stream, func_shaper_new);
+   return amdgpu_dm_atomic_shaper_lut(stream, drm_shaper_lut,
+  drm_shaper_size, func_shaper_new);
 }
 
 static const struct drm_mode_lut3d_mode *
@@ -569,13 +621,23 @@ get_lut3d_mode(struct amdgpu_device *adev,
 int amdgpu_dm_verify_lut3d_size(struct amdgpu_device *adev,
const struct drm_crtc_state *crtc_state)
 {
-   const struct drm_color_lut *lut3

[RFC PATCH v2 17/18] drm/amd/display: decouple steps to reuse in shaper LUT support

2023-01-09 Thread Melissa Wen
Decouple steps of shaper LUT setup and LUT size validation according to
HW caps as a preparation for shaper LUT support.

Signed-off-by: Melissa Wen 
---
 .../amd/display/amdgpu_dm/amdgpu_dm_color.c   | 22 ---
 1 file changed, 14 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
index 0fb1244c8aef..8a930f9bce60 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
@@ -497,6 +497,19 @@ static void amdgpu_dm_atomic_lut3d(struct dc_stream_state 
*stream,
stream->lut3d_func = lut;
 }
 
+static int amdgpu_dm_atomic_shaper_lut(struct dc_stream_state *stream,
+  struct dc_transfer_func *func_shaper_new)
+{
+   /* We don't get DRM shaper LUT yet. We assume the input color space is 
already
+* delinearized, so we don't need a shaper LUT and we can just BYPASS
+*/
+   func_shaper_new->type = TF_TYPE_BYPASS;
+   func_shaper_new->tf = TRANSFER_FUNCTION_LINEAR;
+   stream->func_shaper = func_shaper_new;
+
+   return 0;
+}
+
 /* amdgpu_dm_atomic_shaper_lut3d - set DRM CRTC shaper LUT and 3D LUT to DC
  * interface
  * @dc: Display Core control structure
@@ -519,18 +532,11 @@ static int amdgpu_dm_atomic_shaper_lut3d(struct dc *dc,
lut3d_func_new = (struct dc_3dlut *) stream->lut3d_func;
func_shaper_new = (struct dc_transfer_func *) stream->func_shaper;
 
-   /* We don't get DRM shaper LUT yet. We assume the input color space is
-* already delinearized, so we don't need a shaper LUT and we can just
-* BYPASS.
-*/
-   func_shaper_new->type = TF_TYPE_BYPASS;
-   func_shaper_new->tf = TRANSFER_FUNCTION_LINEAR;
-   stream->func_shaper = func_shaper_new;
 
amdgpu_dm_atomic_lut3d(stream, drm_lut3d, drm_lut3d_size,
   mode, lut3d_func_new);
 
-   return 0;
+   return amdgpu_dm_atomic_shaper_lut(stream, func_shaper_new);
 }
 
 static const struct drm_mode_lut3d_mode *
-- 
2.35.1



[RFC PATCH v2 14/18] drm/amd/display: expand array of supported 3D LUT modes

2023-01-09 Thread Melissa Wen
AMD MPC block support 3D LUTs of dimensions 17 and 9, and also bit
depth 12 and 10, therefore, advertise them to the userspace.

Signed-off-by: Melissa Wen 
---
 .../amd/display/modules/color/color_gamma.h   | 31 +++
 1 file changed, 31 insertions(+)

diff --git a/drivers/gpu/drm/amd/display/modules/color/color_gamma.h 
b/drivers/gpu/drm/amd/display/modules/color/color_gamma.h
index 8e159b1eb9c6..69b9a1aa6dd4 100644
--- a/drivers/gpu/drm/amd/display/modules/color/color_gamma.h
+++ b/drivers/gpu/drm/amd/display/modules/color/color_gamma.h
@@ -47,6 +47,37 @@ static const struct drm_mode_lut3d_mode lut3d_mode_17_12bit 
= {
.flags = 0,
 };
 
+static const struct drm_mode_lut3d_mode amdgpu_lut3d_modes[] = {
+   {
+   .lut_size = 17,
+   .lut_stride = {17, 17, 18},
+   .bit_depth = 12,
+   .color_format = DRM_FORMAT_XRGB16161616,
+   .flags = 0,
+   },
+   {
+   .lut_size = 17,
+   .lut_stride = {17, 17, 18},
+   .bit_depth = 10,
+   .color_format = DRM_FORMAT_XRGB16161616,
+   .flags = 0,
+   },
+   {
+   .lut_size = 9,
+   .lut_stride = {9, 9, 10},
+   .bit_depth = 12,
+   .color_format = DRM_FORMAT_XRGB16161616,
+   .flags = 0,
+   },
+   {
+   .lut_size = 9,
+   .lut_stride = {9, 9, 10},
+   .bit_depth = 10,
+   .color_format = DRM_FORMAT_XRGB16161616,
+   .flags = 0,
+   },
+};
+
 /* For SetRegamma ADL interface support
  * Must match escape type
  */
-- 
2.35.1



[RFC PATCH v2 10/18] drm/amd/display: update lut3d and shaper lut to stream

2023-01-09 Thread Melissa Wen
It follows the same path of out_transfer_func for stream updates, since
shaper LUT and 3D LUT is programmed in funcs.set_output_transfer_func()
and this function is called in the atomic commit_tail when
update_flags.bits.out_tf is set.

Signed-off-by: Melissa Wen 
---
 drivers/gpu/drm/amd/display/dc/core/dc.c | 10 +-
 1 file changed, 9 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c 
b/drivers/gpu/drm/amd/display/dc/core/dc.c
index 2c18c8527079..88f1130c3b83 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc.c
@@ -2562,7 +2562,7 @@ static enum surface_update_type 
check_update_surfaces_for_stream(
stream_update->integer_scaling_update)
su_flags->bits.scaling = 1;
 
-   if (stream_update->out_transfer_func)
+   if (stream_update->out_transfer_func || 
stream_update->lut3d_func)
su_flags->bits.out_tf = 1;
 
if (stream_update->abm_level)
@@ -2911,6 +2911,14 @@ static void copy_stream_update_to_stream(struct dc *dc,
   sizeof(struct dc_transfer_func_distributed_points));
}
 
+   if (update->func_shaper &&
+   stream->func_shaper != update->func_shaper)
+   stream->func_shaper = update->func_shaper;
+
+   if (update->lut3d_func &&
+   stream->lut3d_func != update->lut3d_func)
+   stream->lut3d_func = update->lut3d_func;
+
if (update->hdr_static_metadata)
stream->hdr_static_metadata = *update->hdr_static_metadata;
 
-- 
2.35.1



[RFC PATCH v2 15/18] drm/amd/display: enable 3D-LUT DRM properties if supported

2023-01-09 Thread Melissa Wen
Enable DRM crtc properties related to 3D LUT resources (shaper LUT, 3D
LUT and 3D LUT modes) if it's supported by DCN HW, that means DCN
families 3.0+

Signed-off-by: Melissa Wen 
---
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h |  1 +
 .../amd/display/amdgpu_dm/amdgpu_dm_color.c   | 25 +++
 .../amd/display/amdgpu_dm/amdgpu_dm_crtc.c|  2 ++
 3 files changed, 28 insertions(+)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
index a3813c1e..6f04719d0c1f 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
@@ -786,6 +786,7 @@ void amdgpu_dm_trigger_timing_sync(struct drm_device *dev);
 
 void amdgpu_dm_init_color_mod(void);
 int amdgpu_dm_verify_lut_sizes(const struct drm_crtc_state *crtc_state);
+void amdgpu_dm_enable_lut3d_prop(struct amdgpu_display_manager *dm, struct 
drm_crtc *crtc);
 int amdgpu_dm_update_crtc_color_mgmt(struct dm_crtc_state *crtc);
 int amdgpu_dm_update_plane_color_mgmt(struct dm_crtc_state *crtc,
  struct dc_plane_state *dc_plane_state);
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
index 54d95745f0f0..c547957acd73 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
@@ -388,6 +388,31 @@ int amdgpu_dm_verify_lut_sizes(const struct drm_crtc_state 
*crtc_state)
return 0;
 }
 
+static bool has_mpc_lut3d_caps(struct amdgpu_display_manager *dm)
+{
+   return dm->dc->caps.color.mpc.num_3dluts ? true : false;
+}
+
+/**
+ * amdgpu_dm_enable_lut3d_prop - enable 3D LUT DRM props if HW supports
+ * @crtc: DRM crtc
+ * @dm: amdgpu display manager
+ */
+void amdgpu_dm_enable_lut3d_prop(struct amdgpu_display_manager *dm, struct 
drm_crtc *crtc)
+{
+   int res;
+
+   if (!has_mpc_lut3d_caps(dm))
+   return;
+
+   res = drm_crtc_create_lut3d_mode_property(crtc, amdgpu_lut3d_modes,
+ 
ARRAY_SIZE(amdgpu_lut3d_modes));
+   if (res)
+   drm_dbg(crtc->dev, "CRTC init: Failed to create LUT 3D mode 
properties\n");
+
+   drm_crtc_enable_lut3d(crtc, MAX_COLOR_LUT_ENTRIES, true);
+}
+
 /**
  * amdgpu_dm_update_crtc_color_mgmt: Maps DRM color management to DC stream.
  * @crtc: amdgpu_dm crtc state
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c
index 22125daf9dcf..96494f72a6f4 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c
@@ -461,6 +461,8 @@ int amdgpu_dm_crtc_init(struct amdgpu_display_manager *dm,
drm_crtc_enable_color_mgmt(>base, is_dcn ? MAX_COLOR_LUT_ENTRIES 
: 0,
   true, MAX_COLOR_LUT_ENTRIES);
 
+   amdgpu_dm_enable_lut3d_prop(dm, >base);
+
drm_mode_crtc_set_gamma_size(>base, 
MAX_COLOR_LEGACY_LUT_ENTRIES);
 
return 0;
-- 
2.35.1



[RFC PATCH v2 13/18] drm/amd/display: Define 3D LUT struct for HDR planes

2023-01-09 Thread Melissa Wen
From: Alex Hung 

Add a 3D LUT mode supported by amdgpu driver.

Note: A patchset "IGT tests for pre-blending 3D LUT interfaces" for this
proposal is sent to IGT mailing list.

Signed-off-by: Alex Hung 
---
 .../gpu/drm/amd/display/modules/color/color_gamma.h  | 12 
 1 file changed, 12 insertions(+)

diff --git a/drivers/gpu/drm/amd/display/modules/color/color_gamma.h 
b/drivers/gpu/drm/amd/display/modules/color/color_gamma.h
index 2893abf48208..8e159b1eb9c6 100644
--- a/drivers/gpu/drm/amd/display/modules/color/color_gamma.h
+++ b/drivers/gpu/drm/amd/display/modules/color/color_gamma.h
@@ -27,6 +27,7 @@
 #define COLOR_MOD_COLOR_GAMMA_H_
 
 #include "color_table.h"
+#include 
 
 struct dc_transfer_func;
 struct dc_gamma;
@@ -35,6 +36,17 @@ struct dc_rgb_fixed;
 struct dc_color_caps;
 enum dc_transfer_func_predefined;
 
+/*
+ * 3D LUT mode for 17x17x17 LUT and 12 bits of color depth
+ */
+static const struct drm_mode_lut3d_mode lut3d_mode_17_12bit = {
+   .lut_size = 17,
+   .lut_stride = {17, 17, 18},
+   .bit_depth = 12,
+   .color_format = DRM_FORMAT_XRGB16161616,
+   .flags = 0,
+};
+
 /* For SetRegamma ADL interface support
  * Must match escape type
  */
-- 
2.35.1



[RFC PATCH v2 12/18] drm/amd/display: acquire/release 3D LUT resources for ctx on DCN301

2023-01-09 Thread Melissa Wen
Acquire and release 3D LUT and shaper LUT every time we create/remove a
new ctx and add/remove stream to/from it. 3D LUT acquire/release can
fail and therefore we should check its availability during atomic check
considering the new context created not the current one.

Signed-off-by: Melissa Wen 
---
 .../amd/display/dc/dcn301/dcn301_resource.c   | 47 ++-
 1 file changed, 45 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/dcn301/dcn301_resource.c 
b/drivers/gpu/drm/amd/display/dc/dcn301/dcn301_resource.c
index ee62ae3eb98f..5bae0972bd5e 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn301/dcn301_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn301/dcn301_resource.c
@@ -1260,6 +1260,49 @@ static struct display_stream_compressor 
*dcn301_dsc_create(
return >base;
 }
 
+static enum dc_status
+dcn301_add_stream_to_ctx(struct dc *dc,
+struct dc_state *new_ctx,
+struct dc_stream_state *dc_stream)
+{
+   enum dc_status result = DC_ERROR_UNEXPECTED;
+   struct dc_3dlut *lut3d_func_new = NULL;
+   struct dc_transfer_func *func_shaper_new = NULL;
+
+   result = dcn20_add_stream_to_ctx(dc, new_ctx, dc_stream);
+   if (result != DC_OK)
+   return result;
+
+   if (!dc_acquire_release_mpc_3dlut_for_ctx(dc, true, new_ctx, dc_stream,
+ _func_new, 
_shaper_new))
+   return DC_ERROR_UNEXPECTED;
+
+   dc_stream->lut3d_func = lut3d_func_new;
+   dc_stream->func_shaper = func_shaper_new;
+
+   return DC_OK;
+}
+
+static enum dc_status
+dcn301_remove_stream_from_ctx(struct dc *dc,
+ struct dc_state *new_ctx,
+ struct dc_stream_state *dc_stream)
+{
+   struct dc_3dlut *lut3d_func;
+   struct dc_transfer_func *func_shaper;
+
+   lut3d_func = (struct dc_3dlut *)dc_stream->lut3d_func;
+   func_shaper = (struct dc_transfer_func *)dc_stream->func_shaper;
+
+   if (!dc_acquire_release_mpc_3dlut_for_ctx(dc, false, new_ctx, dc_stream,
+ _func, _shaper))
+   return DC_ERROR_UNEXPECTED;
+
+   dc_stream->lut3d_func = lut3d_func;
+   dc_stream->func_shaper = func_shaper;
+
+   return dcn20_remove_stream_from_ctx(dc, new_ctx, dc_stream);
+}
 
 static void dcn301_destroy_resource_pool(struct resource_pool **pool)
 {
@@ -1406,9 +1449,9 @@ static struct resource_funcs dcn301_res_pool_funcs = {
.update_soc_for_wm_a = dcn30_update_soc_for_wm_a,
.populate_dml_pipes = dcn30_populate_dml_pipes_from_context,
.acquire_idle_pipe_for_layer = dcn20_acquire_idle_pipe_for_layer,
-   .add_stream_to_ctx = dcn30_add_stream_to_ctx,
+   .add_stream_to_ctx = dcn301_add_stream_to_ctx,
.add_dsc_to_stream_resource = dcn20_add_dsc_to_stream_resource,
-   .remove_stream_from_ctx = dcn20_remove_stream_from_ctx,
+   .remove_stream_from_ctx = dcn301_remove_stream_from_ctx,
.populate_dml_writeback_from_context = 
dcn30_populate_dml_writeback_from_context,
.set_mcif_arb_params = dcn30_set_mcif_arb_params,
.find_first_free_match_stream_enc_for_link = 
dcn10_find_first_free_match_stream_enc_for_link,
-- 
2.35.1



[RFC PATCH v2 11/18] drm/amd/display: handle MPC 3D LUT resources for a given context

2023-01-09 Thread Melissa Wen
In the original dc_acquire_release_mpc_3dlut(), only current ctx is
considered, which doesn't fit the steps for atomic checking new ctx.
Therefore, create a function to handle 3D LUT resource for a given
context, so that we can check resources availability in atomic_check
time and handle failures properly.

Signed-off-by: Melissa Wen 
---
 drivers/gpu/drm/amd/display/dc/core/dc.c | 39 
 drivers/gpu/drm/amd/display/dc/dc.h  |  8 +
 2 files changed, 47 insertions(+)

diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c 
b/drivers/gpu/drm/amd/display/dc/core/dc.c
index 88f1130c3b83..76270d21286a 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc.c
@@ -2085,6 +2085,45 @@ bool dc_acquire_release_mpc_3dlut(
return ret;
 }
 
+bool
+dc_acquire_release_mpc_3dlut_for_ctx(struct dc *dc,
+bool acquire,
+struct dc_state *state,
+struct dc_stream_state *stream,
+struct dc_3dlut **lut,
+struct dc_transfer_func **shaper)
+{
+   int pipe_idx;
+   bool ret = false;
+   bool found_pipe_idx = false;
+   const struct resource_pool *pool = dc->res_pool;
+   struct resource_context *res_ctx = >res_ctx;
+   int mpcc_id = 0;
+
+   if (pool && res_ctx) {
+   if (acquire) {
+   /*find pipe idx for the given stream*/
+   for (pipe_idx = 0; pipe_idx < pool->pipe_count; 
pipe_idx++) {
+   if (res_ctx->pipe_ctx[pipe_idx].stream == 
stream) {
+   found_pipe_idx = true;
+   mpcc_id = 
res_ctx->pipe_ctx[pipe_idx].plane_res.hubp->inst;
+   break;
+   }
+   }
+   } else
+   found_pipe_idx = true;/*for release pipe_idx is not 
required*/
+
+   if (found_pipe_idx) {
+   if (acquire && pool->funcs->acquire_post_bldn_3dlut)
+   ret = 
pool->funcs->acquire_post_bldn_3dlut(res_ctx, pool, mpcc_id, lut, shaper);
+   else if (!acquire && 
pool->funcs->release_post_bldn_3dlut)
+   ret = 
pool->funcs->release_post_bldn_3dlut(res_ctx, pool, lut, shaper);
+   }
+   }
+   return ret;
+}
+
+
 static bool is_flip_pending_in_pipes(struct dc *dc, struct dc_state *context)
 {
int i;
diff --git a/drivers/gpu/drm/amd/display/dc/dc.h 
b/drivers/gpu/drm/amd/display/dc/dc.h
index 72963617553e..a5abf7f308c3 100644
--- a/drivers/gpu/drm/amd/display/dc/dc.h
+++ b/drivers/gpu/drm/amd/display/dc/dc.h
@@ -1345,6 +1345,14 @@ bool dc_acquire_release_mpc_3dlut(
struct dc_3dlut **lut,
struct dc_transfer_func **shaper);
 
+bool
+dc_acquire_release_mpc_3dlut_for_ctx(struct dc *dc,
+bool acquire,
+struct dc_state *state,
+struct dc_stream_state *stream,
+struct dc_3dlut **lut,
+struct dc_transfer_func **shaper);
+
 void dc_resource_state_copy_construct(
const struct dc_state *src_ctx,
struct dc_state *dst_ctx);
-- 
2.35.1



[RFC PATCH v2 09/18] drm/amd/display: encapsulate atomic regamma operation

2023-01-09 Thread Melissa Wen
We are introducing DRM 3D LUT property to DM color pipeline in the next
patch, but so far, only for atomic interface. By checking
.set_output_transfer_func in DC drivers with MPC 3D LUT support, we can
verify that regamma is only programmed when 3D LUT programming fails. As
a groundwork to introduce 3D LUT programming and better understand each
step, detach atomic regamma programming from the crtc colocr updating
code.

Signed-off-by: Melissa Wen 
---
 .../amd/display/amdgpu_dm/amdgpu_dm_color.c   | 52 ---
 1 file changed, 33 insertions(+), 19 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
index b54ef1392895..54d95745f0f0 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
@@ -291,6 +291,36 @@ static int __set_output_tf(struct dc_transfer_func *func,
return res ? 0 : -ENOMEM;
 }
 
+static int amdgpu_dm_set_atomic_regamma(struct dc_stream_state *stream,
+   const struct drm_color_lut *regamma_lut,
+   uint32_t regamma_size)
+{
+   int ret = 0;
+
+   if (regamma_size) {
+   /* CRTC RGM goes into RGM LUT.
+*
+* Note: here there is no implicit sRGB regamma. We are using
+* degamma calculation from color module to calculate the curve
+* from a linear base.
+*/
+   stream->out_transfer_func->type = TF_TYPE_DISTRIBUTED_POINTS;
+   stream->out_transfer_func->tf = TRANSFER_FUNCTION_LINEAR;
+
+   ret = __set_output_tf(stream->out_transfer_func, regamma_lut,
+ regamma_size);
+   } else {
+   /*
+* No CRTC RGM means we can just put the block into bypass
+* since we don't have any plane level adjustments using it.
+*/
+   stream->out_transfer_func->type = TF_TYPE_BYPASS;
+   stream->out_transfer_func->tf = TRANSFER_FUNCTION_LINEAR;
+   }
+
+   return ret;
+}
+
 /**
  * __set_input_tf - calculates the input transfer function based on expected
  * input space.
@@ -438,27 +468,11 @@ int amdgpu_dm_update_crtc_color_mgmt(struct dm_crtc_state 
*crtc)
regamma_size, has_rom);
if (r)
return r;
-   } else if (has_regamma) {
-   /* CRTC RGM goes into RGM LUT.
-*
-* Note: here there is no implicit sRGB regamma. We are using
-* degamma calculation from color module to calculate the curve
-* from a linear base.
-*/
-   stream->out_transfer_func->type = TF_TYPE_DISTRIBUTED_POINTS;
-   stream->out_transfer_func->tf = TRANSFER_FUNCTION_LINEAR;
-
-   r = __set_output_tf(stream->out_transfer_func, regamma_lut,
-   regamma_size);
+   } else {
+   regamma_size = has_regamma ? regamma_size : 0;
+   r = amdgpu_dm_set_atomic_regamma(stream, regamma_lut, 
regamma_size);
if (r)
return r;
-   } else {
-   /*
-* No CRTC RGM means we can just put the block into bypass
-* since we don't have any plane level adjustments using it.
-*/
-   stream->out_transfer_func->type = TF_TYPE_BYPASS;
-   stream->out_transfer_func->tf = TRANSFER_FUNCTION_LINEAR;
}
 
/*
-- 
2.35.1



[RFC PATCH v2 08/18] drm/amd/display: add comments to describe DM crtc color mgmt behavior

2023-01-09 Thread Melissa Wen
Describe some expected behavior of the AMD DM color mgmt programming.

Signed-off-by: Melissa Wen 
---
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c | 13 -
 1 file changed, 12 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
index 10a29d131424..b54ef1392895 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
@@ -428,12 +428,23 @@ int amdgpu_dm_update_crtc_color_mgmt(struct dm_crtc_state 
*crtc)
stream->out_transfer_func->type = TF_TYPE_DISTRIBUTED_POINTS;
stream->out_transfer_func->tf = TRANSFER_FUNCTION_SRGB;
 
+   /* Note: even if we pass has_rom as parameter here, we never
+* actually use ROM because the color module only takes the ROM
+* path if transfer_func->type == PREDEFINED.
+*
+* See more in mod_color_calculate_regamma_params()
+*/
r = __set_legacy_tf(stream->out_transfer_func, regamma_lut,
regamma_size, has_rom);
if (r)
return r;
} else if (has_regamma) {
-   /* If atomic regamma, CRTC RGM goes into RGM LUT. */
+   /* CRTC RGM goes into RGM LUT.
+*
+* Note: here there is no implicit sRGB regamma. We are using
+* degamma calculation from color module to calculate the curve
+* from a linear base.
+*/
stream->out_transfer_func->type = TF_TYPE_DISTRIBUTED_POINTS;
stream->out_transfer_func->tf = TRANSFER_FUNCTION_LINEAR;
 
-- 
2.35.1



[RFC PATCH v2 07/18] drm/amd/display: remove unused regamma condition

2023-01-09 Thread Melissa Wen
The function __set_output_tf is only called by
amdgpu_dm_update_crtc_color_mgmt() when using atomic regamma. In this
situation, func->tf == TRANSFER_FUNCTION_LINEAR (the original if
condition) and it never falls into tf != LINEAR (the else condition).
Therefore, remove unused condition to avoid misunderstandings here.

Signed-off-by: Melissa Wen 
---
 .../amd/display/amdgpu_dm/amdgpu_dm_color.c   | 32 ++-
 1 file changed, 10 insertions(+), 22 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
index a4cb23d059bd..10a29d131424 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
@@ -255,14 +255,13 @@ static int __set_legacy_tf(struct dc_transfer_func *func,
  * @func: transfer function
  * @lut: lookup table that defines the color space
  * @lut_size: size of respective lut
- * @has_rom: if ROM can be used for hardcoded curve
  *
  * Returns:
  * 0 in case of success. -ENOMEM if fails.
  */
 static int __set_output_tf(struct dc_transfer_func *func,
-  const struct drm_color_lut *lut, uint32_t lut_size,
-  bool has_rom)
+  const struct drm_color_lut *lut,
+  uint32_t lut_size)
 {
struct dc_gamma *gamma = NULL;
struct calculate_buffer cal_buffer = {0};
@@ -279,24 +278,13 @@ static int __set_output_tf(struct dc_transfer_func *func,
gamma->num_entries = lut_size;
__drm_lut_to_dc_gamma(lut, gamma, false);
 
-   if (func->tf == TRANSFER_FUNCTION_LINEAR) {
-   /*
-* Color module doesn't like calculating regamma params
-* on top of a linear input. But degamma params can be used
-* instead to simulate this.
-*/
-   gamma->type = GAMMA_CUSTOM;
-   res = mod_color_calculate_degamma_params(NULL, func,
-   gamma, true);
-   } else {
-   /*
-* Assume sRGB. The actual mapping will depend on whether the
-* input was legacy or not.
-*/
-   gamma->type = GAMMA_CS_TFM_1D;
-   res = mod_color_calculate_regamma_params(func, gamma, false,
-has_rom, NULL, 
_buffer);
-   }
+   /*
+* Color module doesn't like calculating regamma params
+* on top of a linear input. But degamma params can be used
+* instead to simulate this.
+*/
+   gamma->type = GAMMA_CUSTOM;
+   res = mod_color_calculate_degamma_params(NULL, func, gamma, true);
 
dc_gamma_release();
 
@@ -450,7 +438,7 @@ int amdgpu_dm_update_crtc_color_mgmt(struct dm_crtc_state 
*crtc)
stream->out_transfer_func->tf = TRANSFER_FUNCTION_LINEAR;
 
r = __set_output_tf(stream->out_transfer_func, regamma_lut,
-   regamma_size, has_rom);
+   regamma_size);
if (r)
return r;
} else {
-- 
2.35.1



[RFC PATCH v2 00/18] Add DRM CRTC 3D LUT interface

2023-01-09 Thread Melissa Wen
Hi,

After collecting comments in different places, here is a second version
of the work on adding DRM CRTC 3D LUT support to the current DRM color
mgmt interface. In comparison to previous proposals [1][2][3], here we
add 3D LUT before gamma 1D LUT, but also a shaper 1D LUT before 3D LUT,
that means the following DRM CRTC color correction pipeline:

Blend -> Degamma 1D LUT -> CTM -> Shaper 1D LUT -> 3D LUT -> Gamma 1D LUT

and we also add a DRM CRTC LUT3D_MODE property, based on Alex Hung
proposal for pre-blending 3D LUT [4] (Thanks!), instead of just a
LUT3D_SIZE, that allows userspace to use different supported settings of
3D LUT, fitting VA-API and new color API better. In this sense, I
adjusted the pre-blending proposal for post-blending usage.

Patches 1-6 targets the addition of shaper LUT and 3D LUT properties to
the current DRM CRTC color mgmt pipeline. Patch 6 can be considered an
extra/optional patch to define a default value for LUT3D_MODE, inspired
by what we do for the plane blend mode property (pre-multiplied).

Patches 7-18 targets AMD display code to enable shaper and 3D LUT usage
on DCN 301 (our HW case). Patches 7-9 performs code cleanups on current
AMD DM colors code, patch 10 updates AMD stream in case of user 3D LUT
changes, patch 11/12 rework AMD MPC 3D LUT resource handling by context
for DCN 301 (easily extendible to other DCN families). Finally, from
13-18, we wire up SHAPER LUT, LUT3D and LUT3D MODE to AMD display
driver, exposing modes supported by HW and programming user shaper and
3D LUT accordingly.

Our target userspace is Gamescope/SteamOS.

Basic IGT tests were based on [5][6] and are available here (in-progress):
https://gitlab.freedesktop.org/mwen/igt-gpu-tools/-/commits/crtc-lut3d-api

[1] 
https://lore.kernel.org/all/20201221015730.28333-1-laurent.pinchart+rene...@ideasonboard.com/
[2] 
https://github.com/vsyrjala/linux/commit/4d28e8ddf2a076f30f9e5bdc17cbb4656fe23e69
[3] https://lore.kernel.org/amd-gfx/20220619223104.667413-1-m...@igalia.com/
[4] 
https://lore.kernel.org/dri-devel/20221004211451.1475215-1-alex.h...@amd.com/
[5] https://patchwork.freedesktop.org/series/90165/
[6] https://patchwork.freedesktop.org/series/109402/
[VA_API] 
http://intel.github.io/libva/structVAProcFilterParameterBuffer3DLUT.html
[KMS_pipe_API] https://gitlab.freedesktop.org/pq/color-and-hdr/-/issues/11

Let me know your thoughts.

Thanks,

Melissa

Alex Hung (2):
  drm: Add 3D LUT mode and its attributes
  drm/amd/display: Define 3D LUT struct for HDR planes

Melissa Wen (16):
  drm/drm_color_mgmt: add shaper LUT to color mgmt properties
  drm/drm_color_mgmt: add 3D LUT props to DRM color mgmt
  drm/drm_color_mgmt: add function to create 3D LUT modes supported
  drm/drm_color_mgmt: add function to attach 3D LUT props
  drm/drm_color_mgmt: set first lut3d mode as default
  drm/amd/display: remove unused regamma condition
  drm/amd/display: add comments to describe DM crtc color mgmt behavior
  drm/amd/display: encapsulate atomic regamma operation
  drm/amd/display: update lut3d and shaper lut to stream
  drm/amd/display: handle MPC 3D LUT resources for a given context
  drm/amd/display: acquire/release 3D LUT resources for ctx on DCN301
  drm/amd/display: expand array of supported 3D LUT modes
  drm/amd/display: enable 3D-LUT DRM properties if supported
  drm/amd/display: add user 3D LUT support to the amdgpu_dm color
pipeline
  drm/amd/display: decouple steps to reuse in shaper LUT support
  drm/amd/display: add user shaper LUT support to amdgpu_dm color
pipeline

 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c |   6 +
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h |   3 +
 .../amd/display/amdgpu_dm/amdgpu_dm_color.c   | 370 --
 .../amd/display/amdgpu_dm/amdgpu_dm_crtc.c|   2 +
 drivers/gpu/drm/amd/display/dc/core/dc.c  |  49 ++-
 drivers/gpu/drm/amd/display/dc/dc.h   |   8 +
 .../amd/display/dc/dcn301/dcn301_resource.c   |  47 ++-
 .../amd/display/modules/color/color_gamma.h   |  43 ++
 drivers/gpu/drm/drm_atomic_state_helper.c |   7 +
 drivers/gpu/drm/drm_atomic_uapi.c |  24 ++
 drivers/gpu/drm/drm_color_mgmt.c  | 127 ++
 drivers/gpu/drm/drm_fb_helper.c   |   5 +
 drivers/gpu/drm/drm_mode_config.c |  21 +
 include/drm/drm_color_mgmt.h  |   8 +
 include/drm/drm_crtc.h|  32 +-
 include/drm/drm_mode_config.h |  25 ++
 include/drm/drm_mode_object.h |   2 +-
 include/uapi/drm/drm_mode.h   |  17 +
 18 files changed, 757 insertions(+), 39 deletions(-)

-- 
2.35.1



[PATCH] drm/amd/display: don't enable DRM CRTC degamma property for DCE

2022-11-03 Thread Melissa Wen
DM maps DRM CRTC degamma to DPP (pre-blending) degamma block, but DCE doesn't
support programmable degamma curve anywhere. Currently, a custom degamma is
accepted by DM but just ignored by DCE driver and degamma correction isn't
actually applied. There is no way to map custom degamma in DCE, therefore, DRM
CRTC degamma property shouldn't be enabled for DCE drivers.

Signed-off-by: Melissa Wen 
---
 drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c | 10 --
 1 file changed, 8 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c
index 9ac2805c5d63..b3eadfc61555 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c
@@ -415,7 +415,7 @@ int amdgpu_dm_crtc_init(struct amdgpu_display_manager *dm,
 {
struct amdgpu_crtc *acrtc = NULL;
struct drm_plane *cursor_plane;
-
+   bool is_dcn;
int res = -ENOMEM;
 
cursor_plane = kzalloc(sizeof(*cursor_plane), GFP_KERNEL);
@@ -453,8 +453,14 @@ int amdgpu_dm_crtc_init(struct amdgpu_display_manager *dm,
acrtc->otg_inst = -1;
 
dm->adev->mode_info.crtcs[crtc_index] = acrtc;
-   drm_crtc_enable_color_mgmt(>base, MAX_COLOR_LUT_ENTRIES,
+
+   /* Don't enable DRM CRTC degamma property for DCE since it doesn't
+* support programmable degamma anywhere.
+*/
+   is_dcn = dm->adev->dm.dc->caps.color.dpp.dcn_arch;
+   drm_crtc_enable_color_mgmt(>base, is_dcn ? MAX_COLOR_LUT_ENTRIES 
: 0,
   true, MAX_COLOR_LUT_ENTRIES);
+
drm_mode_crtc_set_gamma_size(>base, 
MAX_COLOR_LEGACY_LUT_ENTRIES);
 
return 0;
-- 
2.35.1



[RFC PATCH v2 9/9] drm/amd/display: enable DRM shaper and 3D LUT properties

2022-09-06 Thread Melissa Wen
Shaper LUT and 3D LUT programming is done, so make the DRM color
properties available.

Signed-off-by: Melissa Wen 
---
 drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c
index c89594f3a5cb..b165a0c269fa 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c
@@ -452,6 +452,12 @@ int amdgpu_dm_crtc_init(struct amdgpu_display_manager *dm,
dm->adev->mode_info.crtcs[crtc_index] = acrtc;
drm_crtc_enable_color_mgmt(>base, MAX_COLOR_LUT_ENTRIES,
   true, MAX_COLOR_LUT_ENTRIES);
+
+   if (dm->dc->caps.color.mpc.num_3dluts)
+   drm_crtc_enable_lut3d(>base,
+ MAX_COLOR_LUT_ENTRIES,
+ MAX_COLOR_3DLUT_ENTRIES);
+
drm_mode_crtc_set_gamma_size(>base, 
MAX_COLOR_LEGACY_LUT_ENTRIES);
 
return 0;
-- 
2.35.1



[RFC PATCH v2 8/9] drm/amd/display: update lut3d and shaper lut to stream

2022-09-06 Thread Melissa Wen
It follows the same path of out_transfer_func for stream updates, since
shaper LUT and 3D LUT is programmed in funcs.set_output_transfer_func()
and this function is called in the atomic commit_tail when
update_flags.bits.out_tf is set.

Signed-off-by: Melissa Wen 
---
 drivers/gpu/drm/amd/display/dc/core/dc.c | 10 +-
 1 file changed, 9 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c 
b/drivers/gpu/drm/amd/display/dc/core/dc.c
index 9860bf38c547..d1fa87ddf1dd 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc.c
@@ -2405,7 +2405,7 @@ static enum surface_update_type 
check_update_surfaces_for_stream(
stream_update->integer_scaling_update)
su_flags->bits.scaling = 1;
 
-   if (stream_update->out_transfer_func)
+   if (stream_update->out_transfer_func || 
stream_update->lut3d_func)
su_flags->bits.out_tf = 1;
 
if (stream_update->abm_level)
@@ -2754,6 +2754,14 @@ static void copy_stream_update_to_stream(struct dc *dc,
   sizeof(struct dc_transfer_func_distributed_points));
}
 
+   if (update->func_shaper &&
+   stream->func_shaper != update->func_shaper)
+   stream->func_shaper = update->func_shaper;
+
+   if (update->lut3d_func &&
+   stream->lut3d_func != update->lut3d_func)
+   stream->lut3d_func = update->lut3d_func;
+
if (update->hdr_static_metadata)
stream->hdr_static_metadata = *update->hdr_static_metadata;
 
-- 
2.35.1



[RFC PATCH v2 7/9] drm/amd/display: add user shaper LUT support to amdgpu_dm color pipeline

2022-09-06 Thread Melissa Wen
Now, we can use shaper LUT to delinearize and/or normalize the color
space for a more efficient 3D LUT support (so far, only for DRM atomic
color mgmt). If a degamma 1D LUT is passed to linearize the color space,
a custom shaper 1D LUT can be used before applying 3D LUT.

Signed-off-by: Melissa Wen 
---
 .../amd/display/amdgpu_dm/amdgpu_dm_color.c   | 105 +++---
 1 file changed, 87 insertions(+), 18 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
index 9777252191b1..b590fc83a88c 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
@@ -352,18 +352,64 @@ static int __set_input_tf(struct dc_transfer_func *func,
return res ? 0 : -ENOMEM;
 }
 
-static int amdgpu_dm_atomic_shaper_lut(struct dc_stream_state *stream,
-  struct dc_transfer_func *func_shaper_new)
+static int __set_func_shaper(struct dc_transfer_func *shaper_func,
+const struct drm_color_lut *lut, uint32_t lut_size)
 {
+   struct dc_gamma *gamma = NULL;
+   struct calculate_buffer cal_buffer = {0};
+   bool res;
+
+   ASSERT(lut && lut_size == MAX_COLOR_LUT_ENTRIES);
+
+   cal_buffer.buffer_index = -1;
+
+   gamma = dc_create_gamma();
+   if (!gamma)
+   return -ENOMEM;
+
+   gamma->num_entries = lut_size;
+   __drm_lut_to_dc_gamma(lut, gamma, false);
+
+   /*
+* Color module doesn't like calculating gamma params
+* on top of a linear input. But degamma params can be used
+* instead to simulate this.
+*/
+   gamma->type = GAMMA_CUSTOM;
+   res = mod_color_calculate_degamma_params(NULL, shaper_func, gamma, 
true);
+
+   dc_gamma_release();
+
+   return res ? 0 : -ENOMEM;
+}
 
-   /* We don't get DRM shaper LUT yet. We assume the input color space is
-* already delinearized, so we don't need a shaper LUT and we can just
-* BYPASS.  However, checking dcn30_set_mpc_shaper_3dlut() it seems
+static int amdgpu_dm_atomic_shaper_lut(struct dc_stream_state *stream,
+  struct dc_transfer_func *func_shaper_new,
+  const struct drm_color_lut *shaper_lut,
+  uint32_t shaper_size)
+{
+   /* If no DRM shaper LUT, we assume the input color space is already
+* delinearized, so we don't need a shaper LUT and we can just BYPASS
+* However, checking dcn30_set_mpc_shaper_3dlut() it seems
 * that setting shaper LUT to BYPASS is not currently supported in the
 * DC level, since shaper LUT programming just fails without params.
 */
-   func_shaper_new->type = TF_TYPE_BYPASS;
-   func_shaper_new->tf = TRANSFER_FUNCTION_LINEAR;
+   if (!shaper_size) {
+   func_shaper_new->type = TF_TYPE_BYPASS;
+   func_shaper_new->tf = TRANSFER_FUNCTION_LINEAR;
+   } else {
+   int r;
+
+   /* If DRM shaper LUT is set, we follow the same behavior of the
+* atomic regamma and assume a linear base */
+   func_shaper_new->type = TF_TYPE_DISTRIBUTED_POINTS;
+   func_shaper_new->tf = TRANSFER_FUNCTION_LINEAR;
+
+   r = __set_func_shaper(func_shaper_new, shaper_lut,
+   shaper_size);
+   if (r)
+   return r;
+   }
 
stream->func_shaper = func_shaper_new;
 
@@ -427,12 +473,27 @@ static uint32_t amdgpu_dm_get_3dlut_size(uint32_t 
lut_size,
 int amdgpu_dm_verify_3dlut_size(const struct drm_crtc_state *crtc_state,
struct amdgpu_device *adev)
 {
-   const struct drm_color_lut *lut3d = NULL;
+   const struct drm_color_lut *shaper = NULL, *lut3d = NULL;
uint32_t exp_size, size;
 
+   /* shaper LUT is only available if 3D LUT color caps*/
+   exp_size = amdgpu_dm_get_3dlut_size(MAX_COLOR_LUT_ENTRIES, adev);
+
+   shaper = __extract_blob_lut(crtc_state->shaper_lut, );
+   if (shaper && size != exp_size) {
+   DRM_DEBUG_DRIVER(
+   "Invalid Shaper LUT size. Should be %u but got %u.\n",
+   exp_size, size);
+   return -EINVAL;
+   }
+
exp_size = amdgpu_dm_get_3dlut_size(MAX_COLOR_3DLUT_ENTRIES, adev);
lut3d = __extract_blob_lut(crtc_state->lut3d, );
 
+   /* shaper LUT implies 3D LUT. See dcn30_set_output_transfer_func() */
+   if (shaper && !lut3d)
+   DRM_DEBUG_DRIVER("Shaper LUT is set without 3D LUT.\n");
+
if (lut3d && size != exp_size) {
DRM_DEBUG_DRIVER("Invalid Gamma 3D LUT size. Should be %u but 
got %u.\n",
  

[RFC PATCH v2 6/9] drm/amd/display: add user 3D LUT support to the amdgpu_dm color pipeline

2022-09-06 Thread Melissa Wen
Map DRM 3D LUT in the atomic color mgmt pipeline to DC. 3D LUT works
better in a non-linear color space, therefore using a degamma to
linearize the input space may produce unexpected results. The next patch
introduces shaper LUT support that can be used to delinearize the color
space before applying 3D LUT conversion.

Note that there is no implicit sRGB degamma/regamma in the original
implementation for DRM atomic color mgmt. Atomic degamma/regamma 1D LUT
is applied considering a linear base.
For reference, see IGT test amdgpu/amd_color and commit
cf020d49b3c4 ("drm/amd/display: Rework CRTC color management")

dc_acquire_release_mpc_3dlut initializes the bits required to program
3DLUT in DC MPC hw block, that is applied by set_output_transfer_func().
But we should verify if the timing to acquire and release shaper and 3D
LUTs from the resource pool in this patch is correct.

Signed-off-by: Melissa Wen 
---
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c |   6 +
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h |   5 +
 .../amd/display/amdgpu_dm/amdgpu_dm_color.c   | 149 +-
 .../gpu/drm/amd/display/dc/core/dc_stream.c   |  13 ++
 4 files changed, 172 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
index dbe76b85552e..05d96978925c 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -9435,6 +9435,12 @@ static int amdgpu_dm_atomic_check(struct drm_device *dev,
goto fail;
}
 
+   ret = amdgpu_dm_verify_3dlut_size(new_crtc_state, adev);
+   if (ret) {
+   DRM_DEBUG_DRIVER("amdgpu_dm_verify_lut_sizes() 
failed\n");
+   goto fail;
+   }
+
if (!new_crtc_state->enable)
continue;
 
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
index b44faaad9b0b..435cf6b4efc1 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
@@ -784,12 +784,17 @@ void amdgpu_dm_update_freesync_caps(struct drm_connector 
*connector,
 
 void amdgpu_dm_trigger_timing_sync(struct drm_device *dev);
 
+/* 3D LUT max size is 17x17x17 */
+#define MAX_COLOR_3DLUT_ENTRIES 4913
+/* 1D LUT degamma, regamma and shaper*/
 #define MAX_COLOR_LUT_ENTRIES 4096
 /* Legacy gamm LUT users such as X doesn't like large LUT sizes */
 #define MAX_COLOR_LEGACY_LUT_ENTRIES 256
 
 void amdgpu_dm_init_color_mod(void);
 int amdgpu_dm_verify_lut_sizes(const struct drm_crtc_state *crtc_state);
+int amdgpu_dm_verify_3dlut_size(const struct drm_crtc_state *crtc_state,
+   struct amdgpu_device *adev);
 int amdgpu_dm_update_crtc_color_mgmt(struct dm_crtc_state *crtc);
 int amdgpu_dm_update_plane_color_mgmt(struct dm_crtc_state *crtc,
  struct dc_plane_state *dc_plane_state);
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
index 54d95745f0f0..9777252191b1 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
@@ -352,6 +352,131 @@ static int __set_input_tf(struct dc_transfer_func *func,
return res ? 0 : -ENOMEM;
 }
 
+static int amdgpu_dm_atomic_shaper_lut(struct dc_stream_state *stream,
+  struct dc_transfer_func *func_shaper_new)
+{
+
+   /* We don't get DRM shaper LUT yet. We assume the input color space is
+* already delinearized, so we don't need a shaper LUT and we can just
+* BYPASS.  However, checking dcn30_set_mpc_shaper_3dlut() it seems
+* that setting shaper LUT to BYPASS is not currently supported in the
+* DC level, since shaper LUT programming just fails without params.
+*/
+   func_shaper_new->type = TF_TYPE_BYPASS;
+   func_shaper_new->tf = TRANSFER_FUNCTION_LINEAR;
+
+   stream->func_shaper = func_shaper_new;
+
+   return 0;
+}
+
+static void __to_dc_lut3d_color(struct dc_rgb *rgb,
+   const struct drm_color_lut lut,
+   int bit_precision)
+{
+   rgb->red = drm_color_lut_extract(lut.red, bit_precision);
+   rgb->green = drm_color_lut_extract(lut.green, bit_precision);
+   rgb->blue  = drm_color_lut_extract(lut.blue, bit_precision);
+}
+
+static void __drm_3dlut_to_dc_3dlut(const struct drm_color_lut *lut,
+   uint32_t lut_size,
+   struct dc_3dlut *lut3d)
+{
+   int lut_i, i;
+
+   ASSERT(lut3d && lut_size == MAX_COLOR_3DLUT_ENTRIES);
+
+   /* So far, only supports 17x17x17 3D LUT with 12-bit*

[RFC PATCH v2 5/9] drm/amd/display: encapsulate atomic regamma operation

2022-09-06 Thread Melissa Wen
We are introducing DRM 3D LUT property to DM color pipeline in the next
patch, but so far, only for atomic interface. By checking
.set_output_transfer_func in DC drivers with MPC 3D LUT support, we can
verify that regamma is only programmed when 3D LUT programming fails. As
a groundwork to introduce 3D LUT programming and better understand each
step, detach atomic regamma programming from the crtc colocr updating
code.

Signed-off-by: Melissa Wen 
---
 .../amd/display/amdgpu_dm/amdgpu_dm_color.c   | 52 ---
 1 file changed, 33 insertions(+), 19 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
index b54ef1392895..54d95745f0f0 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
@@ -291,6 +291,36 @@ static int __set_output_tf(struct dc_transfer_func *func,
return res ? 0 : -ENOMEM;
 }
 
+static int amdgpu_dm_set_atomic_regamma(struct dc_stream_state *stream,
+   const struct drm_color_lut *regamma_lut,
+   uint32_t regamma_size)
+{
+   int ret = 0;
+
+   if (regamma_size) {
+   /* CRTC RGM goes into RGM LUT.
+*
+* Note: here there is no implicit sRGB regamma. We are using
+* degamma calculation from color module to calculate the curve
+* from a linear base.
+*/
+   stream->out_transfer_func->type = TF_TYPE_DISTRIBUTED_POINTS;
+   stream->out_transfer_func->tf = TRANSFER_FUNCTION_LINEAR;
+
+   ret = __set_output_tf(stream->out_transfer_func, regamma_lut,
+ regamma_size);
+   } else {
+   /*
+* No CRTC RGM means we can just put the block into bypass
+* since we don't have any plane level adjustments using it.
+*/
+   stream->out_transfer_func->type = TF_TYPE_BYPASS;
+   stream->out_transfer_func->tf = TRANSFER_FUNCTION_LINEAR;
+   }
+
+   return ret;
+}
+
 /**
  * __set_input_tf - calculates the input transfer function based on expected
  * input space.
@@ -438,27 +468,11 @@ int amdgpu_dm_update_crtc_color_mgmt(struct dm_crtc_state 
*crtc)
regamma_size, has_rom);
if (r)
return r;
-   } else if (has_regamma) {
-   /* CRTC RGM goes into RGM LUT.
-*
-* Note: here there is no implicit sRGB regamma. We are using
-* degamma calculation from color module to calculate the curve
-* from a linear base.
-*/
-   stream->out_transfer_func->type = TF_TYPE_DISTRIBUTED_POINTS;
-   stream->out_transfer_func->tf = TRANSFER_FUNCTION_LINEAR;
-
-   r = __set_output_tf(stream->out_transfer_func, regamma_lut,
-   regamma_size);
+   } else {
+   regamma_size = has_regamma ? regamma_size : 0;
+   r = amdgpu_dm_set_atomic_regamma(stream, regamma_lut, 
regamma_size);
if (r)
return r;
-   } else {
-   /*
-* No CRTC RGM means we can just put the block into bypass
-* since we don't have any plane level adjustments using it.
-*/
-   stream->out_transfer_func->type = TF_TYPE_BYPASS;
-   stream->out_transfer_func->tf = TRANSFER_FUNCTION_LINEAR;
}
 
/*
-- 
2.35.1



[RFC PATCH v2 3/9] drm/drm_color_mgmt: add shaper LUT to color mgmt properties

2022-09-06 Thread Melissa Wen
Shaper LUT is used to shape the contect after blending, i.e.,
de-linearize space before applying 3D LUT color correction. In the next
patch, we are adding 3D LUT property to DRM color mgmt.

Signed-off-by: Melissa Wen 
---
 drivers/gpu/drm/drm_atomic_state_helper.c |  4 +++
 drivers/gpu/drm/drm_atomic_uapi.c | 10 
 drivers/gpu/drm/drm_color_mgmt.c  | 31 ++-
 drivers/gpu/drm/drm_fb_helper.c   |  3 +++
 drivers/gpu/drm/drm_mode_config.c | 14 ++
 include/drm/drm_crtc.h| 14 --
 include/drm/drm_mode_config.h | 12 +
 7 files changed, 79 insertions(+), 9 deletions(-)

diff --git a/drivers/gpu/drm/drm_atomic_state_helper.c 
b/drivers/gpu/drm/drm_atomic_state_helper.c
index 3b6d3bdbd099..bf3222fbf4bb 100644
--- a/drivers/gpu/drm/drm_atomic_state_helper.c
+++ b/drivers/gpu/drm/drm_atomic_state_helper.c
@@ -139,8 +139,11 @@ 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->shaper_lut)
+   drm_property_blob_get(state->shaper_lut);
if (state->gamma_lut)
drm_property_blob_get(state->gamma_lut);
+
state->mode_changed = false;
state->active_changed = false;
state->planes_changed = false;
@@ -212,6 +215,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->shaper_lut);
drm_property_blob_put(state->gamma_lut);
 }
 EXPORT_SYMBOL(__drm_atomic_helper_crtc_destroy_state);
diff --git a/drivers/gpu/drm/drm_atomic_uapi.c 
b/drivers/gpu/drm/drm_atomic_uapi.c
index 434f3d4cb8a2..ee78f4f5976d 100644
--- a/drivers/gpu/drm/drm_atomic_uapi.c
+++ b/drivers/gpu/drm/drm_atomic_uapi.c
@@ -429,6 +429,14 @@ static int drm_atomic_crtc_set_property(struct drm_crtc 
*crtc,
);
state->color_mgmt_changed |= replaced;
return ret;
+   } else if (property == config->shaper_lut_property) {
+   ret = drm_atomic_replace_property_blob_from_id(dev,
+   >shaper_lut,
+   val,
+   -1, sizeof(struct drm_color_lut),
+   );
+   state->color_mgmt_changed |= replaced;
+   return ret;
} else if (property == config->gamma_lut_property) {
ret = drm_atomic_replace_property_blob_from_id(dev,
>gamma_lut,
@@ -480,6 +488,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->shaper_lut_property)
+   *val = (state->shaper_lut) ? state->shaper_lut->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)
diff --git a/drivers/gpu/drm/drm_color_mgmt.c b/drivers/gpu/drm/drm_color_mgmt.c
index 17c6c3eefcd6..873cca35f078 100644
--- a/drivers/gpu/drm/drm_color_mgmt.c
+++ b/drivers/gpu/drm/drm_color_mgmt.c
@@ -69,6 +69,24 @@
  * boot-up state too. Drivers can access the blob for the color conversion
  * matrix through _crtc_state.ctm.
  *
+ * “SHAPER_LUT”:
+ * Blob property to set the shaper lut shaping pixel data after the color
+ * transformation matrix and before applying 3D Lookup Table (3D LUT). It
+ * can be used to delinearize content to get an effective 3D LUT mapping.
+ * The data is interpreted as an array of  drm_color_lut elements.
+ *
+ * Setting this to NULL (blob property value set to 0) means the output
+ * color is identical to the input color. This is generally the driver
+ * boot-up state too. Drivers can access this blob through
+ * _crtc_state.gamma_lut.
+ *
+ * “SHAPER_LUT_SIZE”:
+ * Unsigned range property to give the size of the shaper lookup table to
+ * be set on the SHAPER_LUT property (the size depends on the underlying
+ * hardware). If drivers support multiple LUT sizes then they should
+ * publish the largest size, and sub-sample smaller sized LUTs
+ * appropriately.
+ *
  * “GAMMA_LUT”:
  * Blob property to set the gamma lookup table (LUT) mapping pixel data
  * after the transformation matrix to data sent to the co

[RFC PATCH v2 4/9] drm/drm_color_mgmt: add 3D LUT to color mgmt properties

2022-09-06 Thread Melissa Wen
Add 3D LUT for gammar correction using a 3D lookup table. The position
in the color correction pipeline where 3D LUT is applied depends on hw
design, being after CTM or gamma. If just after CTM, a shaper lut must
be set to shape the content for a non-linear space. That details should
be handled by the driver according to its color capabilities.

Signed-off-by: Melissa Wen 
---
 drivers/gpu/drm/drm_atomic_state_helper.c |  3 ++
 drivers/gpu/drm/drm_atomic_uapi.c | 10 
 drivers/gpu/drm/drm_color_mgmt.c  | 58 +++
 drivers/gpu/drm/drm_fb_helper.c   |  2 +
 drivers/gpu/drm/drm_mode_config.c | 14 ++
 include/drm/drm_color_mgmt.h  |  4 ++
 include/drm/drm_crtc.h| 12 -
 include/drm/drm_mode_config.h | 13 +
 8 files changed, 115 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/drm_atomic_state_helper.c 
b/drivers/gpu/drm/drm_atomic_state_helper.c
index bf3222fbf4bb..cad579c66248 100644
--- a/drivers/gpu/drm/drm_atomic_state_helper.c
+++ b/drivers/gpu/drm/drm_atomic_state_helper.c
@@ -141,6 +141,8 @@ void __drm_atomic_helper_crtc_duplicate_state(struct 
drm_crtc *crtc,
drm_property_blob_get(state->ctm);
if (state->shaper_lut)
drm_property_blob_get(state->shaper_lut);
+   if (state->lut3d)
+   drm_property_blob_get(state->lut3d);
if (state->gamma_lut)
drm_property_blob_get(state->gamma_lut);
 
@@ -216,6 +218,7 @@ void __drm_atomic_helper_crtc_destroy_state(struct 
drm_crtc_state *state)
drm_property_blob_put(state->degamma_lut);
drm_property_blob_put(state->ctm);
drm_property_blob_put(state->shaper_lut);
+   drm_property_blob_put(state->lut3d);
drm_property_blob_put(state->gamma_lut);
 }
 EXPORT_SYMBOL(__drm_atomic_helper_crtc_destroy_state);
diff --git a/drivers/gpu/drm/drm_atomic_uapi.c 
b/drivers/gpu/drm/drm_atomic_uapi.c
index ee78f4f5976d..041b00faebe9 100644
--- a/drivers/gpu/drm/drm_atomic_uapi.c
+++ b/drivers/gpu/drm/drm_atomic_uapi.c
@@ -437,6 +437,14 @@ static int drm_atomic_crtc_set_property(struct drm_crtc 
*crtc,
);
state->color_mgmt_changed |= replaced;
return ret;
+   } else if (property == config->lut3d_property) {
+   ret = drm_atomic_replace_property_blob_from_id(dev,
+   >lut3d,
+   val,
+   -1, sizeof(struct drm_color_lut),
+   );
+   state->color_mgmt_changed |= replaced;
+   return ret;
} else if (property == config->gamma_lut_property) {
ret = drm_atomic_replace_property_blob_from_id(dev,
>gamma_lut,
@@ -490,6 +498,8 @@ drm_atomic_crtc_get_property(struct drm_crtc *crtc,
*val = (state->ctm) ? state->ctm->base.id : 0;
else if (property == config->shaper_lut_property)
*val = (state->shaper_lut) ? state->shaper_lut->base.id : 0;
+   else if (property == config->lut3d_property)
+   *val = (state->lut3d) ? state->lut3d->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)
diff --git a/drivers/gpu/drm/drm_color_mgmt.c b/drivers/gpu/drm/drm_color_mgmt.c
index 873cca35f078..a87bfb866bcb 100644
--- a/drivers/gpu/drm/drm_color_mgmt.c
+++ b/drivers/gpu/drm/drm_color_mgmt.c
@@ -87,6 +87,25 @@
  * publish the largest size, and sub-sample smaller sized LUTs
  * appropriately.
  *
+ * “LUT3D”:
+ * Blob property to set the 3D LUT mapping pixel data after the color
+ * transformation matrix and before gamma 1D lut correction. The
+ * data is interpreted as an array of  drm_color_lut elements.
+ * Hardware might choose not to use the full precision of the LUT
+ * elements.
+ *
+ * Setting this to NULL (blob property value set to 0) means a the output
+ * color is identical to the input color. This is generally the driver
+ * boot-up state too. Drivers can access this blob through
+ * _crtc_state.gamma_lut.
+ *
+ * “LUT3D_SIZE”:
+ * Unsigned range property to give the size of the 3D lookup table to be
+ * set on the LUT3D property (the size depends on the underlying
+ * hardware). If drivers support multiple LUT sizes then they should
+ * publish the largest size, and sub-sample smaller sized LUTs
+ * appropriately.
+ *
  * “GAMMA_LUT”:
  * Blob property to set the gamma lookup table (LUT) mapping pixel data
  * after the transformation matrix to data sent to the connec

[RFC PATCH v2 2/9] drm/amd/display: add comments to describe DM crtc color mgmt behavior

2022-09-06 Thread Melissa Wen
Describe some expected behavior of the AMD DM color mgmt programming.

Signed-off-by: Melissa Wen 
---
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c | 13 -
 1 file changed, 12 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
index 10a29d131424..b54ef1392895 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
@@ -428,12 +428,23 @@ int amdgpu_dm_update_crtc_color_mgmt(struct dm_crtc_state 
*crtc)
stream->out_transfer_func->type = TF_TYPE_DISTRIBUTED_POINTS;
stream->out_transfer_func->tf = TRANSFER_FUNCTION_SRGB;
 
+   /* Note: even if we pass has_rom as parameter here, we never
+* actually use ROM because the color module only takes the ROM
+* path if transfer_func->type == PREDEFINED.
+*
+* See more in mod_color_calculate_regamma_params()
+*/
r = __set_legacy_tf(stream->out_transfer_func, regamma_lut,
regamma_size, has_rom);
if (r)
return r;
} else if (has_regamma) {
-   /* If atomic regamma, CRTC RGM goes into RGM LUT. */
+   /* CRTC RGM goes into RGM LUT.
+*
+* Note: here there is no implicit sRGB regamma. We are using
+* degamma calculation from color module to calculate the curve
+* from a linear base.
+*/
stream->out_transfer_func->type = TF_TYPE_DISTRIBUTED_POINTS;
stream->out_transfer_func->tf = TRANSFER_FUNCTION_LINEAR;
 
-- 
2.35.1



[RFC PATCH v2 1/9] drm/amd/display: remove unused regamma condition

2022-09-06 Thread Melissa Wen
The function __set_output_tf is only called by
amdgpu_dm_update_crtc_color_mgmt() when using atomic regamma. In this
situation, func->tf == TRANSFER_FUNCTION_LINEAR (the original if
condition) and it never falls into tf != LINEAR (the else condition).
Therefore, remove unused condition to avoid misunderstandings here.

Signed-off-by: Melissa Wen 
---
 .../amd/display/amdgpu_dm/amdgpu_dm_color.c   | 32 ++-
 1 file changed, 10 insertions(+), 22 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
index a4cb23d059bd..10a29d131424 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
@@ -255,14 +255,13 @@ static int __set_legacy_tf(struct dc_transfer_func *func,
  * @func: transfer function
  * @lut: lookup table that defines the color space
  * @lut_size: size of respective lut
- * @has_rom: if ROM can be used for hardcoded curve
  *
  * Returns:
  * 0 in case of success. -ENOMEM if fails.
  */
 static int __set_output_tf(struct dc_transfer_func *func,
-  const struct drm_color_lut *lut, uint32_t lut_size,
-  bool has_rom)
+  const struct drm_color_lut *lut,
+  uint32_t lut_size)
 {
struct dc_gamma *gamma = NULL;
struct calculate_buffer cal_buffer = {0};
@@ -279,24 +278,13 @@ static int __set_output_tf(struct dc_transfer_func *func,
gamma->num_entries = lut_size;
__drm_lut_to_dc_gamma(lut, gamma, false);
 
-   if (func->tf == TRANSFER_FUNCTION_LINEAR) {
-   /*
-* Color module doesn't like calculating regamma params
-* on top of a linear input. But degamma params can be used
-* instead to simulate this.
-*/
-   gamma->type = GAMMA_CUSTOM;
-   res = mod_color_calculate_degamma_params(NULL, func,
-   gamma, true);
-   } else {
-   /*
-* Assume sRGB. The actual mapping will depend on whether the
-* input was legacy or not.
-*/
-   gamma->type = GAMMA_CS_TFM_1D;
-   res = mod_color_calculate_regamma_params(func, gamma, false,
-has_rom, NULL, 
_buffer);
-   }
+   /*
+* Color module doesn't like calculating regamma params
+* on top of a linear input. But degamma params can be used
+* instead to simulate this.
+*/
+   gamma->type = GAMMA_CUSTOM;
+   res = mod_color_calculate_degamma_params(NULL, func, gamma, true);
 
dc_gamma_release();
 
@@ -450,7 +438,7 @@ int amdgpu_dm_update_crtc_color_mgmt(struct dm_crtc_state 
*crtc)
stream->out_transfer_func->tf = TRANSFER_FUNCTION_LINEAR;
 
r = __set_output_tf(stream->out_transfer_func, regamma_lut,
-   regamma_size, has_rom);
+   regamma_size);
if (r)
return r;
} else {
-- 
2.35.1



[RFC PATCH v2 0/9] Enable 3D LUT to AMD display drivers

2022-09-06 Thread Melissa Wen
Hi,

>From all feedback at [3DLUT_RFC] and an extensive AMD driver
examination, here I am back with a first attempt to wire up a user 3D
LUT (post-blending) to DC interface via DM CRTC color mgmt :)

I'm following some specific approaches to handle user shaper LUT and
user 3D LUT that I would like to validate if the path taken is correct.

I used a modified version [igt_tests] of Ville's IGT 3D LUT test to
verify that the shaper and 3D LUT programming is happening. However, I
still have doubts about hw behavior and DC MPC's current implementation
for 3D LUT.

Despite some initial patches for code cleanup and DRM interface, my
focus here is the inclusion of a user 3D LUT in the Display Manager,
which is done in the last five patches of this series:

- drm/amd/display: enable DRM shaper and 3D LUT properties
- drm/amd/display: update lut3d and shaper lut to stream
- drm/amd/display: add user shaper LUT support to amdgpu_dm color pipeline
- drm/amd/display: add user 3D LUT support to the amdgpu_dm color pipeline
- drm/amd/display: encapsulate atomic regamma operation

Things to take into account:

- 3D LUT (and shaper LUT) is only available in the atomic pipeline (I
  didn't work on any implicit conversions that are done in the legacy
  path)

- Therefore, I'm not doing any implicit conversions for shaper LUT
  considering the input space, which means: it's set or not. When there
  is no shaper LUT, it's set to BYPASS, but unfortunately, it seems that
  the BYPASS mode for shaper LUT is not supported in the current DC
  dcn30_set_mpc_shaper_3dlut(), since it returns false when
  mpc3_program_shaper returns false (no params). Is the combination of a
  user 3D LUT with a bypassed shaper LUT accepted by the hw?

- I also see in dcn30_set_mpc_shaper_3dlut() that some bits need to be
  set in lut3d_func to have the 3D LUT programmed on the MPC block. In
  this sense, I used the dc_acquire_release_mpc_3dlut() function to get
  the lut3d_func from the resource pool, but I'm not sure if the timing to
  acquire and release the lut3d_func from the resource pool is correct
  (and if I can really use it directly or I should make a copy).

- Still, on this topic, I use for lut3d the same bit.out_tf to update
  the stream in the commit_tail because it triggers
  .set_output_transfer_func that is in charge of setting both OGAM and 3D
  LUT on MPC. There is a chance I got it wrong here, so I appreciate any
  input on this topic.

- Finally, in set_output_transfer_func, AFAIU, even if a user OGAM is
  set, it won't be programmed if the shaper LUT and 3D LUT programming
  are successful. However, if shaper/3DLUT programming fails, OGAM can be
  considered. Should DM only accept DRM regamma if no DRM 3D LUT is
  passed, or allowing the programming of both is still desirable?

Regarding the other patches:

- drm/drm_color_mgmt: add 3D LUT to color mgmt properties
- drm/drm_color_mgmt: add shaper LUT to color mgmt properties

Here, an initial DRM 3D LUT interface is exposed to enable the entire
kernel path and is only available for the atomic pipeline. So far, it
only includes the LUT data and its size, but improvements on this
interface may also add stride and bit depth [VA_API].
Additionally, I'm aware of the current work on exposing a color pipeline
API [KMS_pipe_API].

I'm including some minor changes in this series that I made to better
understand the current DM color mgmt behavior:

- drm/amd/display: add comments to describe DM crtc color mgmt behavior
- drm/amd/display: remove unused regamma condition

...but, there are other code cleanup patches that I'm not including in
this series to avoid unnecessary noise.

You can check the entire work here:
https://gitlab.freedesktop.org/mwen/linux-amd/-/commits/drm_lut3d

[igt_tests] IGT exploratory tests here:
https://gitlab.freedesktop.org/mwen/igt-gpu-tools/-/commits/kms_color_3dlut

[3DLUT_RFC] 
https://lore.kernel.org/amd-gfx/20220619223104.667413-1-m...@igalia.com/
[VA_API] 
http://intel.github.io/libva/structVAProcFilterParameterBuffer3DLUT.html
[KMS_pipe_API] https://gitlab.freedesktop.org/pq/color-and-hdr/-/issues/11

Let me know your thoughts.

Thanks in advance,

Melissa

Melissa Wen (9):
  drm/amd/display: remove unused regamma condition
  drm/amd/display: add comments to describe DM crtc color mgmt behavior
  drm/drm_color_mgmt: add shaper LUT to color mgmt properties
  drm/drm_color_mgmt: add 3D LUT to color mgmt properties
  drm/amd/display: encapsulate atomic regamma operation
  drm/amd/display: add user 3D LUT support to the amdgpu_dm color
pipeline
  drm/amd/display: add user shaper LUT support to amdgpu_dm color
pipeline
  drm/amd/display: update lut3d and shaper lut to stream
  drm/amd/display: enable DRM shaper and 3D LUT properties

 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c |   6 +
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h |   5 +
 .../amd/display/amdgpu_dm/amdgpu_dm_color.c   | 297 --
 .../amd/display/amdgpu

Re: [PATCH 0/4] Add support for atomic async page-flips

2022-08-25 Thread Melissa Wen
On 08/24, Simon Ser wrote:
> This series adds support for DRM_MODE_PAGE_FLIP_ASYNC for atomic
> commits, aka. "immediate flip" (which might result in tearing).
> The feature was only available via the legacy uAPI, however for
> gaming use-cases it may be desirable to enable it via the atomic
> uAPI too.

Hi Simon,

I'm cc'ing André as he has been actively working on it lately and must
be quite familiar with the async flip machinery.

> 
> User-space patch:
> https://github.com/Plagman/gamescope/pull/595
> 
> IGT patch:
> https://patchwork.freedesktop.org/series/107681/

Also, André recently generalized the kms_async_flip to test drivers
other than i915, so I think he can provide some thoughts about the IGT
test too.

Thanks,

Melissa

> 
> Tested on an AMD Picasso iGPU.
> 
> Simon Ser (4):
>   drm: introduce drm_mode_config.atomic_async_page_flip_not_supported
>   drm: allow DRM_MODE_PAGE_FLIP_ASYNC for atomic commits
>   drm: introduce DRM_CAP_ATOMIC_ASYNC_PAGE_FLIP
>   amd/display: indicate support for atomic async page-flips on DCN
> 
>  drivers/gpu/drm/amd/amdgpu/dce_v10_0.c   |  1 +
>  drivers/gpu/drm/amd/amdgpu/dce_v11_0.c   |  1 +
>  drivers/gpu/drm/amd/amdgpu/dce_v6_0.c|  1 +
>  drivers/gpu/drm/amd/amdgpu/dce_v8_0.c|  1 +
>  drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.c |  1 +
>  drivers/gpu/drm/drm_atomic_uapi.c| 28 +---
>  drivers/gpu/drm/drm_ioctl.c  |  5 
>  drivers/gpu/drm/i915/display/intel_display.c |  1 +
>  drivers/gpu/drm/nouveau/nouveau_display.c|  1 +
>  drivers/gpu/drm/radeon/radeon_display.c  |  1 +
>  drivers/gpu/drm/vc4/vc4_kms.c|  1 +
>  include/drm/drm_mode_config.h| 11 
>  include/uapi/drm/drm.h   | 10 ++-
>  13 files changed, 59 insertions(+), 4 deletions(-)
> 
> -- 
> 2.37.2
> 
> 


signature.asc
Description: PGP signature


Re: [BUG][5.20] refcount_t: underflow; use-after-free

2022-08-24 Thread Melissa Wen
On 08/17, Mikhail Gavrilov wrote:
> On Mon, Aug 15, 2022 at 3:37 PM Mikhail Gavrilov
>  wrote:
> >
> > Thanks, I tested this patch.
> > But with this patch use-after-free problem happening in another place:
> 
> Does anyone have an idea why the second use-after-free happened?
> From the trace I don't understand which code is related.
> I don't quite understand what the "Workqueue" entry in the trace means.

Hi Mikhail,

IIUC, you got this second user-after-free by applying the first version
of Maíra's patch, right? So, that version was adding another unbalanced
unlock to the cs ioctl flow, but it was solved in the latest version,
that you can find here: https://patchwork.freedesktop.org/patch/497680/
If this is the situation, can you check this last version?

Thanks,

Melissa

> 
> [ 408.358737] [ cut here ]
> [ 408.358743] refcount_t: underflow; use-after-free.
> [ 408.358760] WARNING: CPU: 9 PID: 62 at lib/refcount.c:28
> refcount_warn_saturate+0xba/0x110
> [ 408.358769] Modules linked in: uinput snd_seq_dummy rfcomm
> snd_hrtimer nft_objref nf_conntrack_netbios_ns nf_conntrack_broadcast
> nft_fib_inet nft_fib_ipv4 nft_fib_ipv6 nft_fib nft_reject_inet
> nf_reject_ipv4 nf_reject_ipv6 nft_reject nft_ct nft_chain_nat nf_nat
> nf_conntrack nf_defrag_ipv6 nf_defrag_ipv4 ip_set nf_tables nfnetlink
> qrtr bnep sunrpc binfmt_misc snd_seq_midi snd_seq_midi_event mt76x2u
> mt76x2_common snd_hda_codec_realtek mt76x02_usb snd_hda_codec_generic
> iwlmvm snd_hda_codec_hdmi mt76_usb intel_rapl_msr snd_hda_intel
> mt76x02_lib intel_rapl_common snd_intel_dspcfg snd_intel_sdw_acpi mt76
> snd_hda_codec vfat fat snd_usb_audio snd_hda_core edac_mce_amd
> mac80211 snd_usbmidi_lib snd_hwdep snd_rawmidi mc snd_seq btusb
> kvm_amd iwlwifi snd_seq_device btrtl btbcm libarc4 btintel eeepc_wmi
> snd_pcm iwlmei kvm btmtk asus_wmi ledtrig_audio irqbypass joydev
> snd_timer sparse_keymap bluetooth platform_profile rapl cfg80211 snd
> video wmi_bmof soundcore i2c_piix4 k10temp rfkill mei
> [ 408.358853] asus_ec_sensors acpi_cpufreq zram hid_logitech_hidpp
> amdgpu igb dca drm_ttm_helper ttm iommu_v2 crct10dif_pclmul gpu_sched
> crc32_pclmul ucsi_ccg crc32c_intel drm_buddy nvme typec_ucsi
> drm_display_helper ghash_clmulni_intel ccp typec nvme_core sp5100_tco
> cec wmi ip6_tables ip_tables fuse
> [ 408.358880] Unloaded tainted modules: amd64_edac():1 amd64_edac():1
> amd64_edac():1 amd64_edac():1 amd64_edac():1 amd64_edac():1
> amd64_edac():1 amd64_edac():1 amd64_edac():1 amd64_edac():1
> pcc_cpufreq():1 amd64_edac():1 pcc_cpufreq():1 pcc_cpufreq():1
> amd64_edac():1 amd64_edac():1 pcc_cpufreq():1 amd64_edac():1
> pcc_cpufreq():1 amd64_edac():1 pcc_cpufreq():1 amd64_edac():1
> pcc_cpufreq():1 pcc_cpufreq():1 amd64_edac():1 pcc_cpufreq():1
> amd64_edac():1 pcc_cpufreq():1 amd64_edac():1 pcc_cpufreq():1
> pcc_cpufreq():1 amd64_edac():1 amd64_edac():1 pcc_cpufreq():1
> pcc_cpufreq():1 amd64_edac():1 pcc_cpufreq():1 amd64_edac():1
> pcc_cpufreq():1 amd64_edac():1 pcc_cpufreq():1 pcc_cpufreq():1
> amd64_edac():1 pcc_cpufreq():1 amd64_edac():1 pcc_cpufreq():1
> amd64_edac():1 pcc_cpufreq():1 pcc_cpufreq():1 amd64_edac():1
> pcc_cpufreq():1 amd64_edac():1 amd64_edac():1 pcc_cpufreq():1
> amd64_edac():1 pcc_cpufreq():1 amd64_edac():1 pcc_cpufreq():1
> pcc_cpufreq():1 pcc_cpufreq():1 fjes():1 pcc_cpufreq():1 fjes():1
> [ 408.358953] pcc_cpufreq():1 pcc_cpufreq():1 fjes():1 pcc_cpufreq():1
> fjes():1 fjes():1 fjes():1 fjes():1 fjes():1
> [ 408.358967] CPU: 9 PID: 62 Comm: kworker/9:0 Tainted: G W L ---
> --- 6.0.0-0.rc1.13.fc38.x86_64+debug #1
> [ 408.358971] Hardware name: System manufacturer System Product
> Name/ROG STRIX X570-I GAMING, BIOS 4403 04/27/2022
> [ 408.358974] Workqueue: events drm_sched_entity_kill_jobs_work [gpu_sched]
> [ 408.358982] RIP: 0010:refcount_warn_saturate+0xba/0x110
> [ 408.358987] Code: 01 01 e8 d9 59 6f 00 0f 0b e9 a2 46 a5 00 80 3d 3e
> 7e be 01 00 75 85 48 c7 c7 70 99 8e 92 c6 05 2e 7e be 01 01 e8 b6 59
> 6f 00 <0f> 0b e9 7f 46 a5 00 80 3d 19 7e be 01 00 0f 85 5e ff ff ff 48
> c7
> [ 408.358990] RSP: 0018:b124003efe60 EFLAGS: 00010286
> [ 408.358994] RAX: 0026 RBX: 9987a025d428 RCX: 
> 
> [ 408.358997] RDX: 0001 RSI: 928d0754 RDI: 
> 
> [ 408.358999] RBP: 9994e4ff5600 R08:  R09: 
> b124003efd10
> [ 408.359001] R10: 0003 R11: 99952e2fffe8 R12: 
> 9994e4ffc800
> [ 408.359004] R13: 998600228cc0 R14: 9994e4ffc805 R15: 
> 9987a025d430
> [ 408.359006] FS: () GS:9994e4e0()
> knlGS:
> [ 408.359009] CS: 0010 DS:  ES:  CR0: 80050033
> [ 408.359012] CR2: 27ac39e78000 CR3: 0001a66d8000 CR4: 
> 00350ee0
> [ 408.359015] Call Trace:
> [ 408.359017] 
> [ 408.359020] process_one_work+0x2a0/0x600
> [ 408.359032] worker_thread+0x4f/0x3a0
> [ 408.359036] ? process_one_work+0x600/0x600
> [ 408.359039] 

Re: [PATCH] drm/amdgpu: Fix use-after-free on amdgpu_bo_list mutex

2022-08-24 Thread Melissa Wen
mdgpu_cs.c
> index d8f1335bc68f..b7bae833c804 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
> @@ -837,16 +837,12 @@ static int amdgpu_cs_vm_handling(struct 
> amdgpu_cs_parser *p)
>   continue;
>  
>   r = amdgpu_vm_bo_update(adev, bo_va, false);
> - if (r) {
> - mutex_unlock(>bo_list->bo_list_mutex);
> + if (r)
>   return r;
> - }
>  
>   r = amdgpu_sync_fence(>job->sync, bo_va->last_pt_update);
> - if (r) {
> - mutex_unlock(>bo_list->bo_list_mutex);
> + if (r)
>   return r;
> - }
Nice catch, Maíra!

Reviewed-by: Melissa Wen 

>   }
>  
>   r = amdgpu_vm_handle_moved(adev, vm);
> -- 
> 2.37.2
> 


signature.asc
Description: PGP signature


Re: [BUG][5.20] refcount_t: underflow; use-after-free

2022-08-15 Thread Melissa Wen
On 08/14, Maíra Canal wrote:
> Hi Mikhail
> 
> Looks like this use-after-free problem was introduced on
> 90af0ca047f3049c4b46e902f432ad6ef1e2ded6. Checking this patch it seems
> like: if amdgpu_cs_vm_handling return r != 0, then it will unlock
> bo_list_mutex inside the function amdgpu_cs_vm_handling and again on
> amdgpu_cs_parser_fini.
> 
> Maybe the following patch will help:
> 
> ---
> From 71d718c0f53a334bb59bcd5dabd29bbe92c724af Mon Sep 17 00:00:00 2001
> From: =?UTF-8?q?Ma=C3=ADra=20Canal?= 
> Date: Sun, 14 Aug 2022 21:12:24 -0300
> Subject: [PATCH] drm/amdgpu: Fix use-after-free on amdgpu_bo_list mutex
> MIME-Version: 1.0
> Content-Type: text/plain; charset=UTF-8
> Content-Transfer-Encoding: 8bit
> 
> Fixes: 90af0ca047f3 ("drm/amdgpu: Protect the amdgpu_bo_list list with a
> mutex v2")
> Reported-by: Mikhail Gavrilov 
> Signed-off-by: Maíra Canal 
> ---
>  drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c | 9 +++--
>  1 file changed, 3 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
> b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
> index d8f1335bc68f..a7fce7b14321 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
> @@ -837,17 +837,14 @@ static int amdgpu_cs_vm_handling(struct
> amdgpu_cs_parser *p)
>   continue;
> 
>   r = amdgpu_vm_bo_update(adev, bo_va, false);
> - if (r) {
> - mutex_unlock(>bo_list->bo_list_mutex);
> + if (r)
>   return r;
> - }
> 
>   r = amdgpu_sync_fence(>job->sync, bo_va->last_pt_update);
> - if (r) {
> - mutex_unlock(>bo_list->bo_list_mutex);
> + if (r)
>   return r;
> - }
>   }
> + mutex_unlock(>bo_list->bo_list_mutex);

I think we don't need to unlock the bo_list_mutex here. If return != 0
amdgpu_cs_parser_fini() will unlock it; otherwise, amdgpu_cs_submit()
unlocks it in the end.

BR,

Melissa
> 
>   r = amdgpu_vm_handle_moved(adev, vm);
>   if (r)
> -- 
> 2.37.1
> ---
> Best Regards,
> - Maíra Canal
> 
> On 8/14/22 18:11, Mikhail Gavrilov wrote:
> > Hi folks.
> > Joined testing 5.20 today (7ebfc85e2cd7).
> > I encountered a frequently GPU freeze, after which a message appears
> > in the kernel logs:
> > [ 220.280990] [ cut here ]
> > [ 220.281000] refcount_t: underflow; use-after-free.
> > [ 220.281019] WARNING: CPU: 1 PID: 3746 at lib/refcount.c:28
> > refcount_warn_saturate+0xba/0x110
> > [ 220.281029] Modules linked in: uinput rfcomm snd_seq_dummy
> > snd_hrtimer nft_objref nf_conntrack_netbios_ns nf_conntrack_broadcast
> > nft_fib_inet nft_fib_ipv4 nft_fib_ipv6 nft_fib nft_reject_inet
> > nf_reject_ipv4 nf_reject_ipv6 nft_reject nft_ct nft_chain_nat nf_nat
> > nf_conntrack nf_defrag_ipv6 nf_defrag_ipv4 ip_set nf_tables nfnetlink
> > qrtr bnep sunrpc snd_seq_midi snd_seq_midi_event vfat intel_rapl_msr
> > fat intel_rapl_common snd_hda_codec_realtek mt76x2u
> > snd_hda_codec_generic snd_hda_codec_hdmi mt76x2_common iwlmvm
> > mt76x02_usb edac_mce_amd mt76_usb snd_hda_intel snd_intel_dspcfg
> > mt76x02_lib snd_intel_sdw_acpi snd_usb_audio snd_hda_codec mt76
> > kvm_amd uvcvideo mac80211 snd_hda_core btusb eeepc_wmi snd_usbmidi_lib
> > videobuf2_vmalloc videobuf2_memops kvm btrtl snd_rawmidi asus_wmi
> > snd_hwdep videobuf2_v4l2 btbcm iwlwifi ledtrig_audio libarc4 btintel
> > snd_seq videobuf2_common sparse_keymap btmtk irqbypass videodev
> > snd_seq_device joydev xpad iwlmei platform_profile bluetooth
> > ff_memless snd_pcm mc rapl
> > [ 220.281185] video snd_timer cfg80211 wmi_bmof snd pcspkr soundcore
> > k10temp i2c_piix4 rfkill mei asus_ec_sensors acpi_cpufreq zram
> > hid_logitech_hidpp amdgpu igb dca drm_ttm_helper ttm crct10dif_pclmul
> > iommu_v2 crc32_pclmul gpu_sched crc32c_intel ucsi_ccg drm_buddy nvme
> > typec_ucsi ghash_clmulni_intel drm_display_helper ccp nvme_core typec
> > sp5100_tco cec wmi ip6_tables ip_tables fuse
> > [ 220.281258] Unloaded tainted modules: amd64_edac():1 amd64_edac():1
> > amd64_edac():1 amd64_edac():1 amd64_edac():1 amd64_edac():1
> > amd64_edac():1 amd64_edac():1 amd64_edac():1 pcc_cpufreq():1
> > amd64_edac():1 pcc_cpufreq():1 pcc_cpufreq():1 amd64_edac():1
> > pcc_cpufreq():1 amd64_edac():1 amd64_edac():1 pcc_cpufreq():1
> > amd64_edac():1 pcc_cpufreq():1 pcc_cpufreq():1 amd64_edac():1
> > pcc_cpufreq():1 pcc_cpufreq():1 amd64_edac():1 pcc_cpufreq():1
> > pcc_cpufreq():1 amd64_edac():1 pcc_cpufreq():1 amd64_edac():1
> > pcc_cpufreq():1 pcc_cpufreq():1 amd64_edac():1 amd64_edac():1
> > pcc_cpufreq():1 pcc_cpufreq():1 amd64_edac():1 amd64_edac():1
> > pcc_cpufreq():1 pcc_cpufreq():1 amd64_edac():1 amd64_edac():1
> > pcc_cpufreq():1 amd64_edac():1 pcc_cpufreq():1 pcc_cpufreq():1
> > amd64_edac():1 pcc_cpufreq():1 amd64_edac():1 amd64_edac():1
> > pcc_cpufreq():1 amd64_edac():1 pcc_cpufreq():1 amd64_edac():1
> > 

Re: [PATCH] drm/amd/display: set panel orientation before drm_dev_register

2022-08-08 Thread Melissa Wen
On 08/05, Simon Ser wrote:
> Hi,
> 
> Have you seen [1] and [2]? CC'ing Sean and Hans, it seems like there's
> a disagreement regarding probing early vs. setting the initial value to
> UNKNOWN.
> 
> If a driver doesn't fetch EDIDs before exposing them to user-space,
> then there is an amount of time where the connectors are exposed as
> CONNECTED but their EDID and mode list isn't properly set. But maybe
> that's what the GETCONNECTOR IOCTLs is supposed to do: probe the
> connector, fetch its EDID, return the proper mode list. So maybe
> drivers shouldn't probe early and should let user-space request probes?
> In which case we could create the panel orientation prop with "Normal",
> and update it accordingly when probing. 

Hi Simon,

I've followed these discussions but AFAIU the AMD display issue is not
exactly the same discussed in other drivers because here we are already
able to read EDID and get mode size needed for a quirk orientation
before drm device registration. So, I understand there isn't the need of
setting an initial value to the immutable property and update it later
(and all the issues this later update might cause). Am I missing
something?

> 
> At any rate, I've tested v2 on the Deck and it works properly.
> 
> Tested-by: Simon Ser 

Thanks for testing it!

Best regards,

Melissa

> 
> Thanks,
> 
> Simon
> 
> [1]: 
> https://lore.kernel.org/dri-devel/CAMavQKJUpYP8jo2JDGMYNBGtbPSSO7z9BAComm5JQoty=hp...@mail.gmail.com/
> [2]: 
> https://lore.kernel.org/dri-devel/20220530081910.3947168-1-hsi...@chromium.org/


signature.asc
Description: PGP signature


Re: [PATCH v2] drm/amd/display: set panel orientation before drm_dev_register

2022-08-08 Thread Melissa Wen
On 08/04, Melissa Wen wrote:
> To set the panel orientation property with quirk, we need the mode size
> provided by EDID. This info is available after EDID is read by 
> dc_link_detect()
> and updated by amdgpu_dm_update_connector_after_detect(). The detection
> happens at driver load in amdgpu_dm_initialize_drm_device() and,
> therefore, we can get modes and set panel orientation before
> drm_dev_register() to avoid DRM warns on creating the connector property
> after device registration:

+ Simon, Hans and Sean

> 
> [2.563969] [ cut here ]
> [2.563971] WARNING: CPU: 6 PID: 325 at 
> drivers/gpu/drm/drm_mode_object.c:45 drm_mode_object_add+0x72/0x80 [drm]
> [2.563997] Modules linked in: btusb btrtl btbcm btintel btmtk bluetooth 
> rfkill ecdh_generic ecc usbhid crc16 amdgpu(+) drm_ttm_helper ttm agpgart 
> gpu_sched i2c_algo_bit drm_display_helper drm_kms_helper syscopyarea 
> sysfillrect sysimgblt fb_sys_fops drm serio_raw sdhci_pci atkbd libps2 cqhci 
> vivaldi_fmap ccp sdhci i8042 crct10dif_pclmul crc32_pclmul hid_multitouch 
> ghash_clmulni_intel aesni_intel crypto_simd cryptd wdat_wdt mmc_core cec 
> xhci_pci sp5100_tco rng_core xhci_pci_renesas serio 8250_dw i2c_hid_acpi 
> i2c_hid btrfs blake2b_generic libcrc32c crc32c_generic crc32c_intel xor 
> raid6_pq dm_mirror dm_region_hash dm_log dm_mod pkcs8_key_parser crypto_user
> [2.564032] CPU: 6 PID: 325 Comm: systemd-udevd Not tainted 
> 5.18.0-amd-staging-drm-next+ #67
> [2.564034] Hardware name: Valve Jupiter/Jupiter, BIOS F7A0105 03/21/2022
> [2.564036] RIP: 0010:drm_mode_object_add+0x72/0x80 [drm]
> [2.564053] Code: f0 89 c3 85 c0 78 07 89 45 00 44 89 65 04 4c 89 ef e8 e2 
> 99 04 f1 31 c0 85 db 0f 4e c3 5b 5d 41 5c 41 5d c3 80 7f 50 00 74 ac <0f> 0b 
> eb a8 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 44 00 00 41 54 4c
> [2.564055] RSP: 0018:b2e880413860 EFLAGS: 00010202
> [2.564056] RAX: c0ba1440 RBX: 99508a860010 RCX: 
> 0001
> [2.564057] RDX: b0b0b0b0 RSI: 99508c050110 RDI: 
> 99508a860010
> [2.564058] RBP: 99508c050110 R08: 0020 R09: 
> 99508c292c20
> [2.564059] R10:  R11: 99508c0507d8 R12: 
> b0b0b0b0
> [2.564060] R13: 0004 R14: c068a4b6 R15: 
> c068a47f
> [2.564061] FS:  7fc69b5f1a40() GS:9953aff8() 
> knlGS:
> [2.564063] CS:  0010 DS:  ES:  CR0: 80050033
> [2.564063] CR2: 7f9506804000 CR3: 000107f92000 CR4: 
> 00350ee0
> [2.564065] Call Trace:
> [2.564068]  
> [2.564070]  drm_property_create+0xc9/0x170 [drm]
> [2.564088]  drm_property_create_enum+0x1f/0x70 [drm]
> [2.564105]  drm_connector_set_panel_orientation_with_quirk+0x96/0xc0 [drm]
> [2.564123]  get_modes+0x4fb/0x530 [amdgpu]
> [2.564378]  drm_helper_probe_single_connector_modes+0x1ad/0x850 
> [drm_kms_helper]
> [2.564390]  drm_client_modeset_probe+0x229/0x1400 [drm]
> [2.564411]  ? xas_store+0x52/0x5e0
> [2.564416]  ? kmem_cache_alloc_trace+0x177/0x2c0
> [2.564420]  __drm_fb_helper_initial_config_and_unlock+0x44/0x4e0 
> [drm_kms_helper]
> [2.564430]  drm_fbdev_client_hotplug+0x173/0x210 [drm_kms_helper]
> [2.564438]  drm_fbdev_generic_setup+0xa5/0x166 [drm_kms_helper]
> [2.564446]  amdgpu_pci_probe+0x35e/0x370 [amdgpu]
> [2.564621]  local_pci_probe+0x45/0x80
> [2.564625]  ? pci_match_device+0xd7/0x130
> [2.564627]  pci_device_probe+0xbf/0x220
> [2.564629]  ? sysfs_do_create_link_sd+0x69/0xd0
> [2.564633]  really_probe+0x19c/0x380
> [2.564637]  __driver_probe_device+0xfe/0x180
> [2.564639]  driver_probe_device+0x1e/0x90
> [2.564641]  __driver_attach+0xc0/0x1c0
> [2.564643]  ? __device_attach_driver+0xe0/0xe0
> [2.564644]  ? __device_attach_driver+0xe0/0xe0
> [2.564646]  bus_for_each_dev+0x78/0xc0
> [2.564648]  bus_add_driver+0x149/0x1e0
> [2.564650]  driver_register+0x8f/0xe0
> [2.564652]  ? 0xc1023000
> [2.564654]  do_one_initcall+0x44/0x200
> [2.564657]  ? kmem_cache_alloc_trace+0x177/0x2c0
> [2.564659]  do_init_module+0x4c/0x250
> [2.564663]  __do_sys_init_module+0x12e/0x1b0
> [2.564666]  do_syscall_64+0x3b/0x90
> [2.564670]  entry_SYSCALL_64_after_hwframe+0x44/0xae
> [2.564673] RIP: 0033:0x7fc69bff232e
> [2.564674] Code: 48 8b 0d 45 0b 0c 00 f7 d8 64 89 01 48 83 c8 ff c3 66 2e 
> 0f 1f 84 00 00 00 00 00 90 f3 0f 1e fa 49 89 ca b8 af 00 00 00 0f 05 <48> 3d 
> 01 f0 ff ff 73 01 c3 48 8b 0d 12 0b 0c 00 f7 d8 64 89 01 48
> [2.564676] RSP: 002b:7ffe872ba3e8 EFLAGS: 0246 ORIG_RAX: 
> 

Re: [PATCH] drm/amd/display: set panel orientation before drm_dev_register

2022-08-08 Thread Melissa Wen
On 08/08, Hans de Goede wrote:
> Hi,
> 
> On 8/5/22 19:34, Simon Ser wrote:
> > Hi,
> > 
> > Have you seen [1] and [2]? CC'ing Sean and Hans, it seems like there's
> > a disagreement regarding probing early vs. setting the initial value to
> > UNKNOWN.
> 
> At least for the discussions I've been involved in so far
> (see the links in the originak email) it was possible to retreive
> the panel orientation before calling drm_dev_register() and IIRC some
> changes were merged (I've at least reviewed them) to add a new
> callback to the panel drivers to get the orientation from the panel
> driver before registering the connector fixing the ordering problem
> for those cases.
> 
> > If a driver doesn't fetch EDIDs before exposing them to user-space,
> > then there is an amount of time where the connectors are exposed as
> > CONNECTED but their EDID and mode list isn't properly set. But maybe
> > that's what the GETCONNECTOR IOCTLs is supposed to do: probe the
> > connector, fetch its EDID, return the proper mode list. So maybe
> > drivers shouldn't probe early and should let user-space request probes?
> > In which case we could create the panel orientation prop with "Normal",
> > and update it accordingly when probing.
> 
> I guess that if in some cases it really is not possible to get
> the orientation before calling drm_dev_register() then this is
> an acceptable solution, as long as the orientation gets set
> properly before the first GETCONNECTOR IOCTL finishes then
> userspace will never know the difference since it needs to do
> the GETCONNECTOR to enumerate the connectors properties anyways.
> 
> > At any rate, I've tested v2 on the Deck and it works properly.
> > 
> > Tested-by: Simon Ser 
> 
> I'm not aware of which patch's v2 you are talking about here, link ?

Hi Hans,

Here is v2: 
https://lore.kernel.org/amd-gfx/20220804161349.3561177-1-m...@igalia.com/

Anyway, let me cc'ing you all there.

Best Regards,

Melissa

> 
> Regards,
> 
> Hans
> 
> 
> 
> 
> 
> > 
> > Thanks,
> > 
> > Simon
> > 
> > [1]: 
> > https://lore.kernel.org/dri-devel/CAMavQKJUpYP8jo2JDGMYNBGtbPSSO7z9BAComm5JQoty=hp...@mail.gmail.com/
> > [2]: 
> > https://lore.kernel.org/dri-devel/20220530081910.3947168-1-hsi...@chromium.org/
> > 
> 


signature.asc
Description: PGP signature


[PATCH v2] drm/amd/display: set panel orientation before drm_dev_register

2022-08-04 Thread Melissa Wen
2.564696] [ cut here ]
[2.564696] WARNING: CPU: 6 PID: 325 at 
drivers/gpu/drm/drm_mode_object.c:242 drm_object_attach_property+0x52/0x80 [drm]
[2.564717] Modules linked in: btusb btrtl btbcm btintel btmtk bluetooth 
rfkill ecdh_generic ecc usbhid crc16 amdgpu(+) drm_ttm_helper ttm agpgart 
gpu_sched i2c_algo_bit drm_display_helper drm_kms_helper syscopyarea 
sysfillrect sysimgblt fb_sys_fops drm serio_raw sdhci_pci atkbd libps2 cqhci 
vivaldi_fmap ccp sdhci i8042 crct10dif_pclmul crc32_pclmul hid_multitouch 
ghash_clmulni_intel aesni_intel crypto_simd cryptd wdat_wdt mmc_core cec 
xhci_pci sp5100_tco rng_core xhci_pci_renesas serio 8250_dw i2c_hid_acpi 
i2c_hid btrfs blake2b_generic libcrc32c crc32c_generic crc32c_intel xor 
raid6_pq dm_mirror dm_region_hash dm_log dm_mod pkcs8_key_parser crypto_user
[2.564738] CPU: 6 PID: 325 Comm: systemd-udevd Tainted: GW 
5.18.0-amd-staging-drm-next+ #67
[2.564740] Hardware name: Valve Jupiter/Jupiter, BIOS F7A0105 03/21/2022
[2.564741] RIP: 0010:drm_object_attach_property+0x52/0x80 [drm]
[2.564759] Code: 2d 83 f8 18 74 33 48 89 74 c1 08 48 8b 4f 08 48 89 94 c1 
c8 00 00 00 48 8b 47 08 83 00 01 c3 4d 85 d2 75 dd 83 7f 58 01 75 d7 <0f> 0b eb 
d3 41 80 78 50 00 74 cc 0f 0b eb c8 44 89 ce 48 c7 c7 28
[2.564760] RSP: 0018:b2e8804138d8 EFLAGS: 00010246
[2.564761] RAX: 0010 RBX: 99508c1a2000 RCX: 99508c1a2180
[2.564762] RDX: 0003 RSI: 99508c050100 RDI: 99508c1a2040
[2.564763] RBP:  R08: 99508a860010 R09: c0c0c0c0
[2.564763] R10:  R11: 0020 R12: 99508a860010
[2.564764] R13: 995088733008 R14: 99508c1a2000 R15: c068a47f
[2.564765] FS:  7fc69b5f1a40() GS:9953aff8() 
knlGS:
[2.564766] CS:  0010 DS:  ES:  CR0: 80050033
[2.564767] CR2: 7f9506804000 CR3: 000107f92000 CR4: 00350ee0
[2.564768] Call Trace:
[2.564769]  
[2.564770]  drm_connector_set_panel_orientation_with_quirk+0x4a/0xc0 [drm]
[2.564789]  get_modes+0x4fb/0x530 [amdgpu]
[2.565024]  drm_helper_probe_single_connector_modes+0x1ad/0x850 
[drm_kms_helper]
[2.565036]  drm_client_modeset_probe+0x229/0x1400 [drm]
[2.565056]  ? xas_store+0x52/0x5e0
[2.565060]  ? kmem_cache_alloc_trace+0x177/0x2c0
[2.565062]  __drm_fb_helper_initial_config_and_unlock+0x44/0x4e0 
[drm_kms_helper]
[2.565072]  drm_fbdev_client_hotplug+0x173/0x210 [drm_kms_helper]
[2.565080]  drm_fbdev_generic_setup+0xa5/0x166 [drm_kms_helper]
[2.565088]  amdgpu_pci_probe+0x35e/0x370 [amdgpu]
[2.565261]  local_pci_probe+0x45/0x80
[2.565263]  ? pci_match_device+0xd7/0x130
[2.565265]  pci_device_probe+0xbf/0x220
[2.565267]  ? sysfs_do_create_link_sd+0x69/0xd0
[2.565268]  really_probe+0x19c/0x380
[2.565270]  __driver_probe_device+0xfe/0x180
[2.565272]  driver_probe_device+0x1e/0x90
[2.565274]  __driver_attach+0xc0/0x1c0
[2.565276]  ? __device_attach_driver+0xe0/0xe0
[2.565278]  ? __device_attach_driver+0xe0/0xe0
[2.565279]  bus_for_each_dev+0x78/0xc0
[2.565281]  bus_add_driver+0x149/0x1e0
[2.565283]  driver_register+0x8f/0xe0
[2.565285]  ? 0xc1023000
[2.565286]  do_one_initcall+0x44/0x200
[2.565288]  ? kmem_cache_alloc_trace+0x177/0x2c0
[2.565290]  do_init_module+0x4c/0x250
[2.565291]  __do_sys_init_module+0x12e/0x1b0
[2.565294]  do_syscall_64+0x3b/0x90
[2.565296]  entry_SYSCALL_64_after_hwframe+0x44/0xae
[2.565297] RIP: 0033:0x7fc69bff232e
[2.565298] Code: 48 8b 0d 45 0b 0c 00 f7 d8 64 89 01 48 83 c8 ff c3 66 2e 
0f 1f 84 00 00 00 00 00 90 f3 0f 1e fa 49 89 ca b8 af 00 00 00 0f 05 <48> 3d 01 
f0 ff ff 73 01 c3 48 8b 0d 12 0b 0c 00 f7 d8 64 89 01 48
[2.565299] RSP: 002b:7ffe872ba3e8 EFLAGS: 0246 ORIG_RAX: 
00af
[2.565301] RAX: ffda RBX: 55873f797820 RCX: 7fc69bff232e
[2.565302] RDX: 55873f7bf390 RSI: 01155e81 RDI: 7fc699e4d010
[2.565303] RBP: 7fc699e4d010 R08: 55873f7bfe20 R09: 01155e90
[2.565303] R10: 00055873f7bf R11: 0246 R12: 55873f7bf390
[2.565304] R13: 000d R14: 55873f7c4cb0 R15: 55873f797820
[2.565306]  
[2.565307] ---[ end trace  ]---

--

v2:
- call amdgpu_dm_connector_get_modes() instead of ddc_get_modes() (Harry)

Fixes: d77de7880e0e0 ("amd/display: enable panel orientation quirks")
Signed-off-by: Melissa Wen 
---
 drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 8 ++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
index 0d54c1486739..2de37b976c23 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm

[PATCH v2 1/4] Documentation/amdgpu_dm: Add DM color correction documentation

2022-08-04 Thread Melissa Wen
AMDGPU DM maps DRM color management properties (degamma, ctm and gamma)
to DC color correction entities. Part of this mapping is already
documented as code comments and can be converted as kernel docs.

v2:
- rebase to amd-staging-drm-next
- fix typos (Tales)
- undo kernel-docs inside functions (Tales)

Signed-off-by: Melissa Wen 
Reviewed-by: Harry Wentland 
Reviewed-by: Tales Aparecida 
---
 .../gpu/amdgpu/display/display-manager.rst|   9 ++
 .../amd/display/amdgpu_dm/amdgpu_dm_color.c   | 109 +-
 2 files changed, 90 insertions(+), 28 deletions(-)

diff --git a/Documentation/gpu/amdgpu/display/display-manager.rst 
b/Documentation/gpu/amdgpu/display/display-manager.rst
index 7ce31f89d9a0..b1b0f11aed83 100644
--- a/Documentation/gpu/amdgpu/display/display-manager.rst
+++ b/Documentation/gpu/amdgpu/display/display-manager.rst
@@ -40,3 +40,12 @@ Atomic Implementation
 
 .. kernel-doc:: drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
:functions: amdgpu_dm_atomic_check amdgpu_dm_atomic_commit_tail
+
+Color Management Properties
+===
+
+.. kernel-doc:: drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
+   :doc: overview
+
+.. kernel-doc:: drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
+   :internal:
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
index a71177305bcd..a4cb23d059bd 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
@@ -29,7 +29,9 @@
 #include "modules/color/color_gamma.h"
 #include "basics/conversion.h"
 
-/*
+/**
+ * DOC: overview
+ *
  * The DC interface to HW gives us the following color management blocks
  * per pipe (surface):
  *
@@ -71,8 +73,8 @@
 
 #define MAX_DRM_LUT_VALUE 0x
 
-/*
- * Initialize the color module.
+/**
+ * amdgpu_dm_init_color_mod - Initialize the color module.
  *
  * We're not using the full color module, only certain components.
  * Only call setup functions for components that we need.
@@ -82,7 +84,14 @@ void amdgpu_dm_init_color_mod(void)
setup_x_points_distribution();
 }
 
-/* Extracts the DRM lut and lut size from a blob. */
+/**
+ * __extract_blob_lut - Extracts the DRM lut and lut size from a blob.
+ * @blob: DRM color mgmt property blob
+ * @size: lut size
+ *
+ * Returns:
+ * DRM LUT or NULL
+ */
 static const struct drm_color_lut *
 __extract_blob_lut(const struct drm_property_blob *blob, uint32_t *size)
 {
@@ -90,13 +99,18 @@ __extract_blob_lut(const struct drm_property_blob *blob, 
uint32_t *size)
return blob ? (struct drm_color_lut *)blob->data : NULL;
 }
 
-/*
- * Return true if the given lut is a linear mapping of values, i.e. it acts
- * like a bypass LUT.
+/**
+ * __is_lut_linear - check if the given lut is a linear mapping of values
+ * @lut: given lut to check values
+ * @size: lut size
  *
  * It is considered linear if the lut represents:
- * f(a) = (0xFF00/MAX_COLOR_LUT_ENTRIES-1)a; for integer a in
- *   [0, MAX_COLOR_LUT_ENTRIES)
+ * f(a) = (0xFF00/MAX_COLOR_LUT_ENTRIES-1)a; for integer a in [0,
+ * MAX_COLOR_LUT_ENTRIES)
+ *
+ * Returns:
+ * True if the given lut is a linear mapping of values, i.e. it acts like a
+ * bypass LUT. Otherwise, false.
  */
 static bool __is_lut_linear(const struct drm_color_lut *lut, uint32_t size)
 {
@@ -119,9 +133,13 @@ static bool __is_lut_linear(const struct drm_color_lut 
*lut, uint32_t size)
return true;
 }
 
-/*
- * Convert the drm_color_lut to dc_gamma. The conversion depends on the size
- * of the lut - whether or not it's legacy.
+/**
+ * __drm_lut_to_dc_gamma - convert the drm_color_lut to dc_gamma.
+ * @lut: DRM lookup table for color conversion
+ * @gamma: DC gamma to set entries
+ * @is_legacy: legacy or atomic gamma
+ *
+ * The conversion depends on the size of the lut - whether or not it's legacy.
  */
 static void __drm_lut_to_dc_gamma(const struct drm_color_lut *lut,
  struct dc_gamma *gamma, bool is_legacy)
@@ -154,8 +172,11 @@ static void __drm_lut_to_dc_gamma(const struct 
drm_color_lut *lut,
}
 }
 
-/*
- * Converts a DRM CTM to a DC CSC float matrix.
+/**
+ * __drm_ctm_to_dc_matrix - converts a DRM CTM to a DC CSC float matrix
+ * @ctm: DRM color transformation matrix
+ * @matrix: DC CSC float matrix
+ *
  * The matrix needs to be a 3x4 (12 entry) matrix.
  */
 static void __drm_ctm_to_dc_matrix(const struct drm_color_ctm *ctm,
@@ -189,7 +210,18 @@ static void __drm_ctm_to_dc_matrix(const struct 
drm_color_ctm *ctm,
}
 }
 
-/* Calculates the legacy transfer function - only for sRGB input space. */
+/**
+ * __set_legacy_tf - Calculates the legacy transfer function
+ * @func: transfer function
+ * @lut: lookup table that defines the color space
+ * @lut_size: size of respective lut
+ * @has_rom: if ROM can be used for hardcoded curve
+ *

[PATCH v2 4/4] Documentation/gpu/amdgpu/amdgpu_dm: add DM docs for pixel blend mode

2022-08-04 Thread Melissa Wen
AMD GPU display manager (DM) maps DRM pixel blend modes (None,
Pre-multiplied, Coverage) to MPC hw blocks through blend configuration
options. Describe relevant elements and how to set and test them to get
the expected DRM blend mode on DCN hw.

v2:
- add ref tag (Tales)

Signed-off-by: Melissa Wen 
Reviewed-by: Tales Aparecida 
---
 .../gpu/amdgpu/display/display-manager.rst| 98 +++
 Documentation/gpu/drm-kms.rst |  2 +
 2 files changed, 100 insertions(+)

diff --git a/Documentation/gpu/amdgpu/display/display-manager.rst 
b/Documentation/gpu/amdgpu/display/display-manager.rst
index 88e2c08c7014..b7abb18cfc82 100644
--- a/Documentation/gpu/amdgpu/display/display-manager.rst
+++ b/Documentation/gpu/amdgpu/display/display-manager.rst
@@ -83,3 +83,101 @@ schemas.
 **DCN 3.0 family color caps and mapping**
 
 .. kernel-figure:: dcn3_cm_drm_current.svg
+
+Blend Mode Properties
+=
+
+Pixel blend mode is a DRM plane composition property of :c:type:`drm_plane` 
used to
+describes how pixels from a foreground plane (fg) are composited with the
+background plane (bg). Here, we present main concepts of DRM blend mode to help
+to understand how this property is mapped to AMD DC interface. See more about
+this DRM property and the alpha blending equations in :ref:`DRM Plane
+Composition Properties `.
+
+Basically, a blend mode sets the alpha blending equation for plane
+composition that fits the mode in which the alpha channel affects the state of
+pixel color values and, therefore, the resulted pixel color. For
+example, consider the following elements of the alpha blending equation:
+
+- *fg.rgb*: Each of the RGB component values from the foreground's pixel.
+- *fg.alpha*: Alpha component value from the foreground's pixel.
+- *bg.rgb*: Each of the RGB component values from the background.
+- *plane_alpha*: Plane alpha value set by the **plane "alpha" property**, see
+  more in :ref:`DRM Plane Composition Properties 
`.
+
+in the basic alpha blending equation::
+
+   out.rgb = alpha * fg.rgb + (1 - alpha) * bg.rgb
+
+the alpha channel value of each pixel in a plane is ignored and only the plane
+alpha affects the resulted pixel color values.
+
+DRM has three blend mode to define the blend formula in the plane composition:
+
+* **None**: Blend formula that ignores the pixel alpha.
+
+* **Pre-multiplied**: Blend formula that assumes the pixel color values in a
+  plane was already pre-multiplied by its own alpha channel before storage.
+
+* **Coverage**: Blend formula that assumes the pixel color values were not
+  pre-multiplied with the alpha channel values.
+
+and pre-multiplied is the default pixel blend mode, that means, when no blend
+mode property is created or defined, DRM considers the plane's pixels has
+pre-multiplied color values. On IGT GPU tools, the kms_plane_alpha_blend test
+provides a set of subtests to verify plane alpha and blend mode properties.
+
+The DRM blend mode and its elements are then mapped by AMDGPU display manager
+(DM) to program the blending configuration of the Multiple Pipe/Plane Combined
+(MPC), as follows:
+
+.. kernel-doc:: drivers/gpu/drm/amd/display/dc/inc/hw/mpc.h
+   :doc: mpc-overview
+
+.. kernel-doc:: drivers/gpu/drm/amd/display/dc/inc/hw/mpc.h
+   :functions: mpcc_blnd_cfg
+
+Therefore, the blending configuration for a single MPCC instance on the MPC
+tree is defined by :c:type:`mpcc_blnd_cfg`, where
+:c:type:`pre_multiplied_alpha` is the alpha pre-multiplied mode flag used to
+set :c:type:`MPCC_ALPHA_MULTIPLIED_MODE`. It controls whether alpha is
+multiplied (true/false), being only true for DRM pre-multiplied blend mode.
+:c:type:`mpcc_alpha_blend_mode` defines the alpha blend mode regarding pixel
+alpha and plane alpha values. It sets one of the three modes for
+:c:type:`MPCC_ALPHA_BLND_MODE`, as described below.
+
+.. kernel-doc:: drivers/gpu/drm/amd/display/dc/inc/hw/mpc.h
+   :functions: mpcc_alpha_blend_mode
+
+DM then maps the elements of `enum mpcc_alpha_blend_mode` to those in the DRM
+blend formula, as follows:
+
+* *MPC pixel alpha* matches *DRM fg.alpha* as the alpha component value
+  from the plane's pixel
+* *MPC global alpha* matches *DRM plane_alpha* when the pixel alpha should
+  be ignored and, therefore, pixel values are not pre-multiplied
+* *MPC global gain* assumes *MPC global alpha* value when both *DRM
+  fg.alpha* and *DRM plane_alpha* participate in the blend equation
+
+In short, *fg.alpha* is ignored by selecting
+:c:type:`MPCC_ALPHA_BLEND_MODE_GLOBAL_ALPHA`. On the other hand, (plane_alpha *
+fg.alpha) component becomes available by selecting
+:c:type:`MPCC_ALPHA_BLEND_MODE_PER_PIXEL_ALPHA_COMBINED_GLOBAL_GAIN`. And the
+:c:type:`MPCC_ALPHA_MULTIPLIED_MODE` defines if the pixel color values are
+pre-multiplied by alpha or not.
+
+Blend configuration flow
+
+
+The alpha blending equation is configured from DRM to DC interface by the
+following path:

[PATCH v2 3/4] drm/amd/display: add doc entries for MPC blending configuration

2022-08-04 Thread Melissa Wen
Describe structs and enums used to set blend mode properties to MPC
blocks. Some pieces of information are already available as code
comments, and were just formatted. Others were collected and summarised
from discussions on AMD issue tracker[1][2].

[1] https://gitlab.freedesktop.org/drm/amd/-/issues/1734
[2] https://gitlab.freedesktop.org/drm/amd/-/issues/1769

v2:
- fix typos (Tales)
- add MPCC to MPC entry in the glossary

Signed-off-by: Melissa Wen 
Reviewed-by: Tales Aparecida 
---
 .../gpu/amdgpu/display/dc-glossary.rst|  2 +-
 drivers/gpu/drm/amd/display/dc/inc/hw/mpc.h   | 91 ---
 2 files changed, 78 insertions(+), 15 deletions(-)

diff --git a/Documentation/gpu/amdgpu/display/dc-glossary.rst 
b/Documentation/gpu/amdgpu/display/dc-glossary.rst
index 116f5f0942fd..0b0ffd428dd2 100644
--- a/Documentation/gpu/amdgpu/display/dc-glossary.rst
+++ b/Documentation/gpu/amdgpu/display/dc-glossary.rst
@@ -170,7 +170,7 @@ consider asking in the amdgfx and update this page.
 MC
   Memory Controller
 
-MPC
+MPC/MPCC
   Multiple pipes and plane combine
 
 MPO
diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/mpc.h 
b/drivers/gpu/drm/amd/display/dc/inc/hw/mpc.h
index 5097037e3962..8d86159d9de0 100644
--- a/drivers/gpu/drm/amd/display/dc/inc/hw/mpc.h
+++ b/drivers/gpu/drm/amd/display/dc/inc/hw/mpc.h
@@ -22,6 +22,16 @@
  *
  */
 
+/**
+ * DOC: mpc-overview
+ *
+ * Multiple Pipe/Plane Combined (MPC) is a component in the hardware pipeline
+ * that performs blending of multiple planes, using global and per-pixel alpha.
+ * It also performs post-blending color correction operations according to the
+ * hardware capabilities, such as color transformation matrix and gamma 1D and
+ * 3D LUT.
+ */
+
 #ifndef __DC_MPCC_H__
 #define __DC_MPCC_H__
 
@@ -48,14 +58,39 @@ enum mpcc_blend_mode {
MPCC_BLEND_MODE_TOP_BOT_BLENDING
 };
 
+/**
+ * enum mpcc_alpha_blend_mode - define the alpha blend mode regarding pixel
+ * alpha and plane alpha values
+ */
 enum mpcc_alpha_blend_mode {
+   /**
+* @MPCC_ALPHA_BLEND_MODE_PER_PIXEL_ALPHA: per pixel alpha using DPP
+* alpha value
+*/
MPCC_ALPHA_BLEND_MODE_PER_PIXEL_ALPHA,
+   /**
+* @MPCC_ALPHA_BLEND_MODE_PER_PIXEL_ALPHA_COMBINED_GLOBAL_GAIN: per
+* pixel alpha using DPP alpha value multiplied by a global gain (plane
+* alpha)
+*/
MPCC_ALPHA_BLEND_MODE_PER_PIXEL_ALPHA_COMBINED_GLOBAL_GAIN,
+   /**
+* @MPCC_ALPHA_BLEND_MODE_GLOBAL_ALPHA: global alpha value, ignores
+* pixel alpha and consider only plane alpha
+*/
MPCC_ALPHA_BLEND_MODE_GLOBAL_ALPHA
 };
 
-/*
- * MPCC blending configuration
+/**
+ * struct mpcc_blnd_cfg - MPCC blending configuration
+ *
+ * @black_color: background color
+ * @alpha_mode: alpha blend mode (MPCC_ALPHA_BLND_MODE)
+ * @pre_multiplied_alpha: whether pixel color values were pre-multiplied by the
+ * alpha channel (MPCC_ALPHA_MULTIPLIED_MODE)
+ * @global_gain: used when blend mode considers both pixel alpha and plane
+ * alpha value and assumes the global alpha value.
+ * @global_alpha: plane alpha value
  */
 struct mpcc_blnd_cfg {
struct tg_color black_color;/* background color */
@@ -107,8 +142,15 @@ struct mpc_dwb_flow_control {
int flow_ctrl_cnt1;
 };
 
-/*
- * MPCC connection and blending configuration for a single MPCC instance.
+/**
+ * struct mpcc - MPCC connection and blending configuration for a single MPCC 
instance.
+ * @mpcc_id: MPCC physical instance
+ * @dpp_id: DPP input to this MPCC
+ * @mpcc_bot: pointer to bottom layer MPCC. NULL when not connected.
+ * @blnd_cfg: the blending configuration for this MPCC
+ * @sm_cfg: stereo mix setting for this MPCC
+ * @shared_bottom: if MPCC output to both OPP and DWB endpoints, true. 
Otherwise, false.
+ *
  * This struct is used as a node in an MPC tree.
  */
 struct mpcc {
@@ -120,8 +162,12 @@ struct mpcc {
bool shared_bottom; /* TRUE if MPCC output to both OPP and 
DWB endpoints, else FALSE */
 };
 
-/*
- * MPC tree represents all MPCC connections for a pipe.
+/**
+ * struct mpc_tree - MPC tree represents all MPCC connections for a pipe.
+ *
+ * @opp_id: the OPP instance that owns this MPC tree
+ * @opp_list: the top MPCC layer of the MPC tree that outputs to OPP endpoint
+ *
  */
 struct mpc_tree {
int opp_id; /* The OPP instance that owns this MPC 
tree */
@@ -149,13 +195,18 @@ struct mpcc_state {
uint32_t busy;
 };
 
+/**
+ * struct mpc_funcs - funcs
+ */
 struct mpc_funcs {
void (*read_mpcc_state)(
struct mpc *mpc,
int mpcc_inst,
struct mpcc_state *s);
 
-   /*
+   /**
+* @insert_plane:
+*
 * Insert DPP into MPC tree based on specified blending position.
 * Only used for planes that are part of blending chain for OPP output

[PATCH v2 2/4] Documentation/amdgpu/display: add DC color caps info

2022-08-04 Thread Melissa Wen
Add details about color correction capabilities and explain a bit about
differences between DC hw generations and also how they are mapped
between DRM and DC interface. Two schemas for DCN 2.0 and 3.0 (converted
to svg from the original png) is included to illustrate it. They were
obtained from a discussion[1] in the amd-gfx mailing list.

[1] 
https://lore.kernel.org/amd-gfx/20220422142811.dm6vtk6v64jcw...@mail.igalia.com/

v1:
- remove redundant comments (Harry)
- fix typos (Harry)

v2:
- reword introduction of color section
- add co-dev tag for Harry - who provided most of the info
- fix typos (Tales)
- describe missing struct parameters (Tales and Siqueira)

Co-developed-by: Harry Wentland 
Signed-off-by: Harry Wentland 
Signed-off-by: Melissa Wen 
Reviewed-by: Tales Aparecida 
---
 .../amdgpu/display/dcn2_cm_drm_current.svg| 1370 +++
 .../amdgpu/display/dcn3_cm_drm_current.svg| 1529 +
 .../gpu/amdgpu/display/display-manager.rst|   34 +
 drivers/gpu/drm/amd/display/dc/dc.h   |   77 +-
 4 files changed, 2997 insertions(+), 13 deletions(-)
 create mode 100644 Documentation/gpu/amdgpu/display/dcn2_cm_drm_current.svg
 create mode 100644 Documentation/gpu/amdgpu/display/dcn3_cm_drm_current.svg

diff --git a/Documentation/gpu/amdgpu/display/dcn2_cm_drm_current.svg 
b/Documentation/gpu/amdgpu/display/dcn2_cm_drm_current.svg
new file mode 100644
index ..315ffc5a1a4b
--- /dev/null
+++ b/Documentation/gpu/amdgpu/display/dcn2_cm_drm_current.svg
@@ -0,0 +1,1370 @@
+
+
+
+http://www.inkscape.org/namespaces/inkscape;
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd;
+   xmlns="http://www.w3.org/2000/svg;
+   xmlns:svg="http://www.w3.org/2000/svg;>
+  
+  
+  
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Matrix
+1D LUT
+3D LUT
+Unpacking
+Other
+drm_framebuffer
+format
+drm_plane
+drm_crtc
+Stream
+MPC
+DPP
+
+Blender
+Degamma
+CTM
+Gamma
+format
+bias_and_scale
+color space matrix
+input_csc_color_matrix
+in_transfer_func
+hdr_mult
+gamut_remap_matrix
+in_shaper_func
+lut3d_func
+blend_tf
+Blender
+gamut_remap_matrix
+func_shaper
+lut3d_func
+out_transfer_func
+csc_color_matrix
+bit_depth_param
+clamping
+output_color_space
+Plane
+Legend
+DCN 2.0
+DC Interface
+DRM Interface
+
+CNVC
+Input CSC
+DeGammaRAM and ROM(sRGB, BT2020
+HDR Multiply
+Gamut Remap
+Shaper 
LUTRAM
+3D 
LUTRAM
+Blend Gamma
+Blender
+GammaRAM
+OCSC
+
+
+color_encoding
+
+pixel_blend_mode
+
+color_range
+
+
+
+
+
+
+
+
+
+
+
+
+  
+
diff --git a/Documentation/gpu/amdgpu/display/dcn3_cm_drm_current.svg 
b/Documentation/gpu/amdgpu/display/dcn3_cm_drm_current.svg
new file mode 100644
index ..7299ee9b6d64
--- /dev/null
+++ b/Documentation/gpu/amdgpu/display/dcn3_cm_drm_current.svg
@@ -0,0 +1,1529 @@
+
+
+
+http://www.inkscape.org/namespaces/inkscape;
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd;
+   xmlns="http://www.w3.org/2000/svg;
+   xmlns:svg="http://www.w3.org/2000/svg;>
+  
+  
+  
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Matrix
+1D LUT
+3D LUT
+Unpacking
+Other
+drm_framebuffer
+format
+drm_plane
+drm_crtc
+Stream
+MPC
+DPP
+
+Blender
+Degamma
+CTM
+Gamma
+format
+bias_and_scale
+color space matrix
+input_csc_color_matrix
+in_transfer_func
+hdr_mult
+gamut_remap_matrix
+in_shaper_func
+lut3d_func
+blend_tf
+Blender
+gamut_remap_matrix
+func_shaper
+lut3d_func
+out_transfer_func
+csc_color_matrix
+bit_depth_param
+clamping
+output_color_space
+Plane
+Legend
+DCN 3.0
+DC Interface
+DRM Interface
+
+CNVC
+In

[PATCH v2 0/4] Documentation/amdgpu/display: describe color and blend mode properties mapping

2022-08-04 Thread Melissa Wen
As mentioned in the previous version, patches 1 and 2 describe DM
mapping of DRM color correction properties to DC interface and where
detached from 3D LUT RFC series [1]. Patches 3 and 4 describe MPC block
programming that matches the three DRM blend modes and came from
previous work [2][3] and discussions on AMD issue tracker. Let me know
any misleading information.

In this version, typos were fixed and I removed unusual kernel-docs
inside functions, as suggested by Tales. I also added description of
some struct elements thanks to Siqueira's feedback. I restructured the
introdutory text of the color section, but preserved the content.
Unfortunately, there are some missing definitions for mpc_blnd_cfg, that
I appreciate if someone can provide more information:

./drivers/gpu/drm/amd/display/dc/inc/hw/mpc.h:109: warning: Function parameter 
or member 'overlap_only' not described in 'mpcc_blnd_cfg'
./drivers/gpu/drm/amd/display/dc/inc/hw/mpc.h:109: warning: Function parameter 
or member 'bottom_gain_mode' not described in 'mpcc_blnd_cfg'
./drivers/gpu/drm/amd/display/dc/inc/hw/mpc.h:109: warning: Function parameter 
or member 'background_color_bpc' not described in 'mpcc_blnd_cfg'
./drivers/gpu/drm/amd/display/dc/inc/hw/mpc.h:109: warning: Function parameter 
or member 'top_gain' not described in 'mpcc_blnd_cfg'
./drivers/gpu/drm/amd/display/dc/inc/hw/mpc.h:109: warning: Function parameter 
or member 'bottom_inside_gain' not described in 'mpcc_blnd_cfg'
./drivers/gpu/drm/amd/display/dc/inc/hw/mpc.h:109: warning: Function parameter 
or member 'bottom_outside_gain' not described in 'mpcc_blnd_cfg' 

[1] https://lore.kernel.org/amd-gfx/20220619223104.667413-1-m...@igalia.com/
[2] https://lore.kernel.org/amd-gfx/20220329201835.2393141-1-m...@igalia.com/
[3] 
https://lore.kernel.org/amd-gfx/7a95d6a4-bc2f-b0e8-83f8-8cc5b7559...@amd.com/

Melissa Wen (4):
  Documentation/amdgpu_dm: Add DM color correction documentation
  Documentation/amdgpu/display: add DC color caps info
  drm/amd/display: add doc entries for MPC blending configuration
  Documentation/gpu/amdgpu/amdgpu_dm: add DM docs for pixel blend mode

 .../gpu/amdgpu/display/dc-glossary.rst|2 +-
 .../amdgpu/display/dcn2_cm_drm_current.svg| 1370 +++
 .../amdgpu/display/dcn3_cm_drm_current.svg| 1529 +
 .../gpu/amdgpu/display/display-manager.rst|  141 ++
 Documentation/gpu/drm-kms.rst |2 +
 .../amd/display/amdgpu_dm/amdgpu_dm_color.c   |  109 +-
 drivers/gpu/drm/amd/display/dc/dc.h   |   77 +-
 drivers/gpu/drm/amd/display/dc/inc/hw/mpc.h   |   91 +-
 8 files changed, 3265 insertions(+), 56 deletions(-)
 create mode 100644 Documentation/gpu/amdgpu/display/dcn2_cm_drm_current.svg
 create mode 100644 Documentation/gpu/amdgpu/display/dcn3_cm_drm_current.svg

-- 
2.35.1



Re: [PATCH] drm/amd/display: set panel orientation before drm_dev_register

2022-08-03 Thread Melissa Wen
On 08/03, Melissa Wen wrote:
> To set the panel orientation property with quirk, we need the mode size
> provided by EDID. This info is available after EDID is read by 
> dc_link_detect()
> and updated by amdgpu_dm_update_connector_after_detect(). The detection
> happens at driver load in amdgpu_dm_initialize_drm_device() and,
> therefore, we can get modes and set panel orientation before
> drm_dev_register() to avoid DRM warns on creating the connector property
> after device registration:

+ cc'ing: Simon Ser

> 
> [2.563969] [ cut here ]
> [2.563971] WARNING: CPU: 6 PID: 325 at 
> drivers/gpu/drm/drm_mode_object.c:45 drm_mode_object_add+0x72/0x80 [drm]
> [2.563997] Modules linked in: btusb btrtl btbcm btintel btmtk bluetooth 
> rfkill ecdh_generic ecc usbhid crc16 amdgpu(+) drm_ttm_helper ttm agpgart 
> gpu_sched i2c_algo_bit drm_display_helper drm_kms_helper syscopyarea 
> sysfillrect sysimgblt fb_sys_fops drm serio_raw sdhci_pci atkbd libps2 cqhci 
> vivaldi_fmap ccp sdhci i8042 crct10dif_pclmul crc32_pclmul hid_multitouch 
> ghash_clmulni_intel aesni_intel crypto_simd cryptd wdat_wdt mmc_core cec 
> xhci_pci sp5100_tco rng_core xhci_pci_renesas serio 8250_dw i2c_hid_acpi 
> i2c_hid btrfs blake2b_generic libcrc32c crc32c_generic crc32c_intel xor 
> raid6_pq dm_mirror dm_region_hash dm_log dm_mod pkcs8_key_parser crypto_user
> [2.564032] CPU: 6 PID: 325 Comm: systemd-udevd Not tainted 
> 5.18.0-amd-staging-drm-next+ #67
> [2.564034] Hardware name: Valve Jupiter/Jupiter, BIOS F7A0105 03/21/2022
> [2.564036] RIP: 0010:drm_mode_object_add+0x72/0x80 [drm]
> [2.564053] Code: f0 89 c3 85 c0 78 07 89 45 00 44 89 65 04 4c 89 ef e8 e2 
> 99 04 f1 31 c0 85 db 0f 4e c3 5b 5d 41 5c 41 5d c3 80 7f 50 00 74 ac <0f> 0b 
> eb a8 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 44 00 00 41 54 4c
> [2.564055] RSP: 0018:b2e880413860 EFLAGS: 00010202
> [2.564056] RAX: c0ba1440 RBX: 99508a860010 RCX: 
> 0001
> [2.564057] RDX: b0b0b0b0 RSI: 99508c050110 RDI: 
> 99508a860010
> [2.564058] RBP: 99508c050110 R08: 0020 R09: 
> 99508c292c20
> [2.564059] R10:  R11: 99508c0507d8 R12: 
> b0b0b0b0
> [2.564060] R13: 0004 R14: c068a4b6 R15: 
> c068a47f
> [2.564061] FS:  7fc69b5f1a40() GS:9953aff8() 
> knlGS:
> [2.564063] CS:  0010 DS:  ES:  CR0: 80050033
> [2.564063] CR2: 7f9506804000 CR3: 000107f92000 CR4: 
> 00350ee0
> [2.564065] Call Trace:
> [2.564068]  
> [2.564070]  drm_property_create+0xc9/0x170 [drm]
> [2.564088]  drm_property_create_enum+0x1f/0x70 [drm]
> [2.564105]  drm_connector_set_panel_orientation_with_quirk+0x96/0xc0 [drm]
> [2.564123]  get_modes+0x4fb/0x530 [amdgpu]
> [2.564378]  drm_helper_probe_single_connector_modes+0x1ad/0x850 
> [drm_kms_helper]
> [2.564390]  drm_client_modeset_probe+0x229/0x1400 [drm]
> [2.564411]  ? xas_store+0x52/0x5e0
> [2.564416]  ? kmem_cache_alloc_trace+0x177/0x2c0
> [2.564420]  __drm_fb_helper_initial_config_and_unlock+0x44/0x4e0 
> [drm_kms_helper]
> [2.564430]  drm_fbdev_client_hotplug+0x173/0x210 [drm_kms_helper]
> [2.564438]  drm_fbdev_generic_setup+0xa5/0x166 [drm_kms_helper]
> [2.564446]  amdgpu_pci_probe+0x35e/0x370 [amdgpu]
> [2.564621]  local_pci_probe+0x45/0x80
> [2.564625]  ? pci_match_device+0xd7/0x130
> [2.564627]  pci_device_probe+0xbf/0x220
> [2.564629]  ? sysfs_do_create_link_sd+0x69/0xd0
> [2.564633]  really_probe+0x19c/0x380
> [2.564637]  __driver_probe_device+0xfe/0x180
> [2.564639]  driver_probe_device+0x1e/0x90
> [2.564641]  __driver_attach+0xc0/0x1c0
> [2.564643]  ? __device_attach_driver+0xe0/0xe0
> [2.564644]  ? __device_attach_driver+0xe0/0xe0
> [2.564646]  bus_for_each_dev+0x78/0xc0
> [2.564648]  bus_add_driver+0x149/0x1e0
> [2.564650]  driver_register+0x8f/0xe0
> [2.564652]  ? 0xc1023000
> [2.564654]  do_one_initcall+0x44/0x200
> [2.564657]  ? kmem_cache_alloc_trace+0x177/0x2c0
> [2.564659]  do_init_module+0x4c/0x250
> [2.564663]  __do_sys_init_module+0x12e/0x1b0
> [2.564666]  do_syscall_64+0x3b/0x90
> [2.564670]  entry_SYSCALL_64_after_hwframe+0x44/0xae
> [2.564673] RIP: 0033:0x7fc69bff232e
> [2.564674] Code: 48 8b 0d 45 0b 0c 00 f7 d8 64 89 01 48 83 c8 ff c3 66 2e 
> 0f 1f 84 00 00 00 00 00 90 f3 0f 1e fa 49 89 ca b8 af 00 00 00 0f 05 <48> 3d 
> 01 f0 ff ff 73 01 c3 48 8b 0d 12 0b 0c 00 f7 d8 64 89 01 48
> [2.564676] RSP: 002b:7ffe872ba3e8 EFLAGS: 0246 ORIG_RAX: 
> 

[PATCH] drm/amd/display: set panel orientation before drm_dev_register

2022-08-03 Thread Melissa Wen
2.564696] [ cut here ]
[2.564696] WARNING: CPU: 6 PID: 325 at 
drivers/gpu/drm/drm_mode_object.c:242 drm_object_attach_property+0x52/0x80 [drm]
[2.564717] Modules linked in: btusb btrtl btbcm btintel btmtk bluetooth 
rfkill ecdh_generic ecc usbhid crc16 amdgpu(+) drm_ttm_helper ttm agpgart 
gpu_sched i2c_algo_bit drm_display_helper drm_kms_helper syscopyarea 
sysfillrect sysimgblt fb_sys_fops drm serio_raw sdhci_pci atkbd libps2 cqhci 
vivaldi_fmap ccp sdhci i8042 crct10dif_pclmul crc32_pclmul hid_multitouch 
ghash_clmulni_intel aesni_intel crypto_simd cryptd wdat_wdt mmc_core cec 
xhci_pci sp5100_tco rng_core xhci_pci_renesas serio 8250_dw i2c_hid_acpi 
i2c_hid btrfs blake2b_generic libcrc32c crc32c_generic crc32c_intel xor 
raid6_pq dm_mirror dm_region_hash dm_log dm_mod pkcs8_key_parser crypto_user
[2.564738] CPU: 6 PID: 325 Comm: systemd-udevd Tainted: GW 
5.18.0-amd-staging-drm-next+ #67
[2.564740] Hardware name: Valve Jupiter/Jupiter, BIOS F7A0105 03/21/2022
[2.564741] RIP: 0010:drm_object_attach_property+0x52/0x80 [drm]
[2.564759] Code: 2d 83 f8 18 74 33 48 89 74 c1 08 48 8b 4f 08 48 89 94 c1 
c8 00 00 00 48 8b 47 08 83 00 01 c3 4d 85 d2 75 dd 83 7f 58 01 75 d7 <0f> 0b eb 
d3 41 80 78 50 00 74 cc 0f 0b eb c8 44 89 ce 48 c7 c7 28
[2.564760] RSP: 0018:b2e8804138d8 EFLAGS: 00010246
[2.564761] RAX: 0010 RBX: 99508c1a2000 RCX: 99508c1a2180
[2.564762] RDX: 0003 RSI: 99508c050100 RDI: 99508c1a2040
[2.564763] RBP:  R08: 99508a860010 R09: c0c0c0c0
[2.564763] R10:  R11: 0020 R12: 99508a860010
[2.564764] R13: 995088733008 R14: 99508c1a2000 R15: c068a47f
[2.564765] FS:  7fc69b5f1a40() GS:9953aff8() 
knlGS:
[2.564766] CS:  0010 DS:  ES:  CR0: 80050033
[2.564767] CR2: 7f9506804000 CR3: 000107f92000 CR4: 00350ee0
[2.564768] Call Trace:
[2.564769]  
[2.564770]  drm_connector_set_panel_orientation_with_quirk+0x4a/0xc0 [drm]
[2.564789]  get_modes+0x4fb/0x530 [amdgpu]
[2.565024]  drm_helper_probe_single_connector_modes+0x1ad/0x850 
[drm_kms_helper]
[2.565036]  drm_client_modeset_probe+0x229/0x1400 [drm]
[2.565056]  ? xas_store+0x52/0x5e0
[2.565060]  ? kmem_cache_alloc_trace+0x177/0x2c0
[2.565062]  __drm_fb_helper_initial_config_and_unlock+0x44/0x4e0 
[drm_kms_helper]
[2.565072]  drm_fbdev_client_hotplug+0x173/0x210 [drm_kms_helper]
[2.565080]  drm_fbdev_generic_setup+0xa5/0x166 [drm_kms_helper]
[2.565088]  amdgpu_pci_probe+0x35e/0x370 [amdgpu]
[2.565261]  local_pci_probe+0x45/0x80
[2.565263]  ? pci_match_device+0xd7/0x130
[2.565265]  pci_device_probe+0xbf/0x220
[2.565267]  ? sysfs_do_create_link_sd+0x69/0xd0
[2.565268]  really_probe+0x19c/0x380
[2.565270]  __driver_probe_device+0xfe/0x180
[2.565272]  driver_probe_device+0x1e/0x90
[2.565274]  __driver_attach+0xc0/0x1c0
[2.565276]  ? __device_attach_driver+0xe0/0xe0
[2.565278]  ? __device_attach_driver+0xe0/0xe0
[2.565279]  bus_for_each_dev+0x78/0xc0
[2.565281]  bus_add_driver+0x149/0x1e0
[2.565283]  driver_register+0x8f/0xe0
[2.565285]  ? 0xc1023000
[2.565286]  do_one_initcall+0x44/0x200
[2.565288]  ? kmem_cache_alloc_trace+0x177/0x2c0
[2.565290]  do_init_module+0x4c/0x250
[2.565291]  __do_sys_init_module+0x12e/0x1b0
[2.565294]  do_syscall_64+0x3b/0x90
[2.565296]  entry_SYSCALL_64_after_hwframe+0x44/0xae
[2.565297] RIP: 0033:0x7fc69bff232e
[2.565298] Code: 48 8b 0d 45 0b 0c 00 f7 d8 64 89 01 48 83 c8 ff c3 66 2e 
0f 1f 84 00 00 00 00 00 90 f3 0f 1e fa 49 89 ca b8 af 00 00 00 0f 05 <48> 3d 01 
f0 ff ff 73 01 c3 48 8b 0d 12 0b 0c 00 f7 d8 64 89 01 48
[2.565299] RSP: 002b:7ffe872ba3e8 EFLAGS: 0246 ORIG_RAX: 
00af
[2.565301] RAX: ffda RBX: 55873f797820 RCX: 7fc69bff232e
[2.565302] RDX: 55873f7bf390 RSI: 01155e81 RDI: 7fc699e4d010
[2.565303] RBP: 7fc699e4d010 R08: 55873f7bfe20 R09: 01155e90
[2.565303] R10: 00055873f7bf R11: 0246 R12: 55873f7bf390
[2.565304] R13: 000d R14: 55873f7c4cb0 R15: 55873f797820
[2.565306]  
[2.565307] ---[ end trace  ]---

Fixes: d77de7880e0e0 ("amd/display: enable panel orientation quirks")
Signed-off-by: Melissa Wen 
---
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c  | 18 +++---
 1 file changed, 15 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
index 0d54c1486739..c2806695589a 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -4133,6 +4133,7 @@ static voi

Re: [PATCH 1/2] drm/amd/display: change variables type

2022-07-26 Thread Melissa Wen
On 07/26, Magali Lemes wrote:
> On 7/25/22 20:38, Melissa Wen wrote:
> 
> > On 07/25, Magali Lemes wrote:
> > > On 7/25/22 16:42, André Almeida wrote:
> > > > Hi Magali,
> > > > 
> > > > Às 15:15 de 25/07/22, Magali Lemes escreveu:
> > > > > As "dcn3_15_soc" and "dcn3_16_soc" are of type "struct
> > > > > _vcs_dpi_soc_bounding_box_st", change their types accordingly.
> > > > > 
> > > > I can see that indeed this type change sense for those variables, but
> > > > isn't a bit strange that the type was wrong in the first place? I wonder
> > > > if this variable is even used, given that it would very likely throw a
> > > > compiler error when using the wrong type and trying to access struct
> > > > members that aren't defined.
> > > 
> > > A compilation error would be thrown if either 
> > > "dc/dcn315/dcn315_resource.h"
> > > or "dc/dcn316/dcn316_resource.h" were included in the files where
> > > "dcn3_15_soc" and "dcn3_16_soc" are initialized. Since they are not
> > > included, the wrong variable type error is not shown.
> > > To solve the sparse warning in the second patch of this series, those
> > > variables need to be declared first, but they are already declared, we're
> > > only missing the headers. If I only add the headers, then those variables
> > > will be seen, and I get the expected incompatible variables types error. 
> > > So,
> > > fixing the types here is a preliminary work for the next patch.
> > > 
> > Hi Magali,
> > 
> > Thanks for inspecting it. What you say makes sense, but André pointed
> > out something that makes sense to me too.
> > 
> > As fas as I checked, dcn3_15_soc and dcn16_soc is not used outside their
> > respective FPU files. Maybe the proper solution is removing those
> > declarations (and make the struct static). Can you take a look at it?
> > 
> > Best Regards,
> > 
> > Melissa
> 
> Hi, Melissa. Thank you for the suggestion!
> My sole reason not to make those structs static was to keep some sort of
> consistency with the rest of the dcn*_resource.h files, since that is where
> all the other structs are first declared. I'm not sure, though, if that's a
> good enough reason not to turn these variables into static. Let me know what
> you think.

I don't see any other file using dcn3_15_soc, it's only in dcn30_fpu, so
better make it static. Also, I see that doing this will ring a bell
for some misuse of the struct outside FPU protection, in the future.

With those points addressed, you can add in the next version:

Reviewed-by: Melissa Wen 

Thanks,

Melissa

> 
> Magali
> 
> 
> 
> > Magali
> > 
> > 
> > > > > Signed-off-by: Magali Lemes 
> > > > > ---
> > > > >drivers/gpu/drm/amd/display/dc/dcn315/dcn315_resource.h | 2 +-
> > > > >drivers/gpu/drm/amd/display/dc/dcn316/dcn316_resource.h | 2 +-
> > > > >2 files changed, 2 insertions(+), 2 deletions(-)
> > > > > 
> > > > > diff --git a/drivers/gpu/drm/amd/display/dc/dcn315/dcn315_resource.h 
> > > > > b/drivers/gpu/drm/amd/display/dc/dcn315/dcn315_resource.h
> > > > > index 39929fa67a51..45276317c057 100644
> > > > > --- a/drivers/gpu/drm/amd/display/dc/dcn315/dcn315_resource.h
> > > > > +++ b/drivers/gpu/drm/amd/display/dc/dcn315/dcn315_resource.h
> > > > > @@ -32,7 +32,7 @@
> > > > >   container_of(pool, struct dcn315_resource_pool, base)
> > > > >extern struct _vcs_dpi_ip_params_st dcn3_15_ip;
> > > > > -extern struct _vcs_dpi_ip_params_st dcn3_15_soc;
> > > > > +extern struct _vcs_dpi_soc_bounding_box_st dcn3_15_soc;
> > > > >struct dcn315_resource_pool {
> > > > >   struct resource_pool base;
> > > > > diff --git a/drivers/gpu/drm/amd/display/dc/dcn316/dcn316_resource.h 
> > > > > b/drivers/gpu/drm/amd/display/dc/dcn316/dcn316_resource.h
> > > > > index 0dc5a6c13ae7..d2234aac5449 100644
> > > > > --- a/drivers/gpu/drm/amd/display/dc/dcn316/dcn316_resource.h
> > > > > +++ b/drivers/gpu/drm/amd/display/dc/dcn316/dcn316_resource.h
> > > > > @@ -32,7 +32,7 @@
> > > > >   container_of(pool, struct dcn316_resource_pool, base)
> > > > >extern struct _vcs_dpi_ip_params_st dcn3_16_ip;
> > > > > -extern struct _vcs_dpi_ip_params_st dcn3_16_soc;
> > > > > +extern struct _vcs_dpi_soc_bounding_box_st dcn3_16_soc;
> > > > >struct dcn316_resource_pool {
> > > > >   struct resource_pool base;


signature.asc
Description: PGP signature


<    1   2   3   4   5   >