[Nouveau] [PATCH v2] drm/nouveau/kms/gf119-: add ctm property support

2019-06-11 Thread Ilia Mirkin
This adds support on GF119:GV100 (exclusive) for CTM (aka CSC).

Signed-off-by: Ilia Mirkin 
---

v1 -> v2:
 - ctm -> csc
 - mark csc.valid = false when there is no ctm property

 drivers/gpu/drm/nouveau/dispnv50/atom.h |  6 ++
 drivers/gpu/drm/nouveau/dispnv50/base907c.c | 65 +
 drivers/gpu/drm/nouveau/dispnv50/wndw.c | 16 +
 drivers/gpu/drm/nouveau/dispnv50/wndw.h |  4 ++
 4 files changed, 91 insertions(+)

diff --git a/drivers/gpu/drm/nouveau/dispnv50/atom.h 
b/drivers/gpu/drm/nouveau/dispnv50/atom.h
index b5fae5ab3fa8..75bda111da10 100644
--- a/drivers/gpu/drm/nouveau/dispnv50/atom.h
+++ b/drivers/gpu/drm/nouveau/dispnv50/atom.h
@@ -184,6 +184,11 @@ struct nv50_wndw_atom {
} i;
} xlut;
 
+   struct {
+   u32 matrix[12];
+   bool valid;
+   } csc;
+
struct {
u8  mode:2;
u8  interval:4;
@@ -221,6 +226,7 @@ struct nv50_wndw_atom {
bool ntfy:1;
bool sema:1;
bool xlut:1;
+   bool csc:1;
bool image:1;
bool scale:1;
bool point:1;
diff --git a/drivers/gpu/drm/nouveau/dispnv50/base907c.c 
b/drivers/gpu/drm/nouveau/dispnv50/base907c.c
index 049ce6da321c..fd0c1d84730b 100644
--- a/drivers/gpu/drm/nouveau/dispnv50/base907c.c
+++ b/drivers/gpu/drm/nouveau/dispnv50/base907c.c
@@ -83,6 +83,68 @@ base907c_ilut(struct nv50_wndw *wndw, struct nv50_wndw_atom 
*asyw)
asyw->xlut.i.load = head907d_olut_load;
 }
 
+static inline u32
+csc_drm_to_base(u64 in)
+{
+   /* base takes a 19-bit 2's complement value in S3.16 format */
+   bool sign = in & BIT_ULL(63);
+   u32 integer = (in >> 32) & 0x7fff;
+   u32 fraction = in & 0x;
+
+   if (integer >= 4) {
+   return (1 << 18) - (sign ? 0 : 1);
+   } else {
+   u32 ret = (integer << 16) | (fraction >> 16);
+   if (sign)
+   ret = -ret;
+   return ret & GENMASK(18, 0);
+   }
+}
+
+static void
+base907c_csc(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw,
+const struct drm_color_ctm *ctm)
+{
+   int i, j;
+
+   for (j = 0; j < 3; j++) {
+   for (i = 0; i < 4; i++) {
+   u32 *val = >csc.matrix[j * 4 + i];
+   /* DRM does not support constant offset, while
+* HW CSC does. Skip it. */
+   if (i == 3) {
+   *val = 0;
+   } else {
+   *val = csc_drm_to_base(ctm->matrix[j * 3 + i]);
+   }
+   }
+   }
+}
+
+static void
+base907c_csc_clr(struct nv50_wndw *wndw)
+{
+   u32 *push;
+   if ((push = evo_wait(>wndw, 2))) {
+   evo_mthd(push, 0x0140, 1);
+   evo_data(push, 0x);
+   evo_kick(push, >wndw);
+   }
+}
+
+static void
+base907c_csc_set(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw)
+{
+   u32 *push, i;
+   if ((push = evo_wait(>wndw, 13))) {
+   evo_mthd(push, 0x0140, 12);
+   evo_data(push, asyw->csc.matrix[0] | 0x8000);
+   for (i = 1; i < 12; i++)
+   evo_data(push, asyw->csc.matrix[i]);
+   evo_kick(push, >wndw);
+   }
+}
+
 const struct nv50_wndw_func
 base907c = {
.acquire = base507c_acquire,
@@ -94,6 +156,9 @@ base907c = {
.ntfy_clr = base507c_ntfy_clr,
.ntfy_wait_begun = base507c_ntfy_wait_begun,
.ilut = base907c_ilut,
+   .csc = base907c_csc,
+   .csc_set = base907c_csc_set,
+   .csc_clr = base907c_csc_clr,
.olut_core = true,
.xlut_set = base907c_xlut_set,
.xlut_clr = base907c_xlut_clr,
diff --git a/drivers/gpu/drm/nouveau/dispnv50/wndw.c 
b/drivers/gpu/drm/nouveau/dispnv50/wndw.c
index 3bee1f063dfb..76843e8231c1 100644
--- a/drivers/gpu/drm/nouveau/dispnv50/wndw.c
+++ b/drivers/gpu/drm/nouveau/dispnv50/wndw.c
@@ -118,6 +118,7 @@ nv50_wndw_flush_clr(struct nv50_wndw *wndw, u32 *interlock, 
bool flush,
if (clr.sema ) wndw->func-> sema_clr(wndw);
if (clr.ntfy ) wndw->func-> ntfy_clr(wndw);
if (clr.xlut ) wndw->func-> xlut_clr(wndw);
+   if (clr.csc  ) wndw->func->  csc_clr(wndw);
if (clr.image) wndw->func->image_clr(wndw);
 
interlock[wndw->interlock.type] |= wndw->interlock.data;
@@ -145,6 +146,7 @@ nv50_wndw_flush_set(struct nv50_wndw *wndw, u32 *interlock,
wndw->func->xlut_set(wndw, asyw);
}
 
+   if (asyw->set.csc  ) wndw->func->csc_set  (wndw, asyw);
if (asyw->set.scale) wndw->func->scale_set(wndw, asyw);
if (asyw->set.point) {
if (asyw->set.point = false, asyw->set.mask)
@@ -334,6 +336,8 @@ nv50_wndw_atomic_check_lut(struct 

Re: [PATCH v5 04/11] drm: Convert connector_helper_funcs->atomic_check to accept drm_atomic_state

2019-06-11 Thread Laurent Pinchart
Hi Sean,

Thank you for the patch.

On Tue, Jun 11, 2019 at 12:08:18PM -0400, Sean Paul wrote:
> From: Sean Paul 
> 
> Everyone who implements connector_helper_funcs->atomic_check reaches
> into the connector state to get the atomic state. Instead of continuing
> this pattern, change the callback signature to just give atomic state
> and let the driver determine what it does and does not need from it.
> 
> Eventually all atomic functions should do this, but that's just too much
> busy work for me.
> 
> Changes in v3:
> - Added to the set
> Changes in v4:
> - None
> Changes in v5:
> - intel_digital_connector_atomic_check declaration moved to i915_atomic.h
> 
> Link to v3: 
> https://patchwork.freedesktop.org/patch/msgid/20190502194956.218441-5-s...@poorly.run
> Link to v4: 
> https://patchwork.freedesktop.org/patch/msgid/20190508160920.144739-5-s...@poorly.run
> 
> Cc: Daniel Vetter 
> Cc: Ville Syrjälä 
> Cc: Jani Nikula 
> Cc: Joonas Lahtinen 
> Cc: Rodrigo Vivi 
> Cc: Ben Skeggs 
> Cc: Laurent Pinchart 
> Cc: Kieran Bingham 
> Cc: Eric Anholt 
> Tested-by: Heiko Stuebner 
> Acked-by: Daniel Vetter 
> Signed-off-by: Sean Paul 
> ---
>  drivers/gpu/drm/drm_atomic_helper.c  |  4 ++--
>  drivers/gpu/drm/i915/intel_atomic.c  |  8 +---
>  drivers/gpu/drm/i915/intel_atomic.h  |  2 +-
>  drivers/gpu/drm/i915/intel_dp_mst.c  |  7 ---
>  drivers/gpu/drm/i915/intel_sdvo.c|  9 +
>  drivers/gpu/drm/i915/intel_tv.c  |  8 +---
>  drivers/gpu/drm/nouveau/dispnv50/disp.c  |  5 +++--
>  drivers/gpu/drm/rcar-du/rcar_lvds.c  | 12 +++-

For the R-Car LVDS driver,

Reviewed-by: Laurent Pinchart 

>  drivers/gpu/drm/vc4/vc4_txp.c|  7 ---
>  include/drm/drm_modeset_helper_vtables.h |  2 +-
>  10 files changed, 37 insertions(+), 27 deletions(-)
> 
> diff --git a/drivers/gpu/drm/drm_atomic_helper.c 
> b/drivers/gpu/drm/drm_atomic_helper.c
> index 2133f62539176..e58be69960692 100644
> --- a/drivers/gpu/drm/drm_atomic_helper.c
> +++ b/drivers/gpu/drm/drm_atomic_helper.c
> @@ -686,7 +686,7 @@ drm_atomic_helper_check_modeset(struct drm_device *dev,
>   }
>  
>   if (funcs->atomic_check)
> - ret = funcs->atomic_check(connector, 
> new_connector_state);
> + ret = funcs->atomic_check(connector, state);
>   if (ret)
>   return ret;
>  
> @@ -728,7 +728,7 @@ drm_atomic_helper_check_modeset(struct drm_device *dev,
>   continue;
>  
>   if (funcs->atomic_check)
> - ret = funcs->atomic_check(connector, 
> new_connector_state);
> + ret = funcs->atomic_check(connector, state);
>   if (ret)
>   return ret;
>   }
> diff --git a/drivers/gpu/drm/i915/intel_atomic.c 
> b/drivers/gpu/drm/i915/intel_atomic.c
> index 58b8049649a0f..ab40448a19d56 100644
> --- a/drivers/gpu/drm/i915/intel_atomic.c
> +++ b/drivers/gpu/drm/i915/intel_atomic.c
> @@ -106,12 +106,14 @@ int intel_digital_connector_atomic_set_property(struct 
> drm_connector *connector,
>  }
>  
>  int intel_digital_connector_atomic_check(struct drm_connector *conn,
> -  struct drm_connector_state *new_state)
> +  struct drm_atomic_state *state)
>  {
> + struct drm_connector_state *new_state =
> + drm_atomic_get_new_connector_state(state, conn);
>   struct intel_digital_connector_state *new_conn_state =
>   to_intel_digital_connector_state(new_state);
>   struct drm_connector_state *old_state =
> - drm_atomic_get_old_connector_state(new_state->state, conn);
> + drm_atomic_get_old_connector_state(state, conn);
>   struct intel_digital_connector_state *old_conn_state =
>   to_intel_digital_connector_state(old_state);
>   struct drm_crtc_state *crtc_state;
> @@ -121,7 +123,7 @@ int intel_digital_connector_atomic_check(struct 
> drm_connector *conn,
>   if (!new_state->crtc)
>   return 0;
>  
> - crtc_state = drm_atomic_get_new_crtc_state(new_state->state, 
> new_state->crtc);
> + crtc_state = drm_atomic_get_new_crtc_state(state, new_state->crtc);
>  
>   /*
>* These properties are handled by fastset, and might not end
> diff --git a/drivers/gpu/drm/i915/intel_atomic.h 
> b/drivers/gpu/drm/i915/intel_atomic.h
> index 1c8507da1a690..58065d3161a34 100644
> --- a/drivers/gpu/drm/i915/intel_atomic.h
> +++ b/drivers/gpu/drm/i915/intel_atomic.h
> @@ -28,7 +28,7 @@ int intel_digital_connector_atomic_set_property(struct 
> drm_connector *connector,
>   struct drm_property *property,
>   u64 val);
>  int intel_digital_connector_atomic_check(struct drm_connector *conn,
> -  struct drm_connector_state *new_state);
> +  

[Nouveau] [PATCH v5 04/11] drm: Convert connector_helper_funcs->atomic_check to accept drm_atomic_state

2019-06-11 Thread Sean Paul
From: Sean Paul 

Everyone who implements connector_helper_funcs->atomic_check reaches
into the connector state to get the atomic state. Instead of continuing
this pattern, change the callback signature to just give atomic state
and let the driver determine what it does and does not need from it.

Eventually all atomic functions should do this, but that's just too much
busy work for me.

Changes in v3:
- Added to the set
Changes in v4:
- None
Changes in v5:
- intel_digital_connector_atomic_check declaration moved to i915_atomic.h

Link to v3: 
https://patchwork.freedesktop.org/patch/msgid/20190502194956.218441-5-s...@poorly.run
Link to v4: 
https://patchwork.freedesktop.org/patch/msgid/20190508160920.144739-5-s...@poorly.run

Cc: Daniel Vetter 
Cc: Ville Syrjälä 
Cc: Jani Nikula 
Cc: Joonas Lahtinen 
Cc: Rodrigo Vivi 
Cc: Ben Skeggs 
Cc: Laurent Pinchart 
Cc: Kieran Bingham 
Cc: Eric Anholt 
Tested-by: Heiko Stuebner 
Acked-by: Daniel Vetter 
Signed-off-by: Sean Paul 
---
 drivers/gpu/drm/drm_atomic_helper.c  |  4 ++--
 drivers/gpu/drm/i915/intel_atomic.c  |  8 +---
 drivers/gpu/drm/i915/intel_atomic.h  |  2 +-
 drivers/gpu/drm/i915/intel_dp_mst.c  |  7 ---
 drivers/gpu/drm/i915/intel_sdvo.c|  9 +
 drivers/gpu/drm/i915/intel_tv.c  |  8 +---
 drivers/gpu/drm/nouveau/dispnv50/disp.c  |  5 +++--
 drivers/gpu/drm/rcar-du/rcar_lvds.c  | 12 +++-
 drivers/gpu/drm/vc4/vc4_txp.c|  7 ---
 include/drm/drm_modeset_helper_vtables.h |  2 +-
 10 files changed, 37 insertions(+), 27 deletions(-)

diff --git a/drivers/gpu/drm/drm_atomic_helper.c 
b/drivers/gpu/drm/drm_atomic_helper.c
index 2133f62539176..e58be69960692 100644
--- a/drivers/gpu/drm/drm_atomic_helper.c
+++ b/drivers/gpu/drm/drm_atomic_helper.c
@@ -686,7 +686,7 @@ drm_atomic_helper_check_modeset(struct drm_device *dev,
}
 
if (funcs->atomic_check)
-   ret = funcs->atomic_check(connector, 
new_connector_state);
+   ret = funcs->atomic_check(connector, state);
if (ret)
return ret;
 
@@ -728,7 +728,7 @@ drm_atomic_helper_check_modeset(struct drm_device *dev,
continue;
 
if (funcs->atomic_check)
-   ret = funcs->atomic_check(connector, 
new_connector_state);
+   ret = funcs->atomic_check(connector, state);
if (ret)
return ret;
}
diff --git a/drivers/gpu/drm/i915/intel_atomic.c 
b/drivers/gpu/drm/i915/intel_atomic.c
index 58b8049649a0f..ab40448a19d56 100644
--- a/drivers/gpu/drm/i915/intel_atomic.c
+++ b/drivers/gpu/drm/i915/intel_atomic.c
@@ -106,12 +106,14 @@ int intel_digital_connector_atomic_set_property(struct 
drm_connector *connector,
 }
 
 int intel_digital_connector_atomic_check(struct drm_connector *conn,
-struct drm_connector_state *new_state)
+struct drm_atomic_state *state)
 {
+   struct drm_connector_state *new_state =
+   drm_atomic_get_new_connector_state(state, conn);
struct intel_digital_connector_state *new_conn_state =
to_intel_digital_connector_state(new_state);
struct drm_connector_state *old_state =
-   drm_atomic_get_old_connector_state(new_state->state, conn);
+   drm_atomic_get_old_connector_state(state, conn);
struct intel_digital_connector_state *old_conn_state =
to_intel_digital_connector_state(old_state);
struct drm_crtc_state *crtc_state;
@@ -121,7 +123,7 @@ int intel_digital_connector_atomic_check(struct 
drm_connector *conn,
if (!new_state->crtc)
return 0;
 
-   crtc_state = drm_atomic_get_new_crtc_state(new_state->state, 
new_state->crtc);
+   crtc_state = drm_atomic_get_new_crtc_state(state, new_state->crtc);
 
/*
 * These properties are handled by fastset, and might not end
diff --git a/drivers/gpu/drm/i915/intel_atomic.h 
b/drivers/gpu/drm/i915/intel_atomic.h
index 1c8507da1a690..58065d3161a34 100644
--- a/drivers/gpu/drm/i915/intel_atomic.h
+++ b/drivers/gpu/drm/i915/intel_atomic.h
@@ -28,7 +28,7 @@ int intel_digital_connector_atomic_set_property(struct 
drm_connector *connector,
struct drm_property *property,
u64 val);
 int intel_digital_connector_atomic_check(struct drm_connector *conn,
-struct drm_connector_state *new_state);
+struct drm_atomic_state *state);
 struct drm_connector_state *
 intel_digital_connector_duplicate_state(struct drm_connector *connector);
 
diff --git a/drivers/gpu/drm/i915/intel_dp_mst.c 
b/drivers/gpu/drm/i915/intel_dp_mst.c
index 0caf645fbbb84..60652ebbdf610 100644
---