Re: [Freedreno] [PATCH v2 20/24] drm/msm: dpu: Use atomic_disable for dpu_crtc_disable

2018-11-19 Thread Jeykumar Sankaran

On 2018-11-16 10:42, Sean Paul wrote:

From: Sean Paul 

Matches dpu_crtc_enable and we'll need the old state in a future patch

Changes in v2:
- None

Signed-off-by: Sean Paul 


Reviewed-by: Jeykumar Sankaran 


---
 drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
index 4d7f9ff1e9f4..9efb41c7973b 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
@@ -815,7 +815,8 @@ static struct drm_crtc_state
*dpu_crtc_duplicate_state(struct drm_crtc *crtc)
return >base;
 }

-static void dpu_crtc_disable(struct drm_crtc *crtc)
+static void dpu_crtc_disable(struct drm_crtc *crtc,
+struct drm_crtc_state *old_crtc_state)
 {
struct dpu_crtc *dpu_crtc;
struct dpu_crtc_state *cstate;
@@ -1407,7 +1408,7 @@ static const struct drm_crtc_funcs dpu_crtc_funcs 
=

{
 };

 static const struct drm_crtc_helper_funcs dpu_crtc_helper_funcs = {
-   .disable = dpu_crtc_disable,
+   .atomic_disable = dpu_crtc_disable,
.atomic_enable = dpu_crtc_enable,
.atomic_check = dpu_crtc_atomic_check,
.atomic_begin = dpu_crtc_atomic_begin,


--
Jeykumar S
___
Freedreno mailing list
Freedreno@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/freedreno


Re: [Freedreno] [PATCH v2 19/24] drm/msm: dpu: Remove vblank_callback from encoder

2018-11-19 Thread Jeykumar Sankaran

On 2018-11-16 10:42, Sean Paul wrote:

From: Sean Paul 

The indirection of registering a callback and opaque pointer isn't 
reall

useful when there's only one callsite. So instead of having the
vblank_cb registration, just give encoder a crtc and let it directly
call the vblank handler.

In a later patch, we'll make use of this further.

Changes in v2:
- None

Cc: Jeykumar Sankaran 
Signed-off-by: Sean Paul 


Reviewed-by: Jeykumar Sankaran 


---
 drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c|  8 +++
 drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h|  6 +
 drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 25 +++--
 drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h | 10 -
 4 files changed, 26 insertions(+), 23 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
index 141ed1b0e90a..4d7f9ff1e9f4 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
@@ -293,9 +293,8 @@ enum dpu_intf_mode dpu_crtc_get_intf_mode(struct
drm_crtc *crtc)
return INTF_MODE_NONE;
 }

-static void dpu_crtc_vblank_cb(void *data)
+void dpu_crtc_vblank_callback(struct drm_crtc *crtc)
 {
-   struct drm_crtc *crtc = (struct drm_crtc *)data;
struct dpu_crtc *dpu_crtc = to_dpu_crtc(crtc);

/* keep statistics on vblank callback - with auto reset via
debugfs */
@@ -771,8 +770,7 @@ static void _dpu_crtc_vblank_enable_no_lock(
 DRMID(enc), enable,
 dpu_crtc);

-   dpu_encoder_register_vblank_callback(enc,
-   dpu_crtc_vblank_cb, (void *)crtc);
+   dpu_encoder_assign_crtc(enc, crtc);
}
} else {
list_for_each_entry(enc, >mode_config.encoder_list,
head) {
@@ -783,7 +781,7 @@ static void _dpu_crtc_vblank_enable_no_lock(
 DRMID(enc), enable,
 dpu_crtc);

-   dpu_encoder_register_vblank_callback(enc, NULL,
NULL);
+   dpu_encoder_assign_crtc(enc, NULL);
}
}
 }
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h
b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h
index 93d21a61a040..54595cc29be5 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h
@@ -270,6 +270,12 @@ static inline int dpu_crtc_frame_pending(struct
drm_crtc *crtc)
  */
 int dpu_crtc_vblank(struct drm_crtc *crtc, bool en);

+/**
+ * dpu_crtc_vblank_callback - called on vblank irq, issues completion
events
+ * @crtc: Pointer to drm crtc object
+ */
+void dpu_crtc_vblank_callback(struct drm_crtc *crtc);
+
 /**
  * dpu_crtc_commit_kickoff - trigger kickoff of the commit for this 
crtc

  * @crtc: Pointer to drm crtc object
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
index d89ac520f7e6..fd6514f681ae 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
@@ -142,9 +142,11 @@ enum dpu_enc_rc_states {
  * @intfs_swapped  Whether or not the phys_enc interfaces have been
swapped
  * for partial update right-only cases, such as
pingpong
  * split where virtual pingpong does not generate
IRQs
- * @crtc_vblank_cb:Callback into the upper layer / CRTC for
- * notification of the VBLANK
- * @crtc_vblank_cb_data:   Data from upper layer for VBLANK
notification
+ * @crtc:  Pointer to the currently assigned crtc. Normally
you
+ * would use crtc->state->encoder_mask to determine
the
+ * link between encoder/crtc. However in this case we
need
+ * to track crtc in the disable() hook which is
called
+ * _after_ encoder_mask is cleared.
  * @crtc_kickoff_cb:   Callback into CRTC that will flush & start
  * all CTL paths
  * @crtc_kickoff_cb_data:  Opaque user data given to crtc_kickoff_cb
@@ -186,8 +188,7 @@ struct dpu_encoder_virt {

bool intfs_swapped;

-   void (*crtc_vblank_cb)(void *);
-   void *crtc_vblank_cb_data;
+   struct drm_crtc *crtc;

struct dentry *debugfs_root;
struct mutex enc_lock;
@@ -1241,8 +1242,8 @@ static void dpu_encoder_vblank_callback(struct
drm_encoder *drm_enc,
dpu_enc = to_dpu_encoder_virt(drm_enc);

spin_lock_irqsave(_enc->enc_spinlock, lock_flags);
-   if (dpu_enc->crtc_vblank_cb)
-   dpu_enc->crtc_vblank_cb(dpu_enc->crtc_vblank_cb_data);
+   if (dpu_enc->crtc)
+   dpu_crtc_vblank_callback(dpu_enc->crtc);
spin_unlock_irqrestore(_enc->enc_spinlock, lock_flags);


Re: [Freedreno] [PATCH v2 18/24] drm/msm: dpu: Remove crtc_lock from setup_mixers

2018-11-19 Thread Jeykumar Sankaran

On 2018-11-16 10:42, Sean Paul wrote:

From: Sean Paul 

I think the intention here was to protect the enc->crtc access, but
that's insufficient to avoid enc->crtc changing. Fortunately we're
already holding the modeset lock when this is called (from
atomic_check), so remove the crtc_lock and add a modeset lock check.

While we're at it, use the encoder mask from crtc state instead of
legacy pointer.

Changes in v2:
- None

Signed-off-by: Sean Paul 


Reviewed-by: Jeykumar Sankaran 


---
 drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c | 12 +++-
 1 file changed, 3 insertions(+), 9 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
index c49aaf412b6e..141ed1b0e90a 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
@@ -474,19 +474,13 @@ static void _dpu_crtc_setup_mixer_for_encoder(

 static void _dpu_crtc_setup_mixers(struct drm_crtc *crtc)
 {
-   struct dpu_crtc *dpu_crtc = to_dpu_crtc(crtc);
struct drm_encoder *enc;

-   mutex_lock(_crtc->crtc_lock);
-   /* Check for mixers on all encoders attached to this crtc */
-   list_for_each_entry(enc, >dev->mode_config.encoder_list,
head) {
-   if (enc->crtc != crtc)
-   continue;
+   WARN_ON(!drm_modeset_is_locked(>mutex));

+   /* Check for mixers on all encoders attached to this crtc */
+   drm_for_each_encoder_mask(enc, crtc->dev,
crtc->state->encoder_mask)
_dpu_crtc_setup_mixer_for_encoder(crtc, enc);
-   }
-
-   mutex_unlock(_crtc->crtc_lock);
 }

 static void _dpu_crtc_setup_lm_bounds(struct drm_crtc *crtc,


--
Jeykumar S
___
Freedreno mailing list
Freedreno@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/freedreno


Re: [Freedreno] [PATCH v2 13/24] drm/msm: dpu: Don't drop locks in crtc_vblank_enable

2018-11-19 Thread Jeykumar Sankaran

On 2018-11-16 10:42, Sean Paul wrote:

From: Sean Paul 

Now that runtime resume is handled in encoder, we don't need to worry
about crtc_lock recursion when calling pm_runtime_(get|put). So drop 
the

lock drops in _dpu_crtc_vblank_enable_no_lock().

Changes in v2:
- None

Signed-off-by: Sean Paul 


Reviewed-by: Jeykumar Sankaran 


---
 drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c | 6 --
 1 file changed, 6 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
index 9be24907f8c1..80de5289ada3 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
@@ -777,10 +777,7 @@ static void _dpu_crtc_vblank_enable_no_lock(
struct drm_encoder *enc;

if (enable) {
-   /* drop lock since power crtc cb may try to re-acquire
lock */
-   mutex_unlock(_crtc->crtc_lock);
pm_runtime_get_sync(dev->dev);
-   mutex_lock(_crtc->crtc_lock);

list_for_each_entry(enc, >mode_config.encoder_list,
head) {
if (enc->crtc != crtc)
@@ -805,10 +802,7 @@ static void _dpu_crtc_vblank_enable_no_lock(
dpu_encoder_register_vblank_callback(enc, NULL,
NULL);
}

-   /* drop lock since power crtc cb may try to re-acquire
lock */
-   mutex_unlock(_crtc->crtc_lock);
pm_runtime_put_sync(dev->dev);
-   mutex_lock(_crtc->crtc_lock);
}
 }


--
Jeykumar S
___
Freedreno mailing list
Freedreno@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/freedreno


Re: [Freedreno] [PATCH v2 05/24] drm/msm: dpu: Handle crtc pm_runtime_resume() directly

2018-11-19 Thread Jeykumar Sankaran

On 2018-11-16 10:42, Sean Paul wrote:

From: Sean Paul 

Instead of registering through dpu_power_handle just to get a call on
runtime_resume, call the crtc function directly.

Changes in v2:
- None

Signed-off-by: Sean Paul 


Reviewed-by: Jeykumar Sankaran 


---
 drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c  | 23 ++-
 drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h  | 10 ++
 drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c   |  4 
 drivers/gpu/drm/msm/disp/dpu1/dpu_trace.h |  8 
 4 files changed, 20 insertions(+), 25 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
index e09209d6c469..c55cb751e2b4 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
@@ -33,7 +33,6 @@
 #include "dpu_plane.h"
 #include "dpu_encoder.h"
 #include "dpu_vbif.h"
-#include "dpu_power_handle.h"
 #include "dpu_core_perf.h"
 #include "dpu_trace.h"

@@ -69,8 +68,6 @@ static void dpu_crtc_destroy(struct drm_crtc *crtc)
if (!crtc)
return;

-   dpu_crtc->phandle = NULL;
-
drm_crtc_cleanup(crtc);
mutex_destroy(_crtc->crtc_lock);
kfree(dpu_crtc);
@@ -844,15 +841,17 @@ static struct drm_crtc_state
*dpu_crtc_duplicate_state(struct drm_crtc *crtc)
return >base;
 }

-static void dpu_crtc_handle_power_event(u32 event_type, void *arg)
+void dpu_crtc_runtime_resume(struct drm_crtc *crtc)
 {
-   struct drm_crtc *crtc = arg;
struct dpu_crtc *dpu_crtc = to_dpu_crtc(crtc);
struct drm_encoder *encoder;

mutex_lock(_crtc->crtc_lock);

-   trace_dpu_crtc_handle_power_event(DRMID(crtc), event_type);
+   if (!dpu_crtc->enabled)
+   goto end;
+
+   trace_dpu_crtc_runtime_resume(DRMID(crtc));

/* restore encoder; crtc will be programmed during commit */
drm_for_each_encoder(encoder, crtc->dev) {
@@ -862,6 +861,7 @@ static void dpu_crtc_handle_power_event(u32
event_type, void *arg)
dpu_encoder_virt_restore(encoder);
}

+end:
mutex_unlock(_crtc->crtc_lock);
 }

@@ -917,10 +917,6 @@ static void dpu_crtc_disable(struct drm_crtc 
*crtc)

dpu_encoder_register_frame_event_callback(encoder, NULL,
NULL);
}

-   if (dpu_crtc->power_event)
-   dpu_power_handle_unregister_event(dpu_crtc->phandle,
-   dpu_crtc->power_event);
-
memset(cstate->mixers, 0, sizeof(cstate->mixers));
cstate->num_mixers = 0;

@@ -972,11 +968,6 @@ static void dpu_crtc_enable(struct drm_crtc *crtc,

/* Enable/restore vblank irq handling */
drm_crtc_vblank_on(crtc);
-
-   dpu_crtc->power_event = dpu_power_handle_register_event(
-   dpu_crtc->phandle, DPU_POWER_EVENT_ENABLE,
-   dpu_crtc_handle_power_event, crtc, dpu_crtc->name);
-
 }

 struct plane_state {
@@ -1522,8 +1513,6 @@ struct drm_crtc *dpu_crtc_init(struct drm_device
*dev, struct drm_plane *plane,
/* initialize event handling */
spin_lock_init(_crtc->event_lock);

-   dpu_crtc->phandle = >phandle;
-
DPU_DEBUG("%s: successfully initialized crtc\n", dpu_crtc->name);
return crtc;
 }
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h
b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h
index 4822602402f9..1dca91d1210f 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h
@@ -151,7 +151,6 @@ struct dpu_crtc_frame_event {
  * @event_worker  : Event worker queue
  * @event_lock: Spinlock around event handling code
  * @phandle: Pointer to power handler
- * @power_event   : registered power event handle
  * @cur_perf  : current performance committed to clock/bandwidth
driver
  */
 struct dpu_crtc {
@@ -187,9 +186,6 @@ struct dpu_crtc {
/* for handling internal event thread */
spinlock_t event_lock;

-   struct dpu_power_handle *phandle;
-   struct dpu_power_event *power_event;
-
struct dpu_core_perf_params cur_perf;

struct dpu_crtc_smmu_state_data smmu_state;
@@ -333,4 +329,10 @@ static inline bool dpu_crtc_is_enabled(struct
drm_crtc *crtc)
return crtc ? crtc->enabled : false;
 }

+/**
+ * dpu_crtc_runtime_resume - called by the top-level on 
pm_runtime_resume

+ * @crtc: CRTC to resume
+ */
+void dpu_crtc_runtime_resume(struct drm_crtc *crtc);
+
 #endif /* _DPU_CRTC_H_ */
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
index ab8574ab8327..654ea5060e02 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
@@ -1137,6 +1137,7 @@ static int __maybe_unused 
dpu_runtime_resume(struct

device *dev)
int rc = -1;
struct platform_device *pdev = to_platform_devi

Re: [Freedreno] [PATCH 1/2] drm/msm/dpu: add dpu encoder uninit

2018-11-19 Thread Jeykumar Sankaran

On 2018-11-16 13:37, Sean Paul wrote:

On Fri, Nov 16, 2018 at 04:35:26PM -0500, Sean Paul wrote:

On Fri, Nov 16, 2018 at 11:22:21AM -0800, Jeykumar Sankaran wrote:
> Add encoder interface to release dpu encoder
> on mode_init failures in kms.
>
> Signed-off-by: Jeykumar Sankaran 
> ---
>  drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 12 ++--
>  drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h |  6 ++
>  2 files changed, 16 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c

b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c

> index dd7ab85..b253165 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
> @@ -422,6 +422,15 @@ void dpu_encoder_get_hw_resources(struct

drm_encoder *drm_enc,

>}
>  }
>
> +void dpu_encoder_uninit(struct drm_encoder *drm_enc)
> +{
> +  struct dpu_encoder_virt *dpu_enc = to_dpu_encoder_virt(drm_enc);
> +
> +  drm_encoder_cleanup(drm_enc);
> +
> +  kfree(dpu_enc);
> +}
> +
>  static void dpu_encoder_destroy(struct drm_encoder *drm_enc)
>  {
>struct dpu_encoder_virt *dpu_enc = NULL;
> @@ -453,10 +462,9 @@ static void dpu_encoder_destroy(struct

drm_encoder *drm_enc)

>dpu_enc->num_phys_encs = 0;
>mutex_unlock(_enc->enc_lock);
>
> -  drm_encoder_cleanup(drm_enc);
>mutex_destroy(_enc->enc_lock);
>
> -  kfree(dpu_enc);
> +  dpu_encoder_uninit(drm_enc);
>  }
>
>  void dpu_encoder_helper_split_config(
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h

b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h

> index 9dbf38f..60b88bd 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h
> @@ -142,6 +142,12 @@ struct drm_encoder *dpu_encoder_init(
>int drm_enc_mode);
>
>  /**
> + * dpu_encoder_uninit - uninitialize virtual encoder object
> + * @drm_enc:  Pointer to drm encoder
> + */
> +void dpu_encoder_uninit(struct drm_encoder *drm_enc);

Just make it static?


I just saw YueHaibing's patch to remove the kfree entirely since 
dpu_enc

is
devm_* managed. IMO, that'd be a better solution than this.

Sean


I still need the unint here to call drm_encoder_cleanup
if the display mode_init fails.

I will rebase the patch on top of https://lkml.org/lkml/2018/11/17/87

Thanks,
Jeykumar S.




> +
> +/**
>   * dpu_encoder_setup - setup dpu_encoder for the display probed
>   * @dev:  Pointer to drm device structure
>   * @enc:  Pointer to the drm_encoder
> --
> The Qualcomm Innovation Center, Inc. is a member of the Code Aurora

Forum,

> a Linux Foundation Collaborative Project
>

--
Sean Paul, Software Engineer, Google / Chromium OS


--
Jeykumar S
___
Freedreno mailing list
Freedreno@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/freedreno


Re: [Freedreno] [PATCH 1/2] drm/msm/dpu: add dpu encoder uninit

2018-11-19 Thread Jeykumar Sankaran

On 2018-11-16 13:35, Sean Paul wrote:

On Fri, Nov 16, 2018 at 11:22:21AM -0800, Jeykumar Sankaran wrote:

Add encoder interface to release dpu encoder
on mode_init failures in kms.

Signed-off-by: Jeykumar Sankaran 
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 12 ++--
 drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h |  6 ++
 2 files changed, 16 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c

b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c

index dd7ab85..b253165 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
@@ -422,6 +422,15 @@ void dpu_encoder_get_hw_resources(struct

drm_encoder *drm_enc,

}
 }

+void dpu_encoder_uninit(struct drm_encoder *drm_enc)
+{
+   struct dpu_encoder_virt *dpu_enc = to_dpu_encoder_virt(drm_enc);
+
+   drm_encoder_cleanup(drm_enc);
+
+   kfree(dpu_enc);
+}
+
 static void dpu_encoder_destroy(struct drm_encoder *drm_enc)
 {
struct dpu_encoder_virt *dpu_enc = NULL;
@@ -453,10 +462,9 @@ static void dpu_encoder_destroy(struct 
drm_encoder

*drm_enc)

dpu_enc->num_phys_encs = 0;
mutex_unlock(_enc->enc_lock);

-   drm_encoder_cleanup(drm_enc);
mutex_destroy(_enc->enc_lock);

-   kfree(dpu_enc);
+   dpu_encoder_uninit(drm_enc);
 }

 void dpu_encoder_helper_split_config(
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h

b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h

index 9dbf38f..60b88bd 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h
@@ -142,6 +142,12 @@ struct drm_encoder *dpu_encoder_init(
int drm_enc_mode);

 /**
+ * dpu_encoder_uninit - uninitialize virtual encoder object
+ * @drm_enc:  Pointer to drm encoder
+ */
+void dpu_encoder_uninit(struct drm_encoder *drm_enc);


Just make it static?

encoder_uninit will be called by dpu_kms in patch 2/2 in case
of mode_init failures.

Thanks and Regards,
Jeykumar S.



+
+/**
  * dpu_encoder_setup - setup dpu_encoder for the display probed
  * @dev:   Pointer to drm device structure
  * @enc:   Pointer to the drm_encoder
--
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora

Forum,

a Linux Foundation Collaborative Project



--
Jeykumar S
___
Freedreno mailing list
Freedreno@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/freedreno


Re: [Freedreno] [PATCH v2 3/3] drm/msm: dpu: Make legacy cursor updates asynchronous

2018-11-19 Thread Jeykumar Sankaran

On 2018-11-16 12:02, Sean Paul wrote:

On Thu, Nov 08, 2018 at 02:00:51PM -0800, Jeykumar Sankaran wrote:

On 2018-10-30 09:00, Sean Paul wrote:
> From: Sean Paul 
>
> This patch sprinkles a few async/legacy_cursor_update checks
> through commit to ensure that cursor updates aren't blocked on vsync.
> There are 2 main components to this, the first is that we don't want

to

> wait_for_commit_done in msm_atomic  before returning from
> atomic_complete.
> The second is that in dpu we don't want to wait for frame_done events
> when
> updating the cursor.
>
> Changes in v2:
> - None
>
> Signed-off-by: Sean Paul 
> ---
>  drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c| 44

+++--

>  drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h|  3 +-
>  drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 22 +++
>  drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h |  6 ++-
>  drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c |  5 ++-
>  drivers/gpu/drm/msm/msm_atomic.c|  3 +-
>  6 files changed, 49 insertions(+), 34 deletions(-)
>
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
> b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
> index ed84cf44a222..1e3e57817b72 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
> @@ -702,7 +702,7 @@ static int _dpu_crtc_wait_for_frame_done(struct
> drm_crtc *crtc)
>return rc;
>  }
>
> -void dpu_crtc_commit_kickoff(struct drm_crtc *crtc)
> +void dpu_crtc_commit_kickoff(struct drm_crtc *crtc, bool async)
>  {
>struct drm_encoder *encoder;
>struct drm_device *dev = crtc->dev;
> @@ -731,27 +731,30 @@ void dpu_crtc_commit_kickoff(struct drm_crtc
> *crtc)
> * Encoder will flush/start now, unless it has a tx
> pending.
> * If so, it may delay and flush at an irq event (e.g.
> ppdone)
> */
> -  dpu_encoder_prepare_for_kickoff(encoder, );
> +  dpu_encoder_prepare_for_kickoff(encoder, , async);
>}
>
> -  /* wait for frame_event_done completion */
> -  DPU_ATRACE_BEGIN("wait_for_frame_done_event");
> -  ret = _dpu_crtc_wait_for_frame_done(crtc);
> -  DPU_ATRACE_END("wait_for_frame_done_event");
> -  if (ret) {
> -  DPU_ERROR("crtc%d wait for frame done
> failed;frame_pending%d\n",
> -  crtc->base.id,
> -  atomic_read(_crtc->frame_pending));
> -  goto end;
> -  }
>
> -  if (atomic_inc_return(_crtc->frame_pending) == 1) {
> -  /* acquire bandwidth and other resources */
> -  DPU_DEBUG("crtc%d first commit\n", crtc->base.id);
> -  } else
> -  DPU_DEBUG("crtc%d commit\n", crtc->base.id);
> +  if (!async) {
> +  /* wait for frame_event_done completion */
> +  DPU_ATRACE_BEGIN("wait_for_frame_done_event");
> +  ret = _dpu_crtc_wait_for_frame_done(crtc);
> +  DPU_ATRACE_END("wait_for_frame_done_event");
> +  if (ret) {
> +  DPU_ERROR("crtc%d wait for frame done
> failed;frame_pending%d\n",
> +  crtc->base.id,
> +
> atomic_read(_crtc->frame_pending));
> +  goto end;
> +  }
> +
> +  if (atomic_inc_return(_crtc->frame_pending) == 1) {
> +  /* acquire bandwidth and other resources */
> +  DPU_DEBUG("crtc%d first commit\n", crtc->base.id);
> +  } else
> +  DPU_DEBUG("crtc%d commit\n", crtc->base.id);
>
> -  dpu_crtc->play_count++;
> +  dpu_crtc->play_count++;
> +  }
>
>dpu_vbif_clear_errors(dpu_kms);
>
> @@ -759,11 +762,12 @@ void dpu_crtc_commit_kickoff(struct drm_crtc
> *crtc)
>if (encoder->crtc != crtc)
>continue;
>
> -  dpu_encoder_kickoff(encoder);
> +  dpu_encoder_kickoff(encoder, async);
>}
>
>  end:
> -  reinit_completion(_crtc->frame_done_comp);
> +  if (!async)
> +  reinit_completion(_crtc->frame_done_comp);
>DPU_ATRACE_END("crtc_commit");
>  }
>
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h
> b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h
> index 4822602402f9..ec633ce3ee6c 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h
> @@ -277,8 +277,9 @@ int dpu_crtc_vblank(struct drm_crtc *crtc, bool

en);

>  /**
>   * dpu_crtc_commit_kickoff - trigger kickoff of the commit for this
> crtc
>   * @crtc: Pointer to drm crtc object
> + * @async: true if the commit is asy

Re: [Freedreno] [PATCH v2 16/24] drm/msm: dpu: Add modeset lock checks where applicable

2018-11-16 Thread Jeykumar Sankaran

On 2018-11-16 10:42, Sean Paul wrote:

From: Sean Paul 

Add modeset lock checks to functions that could be called outside the
core atomic stack.

Changes in v2:
- None

Signed-off-by: Sean Paul 
---


Reviewed-by: Jeykumar Sankaran 


 drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c | 2 ++
 drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c  | 1 +
 2 files changed, 3 insertions(+)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
index a008a87a8113..cd0a0bea4335 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
@@ -284,6 +284,8 @@ enum dpu_intf_mode dpu_crtc_get_intf_mode(struct
drm_crtc *crtc)
return INTF_MODE_NONE;
}

+   WARN_ON(!drm_modeset_is_locked(>mutex));
+
/* TODO: Returns the first INTF_MODE, could there be multiple
values? */
drm_for_each_encoder_mask(encoder, crtc->dev,
crtc->state->encoder_mask)
return dpu_encoder_get_intf_mode(encoder);
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
index 64134d619748..5104fc01147e 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
@@ -358,6 +358,7 @@ void dpu_kms_encoder_enable(struct drm_encoder
*encoder)
if (funcs && funcs->commit)
funcs->commit(encoder);

+
WARN_ON(!drm_modeset_is_locked(>mode_config.connection_mutex));
drm_for_each_crtc(crtc, dev) {
if (!(crtc->state->encoder_mask &
drm_encoder_mask(encoder)))
continue;


--
Jeykumar S
___
Freedreno mailing list
Freedreno@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/freedreno


Re: [Freedreno] [PATCH v2 15/24] drm/msm: dpu: Stop using encoder->crtc pointer

2018-11-16 Thread Jeykumar Sankaran

On 2018-11-16 10:42, Sean Paul wrote:

From: Sean Paul 

It's for legacy drivers, for atomic drivers crtc->state->encoder_mask
should be used to map encoder to crtc.

Changes in v2:
- None

Signed-off-by: Sean Paul 
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c | 46 
 drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c  | 19 +++---
 2 files changed, 29 insertions(+), 36 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
index 156f4c77ca44..a008a87a8113 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
@@ -284,9 +284,9 @@ enum dpu_intf_mode dpu_crtc_get_intf_mode(struct
drm_crtc *crtc)
return INTF_MODE_NONE;
}

-   drm_for_each_encoder(encoder, crtc->dev)
-   if (encoder->crtc == crtc)
-   return dpu_encoder_get_intf_mode(encoder);
+   /* TODO: Returns the first INTF_MODE, could there be multiple
values? */
+   drm_for_each_encoder_mask(encoder, crtc->dev,
crtc->state->encoder_mask)
+   return dpu_encoder_get_intf_mode(encoder);

return INTF_MODE_NONE;
 }
@@ -551,13 +551,9 @@ static void dpu_crtc_atomic_begin(struct drm_crtc
*crtc,
spin_unlock_irqrestore(>event_lock, flags);
}

-   list_for_each_entry(encoder, >mode_config.encoder_list, head)
{
-   if (encoder->crtc != crtc)
-   continue;
-
-   /* encoder will trigger pending mask now */
+   /* encoder will trigger pending mask now */
+   drm_for_each_encoder_mask(encoder, crtc->dev,
crtc->state->encoder_mask)
dpu_encoder_trigger_kickoff_pending(encoder);
-   }

/*
 * If no mixers have been allocated in dpu_crtc_atomic_check(),
@@ -704,7 +700,6 @@ static int _dpu_crtc_wait_for_frame_done(struct
drm_crtc *crtc)
 void dpu_crtc_commit_kickoff(struct drm_crtc *crtc)
 {
struct drm_encoder *encoder;
-   struct drm_device *dev = crtc->dev;
struct dpu_crtc *dpu_crtc = to_dpu_crtc(crtc);
struct dpu_kms *dpu_kms = _dpu_crtc_get_kms(crtc);
struct dpu_crtc_state *cstate = to_dpu_crtc_state(crtc->state);
@@ -720,16 +715,13 @@ void dpu_crtc_commit_kickoff(struct drm_crtc 
*crtc)


DPU_ATRACE_BEGIN("crtc_commit");

-   list_for_each_entry(encoder, >mode_config.encoder_list, head)
{
+   /*
+* Encoder will flush/start now, unless it has a tx pending. If
so, it
+* may delay and flush at an irq event (e.g. ppdone)
+*/
+   drm_for_each_encoder_mask(encoder, crtc->dev,
+ crtc->state->encoder_mask) {
struct dpu_encoder_kickoff_params params = { 0 };
-
-   if (encoder->crtc != crtc)
-   continue;
-
-   /*
-* Encoder will flush/start now, unless it has a tx
pending.
-* If so, it may delay and flush at an irq event (e.g.
ppdone)
-*/
dpu_encoder_prepare_for_kickoff(encoder, );
}

@@ -754,12 +746,8 @@ void dpu_crtc_commit_kickoff(struct drm_crtc 
*crtc)


dpu_vbif_clear_errors(dpu_kms);

-   list_for_each_entry(encoder, >mode_config.encoder_list, head)
{
-   if (encoder->crtc != crtc)
-   continue;
-
+   drm_for_each_encoder_mask(encoder, crtc->dev,
crtc->state->encoder_mask)
dpu_encoder_kickoff(encoder);
-   }
We wont be holding the modeset locks here (and in crtc_atomic_begin) in 
the display thread. Is

it safe to iterate over encoder_mask?


 end:
reinit_completion(_crtc->frame_done_comp);
@@ -883,11 +871,8 @@ static void dpu_crtc_disable(struct drm_crtc 
*crtc)


dpu_core_perf_crtc_update(crtc, 0, true);

-   drm_for_each_encoder(encoder, crtc->dev) {
-   if (encoder->crtc != crtc)
-   continue;
+   drm_for_each_encoder_mask(encoder, crtc->dev,
crtc->state->encoder_mask)
dpu_encoder_register_frame_event_callback(encoder, NULL,
NULL);
-   }

memset(cstate->mixers, 0, sizeof(cstate->mixers));
cstate->num_mixers = 0;
@@ -922,12 +907,9 @@ static void dpu_crtc_enable(struct drm_crtc *crtc,
DRM_DEBUG_KMS("crtc%d\n", crtc->base.id);
dpu_crtc = to_dpu_crtc(crtc);

-   drm_for_each_encoder(encoder, crtc->dev) {
-   if (encoder->crtc != crtc)
-   continue;
+   drm_for_each_encoder_mask(encoder, crtc->dev,
crtc->state->encoder_mask)
dpu_encoder_register_frame_event_callback(encoder,
dpu_crtc_frame_event_cb, (void *)crtc);
-   }

mutex_lock(_crtc->crtc_lock);
trace_dpu_crtc_enable(DRMID(crtc), true, dpu_crtc);
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
index 1bec4540f3e1..64134d619748 100644
--- 

Re: [Freedreno] [PATCH v2 14/24] drm/msm: dpu: Grab the modeset locks in frame_event

2018-11-16 Thread Jeykumar Sankaran

On 2018-11-16 10:42, Sean Paul wrote:

From: Sean Paul 

This patch wraps dpu_core_perf_crtc_release_bw() with modeset locks
since it digs into the state objects.

Changes in v2:
- None

Signed-off-by: Sean Paul 
---

Reviewed-by: Jeykumar Sankaran 


 drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
index 80de5289ada3..156f4c77ca44 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
@@ -335,7 +335,9 @@ static void dpu_crtc_frame_event_work(struct
kthread_work *work)
/* release bandwidth and other resources */
trace_dpu_crtc_frame_event_done(DRMID(crtc),
fevent->event);
+   drm_modeset_lock_all(crtc->dev);
dpu_core_perf_crtc_release_bw(crtc);
+   drm_modeset_unlock_all(crtc->dev);
We might need to revisit this locking when we measure for performance as 
it

could block the incoming frame locking.


} else {

trace_dpu_crtc_frame_event_more_pending(DRMID(crtc),

fevent->event);


--
Jeykumar S
___
Freedreno mailing list
Freedreno@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/freedreno


[Freedreno] [PATCH 2/2] drm/msm/dpu: add display port support in DPU

2018-11-16 Thread Jeykumar Sankaran
Add display port support in DPU by creating hooks
for DP encoder enumeration and encoder mode
initialization.

This change is based on the SDM845 Display port
driver changes[1].

[1] https://lwn.net/Articles/768265/

Signed-off-by: Jeykumar Sankaran 
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c |  3 ++
 drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c | 49 +
 2 files changed, 46 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
index b253165..e9c7edc6 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
@@ -2048,6 +2048,9 @@ static int dpu_encoder_setup_display(struct 
dpu_encoder_virt *dpu_enc,
case DRM_MODE_ENCODER_DSI:
intf_type = INTF_DSI;
break;
+   case DRM_MODE_ENCODER_TMDS:
+   intf_type = INTF_DP;
+   break;
default:
DPU_ERROR_ENC(dpu_enc, "unsupported display interface type\n");
return -EINVAL;
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
index 985c855..b823a37 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
@@ -473,6 +473,31 @@ static void _dpu_kms_initialize_dsi(struct drm_device *dev,
}
 }
 
+static void _dpu_kms_initialize_displayport(struct drm_device *dev,
+   struct msm_drm_private *priv,
+   struct dpu_kms *dpu_kms)
+{
+   struct drm_encoder *encoder = NULL;
+   int rc;
+
+   if (!priv->dp)
+   return;
+
+   encoder = dpu_encoder_init(dev, DRM_MODE_ENCODER_TMDS);
+   if (IS_ERR_OR_NULL(encoder)) {
+   DPU_ERROR("encoder init failed for dsi display\n");
+   return;
+   }
+
+   priv->encoders[priv->num_encoders++] = encoder;
+
+   rc = msm_dp_modeset_init(priv->dp, dev, encoder);
+   if (rc) {
+   DPU_ERROR("modeset_init failed for DP, rc = %d\n", rc);
+   dpu_encoder_uninit(encoder);
+   }
+}
+
 /**
  * _dpu_kms_setup_displays - create encoders, bridges and connectors
  *   for underlying displays
@@ -487,6 +512,8 @@ static void _dpu_kms_setup_displays(struct drm_device *dev,
 {
_dpu_kms_initialize_dsi(dev, priv, dpu_kms);
 
+   _dpu_kms_initialize_displayport(dev, priv, dpu_kms);
+
/**
 * Extend this function to initialize other
 * types of displays
@@ -723,13 +750,23 @@ static void _dpu_kms_set_encoder_mode(struct msm_kms *kms,
info.capabilities = cmd_mode ? MSM_DISPLAY_CAP_CMD_MODE :
MSM_DISPLAY_CAP_VID_MODE;
 
-   /* TODO: No support for DSI swap */
-   for (i = 0; i < ARRAY_SIZE(priv->dsi); i++) {
-   if (priv->dsi[i]) {
-   info.h_tile_instance[info.num_of_h_tiles] = i;
-   info.num_of_h_tiles++;
+   switch (info.intf_type) {
+   case DRM_MODE_ENCODER_DSI:
+   /* TODO: No support for DSI swap */
+   for (i = 0; i < ARRAY_SIZE(priv->dsi); i++) {
+   if (priv->dsi[i]) {
+   info.h_tile_instance[info.num_of_h_tiles] = i;
+   info.num_of_h_tiles++;
+   }
}
-   }
+   break;
+   case DRM_MODE_ENCODER_TMDS:
+   info.num_of_h_tiles = 1;
+   break;
+   default:
+   DPU_ERROR("Invalid connector type\n");
+   return;
+   };
 
rc = dpu_encoder_setup(encoder->dev, encoder, );
if (rc)
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project

___
Freedreno mailing list
Freedreno@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/freedreno


[Freedreno] [PATCH 1/2] drm/msm/dpu: add dpu encoder uninit

2018-11-16 Thread Jeykumar Sankaran
Add encoder interface to release dpu encoder
on mode_init failures in kms.

Signed-off-by: Jeykumar Sankaran 
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 12 ++--
 drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h |  6 ++
 2 files changed, 16 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
index dd7ab85..b253165 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
@@ -422,6 +422,15 @@ void dpu_encoder_get_hw_resources(struct drm_encoder 
*drm_enc,
}
 }
 
+void dpu_encoder_uninit(struct drm_encoder *drm_enc)
+{
+   struct dpu_encoder_virt *dpu_enc = to_dpu_encoder_virt(drm_enc);
+
+   drm_encoder_cleanup(drm_enc);
+
+   kfree(dpu_enc);
+}
+
 static void dpu_encoder_destroy(struct drm_encoder *drm_enc)
 {
struct dpu_encoder_virt *dpu_enc = NULL;
@@ -453,10 +462,9 @@ static void dpu_encoder_destroy(struct drm_encoder 
*drm_enc)
dpu_enc->num_phys_encs = 0;
mutex_unlock(_enc->enc_lock);
 
-   drm_encoder_cleanup(drm_enc);
mutex_destroy(_enc->enc_lock);
 
-   kfree(dpu_enc);
+   dpu_encoder_uninit(drm_enc);
 }
 
 void dpu_encoder_helper_split_config(
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h
index 9dbf38f..60b88bd 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h
@@ -142,6 +142,12 @@ struct drm_encoder *dpu_encoder_init(
int drm_enc_mode);
 
 /**
+ * dpu_encoder_uninit - uninitialize virtual encoder object
+ * @drm_enc:  Pointer to drm encoder
+ */
+void dpu_encoder_uninit(struct drm_encoder *drm_enc);
+
+/**
  * dpu_encoder_setup - setup dpu_encoder for the display probed
  * @dev:   Pointer to drm device structure
  * @enc:   Pointer to the drm_encoder
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project

___
Freedreno mailing list
Freedreno@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/freedreno


[Freedreno] [PATCH v3 5/5] drm/msm: subclass work object for vblank events

2018-11-15 Thread Jeykumar Sankaran
msm maintains a separate structure to define vblank
work definitions and a list to track events submitted
to the workqueue. We can avoid this redundant list
and its protection mechanism, if we subclass the
work object to encapsulate vblank event parameters.

changes in v2:
- subclass optimization on system wq (Sean Paul)
changes in v3:
- none

Signed-off-by: Jeykumar Sankaran 
---
 drivers/gpu/drm/msm/msm_drv.c | 65 +--
 drivers/gpu/drm/msm/msm_drv.h |  7 -
 2 files changed, 19 insertions(+), 53 deletions(-)

diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c
index 478c14c..3f9064d 100644
--- a/drivers/gpu/drm/msm/msm_drv.c
+++ b/drivers/gpu/drm/msm/msm_drv.c
@@ -203,61 +203,44 @@ u32 msm_readl(const void __iomem *addr)
return val;
 }
 
-struct vblank_event {
-   struct list_head node;
+struct msm_vblank_work {
+   struct work_struct work;
int crtc_id;
bool enable;
+   struct msm_drm_private *priv;
 };
 
 static void vblank_ctrl_worker(struct work_struct *work)
 {
-   struct msm_vblank_ctrl *vbl_ctrl = container_of(work,
-   struct msm_vblank_ctrl, work);
-   struct msm_drm_private *priv = container_of(vbl_ctrl,
-   struct msm_drm_private, vblank_ctrl);
+   struct msm_vblank_work *vbl_work = container_of(work,
+   struct msm_vblank_work, work);
+   struct msm_drm_private *priv = vbl_work->priv;
struct msm_kms *kms = priv->kms;
-   struct vblank_event *vbl_ev, *tmp;
-   unsigned long flags;
-
-   spin_lock_irqsave(_ctrl->lock, flags);
-   list_for_each_entry_safe(vbl_ev, tmp, _ctrl->event_list, node) {
-   list_del(_ev->node);
-   spin_unlock_irqrestore(_ctrl->lock, flags);
-
-   if (vbl_ev->enable)
-   kms->funcs->enable_vblank(kms,
-   priv->crtcs[vbl_ev->crtc_id]);
-   else
-   kms->funcs->disable_vblank(kms,
-   priv->crtcs[vbl_ev->crtc_id]);
-
-   kfree(vbl_ev);
 
-   spin_lock_irqsave(_ctrl->lock, flags);
-   }
+   if (vbl_work->enable)
+   kms->funcs->enable_vblank(kms, priv->crtcs[vbl_work->crtc_id]);
+   else
+   kms->funcs->disable_vblank(kms, priv->crtcs[vbl_work->crtc_id]);
 
-   spin_unlock_irqrestore(_ctrl->lock, flags);
+   kfree(vbl_work);
 }
 
 static int vblank_ctrl_queue_work(struct msm_drm_private *priv,
int crtc_id, bool enable)
 {
-   struct msm_vblank_ctrl *vbl_ctrl = >vblank_ctrl;
-   struct vblank_event *vbl_ev;
-   unsigned long flags;
+   struct msm_vblank_work *vbl_work;
 
-   vbl_ev = kzalloc(sizeof(*vbl_ev), GFP_ATOMIC);
-   if (!vbl_ev)
+   vbl_work = kzalloc(sizeof(*vbl_work), GFP_ATOMIC);
+   if (!vbl_work)
return -ENOMEM;
 
-   vbl_ev->crtc_id = crtc_id;
-   vbl_ev->enable = enable;
+   INIT_WORK(_work->work, vblank_ctrl_worker);
 
-   spin_lock_irqsave(_ctrl->lock, flags);
-   list_add_tail(_ev->node, _ctrl->event_list);
-   spin_unlock_irqrestore(_ctrl->lock, flags);
+   vbl_work->crtc_id = crtc_id;
+   vbl_work->enable = enable;
+   vbl_work->priv = priv;
 
-   schedule_work(_ctrl->work);
+   schedule_work(_work->work);
 
return 0;
 }
@@ -269,19 +252,12 @@ static int msm_drm_uninit(struct device *dev)
struct msm_drm_private *priv = ddev->dev_private;
struct msm_kms *kms = priv->kms;
struct msm_mdss *mdss = priv->mdss;
-   struct msm_vblank_ctrl *vbl_ctrl = >vblank_ctrl;
-   struct vblank_event *vbl_ev, *tmp;
int i;
 
/* We must cancel and cleanup any pending vblank enable/disable
 * work before drm_irq_uninstall() to avoid work re-enabling an
 * irq after uninstall has disabled it.
 */
-   flush_work(_ctrl->work);
-   list_for_each_entry_safe(vbl_ev, tmp, _ctrl->event_list, node) {
-   list_del(_ev->node);
-   kfree(vbl_ev);
-   }
 
/* clean up event worker threads */
for (i = 0; i < priv->num_crtcs; i++) {
@@ -469,9 +445,6 @@ static int msm_drm_init(struct device *dev, struct 
drm_driver *drv)
priv->wq = alloc_ordered_workqueue("msm", 0);
 
INIT_LIST_HEAD(>inactive_list);
-   INIT_LIST_HEAD(>vblank_ctrl.event_list);
-   INIT_WORK(>vblank_ctrl.work, vblank_ctrl_worker);
-   spin_lock_init(>vblank_ctrl.lock);
 
drm_mode_config_init(ddev);
 
diff --git a/drivers/gpu/drm/ms

[Freedreno] [PATCH v3 2/5] drm/msm/dpu: use system wq for vblank events

2018-11-15 Thread Jeykumar Sankaran
DPU was using one thread per display to dispatch async commits and
vblank requests. Since clean up already happened in msm to use the
common thread for all the display commits, display threads are only
used to cater vblank requests. Since a single thread is sufficient
to do the job without any performance hits, use system workqueue
to queue requests. A separate patch is submitted later in this
series to remove the display threads altogether.

changes in v2:
- switch to system wq before removing disp threads (Sean Paul)
changes in v3:
- none

Signed-off-by: Jeykumar Sankaran 
---
 drivers/gpu/drm/msm/msm_drv.c | 9 -
 drivers/gpu/drm/msm/msm_drv.h | 2 +-
 2 files changed, 5 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c
index 1ab9ead..90447f3 100644
--- a/drivers/gpu/drm/msm/msm_drv.c
+++ b/drivers/gpu/drm/msm/msm_drv.c
@@ -209,7 +209,7 @@ struct vblank_event {
bool enable;
 };
 
-static void vblank_ctrl_worker(struct kthread_work *work)
+static void vblank_ctrl_worker(struct work_struct *work)
 {
struct msm_vblank_ctrl *vbl_ctrl = container_of(work,
struct msm_vblank_ctrl, work);
@@ -257,8 +257,7 @@ static int vblank_ctrl_queue_work(struct msm_drm_private 
*priv,
list_add_tail(_ev->node, _ctrl->event_list);
spin_unlock_irqrestore(_ctrl->lock, flags);
 
-   kthread_queue_work(>disp_thread[crtc_id].worker,
-   _ctrl->work);
+   schedule_work(_ctrl->work);
 
return 0;
 }
@@ -278,7 +277,7 @@ static int msm_drm_uninit(struct device *dev)
 * work before drm_irq_uninstall() to avoid work re-enabling an
 * irq after uninstall has disabled it.
 */
-   kthread_flush_work(_ctrl->work);
+   flush_work(_ctrl->work);
list_for_each_entry_safe(vbl_ev, tmp, _ctrl->event_list, node) {
list_del(_ev->node);
kfree(vbl_ev);
@@ -476,7 +475,7 @@ static int msm_drm_init(struct device *dev, struct 
drm_driver *drv)
 
INIT_LIST_HEAD(>inactive_list);
INIT_LIST_HEAD(>vblank_ctrl.event_list);
-   kthread_init_work(>vblank_ctrl.work, vblank_ctrl_worker);
+   INIT_WORK(>vblank_ctrl.work, vblank_ctrl_worker);
spin_lock_init(>vblank_ctrl.lock);
 
drm_mode_config_init(ddev);
diff --git a/drivers/gpu/drm/msm/msm_drv.h b/drivers/gpu/drm/msm/msm_drv.h
index 9d11f32..126345c4 100644
--- a/drivers/gpu/drm/msm/msm_drv.h
+++ b/drivers/gpu/drm/msm/msm_drv.h
@@ -78,7 +78,7 @@ enum msm_mdp_plane_property {
 };
 
 struct msm_vblank_ctrl {
-   struct kthread_work work;
+   struct work_struct work;
struct list_head event_list;
spinlock_t lock;
 };
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project

___
Freedreno mailing list
Freedreno@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/freedreno


[Freedreno] [PATCH v3 3/5] drm/msm/dpu: use system wq for idle power collapse

2018-11-15 Thread Jeykumar Sankaran
msm is using system wq for dispatching commit and vblank
events. Switch idle power collapse feature also to use
system wq to handle delayed work handlers so that
msm can get rid of redundant display threads.

changes in v2:
- patch introduced in v2
changes in v3:
- none

Signed-off-by: Jeykumar Sankaran 
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 22 ++
 1 file changed, 6 insertions(+), 16 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
index 82c55ef..dd7ab85 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
@@ -201,7 +201,7 @@ struct dpu_encoder_virt {
bool idle_pc_supported;
struct mutex rc_lock;
enum dpu_enc_rc_states rc_state;
-   struct kthread_delayed_work delayed_off_work;
+   struct delayed_work delayed_off_work;
struct kthread_work vsync_event_work;
struct msm_display_topology topology;
bool mode_set_complete;
@@ -740,7 +740,6 @@ static int dpu_encoder_resource_control(struct drm_encoder 
*drm_enc,
 {
struct dpu_encoder_virt *dpu_enc;
struct msm_drm_private *priv;
-   struct msm_drm_thread *disp_thread;
bool is_vid_mode = false;
 
if (!drm_enc || !drm_enc->dev || !drm_enc->dev->dev_private ||
@@ -753,12 +752,6 @@ static int dpu_encoder_resource_control(struct drm_encoder 
*drm_enc,
is_vid_mode = dpu_enc->disp_info.capabilities &
MSM_DISPLAY_CAP_VID_MODE;
 
-   if (drm_enc->crtc->index >= ARRAY_SIZE(priv->disp_thread)) {
-   DPU_ERROR("invalid crtc index\n");
-   return -EINVAL;
-   }
-   disp_thread = >disp_thread[drm_enc->crtc->index];
-
/*
 * when idle_pc is not supported, process only KICKOFF, STOP and MODESET
 * events and return early for other events (ie wb display).
@@ -775,8 +768,7 @@ static int dpu_encoder_resource_control(struct drm_encoder 
*drm_enc,
switch (sw_event) {
case DPU_ENC_RC_EVENT_KICKOFF:
/* cancel delayed off work, if any */
-   if (kthread_cancel_delayed_work_sync(
-   _enc->delayed_off_work))
+   if (cancel_delayed_work_sync(_enc->delayed_off_work))
DPU_DEBUG_ENC(dpu_enc, "sw_event:%d, work cancelled\n",
sw_event);
 
@@ -835,8 +827,7 @@ static int dpu_encoder_resource_control(struct drm_encoder 
*drm_enc,
return 0;
}
 
-   kthread_queue_delayed_work(
-   _thread->worker,
+   schedule_delayed_work(
_enc->delayed_off_work,
msecs_to_jiffies(dpu_enc->idle_timeout));
 
@@ -847,8 +838,7 @@ static int dpu_encoder_resource_control(struct drm_encoder 
*drm_enc,
 
case DPU_ENC_RC_EVENT_PRE_STOP:
/* cancel delayed off work, if any */
-   if (kthread_cancel_delayed_work_sync(
-   _enc->delayed_off_work))
+   if (cancel_delayed_work_sync(_enc->delayed_off_work))
DPU_DEBUG_ENC(dpu_enc, "sw_event:%d, work cancelled\n",
sw_event);
 
@@ -1351,7 +1341,7 @@ static void dpu_encoder_frame_done_callback(
}
 }
 
-static void dpu_encoder_off_work(struct kthread_work *work)
+static void dpu_encoder_off_work(struct work_struct *work)
 {
struct dpu_encoder_virt *dpu_enc = container_of(work,
struct dpu_encoder_virt, delayed_off_work.work);
@@ -2191,7 +2181,7 @@ int dpu_encoder_setup(struct drm_device *dev, struct 
drm_encoder *enc,
 
 
mutex_init(_enc->rc_lock);
-   kthread_init_delayed_work(_enc->delayed_off_work,
+   INIT_DELAYED_WORK(_enc->delayed_off_work,
dpu_encoder_off_work);
dpu_enc->idle_timeout = IDLE_TIMEOUT;
 
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project

___
Freedreno mailing list
Freedreno@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/freedreno


[Freedreno] [PATCH v3 1/5] drm/msm/dpu: use kthread_destroy_worker to release msm workers

2018-11-15 Thread Jeykumar Sankaran
use kthread_destroy_worker to destroy workers and
release their associated kthreads.

changes in v3:
- introduced in the series

Signed-off-by: Jeykumar Sankaran 
---
 drivers/gpu/drm/msm/msm_drv.c | 6 ++
 1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c
index 9c9f7ff..1ab9ead 100644
--- a/drivers/gpu/drm/msm/msm_drv.c
+++ b/drivers/gpu/drm/msm/msm_drv.c
@@ -287,14 +287,12 @@ static int msm_drm_uninit(struct device *dev)
/* clean up display commit/event worker threads */
for (i = 0; i < priv->num_crtcs; i++) {
if (priv->disp_thread[i].thread) {
-   kthread_flush_worker(>disp_thread[i].worker);
-   kthread_stop(priv->disp_thread[i].thread);
+   kthread_destroy_worker(>disp_thread[i].worker);
priv->disp_thread[i].thread = NULL;
}
 
if (priv->event_thread[i].thread) {
-   kthread_flush_worker(>event_thread[i].worker);
-   kthread_stop(priv->event_thread[i].thread);
+   kthread_destroy_worker(>event_thread[i].worker);
priv->event_thread[i].thread = NULL;
}
}
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project

___
Freedreno mailing list
Freedreno@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/freedreno


[Freedreno] [PATCH v3 4/5] drm/msm: clean up display thread

2018-11-15 Thread Jeykumar Sankaran
Since there are no clients using these threads,
cleaning it up.

changes in v2:
- switch all the dependent clients to use system wq
  before removing the disp_threads (Sean Paul)
changes in v3:
- none

Signed-off-by: Jeykumar Sankaran 
---
 drivers/gpu/drm/msm/msm_drv.c | 35 +--
 drivers/gpu/drm/msm/msm_drv.h |  1 -
 2 files changed, 1 insertion(+), 35 deletions(-)

diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c
index 90447f3..478c14c 100644
--- a/drivers/gpu/drm/msm/msm_drv.c
+++ b/drivers/gpu/drm/msm/msm_drv.c
@@ -283,13 +283,8 @@ static int msm_drm_uninit(struct device *dev)
kfree(vbl_ev);
}
 
-   /* clean up display commit/event worker threads */
+   /* clean up event worker threads */
for (i = 0; i < priv->num_crtcs; i++) {
-   if (priv->disp_thread[i].thread) {
-   kthread_destroy_worker(>disp_thread[i].worker);
-   priv->disp_thread[i].thread = NULL;
-   }
-
if (priv->event_thread[i].thread) {
kthread_destroy_worker(>event_thread[i].worker);
priv->event_thread[i].thread = NULL;
@@ -541,27 +536,6 @@ static int msm_drm_init(struct device *dev, struct 
drm_driver *drv)
 */
param.sched_priority = 16;
for (i = 0; i < priv->num_crtcs; i++) {
-
-   /* initialize display thread */
-   priv->disp_thread[i].crtc_id = priv->crtcs[i]->base.id;
-   kthread_init_worker(>disp_thread[i].worker);
-   priv->disp_thread[i].dev = ddev;
-   priv->disp_thread[i].thread =
-   kthread_run(kthread_worker_fn,
-   >disp_thread[i].worker,
-   "crtc_commit:%d", priv->disp_thread[i].crtc_id);
-   if (IS_ERR(priv->disp_thread[i].thread)) {
-   DRM_DEV_ERROR(dev, "failed to create crtc_commit 
kthread\n");
-   priv->disp_thread[i].thread = NULL;
-   goto err_msm_uninit;
-   }
-
-   ret = sched_setscheduler(priv->disp_thread[i].thread,
-SCHED_FIFO, );
-   if (ret)
-   dev_warn(dev, "disp_thread set priority failed: %d\n",
-ret);
-
/* initialize event thread */
priv->event_thread[i].crtc_id = priv->crtcs[i]->base.id;
kthread_init_worker(>event_thread[i].worker);
@@ -576,13 +550,6 @@ static int msm_drm_init(struct device *dev, struct 
drm_driver *drv)
goto err_msm_uninit;
}
 
-   /**
-* event thread should also run at same priority as disp_thread
-* because it is handling frame_done events. A lower priority
-* event thread and higher priority disp_thread can causes
-* frame_pending counters beyond 2. This can lead to commit
-* failure at crtc commit level.
-*/
ret = sched_setscheduler(priv->event_thread[i].thread,
 SCHED_FIFO, );
if (ret)
diff --git a/drivers/gpu/drm/msm/msm_drv.h b/drivers/gpu/drm/msm/msm_drv.h
index 126345c4..05d33a7 100644
--- a/drivers/gpu/drm/msm/msm_drv.h
+++ b/drivers/gpu/drm/msm/msm_drv.h
@@ -197,7 +197,6 @@ struct msm_drm_private {
unsigned int num_crtcs;
struct drm_crtc *crtcs[MAX_CRTCS];
 
-   struct msm_drm_thread disp_thread[MAX_CRTCS];
struct msm_drm_thread event_thread[MAX_CRTCS];
 
unsigned int num_encoders;
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project

___
Freedreno mailing list
Freedreno@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/freedreno


Re: [Freedreno] [PATCH 6/8] drm/msm: dpu: Separate crtc assignment from vblank enable

2018-11-14 Thread Jeykumar Sankaran

On 2018-11-14 12:52, Sean Paul wrote:

On Wed, Nov 14, 2018 at 12:46:32PM -0800, Jeykumar Sankaran wrote:

On 2018-11-14 11:57, Ville Syrjälä wrote:
> On Wed, Nov 14, 2018 at 11:43:51AM -0800, Jeykumar Sankaran wrote:
> > On 2018-11-14 07:16, Sean Paul wrote:
> > > On Tue, Nov 13, 2018 at 04:48:12PM -0800, Jeykumar Sankaran wrote:
> > >> On 2018-11-13 12:52, Sean Paul wrote:
> > >> > From: Sean Paul 
> > >> >
> > >> > Instead of assigning/clearing the crtc on vblank

enable/disable, we

> > > can
> > >> > just assign and clear the crtc on modeset. That allows us to

just

> > > toggle
> > >> > the encoder's vblank interrupts on vblank_enable.
> > >> >
> > >> > So why is this important? Previously the driver was using the
> legacy
> > >> > pointers to assign/clear the crtc. Legacy pointers are cleared
> _after_
> > >> Which pointers are you referring here as legacy pointers? CRTC?
> > >
> > > encoder->crtc in this case. The loop in vblank_enable_no_lock

relies

> on
> > > enc->crtc == crtc
> > >
> > >> > disabling the hardware, so the legacy pointer was valid during
> > >> > vblank_disable, but that's not something we should rely on.
> > >> >
> > >> > Instead of relying on the core ordering the legacy pointer
> assignments
> > >> > just so, we'll assign the crtc in dpu_crtc enable/disable. This

is

> the
> > >> > only place that mapping can change, so we're covered there.
> > >> >
> > >> > We're also taking advantage of drm_crtc_vblank_on/off. By using
> this,
> > > we
> > >> > ensure that vblank_enable/disable can never be called while the
> crtc
> > > is
> > >> > off (which means the assigned crtc will always be valid). As

such,

> we
> > >>
> > >> What about the drm_vblank_enable/disable triggered by

drm_vblank_get

> > > when
> > >> crtc
> > >> is disabled? What is the expected behavior there? the
> vblank_requested
> > >> variable removed by the next patch was introduced to cache the
> > >> request.
> > >
> > > That case is covered by the modeset locks held when calling

disable().

> > >
> > I am sure it will take care of drm_crtc_vblank_on/off triggered

within

> > crtc_disable.
> > My question was what was the expected behaviour when
> > DRM_IOCTL_WAIT_VBLANK is
> > called when crtc is disabled? the ioctl will try to call
> > drm_vblank_get
> > and I
> > don't see the patch checking for crtc being enabled in the path.
>
> drm_vblank_off()
> // .enable_vblank/.disable_vblank will never be called here
> drm_vblank_on()
>
> So if you use drm_vblank_on/off judiciously you will never
> have to deal with this particular problem.
>
Thanks ville for clarifying that.

We can make sure to avoid that sequence if we have control over it. In

DPU,

CRTC calls
dpu_vblank_off in crtc_disable. After disabling, no one stopping
userspace clients to call into DRM_IOCTL_WAIT_VBLANK on the crtc. This

ioctl

calls enable_vblank when it sees the vblank is disabled [1].



That's prevented by this bit in drm_vblank.c:

/*
 * Prevent subsequent drm_vblank_get() from re-enabling
 * the vblank interrupt by bumping the refcount.
 */
if (!vblank->inmodeset) {
atomic_inc(>refcount);
vblank->inmodeset = 1;
}

Basically it turns off the hw and then takes a reference such that
drm_vblank_get will never call drm_vblank_enable.

Sean


That explains it! Thanks Sean!


So far, the dpu_crtc_vblank was failing when it finds that the crtc is
disabled.
With this patch, the condition was removed, so I was wondering what is

the

expected behavior with this patch.

[1]

https://gitlab.freedesktop.org/seanpaul/dpu-staging/blob/for-next/drivers/
gpu/drm/drm_vblank.c#L956


Thanks and Regards,
Jeykumar S.
> --
> Ville Syrjälä
> Intel

--
Jeykumar S


--
Sean Paul, Software Engineer, Google / Chromium OS


--
Jeykumar S
___
Freedreno mailing list
Freedreno@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/freedreno


Re: [Freedreno] [PATCH 6/8] drm/msm: dpu: Separate crtc assignment from vblank enable

2018-11-14 Thread Jeykumar Sankaran

On 2018-11-14 11:57, Ville Syrjälä wrote:

On Wed, Nov 14, 2018 at 11:43:51AM -0800, Jeykumar Sankaran wrote:

On 2018-11-14 07:16, Sean Paul wrote:
> On Tue, Nov 13, 2018 at 04:48:12PM -0800, Jeykumar Sankaran wrote:
>> On 2018-11-13 12:52, Sean Paul wrote:
>> > From: Sean Paul 
>> >
>> > Instead of assigning/clearing the crtc on vblank enable/disable, we
> can
>> > just assign and clear the crtc on modeset. That allows us to just
> toggle
>> > the encoder's vblank interrupts on vblank_enable.
>> >
>> > So why is this important? Previously the driver was using the

legacy

>> > pointers to assign/clear the crtc. Legacy pointers are cleared

_after_

>> Which pointers are you referring here as legacy pointers? CRTC?
>
> encoder->crtc in this case. The loop in vblank_enable_no_lock relies

on

> enc->crtc == crtc
>
>> > disabling the hardware, so the legacy pointer was valid during
>> > vblank_disable, but that's not something we should rely on.
>> >
>> > Instead of relying on the core ordering the legacy pointer

assignments

>> > just so, we'll assign the crtc in dpu_crtc enable/disable. This is

the

>> > only place that mapping can change, so we're covered there.
>> >
>> > We're also taking advantage of drm_crtc_vblank_on/off. By using

this,

> we
>> > ensure that vblank_enable/disable can never be called while the

crtc

> is
>> > off (which means the assigned crtc will always be valid). As such,

we

>>
>> What about the drm_vblank_enable/disable triggered by drm_vblank_get
> when
>> crtc
>> is disabled? What is the expected behavior there? the

vblank_requested

>> variable removed by the next patch was introduced to cache the
>> request.
>
> That case is covered by the modeset locks held when calling disable().
>
I am sure it will take care of drm_crtc_vblank_on/off triggered within
crtc_disable.
My question was what was the expected behaviour when
DRM_IOCTL_WAIT_VBLANK is
called when crtc is disabled? the ioctl will try to call 
drm_vblank_get

and I
don't see the patch checking for crtc being enabled in the path.


drm_vblank_off()
// .enable_vblank/.disable_vblank will never be called here
drm_vblank_on()

So if you use drm_vblank_on/off judiciously you will never
have to deal with this particular problem.


Thanks ville for clarifying that.

We can make sure to avoid that sequence if we have control over it. In 
DPU, CRTC calls

dpu_vblank_off in crtc_disable. After disabling, no one stopping
userspace clients to call into DRM_IOCTL_WAIT_VBLANK on the crtc. This 
ioctl

calls enable_vblank when it sees the vblank is disabled [1].

So far, the dpu_crtc_vblank was failing when it finds that the crtc is 
disabled.
With this patch, the condition was removed, so I was wondering what is 
the

expected behavior with this patch.

[1] 
https://gitlab.freedesktop.org/seanpaul/dpu-staging/blob/for-next/drivers/gpu/drm/drm_vblank.c#L956


Thanks and Regards,
Jeykumar S.

--
Ville Syrjälä
Intel


--
Jeykumar S
___
Freedreno mailing list
Freedreno@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/freedreno


Re: [Freedreno] [PATCH 6/8] drm/msm: dpu: Separate crtc assignment from vblank enable

2018-11-14 Thread Jeykumar Sankaran

On 2018-11-14 07:16, Sean Paul wrote:

On Tue, Nov 13, 2018 at 04:48:12PM -0800, Jeykumar Sankaran wrote:

On 2018-11-13 12:52, Sean Paul wrote:
> From: Sean Paul 
>
> Instead of assigning/clearing the crtc on vblank enable/disable, we

can

> just assign and clear the crtc on modeset. That allows us to just

toggle

> the encoder's vblank interrupts on vblank_enable.
>
> So why is this important? Previously the driver was using the legacy
> pointers to assign/clear the crtc. Legacy pointers are cleared _after_
Which pointers are you referring here as legacy pointers? CRTC?


encoder->crtc in this case. The loop in vblank_enable_no_lock relies on
enc->crtc == crtc


> disabling the hardware, so the legacy pointer was valid during
> vblank_disable, but that's not something we should rely on.
>
> Instead of relying on the core ordering the legacy pointer assignments
> just so, we'll assign the crtc in dpu_crtc enable/disable. This is the
> only place that mapping can change, so we're covered there.
>
> We're also taking advantage of drm_crtc_vblank_on/off. By using this,

we

> ensure that vblank_enable/disable can never be called while the crtc

is

> off (which means the assigned crtc will always be valid). As such, we

What about the drm_vblank_enable/disable triggered by drm_vblank_get

when

crtc
is disabled? What is the expected behavior there? the vblank_requested
variable removed by the next patch was introduced to cache the 
request.


That case is covered by the modeset locks held when calling disable().

I am sure it will take care of drm_crtc_vblank_on/off triggered within 
crtc_disable.
My question was what was the expected behaviour when 
DRM_IOCTL_WAIT_VBLANK is
called when crtc is disabled? the ioctl will try to call drm_vblank_get 
and I

don't see the patch checking for crtc being enabled in the path.

Thanks and Regards,
Jeykumar S.




> don't need to use modeset locks or the crtc_lock in the
> vblank_enable/disable routine to be sure state is consistent.
>
> ...I think.
>
> Signed-off-by: Sean Paul 
> ---
>  drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c| 77

+

>  drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 27 +---
>  drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h | 10 +++
>  3 files changed, 59 insertions(+), 55 deletions(-)
>
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
> b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
> index 4b7f98a6ab60..59e823281fdf 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
> @@ -757,43 +757,6 @@ void dpu_crtc_commit_kickoff(struct drm_crtc

*crtc)

>DPU_ATRACE_END("crtc_commit");
>  }
>
> -/**
> - * _dpu_crtc_vblank_enable_no_lock - update power resource and vblank
> request
> - * @dpu_crtc: Pointer to dpu crtc structure
> - * @enable: Whether to enable/disable vblanks
> - */
> -static void _dpu_crtc_vblank_enable_no_lock(
> -  struct dpu_crtc *dpu_crtc, bool enable)
> -{
> -  struct drm_crtc *crtc = _crtc->base;
> -  struct drm_device *dev = crtc->dev;
> -  struct drm_encoder *enc;
> -
> -  if (enable) {
> -  list_for_each_entry(enc, >mode_config.encoder_list,
> head) {
> -  if (enc->crtc != crtc)
> -  continue;
> -
> -
> trace_dpu_crtc_vblank_enable(DRMID(_crtc->base),
> -   DRMID(enc), enable,
> -   dpu_crtc);
> -
> -  dpu_encoder_assign_crtc(enc, crtc);
> -  }
> -  } else {
> -  list_for_each_entry(enc, >mode_config.encoder_list,
> head) {
> -  if (enc->crtc != crtc)
> -  continue;
> -
> -
> trace_dpu_crtc_vblank_enable(DRMID(_crtc->base),
> -   DRMID(enc), enable,
> -   dpu_crtc);
> -
> -  dpu_encoder_assign_crtc(enc, NULL);
> -  }
> -  }
> -}
> -
>  /**
>   * dpu_crtc_duplicate_state - state duplicate hook
>   * @crtc: Pointer to drm crtc structure
> @@ -847,6 +810,10 @@ static void dpu_crtc_disable(struct drm_crtc

*crtc,

>/* Disable/save vblank irq handling */
>drm_crtc_vblank_off(crtc);
>
> +  drm_for_each_encoder_mask(encoder, crtc->dev,
> +old_crtc_state->encoder_mask)
> +  dpu_encoder_assign_crtc(encoder, NULL);
> +
>mutex_lock(_crtc->crtc_lock);
>
>/* wait for frame_event_done completion */
> @@ -856,9 +823,6 @@ static void dpu_crtc_disable(struct drm_crtc

*crtc,

>atomic_read(_crtc->frame_pending));
&g

Re: [Freedreno] [PATCH 3/8] drm/msm: dpu: Remove vblank_callback from encoder

2018-11-14 Thread Jeykumar Sankaran

On 2018-11-14 07:13, Sean Paul wrote:

On Tue, Nov 13, 2018 at 04:47:22PM -0800, Jeykumar Sankaran wrote:

On 2018-11-13 12:52, Sean Paul wrote:
> From: Sean Paul 
>
> The indirection of registering a callback and opaque pointer isn't

real

> useful when there's only one callsite. So instead of having the
> vblank_cb registration, just give encoder a crtc and let it directly
> call the vblank handler.
>
> In a later patch, we'll make use of this further.
>
> Signed-off-by: Sean Paul 
> ---
>  drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c|  8 +++
>  drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h|  6 +
>  drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 25

+++--

>  drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h | 10 -
>  4 files changed, 26 insertions(+), 23 deletions(-)
>
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
> b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
> index adda0aa0cbaa..38119b4d4a80 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
> @@ -291,9 +291,8 @@ enum dpu_intf_mode dpu_crtc_get_intf_mode(struct
> drm_crtc *crtc)
>return INTF_MODE_NONE;
>  }
>
> -static void dpu_crtc_vblank_cb(void *data)
> +void dpu_crtc_vblank_callback(struct drm_crtc *crtc)
>  {
> -  struct drm_crtc *crtc = (struct drm_crtc *)data;
>struct dpu_crtc *dpu_crtc = to_dpu_crtc(crtc);

Since we are calling into a locally stored CRTC and not tracking

disable.

Should
we check for crtc->enable before processing the callback?

I see vblank_on/off cant be called when CRTC is disabled with the rest
of the patches in the series. But this callback is triggered by IRQ's
context.


Hmm, yeah, I had assumed that we wouldn't have any interrupts after irq
disable.
However it doesn't seem like that's the case.

That said, I don't think checking crtc->enable is quite what we want. 
In

the
case of disable, the crtc is cleared from the encoder, so checking for
crtc != NULL would be better here. SGTY?
That would still cause a race as crtc assignment will be protected by 
modeset

locks and crtc != NULL check isn't.


Now that I've dug into the vblank irq handling a bit in the encoder, it
seems
like that could be moved to the crtc and a bunch of the
encoder->crtc->encoder
bouncing around could be avoided. Off the top of your head, is there 
any

reason
we couldn't move the vblank irq handling into crtc from encoder?
vblank irq handlers are only needed for video mode. As with all the 
other

IRQ's, the handlers are implemented in phys_encoder level and the events
are forwarded as and when needed.

BTW, the vblank irq flows from phys_enc->virtual_enc->crtc.

Thanks,
Jeykumar S.



Sean



>
>/* keep statistics on vblank callback - with auto reset via
> debugfs */
> @@ -779,8 +778,7 @@ static void _dpu_crtc_vblank_enable_no_lock(
> DRMID(enc), enable,
> dpu_crtc);
>
> -  dpu_encoder_register_vblank_callback(enc,
> -  dpu_crtc_vblank_cb, (void *)crtc);
> +  dpu_encoder_assign_crtc(enc, crtc);
>}
>} else {
>list_for_each_entry(enc, >mode_config.encoder_list,
> head) {
> @@ -791,7 +789,7 @@ static void _dpu_crtc_vblank_enable_no_lock(
> DRMID(enc), enable,
> dpu_crtc);
>
> -  dpu_encoder_register_vblank_callback(enc, NULL,
> NULL);
> +  dpu_encoder_assign_crtc(enc, NULL);
>}
>}
>  }
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h
> b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h
> index 93d21a61a040..54595cc29be5 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h
> @@ -270,6 +270,12 @@ static inline int dpu_crtc_frame_pending(struct
> drm_crtc *crtc)
>   */
>  int dpu_crtc_vblank(struct drm_crtc *crtc, bool en);
>
> +/**
> + * dpu_crtc_vblank_callback - called on vblank irq, issues completion
> events
> + * @crtc: Pointer to drm crtc object
> + */
> +void dpu_crtc_vblank_callback(struct drm_crtc *crtc);
> +
>  /**
>   * dpu_crtc_commit_kickoff - trigger kickoff of the commit for this
> crtc
>   * @crtc: Pointer to drm crtc object
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
> b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
> index d89ac520f7e6..fd6514f681ae 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
> @@ -142,9 +142,11 @@ enum dpu_enc_rc_states {
>   * @intfs_swapped Whether or not the 

Re: [Freedreno] [PATCH 6/8] drm/msm: dpu: Separate crtc assignment from vblank enable

2018-11-13 Thread Jeykumar Sankaran

On 2018-11-13 12:52, Sean Paul wrote:

From: Sean Paul 

Instead of assigning/clearing the crtc on vblank enable/disable, we can
just assign and clear the crtc on modeset. That allows us to just 
toggle

the encoder's vblank interrupts on vblank_enable.

So why is this important? Previously the driver was using the legacy
pointers to assign/clear the crtc. Legacy pointers are cleared _after_

Which pointers are you referring here as legacy pointers? CRTC?

disabling the hardware, so the legacy pointer was valid during
vblank_disable, but that's not something we should rely on.

Instead of relying on the core ordering the legacy pointer assignments
just so, we'll assign the crtc in dpu_crtc enable/disable. This is the
only place that mapping can change, so we're covered there.

We're also taking advantage of drm_crtc_vblank_on/off. By using this, 
we

ensure that vblank_enable/disable can never be called while the crtc is
off (which means the assigned crtc will always be valid). As such, we


What about the drm_vblank_enable/disable triggered by drm_vblank_get 
when crtc

is disabled? What is the expected behavior there? the vblank_requested
variable removed by the next patch was introduced to cache the request.


don't need to use modeset locks or the crtc_lock in the
vblank_enable/disable routine to be sure state is consistent.

...I think.

Signed-off-by: Sean Paul 
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c| 77 +
 drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 27 +---
 drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h | 10 +++
 3 files changed, 59 insertions(+), 55 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
index 4b7f98a6ab60..59e823281fdf 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
@@ -757,43 +757,6 @@ void dpu_crtc_commit_kickoff(struct drm_crtc 
*crtc)

DPU_ATRACE_END("crtc_commit");
 }

-/**
- * _dpu_crtc_vblank_enable_no_lock - update power resource and vblank
request
- * @dpu_crtc: Pointer to dpu crtc structure
- * @enable: Whether to enable/disable vblanks
- */
-static void _dpu_crtc_vblank_enable_no_lock(
-   struct dpu_crtc *dpu_crtc, bool enable)
-{
-   struct drm_crtc *crtc = _crtc->base;
-   struct drm_device *dev = crtc->dev;
-   struct drm_encoder *enc;
-
-   if (enable) {
-   list_for_each_entry(enc, >mode_config.encoder_list,
head) {
-   if (enc->crtc != crtc)
-   continue;
-
-
trace_dpu_crtc_vblank_enable(DRMID(_crtc->base),
-DRMID(enc), enable,
-dpu_crtc);
-
-   dpu_encoder_assign_crtc(enc, crtc);
-   }
-   } else {
-   list_for_each_entry(enc, >mode_config.encoder_list,
head) {
-   if (enc->crtc != crtc)
-   continue;
-
-
trace_dpu_crtc_vblank_enable(DRMID(_crtc->base),
-DRMID(enc), enable,
-dpu_crtc);
-
-   dpu_encoder_assign_crtc(enc, NULL);
-   }
-   }
-}
-
 /**
  * dpu_crtc_duplicate_state - state duplicate hook
  * @crtc: Pointer to drm crtc structure
@@ -847,6 +810,10 @@ static void dpu_crtc_disable(struct drm_crtc 
*crtc,

/* Disable/save vblank irq handling */
drm_crtc_vblank_off(crtc);

+   drm_for_each_encoder_mask(encoder, crtc->dev,
+ old_crtc_state->encoder_mask)
+   dpu_encoder_assign_crtc(encoder, NULL);
+
mutex_lock(_crtc->crtc_lock);

/* wait for frame_event_done completion */
@@ -856,9 +823,6 @@ static void dpu_crtc_disable(struct drm_crtc *crtc,
atomic_read(_crtc->frame_pending));

trace_dpu_crtc_disable(DRMID(crtc), false, dpu_crtc);
-   if (dpu_crtc->enabled && dpu_crtc->vblank_requested) {
-   _dpu_crtc_vblank_enable_no_lock(dpu_crtc, false);
-   }
dpu_crtc->enabled = false;

if (atomic_read(_crtc->frame_pending)) {
@@ -922,13 +886,13 @@ static void dpu_crtc_enable(struct drm_crtc 
*crtc,


mutex_lock(_crtc->crtc_lock);
trace_dpu_crtc_enable(DRMID(crtc), true, dpu_crtc);
-   if (!dpu_crtc->enabled && dpu_crtc->vblank_requested) {
-   _dpu_crtc_vblank_enable_no_lock(dpu_crtc, true);
-   }
dpu_crtc->enabled = true;

mutex_unlock(_crtc->crtc_lock);

+   drm_for_each_encoder_mask(encoder, crtc->dev,
crtc->state->encoder_mask)
+   dpu_encoder_assign_crtc(encoder, crtc);
+
/* Enable/restore vblank irq handling */
drm_crtc_vblank_on(crtc);
 }
@@ -1173,10 +1137,33 @@ static int dpu_crtc_atomic_check(struct 
drm_crtc

*crtc,
 int dpu_crtc_vblank(struct drm_crtc 

Re: [Freedreno] [PATCH 7/8] drm/msm: dpu: Remove vblank_requested flag from dpu_crtc

2018-11-13 Thread Jeykumar Sankaran

On 2018-11-13 12:52, Sean Paul wrote:

From: Sean Paul 

It's just for debug output, we don't need it

Signed-off-by: Sean Paul 
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c  |  6 --
 drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h  |  2 --
 drivers/gpu/drm/msm/disp/dpu1/dpu_trace.h | 14 --
 3 files changed, 4 insertions(+), 18 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
index 59e823281fdf..ab96a2e69efa 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
@@ -1163,10 +1163,6 @@ int dpu_crtc_vblank(struct drm_crtc *crtc, bool 
en)

dpu_encoder_toggle_vblank_for_crtc(enc, crtc, en);
}

-   mutex_lock(_crtc->crtc_lock);
-   dpu_crtc->vblank_requested = en;
-   mutex_unlock(_crtc->crtc_lock);
-
return 0;
 }

@@ -1282,8 +1278,6 @@ static int _dpu_debugfs_status_show(struct 
seq_file

*s, void *data)
dpu_crtc->vblank_cb_time = ktime_set(0, 0);
}

-   seq_printf(s, "vblank_enable:%d\n", dpu_crtc->vblank_requested);
-
mutex_unlock(_crtc->crtc_lock);
drm_modeset_unlock_all(crtc->dev);



I see few more references @ 
https://gitlab.freedesktop.org/seanpaul/dpu-staging/blob/for-next/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c#L900


Which change is removing them?


diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h
b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h
index 54595cc29be5..2b358546af49 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h
@@ -132,7 +132,6 @@ struct dpu_crtc_frame_event {
  * @vblank_cb_count : count of vblank callback since last reset
  * @play_count: frame count between crtc enable and disable
  * @vblank_cb_time  : ktime at vblank count reset
- * @vblank_requested : whether the user has requested vblank events
  * @enabled   : whether the DPU CRTC is currently enabled. updated 
in

the
  *  commit-thread, not state-swap time which is 
earlier,

so
  *  safe to make decisions on during VBLANK on/off 
work

@@ -166,7 +165,6 @@ struct dpu_crtc {
u32 vblank_cb_count;
u64 play_count;
ktime_t vblank_cb_time;
-   bool vblank_requested;
bool enabled;

struct list_head feature_list;
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_trace.h
b/drivers/gpu/drm/msm/disp/dpu1/dpu_trace.h
index 328df37d7580..c78b521ceda1 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_trace.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_trace.h
@@ -728,20 +728,17 @@ TRACE_EVENT(dpu_crtc_vblank_enable,
__field(uint32_t,   enc_id  )
__field(bool,   enable  )
__field(bool,   enabled )
-   __field(bool,   vblank_requested )
),
TP_fast_assign(
__entry->drm_id = drm_id;
__entry->enc_id = enc_id;
__entry->enable = enable;
__entry->enabled = crtc->enabled;
-   __entry->vblank_requested = crtc->vblank_requested;
),
-   TP_printk("id:%u encoder:%u enable:%s state{enabled:%s
vblank_req:%s}",
+   TP_printk("id:%u encoder:%u enable:%s state{enabled:%s}",
  __entry->drm_id, __entry->enc_id,
  __entry->enable ? "true" : "false",
- __entry->enabled ? "true" : "false",
- __entry->vblank_requested ? "true" : "false")
+ __entry->enabled ? "true" : "false")
 );

 DECLARE_EVENT_CLASS(dpu_crtc_enable_template,
@@ -751,18 +748,15 @@ DECLARE_EVENT_CLASS(dpu_crtc_enable_template,
__field(uint32_t,   drm_id  )
__field(bool,   enable  )
__field(bool,   enabled )
-   __field(bool,   vblank_requested )
),
TP_fast_assign(
__entry->drm_id = drm_id;
__entry->enable = enable;
__entry->enabled = crtc->enabled;
-   __entry->vblank_requested = crtc->vblank_requested;
),
-   TP_printk("id:%u enable:%s state{enabled:%s vblank_req:%s}",
+   TP_printk("id:%u enable:%s state{enabled:%s}",
  __entry->drm_id, __entry->enable ? "true" : "false",
- __entry->enabled ? "true" : "false",
- __entry->vblank_requested ? "true" : "false")
+ __entry->enabled ? "true" : "false")
 );
 DEFINE_EVENT(dpu_crtc_enable_template, dpu_crtc_enable,
TP_PROTO(uint32_t drm_id, bool enable, struct dpu_crtc *crtc),


--
Jeykumar S
___
Freedreno mailing list
Freedreno@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/freedreno


Re: [Freedreno] [PATCH 3/8] drm/msm: dpu: Remove vblank_callback from encoder

2018-11-13 Thread Jeykumar Sankaran

On 2018-11-13 12:52, Sean Paul wrote:

From: Sean Paul 

The indirection of registering a callback and opaque pointer isn't real
useful when there's only one callsite. So instead of having the
vblank_cb registration, just give encoder a crtc and let it directly
call the vblank handler.

In a later patch, we'll make use of this further.

Signed-off-by: Sean Paul 
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c|  8 +++
 drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h|  6 +
 drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 25 +++--
 drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h | 10 -
 4 files changed, 26 insertions(+), 23 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
index adda0aa0cbaa..38119b4d4a80 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
@@ -291,9 +291,8 @@ enum dpu_intf_mode dpu_crtc_get_intf_mode(struct
drm_crtc *crtc)
return INTF_MODE_NONE;
 }

-static void dpu_crtc_vblank_cb(void *data)
+void dpu_crtc_vblank_callback(struct drm_crtc *crtc)
 {
-   struct drm_crtc *crtc = (struct drm_crtc *)data;
struct dpu_crtc *dpu_crtc = to_dpu_crtc(crtc);


Since we are calling into a locally stored CRTC and not tracking 
disable. Should

we check for crtc->enable before processing the callback?

I see vblank_on/off cant be called when CRTC is disabled with the rest
of the patches in the series. But this callback is triggered by IRQ's
context.



/* keep statistics on vblank callback - with auto reset via
debugfs */
@@ -779,8 +778,7 @@ static void _dpu_crtc_vblank_enable_no_lock(
 DRMID(enc), enable,
 dpu_crtc);

-   dpu_encoder_register_vblank_callback(enc,
-   dpu_crtc_vblank_cb, (void *)crtc);
+   dpu_encoder_assign_crtc(enc, crtc);
}
} else {
list_for_each_entry(enc, >mode_config.encoder_list,
head) {
@@ -791,7 +789,7 @@ static void _dpu_crtc_vblank_enable_no_lock(
 DRMID(enc), enable,
 dpu_crtc);

-   dpu_encoder_register_vblank_callback(enc, NULL,
NULL);
+   dpu_encoder_assign_crtc(enc, NULL);
}
}
 }
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h
b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h
index 93d21a61a040..54595cc29be5 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h
@@ -270,6 +270,12 @@ static inline int dpu_crtc_frame_pending(struct
drm_crtc *crtc)
  */
 int dpu_crtc_vblank(struct drm_crtc *crtc, bool en);

+/**
+ * dpu_crtc_vblank_callback - called on vblank irq, issues completion
events
+ * @crtc: Pointer to drm crtc object
+ */
+void dpu_crtc_vblank_callback(struct drm_crtc *crtc);
+
 /**
  * dpu_crtc_commit_kickoff - trigger kickoff of the commit for this 
crtc

  * @crtc: Pointer to drm crtc object
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
index d89ac520f7e6..fd6514f681ae 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
@@ -142,9 +142,11 @@ enum dpu_enc_rc_states {
  * @intfs_swapped  Whether or not the phys_enc interfaces have been
swapped
  * for partial update right-only cases, such as
pingpong
  * split where virtual pingpong does not generate
IRQs
- * @crtc_vblank_cb:Callback into the upper layer / CRTC for
- * notification of the VBLANK
- * @crtc_vblank_cb_data:   Data from upper layer for VBLANK
notification
+ * @crtc:  Pointer to the currently assigned crtc. Normally
you
+ * would use crtc->state->encoder_mask to determine
the
+ * link between encoder/crtc. However in this case we
need
+ * to track crtc in the disable() hook which is
called
+ * _after_ encoder_mask is cleared.
  * @crtc_kickoff_cb:   Callback into CRTC that will flush & start
  * all CTL paths
  * @crtc_kickoff_cb_data:  Opaque user data given to crtc_kickoff_cb
@@ -186,8 +188,7 @@ struct dpu_encoder_virt {

bool intfs_swapped;

-   void (*crtc_vblank_cb)(void *);
-   void *crtc_vblank_cb_data;
+   struct drm_crtc *crtc;

struct dentry *debugfs_root;
struct mutex enc_lock;
@@ -1241,8 +1242,8 @@ static void dpu_encoder_vblank_callback(struct
drm_encoder *drm_enc,
dpu_enc = to_dpu_encoder_virt(drm_enc);

spin_lock_irqsave(_enc->enc_spinlock, lock_flags);
-   if (dpu_enc->crtc_vblank_cb)
-   

Re: [Freedreno] [PATCH 12/12] drm/msm: dpu: Move crtc runtime resume to encoder

2018-11-12 Thread Jeykumar Sankaran

On 2018-11-12 11:42, Sean Paul wrote:

From: Sean Paul 

The crtc runtime resume doesn't actually operate on the crtc, but 
rather

its encoders. The problem with this is that we need to inspect the crtc
state to get the currently connected encoders. Since runtime resume
isn't guaranteed to be called while holding the modeset locks (although
it sometimes is), this presents a race condition.

Now that we have ->enabled on the virtual encoders, and a lock to
protect it, just call resume on each encoder and only restore the ones
that are enabled.

Signed-off-by: Sean Paul 
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c| 24 -
 drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h|  6 --
 drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 24 +
 drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h |  4 ++--
 drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c |  6 +++---
 5 files changed, 15 insertions(+), 49 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
index d8f58caf2772..9be24907f8c1 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
@@ -841,30 +841,6 @@ static struct drm_crtc_state
*dpu_crtc_duplicate_state(struct drm_crtc *crtc)
return >base;
 }

-void dpu_crtc_runtime_resume(struct drm_crtc *crtc)
-{
-   struct dpu_crtc *dpu_crtc = to_dpu_crtc(crtc);
-   struct drm_encoder *encoder;
-
-   mutex_lock(_crtc->crtc_lock);
-
-   if (!dpu_crtc->enabled)
-   goto end;
-
-   trace_dpu_crtc_runtime_resume(DRMID(crtc));
-
-   /* restore encoder; crtc will be programmed during commit */
-   drm_for_each_encoder(encoder, crtc->dev) {
-   if (encoder->crtc != crtc)
-   continue;
-
-   dpu_encoder_virt_restore(encoder);
-   }
I agree the patch provides a cleaner solution. Just for the 
understanding,

won't the race condition be addressed if we acquire the
modeset lock here and iterate through crtc->state->encoder_mask?

Thanks and Regards,
Jeykumar S.

-
-end:
-   mutex_unlock(_crtc->crtc_lock);
-}
-
 static void dpu_crtc_disable(struct drm_crtc *crtc)
 {
struct dpu_crtc *dpu_crtc;
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h
b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h
index 1dca91d1210f..93d21a61a040 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h
@@ -329,10 +329,4 @@ static inline bool dpu_crtc_is_enabled(struct
drm_crtc *crtc)
return crtc ? crtc->enabled : false;
 }

-/**
- * dpu_crtc_runtime_resume - called by the top-level on 
pm_runtime_resume

- * @crtc: CRTC to resume
- */
-void dpu_crtc_runtime_resume(struct drm_crtc *crtc);
-
 #endif /* _DPU_CRTC_H_ */
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
index 3daa86220d47..d89ac520f7e6 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
@@ -1089,28 +1089,24 @@ static void 
_dpu_encoder_virt_enable_helper(struct

drm_encoder *drm_enc)
_dpu_encoder_update_vsync_source(dpu_enc, _enc->disp_info);
 }

-void dpu_encoder_virt_restore(struct drm_encoder *drm_enc)
+void dpu_encoder_virt_runtime_resume(struct drm_encoder *drm_enc)
 {
-   struct dpu_encoder_virt *dpu_enc = NULL;
-   int i;
-
-   if (!drm_enc) {
-   DPU_ERROR("invalid encoder\n");
-   return;
-   }
-   dpu_enc = to_dpu_encoder_virt(drm_enc);
+   struct dpu_encoder_virt *dpu_enc = to_dpu_encoder_virt(drm_enc);

-   for (i = 0; i < dpu_enc->num_phys_encs; i++) {
-   struct dpu_encoder_phys *phys = dpu_enc->phys_encs[i];
+   mutex_lock(_enc->enc_lock);

-   if (phys && (phys != dpu_enc->cur_master) &&
phys->ops.restore)
-   phys->ops.restore(phys);
-   }
+   if (!dpu_enc->enabled)
+   goto out;

+   if (dpu_enc->cur_slave && dpu_enc->cur_slave->ops.restore)
+   dpu_enc->cur_slave->ops.restore(dpu_enc->cur_slave);
if (dpu_enc->cur_master && dpu_enc->cur_master->ops.restore)
dpu_enc->cur_master->ops.restore(dpu_enc->cur_master);

_dpu_encoder_virt_enable_helper(drm_enc);
+
+out:
+   mutex_unlock(_enc->enc_lock);
 }

 static void dpu_encoder_virt_enable(struct drm_encoder *drm_enc)
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h
b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h
index 9dbf38f446d9..aa4f135218fa 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h
@@ -126,10 +126,10 @@ int dpu_encoder_wait_for_event(struct drm_encoder
*drm_encoder,
 enum dpu_intf_mode dpu_encoder_get_intf_mode(struct drm_encoder
*encoder);

 /**
- * dpu_encoder_virt_restore - restore the encoder configs
+ * dpu_encoder_virt_runtime_resume - pm runtime resume the encoder
configs
  * 

Re: [Freedreno] [PATCH 11/12] drm/msm: dpu: Add ->enabled to dpu_encoder_virt

2018-11-12 Thread Jeykumar Sankaran

On 2018-11-12 11:42, Sean Paul wrote:

From: Sean Paul 

Add a bool to dpu_encoder_virt to track whether the encoder is enabled
or not. Repurpose the enc_lock mutex to ensure that it is consistent
with the hw state.

Signed-off-by: Sean Paul 
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 27 +
 1 file changed, 22 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
index 10a0676d1dcf..3daa86220d47 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
@@ -132,6 +132,7 @@ enum dpu_enc_rc_states {
  * @base:  drm_encoder base class for registration with DRM
  * @enc_spinlock:  Virtual-Encoder-Wide Spin Lock for IRQ purposes
  * @bus_scaling_client:Client handle to the bus scaling interface
+ * @enabled:   True if the encoder is active, protected by
enc_lock
  * @num_phys_encs: Actual number of physical encoders contained.
  * @phys_encs: Container of physical encoders managed.
  * @cur_master:Pointer to the current master in this
mode. Optimization
@@ -148,8 +149,8 @@ enum dpu_enc_rc_states {
  * all CTL paths
  * @crtc_kickoff_cb_data:  Opaque user data given to crtc_kickoff_cb
  * @debugfs_root:  Debug file system root file node
- * @enc_lock:  Lock around physical encoder
create/destroy and
-   access.
+ * @enc_lock:  Lock around physical encoder
+ * create/destroy/enable/disable
  * @frame_busy_mask:   Bitmask tracking which phys_enc we are
still
  * busy processing current command.
  * Bit0 = phys_encs[0] etc.
@@ -175,6 +176,8 @@ struct dpu_encoder_virt {
spinlock_t enc_spinlock;
uint32_t bus_scaling_client;

+   bool enabled;
+
unsigned int num_phys_encs;
struct dpu_encoder_phys *phys_encs[MAX_PHYS_ENCODERS_PER_VIRTUAL];
struct dpu_encoder_phys *cur_master;
@@ -1121,6 +1124,8 @@ static void dpu_encoder_virt_enable(struct
drm_encoder *drm_enc)
return;
}
dpu_enc = to_dpu_encoder_virt(drm_enc);
+
+   mutex_lock(_enc->enc_lock);
cur_mode = _enc->base.crtc->state->adjusted_mode;

trace_dpu_enc_enable(DRMID(drm_enc), cur_mode->hdisplay,
@@ -1137,10 +1142,15 @@ static void dpu_encoder_virt_enable(struct
drm_encoder *drm_enc)
if (ret) {
DPU_ERROR_ENC(dpu_enc, "dpu resource control failed:
%d\n",
ret);
-   return;
+   goto out;
}

_dpu_encoder_virt_enable_helper(drm_enc);
+
+   dpu_enc->enabled = true;
+
+out:
+   mutex_unlock(_enc->enc_lock);
 }

 static void dpu_encoder_virt_disable(struct drm_encoder *drm_enc)
@@ -1162,11 +1172,14 @@ static void dpu_encoder_virt_disable(struct
drm_encoder *drm_enc)
return;
}

-   mode = _enc->crtc->state->adjusted_mode;
-
dpu_enc = to_dpu_encoder_virt(drm_enc);
DPU_DEBUG_ENC(dpu_enc, "\n");

+   mutex_lock(_enc->enc_lock);

Where do you expect it to go wrong if enable/disable
is not protected using enc_lock?

Thanks and Regards,
Jeykumar S.

+   dpu_enc->enabled = false;
+
+   mode = _enc->crtc->state->adjusted_mode;
+
priv = drm_enc->dev->dev_private;
dpu_kms = to_dpu_kms(priv->kms);

@@ -1200,6 +1213,8 @@ static void dpu_encoder_virt_disable(struct
drm_encoder *drm_enc)
DPU_DEBUG_ENC(dpu_enc, "encoder disabled\n");

dpu_rm_release(_kms->rm, drm_enc);
+
+   mutex_unlock(_enc->enc_lock);
 }

 static enum dpu_intf dpu_encoder_get_intf(struct dpu_mdss_cfg 
*catalog,

@@ -2233,6 +2248,8 @@ struct drm_encoder *dpu_encoder_init(struct
drm_device *dev,

drm_encoder_helper_add(_enc->base, _encoder_helper_funcs);

+   dpu_enc->enabled = false;
+
return _enc->base;
 }


--
Jeykumar S
___
Freedreno mailing list
Freedreno@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/freedreno


Re: [Freedreno] [PATCH 10/12] drm/msm: dpu: Fix typo in dpu_encoder

2018-11-12 Thread Jeykumar Sankaran

On 2018-11-12 11:42, Sean Paul wrote:

From: Sean Paul 

enc_spinlock instead of enc_spin_lock.

Signed-off-by: Sean Paul 
---


Reviewed-by: Jeykumar Sankaran 


 drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
index 82c55efb500f..10a0676d1dcf 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
@@ -130,7 +130,7 @@ enum dpu_enc_rc_states {
  * Virtual encoder defers as much as possible to the physical
encoders.
  * Virtual encoder registers itself with the DRM Framework as the
encoder.
  * @base:  drm_encoder base class for registration with DRM
- * @enc_spin_lock: Virtual-Encoder-Wide Spin Lock for IRQ purposes
+ * @enc_spinlock:  Virtual-Encoder-Wide Spin Lock for IRQ purposes
  * @bus_scaling_client:Client handle to the bus scaling interface
  * @num_phys_encs: Actual number of physical encoders contained.
  * @phys_encs: Container of physical encoders managed.


--
Jeykumar S
___
Freedreno mailing list
Freedreno@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/freedreno


Re: [Freedreno] [PATCH 04/12] drm/msm: dpu: Don't use power_event for vbif_init_memtypes

2018-11-12 Thread Jeykumar Sankaran

On 2018-11-12 17:06, Jeykumar Sankaran wrote:

On 2018-11-12 11:42, Sean Paul wrote:

From: Sean Paul 

power_events are only used for pm_runtime, and that's all handled in
dpu_kms. So just call vbif_init_memtypes at the correct times.

Signed-off-by: Sean Paul 
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c | 21 +++--
 drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h |  1 -
 2 files changed, 3 insertions(+), 19 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
index 23094d108e81..ae2bbaae923d 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
@@ -651,10 +651,6 @@ static void _dpu_kms_hw_destroy(struct dpu_kms
*dpu_kms)
dpu_hw_intr_destroy(dpu_kms->hw_intr);
dpu_kms->hw_intr = NULL;

-   if (dpu_kms->power_event)
-   dpu_power_handle_unregister_event(
-   _kms->phandle, dpu_kms->power_event);
-
/* safe to call these more than once during shutdown */
_dpu_debugfs_destroy(dpu_kms);
_dpu_kms_mmu_destroy(dpu_kms);
@@ -832,16 +828,6 @@ u64 dpu_kms_get_clk_rate(struct dpu_kms *dpu_kms,
char *clock_name)
return clk_get_rate(clk->clk);
 }

-static void dpu_kms_handle_power_event(u32 event_type, void *usr)
-{
-   struct dpu_kms *dpu_kms = usr;
-
-   if (!dpu_kms)
-   return;
-
-   dpu_vbif_init_memtypes(dpu_kms);
-}
-
 static int dpu_kms_hw_init(struct msm_kms *kms)
 {
struct dpu_kms *dpu_kms;
@@ -1015,10 +1001,7 @@ static int dpu_kms_hw_init(struct msm_kms *kms)
/*
 * Handle (re)initializations during power enable
 */
-   dpu_kms_handle_power_event(DPU_POWER_EVENT_ENABLE, dpu_kms);
-   dpu_kms->power_event = dpu_power_handle_register_event(
-   _kms->phandle, DPU_POWER_EVENT_ENABLE,
-   dpu_kms_handle_power_event, dpu_kms, "kms");
+   dpu_vbif_init_memtypes(dpu_kms);

pm_runtime_put_sync(_kms->pdev->dev);

@@ -1172,6 +1155,8 @@ static int __maybe_unused 
dpu_runtime_resume(struct

device *dev)
return rc;
}

+   dpu_vbif_init_memtypes(dpu_kms);
+
rc = dpu_power_resource_enable(_kms->phandle, true);
if (rc)
DPU_ERROR("resource enable failed: %d\n", rc);
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h
b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h
index f2c78deb0854..5f08be187c86 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h
@@ -114,7 +114,6 @@ struct dpu_kms {
struct dpu_mdss_cfg *catalog;

struct dpu_power_handle phandle;


You can get rid of the handle and header inclusions here itself
to clean up KMS from power_handle stuff!


nvm. I see you are taking care of this in patch 9/12.



-   struct dpu_power_event *power_event;

/* directory entry for debugfs */
struct dentry *debugfs_root;


--
Jeykumar S
___
Freedreno mailing list
Freedreno@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/freedreno


Re: [Freedreno] [PATCH 09/12] drm/msm: dpu: Remove dpu_power_handle

2018-11-12 Thread Jeykumar Sankaran

On 2018-11-12 11:42, Sean Paul wrote:

From: Sean Paul 

Now that we don't have any event handlers, remove dpu_power_handle!

Signed-off-by: Sean Paul 


Reviewed-by: Jeykumar Sankaran 


---
 drivers/gpu/drm/msm/Makefile  |   1 -
 drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c   |  11 --
 drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h   |   3 -
 .../gpu/drm/msm/disp/dpu1/dpu_power_handle.c  | 136 --
 .../gpu/drm/msm/disp/dpu1/dpu_power_handle.h  | 113 ---
 5 files changed, 264 deletions(-)
 delete mode 100644 drivers/gpu/drm/msm/disp/dpu1/dpu_power_handle.c
 delete mode 100644 drivers/gpu/drm/msm/disp/dpu1/dpu_power_handle.h

diff --git a/drivers/gpu/drm/msm/Makefile 
b/drivers/gpu/drm/msm/Makefile

index 19ab521d4c3a..7d02ef3655b5 100644
--- a/drivers/gpu/drm/msm/Makefile
+++ b/drivers/gpu/drm/msm/Makefile
@@ -72,7 +72,6 @@ msm-y := \
disp/dpu1/dpu_kms.o \
disp/dpu1/dpu_mdss.o \
disp/dpu1/dpu_plane.o \
-   disp/dpu1/dpu_power_handle.o \
disp/dpu1/dpu_rm.o \
disp/dpu1/dpu_vbif.o \
msm_atomic.o \
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
index bae7e86b2913..e42685a1d928 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
@@ -1063,8 +1063,6 @@ static int dpu_bind(struct device *dev, struct
device *master, void *data)
return ret;
}

-   dpu_power_resource_init(pdev, _kms->phandle);
-
platform_set_drvdata(pdev, dpu_kms);

msm_kms_init(_kms->base, _funcs);
@@ -1084,7 +1082,6 @@ static void dpu_unbind(struct device *dev, struct
device *master, void *data)
struct dpu_kms *dpu_kms = platform_get_drvdata(pdev);
struct dss_module_power *mp = _kms->mp;

-   dpu_power_resource_deinit(pdev, _kms->phandle);
msm_dss_put_clk(mp->clk_config, mp->num_clk);
devm_kfree(>dev, mp->clk_config);
mp->num_clk = 0;
@@ -1123,10 +1120,6 @@ static int __maybe_unused
dpu_runtime_suspend(struct device *dev)
return rc;
}

-   rc = dpu_power_resource_enable(_kms->phandle, false);
-   if (rc)
-   DPU_ERROR("resource disable failed: %d\n", rc);
-
rc = msm_dss_enable_clk(mp->clk_config, mp->num_clk, false);
if (rc)
DPU_ERROR("clock disable failed rc:%d\n", rc);
@@ -1160,10 +1153,6 @@ static int __maybe_unused 
dpu_runtime_resume(struct

device *dev)
drm_for_each_crtc(crtc, ddev)
dpu_crtc_runtime_resume(crtc);

-   rc = dpu_power_resource_enable(_kms->phandle, true);
-   if (rc)
-   DPU_ERROR("resource enable failed: %d\n", rc);
-
return rc;
 }

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h
b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h
index 4e5acacb3065..59e18e2d3c59 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h
@@ -31,7 +31,6 @@
 #include "dpu_hw_top.h"
 #include "dpu_io_util.h"
 #include "dpu_rm.h"
-#include "dpu_power_handle.h"
 #include "dpu_irq.h"
 #include "dpu_core_perf.h"

@@ -114,8 +113,6 @@ struct dpu_kms {
int core_rev;
struct dpu_mdss_cfg *catalog;

-   struct dpu_power_handle phandle;
-
/* directory entry for debugfs */
struct dentry *debugfs_root;
struct dentry *debugfs_danger;
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_power_handle.c
b/drivers/gpu/drm/msm/disp/dpu1/dpu_power_handle.c
deleted file mode 100644
index 8e64f0a52147..
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_power_handle.c
+++ /dev/null
@@ -1,136 +0,0 @@
-/* Copyright (c) 2014-2018, The Linux Foundation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or 
modify

- * it under the terms of the GNU General Public License version 2 and
- * only version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- */
-
-#define pr_fmt(fmt)"[drm:%s:%d]: " fmt, __func__, __LINE__
-
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-
-#include "dpu_power_handle.h"
-#include "dpu_trace.h"
-
-static void dpu_power_event_trigger_locked(struct dpu_power_handle
*phandle,
-   u32 event_type)
-{
-   struct dpu_power_event *event;
-
-   list_for_each_entry(event, >event_list, list) {
-   if (event->event_type & event_type)
-   event->cb_fnc(event_type, event->usr);
-   }
-}
-
-void dpu_power_resource_init(struct platform

Re: [Freedreno] [PATCH 08/12] drm/msm: dpu: Move DPU_POWER_HANDLE_DBUS_ID to core_perf

2018-11-12 Thread Jeykumar Sankaran

On 2018-11-12 11:42, Sean Paul wrote:

From: Sean Paul 

It's only used in core_perf, so stick it there (and change the name to
reflect that).

Signed-off-by: Sean Paul 
---


Reviewed-by: Jeykumar Sankaran 


 drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.c | 34 +--
 drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.h | 17 --
 drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c  |  4 +--
 .../gpu/drm/msm/disp/dpu1/dpu_power_handle.h  | 13 ---
 4 files changed, 34 insertions(+), 34 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.c
b/drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.c
index ef6dd43f8bec..bffc51e496e7 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.c
@@ -95,20 +95,20 @@ static void _dpu_core_perf_calc_crtc(struct dpu_kms
*kms,
memset(perf, 0, sizeof(struct dpu_core_perf_params));

if (!dpu_cstate->bw_control) {
-   for (i = 0; i < DPU_POWER_HANDLE_DBUS_ID_MAX; i++) {
+   for (i = 0; i < DPU_CORE_PERF_DATA_BUS_ID_MAX; i++) {
perf->bw_ctl[i] = kms->catalog->perf.max_bw_high *
1000ULL;
perf->max_per_pipe_ib[i] = perf->bw_ctl[i];
}
perf->core_clk_rate = kms->perf.max_core_clk_rate;
} else if (kms->perf.perf_tune.mode == DPU_PERF_MODE_MINIMUM) {
-   for (i = 0; i < DPU_POWER_HANDLE_DBUS_ID_MAX; i++) {
+   for (i = 0; i < DPU_CORE_PERF_DATA_BUS_ID_MAX; i++) {
perf->bw_ctl[i] = 0;
perf->max_per_pipe_ib[i] = 0;
}
perf->core_clk_rate = 0;
} else if (kms->perf.perf_tune.mode == DPU_PERF_MODE_FIXED) {
-   for (i = 0; i < DPU_POWER_HANDLE_DBUS_ID_MAX; i++) {
+   for (i = 0; i < DPU_CORE_PERF_DATA_BUS_ID_MAX; i++) {
perf->bw_ctl[i] = kms->perf.fix_core_ab_vote;
perf->max_per_pipe_ib[i] =
kms->perf.fix_core_ib_vote;
}
@@ -118,12 +118,12 @@ static void _dpu_core_perf_calc_crtc(struct 
dpu_kms

*kms,
DPU_DEBUG(
"crtc=%d clk_rate=%llu core_ib=%llu core_ab=%llu
llcc_ib=%llu llcc_ab=%llu mem_ib=%llu mem_ab=%llu\n",
crtc->base.id, perf->core_clk_rate,
-
perf->max_per_pipe_ib[DPU_POWER_HANDLE_DBUS_ID_MNOC],
-   perf->bw_ctl[DPU_POWER_HANDLE_DBUS_ID_MNOC],
-
perf->max_per_pipe_ib[DPU_POWER_HANDLE_DBUS_ID_LLCC],
-   perf->bw_ctl[DPU_POWER_HANDLE_DBUS_ID_LLCC],
-
perf->max_per_pipe_ib[DPU_POWER_HANDLE_DBUS_ID_EBI],
-   perf->bw_ctl[DPU_POWER_HANDLE_DBUS_ID_EBI]);
+
perf->max_per_pipe_ib[DPU_CORE_PERF_DATA_BUS_ID_MNOC],
+   perf->bw_ctl[DPU_CORE_PERF_DATA_BUS_ID_MNOC],
+
perf->max_per_pipe_ib[DPU_CORE_PERF_DATA_BUS_ID_LLCC],
+   perf->bw_ctl[DPU_CORE_PERF_DATA_BUS_ID_LLCC],
+
perf->max_per_pipe_ib[DPU_CORE_PERF_DATA_BUS_ID_EBI],
+   perf->bw_ctl[DPU_CORE_PERF_DATA_BUS_ID_EBI]);
 }

 int dpu_core_perf_crtc_check(struct drm_crtc *crtc,
@@ -158,8 +158,8 @@ int dpu_core_perf_crtc_check(struct drm_crtc *crtc,
/* obtain new values */
_dpu_core_perf_calc_crtc(kms, crtc, state, _cstate->new_perf);

-   for (i = DPU_POWER_HANDLE_DBUS_ID_MNOC;
-   i < DPU_POWER_HANDLE_DBUS_ID_MAX; i++) {
+   for (i = DPU_CORE_PERF_DATA_BUS_ID_MNOC;
+   i < DPU_CORE_PERF_DATA_BUS_ID_MAX; i++) {
bw_sum_of_intfs = dpu_cstate->new_perf.bw_ctl[i];
curr_client_type = dpu_crtc_get_client_type(crtc);

@@ -290,7 +290,7 @@ void dpu_core_perf_crtc_release_bw(struct drm_crtc
*crtc)
if (kms->perf.enable_bw_release) {
trace_dpu_cmd_release_bw(crtc->base.id);
DPU_DEBUG("Release BW crtc=%d\n", crtc->base.id);
-   for (i = 0; i < DPU_POWER_HANDLE_DBUS_ID_MAX; i++) {
+   for (i = 0; i < DPU_CORE_PERF_DATA_BUS_ID_MAX; i++) {
dpu_crtc->cur_perf.bw_ctl[i] = 0;
_dpu_core_perf_crtc_update_bus(kms, crtc, i);
}
@@ -367,7 +367,7 @@ int dpu_core_perf_crtc_update(struct drm_crtc 
*crtc,

new = _cstate->new_perf;

if (_dpu_core_perf_crtc_is_power_on(crtc) && !stop_req) {
-   for (i = 0; i < DPU_POWER_HANDLE_DBUS_ID_MAX; i++) {
+   for (i = 0; i < DPU_CORE_PERF_DATA_BUS_ID_MAX; i++) {
/*
 * cases for bus bandwidth update.
 * 1. new bandwidth vote - "ab or ib vote" is
higher
@@ -409,13 +409,13 @@ int dpu_core_perf_

Re: [Freedreno] [PATCH 07/12] drm/msm: dpu: Include dpu_io_util.h directly in dpu_kms.h

2018-11-12 Thread Jeykumar Sankaran

On 2018-11-12 11:42, Sean Paul wrote:

From: Sean Paul 

It's needed for struct dss_module_power, and is currently being pulled
in by dpu_power_handle.h

Signed-off-by: Sean Paul 
---


Reviewed-by: Jeykumar Sankaran 


 drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h
b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h
index 5f08be187c86..4e5acacb3065 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h
@@ -29,6 +29,7 @@
 #include "dpu_hw_lm.h"
 #include "dpu_hw_interrupts.h"
 #include "dpu_hw_top.h"
+#include "dpu_io_util.h"
 #include "dpu_rm.h"
 #include "dpu_power_handle.h"
 #include "dpu_irq.h"


--
Jeykumar S
___
Freedreno mailing list
Freedreno@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/freedreno


Re: [Freedreno] [PATCH 06/12] drm/msm: dpu: Remove power_handle from core_perf

2018-11-12 Thread Jeykumar Sankaran

On 2018-11-12 11:42, Sean Paul wrote:

From: Sean Paul 

It's unused

Signed-off-by: Sean Paul 
---


Reviewed-by: Jeykumar Sankaran 


 drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.c | 3 ---
 drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.h | 5 -
 drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c   | 1 -
 3 files changed, 9 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.c
b/drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.c
index 22e84b3d7f98..ef6dd43f8bec 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.c
@@ -605,7 +605,6 @@ void dpu_core_perf_destroy(struct dpu_core_perf 
*perf)

dpu_core_perf_debugfs_destroy(perf);
perf->max_core_clk_rate = 0;
perf->core_clk = NULL;
-   perf->phandle = NULL;
perf->catalog = NULL;
perf->dev = NULL;
 }
@@ -613,12 +612,10 @@ void dpu_core_perf_destroy(struct dpu_core_perf
*perf)
 int dpu_core_perf_init(struct dpu_core_perf *perf,
struct drm_device *dev,
struct dpu_mdss_cfg *catalog,
-   struct dpu_power_handle *phandle,
struct dss_clk *core_clk)
 {
perf->dev = dev;
perf->catalog = catalog;
-   perf->phandle = phandle;
perf->core_clk = core_clk;

perf->max_core_clk_rate = core_clk->max_rate;
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.h
b/drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.h
index fbcbe0c7527a..68b84d85eb8f 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.h
@@ -19,7 +19,6 @@
 #include 

 #include "dpu_hw_catalog.h"
-#include "dpu_power_handle.h"

 #defineDPU_PERF_DEFAULT_MAX_CORE_CLK_RATE  41250

@@ -52,7 +51,6 @@ struct dpu_core_perf_tune {
  * @dev: Pointer to drm device
  * @debugfs_root: top level debug folder
  * @catalog: Pointer to catalog configuration
- * @phandle: Pointer to power handler
  * @core_clk: Pointer to core clock structure
  * @core_clk_rate: current core clock rate
  * @max_core_clk_rate: maximum allowable core clock rate
@@ -66,7 +64,6 @@ struct dpu_core_perf {
struct drm_device *dev;
struct dentry *debugfs_root;
struct dpu_mdss_cfg *catalog;
-   struct dpu_power_handle *phandle;
struct dss_clk *core_clk;
u64 core_clk_rate;
u64 max_core_clk_rate;
@@ -113,13 +110,11 @@ void dpu_core_perf_destroy(struct dpu_core_perf
*perf);
  * @perf: Pointer to core performance context
  * @dev: Pointer to drm device
  * @catalog: Pointer to catalog
- * @phandle: Pointer to power handle
  * @core_clk: pointer to core clock
  */
 int dpu_core_perf_init(struct dpu_core_perf *perf,
struct drm_device *dev,
struct dpu_mdss_cfg *catalog,
-   struct dpu_power_handle *phandle,
struct dss_clk *core_clk);

 /**
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
index 62a02c606811..bae7e86b2913 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
@@ -957,7 +957,6 @@ static int dpu_kms_hw_init(struct msm_kms *kms)
}

rc = dpu_core_perf_init(_kms->perf, dev, dpu_kms->catalog,
-   _kms->phandle,
_dpu_kms_get_clk(dpu_kms, "core"));
if (rc) {
DPU_ERROR("failed to init perf %d\n", rc);


--
Jeykumar S
___
Freedreno mailing list
Freedreno@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/freedreno


Re: [Freedreno] [PATCH 05/12] drm/msm: dpu: Handle crtc pm_runtime_resume() directly

2018-11-12 Thread Jeykumar Sankaran

On 2018-11-12 11:42, Sean Paul wrote:

From: Sean Paul 

Instead of registering through dpu_power_handle just to get a call on
runtime_resume, call the crtc function directly.

Signed-off-by: Sean Paul 
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c  | 23 ++-
 drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h  | 10 ++
 drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c   |  4 
 drivers/gpu/drm/msm/disp/dpu1/dpu_trace.h |  8 
 4 files changed, 20 insertions(+), 25 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
index e09209d6c469..c55cb751e2b4 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
@@ -33,7 +33,6 @@
 #include "dpu_plane.h"
 #include "dpu_encoder.h"
 #include "dpu_vbif.h"
-#include "dpu_power_handle.h"
 #include "dpu_core_perf.h"
 #include "dpu_trace.h"

@@ -69,8 +68,6 @@ static void dpu_crtc_destroy(struct drm_crtc *crtc)
if (!crtc)
return;

-   dpu_crtc->phandle = NULL;
-
drm_crtc_cleanup(crtc);
mutex_destroy(_crtc->crtc_lock);
kfree(dpu_crtc);
@@ -844,15 +841,17 @@ static struct drm_crtc_state
*dpu_crtc_duplicate_state(struct drm_crtc *crtc)
return >base;
 }

-static void dpu_crtc_handle_power_event(u32 event_type, void *arg)
+void dpu_crtc_runtime_resume(struct drm_crtc *crtc)
 {
-   struct drm_crtc *crtc = arg;
struct dpu_crtc *dpu_crtc = to_dpu_crtc(crtc);
struct drm_encoder *encoder;

mutex_lock(_crtc->crtc_lock);

-   trace_dpu_crtc_handle_power_event(DRMID(crtc), event_type);
+   if (!dpu_crtc->enabled)
+   goto end;
+
+   trace_dpu_crtc_runtime_resume(DRMID(crtc));

/* restore encoder; crtc will be programmed during commit */
drm_for_each_encoder(encoder, crtc->dev) {
@@ -862,6 +861,7 @@ static void dpu_crtc_handle_power_event(u32
event_type, void *arg)
dpu_encoder_virt_restore(encoder);
}

+end:
mutex_unlock(_crtc->crtc_lock);
 }

@@ -917,10 +917,6 @@ static void dpu_crtc_disable(struct drm_crtc 
*crtc)

dpu_encoder_register_frame_event_callback(encoder, NULL,
NULL);
}

-   if (dpu_crtc->power_event)
-   dpu_power_handle_unregister_event(dpu_crtc->phandle,
-   dpu_crtc->power_event);
-
memset(cstate->mixers, 0, sizeof(cstate->mixers));
cstate->num_mixers = 0;

@@ -972,11 +968,6 @@ static void dpu_crtc_enable(struct drm_crtc *crtc,

/* Enable/restore vblank irq handling */
drm_crtc_vblank_on(crtc);
-
-   dpu_crtc->power_event = dpu_power_handle_register_event(
-   dpu_crtc->phandle, DPU_POWER_EVENT_ENABLE,
-   dpu_crtc_handle_power_event, crtc, dpu_crtc->name);
-
 }

 struct plane_state {
@@ -1522,8 +1513,6 @@ struct drm_crtc *dpu_crtc_init(struct drm_device
*dev, struct drm_plane *plane,
/* initialize event handling */
spin_lock_init(_crtc->event_lock);

If this is for synchronizing power events, we can get rid of this too.

Thanks,
Jeykumar S.


-   dpu_crtc->phandle = >phandle;
-
DPU_DEBUG("%s: successfully initialized crtc\n", dpu_crtc->name);
return crtc;
 }
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h
b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h
index 4822602402f9..1dca91d1210f 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h
@@ -151,7 +151,6 @@ struct dpu_crtc_frame_event {
  * @event_worker  : Event worker queue
  * @event_lock: Spinlock around event handling code
  * @phandle: Pointer to power handler
- * @power_event   : registered power event handle
  * @cur_perf  : current performance committed to clock/bandwidth
driver
  */
 struct dpu_crtc {
@@ -187,9 +186,6 @@ struct dpu_crtc {
/* for handling internal event thread */
spinlock_t event_lock;

-   struct dpu_power_handle *phandle;
-   struct dpu_power_event *power_event;
-
struct dpu_core_perf_params cur_perf;

struct dpu_crtc_smmu_state_data smmu_state;
@@ -333,4 +329,10 @@ static inline bool dpu_crtc_is_enabled(struct
drm_crtc *crtc)
return crtc ? crtc->enabled : false;
 }

+/**
+ * dpu_crtc_runtime_resume - called by the top-level on 
pm_runtime_resume

+ * @crtc: CRTC to resume
+ */
+void dpu_crtc_runtime_resume(struct drm_crtc *crtc);
+
 #endif /* _DPU_CRTC_H_ */
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
index ae2bbaae923d..62a02c606811 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
@@ -1140,6 +1140,7 @@ static int __maybe_unused 
dpu_runtime_resume(struct

device *dev)
int rc = -1;
struct platform_device *pdev = to_platform_device(dev);
struct dpu_kms *dpu_kms = platform_get_drvdata(pdev);
+   struct drm_crtc *crtc;

Re: [Freedreno] [PATCH 04/12] drm/msm: dpu: Don't use power_event for vbif_init_memtypes

2018-11-12 Thread Jeykumar Sankaran

On 2018-11-12 11:42, Sean Paul wrote:

From: Sean Paul 

power_events are only used for pm_runtime, and that's all handled in
dpu_kms. So just call vbif_init_memtypes at the correct times.

Signed-off-by: Sean Paul 
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c | 21 +++--
 drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h |  1 -
 2 files changed, 3 insertions(+), 19 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
index 23094d108e81..ae2bbaae923d 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
@@ -651,10 +651,6 @@ static void _dpu_kms_hw_destroy(struct dpu_kms
*dpu_kms)
dpu_hw_intr_destroy(dpu_kms->hw_intr);
dpu_kms->hw_intr = NULL;

-   if (dpu_kms->power_event)
-   dpu_power_handle_unregister_event(
-   _kms->phandle, dpu_kms->power_event);
-
/* safe to call these more than once during shutdown */
_dpu_debugfs_destroy(dpu_kms);
_dpu_kms_mmu_destroy(dpu_kms);
@@ -832,16 +828,6 @@ u64 dpu_kms_get_clk_rate(struct dpu_kms *dpu_kms,
char *clock_name)
return clk_get_rate(clk->clk);
 }

-static void dpu_kms_handle_power_event(u32 event_type, void *usr)
-{
-   struct dpu_kms *dpu_kms = usr;
-
-   if (!dpu_kms)
-   return;
-
-   dpu_vbif_init_memtypes(dpu_kms);
-}
-
 static int dpu_kms_hw_init(struct msm_kms *kms)
 {
struct dpu_kms *dpu_kms;
@@ -1015,10 +1001,7 @@ static int dpu_kms_hw_init(struct msm_kms *kms)
/*
 * Handle (re)initializations during power enable
 */
-   dpu_kms_handle_power_event(DPU_POWER_EVENT_ENABLE, dpu_kms);
-   dpu_kms->power_event = dpu_power_handle_register_event(
-   _kms->phandle, DPU_POWER_EVENT_ENABLE,
-   dpu_kms_handle_power_event, dpu_kms, "kms");
+   dpu_vbif_init_memtypes(dpu_kms);

pm_runtime_put_sync(_kms->pdev->dev);

@@ -1172,6 +1155,8 @@ static int __maybe_unused 
dpu_runtime_resume(struct

device *dev)
return rc;
}

+   dpu_vbif_init_memtypes(dpu_kms);
+
rc = dpu_power_resource_enable(_kms->phandle, true);
if (rc)
DPU_ERROR("resource enable failed: %d\n", rc);
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h
b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h
index f2c78deb0854..5f08be187c86 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h
@@ -114,7 +114,6 @@ struct dpu_kms {
struct dpu_mdss_cfg *catalog;

struct dpu_power_handle phandle;


You can get rid of the handle and header inclusions here itself
to clean up KMS from power_handle stuff!


-   struct dpu_power_event *power_event;

/* directory entry for debugfs */
struct dentry *debugfs_root;


--
Jeykumar S
___
Freedreno mailing list
Freedreno@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/freedreno


Re: [Freedreno] [PATCH 04/12] drm/msm: dpu: Don't use power_event for vbif_init_memtypes

2018-11-12 Thread Jeykumar Sankaran

On 2018-11-12 11:42, Sean Paul wrote:

From: Sean Paul 

power_events are only used for pm_runtime, and that's all handled in
dpu_kms. So just call vbif_init_memtypes at the correct times.

Signed-off-by: Sean Paul 
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c | 21 +++--
 drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h |  1 -
 2 files changed, 3 insertions(+), 19 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
index 23094d108e81..ae2bbaae923d 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
@@ -651,10 +651,6 @@ static void _dpu_kms_hw_destroy(struct dpu_kms
*dpu_kms)
dpu_hw_intr_destroy(dpu_kms->hw_intr);
dpu_kms->hw_intr = NULL;

-   if (dpu_kms->power_event)
-   dpu_power_handle_unregister_event(
-   _kms->phandle, dpu_kms->power_event);
-
/* safe to call these more than once during shutdown */
_dpu_debugfs_destroy(dpu_kms);
_dpu_kms_mmu_destroy(dpu_kms);
@@ -832,16 +828,6 @@ u64 dpu_kms_get_clk_rate(struct dpu_kms *dpu_kms,
char *clock_name)
return clk_get_rate(clk->clk);
 }

-static void dpu_kms_handle_power_event(u32 event_type, void *usr)
-{
-   struct dpu_kms *dpu_kms = usr;
-
-   if (!dpu_kms)
-   return;
-
-   dpu_vbif_init_memtypes(dpu_kms);
-}
-
 static int dpu_kms_hw_init(struct msm_kms *kms)
 {
struct dpu_kms *dpu_kms;
@@ -1015,10 +1001,7 @@ static int dpu_kms_hw_init(struct msm_kms *kms)
/*
 * Handle (re)initializations during power enable
 */


Is this comment valid anymore?


-   dpu_kms_handle_power_event(DPU_POWER_EVENT_ENABLE, dpu_kms);
-   dpu_kms->power_event = dpu_power_handle_register_event(
-   _kms->phandle, DPU_POWER_EVENT_ENABLE,
-   dpu_kms_handle_power_event, dpu_kms, "kms");
+   dpu_vbif_init_memtypes(dpu_kms);

pm_runtime_put_sync(_kms->pdev->dev);

@@ -1172,6 +1155,8 @@ static int __maybe_unused 
dpu_runtime_resume(struct

device *dev)
return rc;
}

+   dpu_vbif_init_memtypes(dpu_kms);
+
rc = dpu_power_resource_enable(_kms->phandle, true);
if (rc)
DPU_ERROR("resource enable failed: %d\n", rc);
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h
b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h
index f2c78deb0854..5f08be187c86 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h
@@ -114,7 +114,6 @@ struct dpu_kms {
struct dpu_mdss_cfg *catalog;

struct dpu_power_handle phandle;
-   struct dpu_power_event *power_event;

/* directory entry for debugfs */
struct dentry *debugfs_root;


--
Jeykumar S
___
Freedreno mailing list
Freedreno@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/freedreno


Re: [Freedreno] [PATCH 03/12] drm/msm: dpu: Remove dpu_power_client

2018-11-12 Thread Jeykumar Sankaran

On 2018-11-12 11:42, Sean Paul wrote:

From: Sean Paul 

There's only one client -- core, and it's only used for runtime pm 
which

is already refcounted.

Signed-off-by: Sean Paul 


Reviewed-by: Jeykumar Sankaran 


---
 drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c   | 22 +
 drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h   |  1 -
 .../gpu/drm/msm/disp/dpu1/dpu_power_handle.c  | 96 +--
 .../gpu/drm/msm/disp/dpu1/dpu_power_handle.h  | 86 +
 4 files changed, 6 insertions(+), 199 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
index 985c855796ae..23094d108e81 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
@@ -676,11 +676,6 @@ static void _dpu_kms_hw_destroy(struct dpu_kms
*dpu_kms)
dpu_hw_catalog_deinit(dpu_kms->catalog);
dpu_kms->catalog = NULL;

-   if (dpu_kms->core_client)
-   dpu_power_client_destroy(_kms->phandle,
-   dpu_kms->core_client);
-   dpu_kms->core_client = NULL;
-
if (dpu_kms->vbif[VBIF_NRT])
devm_iounmap(_kms->pdev->dev,
dpu_kms->vbif[VBIF_NRT]);
dpu_kms->vbif[VBIF_NRT] = NULL;
@@ -913,17 +908,6 @@ static int dpu_kms_hw_init(struct msm_kms *kms)
dpu_kms->reg_dma_len = dpu_iomap_size(dpu_kms->pdev,
"regdma");
}

-   dpu_kms->core_client = dpu_power_client_create(_kms->phandle,
-   "core");
-   if (IS_ERR_OR_NULL(dpu_kms->core_client)) {
-   rc = PTR_ERR(dpu_kms->core_client);
-   if (!dpu_kms->core_client)
-   rc = -EINVAL;
-   DPU_ERROR("dpu power client create failed: %d\n", rc);
-   dpu_kms->core_client = NULL;
-   goto error;
-   }
-
pm_runtime_get_sync(_kms->pdev->dev);

_dpu_kms_core_hw_rev_init(dpu_kms);
@@ -1157,8 +1141,7 @@ static int __maybe_unused 
dpu_runtime_suspend(struct

device *dev)
return rc;
}

-   rc = dpu_power_resource_enable(_kms->phandle,
-   dpu_kms->core_client, false);
+   rc = dpu_power_resource_enable(_kms->phandle, false);
if (rc)
DPU_ERROR("resource disable failed: %d\n", rc);

@@ -1189,8 +1172,7 @@ static int __maybe_unused 
dpu_runtime_resume(struct

device *dev)
return rc;
}

-   rc = dpu_power_resource_enable(_kms->phandle,
-   dpu_kms->core_client, true);
+   rc = dpu_power_resource_enable(_kms->phandle, true);
if (rc)
DPU_ERROR("resource enable failed: %d\n", rc);

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h
b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h
index 2a3625eef6d3..f2c78deb0854 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h
@@ -114,7 +114,6 @@ struct dpu_kms {
struct dpu_mdss_cfg *catalog;

struct dpu_power_handle phandle;
-   struct dpu_power_client *core_client;
struct dpu_power_event *power_event;

/* directory entry for debugfs */
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_power_handle.c
b/drivers/gpu/drm/msm/disp/dpu1/dpu_power_handle.c
index 8c6f92aaaf87..8e64f0a52147 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_power_handle.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_power_handle.c
@@ -35,59 +35,11 @@ static void dpu_power_event_trigger_locked(struct
dpu_power_handle *phandle,
}
 }

-struct dpu_power_client *dpu_power_client_create(
-   struct dpu_power_handle *phandle, char *client_name)
-{
-   struct dpu_power_client *client;
-   static u32 id;
-
-   if (!client_name || !phandle) {
-   pr_err("client name is null or invalid power data\n");
-   return ERR_PTR(-EINVAL);
-   }
-
-   client = kzalloc(sizeof(struct dpu_power_client), GFP_KERNEL);
-   if (!client)
-   return ERR_PTR(-ENOMEM);
-
-   mutex_lock(>phandle_lock);
-   strlcpy(client->name, client_name, MAX_CLIENT_NAME_LEN);
-   client->usecase_ndx = VOTE_INDEX_DISABLE;
-   client->id = id;
-   client->active = true;
-   pr_debug("client %s created:%pK id :%d\n", client_name,
-   client, id);
-   id++;
-   list_add(>list, >power_client_clist);
-   mutex_unlock(>phandle_lock);
-
-   return client;
-}
-
-void dpu_power_client_destroy(struct dpu_power_handle *phandle,
-   struct dpu_power_client *client)
-{
-   if (!client  || !phandle) {
-   pr_err("reg bus vote: invalid client handle\n");
-   } else if (!client->active) {
-   pr_err("dpu power deinit already done\n");
-   kf

Re: [Freedreno] [PATCH 02/12] drm/msm: dpu: Remove unused trace_dpu_perf_update_bus()

2018-11-12 Thread Jeykumar Sankaran

On 2018-11-12 11:42, Sean Paul wrote:

From: Sean Paul 

Signed-off-by: Sean Paul 
---


Reviewed-by: Jeykumar Sankaran 


 drivers/gpu/drm/msm/disp/dpu1/dpu_trace.h | 21 -
 1 file changed, 21 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_trace.h
b/drivers/gpu/drm/msm/disp/dpu1/dpu_trace.h
index 0c122e173892..7ab0ba8224f6 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_trace.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_trace.h
@@ -99,27 +99,6 @@ TRACE_EVENT(dpu_perf_set_ot,
__entry->vbif_idx)
 )

-TRACE_EVENT(dpu_perf_update_bus,
-   TP_PROTO(int client, unsigned long long ab_quota,
-   unsigned long long ib_quota),
-   TP_ARGS(client, ab_quota, ib_quota),
-   TP_STRUCT__entry(
-   __field(int, client)
-   __field(u64, ab_quota)
-   __field(u64, ib_quota)
-   ),
-   TP_fast_assign(
-   __entry->client = client;
-   __entry->ab_quota = ab_quota;
-   __entry->ib_quota = ib_quota;
-   ),
-   TP_printk("Request client:%d ab=%llu ib=%llu",
-   __entry->client,
-   __entry->ab_quota,
-   __entry->ib_quota)
-)
-
-
 TRACE_EVENT(dpu_cmd_release_bw,
TP_PROTO(u32 crtc_id),
TP_ARGS(crtc_id),


--
Jeykumar S
___
Freedreno mailing list
Freedreno@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/freedreno


Re: [Freedreno] [PATCH 01/12] drm/msm: dpu: Remove dpu_power_handle_get_dbus_name()

2018-11-12 Thread Jeykumar Sankaran

On 2018-11-12 11:42, Sean Paul wrote:

From: Sean Paul 

It's only used for debugfs, so just output the enum value instead.

Signed-off-by: Sean Paul 
---


Reviewed-by: Jeykumar Sankaran 


 drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c |  6 ++
 drivers/gpu/drm/msm/disp/dpu1/dpu_power_handle.c | 14 --
 drivers/gpu/drm/msm/disp/dpu1/dpu_power_handle.h |  7 ---
 3 files changed, 2 insertions(+), 25 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
index ed84cf44a222..e09209d6c469 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
@@ -1381,11 +1381,9 @@ static int dpu_crtc_debugfs_state_show(struct
seq_file *s, void *v)
dpu_crtc->cur_perf.core_clk_rate);
for (i = DPU_POWER_HANDLE_DBUS_ID_MNOC;
i < DPU_POWER_HANDLE_DBUS_ID_MAX; i++) {
-   seq_printf(s, "bw_ctl[%s]: %llu\n",
-   dpu_power_handle_get_dbus_name(i),
+   seq_printf(s, "bw_ctl[%d]: %llu\n", i,
dpu_crtc->cur_perf.bw_ctl[i]);
-   seq_printf(s, "max_per_pipe_ib[%s]: %llu\n",
-   dpu_power_handle_get_dbus_name(i),
+   seq_printf(s, "max_per_pipe_ib[%d]: %llu\n", i,
dpu_crtc->cur_perf.max_per_pipe_ib[i]);
}

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_power_handle.c
b/drivers/gpu/drm/msm/disp/dpu1/dpu_power_handle.c
index fc14116789f2..8c6f92aaaf87 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_power_handle.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_power_handle.c
@@ -24,20 +24,6 @@
 #include "dpu_power_handle.h"
 #include "dpu_trace.h"

-static const char *data_bus_name[DPU_POWER_HANDLE_DBUS_ID_MAX] = {
-   [DPU_POWER_HANDLE_DBUS_ID_MNOC] = "qcom,dpu-data-bus",
-   [DPU_POWER_HANDLE_DBUS_ID_LLCC] = "qcom,dpu-llcc-bus",
-   [DPU_POWER_HANDLE_DBUS_ID_EBI] = "qcom,dpu-ebi-bus",
-};
-
-const char *dpu_power_handle_get_dbus_name(u32 bus_id)
-{
-   if (bus_id < DPU_POWER_HANDLE_DBUS_ID_MAX)
-   return data_bus_name[bus_id];
-
-   return NULL;
-}
-
 static void dpu_power_event_trigger_locked(struct dpu_power_handle
*phandle,
u32 event_type)
 {
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_power_handle.h
b/drivers/gpu/drm/msm/disp/dpu1/dpu_power_handle.h
index a65b7a297f21..f627ae28ec68 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_power_handle.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_power_handle.h
@@ -207,11 +207,4 @@ struct dpu_power_event
*dpu_power_handle_register_event(
 void dpu_power_handle_unregister_event(struct dpu_power_handle 
*phandle,

struct dpu_power_event *event);

-/**
- * dpu_power_handle_get_dbus_name - get name of given data bus 
identifier

- * @bus_id:data bus identifier
- * Return: Pointer to name string if success; NULL otherwise
- */
-const char *dpu_power_handle_get_dbus_name(u32 bus_id);
-
 #endif /* _DPU_POWER_HANDLE_H_ */


--
Jeykumar S
___
Freedreno mailing list
Freedreno@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/freedreno


Re: [Freedreno] [PATCH v2 1/3] drm/msm: dpu: Mask inactive pending flushes

2018-11-08 Thread Jeykumar Sankaran

On 2018-11-08 13:40, Sean Paul wrote:

On Thu, Nov 08, 2018 at 01:03:03PM -0800, Jeykumar Sankaran wrote:

On 2018-10-30 09:00, Sean Paul wrote:
> From: Sean Paul 
>
> This patch masks any pending flushes which have not been latched for a
> commit. This will catch the case where an asynchronous update is
> nullified by a disable in the same frame.
>
> Changes in v2:
> - Added to the set
>
> Signed-off-by: Sean Paul 
> ---
>  drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c | 7 +++
>  1 file changed, 7 insertions(+)
>
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c
> b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c
> index 8fa601a9abbf..d7a7fedc09f7 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c
> @@ -28,6 +28,7 @@
>  #define   CTL_TOP   0x014
>  #define   CTL_FLUSH 0x018
>  #define   CTL_START 0x01C
> +#define   CTL_FLUSH_MASK0x090
>  #define   CTL_PREPARE   0x0d0
>  #define   CTL_SW_RESET  0x030
>  #define   CTL_LAYER_EXTN_OFFSET 0x40
> @@ -121,6 +122,12 @@ static inline void

dpu_hw_ctl_trigger_flush(struct

> dpu_hw_ctl *ctx)
>  {
>trace_dpu_hw_ctl_trigger_pending_flush(ctx->pending_flush_mask,
> dpu_hw_ctl_get_flush_register(ctx));
> +
> +  /*
> +   * Async updates could have changed CTL_FLUSH since it was last
> latched.
> +   * Mask anything not involved in this latest commit.
> +   */
> +  DPU_REG_WRITE(>hw, CTL_FLUSH_MASK, ~ctx->pending_flush_mask);
Do we need this change for adding the current async cursor support?


Hmm, I think you asked me to implement this at the weekly meeting a 
little

while ago. Apparently HW team requested that we mask off the bits for
planes which have been disabled-but-not-flushed?

OK. If you want to implement the HW team recommendation, you should 
block the
FLUSH writes until both FLUSH and FLUSH_MASK writes goes through. We can 
do
that by writing 0x to the FLUSH_MASK indicating "hardware is not 
ready"

at the beginnging of the new vsync window. Since async updates dont wait
for commit_done (vsync), we can do that only for sync commits. Once we 
are
done programming all the registers and the final flush bits are ready, 
the
order of writing has to be reversed by writing FLUSH first and then 
FLUSH_MASK

to the inverse of FLUSH to unblock the hardware programming on vsync.

Still, there is a small window of error where vsync can happen between 
FLUSH
and FLUSH_MASK writes where we will end up missing the vsync but no 
partial

frame registers will be programmed.

I believe we have decided to try out this approach with a fresh set of 
patches
and let the current cursor support get in as such. In that case, we can 
drop

this patch from this series.

Thanks,
Jeykumar S.


Sean

We are not masking any bit by default. So there is no need for 
updating

it

here.

The usage of flush_mask is not completely explored yet. Maybe we can 
add
this register support when we revisit this async logic as we 
discussed.


Thanks and Regards,
Jeykumar S.
>DPU_REG_WRITE(>hw, CTL_FLUSH, ctx->pending_flush_mask);
>  }

--
Jeykumar S


--
Jeykumar S
___
Freedreno mailing list
Freedreno@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/freedreno


Re: [Freedreno] [PATCH 1/2] drm/msm: use common display thread for dispatching vblank events

2018-11-08 Thread Jeykumar Sankaran

On 2018-11-01 12:09, Sean Paul wrote:

On Wed, Oct 31, 2018 at 05:19:04PM -0700, Jeykumar Sankaran wrote:

DPU was using one thread per display to dispatch async
commits and vblank requests. Since clean up already happened
in msm to use the common thread for all the display commits,
display threads are only used to cater vblank requests. Single
thread is sufficient to do the job without any performance hits.

Signed-off-by: Jeykumar Sankaran 
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c |  6 +---
 drivers/gpu/drm/msm/msm_drv.c   | 50

-

 drivers/gpu/drm/msm/msm_drv.h   |  2 +-
 3 files changed, 23 insertions(+), 35 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c

b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c

index 82c55ef..aff20f5 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
@@ -753,11 +753,7 @@ static int dpu_encoder_resource_control(struct

drm_encoder *drm_enc,

is_vid_mode = dpu_enc->disp_info.capabilities &
MSM_DISPLAY_CAP_VID_MODE;

-   if (drm_enc->crtc->index >= ARRAY_SIZE(priv->disp_thread)) {
-   DPU_ERROR("invalid crtc index\n");
-   return -EINVAL;
-   }
-   disp_thread = >disp_thread[drm_enc->crtc->index];
+   disp_thread = >disp_thread;

/*
 * when idle_pc is not supported, process only KICKOFF, STOP and

MODESET

diff --git a/drivers/gpu/drm/msm/msm_drv.c

b/drivers/gpu/drm/msm/msm_drv.c

index 9c9f7ff..1f384b3 100644
--- a/drivers/gpu/drm/msm/msm_drv.c
+++ b/drivers/gpu/drm/msm/msm_drv.c
@@ -257,8 +257,7 @@ static int vblank_ctrl_queue_work(struct

msm_drm_private *priv,

list_add_tail(_ev->node, _ctrl->event_list);
spin_unlock_irqrestore(_ctrl->lock, flags);

-   kthread_queue_work(>disp_thread[crtc_id].worker,
-   _ctrl->work);
+   kthread_queue_work(>disp_thread.worker, _ctrl->work);

return 0;
 }
@@ -284,14 +283,12 @@ static int msm_drm_uninit(struct device *dev)
kfree(vbl_ev);
}

+   kthread_flush_worker(>disp_thread.worker);
+   kthread_stop(priv->disp_thread.thread);


I realize this is moving existing code, but is there a race here? You
can't have
work enqueued in between the flush and stop?
I looked further into this comment. Ideally, we call into msm_unbind 
only when
the device is released and we release the device only on the last close 
of

the drm device. So the userspace doesn't have any device handle to make
ioctl calls, which could queue jobs to this queue. Since we are making 
sure

to flush out the last job already on the queue, we can safely call the
kthread_stop here.

Thanks and Regards,
Jeykumar S.



You might also want to use kthread_destroy_worker to do this work (in a
follow-up patch including the event threads too).


+   priv->disp_thread.thread = NULL;
+
/* clean up display commit/event worker threads */


This comment needs updating now


for (i = 0; i < priv->num_crtcs; i++) {
-   if (priv->disp_thread[i].thread) {
-

kthread_flush_worker(>disp_thread[i].worker);

-   kthread_stop(priv->disp_thread[i].thread);
-   priv->disp_thread[i].thread = NULL;
-   }
-
if (priv->event_thread[i].thread) {


kthread_flush_worker(>event_thread[i].worker);

kthread_stop(priv->event_thread[i].thread);
@@ -537,6 +534,22 @@ static int msm_drm_init(struct device *dev, 
struct

drm_driver *drv)

ddev->mode_config.funcs = _config_funcs;
ddev->mode_config.helper_private = _config_helper_funcs;

+   /* initialize display thread */
+   kthread_init_worker(>disp_thread.worker);
+   priv->disp_thread.dev = ddev;
+   priv->disp_thread.thread = kthread_run(kthread_worker_fn,
+  >disp_thread.worker,
+  "disp_thread");
+   if (IS_ERR(priv->disp_thread.thread)) {
+   DRM_DEV_ERROR(dev, "failed to create crtc_commit

kthread\n");

+   priv->disp_thread.thread = NULL;
+   goto err_msm_uninit;
+   }
+
+   ret = sched_setscheduler(priv->disp_thread.thread, SCHED_FIFO,

);

+   if (ret)
+   pr_warn("display thread priority update failed: %d\n",

ret);

+
/**
 * this priority was found during empiric testing to have

appropriate

 * realtime scheduling to process display updates and interact

with
@@ -544,27 +557,6 @@ static int msm_drm_init(struct device *dev, 
struct

drm_driver *drv)

 */
param.sched_priority = 16;
for (i = 0; i < priv->num_crtcs; i++

Re: [Freedreno] [PATCH v2 3/3] drm/msm: dpu: Make legacy cursor updates asynchronous

2018-11-08 Thread Jeykumar Sankaran

On 2018-10-30 09:00, Sean Paul wrote:

From: Sean Paul 

This patch sprinkles a few async/legacy_cursor_update checks
through commit to ensure that cursor updates aren't blocked on vsync.
There are 2 main components to this, the first is that we don't want to
wait_for_commit_done in msm_atomic  before returning from 
atomic_complete.
The second is that in dpu we don't want to wait for frame_done events 
when

updating the cursor.

Changes in v2:
- None

Signed-off-by: Sean Paul 
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c| 44 +++--
 drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h|  3 +-
 drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 22 +++
 drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h |  6 ++-
 drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c |  5 ++-
 drivers/gpu/drm/msm/msm_atomic.c|  3 +-
 6 files changed, 49 insertions(+), 34 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
index ed84cf44a222..1e3e57817b72 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
@@ -702,7 +702,7 @@ static int _dpu_crtc_wait_for_frame_done(struct
drm_crtc *crtc)
return rc;
 }

-void dpu_crtc_commit_kickoff(struct drm_crtc *crtc)
+void dpu_crtc_commit_kickoff(struct drm_crtc *crtc, bool async)
 {
struct drm_encoder *encoder;
struct drm_device *dev = crtc->dev;
@@ -731,27 +731,30 @@ void dpu_crtc_commit_kickoff(struct drm_crtc 
*crtc)

 * Encoder will flush/start now, unless it has a tx
pending.
 * If so, it may delay and flush at an irq event (e.g.
ppdone)
 */
-   dpu_encoder_prepare_for_kickoff(encoder, );
+   dpu_encoder_prepare_for_kickoff(encoder, , async);
}

-   /* wait for frame_event_done completion */
-   DPU_ATRACE_BEGIN("wait_for_frame_done_event");
-   ret = _dpu_crtc_wait_for_frame_done(crtc);
-   DPU_ATRACE_END("wait_for_frame_done_event");
-   if (ret) {
-   DPU_ERROR("crtc%d wait for frame done
failed;frame_pending%d\n",
-   crtc->base.id,
-   atomic_read(_crtc->frame_pending));
-   goto end;
-   }

-   if (atomic_inc_return(_crtc->frame_pending) == 1) {
-   /* acquire bandwidth and other resources */
-   DPU_DEBUG("crtc%d first commit\n", crtc->base.id);
-   } else
-   DPU_DEBUG("crtc%d commit\n", crtc->base.id);
+   if (!async) {
+   /* wait for frame_event_done completion */
+   DPU_ATRACE_BEGIN("wait_for_frame_done_event");
+   ret = _dpu_crtc_wait_for_frame_done(crtc);
+   DPU_ATRACE_END("wait_for_frame_done_event");
+   if (ret) {
+   DPU_ERROR("crtc%d wait for frame done
failed;frame_pending%d\n",
+   crtc->base.id,
+
atomic_read(_crtc->frame_pending));
+   goto end;
+   }
+
+   if (atomic_inc_return(_crtc->frame_pending) == 1) {
+   /* acquire bandwidth and other resources */
+   DPU_DEBUG("crtc%d first commit\n", crtc->base.id);
+   } else
+   DPU_DEBUG("crtc%d commit\n", crtc->base.id);

-   dpu_crtc->play_count++;
+   dpu_crtc->play_count++;
+   }

dpu_vbif_clear_errors(dpu_kms);

@@ -759,11 +762,12 @@ void dpu_crtc_commit_kickoff(struct drm_crtc 
*crtc)

if (encoder->crtc != crtc)
continue;

-   dpu_encoder_kickoff(encoder);
+   dpu_encoder_kickoff(encoder, async);
}

 end:
-   reinit_completion(_crtc->frame_done_comp);
+   if (!async)
+   reinit_completion(_crtc->frame_done_comp);
DPU_ATRACE_END("crtc_commit");
 }

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h
b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h
index 4822602402f9..ec633ce3ee6c 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h
@@ -277,8 +277,9 @@ int dpu_crtc_vblank(struct drm_crtc *crtc, bool 
en);

 /**
  * dpu_crtc_commit_kickoff - trigger kickoff of the commit for this 
crtc

  * @crtc: Pointer to drm crtc object
+ * @async: true if the commit is asynchronous, false otherwise
  */
-void dpu_crtc_commit_kickoff(struct drm_crtc *crtc);
+void dpu_crtc_commit_kickoff(struct drm_crtc *crtc, bool async);

 /**
  * dpu_crtc_complete_commit - callback signalling completion of 
current

commit
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
index 82c55efb500f..a8ba10ceaacf 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
@@ -1375,7 +1375,8 @@ static void dpu_encoder_off_work(struct 
kthread_work

*work)
  * extra_flush_bits: 

Re: [Freedreno] [PATCH v2 1/3] drm/msm: dpu: Mask inactive pending flushes

2018-11-08 Thread Jeykumar Sankaran

On 2018-10-30 09:00, Sean Paul wrote:

From: Sean Paul 

This patch masks any pending flushes which have not been latched for a
commit. This will catch the case where an asynchronous update is
nullified by a disable in the same frame.

Changes in v2:
- Added to the set

Signed-off-by: Sean Paul 
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c | 7 +++
 1 file changed, 7 insertions(+)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c
b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c
index 8fa601a9abbf..d7a7fedc09f7 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c
@@ -28,6 +28,7 @@
 #define   CTL_TOP   0x014
 #define   CTL_FLUSH 0x018
 #define   CTL_START 0x01C
+#define   CTL_FLUSH_MASK0x090
 #define   CTL_PREPARE   0x0d0
 #define   CTL_SW_RESET  0x030
 #define   CTL_LAYER_EXTN_OFFSET 0x40
@@ -121,6 +122,12 @@ static inline void dpu_hw_ctl_trigger_flush(struct
dpu_hw_ctl *ctx)
 {
trace_dpu_hw_ctl_trigger_pending_flush(ctx->pending_flush_mask,
 dpu_hw_ctl_get_flush_register(ctx));
+
+   /*
+* Async updates could have changed CTL_FLUSH since it was last
latched.
+* Mask anything not involved in this latest commit.
+*/
+   DPU_REG_WRITE(>hw, CTL_FLUSH_MASK, ~ctx->pending_flush_mask);

Do we need this change for adding the current async cursor support?
We are not masking any bit by default. So there is no need for updating 
it here.


The usage of flush_mask is not completely explored yet. Maybe we can add
this register support when we revisit this async logic as we discussed.

Thanks and Regards,
Jeykumar S.

DPU_REG_WRITE(>hw, CTL_FLUSH, ctx->pending_flush_mask);
 }


--
Jeykumar S
___
Freedreno mailing list
Freedreno@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/freedreno


Re: [Freedreno] [PATCH v2 2/3] drm/msm: dpu: Only check flush register against pending flushes

2018-11-08 Thread Jeykumar Sankaran

On 2018-10-30 09:00, Sean Paul wrote:

From: Sean Paul 

There exists a case where a flush of a plane/dma may have been 
triggered
& started from an async commit. If that plane/dma is subsequently 
disabled

by the next commit, the flush register will continue to hold the flush
bit for the disabled plane. Since the bit remains active,
pending_kickoff_cnt will never decrement and we'll miss frame_done
events.

This patch limits the check of flush_register to include only those 
bits

which have been updated with the latest commit.

Changes in v2:
- None



Reviewed-by: Jeykumar Sankaran 


Signed-off-by: Sean Paul 
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c
b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c
index b3c68c4fcc8e..667f304c92ea 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c
@@ -331,7 +331,7 @@ static void dpu_encoder_phys_vid_vblank_irq(void 
*arg,

int irq_idx)
if (hw_ctl && hw_ctl->ops.get_flush_register)
flush_register = hw_ctl->ops.get_flush_register(hw_ctl);

-   if (flush_register == 0)
+   if (!(flush_register & hw_ctl->ops.get_pending_flush(hw_ctl)))
new_cnt =
atomic_add_unless(_enc->pending_kickoff_cnt,
-1, 0);
spin_unlock_irqrestore(phys_enc->enc_spinlock, lock_flags);


--
Jeykumar S
___
Freedreno mailing list
Freedreno@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/freedreno


[Freedreno] [PATCH v2 3/5] drm/msm/dpu: use system wq for idle power collapse

2018-11-06 Thread Jeykumar Sankaran
msm is using system wq for dispatching commit and vblank
events. Switch idle power collapse feature also to use
system wq to handle delayed work handlers so that
msm can get rid of redundant display threads.

changes in v2:
- patch introduced in v2

Signed-off-by: Jeykumar Sankaran 
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 26 +++---
 1 file changed, 7 insertions(+), 19 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
index 82c55ef..9b3d1f2 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
@@ -201,7 +201,7 @@ struct dpu_encoder_virt {
bool idle_pc_supported;
struct mutex rc_lock;
enum dpu_enc_rc_states rc_state;
-   struct kthread_delayed_work delayed_off_work;
+   struct delayed_work delayed_off_work;
struct kthread_work vsync_event_work;
struct msm_display_topology topology;
bool mode_set_complete;
@@ -740,7 +740,6 @@ static int dpu_encoder_resource_control(struct drm_encoder 
*drm_enc,
 {
struct dpu_encoder_virt *dpu_enc;
struct msm_drm_private *priv;
-   struct msm_drm_thread *disp_thread;
bool is_vid_mode = false;
 
if (!drm_enc || !drm_enc->dev || !drm_enc->dev->dev_private ||
@@ -753,12 +752,6 @@ static int dpu_encoder_resource_control(struct drm_encoder 
*drm_enc,
is_vid_mode = dpu_enc->disp_info.capabilities &
MSM_DISPLAY_CAP_VID_MODE;
 
-   if (drm_enc->crtc->index >= ARRAY_SIZE(priv->disp_thread)) {
-   DPU_ERROR("invalid crtc index\n");
-   return -EINVAL;
-   }
-   disp_thread = >disp_thread[drm_enc->crtc->index];
-
/*
 * when idle_pc is not supported, process only KICKOFF, STOP and MODESET
 * events and return early for other events (ie wb display).
@@ -775,8 +768,7 @@ static int dpu_encoder_resource_control(struct drm_encoder 
*drm_enc,
switch (sw_event) {
case DPU_ENC_RC_EVENT_KICKOFF:
/* cancel delayed off work, if any */
-   if (kthread_cancel_delayed_work_sync(
-   _enc->delayed_off_work))
+   if (cancel_delayed_work_sync(_enc->delayed_off_work))
DPU_DEBUG_ENC(dpu_enc, "sw_event:%d, work cancelled\n",
sw_event);
 
@@ -835,10 +827,8 @@ static int dpu_encoder_resource_control(struct drm_encoder 
*drm_enc,
return 0;
}
 
-   kthread_queue_delayed_work(
-   _thread->worker,
-   _enc->delayed_off_work,
-   msecs_to_jiffies(dpu_enc->idle_timeout));
+   schedule_delayed_work(_enc->delayed_off_work,
+ msecs_to_jiffies(dpu_enc->idle_timeout));
 
trace_dpu_enc_rc(DRMID(drm_enc), sw_event,
 dpu_enc->idle_pc_supported, dpu_enc->rc_state,
@@ -847,8 +837,7 @@ static int dpu_encoder_resource_control(struct drm_encoder 
*drm_enc,
 
case DPU_ENC_RC_EVENT_PRE_STOP:
/* cancel delayed off work, if any */
-   if (kthread_cancel_delayed_work_sync(
-   _enc->delayed_off_work))
+   if (cancel_delayed_work_sync(_enc->delayed_off_work))
DPU_DEBUG_ENC(dpu_enc, "sw_event:%d, work cancelled\n",
sw_event);
 
@@ -1351,7 +1340,7 @@ static void dpu_encoder_frame_done_callback(
}
 }
 
-static void dpu_encoder_off_work(struct kthread_work *work)
+static void dpu_encoder_off_work(struct work_struct *work)
 {
struct dpu_encoder_virt *dpu_enc = container_of(work,
struct dpu_encoder_virt, delayed_off_work.work);
@@ -2191,8 +2180,7 @@ int dpu_encoder_setup(struct drm_device *dev, struct 
drm_encoder *enc,
 
 
mutex_init(_enc->rc_lock);
-   kthread_init_delayed_work(_enc->delayed_off_work,
-   dpu_encoder_off_work);
+   INIT_DELAYED_WORK(_enc->delayed_off_work, dpu_encoder_off_work);
dpu_enc->idle_timeout = IDLE_TIMEOUT;
 
kthread_init_work(_enc->vsync_event_work,
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project

___
Freedreno mailing list
Freedreno@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/freedreno


[Freedreno] [PATCH v2 4/5] drm/msm: clean up display thread

2018-11-06 Thread Jeykumar Sankaran
Since there are no clients using these threads,
cleaning it up.

changes in v2:
- switch all the dependent clients to use system wq
  before removing the disp_threads (Sean Paul)

Signed-off-by: Jeykumar Sankaran 
---
 drivers/gpu/drm/msm/msm_drv.c | 35 +--
 drivers/gpu/drm/msm/msm_drv.h |  1 -
 2 files changed, 1 insertion(+), 35 deletions(-)

diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c
index 7d3ca99..6d6c73b 100644
--- a/drivers/gpu/drm/msm/msm_drv.c
+++ b/drivers/gpu/drm/msm/msm_drv.c
@@ -298,13 +298,8 @@ static int msm_drm_uninit(struct device *dev)
kfree(vbl_ev);
}
 
-   /* clean up display commit/event worker threads */
+   /* clean up event worker threads */
for (i = 0; i < priv->num_crtcs; i++) {
-   if (priv->disp_thread[i].thread) {
-   kthread_destroy_worker(>disp_thread[i].worker);
-   priv->disp_thread[i].thread = NULL;
-   }
-
if (priv->event_thread[i].thread) {
kthread_destroy_worker(>event_thread[i].worker);
priv->event_thread[i].thread = NULL;
@@ -541,27 +536,6 @@ static int msm_drm_init(struct device *dev, struct 
drm_driver *drv)
 */
param.sched_priority = 16;
for (i = 0; i < priv->num_crtcs; i++) {
-
-   /* initialize display thread */
-   priv->disp_thread[i].crtc_id = priv->crtcs[i]->base.id;
-   kthread_init_worker(>disp_thread[i].worker);
-   priv->disp_thread[i].dev = ddev;
-   priv->disp_thread[i].thread =
-   kthread_run(kthread_worker_fn,
-   >disp_thread[i].worker,
-   "crtc_commit:%d", priv->disp_thread[i].crtc_id);
-   if (IS_ERR(priv->disp_thread[i].thread)) {
-   DRM_DEV_ERROR(dev, "failed to create crtc_commit 
kthread\n");
-   priv->disp_thread[i].thread = NULL;
-   goto err_msm_uninit;
-   }
-
-   ret = sched_setscheduler(priv->disp_thread[i].thread,
-SCHED_FIFO, );
-   if (ret)
-   dev_warn(dev, "disp_thread set priority failed: %d\n",
-ret);
-
/* initialize event thread */
priv->event_thread[i].crtc_id = priv->crtcs[i]->base.id;
kthread_init_worker(>event_thread[i].worker);
@@ -576,13 +550,6 @@ static int msm_drm_init(struct device *dev, struct 
drm_driver *drv)
goto err_msm_uninit;
}
 
-   /**
-* event thread should also run at same priority as disp_thread
-* because it is handling frame_done events. A lower priority
-* event thread and higher priority disp_thread can causes
-* frame_pending counters beyond 2. This can lead to commit
-* failure at crtc commit level.
-*/
ret = sched_setscheduler(priv->event_thread[i].thread,
 SCHED_FIFO, );
if (ret)
diff --git a/drivers/gpu/drm/msm/msm_drv.h b/drivers/gpu/drm/msm/msm_drv.h
index 126345c4..05d33a7 100644
--- a/drivers/gpu/drm/msm/msm_drv.h
+++ b/drivers/gpu/drm/msm/msm_drv.h
@@ -197,7 +197,6 @@ struct msm_drm_private {
unsigned int num_crtcs;
struct drm_crtc *crtcs[MAX_CRTCS];
 
-   struct msm_drm_thread disp_thread[MAX_CRTCS];
struct msm_drm_thread event_thread[MAX_CRTCS];
 
unsigned int num_encoders;
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project

___
Freedreno mailing list
Freedreno@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/freedreno


[Freedreno] [PATCH v2 1/5] drm/msm: destroy msm threads after config cleanup

2018-11-06 Thread Jeykumar Sankaran
To avoid any possible work queues to msm threads, clean up
the threads after the CRTC objects are released in
config cleanup.

changes in v2:
- fix race condition before kthread flush and stop (Sean Paul)
- use kthread_destroy_worker for cleaning up kthread (Sean Paul)

Signed-off-by: Jeykumar Sankaran 
---
 drivers/gpu/drm/msm/msm_drv.c | 36 +---
 1 file changed, 17 insertions(+), 19 deletions(-)

diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c
index 9c9f7ff..e913059 100644
--- a/drivers/gpu/drm/msm/msm_drv.c
+++ b/drivers/gpu/drm/msm/msm_drv.c
@@ -278,6 +278,21 @@ static int msm_drm_uninit(struct device *dev)
 * work before drm_irq_uninstall() to avoid work re-enabling an
 * irq after uninstall has disabled it.
 */
+   msm_gem_shrinker_cleanup(ddev);
+
+   drm_kms_helper_poll_fini(ddev);
+
+   drm_dev_unregister(ddev);
+
+   msm_perf_debugfs_cleanup(priv);
+   msm_rd_debugfs_cleanup(priv);
+
+#ifdef CONFIG_DRM_FBDEV_EMULATION
+   if (fbdev && priv->fbdev)
+   msm_fbdev_free(ddev);
+#endif
+   drm_mode_config_cleanup(ddev);
+
kthread_flush_work(_ctrl->work);
list_for_each_entry_safe(vbl_ev, tmp, _ctrl->event_list, node) {
list_del(_ev->node);
@@ -287,33 +302,16 @@ static int msm_drm_uninit(struct device *dev)
/* clean up display commit/event worker threads */
for (i = 0; i < priv->num_crtcs; i++) {
if (priv->disp_thread[i].thread) {
-   kthread_flush_worker(>disp_thread[i].worker);
-   kthread_stop(priv->disp_thread[i].thread);
+   kthread_destroy_worker(>disp_thread[i].worker);
priv->disp_thread[i].thread = NULL;
}
 
if (priv->event_thread[i].thread) {
-   kthread_flush_worker(>event_thread[i].worker);
-   kthread_stop(priv->event_thread[i].thread);
+   kthread_destroy_worker(>event_thread[i].worker);
priv->event_thread[i].thread = NULL;
}
}
 
-   msm_gem_shrinker_cleanup(ddev);
-
-   drm_kms_helper_poll_fini(ddev);
-
-   drm_dev_unregister(ddev);
-
-   msm_perf_debugfs_cleanup(priv);
-   msm_rd_debugfs_cleanup(priv);
-
-#ifdef CONFIG_DRM_FBDEV_EMULATION
-   if (fbdev && priv->fbdev)
-   msm_fbdev_free(ddev);
-#endif
-   drm_mode_config_cleanup(ddev);
-
pm_runtime_get_sync(dev);
drm_irq_uninstall(ddev);
pm_runtime_put_sync(dev);
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project

___
Freedreno mailing list
Freedreno@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/freedreno


[Freedreno] [PATCH v2 2/5] drm/msm/dpu: use system wq for vblank events

2018-11-06 Thread Jeykumar Sankaran
DPU was using one thread per display to dispatch async commits and
vblank requests. Since clean up already happened in msm to use the
common thread for all the display commits, display threads are only
used to cater vblank requests. Since a single thread is sufficient
to do the job without any performance hits, use system workqueue
to queue requests. A separate patch is submitted later in this
series to remove the display threads altogether.

changes in v2:
- switch to system wq before removing disp threads (Sean Paul)

Signed-off-by: Jeykumar Sankaran 
---
 drivers/gpu/drm/msm/msm_drv.c | 9 -
 drivers/gpu/drm/msm/msm_drv.h | 2 +-
 2 files changed, 5 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c
index e913059..7d3ca99 100644
--- a/drivers/gpu/drm/msm/msm_drv.c
+++ b/drivers/gpu/drm/msm/msm_drv.c
@@ -209,7 +209,7 @@ struct vblank_event {
bool enable;
 };
 
-static void vblank_ctrl_worker(struct kthread_work *work)
+static void vblank_ctrl_worker(struct work_struct *work)
 {
struct msm_vblank_ctrl *vbl_ctrl = container_of(work,
struct msm_vblank_ctrl, work);
@@ -257,8 +257,7 @@ static int vblank_ctrl_queue_work(struct msm_drm_private 
*priv,
list_add_tail(_ev->node, _ctrl->event_list);
spin_unlock_irqrestore(_ctrl->lock, flags);
 
-   kthread_queue_work(>disp_thread[crtc_id].worker,
-   _ctrl->work);
+   schedule_work(_ctrl->work);
 
return 0;
 }
@@ -293,7 +292,7 @@ static int msm_drm_uninit(struct device *dev)
 #endif
drm_mode_config_cleanup(ddev);
 
-   kthread_flush_work(_ctrl->work);
+   flush_work(_ctrl->work);
list_for_each_entry_safe(vbl_ev, tmp, _ctrl->event_list, node) {
list_del(_ev->node);
kfree(vbl_ev);
@@ -476,7 +475,7 @@ static int msm_drm_init(struct device *dev, struct 
drm_driver *drv)
 
INIT_LIST_HEAD(>inactive_list);
INIT_LIST_HEAD(>vblank_ctrl.event_list);
-   kthread_init_work(>vblank_ctrl.work, vblank_ctrl_worker);
+   INIT_WORK(>vblank_ctrl.work, vblank_ctrl_worker);
spin_lock_init(>vblank_ctrl.lock);
 
drm_mode_config_init(ddev);
diff --git a/drivers/gpu/drm/msm/msm_drv.h b/drivers/gpu/drm/msm/msm_drv.h
index 9d11f32..126345c4 100644
--- a/drivers/gpu/drm/msm/msm_drv.h
+++ b/drivers/gpu/drm/msm/msm_drv.h
@@ -78,7 +78,7 @@ enum msm_mdp_plane_property {
 };
 
 struct msm_vblank_ctrl {
-   struct kthread_work work;
+   struct work_struct work;
struct list_head event_list;
spinlock_t lock;
 };
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project

___
Freedreno mailing list
Freedreno@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/freedreno


[Freedreno] [PATCH v2 5/5] drm/msm: subclass work object for vblank events

2018-11-06 Thread Jeykumar Sankaran
msm maintains a separate structure to define vblank
work definitions and a list to track events submitted
to the workqueue. We can avoid this redundant list
and its protection mechanism, if we subclass the
work object to encapsulate vblank event parameters.

changes in v2:
- subclass optimization on system wq (Sean Paul)

Signed-off-by: Jeykumar Sankaran 
---
 drivers/gpu/drm/msm/msm_drv.c | 67 +--
 drivers/gpu/drm/msm/msm_drv.h |  7 -
 2 files changed, 20 insertions(+), 54 deletions(-)

diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c
index 6d6c73b..8da5be2 100644
--- a/drivers/gpu/drm/msm/msm_drv.c
+++ b/drivers/gpu/drm/msm/msm_drv.c
@@ -203,61 +203,44 @@ u32 msm_readl(const void __iomem *addr)
return val;
 }
 
-struct vblank_event {
-   struct list_head node;
+struct msm_vblank_work {
+   struct work_struct work;
int crtc_id;
bool enable;
+   struct msm_drm_private *priv;
 };
 
 static void vblank_ctrl_worker(struct work_struct *work)
 {
-   struct msm_vblank_ctrl *vbl_ctrl = container_of(work,
-   struct msm_vblank_ctrl, work);
-   struct msm_drm_private *priv = container_of(vbl_ctrl,
-   struct msm_drm_private, vblank_ctrl);
+   struct msm_vblank_work *vbl_work = container_of(work,
+   struct msm_vblank_work, work);
+   struct msm_drm_private *priv = vbl_work->priv;
struct msm_kms *kms = priv->kms;
-   struct vblank_event *vbl_ev, *tmp;
-   unsigned long flags;
-
-   spin_lock_irqsave(_ctrl->lock, flags);
-   list_for_each_entry_safe(vbl_ev, tmp, _ctrl->event_list, node) {
-   list_del(_ev->node);
-   spin_unlock_irqrestore(_ctrl->lock, flags);
-
-   if (vbl_ev->enable)
-   kms->funcs->enable_vblank(kms,
-   priv->crtcs[vbl_ev->crtc_id]);
-   else
-   kms->funcs->disable_vblank(kms,
-   priv->crtcs[vbl_ev->crtc_id]);
 
-   kfree(vbl_ev);
-
-   spin_lock_irqsave(_ctrl->lock, flags);
-   }
+   if (vbl_work->enable)
+   kms->funcs->enable_vblank(kms, priv->crtcs[vbl_work->crtc_id]);
+   else
+   kms->funcs->disable_vblank(kms, priv->crtcs[vbl_work->crtc_id]);
 
-   spin_unlock_irqrestore(_ctrl->lock, flags);
+   kfree(vbl_work);
 }
 
 static int vblank_ctrl_queue_work(struct msm_drm_private *priv,
int crtc_id, bool enable)
 {
-   struct msm_vblank_ctrl *vbl_ctrl = >vblank_ctrl;
-   struct vblank_event *vbl_ev;
-   unsigned long flags;
+   struct msm_vblank_work *vbl_work;
 
-   vbl_ev = kzalloc(sizeof(*vbl_ev), GFP_ATOMIC);
-   if (!vbl_ev)
+   vbl_work = kzalloc(sizeof(*vbl_work), GFP_ATOMIC);
+   if (!vbl_work)
return -ENOMEM;
 
-   vbl_ev->crtc_id = crtc_id;
-   vbl_ev->enable = enable;
+   INIT_WORK(_work->work, vblank_ctrl_worker);
 
-   spin_lock_irqsave(_ctrl->lock, flags);
-   list_add_tail(_ev->node, _ctrl->event_list);
-   spin_unlock_irqrestore(_ctrl->lock, flags);
+   vbl_work->crtc_id = crtc_id;
+   vbl_work->enable = enable;
+   vbl_work->priv = priv;
 
-   schedule_work(_ctrl->work);
+   schedule_work(_work->work);
 
return 0;
 }
@@ -269,14 +252,13 @@ static int msm_drm_uninit(struct device *dev)
struct msm_drm_private *priv = ddev->dev_private;
struct msm_kms *kms = priv->kms;
struct msm_mdss *mdss = priv->mdss;
-   struct msm_vblank_ctrl *vbl_ctrl = >vblank_ctrl;
-   struct vblank_event *vbl_ev, *tmp;
int i;
 
/* We must cancel and cleanup any pending vblank enable/disable
 * work before drm_irq_uninstall() to avoid work re-enabling an
 * irq after uninstall has disabled it.
 */
+
msm_gem_shrinker_cleanup(ddev);
 
drm_kms_helper_poll_fini(ddev);
@@ -292,12 +274,6 @@ static int msm_drm_uninit(struct device *dev)
 #endif
drm_mode_config_cleanup(ddev);
 
-   flush_work(_ctrl->work);
-   list_for_each_entry_safe(vbl_ev, tmp, _ctrl->event_list, node) {
-   list_del(_ev->node);
-   kfree(vbl_ev);
-   }
-
/* clean up event worker threads */
for (i = 0; i < priv->num_crtcs; i++) {
if (priv->event_thread[i].thread) {
@@ -469,9 +445,6 @@ static int msm_drm_init(struct device *dev, struct 
drm_driver *drv)
priv->wq = alloc_ordered_workqueue("msm", 0);
 
INIT_LIST_HEAD(>inactive_list);
-   INIT_LIST_HEAD

Re: [Freedreno] [PATCH 2/2] drm/msm: subclass work object for vblank events

2018-11-05 Thread Jeykumar Sankaran

On 2018-11-05 09:24, Sean Paul wrote:

On Fri, Nov 02, 2018 at 04:38:48PM -0700, Jeykumar Sankaran wrote:

On 2018-11-01 12:18, Sean Paul wrote:
> On Wed, Oct 31, 2018 at 05:19:05PM -0700, Jeykumar Sankaran wrote:
> > msm maintains a separate structure to define vblank
> > work definitions and a list to track events submitted
> > to the display worker thread. We can avoid these
> > redundant list and its protection mechanism, if we
> > subclass the work object to encapsulate vblank
> > event parameters.
> >
> > Signed-off-by: Jeykumar Sankaran 
> > ---
> >  drivers/gpu/drm/msm/msm_drv.c | 70
> ---
> >  drivers/gpu/drm/msm/msm_drv.h |  7 -
> >  2 files changed, 19 insertions(+), 58 deletions(-)
> >
> > diff --git a/drivers/gpu/drm/msm/msm_drv.c
> b/drivers/gpu/drm/msm/msm_drv.c
> > index 1f384b3..67a96ee 100644
> > --- a/drivers/gpu/drm/msm/msm_drv.c
> > +++ b/drivers/gpu/drm/msm/msm_drv.c


/snip


> >  static int vblank_ctrl_queue_work(struct msm_drm_private *priv,
> >   int crtc_id, bool enable)
> >  {
> > - struct msm_vblank_ctrl *vbl_ctrl = >vblank_ctrl;
> > - struct vblank_event *vbl_ev;
> > - unsigned long flags;
> > + struct msm_vblank_work *vbl_work;
> >
> > - vbl_ev = kzalloc(sizeof(*vbl_ev), GFP_ATOMIC);
> > - if (!vbl_ev)
> > + vbl_work = kzalloc(sizeof(*vbl_work), GFP_ATOMIC);
> > + if (!vbl_work)
> >   return -ENOMEM;
> >
> > - vbl_ev->crtc_id = crtc_id;
> > - vbl_ev->enable = enable;
> > + kthread_init_work(_work->work, vblank_ctrl_worker);
> >
> > - spin_lock_irqsave(_ctrl->lock, flags);
> > - list_add_tail(_ev->node, _ctrl->event_list);
> > - spin_unlock_irqrestore(_ctrl->lock, flags);
> > + vbl_work->crtc_id = crtc_id;
> > + vbl_work->enable = enable;
> > + vbl_work->priv = priv;
> >
> > - kthread_queue_work(>disp_thread.worker, _ctrl->work);
> > + kthread_queue_work(>disp_thread.worker, _work->work);
>
> So I think this can get even more simplified. In the short term, you

can

> just
> use the systemwq to do the enable and disable.

you mean priv->wq?



I meant the system workqueue, we probably don't need our own for this.



>
> In the long term, the enable_vblank/disable_vblank functions should be
> optimized so they don't sleep. I took a quick look at them perhaps

this

> is
> all because of the crtc_lock mutex? That lock seems a bit suspicious

to

> me,
> especially being dropped around the pm_runtime calls in
> _dpu_crtc_vblank_enable_no_lock(). I think we could probably rely on

the

> modeset
> locks for some of these functions, and perhaps convert it to a

spinlock

> if
> we
> can't get rid of it entirely.

crtc_lock has a history of usage in the downstream driver. It was

introduced

to protect
vblank variables when vblank requests were handled in the user thread
(not the display thread). When event threads were introduced to 
receive
encoder events, the lock was further expanded to protect few more 
vars.

It

was
also needed to synchronize CRTC accesses between debugfs dump calls
and display thread.


The debugfs case can be solved pretty easily by using the modeset 
locks. I
haven't looked closely at the event threads, could we convert crtc_lock 
to

a
spinlock and then make vblank enable/disable synchronous?
Did a little digging into the reason why vblank enable/disable was made 
asynchronous
in the first place. Looks like Rob was also using priv->wq to queue 
vblank requests

before display threads were introduced by the DPU driver.

The only reason I can think of was to support smart panels, where we 
wait for

CTL_START interrupt instead of PING_PONG_DONE which is needed for fence
releases. Need to confirm with Rob for MDP5 behaviour before switcing to 
sync.


For now, I submit a patch to use system wq.


Sean



Would like to deal with this cleanup bit later once we lose these 
extra

threads.

Thanks and Regards,
Jeykumar S.

>
> Sean
>
> >
> >   return 0;
> >  }
> > @@ -269,20 +252,8 @@ static int msm_drm_uninit(struct device *dev)
> >   struct msm_drm_private *priv = ddev->dev_private;
> >   struct msm_kms *kms = priv->kms;
> >   struct msm_mdss *mdss = priv->mdss;
> > - struct msm_vblank_ctrl *vbl_ctrl = >vblank_ctrl;
> > - struct vblank_event *vbl_ev, *tmp;
> >   int i;
> >
> > - /* We must cancel and cleanup any pending vblank enable/disable
> > -  * work before drm_irq_uninstall() to avoid 

Re: [Freedreno] [PATCH 2/2] drm/msm: subclass work object for vblank events

2018-11-02 Thread Jeykumar Sankaran

On 2018-11-01 12:18, Sean Paul wrote:

On Wed, Oct 31, 2018 at 05:19:05PM -0700, Jeykumar Sankaran wrote:

msm maintains a separate structure to define vblank
work definitions and a list to track events submitted
to the display worker thread. We can avoid these
redundant list and its protection mechanism, if we
subclass the work object to encapsulate vblank
event parameters.

Signed-off-by: Jeykumar Sankaran 
---
 drivers/gpu/drm/msm/msm_drv.c | 70

---

 drivers/gpu/drm/msm/msm_drv.h |  7 -
 2 files changed, 19 insertions(+), 58 deletions(-)

diff --git a/drivers/gpu/drm/msm/msm_drv.c

b/drivers/gpu/drm/msm/msm_drv.c

index 1f384b3..67a96ee 100644
--- a/drivers/gpu/drm/msm/msm_drv.c
+++ b/drivers/gpu/drm/msm/msm_drv.c
@@ -203,61 +203,44 @@ u32 msm_readl(const void __iomem *addr)
return val;
 }

-struct vblank_event {
-   struct list_head node;
+struct msm_vblank_work {
+   struct kthread_work work;
int crtc_id;
bool enable;
+   struct msm_drm_private *priv;
 };

 static void vblank_ctrl_worker(struct kthread_work *work)
 {
-   struct msm_vblank_ctrl *vbl_ctrl = container_of(work,
-   struct msm_vblank_ctrl,

work);

-   struct msm_drm_private *priv = container_of(vbl_ctrl,
-   struct msm_drm_private,

vblank_ctrl);

+   struct msm_vblank_work *vbl_work = container_of(work,
+   struct msm_vblank_work,

work);

+   struct msm_drm_private *priv = vbl_work->priv;
struct msm_kms *kms = priv->kms;
-   struct vblank_event *vbl_ev, *tmp;
-   unsigned long flags;
-
-   spin_lock_irqsave(_ctrl->lock, flags);
-   list_for_each_entry_safe(vbl_ev, tmp, _ctrl->event_list, node)

{

-   list_del(_ev->node);
-   spin_unlock_irqrestore(_ctrl->lock, flags);
-
-   if (vbl_ev->enable)
-   kms->funcs->enable_vblank(kms,
-

priv->crtcs[vbl_ev->crtc_id]);

-   else
-   kms->funcs->disable_vblank(kms,
-

priv->crtcs[vbl_ev->crtc_id]);


-   kfree(vbl_ev);
-
-   spin_lock_irqsave(_ctrl->lock, flags);
-   }
+   if (vbl_work->enable)
+   kms->funcs->enable_vblank(kms,

priv->crtcs[vbl_work->crtc_id]);

+   else
+   kms->funcs->disable_vblank(kms,

priv->crtcs[vbl_work->crtc_id]);


-   spin_unlock_irqrestore(_ctrl->lock, flags);
+   kfree(vbl_work);
 }

 static int vblank_ctrl_queue_work(struct msm_drm_private *priv,
int crtc_id, bool enable)
 {
-   struct msm_vblank_ctrl *vbl_ctrl = >vblank_ctrl;
-   struct vblank_event *vbl_ev;
-   unsigned long flags;
+   struct msm_vblank_work *vbl_work;

-   vbl_ev = kzalloc(sizeof(*vbl_ev), GFP_ATOMIC);
-   if (!vbl_ev)
+   vbl_work = kzalloc(sizeof(*vbl_work), GFP_ATOMIC);
+   if (!vbl_work)
return -ENOMEM;

-   vbl_ev->crtc_id = crtc_id;
-   vbl_ev->enable = enable;
+   kthread_init_work(_work->work, vblank_ctrl_worker);

-   spin_lock_irqsave(_ctrl->lock, flags);
-   list_add_tail(_ev->node, _ctrl->event_list);
-   spin_unlock_irqrestore(_ctrl->lock, flags);
+   vbl_work->crtc_id = crtc_id;
+   vbl_work->enable = enable;
+   vbl_work->priv = priv;

-   kthread_queue_work(>disp_thread.worker, _ctrl->work);
+   kthread_queue_work(>disp_thread.worker, _work->work);


So I think this can get even more simplified. In the short term, you 
can

just
use the systemwq to do the enable and disable.


you mean priv->wq?



In the long term, the enable_vblank/disable_vblank functions should be
optimized so they don't sleep. I took a quick look at them perhaps this 
is

all because of the crtc_lock mutex? That lock seems a bit suspicious to
me,
especially being dropped around the pm_runtime calls in
_dpu_crtc_vblank_enable_no_lock(). I think we could probably rely on 
the

modeset
locks for some of these functions, and perhaps convert it to a spinlock 
if

we
can't get rid of it entirely.


crtc_lock has a history of usage in the downstream driver. It was 
introduced to protect

vblank variables when vblank requests were handled in the user thread
(not the display thread). When event threads were introduced to receive
encoder events, the lock was further expanded to protect few more vars. 
It was

also needed to synchronize CRTC accesses between debugfs dump calls
and display thread.

Would like to deal with this cleanup bit later once we lose these extra 
threads.


Thanks and Regards,
Jeykumar S.



Sean



return 0;
 }
@@ -269,20 +252,8 @@ static int msm_drm_uninit(struct device *dev)
struct msm_drm_private *priv = ddev->dev_priva

Re: [Freedreno] [PATCH 1/2] drm/msm: use common display thread for dispatching vblank events

2018-11-02 Thread Jeykumar Sankaran

On 2018-11-01 12:09, Sean Paul wrote:

On Wed, Oct 31, 2018 at 05:19:04PM -0700, Jeykumar Sankaran wrote:

DPU was using one thread per display to dispatch async
commits and vblank requests. Since clean up already happened
in msm to use the common thread for all the display commits,
display threads are only used to cater vblank requests. Single
thread is sufficient to do the job without any performance hits.

Signed-off-by: Jeykumar Sankaran 
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c |  6 +---
 drivers/gpu/drm/msm/msm_drv.c   | 50

-

 drivers/gpu/drm/msm/msm_drv.h   |  2 +-
 3 files changed, 23 insertions(+), 35 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c

b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c

index 82c55ef..aff20f5 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
@@ -753,11 +753,7 @@ static int dpu_encoder_resource_control(struct

drm_encoder *drm_enc,

is_vid_mode = dpu_enc->disp_info.capabilities &
MSM_DISPLAY_CAP_VID_MODE;

-   if (drm_enc->crtc->index >= ARRAY_SIZE(priv->disp_thread)) {
-   DPU_ERROR("invalid crtc index\n");
-   return -EINVAL;
-   }
-   disp_thread = >disp_thread[drm_enc->crtc->index];
+   disp_thread = >disp_thread;

/*
 * when idle_pc is not supported, process only KICKOFF, STOP and

MODESET

diff --git a/drivers/gpu/drm/msm/msm_drv.c

b/drivers/gpu/drm/msm/msm_drv.c

index 9c9f7ff..1f384b3 100644
--- a/drivers/gpu/drm/msm/msm_drv.c
+++ b/drivers/gpu/drm/msm/msm_drv.c
@@ -257,8 +257,7 @@ static int vblank_ctrl_queue_work(struct

msm_drm_private *priv,

list_add_tail(_ev->node, _ctrl->event_list);
spin_unlock_irqrestore(_ctrl->lock, flags);

-   kthread_queue_work(>disp_thread[crtc_id].worker,
-   _ctrl->work);
+   kthread_queue_work(>disp_thread.worker, _ctrl->work);

return 0;
 }
@@ -284,14 +283,12 @@ static int msm_drm_uninit(struct device *dev)
kfree(vbl_ev);
}

+   kthread_flush_worker(>disp_thread.worker);
+   kthread_stop(priv->disp_thread.thread);


I realize this is moving existing code, but is there a race here? You
can't have
work enqueued in between the flush and stop?

Yes. I see only priv->kms is checked before queuing the work.

I can move the thread cleanup after the drm_mode_config_cleanup which
releases the CRTC objects. This way no one can make any further vblank 
requests.


Thanks and Regards,
Jeykumar S.


You might also want to use kthread_destroy_worker to do this work (in a
follow-up patch including the event threads too).


+   priv->disp_thread.thread = NULL;
+
/* clean up display commit/event worker threads */


This comment needs updating now


for (i = 0; i < priv->num_crtcs; i++) {
-   if (priv->disp_thread[i].thread) {
-

kthread_flush_worker(>disp_thread[i].worker);

-   kthread_stop(priv->disp_thread[i].thread);
-   priv->disp_thread[i].thread = NULL;
-   }
-
if (priv->event_thread[i].thread) {


kthread_flush_worker(>event_thread[i].worker);

kthread_stop(priv->event_thread[i].thread);
@@ -537,6 +534,22 @@ static int msm_drm_init(struct device *dev, 
struct

drm_driver *drv)

ddev->mode_config.funcs = _config_funcs;
ddev->mode_config.helper_private = _config_helper_funcs;

+   /* initialize display thread */
+   kthread_init_worker(>disp_thread.worker);
+   priv->disp_thread.dev = ddev;
+   priv->disp_thread.thread = kthread_run(kthread_worker_fn,
+  >disp_thread.worker,
+  "disp_thread");
+   if (IS_ERR(priv->disp_thread.thread)) {
+   DRM_DEV_ERROR(dev, "failed to create crtc_commit

kthread\n");

+   priv->disp_thread.thread = NULL;
+   goto err_msm_uninit;
+   }
+
+   ret = sched_setscheduler(priv->disp_thread.thread, SCHED_FIFO,

);

+   if (ret)
+   pr_warn("display thread priority update failed: %d\n",

ret);

+
/**
 * this priority was found during empiric testing to have

appropriate

 * realtime scheduling to process display updates and interact

with
@@ -544,27 +557,6 @@ static int msm_drm_init(struct device *dev, 
struct

drm_driver *drv)

 */
param.sched_priority = 16;
for (i = 0; i < priv->num_crtcs; i++) {
-
-   /* initialize display thread */
-   priv->disp_thread[i].crtc_id = priv->crtcs[i]->base.id;
-   kthread_init_worker(

[Freedreno] [PATCH v4 3/3] arm64: dts: sdm845: Add display nodes to MTP dts

2018-11-02 Thread Jeykumar Sankaran
Add mdss, dsi, dsi_phy, dsi pinctrl  and truly nt35597 panel nodes to
sdm845 MTP board dtsi.

Changes in v4:
- patch introduced in the series
- move around added nodes to preserve alphabetical order (Doug Anderson)

Signed-off-by: Jeykumar Sankaran 
---
 arch/arm64/boot/dts/qcom/sdm845-mtp.dts | 124 
 1 file changed, 124 insertions(+)

diff --git a/arch/arm64/boot/dts/qcom/sdm845-mtp.dts 
b/arch/arm64/boot/dts/qcom/sdm845-mtp.dts
index eedfaf8..eb2a05b 100644
--- a/arch/arm64/boot/dts/qcom/sdm845-mtp.dts
+++ b/arch/arm64/boot/dts/qcom/sdm845-mtp.dts
@@ -7,6 +7,7 @@
 
 /dts-v1/;
 
+#include 
 #include 
 #include "sdm845.dtsi"
 
@@ -343,11 +344,118 @@
};
 };
 
+ {
+   status = "okay";
+   qcom,dual-dsi-mode;
+   qcom,master-dsi;
+   qcom,sync-dual-dsi;
+
+   vdda-supply = <_mipi_dsi0_1p2>;
+
+   panel@0 {
+   compatible = "truly,nt35597-2K-display";
+   reg = <0>;
+
+   vdda-supply = <_l14a_1p88>;
+   vdispp-supply = <_regulator>;
+   vdispn-supply = <_regulator>;
+
+   pinctrl-names = "default", "suspend";
+   pinctrl-0 = <_dsi_active>;
+   pinctrl-1 = <_dsi_suspend>;
+
+   reset-gpios = < 6 GPIO_ACTIVE_HIGH>;
+   mode-gpios = < 52 GPIO_ACTIVE_HIGH>;
+
+   display-timings {
+   timing0: timing-0 {
+   /* originally
+* 268316160 Mhz,
+* but value below fits
+* better w/ downstream
+*/
+   clock-frequency = <268316138>;
+   hactive = <1440>;
+   vactive = <2560>;
+   hfront-porch = <200>;
+   hback-porch = <64>;
+   hsync-len = <32>;
+   vfront-porch = <8>;
+   vback-porch = <7>;
+   vsync-len = <1>;
+   };
+   };
+
+   ports {
+   #address-cells = <1>;
+   #size-cells = <0>;
+   port@0 {
+   reg = <0>;
+   panel0_in: endpoint {
+   remote-endpoint = <_out>;
+   };
+   };
+
+   port@1 {
+   reg = <1>;
+   panel1_in: endpoint {
+   remote-endpoint = <_out>;
+   };
+   };
+   };
+   };
+
+   ports {
+   port@1 {
+   endpoint {
+   remote-endpoint = <_in>;
+   data-lanes = <0 1 2 3>;
+   };
+   };
+   };
+};
+
+_phy {
+   status = "okay";
+   vdds-supply = <_mipi_dsi0_pll>;
+};
+
+ {
+   status = "okay";
+
+   qcom,dual-dsi-mode;
+   qcom,sync-dual-dsi;
+
+   vdda-supply = <_mipi_dsi1_1p2>;
+
+   ports {
+   port@1 {
+   endpoint {
+   remote-endpoint = <_in>;
+   data-lanes = <0 1 2 3>;
+   };
+   };
+   };
+};
+
+_phy {
+   status = "okay";
+   vdds-supply = <_mipi_dsi1_pll>;
+};
+
  {
status = "okay";
clock-frequency = <40>;
 };
 
+ {
+   status = "okay";
+};
+
+_mdp {
+   status = "okay";
+};
+
 _id_1 {
status = "okay";
 };
@@ -419,6 +527,22 @@
 
 /* PINCTRL - additions to nodes defined in sdm845.dtsi */
 
+_dsi_active {
+   pinconf {
+   pins = "gpio6", "gpio52";
+   drive-strength = <8>;
+   bias-disable;
+   };
+};
+
+_dsi_suspend {
+   pinconf {
+   pins = "gpio6", "gpio52";
+   drive-strength = <2>;
+   bias-pull-down;
+   };
+};
+
 _i2c10_default {
pinconf {
pins = "gpio55", "gpio56";
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project

___
Freedreno mailing list
Freedreno@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/freedreno


[Freedreno] [PATCH v4 0/3]

2018-11-02 Thread Jeykumar Sankaran
Reviving the patch posted by Sean initially.

This patch set adds MDSS and DSI nodes to SDM845 dtsi to enable display. The
patches are tested on SDM845 MTP platform using the kernel based on [1].

Part of the dependent drivers are already posted on list. Rest of the
dependencies are met using using downstream version of the driver(s) which are
yet to make it to the list. 

References to the driver patches used for testing:

display controller: 
https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git/commit/arch/arm64/boot/dts/qcom/sdm845.dtsi?id=40019e8452fe76867bdb2e7
WLED: 
https://patchwork.kernel.org/project/linux-arm-msm/list/?series=11023=both=*
Panel: https://patchwork.freedesktop.org/series/50657/
iommu: https://patchwork.kernel.org/patch/10534999/

[1] 
https://git.linaro.org/landing-teams/working/qualcomm/kernel.git/log/?h=integration-linux-qcomlt

Thanks and Regards,
Jeykumar S.

Changes in v4:
- changes to add pinctrl nodes to SoC dts and display nodes to MTP
  are included in the series
- clock name clean up in dsi nodes
- move around added nodes to maintain naming orders

Jeykumar Sankaran (3):
  arm64: dts: qcom: sdm845: Add dpu to sdm845 dts file
  arm64: dts: sdm845: Add dsi pinctrl nodes
  arm64: dts: sdm845: Add display nodes to MTP dts

 arch/arm64/boot/dts/qcom/sdm845-mtp.dts | 124 +++
 arch/arm64/boot/dts/qcom/sdm845.dtsi| 205 
 2 files changed, 329 insertions(+)

-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project

___
Freedreno mailing list
Freedreno@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/freedreno


[Freedreno] [PATCH v4 2/3] arm64: dts: sdm845: Add dsi pinctrl nodes

2018-11-02 Thread Jeykumar Sankaran
Add dsi active/suspend pinctrl nodes to sdm845 SoC dts.

Changes in v4:
- patch introduced in the series

Signed-off-by: Jeykumar Sankaran 
---
 arch/arm64/boot/dts/qcom/sdm845.dtsi | 14 ++
 1 file changed, 14 insertions(+)

diff --git a/arch/arm64/boot/dts/qcom/sdm845.dtsi 
b/arch/arm64/boot/dts/qcom/sdm845.dtsi
index 5728b4c..35df5d2 100644
--- a/arch/arm64/boot/dts/qcom/sdm845.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm845.dtsi
@@ -822,6 +822,20 @@
interrupt-controller;
#interrupt-cells = <2>;
 
+   dpu_dsi_active: dpu-dsi-active {
+   pinmux {
+   pins = "gpio6", "gpio52";
+   function = "gpio";
+   };
+   };
+
+   dpu_dsi_suspend: dpu-dsi-suspend {
+   pinmux {
+   pins = "gpio6", "gpio52";
+   function = "gpio";
+   };
+   };
+
qup_i2c0_default: qup-i2c0-default {
pinmux {
pins = "gpio0", "gpio1";
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project

___
Freedreno mailing list
Freedreno@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/freedreno


[Freedreno] [PATCH v4 1/3] arm64: dts: qcom: sdm845: Add dpu to sdm845 dts file

2018-11-02 Thread Jeykumar Sankaran
DPU is short for the Display Processing Unit. It is the display
controller on Qualcomm SDM845 chips.

This change adds MDSS and DSI nodes to enable display on the
target device.

Changes in v2:
 - Beefed up commit message
 - Use SoC specific compatibles for mdss and dpu (Rob H)
 - Use assigned-clocks to set initial clock frequency(Rob H)
Changes in v3:
 - added IOMMU node
 - Fix device naming (remove _phys)
 - Use correct IRQ_TYPE in interrupt specifiers
Changes in v4:
 - move mdss node to preserve the unit address sort order
 - remove _clk suffix from dsi clocks
 (both the comments are from Doug Anderson)

Signed-off-by: Jeykumar Sankaran 
Signed-off-by: Sean Paul 
---
 arch/arm64/boot/dts/qcom/sdm845.dtsi | 191 +++
 1 file changed, 191 insertions(+)

diff --git a/arch/arm64/boot/dts/qcom/sdm845.dtsi 
b/arch/arm64/boot/dts/qcom/sdm845.dtsi
index b72bdb0..5728b4c 100644
--- a/arch/arm64/boot/dts/qcom/sdm845.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm845.dtsi
@@ -1248,6 +1248,197 @@
};
};
 
+   mdss: mdss@ae0 {
+   compatible = "qcom,sdm845-mdss";
+   reg = <0xae0 0x1000>;
+   reg-names = "mdss";
+
+   power-domains = < 0>;
+
+   clocks = < GCC_DISP_AHB_CLK>,
+< GCC_DISP_AXI_CLK>,
+< DISP_CC_MDSS_MDP_CLK>;
+   clock-names = "iface", "bus", "core";
+
+   assigned-clocks = < DISP_CC_MDSS_MDP_CLK>;
+   assigned-clock-rates = <3>;
+
+   interrupts = ;
+   interrupt-controller;
+   #interrupt-cells = <1>;
+
+   iommus = <_smmu 0x880 0x8>,
+<_smmu 0xc80 0x8>;
+
+   #address-cells = <1>;
+   #size-cells = <1>;
+   ranges;
+
+   mdss_mdp: mdp@ae01000 {
+   compatible = "qcom,sdm845-dpu";
+   reg = <0x0ae01000 0x8f000>,
+ <0x0aeb 0x2008>;
+   reg-names = "mdp", "vbif";
+
+   clocks = < DISP_CC_MDSS_AHB_CLK>,
+< DISP_CC_MDSS_AXI_CLK>,
+< DISP_CC_MDSS_MDP_CLK>,
+< DISP_CC_MDSS_VSYNC_CLK>;
+   clock-names = "iface", "bus", "core", "vsync";
+
+   assigned-clocks = < 
DISP_CC_MDSS_MDP_CLK>,
+ < 
DISP_CC_MDSS_VSYNC_CLK>;
+   assigned-clock-rates = <3>,
+  <1920>;
+
+   interrupt-parent = <>;
+   interrupts = <0 IRQ_TYPE_LEVEL_HIGH>;
+
+   ports {
+   #address-cells = <1>;
+   #size-cells = <0>;
+
+   port@0 {
+   reg = <0>;
+   dpu_intf1_out: endpoint {
+   remote-endpoint = 
<_in>;
+   };
+   };
+
+   port@1 {
+   reg = <1>;
+   dpu_intf2_out: endpoint {
+   remote-endpoint = 
<_in>;
+   };
+   };
+   };
+   };
+
+   dsi0: dsi@ae94000 {
+   compatible = "qcom,mdss-dsi-ctrl";
+   reg = <0xae94000 0x400>;
+   reg-names = "dsi_ctrl";
+
+   interrupt-parent = <>;
+   interrupts = <4 IRQ_TYPE_LEVEL_HIGH>;
+
+   clocks = < DISP_CC_MDSS_BYTE0_CLK>,
+< DISP_CC_MDSS_BYTE0_INTF_CLK>,
+  

[Freedreno] [PATCH] arm64: dts: sdm845: Add display nodes to MTP dts

2018-11-02 Thread Jeykumar Sankaran
Add mdss, dsi, dsi_phy, dsi pinctrl  and truly nt35597 panel nodes to
sdm845 MTP board dtsi.

Signed-off-by: Jeykumar Sankaran 
---
 arch/arm64/boot/dts/qcom/sdm845-mtp.dts | 124 
 1 file changed, 124 insertions(+)

diff --git a/arch/arm64/boot/dts/qcom/sdm845-mtp.dts 
b/arch/arm64/boot/dts/qcom/sdm845-mtp.dts
index 6d651f3..6e98ae8 100644
--- a/arch/arm64/boot/dts/qcom/sdm845-mtp.dts
+++ b/arch/arm64/boot/dts/qcom/sdm845-mtp.dts
@@ -8,6 +8,7 @@
 /dts-v1/;
 
 #include "sdm845.dtsi"
+#include 
 
 / {
model = "Qualcomm Technologies, Inc. SDM845 MTP";
@@ -22,6 +23,113 @@
};
 };
 
+ {
+   status = "okay";
+   qcom,dual-dsi-mode;
+   qcom,master-dsi;
+   qcom,sync-dual-dsi;
+
+   vdda-supply = <_mipi_dsi0_1p2>;
+
+   panel@0 {
+   compatible = "truly,nt35597-2K-display";
+   reg = <0>;
+
+   vdda-supply = <_l14a_1p88>;
+   vdispp-supply = <_regulator>;
+   vdispn-supply = <_regulator>;
+
+   pinctrl-names = "default", "suspend";
+   pinctrl-0 = <_dsi_active>;
+   pinctrl-1 = <_dsi_suspend>;
+
+   reset-gpios = < 6 GPIO_ACTIVE_HIGH>;
+   mode-gpios = < 52 GPIO_ACTIVE_HIGH>;
+
+   display-timings {
+   timing0: timing-0 {
+   /* originally
+* 268316160 Mhz,
+* but value below fits
+* better w/ downstream
+*/
+   clock-frequency = <268316138>;
+   hactive = <1440>;
+   vactive = <2560>;
+   hfront-porch = <200>;
+   hback-porch = <64>;
+   hsync-len = <32>;
+   vfront-porch = <8>;
+   vback-porch = <7>;
+   vsync-len = <1>;
+   };
+   };
+
+   ports {
+   #address-cells = <1>;
+   #size-cells = <0>;
+   port@0 {
+   reg = <0>;
+   panel0_in: endpoint {
+   remote-endpoint = <_out>;
+   };
+   };
+
+   port@1 {
+   reg = <1>;
+   panel1_in: endpoint {
+   remote-endpoint = <_out>;
+   };
+   };
+   };
+   };
+
+   ports {
+   port@1 {
+   endpoint {
+   remote-endpoint = <_in>;
+   data-lanes = <0 1 2 3>;
+   };
+   };
+   };
+};
+
+_phy {
+   status = "okay";
+   vdds-supply = <_mipi_dsi0_pll>;
+};
+
+ {
+   status = "okay";
+
+   qcom,dual-dsi-mode;
+   qcom,sync-dual-dsi;
+
+   vdda-supply = <_mipi_dsi1_1p2>;
+
+   ports {
+   port@1 {
+   endpoint {
+   remote-endpoint = <_in>;
+   data-lanes = <0 1 2 3>;
+   };
+   };
+   };
+};
+
+_phy {
+   status = "okay";
+   vdds-supply = <_mipi_dsi1_pll>;
+};
+
+ {
+   status = "okay";
+};
+
+_mdp {
+   status = "okay";
+};
+
  {
status = "okay";
clock-frequency = <40>;
@@ -58,3 +166,19 @@
bias-pull-up;
};
 };
+
+_dsi_active {
+   pinconf {
+   pins = "gpio6", "gpio52";
+   drive-strength = <8>;
+   bias-disable;
+   };
+};
+
+_dsi_suspend {
+   pinconf {
+   pins = "gpio6", "gpio52";
+   drive-strength = <2>;
+   bias-pull-down;
+   };
+};
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project

___
Freedreno mailing list
Freedreno@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/freedreno


[Freedreno] [PATCH] arm64: dts: sdm845: Add dsi pinctrl nodes

2018-11-02 Thread Jeykumar Sankaran
Add dsi active/suspend pinctrl nodes to sdm845 SoC dts.

Signed-off-by: Jeykumar Sankaran 
---
 arch/arm64/boot/dts/qcom/sdm845.dtsi | 14 ++
 1 file changed, 14 insertions(+)

diff --git a/arch/arm64/boot/dts/qcom/sdm845.dtsi 
b/arch/arm64/boot/dts/qcom/sdm845.dtsi
index dd612ac..e6a64f6 100644
--- a/arch/arm64/boot/dts/qcom/sdm845.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm845.dtsi
@@ -714,6 +714,20 @@
interrupt-controller;
#interrupt-cells = <2>;
 
+   dpu_dsi_active: dpu-dsi-active {
+   pinmux {
+   pins = "gpio6", "gpio52";
+   function = "gpio";
+   };
+   };
+
+   dpu_dsi_suspend: dpu-dsi-suspend {
+   pinmux {
+   pins = "gpio6", "gpio52";
+   function = "gpio";
+   };
+   };
+
qup_i2c0_default: qup-i2c0-default {
pinmux {
pins = "gpio0", "gpio1";
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project

___
Freedreno mailing list
Freedreno@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/freedreno


Re: [Freedreno] [PATCH] drm/msm/dpu: Don't use devm for component devices

2018-11-02 Thread Jeykumar Sankaran

On 2018-11-02 07:30, Jordan Crouse wrote:

Devices that are bound as components should not use devm since
device managed memory is not freed when the component is
unbound.

In particular this is an issue if the component bind fails
due to an -EPROBE_DEFER. In this case the bind would try again


Isn't this the only case where using devm would be a problem? Even in 
this case
do you expect any leaks if devm_kfree is called before DEFERing due to 
errors

and in unbounds?

Thanks,
Jeykumar S.

later and any devm managed memory allocated during the former
aborted attempt would be leaked until the device itself was
destroyed. Since all the memory allocated during a bind
should be freed during an unbind (or bind error case) there isn't
any reason to use devm for resources that have a explicit
teardown step.

This doesn't remove devm for all resources - in particular
msm_ioremap() still uses devm_ioremap() but thats a generic
issue that can easily be addressed as a cleanup later and the
unbind code already does the requisite devm calls to unmap it.

Signed-off-by: Jordan Crouse 
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c |  4 ++--
 drivers/gpu/drm/msm/disp/dpu1/dpu_io_util.c |  4 +---
 drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c | 10 ++
 drivers/gpu/drm/msm/disp/dpu1/dpu_mdss.c|  8 +---
 4 files changed, 14 insertions(+), 12 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
index 82c55efb500f..287d4c3e58c3 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
@@ -2220,14 +2220,14 @@ struct drm_encoder *dpu_encoder_init(struct
drm_device *dev,
struct dpu_encoder_virt *dpu_enc = NULL;
int rc = 0;

-   dpu_enc = devm_kzalloc(dev->dev, sizeof(*dpu_enc), GFP_KERNEL);
+   dpu_enc = kzalloc(sizeof(*dpu_enc), GFP_KERNEL);
if (!dpu_enc)
return ERR_PTR(ENOMEM);

rc = drm_encoder_init(dev, _enc->base, _encoder_funcs,
drm_enc_mode, NULL);
if (rc) {
-   devm_kfree(dev->dev, dpu_enc);
+   kfree(dpu_enc);
return ERR_PTR(rc);
}

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_io_util.c
b/drivers/gpu/drm/msm/disp/dpu1/dpu_io_util.c
index 89ee4b36beff..90b53e9508f2 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_io_util.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_io_util.c
@@ -155,9 +155,7 @@ int msm_dss_parse_clock(struct platform_device 
*pdev,

return 0;
}

-   mp->clk_config = devm_kzalloc(>dev,
- sizeof(struct dss_clk) * num_clk,
- GFP_KERNEL);
+	mp->clk_config = kcalloc(num_clk, sizeof(struct dss_clk), 
GFP_KERNEL);

if (!mp->clk_config)
return -ENOMEM;

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
index 985c855796ae..5ac3c3f3b08d 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
@@ -1086,13 +1086,14 @@ static int dpu_bind(struct device *dev, struct
device *master, void *data)
struct dss_module_power *mp;
int ret = 0;

-   dpu_kms = devm_kzalloc(>dev, sizeof(*dpu_kms), GFP_KERNEL);
+   dpu_kms = kzalloc(sizeof(*dpu_kms), GFP_KERNEL);
if (!dpu_kms)
return -ENOMEM;

mp = _kms->mp;
ret = msm_dss_parse_clock(pdev, mp);
if (ret) {
+   kfree(dpu_kms);
DPU_ERROR("failed to parse clocks, ret=%d\n", ret);
return ret;
}
@@ -1109,7 +1110,7 @@ static int dpu_bind(struct device *dev, struct 
device

*master, void *data)
dpu_kms->rpm_enabled = true;

priv->kms = _kms->base;
-   return ret;
+   return 0;
 }

 static void dpu_unbind(struct device *dev, struct device *master, void
*data)
@@ -1120,11 +1121,12 @@ static void dpu_unbind(struct device *dev, 
struct

device *master, void *data)

dpu_power_resource_deinit(pdev, _kms->phandle);
msm_dss_put_clk(mp->clk_config, mp->num_clk);
-   devm_kfree(>dev, mp->clk_config);
-   mp->num_clk = 0;
+   kfree(mp->clk_config);

if (dpu_kms->rpm_enabled)
pm_runtime_disable(>dev);
+
+   kfree(dpu_kms);
 }

 static const struct component_ops dpu_ops = {
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_mdss.c
b/drivers/gpu/drm/msm/disp/dpu1/dpu_mdss.c
index 2235ef8129f4..34ab489b1a5b 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_mdss.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_mdss.c
@@ -161,7 +161,7 @@ static void dpu_mdss_destroy(struct drm_device 
*dev)

free_irq(platform_get_irq(pdev, 0), dpu_mdss);

msm_dss_put_clk(mp->clk_config, mp->num_clk);
-   devm_kfree(>dev, mp->clk_config);
+   kfree(mp->clk_config);

if (dpu_mdss->mmio)
devm_iounmap(>dev, dpu_mdss->mmio);

Re: [Freedreno] [[DPU PATCH]] drm/msm/dpu: Correct dpu destroy and disable order

2018-11-02 Thread Jeykumar Sankaran

On 2018-11-01 23:17, Jayant Shekhar wrote:

In case of msm drm bind failure, dpu_mdss_destroy is triggered.
In this function, resources are freed and pm runtime disable is
called, which triggers dpu_mdss_disable. Now in dpu_mdss_disable,
driver tries to access a memory which is already freed. This
results in kernel panic. Fix this by ensuring proper sequence
of dpu destroy and disable calls.

Change-Id: Id6e01a537ae9c40789c5752dc28c397391ab7dfe

Please strip down Change-Id before posting the patch.

Signed-off-by: Jayant Shekhar 
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_mdss.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_mdss.c
b/drivers/gpu/drm/msm/disp/dpu1/dpu_mdss.c
index fd9c893..cd9a6bd 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_mdss.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_mdss.c
@@ -156,6 +156,8 @@ static void dpu_mdss_destroy(struct drm_device 
*dev)

struct dpu_mdss *dpu_mdss = to_dpu_mdss(priv->mdss);
struct dss_module_power *mp = _mdss->mp;

+   pm_runtime_disable(dev->dev);
+
_dpu_mdss_irq_domain_fini(dpu_mdss);

free_irq(platform_get_irq(pdev, 0), dpu_mdss);
@@ -167,7 +169,6 @@ static void dpu_mdss_destroy(struct drm_device 
*dev)

devm_iounmap(>dev, dpu_mdss->mmio);
dpu_mdss->mmio = NULL;


Lots of double line spacing. Get rid of them.

-   pm_runtime_disable(dev->dev);
priv->mdss = NULL;
 }

Also drop "DPU PATCH" prefix.
--
Jeykumar s
___
Freedreno mailing list
Freedreno@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/freedreno


[Freedreno] [PATCH v3] Add display nodes to SDM845 dtsi

2018-11-01 Thread Jeykumar Sankaran
Reviving the patch posted by Sean initially.

This patch set adds MDSS and DSI nodes to SDM845 dtsi to enable display. The
patches are tested on SDM845 MTP platform using the kernel based on [1].

Part of the dependent drivers are already posted on list. Rest of the 
dependencies are met using using downstream version of the driver(s)
which are yet to make it to the list. 

References to the driver patches used for testing:

display controller: 
https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git/commit/arch/arm64/boot/dts/qcom/sdm845.dtsi?id=40019e8452fe76867bdb2e7
WLED: 
https://patchwork.kernel.org/project/linux-arm-msm/list/?series=11023=both=*
Panel: https://patchwork.freedesktop.org/series/50657/
iommu: https://patchwork.kernel.org/patch/10534999/

[1] 
https://git.linaro.org/landing-teams/working/qualcomm/kernel.git/log/?h=integration-linux-qcomlt

Thanks and Regards,
Jeykumar S.


Jeykumar Sankaran (1):
  arm64: dts: qcom: sdm845: Add dpu to sdm845 dts file

 arch/arm64/boot/dts/qcom/sdm845.dtsi | 191 +++
 1 file changed, 191 insertions(+)

-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project

___
Freedreno mailing list
Freedreno@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/freedreno


[Freedreno] [PATCH v3] arm64: dts: qcom: sdm845: Add dpu to sdm845 dts file

2018-11-01 Thread Jeykumar Sankaran
DPU is short for the Display Processing Unit. It is the display
controller on Qualcomm SDM845 chips.

This change adds MDSS and DSI nodes to enable display on the
target device.

Changes in v2:
 - Beefed up commit message
 - Use SoC specific compatibles for mdss and dpu (Rob H)
 - Use assigned-clocks to set initial clock frequency(Rob H)
Changes in v3:
 - added IOMMU node
 - Fix device naming (remove _phys)
 - Use correct IRQ_TYPE in interrupt specifiers

Signed-off-by: Jeykumar Sankaran 
Signed-off-by: Sean Paul 
---
 arch/arm64/boot/dts/qcom/sdm845.dtsi | 191 +++
 1 file changed, 191 insertions(+)

diff --git a/arch/arm64/boot/dts/qcom/sdm845.dtsi 
b/arch/arm64/boot/dts/qcom/sdm845.dtsi
index 0c9a2aa..dd612ac 100644
--- a/arch/arm64/boot/dts/qcom/sdm845.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm845.dtsi
@@ -978,6 +978,197 @@
#thermal-sensor-cells = <1>;
};
 
+   mdss: mdss@ae0 {
+   compatible = "qcom,sdm845-mdss";
+   reg = <0xae0 0x1000>;
+   reg-names = "mdss";
+
+   power-domains = < 0>;
+
+   clocks = < GCC_DISP_AHB_CLK>,
+< GCC_DISP_AXI_CLK>,
+< DISP_CC_MDSS_MDP_CLK>;
+   clock-names = "iface", "bus", "core";
+
+   assigned-clocks = < DISP_CC_MDSS_MDP_CLK>;
+   assigned-clock-rates = <3>;
+
+   interrupts = ;
+   interrupt-controller;
+   #interrupt-cells = <1>;
+
+   iommus = <_smmu 0x880 0x8>,
+<_smmu 0xc80 0x8>;
+
+   #address-cells = <1>;
+   #size-cells = <1>;
+   ranges;
+
+   mdss_mdp: mdp@ae01000 {
+   compatible = "qcom,sdm845-dpu";
+   reg = <0x0ae01000 0x8f000>,
+ <0x0aeb 0x2008>;
+   reg-names = "mdp", "vbif";
+
+   clocks = < DISP_CC_MDSS_AHB_CLK>,
+< DISP_CC_MDSS_AXI_CLK>,
+< DISP_CC_MDSS_MDP_CLK>,
+< DISP_CC_MDSS_VSYNC_CLK>;
+   clock-names = "iface", "bus", "core", "vsync";
+
+   assigned-clocks = < 
DISP_CC_MDSS_MDP_CLK>,
+ < 
DISP_CC_MDSS_VSYNC_CLK>;
+   assigned-clock-rates = <3>,
+  <1920>;
+
+   interrupt-parent = <>;
+   interrupts = <0 IRQ_TYPE_LEVEL_HIGH>;
+
+   ports {
+   #address-cells = <1>;
+   #size-cells = <0>;
+
+   port@0 {
+   reg = <0>;
+   dpu_intf1_out: endpoint {
+   remote-endpoint = 
<_in>;
+   };
+   };
+
+   port@1 {
+   reg = <1>;
+   dpu_intf2_out: endpoint {
+   remote-endpoint = 
<_in>;
+   };
+   };
+   };
+   };
+
+   dsi0: dsi@ae94000 {
+   compatible = "qcom,mdss-dsi-ctrl";
+   reg = <0xae94000 0x400>;
+   reg-names = "dsi_ctrl";
+
+   interrupt-parent = <>;
+   interrupts = <4 IRQ_TYPE_LEVEL_HIGH>;
+
+   clocks = < DISP_CC_MDSS_BYTE0_CLK>,
+< DISP_CC_MDSS_BYTE0_INTF_CLK>,
+< DISP_CC_MDSS_PCLK0_CLK>,
+< DISP_CC_MDSS_ESC0_CLK>,

[Freedreno] [PATCH 2/2] drm/msm: subclass work object for vblank events

2018-10-31 Thread Jeykumar Sankaran
msm maintains a separate structure to define vblank
work definitions and a list to track events submitted
to the display worker thread. We can avoid these
redundant list and its protection mechanism, if we
subclass the work object to encapsulate vblank
event parameters.

Signed-off-by: Jeykumar Sankaran 
---
 drivers/gpu/drm/msm/msm_drv.c | 70 ---
 drivers/gpu/drm/msm/msm_drv.h |  7 -
 2 files changed, 19 insertions(+), 58 deletions(-)

diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c
index 1f384b3..67a96ee 100644
--- a/drivers/gpu/drm/msm/msm_drv.c
+++ b/drivers/gpu/drm/msm/msm_drv.c
@@ -203,61 +203,44 @@ u32 msm_readl(const void __iomem *addr)
return val;
 }
 
-struct vblank_event {
-   struct list_head node;
+struct msm_vblank_work {
+   struct kthread_work work;
int crtc_id;
bool enable;
+   struct msm_drm_private *priv;
 };
 
 static void vblank_ctrl_worker(struct kthread_work *work)
 {
-   struct msm_vblank_ctrl *vbl_ctrl = container_of(work,
-   struct msm_vblank_ctrl, work);
-   struct msm_drm_private *priv = container_of(vbl_ctrl,
-   struct msm_drm_private, vblank_ctrl);
+   struct msm_vblank_work *vbl_work = container_of(work,
+   struct msm_vblank_work, work);
+   struct msm_drm_private *priv = vbl_work->priv;
struct msm_kms *kms = priv->kms;
-   struct vblank_event *vbl_ev, *tmp;
-   unsigned long flags;
-
-   spin_lock_irqsave(_ctrl->lock, flags);
-   list_for_each_entry_safe(vbl_ev, tmp, _ctrl->event_list, node) {
-   list_del(_ev->node);
-   spin_unlock_irqrestore(_ctrl->lock, flags);
-
-   if (vbl_ev->enable)
-   kms->funcs->enable_vblank(kms,
-   priv->crtcs[vbl_ev->crtc_id]);
-   else
-   kms->funcs->disable_vblank(kms,
-   priv->crtcs[vbl_ev->crtc_id]);
 
-   kfree(vbl_ev);
-
-   spin_lock_irqsave(_ctrl->lock, flags);
-   }
+   if (vbl_work->enable)
+   kms->funcs->enable_vblank(kms, priv->crtcs[vbl_work->crtc_id]);
+   else
+   kms->funcs->disable_vblank(kms, priv->crtcs[vbl_work->crtc_id]);
 
-   spin_unlock_irqrestore(_ctrl->lock, flags);
+   kfree(vbl_work);
 }
 
 static int vblank_ctrl_queue_work(struct msm_drm_private *priv,
int crtc_id, bool enable)
 {
-   struct msm_vblank_ctrl *vbl_ctrl = >vblank_ctrl;
-   struct vblank_event *vbl_ev;
-   unsigned long flags;
+   struct msm_vblank_work *vbl_work;
 
-   vbl_ev = kzalloc(sizeof(*vbl_ev), GFP_ATOMIC);
-   if (!vbl_ev)
+   vbl_work = kzalloc(sizeof(*vbl_work), GFP_ATOMIC);
+   if (!vbl_work)
return -ENOMEM;
 
-   vbl_ev->crtc_id = crtc_id;
-   vbl_ev->enable = enable;
+   kthread_init_work(_work->work, vblank_ctrl_worker);
 
-   spin_lock_irqsave(_ctrl->lock, flags);
-   list_add_tail(_ev->node, _ctrl->event_list);
-   spin_unlock_irqrestore(_ctrl->lock, flags);
+   vbl_work->crtc_id = crtc_id;
+   vbl_work->enable = enable;
+   vbl_work->priv = priv;
 
-   kthread_queue_work(>disp_thread.worker, _ctrl->work);
+   kthread_queue_work(>disp_thread.worker, _work->work);
 
return 0;
 }
@@ -269,20 +252,8 @@ static int msm_drm_uninit(struct device *dev)
struct msm_drm_private *priv = ddev->dev_private;
struct msm_kms *kms = priv->kms;
struct msm_mdss *mdss = priv->mdss;
-   struct msm_vblank_ctrl *vbl_ctrl = >vblank_ctrl;
-   struct vblank_event *vbl_ev, *tmp;
int i;
 
-   /* We must cancel and cleanup any pending vblank enable/disable
-* work before drm_irq_uninstall() to avoid work re-enabling an
-* irq after uninstall has disabled it.
-*/
-   kthread_flush_work(_ctrl->work);
-   list_for_each_entry_safe(vbl_ev, tmp, _ctrl->event_list, node) {
-   list_del(_ev->node);
-   kfree(vbl_ev);
-   }
-
kthread_flush_worker(>disp_thread.worker);
kthread_stop(priv->disp_thread.thread);
priv->disp_thread.thread = NULL;
@@ -474,9 +445,6 @@ static int msm_drm_init(struct device *dev, struct 
drm_driver *drv)
priv->wq = alloc_ordered_workqueue("msm", 0);
 
INIT_LIST_HEAD(>inactive_list);
-   INIT_LIST_HEAD(>vblank_ctrl.event_list);
-   kthread_init_work(>vblank_ctrl.work, vblank_ctrl_worker);
-   spin_lock_init(>vblank_ctrl.lock);
 
drm_mode_config_init(ddev);
 
diff --g

[Freedreno] [PATCH 1/2] drm/msm: use common display thread for dispatching vblank events

2018-10-31 Thread Jeykumar Sankaran
DPU was using one thread per display to dispatch async
commits and vblank requests. Since clean up already happened
in msm to use the common thread for all the display commits,
display threads are only used to cater vblank requests. Single
thread is sufficient to do the job without any performance hits.

Signed-off-by: Jeykumar Sankaran 
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c |  6 +---
 drivers/gpu/drm/msm/msm_drv.c   | 50 -
 drivers/gpu/drm/msm/msm_drv.h   |  2 +-
 3 files changed, 23 insertions(+), 35 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
index 82c55ef..aff20f5 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
@@ -753,11 +753,7 @@ static int dpu_encoder_resource_control(struct drm_encoder 
*drm_enc,
is_vid_mode = dpu_enc->disp_info.capabilities &
MSM_DISPLAY_CAP_VID_MODE;
 
-   if (drm_enc->crtc->index >= ARRAY_SIZE(priv->disp_thread)) {
-   DPU_ERROR("invalid crtc index\n");
-   return -EINVAL;
-   }
-   disp_thread = >disp_thread[drm_enc->crtc->index];
+   disp_thread = >disp_thread;
 
/*
 * when idle_pc is not supported, process only KICKOFF, STOP and MODESET
diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c
index 9c9f7ff..1f384b3 100644
--- a/drivers/gpu/drm/msm/msm_drv.c
+++ b/drivers/gpu/drm/msm/msm_drv.c
@@ -257,8 +257,7 @@ static int vblank_ctrl_queue_work(struct msm_drm_private 
*priv,
list_add_tail(_ev->node, _ctrl->event_list);
spin_unlock_irqrestore(_ctrl->lock, flags);
 
-   kthread_queue_work(>disp_thread[crtc_id].worker,
-   _ctrl->work);
+   kthread_queue_work(>disp_thread.worker, _ctrl->work);
 
return 0;
 }
@@ -284,14 +283,12 @@ static int msm_drm_uninit(struct device *dev)
kfree(vbl_ev);
}
 
+   kthread_flush_worker(>disp_thread.worker);
+   kthread_stop(priv->disp_thread.thread);
+   priv->disp_thread.thread = NULL;
+
/* clean up display commit/event worker threads */
for (i = 0; i < priv->num_crtcs; i++) {
-   if (priv->disp_thread[i].thread) {
-   kthread_flush_worker(>disp_thread[i].worker);
-   kthread_stop(priv->disp_thread[i].thread);
-   priv->disp_thread[i].thread = NULL;
-   }
-
if (priv->event_thread[i].thread) {
kthread_flush_worker(>event_thread[i].worker);
kthread_stop(priv->event_thread[i].thread);
@@ -537,6 +534,22 @@ static int msm_drm_init(struct device *dev, struct 
drm_driver *drv)
ddev->mode_config.funcs = _config_funcs;
ddev->mode_config.helper_private = _config_helper_funcs;
 
+   /* initialize display thread */
+   kthread_init_worker(>disp_thread.worker);
+   priv->disp_thread.dev = ddev;
+   priv->disp_thread.thread = kthread_run(kthread_worker_fn,
+  >disp_thread.worker,
+  "disp_thread");
+   if (IS_ERR(priv->disp_thread.thread)) {
+   DRM_DEV_ERROR(dev, "failed to create crtc_commit kthread\n");
+   priv->disp_thread.thread = NULL;
+   goto err_msm_uninit;
+   }
+
+   ret = sched_setscheduler(priv->disp_thread.thread, SCHED_FIFO, );
+   if (ret)
+   pr_warn("display thread priority update failed: %d\n", ret);
+
/**
 * this priority was found during empiric testing to have appropriate
 * realtime scheduling to process display updates and interact with
@@ -544,27 +557,6 @@ static int msm_drm_init(struct device *dev, struct 
drm_driver *drv)
 */
param.sched_priority = 16;
for (i = 0; i < priv->num_crtcs; i++) {
-
-   /* initialize display thread */
-   priv->disp_thread[i].crtc_id = priv->crtcs[i]->base.id;
-   kthread_init_worker(>disp_thread[i].worker);
-   priv->disp_thread[i].dev = ddev;
-   priv->disp_thread[i].thread =
-   kthread_run(kthread_worker_fn,
-   >disp_thread[i].worker,
-   "crtc_commit:%d", priv->disp_thread[i].crtc_id);
-   if (IS_ERR(priv->disp_thread[i].thread)) {
-   DRM_DEV_ERROR(dev, "failed to create crtc_commit 
kthread\n");
-   priv->disp_thread[i].thread = NULL;
-   goto err_msm_uninit;
-   }
-
- 

Re: [Freedreno] [PATCH 07/25] drm/msm/dpu: reserve using crtc state

2018-10-12 Thread Jeykumar Sankaran

On 2018-10-09 23:28, Jeykumar Sankaran wrote:

On 2018-10-09 14:06, Sean Paul wrote:

On Mon, Oct 08, 2018 at 09:27:24PM -0700, Jeykumar Sankaran wrote:

DPU maintained reservation lists to cache assigned
HW blocks for the display and a retrieval mechanism for
the individual DRM components to query their respective
HW blocks.

This patch uses the sub-classed CRTC state to store
and track HW blocks assigned for different components
of the display pipeline. It helps the driver:
- to get rid of unwanted store and retrieval RM API's
- to preserve HW resources assigned in atomic_check
  through atomic swap/duplicate.

Separate patch is submitted to remove resource
reservation in atomic_commit path.

Signed-off-by: Jeykumar Sankaran 
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c   | 65

+++---

 drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h   | 14 +
 drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c| 28 +++---
 .../gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c   | 20 ++-
 drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c | 58

---

 5 files changed, 72 insertions(+), 113 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c

b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c

index 4960641..0625f56 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
@@ -421,69 +421,20 @@ void dpu_crtc_complete_commit(struct drm_crtc

*crtc,

trace_dpu_crtc_complete_commit(DRMID(crtc));
 }

-static void _dpu_crtc_setup_mixer_for_encoder(
-   struct drm_crtc *crtc,
-   struct drm_encoder *enc)
+static void _dpu_crtc_setup_mixers(struct drm_crtc *crtc)
 {
struct dpu_crtc_state *cstate = to_dpu_crtc_state(crtc->state);
-   struct dpu_kms *dpu_kms = _dpu_crtc_get_kms(crtc);
-   struct dpu_rm *rm = _kms->rm;
struct dpu_crtc_mixer *mixer;
-   struct dpu_hw_ctl *last_valid_ctl = NULL;
-   int i;
-   struct dpu_rm_hw_iter lm_iter, ctl_iter;
-
-   dpu_rm_init_hw_iter(_iter, enc->base.id, DPU_HW_BLK_LM);
-   dpu_rm_init_hw_iter(_iter, enc->base.id, DPU_HW_BLK_CTL);
+   int i, ctl_index;

/* Set up all the mixers and ctls reserved by this encoder */
-   for (i = cstate->num_mixers; i < ARRAY_SIZE(cstate->mixers); i++)

{

+   for (i = 0; i < cstate->num_mixers; i++) {
mixer = >mixers[i];

-   if (!dpu_rm_get_hw(rm, _iter))
-   break;
-   mixer->hw_lm = (struct dpu_hw_mixer *)lm_iter.hw;
-
/* CTL may be <= LMs, if <, multiple LMs controlled by 1

CTL */

-   if (!dpu_rm_get_hw(rm, _iter)) {
-   DPU_DEBUG("no ctl assigned to lm %d, using

previous\n",

-   mixer->hw_lm->idx - LM_0);
-   mixer->lm_ctl = last_valid_ctl;
-   } else {
-   mixer->lm_ctl = (struct dpu_hw_ctl *)ctl_iter.hw;
-   last_valid_ctl = mixer->lm_ctl;
-   }
-
-   /* Shouldn't happen, mixers are always >= ctls */
-   if (!mixer->lm_ctl) {
-   DPU_ERROR("no valid ctls found for lm %d\n",
-   mixer->hw_lm->idx - LM_0);
-   return;
-   }
-
-   cstate->num_mixers++;
-   DPU_DEBUG("setup mixer %d: lm %d\n",
-   i, mixer->hw_lm->idx - LM_0);
-   DPU_DEBUG("setup mixer %d: ctl %d\n",
-   i, mixer->lm_ctl->idx - CTL_0);
-   }
-}
-
-static void _dpu_crtc_setup_mixers(struct drm_crtc *crtc)
-{
-   struct dpu_crtc *dpu_crtc = to_dpu_crtc(crtc);
-   struct drm_encoder *enc;
-
-   mutex_lock(_crtc->crtc_lock);
-   /* Check for mixers on all encoders attached to this crtc */
-   list_for_each_entry(enc, >dev->mode_config.encoder_list,

head) {

-   if (enc->crtc != crtc)
-   continue;
-
-   _dpu_crtc_setup_mixer_for_encoder(crtc, enc);
+   ctl_index = min(i, cstate->num_ctls - 1);


This is another one of those places I mentioned where we're just 
assuming

a
value is going to be in a certain range. If
num_ctls/num_intfs/num_phys_encs
(all the same value afaict) is 0, we end up in a bad place.
Even though all these variables have the same value, they are 
representing the

sizes of logically seperate components.



At a minimum, there should be a WARN_ON/BUG_ON somewhere ensuring this 
can

never
drop below 0.

Isn't RM guaranteeing that? I can add the WARN_ON checks on these
num_xxx when the HW blocks are allocated.

Thanks,
Jeykumar S.



+   mixer->lm_ctl = cstate->hw_ctls[ctl_index];
}
-
-   mutex_unlock(_crt

[Freedreno] [PATCH v4] drm/msm: validate display and event threads

2018-10-10 Thread Jeykumar Sankaran
While creating display and event threads per crtc, validate
them before setting their priorities.

changes in v2:
- use dev_warn (Abhinav Kumar)
changes in v3:
- fix compilation error
changes in v4:
- Remove Change-Id (Sean Paul)
- Keep logging within 80 char limit (Sean Paul)

Signed-off-by: Jeykumar Sankaran 
---
 drivers/gpu/drm/msm/msm_drv.c | 49 ++-
 1 file changed, 16 insertions(+), 33 deletions(-)

diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c
index 4904d0d..dcff812 100644
--- a/drivers/gpu/drm/msm/msm_drv.c
+++ b/drivers/gpu/drm/msm/msm_drv.c
@@ -553,17 +553,18 @@ static int msm_drm_init(struct device *dev, struct 
drm_driver *drv)
kthread_run(kthread_worker_fn,
>disp_thread[i].worker,
"crtc_commit:%d", priv->disp_thread[i].crtc_id);
-   ret = sched_setscheduler(priv->disp_thread[i].thread,
-   SCHED_FIFO, );
-   if (ret)
-   pr_warn("display thread priority update failed: %d\n",
-   ret);
-
if (IS_ERR(priv->disp_thread[i].thread)) {
dev_err(dev, "failed to create crtc_commit kthread\n");
priv->disp_thread[i].thread = NULL;
+   goto err_msm_uninit;
}
 
+   ret = sched_setscheduler(priv->disp_thread[i].thread,
+SCHED_FIFO, );
+   if (ret)
+   dev_warn(dev, "disp_thread set priority failed: %d\n",
+ret);
+
/* initialize event thread */
priv->event_thread[i].crtc_id = priv->crtcs[i]->base.id;
kthread_init_worker(>event_thread[i].worker);
@@ -572,6 +573,12 @@ static int msm_drm_init(struct device *dev, struct 
drm_driver *drv)
kthread_run(kthread_worker_fn,
>event_thread[i].worker,
"crtc_event:%d", priv->event_thread[i].crtc_id);
+   if (IS_ERR(priv->event_thread[i].thread)) {
+   dev_err(dev, "failed to create crtc_event kthread\n");
+   priv->event_thread[i].thread = NULL;
+   goto err_msm_uninit;
+   }
+
/**
 * event thread should also run at same priority as disp_thread
 * because it is handling frame_done events. A lower priority
@@ -580,34 +587,10 @@ static int msm_drm_init(struct device *dev, struct 
drm_driver *drv)
 * failure at crtc commit level.
 */
ret = sched_setscheduler(priv->event_thread[i].thread,
-   SCHED_FIFO, );
+SCHED_FIFO, );
if (ret)
-   pr_warn("display event thread priority update failed: 
%d\n",
-   ret);
-
-   if (IS_ERR(priv->event_thread[i].thread)) {
-   dev_err(dev, "failed to create crtc_event kthread\n");
-   priv->event_thread[i].thread = NULL;
-   }
-
-   if ((!priv->disp_thread[i].thread) ||
-   !priv->event_thread[i].thread) {
-   /* clean up previously created threads if any */
-   for ( ; i >= 0; i--) {
-   if (priv->disp_thread[i].thread) {
-   kthread_stop(
-   priv->disp_thread[i].thread);
-   priv->disp_thread[i].thread = NULL;
-   }
-
-   if (priv->event_thread[i].thread) {
-   kthread_stop(
-   priv->event_thread[i].thread);
-   priv->event_thread[i].thread = NULL;
-   }
-   }
-   goto err_msm_uninit;
-   }
+   dev_warn(dev, "event_thread set priority failed:%d\n",
+ret);
}
 
ret = drm_vblank_init(ddev, priv->num_crtcs);
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project

___
Freedreno mailing list
Freedreno@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/freedreno


Re: [Freedreno] [PATCH 14/25] drm/msm/dpu: remove enc_id tagging for hw blocks

2018-10-10 Thread Jeykumar Sankaran

On 2018-10-10 08:06, Sean Paul wrote:

On Mon, Oct 08, 2018 at 09:27:31PM -0700, Jeykumar Sankaran wrote:

RM was using encoder id's to tag HW block's to reserve
and retrieve later for display pipeline. Now
that all the reserved HW blocks for a display are
maintained in its crtc state, no retrieval is needed.
This patch cleans up RM of encoder id tagging.

Signed-off-by: Jeykumar Sankaran 
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c| 90

+--

 drivers/gpu/drm/msm/disp/dpu1/dpu_trace.h | 28 --
 2 files changed, 36 insertions(+), 82 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c

b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c

index 303f1b3..a8461b8 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c
@@ -21,9 +21,6 @@
 #include "dpu_encoder.h"
 #include "dpu_trace.h"

-#define RESERVED_BY_OTHER(h, r)  \
-   ((h)->enc_id && (h)->enc_id != r)
-
 /**
  * struct dpu_rm_requirements - Reservation requirements parameter

bundle

  * @topology:  selected topology for the display
@@ -38,12 +35,13 @@ struct dpu_rm_requirements {
 /**
  * struct dpu_rm_hw_blk - hardware block tracking list member
  * @list:  List head for list of all hardware blocks tracking items
- * @enc_id:Encoder id to which this blk is binded
+ * @in_use: True, if the hw block is assigned to a display

pipeline.

+ * False, otherwise
  * @hw:Pointer to the hardware register access object for

this block

  */
 struct dpu_rm_hw_blk {
struct list_head list;
-   uint32_t enc_id;
+   bool in_use;


How do the reservations work for TEST_ONLY commits? At a quick glance 
it

looks
like they might be marked in_use?


Yes. We have a bug. I guess I should be releasing them in 
drm_crtc_destroy_state.


Thanks and Regards,
Jeykumar S.


Sean


struct dpu_hw_blk *hw;
 };

@@ -51,23 +49,19 @@ struct dpu_rm_hw_blk {
  * struct dpu_rm_hw_iter - iterator for use with dpu_rm
  * @hw: dpu_hw object requested, or NULL on failure
  * @blk: dpu_rm internal block representation. Clients ignore. Used 
as

iterator.
- * @enc_id: DRM ID of Encoder client wishes to search for, or 0 for 
Any

Encoder

  * @type: Hardware Block Type client wishes to search for.
  */
 struct dpu_rm_hw_iter {
struct dpu_hw_blk *hw;
struct dpu_rm_hw_blk *blk;
-   uint32_t enc_id;
enum dpu_hw_blk_type type;
 };

 static void _dpu_rm_init_hw_iter(
struct dpu_rm_hw_iter *iter,
-   uint32_t enc_id,
enum dpu_hw_blk_type type)
 {
memset(iter, 0, sizeof(*iter));
-   iter->enc_id = enc_id;
iter->type = type;
 }

@@ -91,16 +85,12 @@ static bool _dpu_rm_get_hw_locked(struct dpu_rm 
*rm,

struct dpu_rm_hw_iter *i)

i->blk = list_prepare_entry(i->blk, blk_list, list);

list_for_each_entry_continue(i->blk, blk_list, list) {
-   if (i->enc_id == i->blk->enc_id) {
+   if (!i->blk->in_use) {
i->hw = i->blk->hw;
-   DPU_DEBUG("found type %d id %d for enc %d\n",
-   i->type, i->blk->hw->id,

i->enc_id);

return true;
}
}

-   DPU_DEBUG("no match, type %d for enc %d\n", i->type, i->enc_id);
-
return false;
 }

@@ -196,7 +186,6 @@ static int _dpu_rm_hw_blk_create(
}

blk->hw = hw;
-   blk->enc_id = 0;
list_add_tail(>list, >hw_blks[type]);

return 0;
@@ -301,7 +290,6 @@ static bool _dpu_rm_needs_split_display(const 
struct

msm_display_topology *top)

  * proposed use case requirements, incl. hardwired dependent blocks

like

  * pingpong
  * @rm: dpu resource manager handle
- * @enc_id: encoder id requesting for allocation
  * @reqs: proposed use case requirements
  * @lm: proposed layer mixer, function checks if lm, and all other

hardwired

  *  blocks connected to the lm (pp) is available and appropriate
@@ -313,7 +301,6 @@ static bool _dpu_rm_needs_split_display(const 
struct

msm_display_topology *top)

  */
 static bool _dpu_rm_check_lm_and_get_connected_blks(
struct dpu_rm *rm,
-   uint32_t enc_id,
struct dpu_rm_requirements *reqs,
struct dpu_rm_hw_blk *lm,
struct dpu_rm_hw_blk **pp,
@@ -339,13 +326,7 @@ static bool

_dpu_rm_check_lm_and_get_connected_blks(

}
}

-   /* Already reserved? */
-   if (RESERVED_BY_OTHER(lm, enc_id)) {
-   DPU_DEBUG("lm %d already reserved\n", lm_cfg->id);
-   return false;
-   }
-
-   _dpu_rm_init_hw_iter(, 0, DPU_HW_BLK_PINGPONG);
+   _dpu_rm_init_hw_iter(, DPU_HW_BLK_PINGPONG);
while (_dpu_rm_ge

Re: [Freedreno] [PATCH 24/25] drm/msm/dpu: remove mutex locking for RM interfaces

2018-10-10 Thread Jeykumar Sankaran

On 2018-10-10 07:36, Sean Paul wrote:

On Tue, Oct 09, 2018 at 11:03:24PM -0700, Jeykumar Sankaran wrote:

On 2018-10-09 12:57, Sean Paul wrote:
> On Mon, Oct 08, 2018 at 09:27:41PM -0700, Jeykumar Sankaran wrote:
> > Since HW reservations are happening through atomic_check
> > and all the display commits are catered by a single commit thread,
> > it is not necessary to protect the interfaces by a separate
> > mutex.
> >
> > Signed-off-by: Jeykumar Sankaran 
> > ---
> >  drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c | 24



> >  drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h |  2 --
> >  2 files changed, 26 deletions(-)
> >
>
> /snip
>
> > diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h
> b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h
> > index 8676fa5..9acbeba 100644
> > --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h
> > +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h
> > @@ -24,11 +24,9 @@
> >   * struct dpu_rm - DPU dynamic hardware resource manager
> >   * @hw_blks: array of lists of hardware resources present in the
> system, one
> >   *   list per type of hardware block
> > - * @rm_lock: resource manager mutex
> >   */
> >  struct dpu_rm {
> >   struct list_head hw_blks[DPU_HW_BLK_MAX];
>
> At this point, there's really not much point to even having the rm.

It's

> just
> another level of indirection that IMO complicates the code. If you

look

> at the usage of hw_blks, the code is always looking at a specific type
> of
> hw_blk, so the array is unnecessary.
>
> dpu_kms could just keep a few arrays/lists of the hw types, and the

crtc

> and encoder
> reserve functions can just go in crtc/encoder.
>
> Sean
>
RM has been reduced to its current form to manage only LM/PP, CTL and
interfaces.
Our eventual plan is to support all the advanced HW blocks and its

features

in
an upstream friendly way. When RM grows to manage all its subblocks,
iteration
logic may get heavy since the chipset have HW chain restrictions on

various

hw blocks.
To provide room for the growth, I suggest keeping the allocation
helpers in a separate file. But I can see why you want to maintain the

HW

block lists
in the KMS.


At least for the blocks that exist, using the RM is unnecessary, does 
that
change for the current blocks when you add more? I'm guessing their 
code

will
remain unchanged.


Yes. But to seperate out the allocation logics, I prefered the separate
file. I guess we can hold off the discussion until we need those 
enhancements.


I can get rid of the RM files for now and move the allocation functions 
to

the respective files (CRTC / Encoder).

Thanks,
Jeykumar S.

If the new blocks you're adding have a lot of commonality, perhaps it
makes
sense to re-introduce the RM, but IMO it doesn't make sense for 
lm/ctl/pp.


Sean



Thanks,
Jeykumar S.
> > - struct mutex rm_lock;
> >  };
> >
> >  /**
> > --
> > The Qualcomm Innovation Center, Inc. is a member of the Code Aurora
> Forum,
> > a Linux Foundation Collaborative Project
> >
> > ___
> > Freedreno mailing list
> > Freedreno@lists.freedesktop.org
> > https://lists.freedesktop.org/mailman/listinfo/freedreno

--
Jeykumar S


--
Jeykumar S
___
Freedreno mailing list
Freedreno@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/freedreno


Re: [Freedreno] [PATCH 01/25] drm/msm/dpu: fix hw ctl retrieval for mixer muxing

2018-10-10 Thread Jeykumar Sankaran

On 2018-10-10 07:29, Sean Paul wrote:

On Tue, Oct 09, 2018 at 10:46:41PM -0700, Jeykumar Sankaran wrote:

On 2018-10-09 11:07, Sean Paul wrote:
> On Mon, Oct 08, 2018 at 09:27:18PM -0700, Jeykumar Sankaran wrote:
> > Layer mixer/pingpong block counts and hw ctl block counts
> > will not be same for all the topologies (e.g. layer
> > mixer muxing to single interface)
> >
> > Use the encoder's split_role info to retrieve the
> > respective control path for programming.
> >
> > Signed-off-by: Jeykumar Sankaran 
> > ---
> >  drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 9 ++---
> >  1 file changed, 6 insertions(+), 3 deletions(-)
> >
> > diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
> b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
> > index 96cdf06..d12f896 100644
> > --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
> > +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
> > @@ -1060,6 +1060,7 @@ static void dpu_encoder_virt_mode_set(struct
> drm_encoder *drm_enc,
> >
> >   for (i = 0; i < dpu_enc->num_phys_encs; i++) {
> >   struct dpu_encoder_phys *phys = dpu_enc->phys_encs[i];
> > + int ctl_index;
> >
> >   if (phys) {
> >   if (!dpu_enc->hw_pp[i]) {
> > @@ -1068,14 +1069,16 @@ static void dpu_encoder_virt_mode_set(struct
> drm_encoder *drm_enc,
> >   return;
> >   }
> >
> > - if (!hw_ctl[i]) {
> > + ctl_index = phys->split_role == ENC_ROLE_SLAVE ? 1
> : 0;
> > +
>
> What if MAX_CHANNELS_PER_ENC isn't 2? Similarly, what if num_phys_encs

> MAX_CHANNELS_PER_ENC? It seems like there should be a more formal
> relationship
> between all of these verious values (num_of_h_tiles assumed to be <= 2
> as
> well).
> If one of them changes beyond the assumed bound, the rest of the

driver

> falls
> over pretty hard.
>
MAX_CHANNELS_PER_ENC is set to 2 to represent HW limitation on the

chipset

as
we cannot gang up more than 2 LM chain to an interface. Supporting 
more

than

2
might demand much larger changes than validating for boundaries.

num_phys_enc is the max no of phys encoders we create as we are 
looping

through
num_of_h_tiles which cannot be more than priv->dsi array size.

So its very unlikely we would expect these loops to go out of bound!


For now, sure. However a new revision of hardware will be a pain to add
support
for if we add more assumptions, and secondly it makes it _really_ hard 
to

understand the code if you don't have Qualcomm employee-level access to
the
hardware design :).

I am having a hard time understanding why you have to see these counts 
as

"assumptions".

Except for MAX_CHANNELS_PER_ENC, all the other counts are either 
calculated

or derived from the other modules linked to the topology.

h_tiles is the drm_connector terminology which represents the number of 
panels

the display is driving. We use this information to determine the HW
block chains in the MDP. HW blocks counts (pp or ctl) need not be same
as the h_tile count to replace them with.

I believe maintaining the counts independently at each layer allows us 
to have more

flexibility to support independent HW chaining for future revisions.

Would it be more convincing if I get the MAX_CHANNELS_PER_ENC value from 
catalog.c?


So this is why I'm advocating for the reduction of the number of 
"num_of_"

values we assume are all in the same range. It's a lot easier to
understand the
hardware when you can see that a phys encoder is needed per h tile, and
that a
ctl/pp is needed per phys encoder.
This is exactly the idea I don't want to convey to the reader. For the 
LM merge path,
each phys encoder will not be having its own control. Based on the 
topology we

are supporting, HW block counts can vary. We can even drive:
- 2 interfaces with 1 ctl and 1 ping pong
- 1 interface with 1 ctl and 2 ping pongs
- 1 interface with 1 ctl and 1 ping pong

Thanks,
Jeykumar S.



Anyways, just my $0.02.

Sean



Thanks,
Jeykumar S.
>
> > + if (!hw_ctl[ctl_index]) {
> >   DPU_ERROR_ENC(dpu_enc, "no ctl block
> assigned"
> > -  "at idx: %d\n", i);
> > +  "at idx: %d\n", ctl_index);
> >   return;
>
> When you return on error here, should you give back the resources that
> you've
> already provisioned?
>
> >   }
> >
> >   phys->hw_pp = dpu_enc->hw_pp[i];
> > - phys->hw_ctl = hw_ctl

Re: [Freedreno] [DPU PATCH 0/3] Add support for DisplayPort driver on SnapDragon 845

2018-10-10 Thread Jeykumar Sankaran

On 2018-10-10 10:15, Chandan Uddaraju wrote:

These patches add support for Display-Port driver on SnapDragon 845
hardware. It adds
DP driver and DP PLL driver files along with the needed device-tree
bindings.

The block diagram of DP driver is shown below:


 +-+
 |DRM FRAMEWORK|
 +--+--+
|
   +v+
   | DP DRM  |
   +++
|
   +v+
 ++|   DP+--++--+
 ++---+| DISPLAY |+---+  |  |
 |++-+-+-+|  |  |
 ||  | |  |  |  |
 ||  | |  |  |  |
 ||  | |  |  |  |
 vv  v v  v  v  v
 +--+ +--+ +---+ ++ ++ +---+ +-+
 |  DP  | |  DP  | |DP | | DP | | DP | |DP | | DP  |
 |PARSER| |EXTCON| |AUX| |LINK| |CTRL| |PHY| |POWER|
 +--+---+ +---+--+ +---+ ++ +--+-+ +-+-+ +-+
| || |
 +--v---+ +---v-+ +v-v+
 |DEVICE| |EXTCON   | |  DP   |
 | TREE | |INTERFACE| |CATALOG|
 +--+ +-+ +---+---+
  |
  +---v+
  |CTRL/PHY|
  |   HW   |
  ++


It will be more helpful to have this block diagram in

[DPU PATCH 2/3] drm/msm/dp: add displayPort driver support

Thanks,
Jeykumar S.




These patches have dependency on clock driver changes mentioned below:
https://patchwork.kernel.org/patch/10632753/
https://patchwork.kernel.org/patch/10632757/



Chandan Uddaraju (3):
  dt-bindings: msm/dp: add bindings of DP/DP-PLL driver for Snapdragon
845
  drm/msm/dp: add displayPort driver support
  drm/msm/dp: add support for DP PLL driver

 .../devicetree/bindings/display/msm/dp.txt |  249 
 .../devicetree/bindings/display/msm/dpu.txt|   16 +-
 drivers/gpu/drm/msm/Kconfig|   25 +
 drivers/gpu/drm/msm/Makefile   |   21 +-
 drivers/gpu/drm/msm/disp/dpu1/dpu_io_util.c|  206 +++
 drivers/gpu/drm/msm/disp/dpu1/dpu_io_util.h|   44 +
 drivers/gpu/drm/msm/dp/dp_aux.c|  570 +++
 drivers/gpu/drm/msm/dp/dp_aux.h|   44 +
 drivers/gpu/drm/msm/dp/dp_catalog.c| 1188 
+++

 drivers/gpu/drm/msm/dp/dp_catalog.h|  144 ++
 drivers/gpu/drm/msm/dp/dp_ctrl.c   | 1476
+++
 drivers/gpu/drm/msm/dp/dp_ctrl.h   |   50 +
 drivers/gpu/drm/msm/dp/dp_debug.c  |  507 +++
 drivers/gpu/drm/msm/dp/dp_debug.h  |   81 +
 drivers/gpu/drm/msm/dp/dp_display.c| 1027 
+

 drivers/gpu/drm/msm/dp/dp_display.h|   58 +
 drivers/gpu/drm/msm/dp/dp_drm.c|  542 +++
 drivers/gpu/drm/msm/dp/dp_drm.h|   52 +
 drivers/gpu/drm/msm/dp/dp_extcon.c |  400 +
 drivers/gpu/drm/msm/dp/dp_extcon.h |  111 ++
 drivers/gpu/drm/msm/dp/dp_link.c   | 1549

 drivers/gpu/drm/msm/dp/dp_link.h   |  184 +++
 drivers/gpu/drm/msm/dp/dp_panel.c  |  624 
 drivers/gpu/drm/msm/dp/dp_panel.h  |  121 ++
 drivers/gpu/drm/msm/dp/dp_parser.c |  679 +
 drivers/gpu/drm/msm/dp/dp_parser.h |  208 +++
 drivers/gpu/drm/msm/dp/dp_power.c  |  652 
 drivers/gpu/drm/msm/dp/dp_power.h  |   59 +
 drivers/gpu/drm/msm/dp/dp_reg.h|  357 +
 drivers/gpu/drm/msm/dp/pll/dp_pll.c|  153 ++
 drivers/gpu/drm/msm/dp/pll/dp_pll.h|   64 +
 drivers/gpu/drm/msm/dp/pll/dp_pll_10nm.c   |  401 +
 drivers/gpu/drm/msm/dp/pll/dp_pll_10nm.h   |   94 ++
 drivers/gpu/drm/msm/dp/pll/dp_pll_10nm_util.c  |  531 +++
 drivers/gpu/drm/msm/msm_drv.c  |2 +
 drivers/gpu/drm/msm/msm_drv.h  |   22 +
 include/drm/drm_dp_helper.h|   19 +
 37 files changed, 12525 insertions(+), 5 deletions(-)
 create mode 100644 
Documentation/devicetree/bindings/display/msm/dp.txt

 create mode 100644 drivers/gpu/drm/msm/dp/dp_aux.c
 create mode 100644 drivers/gpu/drm/msm/dp/dp_aux.h
 create mode 100644 drivers/gpu/drm/msm/dp/dp_catalog.c
 create mode 100644 drivers/gpu/drm/msm/dp/dp_catalog.h
 create mode 100644 drivers/gpu/drm/msm/dp/dp_ctrl.c
 create mode 100644 drivers/gpu/drm/msm/dp/dp_ctrl.h
 create mode 100644 drivers/gpu/drm/msm/dp/dp_debug.c
 create mode 100644 drivers/gpu/drm/msm/dp/dp_debug.h
 create 

Re: [Freedreno] [PATCH 07/25] drm/msm/dpu: reserve using crtc state

2018-10-10 Thread Jeykumar Sankaran

On 2018-10-09 14:06, Sean Paul wrote:

On Mon, Oct 08, 2018 at 09:27:24PM -0700, Jeykumar Sankaran wrote:

DPU maintained reservation lists to cache assigned
HW blocks for the display and a retrieval mechanism for
the individual DRM components to query their respective
HW blocks.

This patch uses the sub-classed CRTC state to store
and track HW blocks assigned for different components
of the display pipeline. It helps the driver:
- to get rid of unwanted store and retrieval RM API's
- to preserve HW resources assigned in atomic_check
  through atomic swap/duplicate.

Separate patch is submitted to remove resource
reservation in atomic_commit path.

Signed-off-by: Jeykumar Sankaran 
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c   | 65

+++---

 drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h   | 14 +
 drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c| 28 +++---
 .../gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c   | 20 ++-
 drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c | 58

---

 5 files changed, 72 insertions(+), 113 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c

b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c

index 4960641..0625f56 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
@@ -421,69 +421,20 @@ void dpu_crtc_complete_commit(struct drm_crtc

*crtc,

trace_dpu_crtc_complete_commit(DRMID(crtc));
 }

-static void _dpu_crtc_setup_mixer_for_encoder(
-   struct drm_crtc *crtc,
-   struct drm_encoder *enc)
+static void _dpu_crtc_setup_mixers(struct drm_crtc *crtc)
 {
struct dpu_crtc_state *cstate = to_dpu_crtc_state(crtc->state);
-   struct dpu_kms *dpu_kms = _dpu_crtc_get_kms(crtc);
-   struct dpu_rm *rm = _kms->rm;
struct dpu_crtc_mixer *mixer;
-   struct dpu_hw_ctl *last_valid_ctl = NULL;
-   int i;
-   struct dpu_rm_hw_iter lm_iter, ctl_iter;
-
-   dpu_rm_init_hw_iter(_iter, enc->base.id, DPU_HW_BLK_LM);
-   dpu_rm_init_hw_iter(_iter, enc->base.id, DPU_HW_BLK_CTL);
+   int i, ctl_index;

/* Set up all the mixers and ctls reserved by this encoder */
-   for (i = cstate->num_mixers; i < ARRAY_SIZE(cstate->mixers); i++)

{

+   for (i = 0; i < cstate->num_mixers; i++) {
mixer = >mixers[i];

-   if (!dpu_rm_get_hw(rm, _iter))
-   break;
-   mixer->hw_lm = (struct dpu_hw_mixer *)lm_iter.hw;
-
/* CTL may be <= LMs, if <, multiple LMs controlled by 1

CTL */

-   if (!dpu_rm_get_hw(rm, _iter)) {
-   DPU_DEBUG("no ctl assigned to lm %d, using

previous\n",

-   mixer->hw_lm->idx - LM_0);
-   mixer->lm_ctl = last_valid_ctl;
-   } else {
-   mixer->lm_ctl = (struct dpu_hw_ctl *)ctl_iter.hw;
-   last_valid_ctl = mixer->lm_ctl;
-   }
-
-   /* Shouldn't happen, mixers are always >= ctls */
-   if (!mixer->lm_ctl) {
-   DPU_ERROR("no valid ctls found for lm %d\n",
-   mixer->hw_lm->idx - LM_0);
-   return;
-   }
-
-   cstate->num_mixers++;
-   DPU_DEBUG("setup mixer %d: lm %d\n",
-   i, mixer->hw_lm->idx - LM_0);
-   DPU_DEBUG("setup mixer %d: ctl %d\n",
-   i, mixer->lm_ctl->idx - CTL_0);
-   }
-}
-
-static void _dpu_crtc_setup_mixers(struct drm_crtc *crtc)
-{
-   struct dpu_crtc *dpu_crtc = to_dpu_crtc(crtc);
-   struct drm_encoder *enc;
-
-   mutex_lock(_crtc->crtc_lock);
-   /* Check for mixers on all encoders attached to this crtc */
-   list_for_each_entry(enc, >dev->mode_config.encoder_list,

head) {

-   if (enc->crtc != crtc)
-   continue;
-
-   _dpu_crtc_setup_mixer_for_encoder(crtc, enc);
+   ctl_index = min(i, cstate->num_ctls - 1);


This is another one of those places I mentioned where we're just 
assuming

a
value is going to be in a certain range. If
num_ctls/num_intfs/num_phys_encs
(all the same value afaict) is 0, we end up in a bad place.
Even though all these variables have the same value, they are 
representing the

sizes of logically seperate components.



At a minimum, there should be a WARN_ON/BUG_ON somewhere ensuring this 
can

never
drop below 0.

Isn't RM guaranteeing that? I can add the WARN_ON checks on these
num_xxx when the HW blocks are allocated.

Thanks,
Jeykumar S.



+   mixer->lm_ctl = cstate->hw_ctls[ctl_index];
}
-
-   mutex_unlock(_crtc->crtc_lock);
 }

 static void _dpu_cr

Re: [Freedreno] [PATCH 22/25] drm/msm/dpu: make crtc and encoder specific HW reservation

2018-10-10 Thread Jeykumar Sankaran

On 2018-10-09 13:41, Sean Paul wrote:

On Mon, Oct 08, 2018 at 09:27:39PM -0700, Jeykumar Sankaran wrote:

Instead of letting encoder make a centralized reservation for
all of its display DRM components, this path splits the
responsibility between CRTC and Encoder, each requesting
RM for the HW mapping of its own domain.

Signed-off-by: Jeykumar Sankaran 
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c| 31 +
 drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 14 ++
 drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c  | 69

-

 drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h  | 36 +++
 4 files changed, 119 insertions(+), 31 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c

b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c

index 0625f56..0536b8a 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
@@ -47,6 +47,8 @@
 #define LEFT_MIXER 0
 #define RIGHT_MIXER 1

+#define MAX_VDISPLAY_SPLIT 1080
+
 static inline int _dpu_crtc_get_mixer_width(struct dpu_crtc_state

*cstate,

struct drm_display_mode *mode)
 {
@@ -448,6 +450,7 @@ static void _dpu_crtc_setup_lm_bounds(struct

drm_crtc *crtc,


for (i = 0; i < cstate->num_mixers; i++) {
struct drm_rect *r = >lm_bounds[i];
+
r->x1 = crtc_split_width * i;
r->y1 = 0;
r->x2 = r->x1 + crtc_split_width;
@@ -885,6 +888,7 @@ static void dpu_crtc_disable(struct drm_crtc 
*crtc)

struct drm_display_mode *mode;
struct drm_encoder *encoder;
struct msm_drm_private *priv;
+   struct dpu_kms *dpu_kms;
unsigned long flags;

if (!crtc || !crtc->dev || !crtc->dev->dev_private ||

!crtc->state) {
@@ -895,6 +899,7 @@ static void dpu_crtc_disable(struct drm_crtc 
*crtc)

cstate = to_dpu_crtc_state(crtc->state);
mode = >base.adjusted_mode;
priv = crtc->dev->dev_private;
+   dpu_kms = to_dpu_kms(priv->kms);

DRM_DEBUG_KMS("crtc%d\n", crtc->base.id);

@@ -953,6 +958,8 @@ static void dpu_crtc_disable(struct drm_crtc 
*crtc)

crtc->state->event = NULL;
spin_unlock_irqrestore(>dev->event_lock, flags);
}
+
+   dpu_rm_crtc_release(_kms->rm, crtc->state);
 }

 static void dpu_crtc_enable(struct drm_crtc *crtc,
@@ -1004,6 +1011,21 @@ struct plane_state {
u32 pipe_id;
 };

+static void _dpu_crtc_get_topology(
+   struct drm_crtc_state *crtc_state,
+   struct drm_display_mode *mode)
+{
+   struct dpu_crtc_state *dpu_cstate = to_dpu_crtc_state(crtc_state);
+
+   dpu_cstate->num_mixers = (mode->vdisplay > MAX_VDISPLAY_SPLIT) ? 2

: 1;

+
+   /**
+* encoder->atomic_check is invoked before crtc->atomic_check.
+* so dpu_cstate->num_intfs should have a non-zero value.
+*/
+   dpu_cstate->num_ctls = dpu_cstate->num_intfs;


Why do we need num_ctls? Can't we just use dpu_cstate->num_intfs 
directly?

Also,
you don't really need these in their own function, especially if 
num_ctls

goes
away.


Yes. I can live with just that. But since dpu_cstate maintains HW arrays
for each type, I thought it would be more readable if I could use
separate variables to track their counts instead of iterating over
ctl arrays over dpu_cstate->num_intfs and leaving comments that both
will be same for this version of hardware.

Also, the counts need not be the same for all the Snapdragon variants.

Thanks,
Jeykumar S.

+}
+
 static int dpu_crtc_atomic_check(struct drm_crtc *crtc,
struct drm_crtc_state *state)
 {
@@ -1014,6 +1036,8 @@ static int dpu_crtc_atomic_check(struct drm_crtc

*crtc,

const struct drm_plane_state *pstate;
struct drm_plane *plane;
struct drm_display_mode *mode;
+   struct msm_drm_private *priv;
+   struct dpu_kms *dpu_kms;

int cnt = 0, rc = 0, mixer_width, i, z_pos;

@@ -1039,6 +1063,9 @@ static int dpu_crtc_atomic_check(struct drm_crtc

*crtc,

goto end;
}

+   priv = crtc->dev->dev_private;
+   dpu_kms = to_dpu_kms(priv->kms);
+
mode = >adjusted_mode;
DPU_DEBUG("%s: check", dpu_crtc->name);

@@ -1229,6 +1256,10 @@ static int dpu_crtc_atomic_check(struct 
drm_crtc

*crtc,

}
}

+   _dpu_crtc_get_topology(state, mode);
+   if (drm_atomic_crtc_needs_modeset(state))
+   rc = dpu_rm_crtc_reserve(_kms->rm, state);
+
 end:
kfree(pstates);
return rc;
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c

b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c

index 5d501c8..ce66309 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
@@ -6

Re: [Freedreno] [PATCH 24/25] drm/msm/dpu: remove mutex locking for RM interfaces

2018-10-10 Thread Jeykumar Sankaran

On 2018-10-09 12:57, Sean Paul wrote:

On Mon, Oct 08, 2018 at 09:27:41PM -0700, Jeykumar Sankaran wrote:

Since HW reservations are happening through atomic_check
and all the display commits are catered by a single commit thread,
it is not necessary to protect the interfaces by a separate
mutex.

Signed-off-by: Jeykumar Sankaran 
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c | 24 
 drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h |  2 --
 2 files changed, 26 deletions(-)



/snip


diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h

b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h

index 8676fa5..9acbeba 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h
@@ -24,11 +24,9 @@
  * struct dpu_rm - DPU dynamic hardware resource manager
  * @hw_blks: array of lists of hardware resources present in the

system, one

  * list per type of hardware block
- * @rm_lock: resource manager mutex
  */
 struct dpu_rm {
struct list_head hw_blks[DPU_HW_BLK_MAX];


At this point, there's really not much point to even having the rm. 
It's

just
another level of indirection that IMO complicates the code. If you look
at the usage of hw_blks, the code is always looking at a specific type 
of

hw_blk, so the array is unnecessary.

dpu_kms could just keep a few arrays/lists of the hw types, and the 
crtc

and encoder
reserve functions can just go in crtc/encoder.

Sean

RM has been reduced to its current form to manage only LM/PP, CTL and 
interfaces.
Our eventual plan is to support all the advanced HW blocks and its 
features in
an upstream friendly way. When RM grows to manage all its subblocks, 
iteration
logic may get heavy since the chipset have HW chain restrictions on 
various hw blocks.

To provide room for the growth, I suggest keeping the allocation
helpers in a separate file. But I can see why you want to maintain the 
HW block lists

in the KMS.

Thanks,
Jeykumar S.

-   struct mutex rm_lock;
 };

 /**
--
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora

Forum,

a Linux Foundation Collaborative Project

___
Freedreno mailing list
Freedreno@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/freedreno


--
Jeykumar S
___
Freedreno mailing list
Freedreno@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/freedreno


Re: [Freedreno] [PATCH 01/25] drm/msm/dpu: fix hw ctl retrieval for mixer muxing

2018-10-09 Thread Jeykumar Sankaran

On 2018-10-09 11:07, Sean Paul wrote:

On Mon, Oct 08, 2018 at 09:27:18PM -0700, Jeykumar Sankaran wrote:

Layer mixer/pingpong block counts and hw ctl block counts
will not be same for all the topologies (e.g. layer
mixer muxing to single interface)

Use the encoder's split_role info to retrieve the
respective control path for programming.

Signed-off-by: Jeykumar Sankaran 
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 9 ++---
 1 file changed, 6 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c

b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c

index 96cdf06..d12f896 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
@@ -1060,6 +1060,7 @@ static void dpu_encoder_virt_mode_set(struct

drm_encoder *drm_enc,


for (i = 0; i < dpu_enc->num_phys_encs; i++) {
struct dpu_encoder_phys *phys = dpu_enc->phys_encs[i];
+   int ctl_index;

if (phys) {
if (!dpu_enc->hw_pp[i]) {
@@ -1068,14 +1069,16 @@ static void dpu_encoder_virt_mode_set(struct

drm_encoder *drm_enc,

return;
}

-   if (!hw_ctl[i]) {
+   ctl_index = phys->split_role == ENC_ROLE_SLAVE ? 1

: 0;

+


What if MAX_CHANNELS_PER_ENC isn't 2? Similarly, what if num_phys_encs 
>

MAX_CHANNELS_PER_ENC? It seems like there should be a more formal
relationship
between all of these verious values (num_of_h_tiles assumed to be <= 2 
as

well).
If one of them changes beyond the assumed bound, the rest of the driver
falls
over pretty hard.

MAX_CHANNELS_PER_ENC is set to 2 to represent HW limitation on the 
chipset as
we cannot gang up more than 2 LM chain to an interface. Supporting more 
than 2

might demand much larger changes than validating for boundaries.

num_phys_enc is the max no of phys encoders we create as we are looping 
through

num_of_h_tiles which cannot be more than priv->dsi array size.

So its very unlikely we would expect these loops to go out of bound!

Thanks,
Jeykumar S.



+   if (!hw_ctl[ctl_index]) {
DPU_ERROR_ENC(dpu_enc, "no ctl block

assigned"

-"at idx: %d\n", i);
+"at idx: %d\n", ctl_index);
return;


When you return on error here, should you give back the resources that
you've
already provisioned?


}

phys->hw_pp = dpu_enc->hw_pp[i];
-   phys->hw_ctl = hw_ctl[i];
+   phys->hw_ctl = hw_ctl[ctl_index];

phys->connector = conn->state->connector;
if (phys->ops.mode_set)
--
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora

Forum,

a Linux Foundation Collaborative Project

___
Freedreno mailing list
Freedreno@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/freedreno


--
Jeykumar S
___
Freedreno mailing list
Freedreno@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/freedreno


Re: [Freedreno] [PATCH 2/2] drm/msm: dpu: Remove checks from dpu_plane_destroy_state()

2018-10-09 Thread Jeykumar Sankaran

On 2018-10-04 11:09, Sean Paul wrote:

From: Sean Paul 

They're not needed.

Signed-off-by: Sean Paul 
---


Reviewed-by: Jeykumar Sankaran 


 drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 13 +
 1 file changed, 1 insertion(+), 12 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
index f549daf30fe6..4213e7a8e525 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
@@ -1193,19 +1193,8 @@ static void dpu_plane_destroy(struct drm_plane
*plane)
 static void dpu_plane_destroy_state(struct drm_plane *plane,
struct drm_plane_state *state)
 {
-   struct dpu_plane_state *pstate;
-
-   if (!plane || !state) {
-   DPU_ERROR("invalid arg(s), plane %d state %d\n",
-   plane != 0, state != 0);
-   return;
-   }
-
-   pstate = to_dpu_plane_state(state);
-
__drm_atomic_helper_plane_destroy_state(state);
-
-   kfree(pstate);
+   kfree(to_dpu_plane_state(state));
 }

 static struct drm_plane_state *


--
Jeykumar S
___
Freedreno mailing list
Freedreno@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/freedreno


Re: [Freedreno] [PATCH 1/2] drm/msm: dpu: Fix memory leak caused by dropped reference

2018-10-09 Thread Jeykumar Sankaran

On 2018-10-04 11:09, Sean Paul wrote:

From: Sean Paul 

We are currently leaking a drm_crtc_commit struct for every atomic
commit containing plane state. The dpu plane destroy function cleans up

dpu plane destroy -> dpu_plane_destroy_state

the fb reference manually, but fails to release the commit ref. As a
result, we just keep allocating drm_crtc_commits without ever freeing
them. Fortunately there's a helper function which will clean up all of
our mess at once, so use that.

Thanks to Doug Anderson for reporting the memory leak (and leaving
breadcrumbs from kmemleak!).

Reported-by: Doug Anderson 
Signed-off-by: Sean Paul 
---

With the nit addressed:

Reviewed-by: Jeykumar Sankaran 


 drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
index fc59a69aa832..f549daf30fe6 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
@@ -1203,9 +1203,7 @@ static void dpu_plane_destroy_state(struct 
drm_plane

*plane,

pstate = to_dpu_plane_state(state);

-   /* remove ref count for frame buffers */
-   if (state->fb)
-   drm_framebuffer_put(state->fb);
+   __drm_atomic_helper_plane_destroy_state(state);

kfree(pstate);
 }


--
Jeykumar S
___
Freedreno mailing list
Freedreno@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/freedreno


Re: [Freedreno] [PATCH 18/25] drm/msm/dpu: merge RM interface reservation helpers

2018-10-09 Thread Jeykumar Sankaran

On 2018-10-09 09:50, Jordan Crouse wrote:

On Mon, Oct 08, 2018 at 09:27:35PM -0700, Jeykumar Sankaran wrote:

we don't have enough reasons why the HW block looping's
cannot happen in the same function. So merge them.


looping's -> looping. So there are reasons one might break them out
but not interesting ones?


Not just yet. Once we start supporting different type of connectors such
as writeback & DP and the parsing logic for the respective type of
INTF grows up, we *may* want to split this up.

Thanks
Jeykumar S.


Signed-off-by: Jeykumar Sankaran 
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c | 63

++

 1 file changed, 26 insertions(+), 37 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c

b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c

index a79456c..bb59250 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c
@@ -435,52 +435,39 @@ static int _dpu_rm_reserve_ctls(
return 0;
 }

-static struct dpu_rm_hw_blk *_dpu_rm_reserve_intf(
-   struct dpu_rm *rm,
-   uint32_t id,
-   enum dpu_hw_blk_type type)
-{
-   struct dpu_rm_hw_blk *iter;
-   struct list_head *blk_list = >hw_blks[DPU_HW_BLK_INTF];
-
-   /* Find the block entry in the rm, and note the reservation */
-   list_for_each_entry(iter, blk_list, list)  {
-   if (iter->hw->id != id || iter->in_use)
-   continue;
-
-   trace_dpu_rm_reserve_intf(iter->hw->id, DPU_HW_BLK_INTF);
-
-   break;
-   }
-
-   /* Shouldn't happen since intfs are fixed at probe */
-   if (!iter) {
-   DPU_ERROR("couldn't find type %d id %d\n", type, id);
-   return NULL;
-   }
-
-   return iter;
-}
-
-static int _dpu_rm_reserve_intf_related_hw(
+static int _dpu_rm_reserve_intfs(
struct dpu_rm *rm,
struct dpu_crtc_state *dpu_cstate,
struct dpu_encoder_hw_resources *hw_res)
 {
-   struct dpu_rm_hw_blk *blk;
+   struct dpu_rm_hw_blk *iter;
+   struct list_head *blk_list = >hw_blks[DPU_HW_BLK_INTF];
int i, num_intfs = 0;

for (i = 0; i < ARRAY_SIZE(hw_res->intfs); i++) {
+   struct dpu_rm_hw_blk *intf_blk = NULL;
+
if (hw_res->intfs[i] == INTF_MODE_NONE)
continue;

-   blk = _dpu_rm_reserve_intf(rm, i + INTF_0,
-   DPU_HW_BLK_INTF);
-   if (!blk)
-   return -ENAVAIL;
+   list_for_each_entry(iter, blk_list, list)  {
+   if (iter->in_use)
+   continue;
+
+   if (iter->hw->id == (INTF_0 + i)) {
+   intf_blk = iter;
+   break;
+   }
+   }
+
+   if (!intf_blk)
+   return -EINVAL;

-   blk->in_use = true;
-   dpu_cstate->hw_intfs[num_intfs++] =

to_dpu_hw_intf(blk->hw);

+   intf_blk->in_use = true;
+   dpu_cstate->hw_intfs[num_intfs++] =
+

to_dpu_hw_intf(intf_blk->hw);

+
+   trace_dpu_rm_reserve_intf(intf_blk->hw->id,

DPU_HW_BLK_INTF);

}

dpu_cstate->num_intfs = num_intfs;
@@ -507,9 +494,11 @@ static int _dpu_rm_make_reservation(
return ret;
}

-   ret = _dpu_rm_reserve_intf_related_hw(rm, dpu_cstate,

>hw_res);

-   if (ret)
+   ret = _dpu_rm_reserve_intfs(rm, dpu_cstate, >hw_res);
+   if (ret) {
+   DPU_ERROR("unable to find appropriate INTF\n");


Since there is only once consumer of this function, I would move this
error
message down into the sub-function and provide more debug information -
like
which INTF wasn't found.


return ret;
+   }


And you don't need to return ret in this block - you can just drop out 
to

the
bottom.



return ret;
 }


--
Jeykumar S
___
Freedreno mailing list
Freedreno@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/freedreno


Re: [Freedreno] [PATCH v3] drm/msm: validate display and event threads

2018-10-09 Thread Jeykumar Sankaran

On 2018-10-09 07:24, Sean Paul wrote:

On Mon, Oct 08, 2018 at 04:55:45PM -0700, Jeykumar Sankaran wrote:

While creating display and event threads per crtc, validate
them before setting their priorities.

changes in v2:
- use dev_warn (Abhinav Kumar)
changes in v3:
- fix compilation error

Change-Id: I1dda805286df981c0f0e2b26507d089d3a21ff6c


No Change-Id's please!

FWIW, checkpatch.pl would have caught this and the nits I found below. 
It

might
be worth running patches through it before sending.


Signed-off-by: Jeykumar Sankaran 
---
 drivers/gpu/drm/msm/msm_drv.c | 49

++-

 1 file changed, 16 insertions(+), 33 deletions(-)

diff --git a/drivers/gpu/drm/msm/msm_drv.c

b/drivers/gpu/drm/msm/msm_drv.c

index 4904d0d..ab1b0a9 100644
--- a/drivers/gpu/drm/msm/msm_drv.c
+++ b/drivers/gpu/drm/msm/msm_drv.c
@@ -553,17 +553,18 @@ static int msm_drm_init(struct device *dev, 
struct

drm_driver *drv)

kthread_run(kthread_worker_fn,
>disp_thread[i].worker,
"crtc_commit:%d",

priv->disp_thread[i].crtc_id);

-   ret = sched_setscheduler(priv->disp_thread[i].thread,
-   SCHED_FIFO,

);

-   if (ret)
-   pr_warn("display thread priority update failed:

%d\n",

-

ret);

-
if (IS_ERR(priv->disp_thread[i].thread)) {
dev_err(dev, "failed to create crtc_commit

kthread\n");

priv->disp_thread[i].thread = NULL;
+   goto err_msm_uninit;
}

+   ret = sched_setscheduler(priv->disp_thread[i].thread,
+SCHED_FIFO, );
+   if (ret)
+   dev_warn(dev, "display thread priority update

failed: %d\n",

Although this is wrapped, the line still exceeds 80 chars. Perhaps:

dev_warn(dev, "disp_thread set priority failed
%d\n",
 ret);

I did run the checkpath.pl on this patch. Check patch usually will not 
complain

if the >80 exceeding line is the logging string.

https://01.org/linuxgraphics/gfx-docs/drm/process/coding-style.html#breaking-long-lines-and-strings

https://gitlab.freedesktop.org/seanpaul/dpu-staging/blob/for-next/scripts/checkpatch.pl#L3058

Anyway, rewording will be a good idea to avoid nits!


+   ret);
+
/* initialize event thread */
priv->event_thread[i].crtc_id = priv->crtcs[i]->base.id;
kthread_init_worker(>event_thread[i].worker);
@@ -572,6 +573,12 @@ static int msm_drm_init(struct device *dev, 
struct

drm_driver *drv)

kthread_run(kthread_worker_fn,
>event_thread[i].worker,
"crtc_event:%d",

priv->event_thread[i].crtc_id);

+   if (IS_ERR(priv->event_thread[i].thread)) {
+   dev_err(dev, "failed to create crtc_event

kthread\n");

+   priv->event_thread[i].thread = NULL;
+   goto err_msm_uninit;
+   }
+
/**
 * event thread should also run at same priority as

disp_thread

 * because it is handling frame_done events. A lower

priority
@@ -580,34 +587,10 @@ static int msm_drm_init(struct device *dev, 
struct

drm_driver *drv)

 * failure at crtc commit level.
 */
ret = sched_setscheduler(priv->event_thread[i].thread,
-   SCHED_FIFO,

);

+SCHED_FIFO, );
if (ret)
-   pr_warn("display event thread priority update

failed: %d\n",

-

ret);

-
-   if (IS_ERR(priv->event_thread[i].thread)) {
-   dev_err(dev, "failed to create crtc_event

kthread\n");

-   priv->event_thread[i].thread = NULL;
-   }
-
-   if ((!priv->disp_thread[i].thread) ||
-   !priv->event_thread[i].thread) {
-   /* clean up previously created threads if any */
-   for ( ; i >= 0; i--) {
-   if (priv->disp_thread[i].thread) {
-   kthread_stop(
-

priv->disp_thread[i].thread);

-   priv->disp_thread[i].thread =

NULL;

-   }
-
-   if (priv->event_thread[i].thread) {
-   kthread_stop(
-

priv->event_thread[i].thread);

[Freedreno] [PATCH 25/25] drm/msm/dpu: maintain RM init check internally

2018-10-08 Thread Jeykumar Sankaran
Move and maintain RM initialization flag checks
from KMS to RM.

Signed-off-by: Jeykumar Sankaran 
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c |  6 +-
 drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h |  1 -
 drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c  | 12 
 drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h  |  3 +++
 4 files changed, 16 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
index fdc89a8..59ccc46 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
@@ -668,9 +668,7 @@ static void _dpu_kms_hw_destroy(struct dpu_kms *dpu_kms)
}
}
 
-   if (dpu_kms->rm_init)
-   dpu_rm_destroy(_kms->rm);
-   dpu_kms->rm_init = false;
+   dpu_rm_destroy(_kms->rm);
 
if (dpu_kms->catalog)
dpu_hw_catalog_deinit(dpu_kms->catalog);
@@ -1085,8 +1083,6 @@ static int dpu_kms_hw_init(struct msm_kms *kms)
goto power_error;
}
 
-   dpu_kms->rm_init = true;
-
dpu_kms->hw_mdp = dpu_hw_mdptop_init(MDP_TOP, dpu_kms->mmio,
 dpu_kms->catalog);
if (IS_ERR_OR_NULL(dpu_kms->hw_mdp)) {
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h
index 66d4666..1fff795 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h
@@ -140,7 +140,6 @@ struct dpu_kms {
bool suspend_block;
 
struct dpu_rm rm;
-   bool rm_init;
 
struct dpu_hw_vbif *hw_vbif[VBIF_MAX];
struct dpu_hw_mdp *hw_mdp;
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c
index 9a63128..3452fb9 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c
@@ -65,6 +65,9 @@ int dpu_rm_destroy(struct dpu_rm *rm)
struct dpu_rm_hw_blk *hw_cur, *hw_nxt;
enum dpu_hw_blk_type type;
 
+   if (!rm->initialized)
+   return 0;
+
for (type = 0; type < DPU_HW_BLK_MAX; type++) {
list_for_each_entry_safe(hw_cur, hw_nxt, >hw_blks[type],
list) {
@@ -74,6 +77,8 @@ int dpu_rm_destroy(struct dpu_rm *rm)
}
}
 
+   rm->initialized = false;
+
return 0;
 }
 
@@ -141,6 +146,11 @@ int dpu_rm_init(struct dpu_rm *rm,
return -EINVAL;
}
 
+   if (rm->initialized) {
+   DPU_DEBUG("RM is already initialized\n");
+   return 0;
+   }
+
/* Clear, setup lists */
memset(rm, 0, sizeof(*rm));
 
@@ -196,6 +206,8 @@ int dpu_rm_init(struct dpu_rm *rm,
}
}
 
+   rm->initialized = true;
+
return 0;
 
 fail:
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h
index 9acbeba..74e5d58 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h
@@ -24,9 +24,12 @@
  * struct dpu_rm - DPU dynamic hardware resource manager
  * @hw_blks: array of lists of hardware resources present in the system, one
  * list per type of hardware block
+ * @initialized: True, when RM is initialized with hw block list.
+ *   False, otherwise
  */
 struct dpu_rm {
struct list_head hw_blks[DPU_HW_BLK_MAX];
+   bool initialized;
 };
 
 /**
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project

___
Freedreno mailing list
Freedreno@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/freedreno


[Freedreno] [PATCH 14/25] drm/msm/dpu: remove enc_id tagging for hw blocks

2018-10-08 Thread Jeykumar Sankaran
RM was using encoder id's to tag HW block's to reserve
and retrieve later for display pipeline. Now
that all the reserved HW blocks for a display are
maintained in its crtc state, no retrieval is needed.
This patch cleans up RM of encoder id tagging.

Signed-off-by: Jeykumar Sankaran 
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c| 90 +--
 drivers/gpu/drm/msm/disp/dpu1/dpu_trace.h | 28 --
 2 files changed, 36 insertions(+), 82 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c
index 303f1b3..a8461b8 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c
@@ -21,9 +21,6 @@
 #include "dpu_encoder.h"
 #include "dpu_trace.h"
 
-#define RESERVED_BY_OTHER(h, r)  \
-   ((h)->enc_id && (h)->enc_id != r)
-
 /**
  * struct dpu_rm_requirements - Reservation requirements parameter bundle
  * @topology:  selected topology for the display
@@ -38,12 +35,13 @@ struct dpu_rm_requirements {
 /**
  * struct dpu_rm_hw_blk - hardware block tracking list member
  * @list:  List head for list of all hardware blocks tracking items
- * @enc_id:Encoder id to which this blk is binded
+ * @in_use: True, if the hw block is assigned to a display pipeline.
+ * False, otherwise
  * @hw:Pointer to the hardware register access object for this 
block
  */
 struct dpu_rm_hw_blk {
struct list_head list;
-   uint32_t enc_id;
+   bool in_use;
struct dpu_hw_blk *hw;
 };
 
@@ -51,23 +49,19 @@ struct dpu_rm_hw_blk {
  * struct dpu_rm_hw_iter - iterator for use with dpu_rm
  * @hw: dpu_hw object requested, or NULL on failure
  * @blk: dpu_rm internal block representation. Clients ignore. Used as 
iterator.
- * @enc_id: DRM ID of Encoder client wishes to search for, or 0 for Any Encoder
  * @type: Hardware Block Type client wishes to search for.
  */
 struct dpu_rm_hw_iter {
struct dpu_hw_blk *hw;
struct dpu_rm_hw_blk *blk;
-   uint32_t enc_id;
enum dpu_hw_blk_type type;
 };
 
 static void _dpu_rm_init_hw_iter(
struct dpu_rm_hw_iter *iter,
-   uint32_t enc_id,
enum dpu_hw_blk_type type)
 {
memset(iter, 0, sizeof(*iter));
-   iter->enc_id = enc_id;
iter->type = type;
 }
 
@@ -91,16 +85,12 @@ static bool _dpu_rm_get_hw_locked(struct dpu_rm *rm, struct 
dpu_rm_hw_iter *i)
i->blk = list_prepare_entry(i->blk, blk_list, list);
 
list_for_each_entry_continue(i->blk, blk_list, list) {
-   if (i->enc_id == i->blk->enc_id) {
+   if (!i->blk->in_use) {
i->hw = i->blk->hw;
-   DPU_DEBUG("found type %d id %d for enc %d\n",
-   i->type, i->blk->hw->id, i->enc_id);
return true;
}
}
 
-   DPU_DEBUG("no match, type %d for enc %d\n", i->type, i->enc_id);
-
return false;
 }
 
@@ -196,7 +186,6 @@ static int _dpu_rm_hw_blk_create(
}
 
blk->hw = hw;
-   blk->enc_id = 0;
list_add_tail(>list, >hw_blks[type]);
 
return 0;
@@ -301,7 +290,6 @@ static bool _dpu_rm_needs_split_display(const struct 
msm_display_topology *top)
  * proposed use case requirements, incl. hardwired dependent blocks like
  * pingpong
  * @rm: dpu resource manager handle
- * @enc_id: encoder id requesting for allocation
  * @reqs: proposed use case requirements
  * @lm: proposed layer mixer, function checks if lm, and all other hardwired
  *  blocks connected to the lm (pp) is available and appropriate
@@ -313,7 +301,6 @@ static bool _dpu_rm_needs_split_display(const struct 
msm_display_topology *top)
  */
 static bool _dpu_rm_check_lm_and_get_connected_blks(
struct dpu_rm *rm,
-   uint32_t enc_id,
struct dpu_rm_requirements *reqs,
struct dpu_rm_hw_blk *lm,
struct dpu_rm_hw_blk **pp,
@@ -339,13 +326,7 @@ static bool _dpu_rm_check_lm_and_get_connected_blks(
}
}
 
-   /* Already reserved? */
-   if (RESERVED_BY_OTHER(lm, enc_id)) {
-   DPU_DEBUG("lm %d already reserved\n", lm_cfg->id);
-   return false;
-   }
-
-   _dpu_rm_init_hw_iter(, 0, DPU_HW_BLK_PINGPONG);
+   _dpu_rm_init_hw_iter(, DPU_HW_BLK_PINGPONG);
while (_dpu_rm_get_hw_locked(rm, )) {
if (iter.blk->hw->id == lm_cfg->pingpong) {
*pp = iter.blk;
@@ -358,16 +339,10 @@ static bool _dpu_rm_check_lm_and_get_connected_blks(
return false;
}
 
-   if (RESERVED_BY_OTHER(*pp, enc_id)) {
-   DPU_DEBUG("lm %d pp %d already reserved\n", lm->h

[Freedreno] [PATCH 17/25] drm/msm/dpu: remove RM HW block list iterator

2018-10-08 Thread Jeykumar Sankaran
Replacing with simpler linked list helper iterators.

Signed-off-by: Jeykumar Sankaran 
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c | 120 +
 1 file changed, 46 insertions(+), 74 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c
index 1234991..a79456c 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c
@@ -45,49 +45,6 @@ struct dpu_rm_hw_blk {
struct dpu_hw_blk *hw;
 };
 
-/**
- * struct dpu_rm_hw_iter - iterator for use with dpu_rm
- * @blk: dpu_rm internal block representation. Clients ignore. Used as 
iterator.
- * @type: Hardware Block Type client wishes to search for.
- */
-struct dpu_rm_hw_iter {
-   struct dpu_rm_hw_blk *blk;
-   enum dpu_hw_blk_type type;
-};
-
-static void _dpu_rm_init_hw_iter(
-   struct dpu_rm_hw_iter *iter,
-   enum dpu_hw_blk_type type)
-{
-   memset(iter, 0, sizeof(*iter));
-   iter->type = type;
-}
-
-static bool _dpu_rm_get_hw_locked(struct dpu_rm *rm, struct dpu_rm_hw_iter *i)
-{
-   struct list_head *blk_list;
-
-   if (!rm || !i || i->type >= DPU_HW_BLK_MAX) {
-   DPU_ERROR("invalid rm\n");
-   return false;
-   }
-
-   blk_list = >hw_blks[i->type];
-
-   if (i->blk && (>blk->list == blk_list)) {
-   DPU_DEBUG("attempt resume iteration past last\n");
-   return false;
-   }
-
-   i->blk = list_prepare_entry(i->blk, blk_list, list);
-
-   list_for_each_entry_continue(i->blk, blk_list, list)
-   if (!i->blk->in_use)
-   return true;
-
-   return false;
-}
-
 static void _dpu_rm_hw_destroy(enum dpu_hw_blk_type type, void *hw)
 {
switch (type) {
@@ -301,7 +258,8 @@ static bool _dpu_rm_check_lm_and_get_connected_blks(
struct dpu_rm_hw_blk *primary_lm)
 {
const struct dpu_lm_cfg *lm_cfg = to_dpu_hw_mixer(lm->hw)->cap;
-   struct dpu_rm_hw_iter iter;
+   struct dpu_rm_hw_blk *iter;
+   struct list_head *blk_list = >hw_blks[DPU_HW_BLK_PINGPONG];
 
*pp = NULL;
 
@@ -320,10 +278,12 @@ static bool _dpu_rm_check_lm_and_get_connected_blks(
}
}
 
-   _dpu_rm_init_hw_iter(, DPU_HW_BLK_PINGPONG);
-   while (_dpu_rm_get_hw_locked(rm, )) {
-   if (iter.blk->hw->id == lm_cfg->pingpong) {
-   *pp = iter.blk;
+   list_for_each_entry(iter, blk_list, list) {
+   if (iter->in_use)
+   continue;
+
+   if (iter->hw->id == lm_cfg->pingpong) {
+   *pp = iter;
break;
}
}
@@ -343,7 +303,8 @@ static int _dpu_rm_reserve_lms(struct dpu_rm *rm,
 {
struct dpu_rm_hw_blk *lm[MAX_BLOCKS];
struct dpu_rm_hw_blk *pp[MAX_BLOCKS];
-   struct dpu_rm_hw_iter iter_i, iter_j;
+   struct dpu_rm_hw_blk *iter_i, *iter_j;
+   struct list_head *blk_list = >hw_blks[DPU_HW_BLK_LM];
int lm_count = 0;
int i, rc = 0;
 
@@ -353,14 +314,18 @@ static int _dpu_rm_reserve_lms(struct dpu_rm *rm,
}
 
/* Find a primary mixer */
-   _dpu_rm_init_hw_iter(_i, DPU_HW_BLK_LM);
-   while (lm_count != reqs->topology.num_lm &&
-   _dpu_rm_get_hw_locked(rm, _i)) {
+   list_for_each_entry(iter_i, blk_list, list) {
+   if (iter_i->in_use)
+   continue;
+
+   if (lm_count == reqs->topology.num_lm)
+   break;
+
memset(, 0, sizeof(lm));
memset(, 0, sizeof(pp));
 
lm_count = 0;
-   lm[lm_count] = iter_i.blk;
+   lm[lm_count] = iter_i;
 
if (!_dpu_rm_check_lm_and_get_connected_blks(
rm, reqs, lm[lm_count],
@@ -370,19 +335,22 @@ static int _dpu_rm_reserve_lms(struct dpu_rm *rm,
++lm_count;
 
/* Valid primary mixer found, find matching peers */
-   _dpu_rm_init_hw_iter(_j, DPU_HW_BLK_LM);
+   list_for_each_entry(iter_j, blk_list, list) {
+   if (iter_j->in_use)
+   continue;
 
-   while (lm_count != reqs->topology.num_lm &&
-   _dpu_rm_get_hw_locked(rm, _j)) {
-   if (iter_i.blk == iter_j.blk)
+   if (lm_count == reqs->topology.num_lm)
+   break;
+
+   if (iter_i == iter_j)
continue;
 
if (!_dpu_rm_check_lm_and_get_connected_blks(
-   rm, reqs, iter_j.blk,
-   [lm_cou

[Freedreno] [PATCH 24/25] drm/msm/dpu: remove mutex locking for RM interfaces

2018-10-08 Thread Jeykumar Sankaran
Since HW reservations are happening through atomic_check
and all the display commits are catered by a single commit thread,
it is not necessary to protect the interfaces by a separate
mutex.

Signed-off-by: Jeykumar Sankaran 
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c | 24 
 drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h |  2 --
 2 files changed, 26 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c
index 34e09aa..9a63128 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c
@@ -74,8 +74,6 @@ int dpu_rm_destroy(struct dpu_rm *rm)
}
}
 
-   mutex_destroy(>rm_lock);
-
return 0;
 }
 
@@ -146,8 +144,6 @@ int dpu_rm_init(struct dpu_rm *rm,
/* Clear, setup lists */
memset(rm, 0, sizeof(*rm));
 
-   mutex_init(>rm_lock);
-
for (type = 0; type < DPU_HW_BLK_MAX; type++)
INIT_LIST_HEAD(>hw_blks[type]);
 
@@ -473,11 +469,7 @@ void dpu_rm_crtc_release(struct dpu_rm *rm, struct 
drm_crtc_state *crtc_state)
 {
struct dpu_crtc_state *dpu_cstate = to_dpu_crtc_state(crtc_state);
 
-   mutex_lock(>rm_lock);
-
_dpu_rm_crtc_release_reservation(rm, dpu_cstate);
-
-   mutex_unlock(>rm_lock);
 }
 
 void dpu_rm_encoder_release(struct dpu_rm *rm,
@@ -485,11 +477,7 @@ void dpu_rm_encoder_release(struct dpu_rm *rm,
 {
struct dpu_crtc_state *dpu_cstate = to_dpu_crtc_state(crtc_state);
 
-   mutex_lock(>rm_lock);
-
_dpu_rm_encoder_release_reservation(rm, dpu_cstate);
-
-   mutex_unlock(>rm_lock);
 }
 
 int dpu_rm_crtc_reserve(
@@ -506,8 +494,6 @@ int dpu_rm_crtc_reserve(
 
DRM_DEBUG_KMS("reserving hw for crtc %d\n", crtc_state->crtc->base.id);
 
-   mutex_lock(>rm_lock);
-
ret = _dpu_rm_reserve_lms(rm, dpu_cstate);
if (ret) {
DPU_ERROR("unable to find appropriate mixers\n");
@@ -520,15 +506,11 @@ int dpu_rm_crtc_reserve(
goto cleanup_on_fail;
}
 
-   mutex_unlock(>rm_lock);
-
return ret;
 
 cleanup_on_fail:
_dpu_rm_crtc_release_reservation(rm, dpu_cstate);
 
-   mutex_unlock(>rm_lock);
-
return ret;
 }
 
@@ -547,8 +529,6 @@ int dpu_rm_encoder_reserve(
 
DRM_DEBUG_KMS("reserving hw for enc %d\n", enc->base.id);
 
-   mutex_lock(>rm_lock);
-
dpu_encoder_get_hw_resources(enc, _res);
 
ret = _dpu_rm_reserve_intfs(rm, dpu_cstate, _res);
@@ -557,14 +537,10 @@ int dpu_rm_encoder_reserve(
goto cleanup_on_fail;
}
 
-   mutex_unlock(>rm_lock);
-
return ret;
 
 cleanup_on_fail:
_dpu_rm_encoder_release_reservation(rm, dpu_cstate);
 
-   mutex_unlock(>rm_lock);
-
return ret;
 }
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h
index 8676fa5..9acbeba 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h
@@ -24,11 +24,9 @@
  * struct dpu_rm - DPU dynamic hardware resource manager
  * @hw_blks: array of lists of hardware resources present in the system, one
  * list per type of hardware block
- * @rm_lock: resource manager mutex
  */
 struct dpu_rm {
struct list_head hw_blks[DPU_HW_BLK_MAX];
-   struct mutex rm_lock;
 };
 
 /**
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project

___
Freedreno mailing list
Freedreno@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/freedreno


[Freedreno] [PATCH 18/25] drm/msm/dpu: merge RM interface reservation helpers

2018-10-08 Thread Jeykumar Sankaran
we don't have enough reasons why the HW block looping's
cannot happen in the same function. So merge them.

Signed-off-by: Jeykumar Sankaran 
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c | 63 ++
 1 file changed, 26 insertions(+), 37 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c
index a79456c..bb59250 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c
@@ -435,52 +435,39 @@ static int _dpu_rm_reserve_ctls(
return 0;
 }
 
-static struct dpu_rm_hw_blk *_dpu_rm_reserve_intf(
-   struct dpu_rm *rm,
-   uint32_t id,
-   enum dpu_hw_blk_type type)
-{
-   struct dpu_rm_hw_blk *iter;
-   struct list_head *blk_list = >hw_blks[DPU_HW_BLK_INTF];
-
-   /* Find the block entry in the rm, and note the reservation */
-   list_for_each_entry(iter, blk_list, list)  {
-   if (iter->hw->id != id || iter->in_use)
-   continue;
-
-   trace_dpu_rm_reserve_intf(iter->hw->id, DPU_HW_BLK_INTF);
-
-   break;
-   }
-
-   /* Shouldn't happen since intfs are fixed at probe */
-   if (!iter) {
-   DPU_ERROR("couldn't find type %d id %d\n", type, id);
-   return NULL;
-   }
-
-   return iter;
-}
-
-static int _dpu_rm_reserve_intf_related_hw(
+static int _dpu_rm_reserve_intfs(
struct dpu_rm *rm,
struct dpu_crtc_state *dpu_cstate,
struct dpu_encoder_hw_resources *hw_res)
 {
-   struct dpu_rm_hw_blk *blk;
+   struct dpu_rm_hw_blk *iter;
+   struct list_head *blk_list = >hw_blks[DPU_HW_BLK_INTF];
int i, num_intfs = 0;
 
for (i = 0; i < ARRAY_SIZE(hw_res->intfs); i++) {
+   struct dpu_rm_hw_blk *intf_blk = NULL;
+
if (hw_res->intfs[i] == INTF_MODE_NONE)
continue;
 
-   blk = _dpu_rm_reserve_intf(rm, i + INTF_0,
-   DPU_HW_BLK_INTF);
-   if (!blk)
-   return -ENAVAIL;
+   list_for_each_entry(iter, blk_list, list)  {
+   if (iter->in_use)
+   continue;
+
+   if (iter->hw->id == (INTF_0 + i)) {
+   intf_blk = iter;
+   break;
+   }
+   }
+
+   if (!intf_blk)
+   return -EINVAL;
 
-   blk->in_use = true;
-   dpu_cstate->hw_intfs[num_intfs++] = to_dpu_hw_intf(blk->hw);
+   intf_blk->in_use = true;
+   dpu_cstate->hw_intfs[num_intfs++] =
+   to_dpu_hw_intf(intf_blk->hw);
+
+   trace_dpu_rm_reserve_intf(intf_blk->hw->id, DPU_HW_BLK_INTF);
}
 
dpu_cstate->num_intfs = num_intfs;
@@ -507,9 +494,11 @@ static int _dpu_rm_make_reservation(
return ret;
}
 
-   ret = _dpu_rm_reserve_intf_related_hw(rm, dpu_cstate, >hw_res);
-   if (ret)
+   ret = _dpu_rm_reserve_intfs(rm, dpu_cstate, >hw_res);
+   if (ret) {
+   DPU_ERROR("unable to find appropriate INTF\n");
return ret;
+   }
 
return ret;
 }
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project

___
Freedreno mailing list
Freedreno@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/freedreno


[Freedreno] [PATCH 15/25] drm/msm/dpu: avoid redundant hw blk reference

2018-10-08 Thread Jeykumar Sankaran
Get rid of hw block pointer in RM iter as we can
access the same through dpu_hw_blk.

Signed-off-by: Jeykumar Sankaran 
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c | 10 ++
 1 file changed, 2 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c
index a8461b8..3a92a3e 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c
@@ -47,12 +47,10 @@ struct dpu_rm_hw_blk {
 
 /**
  * struct dpu_rm_hw_iter - iterator for use with dpu_rm
- * @hw: dpu_hw object requested, or NULL on failure
  * @blk: dpu_rm internal block representation. Clients ignore. Used as 
iterator.
  * @type: Hardware Block Type client wishes to search for.
  */
 struct dpu_rm_hw_iter {
-   struct dpu_hw_blk *hw;
struct dpu_rm_hw_blk *blk;
enum dpu_hw_blk_type type;
 };
@@ -74,7 +72,6 @@ static bool _dpu_rm_get_hw_locked(struct dpu_rm *rm, struct 
dpu_rm_hw_iter *i)
return false;
}
 
-   i->hw = NULL;
blk_list = >hw_blks[i->type];
 
if (i->blk && (>blk->list == blk_list)) {
@@ -84,12 +81,9 @@ static bool _dpu_rm_get_hw_locked(struct dpu_rm *rm, struct 
dpu_rm_hw_iter *i)
 
i->blk = list_prepare_entry(i->blk, blk_list, list);
 
-   list_for_each_entry_continue(i->blk, blk_list, list) {
-   if (!i->blk->in_use) {
-   i->hw = i->blk->hw;
+   list_for_each_entry_continue(i->blk, blk_list, list)
+   if (!i->blk->in_use)
return true;
-   }
-   }
 
return false;
 }
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project

___
Freedreno mailing list
Freedreno@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/freedreno


[Freedreno] [PATCH 12/25] drm/msm/dpu: remove mode_set_complete

2018-10-08 Thread Jeykumar Sankaran
This flag was introduced as a fix to notify modeset complete
when hw reservations were happening in both atomic_check
and atomic_commit paths. Now that we are reserving only in
atomic_check, we can get rid of this flag.

Signed-off-by: Jeykumar Sankaran 
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 19 +++
 1 file changed, 3 insertions(+), 16 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
index dd482ca..468b8fd0 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
@@ -167,7 +167,6 @@ enum dpu_enc_rc_states {
  * clks and resources after IDLE_TIMEOUT time.
  * @vsync_event_work:  worker to handle vsync event for autorefresh
  * @topology:   topology of the display
- * @mode_set_complete:  flag to indicate modeset completion
  * @idle_timeout:  idle timeout duration in milliseconds
  */
 struct dpu_encoder_virt {
@@ -204,7 +203,6 @@ struct dpu_encoder_virt {
struct kthread_delayed_work delayed_off_work;
struct kthread_work vsync_event_work;
struct msm_display_topology topology;
-   bool mode_set_complete;
 
u32 idle_timeout;
 };
@@ -636,18 +634,9 @@ static int dpu_encoder_virt_atomic_check(
 
topology = dpu_encoder_get_topology(dpu_enc, dpu_kms, adj_mode);
 
-   if (!ret) {
-   /*
-* Avoid reserving resources when mode set is pending. Topology
-* info may not be available to complete reservation.
-*/
-   if (drm_atomic_crtc_needs_modeset(crtc_state)
-   && dpu_enc->mode_set_complete) {
-   ret = dpu_rm_reserve(_kms->rm, drm_enc, crtc_state,
-topology, false);
-   dpu_enc->mode_set_complete = false;
-   }
-   }
+   if (!ret && drm_atomic_crtc_needs_modeset(crtc_state))
+   ret = dpu_rm_reserve(_kms->rm, drm_enc, crtc_state,
+topology, false);
 
if (!ret)
drm_mode_set_crtcinfo(adj_mode, 0);
@@ -1060,8 +1049,6 @@ static void dpu_encoder_virt_mode_set(struct drm_encoder 
*drm_enc,
phys->ops.mode_set(phys, mode, adj_mode);
}
}
-
-   dpu_enc->mode_set_complete = true;
 }
 
 static void _dpu_encoder_virt_enable_helper(struct drm_encoder *drm_enc)
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project

___
Freedreno mailing list
Freedreno@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/freedreno


[Freedreno] [PATCH 20/25] drm/msm/dpu: refine layer mixer reservations

2018-10-08 Thread Jeykumar Sankaran
Validate layer mixer pairs for compatibility before retrieving
the connected pingpong blocks.

Signed-off-by: Jeykumar Sankaran 
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c | 61 ++
 1 file changed, 17 insertions(+), 44 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c
index 85a0fe2..f794d13 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c
@@ -235,61 +235,32 @@ static bool _dpu_rm_needs_split_display(const struct 
dpu_crtc_state *dpu_cstate)
 }
 
 /**
- * _dpu_rm_check_lm_and_get_connected_blks - check if proposed layer mixer 
meets
- * proposed use case requirements, incl. hardwired dependent blocks like
- * pingpong
+ * _dpu_rm_get_connected_pp - retrieve hardwired pingpong block
  * @rm: dpu resource manager handle
  * @lm: proposed layer mixer, function checks if lm, and all other hardwired
- *  blocks connected to the lm (pp) is available and appropriate
- * @pp: output parameter, pingpong block attached to the layer mixer.
- *  NULL if pp was not available, or not matching requirements.
- * @primary_lm: if non-null, this function check if lm is compatible primary_lm
- *  as well as satisfying all other requirements
- * @Return: true if lm matches all requirements, false otherwise
+ * @Return: handle to ping pong rm block
  */
-static bool _dpu_rm_check_lm_and_get_connected_blks(
-   struct dpu_rm *rm,
-   struct dpu_rm_hw_blk *lm,
-   struct dpu_rm_hw_blk **pp,
-   struct dpu_rm_hw_blk *primary_lm)
+static struct dpu_rm_hw_blk *
+_dpu_rm_get_connected_pp(struct dpu_rm *rm, struct dpu_rm_hw_blk *lm)
 {
const struct dpu_lm_cfg *lm_cfg = to_dpu_hw_mixer(lm->hw)->cap;
-   struct dpu_rm_hw_blk *iter;
struct list_head *blk_list = >hw_blks[DPU_HW_BLK_PINGPONG];
-
-   *pp = NULL;
-
-   DPU_DEBUG("check lm %d pp %d\n",
-  lm_cfg->id, lm_cfg->pingpong);
-
-   /* Check if this layer mixer is a peer of the proposed primary LM */
-   if (primary_lm) {
-   const struct dpu_lm_cfg *prim_lm_cfg =
-   to_dpu_hw_mixer(primary_lm->hw)->cap;
-
-   if (!test_bit(lm_cfg->id, _lm_cfg->lm_pair_mask)) {
-   DPU_DEBUG("lm %d not peer of lm %d\n", lm_cfg->id,
-   prim_lm_cfg->id);
-   return false;
-   }
-   }
+   struct dpu_rm_hw_blk *iter, *pp = NULL;
 
list_for_each_entry(iter, blk_list, list) {
if (iter->in_use)
continue;
 
if (iter->hw->id == lm_cfg->pingpong) {
-   *pp = iter;
+   pp = iter;
break;
}
}
 
-   if (!*pp) {
-   DPU_ERROR("failed to get pp on lm %d\n", lm_cfg->pingpong);
-   return false;
-   }
+   if (!pp)
+   DPU_ERROR("failed to get pp on lm %d\n", lm->hw->id);
 
-   return true;
+   return pp;
 }
 
 static int _dpu_rm_reserve_lms(struct dpu_rm *rm,
@@ -315,15 +286,15 @@ static int _dpu_rm_reserve_lms(struct dpu_rm *rm,
 
lm_count = 0;
lm[lm_count] = iter_i;
-
-   if (!_dpu_rm_check_lm_and_get_connected_blks(
-   rm, lm[lm_count], [lm_count], NULL))
-   continue;
+   pp[lm_count] = _dpu_rm_get_connected_pp(rm, iter_i);
 
++lm_count;
 
/* Valid primary mixer found, find matching peers */
list_for_each_entry(iter_j, blk_list, list) {
+   const struct dpu_lm_cfg *prim_lm_cfg =
+   to_dpu_hw_mixer(iter_i->hw)->cap;
+
if (iter_j->in_use)
continue;
 
@@ -333,11 +304,13 @@ static int _dpu_rm_reserve_lms(struct dpu_rm *rm,
if (iter_i == iter_j)
continue;
 
-   if (!_dpu_rm_check_lm_and_get_connected_blks(
-   rm, iter_j, [lm_count], iter_i))
+   if (!test_bit(iter_j->hw->id,
+ _lm_cfg->lm_pair_mask))
continue;
 
lm[lm_count] = iter_j;
+   pp[lm_count] = _dpu_rm_get_connected_pp(rm, iter_j);
+
++lm_count;
}
}
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project

___
Freedreno mailing list
Freedreno@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/freedreno


[Freedreno] [PATCH 19/25] drm/msm/dpu: remove msm_display_topology

2018-10-08 Thread Jeykumar Sankaran
msm_display_topology was used for providing HW block
layout of the pipeline for a specific display topology.
We already got rid of its usage from DSI driver. In DPU,
it was used to provide the details on HW blocks while
reserving resources. Since we can use the crtc state used
for storing the assigned HW blocks for providing the info,
we can conveniently get rid of this structure.

Signed-off-by: Jeykumar Sankaran 
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 29 --
 drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c  | 82 -
 drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h  |  4 +-
 drivers/gpu/drm/msm/msm_drv.h   | 12 -
 4 files changed, 33 insertions(+), 94 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
index dd17528..5d501c8 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
@@ -166,7 +166,6 @@ enum dpu_enc_rc_states {
  * @delayed_off_work:  delayed worker to schedule disabling of
  * clks and resources after IDLE_TIMEOUT time.
  * @vsync_event_work:  worker to handle vsync event for autorefresh
- * @topology:   topology of the display
  * @idle_timeout:  idle timeout duration in milliseconds
  */
 struct dpu_encoder_virt {
@@ -202,7 +201,6 @@ struct dpu_encoder_virt {
enum dpu_enc_rc_states rc_state;
struct kthread_delayed_work delayed_off_work;
struct kthread_work vsync_event_work;
-   struct msm_display_topology topology;
 
u32 idle_timeout;
 };
@@ -557,25 +555,19 @@ static void _dpu_encoder_adjust_mode(struct drm_connector 
*connector,
}
 }
 
-static struct msm_display_topology dpu_encoder_get_topology(
+static void _dpu_encoder_get_topology(
struct dpu_encoder_virt *dpu_enc,
-   struct dpu_kms *dpu_kms,
+   struct drm_crtc_state *crtc_state,
struct drm_display_mode *mode)
 {
-   struct msm_display_topology topology;
-   int i, intf_count = 0;
-
-   for (i = 0; i < MAX_PHYS_ENCODERS_PER_VIRTUAL; i++)
-   if (dpu_enc->phys_encs[i])
-   intf_count++;
+   struct dpu_crtc_state *dpu_cstate = to_dpu_crtc_state(crtc_state);
 
/* User split topology for width > 1080 */
-   topology.num_lm = (mode->vdisplay > MAX_VDISPLAY_SPLIT) ? 2 : 1;
-   topology.num_enc = 0;
-   topology.num_intf = intf_count;
-
-   return topology;
+   dpu_cstate->num_mixers = (mode->vdisplay > MAX_VDISPLAY_SPLIT) ? 2 : 1;
+   dpu_cstate->num_ctls = dpu_enc->num_phys_encs;
+   dpu_cstate->num_intfs = dpu_enc->num_phys_encs;
 }
+
 static int dpu_encoder_virt_atomic_check(
struct drm_encoder *drm_enc,
struct drm_crtc_state *crtc_state,
@@ -586,7 +578,6 @@ static int dpu_encoder_virt_atomic_check(
struct dpu_kms *dpu_kms;
const struct drm_display_mode *mode;
struct drm_display_mode *adj_mode;
-   struct msm_display_topology topology;
int i = 0;
int ret = 0;
 
@@ -632,11 +623,9 @@ static int dpu_encoder_virt_atomic_check(
}
}
 
-   topology = dpu_encoder_get_topology(dpu_enc, dpu_kms, adj_mode);
-
+   _dpu_encoder_get_topology(dpu_enc, crtc_state, adj_mode);
if (!ret && drm_atomic_crtc_needs_modeset(crtc_state))
-   ret = dpu_rm_reserve(_kms->rm, drm_enc, crtc_state,
-topology);
+   ret = dpu_rm_reserve(_kms->rm, drm_enc, crtc_state);
 
if (!ret)
drm_mode_set_crtcinfo(adj_mode, 0);
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c
index bb59250..85a0fe2 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c
@@ -23,11 +23,9 @@
 
 /**
  * struct dpu_rm_requirements - Reservation requirements parameter bundle
- * @topology:  selected topology for the display
  * @hw_res:   Hardware resources required as reported by the encoders
  */
 struct dpu_rm_requirements {
-   struct msm_display_topology topology;
struct dpu_encoder_hw_resources hw_res;
 };
 
@@ -231,9 +229,9 @@ int dpu_rm_init(struct dpu_rm *rm,
return rc;
 }
 
-static bool _dpu_rm_needs_split_display(const struct msm_display_topology *top)
+static bool _dpu_rm_needs_split_display(const struct dpu_crtc_state 
*dpu_cstate)
 {
-   return top->num_intf > 1;
+   return dpu_cstate->num_intfs > 1;
 }
 
 /**
@@ -241,7 +239,6 @@ static bool _dpu_rm_needs_split_display(const struct 
msm_display_topology *top)
  * proposed use case requirements, incl. hardwired dependent blocks like
  * pingpong
  * @rm: dpu resource manager handle
- * @reqs: proposed use ca

[Freedreno] [PATCH 22/25] drm/msm/dpu: make crtc and encoder specific HW reservation

2018-10-08 Thread Jeykumar Sankaran
Instead of letting encoder make a centralized reservation for
all of its display DRM components, this path splits the
responsibility between CRTC and Encoder, each requesting
RM for the HW mapping of its own domain.

Signed-off-by: Jeykumar Sankaran 
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c| 31 +
 drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 14 ++
 drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c  | 69 -
 drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h  | 36 +++
 4 files changed, 119 insertions(+), 31 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
index 0625f56..0536b8a 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
@@ -47,6 +47,8 @@
 #define LEFT_MIXER 0
 #define RIGHT_MIXER 1
 
+#define MAX_VDISPLAY_SPLIT 1080
+
 static inline int _dpu_crtc_get_mixer_width(struct dpu_crtc_state *cstate,
struct drm_display_mode *mode)
 {
@@ -448,6 +450,7 @@ static void _dpu_crtc_setup_lm_bounds(struct drm_crtc *crtc,
 
for (i = 0; i < cstate->num_mixers; i++) {
struct drm_rect *r = >lm_bounds[i];
+
r->x1 = crtc_split_width * i;
r->y1 = 0;
r->x2 = r->x1 + crtc_split_width;
@@ -885,6 +888,7 @@ static void dpu_crtc_disable(struct drm_crtc *crtc)
struct drm_display_mode *mode;
struct drm_encoder *encoder;
struct msm_drm_private *priv;
+   struct dpu_kms *dpu_kms;
unsigned long flags;
 
if (!crtc || !crtc->dev || !crtc->dev->dev_private || !crtc->state) {
@@ -895,6 +899,7 @@ static void dpu_crtc_disable(struct drm_crtc *crtc)
cstate = to_dpu_crtc_state(crtc->state);
mode = >base.adjusted_mode;
priv = crtc->dev->dev_private;
+   dpu_kms = to_dpu_kms(priv->kms);
 
DRM_DEBUG_KMS("crtc%d\n", crtc->base.id);
 
@@ -953,6 +958,8 @@ static void dpu_crtc_disable(struct drm_crtc *crtc)
crtc->state->event = NULL;
spin_unlock_irqrestore(>dev->event_lock, flags);
}
+
+   dpu_rm_crtc_release(_kms->rm, crtc->state);
 }
 
 static void dpu_crtc_enable(struct drm_crtc *crtc,
@@ -1004,6 +1011,21 @@ struct plane_state {
u32 pipe_id;
 };
 
+static void _dpu_crtc_get_topology(
+   struct drm_crtc_state *crtc_state,
+   struct drm_display_mode *mode)
+{
+   struct dpu_crtc_state *dpu_cstate = to_dpu_crtc_state(crtc_state);
+
+   dpu_cstate->num_mixers = (mode->vdisplay > MAX_VDISPLAY_SPLIT) ? 2 : 1;
+
+   /**
+* encoder->atomic_check is invoked before crtc->atomic_check.
+* so dpu_cstate->num_intfs should have a non-zero value.
+*/
+   dpu_cstate->num_ctls = dpu_cstate->num_intfs;
+}
+
 static int dpu_crtc_atomic_check(struct drm_crtc *crtc,
struct drm_crtc_state *state)
 {
@@ -1014,6 +1036,8 @@ static int dpu_crtc_atomic_check(struct drm_crtc *crtc,
const struct drm_plane_state *pstate;
struct drm_plane *plane;
struct drm_display_mode *mode;
+   struct msm_drm_private *priv;
+   struct dpu_kms *dpu_kms;
 
int cnt = 0, rc = 0, mixer_width, i, z_pos;
 
@@ -1039,6 +1063,9 @@ static int dpu_crtc_atomic_check(struct drm_crtc *crtc,
goto end;
}
 
+   priv = crtc->dev->dev_private;
+   dpu_kms = to_dpu_kms(priv->kms);
+
mode = >adjusted_mode;
DPU_DEBUG("%s: check", dpu_crtc->name);
 
@@ -1229,6 +1256,10 @@ static int dpu_crtc_atomic_check(struct drm_crtc *crtc,
}
}
 
+   _dpu_crtc_get_topology(state, mode);
+   if (drm_atomic_crtc_needs_modeset(state))
+   rc = dpu_rm_crtc_reserve(_kms->rm, state);
+
 end:
kfree(pstates);
return rc;
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
index 5d501c8..ce66309 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
@@ -67,8 +67,6 @@
 
 #define IDLE_SHORT_TIMEOUT 1
 
-#define MAX_VDISPLAY_SPLIT 1080
-
 /**
  * enum dpu_enc_rc_events - events for resource control state machine
  * @DPU_ENC_RC_EVENT_KICKOFF:
@@ -557,14 +555,10 @@ static void _dpu_encoder_adjust_mode(struct drm_connector 
*connector,
 
 static void _dpu_encoder_get_topology(
struct dpu_encoder_virt *dpu_enc,
-   struct drm_crtc_state *crtc_state,
-   struct drm_display_mode *mode)
+   struct drm_crtc_state *crtc_state)
 {
struct dpu_crtc_state *dpu_cstate = to_dpu_crtc_state(crtc_state);
 
-   /* User split topology for width > 1080 */
-   dpu_cstate-

[Freedreno] [PATCH 21/25] drm/msm/dpu: merge RM reservation helpers

2018-10-08 Thread Jeykumar Sankaran
We cleaned up RM reserve api's enough to get rid of
most of its unwanted checks and release handlers. To
improve further the readability of the function, merging
down the individual HW type allocators into one function.

Signed-off-by: Jeykumar Sankaran 
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c | 73 +++---
 1 file changed, 24 insertions(+), 49 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c
index f794d13..5304597 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c
@@ -22,15 +22,6 @@
 #include "dpu_trace.h"
 
 /**
- * struct dpu_rm_requirements - Reservation requirements parameter bundle
- * @hw_res:   Hardware resources required as reported by the encoders
- */
-struct dpu_rm_requirements {
-   struct dpu_encoder_hw_resources hw_res;
-};
-
-
-/**
  * struct dpu_rm_hw_blk - hardware block tracking list member
  * @list:  List head for list of all hardware blocks tracking items
  * @in_use: True, if the hw block is assigned to a display pipeline.
@@ -427,41 +418,6 @@ static int _dpu_rm_reserve_intfs(
return 0;
 }
 
-static int _dpu_rm_make_reservation(
-   struct dpu_rm *rm,
-   struct dpu_crtc_state *dpu_cstate,
-   struct dpu_rm_requirements *reqs)
-{
-   int ret;
-
-   ret = _dpu_rm_reserve_lms(rm, dpu_cstate);
-   if (ret) {
-   DPU_ERROR("unable to find appropriate mixers\n");
-   return ret;
-   }
-
-   ret = _dpu_rm_reserve_ctls(rm, dpu_cstate);
-   if (ret) {
-   DPU_ERROR("unable to find appropriate CTL\n");
-   return ret;
-   }
-
-   ret = _dpu_rm_reserve_intfs(rm, dpu_cstate, >hw_res);
-   if (ret) {
-   DPU_ERROR("unable to find appropriate INTF\n");
-   return ret;
-   }
-
-   return ret;
-}
-
-static void _dpu_rm_populate_requirements(
-   struct drm_encoder *enc,
-   struct dpu_rm_requirements *reqs)
-{
-   dpu_encoder_get_hw_resources(enc, >hw_res);
-}
-
 static int _dpu_rm_release_hw(struct dpu_rm *rm, enum dpu_hw_blk_type type,
  int id)
 {
@@ -535,7 +491,7 @@ int dpu_rm_reserve(
struct drm_encoder *enc,
struct drm_crtc_state *crtc_state)
 {
-   struct dpu_rm_requirements reqs;
+   struct dpu_encoder_hw_resources hw_res;
struct dpu_crtc_state *dpu_cstate = to_dpu_crtc_state(crtc_state);
int ret;
 
@@ -548,14 +504,33 @@ int dpu_rm_reserve(
 
mutex_lock(>rm_lock);
 
-   _dpu_rm_populate_requirements(enc, );
+   dpu_encoder_get_hw_resources(enc, _res);
 
-   ret = _dpu_rm_make_reservation(rm, dpu_cstate, );
+   ret = _dpu_rm_reserve_lms(rm, dpu_cstate);
if (ret) {
-   DPU_ERROR("failed to reserve hw resources: %d\n", ret);
-   _dpu_rm_release_reservation(rm, dpu_cstate);
+   DPU_ERROR("unable to find appropriate mixers\n");
+   goto cleanup_on_fail;
}
 
+   ret = _dpu_rm_reserve_ctls(rm, dpu_cstate);
+   if (ret) {
+   DPU_ERROR("unable to find appropriate CTL\n");
+   goto cleanup_on_fail;
+   }
+
+   ret = _dpu_rm_reserve_intfs(rm, dpu_cstate, _res);
+   if (ret) {
+   DPU_ERROR("unable to find appropriate INTF\n");
+   goto cleanup_on_fail;
+   }
+
+   mutex_unlock(>rm_lock);
+
+   return ret;
+
+cleanup_on_fail:
+   _dpu_rm_release_reservation(rm, dpu_cstate);
+
mutex_unlock(>rm_lock);
 
return ret;
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project

___
Freedreno mailing list
Freedreno@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/freedreno


[Freedreno] [PATCH 16/25] drm/msm/dpu: clean up test_only flag for RM reservation

2018-10-08 Thread Jeykumar Sankaran
Encoder uses test_only flag to differentiate RM reservations
invoked from atomic check and atomic_commit phases.
After reserving the HW blocks, if test_only was set, RM
releases the reservation. Retains them if not. Since we
got rid of RM reserve call from atomic_commit path, get rid
of this flag.

Signed-off-by: Jeykumar Sankaran 
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c |  2 +-
 drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c  | 13 +++--
 drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h  |  4 +---
 3 files changed, 5 insertions(+), 14 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
index 468b8fd0..dd17528 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
@@ -636,7 +636,7 @@ static int dpu_encoder_virt_atomic_check(
 
if (!ret && drm_atomic_crtc_needs_modeset(crtc_state))
ret = dpu_rm_reserve(_kms->rm, drm_enc, crtc_state,
-topology, false);
+topology);
 
if (!ret)
drm_mode_set_crtcinfo(adj_mode, 0);
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c
index 3a92a3e..1234991 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c
@@ -631,8 +631,7 @@ int dpu_rm_reserve(
struct dpu_rm *rm,
struct drm_encoder *enc,
struct drm_crtc_state *crtc_state,
-   struct msm_display_topology topology,
-   bool test_only)
+   struct msm_display_topology topology)
 {
struct dpu_rm_requirements reqs;
struct dpu_crtc_state *dpu_cstate = to_dpu_crtc_state(crtc_state);
@@ -642,8 +641,8 @@ int dpu_rm_reserve(
if (!drm_atomic_crtc_needs_modeset(crtc_state))
return 0;
 
-   DRM_DEBUG_KMS("reserving hw for enc %d crtc %d test_only %d\n",
- enc->base.id, crtc_state->crtc->base.id, test_only);
+   DRM_DEBUG_KMS("reserving hw for enc %d crtc %d\n",
+ enc->base.id, crtc_state->crtc->base.id);
 
mutex_lock(>rm_lock);
 
@@ -657,13 +656,7 @@ int dpu_rm_reserve(
if (ret) {
DPU_ERROR("failed to reserve hw resources: %d\n", ret);
_dpu_rm_release_reservation(rm, dpu_cstate);
-   } else if (test_only) {
-/* test_only: test the reservation and then undo */
-   DPU_DEBUG("test_only: discard test [enc: %d]\n",
-   enc->base.id);
-   _dpu_rm_release_reservation(rm, dpu_cstate);
}
-
 end:
mutex_unlock(>rm_lock);
 
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h
index 7ac1553..415eeec 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h
@@ -63,14 +63,12 @@ int dpu_rm_init(struct dpu_rm *rm,
  * @drm_enc: DRM Encoder handle
  * @crtc_state: Proposed Atomic DRM CRTC State handle
  * @topology: Pointer to topology info for the display
- * @test_only: Atomic-Test phase, discard results (unless property overrides)
  * @Return: 0 on Success otherwise -ERROR
  */
 int dpu_rm_reserve(struct dpu_rm *rm,
struct drm_encoder *drm_enc,
struct drm_crtc_state *crtc_state,
-   struct msm_display_topology topology,
-   bool test_only);
+   struct msm_display_topology topology);
 
 /**
  * dpu_rm_release - Given the encoder for the display chain, release any
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project

___
Freedreno mailing list
Freedreno@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/freedreno


[Freedreno] [PATCH 10/25] drm/msm/dpu: maintain hw_mdp in kms

2018-10-08 Thread Jeykumar Sankaran
hw_mdp block is common for displays. No need
to reserve per display.

Signed-off-by: Jeykumar Sankaran 
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c |  7 ++-
 drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c  | 20 
 drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h  | 10 --
 3 files changed, 6 insertions(+), 31 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
index 8309850..fdc89a8 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
@@ -689,6 +689,10 @@ static void _dpu_kms_hw_destroy(struct dpu_kms *dpu_kms)
devm_iounmap(_kms->pdev->dev, dpu_kms->vbif[VBIF_RT]);
dpu_kms->vbif[VBIF_RT] = NULL;
 
+   if (dpu_kms->hw_mdp)
+   dpu_hw_mdp_destroy(dpu_kms->hw_mdp);
+   dpu_kms->hw_mdp = NULL;
+
if (dpu_kms->mmio)
devm_iounmap(_kms->pdev->dev, dpu_kms->mmio);
dpu_kms->mmio = NULL;
@@ -1083,7 +1087,8 @@ static int dpu_kms_hw_init(struct msm_kms *kms)
 
dpu_kms->rm_init = true;
 
-   dpu_kms->hw_mdp = dpu_rm_get_mdp(_kms->rm);
+   dpu_kms->hw_mdp = dpu_hw_mdptop_init(MDP_TOP, dpu_kms->mmio,
+dpu_kms->catalog);
if (IS_ERR_OR_NULL(dpu_kms->hw_mdp)) {
rc = PTR_ERR(dpu_kms->hw_mdp);
if (!dpu_kms->hw_mdp)
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c
index 24fc1c7..561120d 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c
@@ -63,11 +63,6 @@ struct dpu_rm_hw_iter {
enum dpu_hw_blk_type type;
 };
 
-struct dpu_hw_mdp *dpu_rm_get_mdp(struct dpu_rm *rm)
-{
-   return rm->hw_mdp;
-}
-
 static void _dpu_rm_init_hw_iter(
struct dpu_rm_hw_iter *iter,
uint32_t enc_id,
@@ -151,9 +146,6 @@ int dpu_rm_destroy(struct dpu_rm *rm)
}
}
 
-   dpu_hw_mdp_destroy(rm->hw_mdp);
-   rm->hw_mdp = NULL;
-
mutex_destroy(>rm_lock);
 
return 0;
@@ -168,11 +160,8 @@ static int _dpu_rm_hw_blk_create(
void *hw_catalog_info)
 {
struct dpu_rm_hw_blk *blk;
-   struct dpu_hw_mdp *hw_mdp;
void *hw;
 
-   hw_mdp = rm->hw_mdp;
-
switch (type) {
case DPU_HW_BLK_LM:
hw = dpu_hw_lm_init(id, mmio, cat);
@@ -236,15 +225,6 @@ int dpu_rm_init(struct dpu_rm *rm,
for (type = 0; type < DPU_HW_BLK_MAX; type++)
INIT_LIST_HEAD(>hw_blks[type]);
 
-   /* Some of the sub-blocks require an mdptop to be created */
-   rm->hw_mdp = dpu_hw_mdptop_init(MDP_TOP, mmio, cat);
-   if (IS_ERR_OR_NULL(rm->hw_mdp)) {
-   rc = PTR_ERR(rm->hw_mdp);
-   rm->hw_mdp = NULL;
-   DPU_ERROR("failed: mdp hw not available\n");
-   goto fail;
-   }
-
/* Interrogate HW catalog and create tracking items for hw blocks */
for (i = 0; i < cat->mixer_count; i++) {
struct dpu_lm_cfg *lm = >mixer[i];
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h
index c7e3b2b..7ac1553 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h
@@ -24,13 +24,11 @@
  * struct dpu_rm - DPU dynamic hardware resource manager
  * @hw_blks: array of lists of hardware resources present in the system, one
  * list per type of hardware block
- * @hw_mdp: hardware object for mdp_top
  * @lm_max_width: cached layer mixer maximum width
  * @rm_lock: resource manager mutex
  */
 struct dpu_rm {
struct list_head hw_blks[DPU_HW_BLK_MAX];
-   struct dpu_hw_mdp *hw_mdp;
uint32_t lm_max_width;
struct mutex rm_lock;
 };
@@ -82,12 +80,4 @@ int dpu_rm_reserve(struct dpu_rm *rm,
  * @Return: 0 on Success otherwise -ERROR
  */
 void dpu_rm_release(struct dpu_rm *rm, struct drm_crtc_state *crtc_state);
-
-/**
- * dpu_rm_get_mdp - Retrieve HW block for MDP TOP.
- * This is never reserved, and is usable by any display.
- * @rm: DPU Resource Manager handle
- * @Return: Pointer to hw block or NULL
- */
-struct dpu_hw_mdp *dpu_rm_get_mdp(struct dpu_rm *rm);
 #endif /* __DPU_RM_H__ */
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project

___
Freedreno mailing list
Freedreno@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/freedreno


[Freedreno] [PATCH 03/25] drm/msm/dpu: remove dev from RM

2018-10-08 Thread Jeykumar Sankaran
Not used. Remove from RM.

Signed-off-by: Jeykumar Sankaran 
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c | 3 +--
 drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c  | 7 ++-
 drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h  | 6 +-
 3 files changed, 4 insertions(+), 12 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
index 0a683e6..8309850 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
@@ -1075,8 +1075,7 @@ static int dpu_kms_hw_init(struct msm_kms *kms)
goto power_error;
}
 
-   rc = dpu_rm_init(_kms->rm, dpu_kms->catalog, dpu_kms->mmio,
-   dpu_kms->dev);
+   rc = dpu_rm_init(_kms->rm, dpu_kms->catalog, dpu_kms->mmio);
if (rc) {
DPU_ERROR("rm init failed: %d\n", rc);
goto power_error;
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c
index 36a929b..5ce89b9 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c
@@ -224,13 +224,12 @@ static int _dpu_rm_hw_blk_create(
 
 int dpu_rm_init(struct dpu_rm *rm,
struct dpu_mdss_cfg *cat,
-   void __iomem *mmio,
-   struct drm_device *dev)
+   void __iomem *mmio)
 {
int rc, i;
enum dpu_hw_blk_type type;
 
-   if (!rm || !cat || !mmio || !dev) {
+   if (!rm || !cat || !mmio) {
DPU_ERROR("invalid kms\n");
return -EINVAL;
}
@@ -243,8 +242,6 @@ int dpu_rm_init(struct dpu_rm *rm,
for (type = 0; type < DPU_HW_BLK_MAX; type++)
INIT_LIST_HEAD(>hw_blks[type]);
 
-   rm->dev = dev;
-
/* Some of the sub-blocks require an mdptop to be created */
rm->hw_mdp = dpu_hw_mdptop_init(MDP_TOP, mmio, cat);
if (IS_ERR_OR_NULL(rm->hw_mdp)) {
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h
index 0dd3c21..f41fd19 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h
@@ -22,7 +22,6 @@
 
 /**
  * struct dpu_rm - DPU dynamic hardware resource manager
- * @dev: device handle for event logging purposes
  * @hw_blks: array of lists of hardware resources present in the system, one
  * list per type of hardware block
  * @hw_mdp: hardware object for mdp_top
@@ -30,7 +29,6 @@
  * @rm_lock: resource manager mutex
  */
 struct dpu_rm {
-   struct drm_device *dev;
struct list_head hw_blks[DPU_HW_BLK_MAX];
struct dpu_hw_mdp *hw_mdp;
uint32_t lm_max_width;
@@ -63,13 +61,11 @@ struct dpu_rm_hw_iter {
  * @rm: DPU Resource Manager handle
  * @cat: Pointer to hardware catalog
  * @mmio: mapped register io address of MDP
- * @dev: device handle for event logging purposes
  * @Return: 0 on Success otherwise -ERROR
  */
 int dpu_rm_init(struct dpu_rm *rm,
struct dpu_mdss_cfg *cat,
-   void __iomem *mmio,
-   struct drm_device *dev);
+   void __iomem *mmio);
 
 /**
  * dpu_rm_destroy - Free all memory allocated by dpu_rm_init
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project

___
Freedreno mailing list
Freedreno@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/freedreno


[Freedreno] [PATCH 23/25] drm/msm/dpu: remove max_width from RM

2018-10-08 Thread Jeykumar Sankaran
Unused variable in the driver.

Signed-off-by: Jeykumar Sankaran 
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c | 12 
 drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h |  2 --
 2 files changed, 14 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c
index 901b1fc..34e09aa 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c
@@ -166,18 +166,6 @@ int dpu_rm_init(struct dpu_rm *rm,
DPU_ERROR("failed: lm hw not available\n");
goto fail;
}
-
-   if (!rm->lm_max_width) {
-   rm->lm_max_width = lm->sblk->maxwidth;
-   } else if (rm->lm_max_width != lm->sblk->maxwidth) {
-   /*
-* Don't expect to have hw where lm max widths differ.
-* If found, take the min.
-*/
-   DPU_ERROR("unsupported: lm maxwidth differs\n");
-   if (rm->lm_max_width > lm->sblk->maxwidth)
-   rm->lm_max_width = lm->sblk->maxwidth;
-   }
}
 
for (i = 0; i < cat->pingpong_count; i++) {
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h
index 0b1deb0..8676fa5 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h
@@ -24,12 +24,10 @@
  * struct dpu_rm - DPU dynamic hardware resource manager
  * @hw_blks: array of lists of hardware resources present in the system, one
  * list per type of hardware block
- * @lm_max_width: cached layer mixer maximum width
  * @rm_lock: resource manager mutex
  */
 struct dpu_rm {
struct list_head hw_blks[DPU_HW_BLK_MAX];
-   uint32_t lm_max_width;
struct mutex rm_lock;
 };
 
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project

___
Freedreno mailing list
Freedreno@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/freedreno


[Freedreno] [PATCH 04/25] drm/msm/dpu: clean up dpu_rm_check_property_topctl declaration

2018-10-08 Thread Jeykumar Sankaran
Definition was removed already. Clean up header declaration.

Signed-off-by: Jeykumar Sankaran 
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h | 8 
 1 file changed, 8 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h
index f41fd19..eb6a6ac 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h
@@ -136,12 +136,4 @@ void dpu_rm_init_hw_iter(
  * @Return: true on match found, false on no match found
  */
 bool dpu_rm_get_hw(struct dpu_rm *rm, struct dpu_rm_hw_iter *iter);
-
-/**
- * dpu_rm_check_property_topctl - validate property bitmask before it is set
- * @val: user's proposed topology control bitmask
- * @Return: 0 on success or error
- */
-int dpu_rm_check_property_topctl(uint64_t val);
-
 #endif /* __DPU_RM_H__ */
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project

___
Freedreno mailing list
Freedreno@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/freedreno


[Freedreno] [PATCH 02/25] drm/msm/dpu: avoid tracking reservations in RM

2018-10-08 Thread Jeykumar Sankaran
RM was equipped with reservation tracking structure RSVP
to cache HW reservation of displays for certain clients
where atomic_checks (atomic commit with TEST_ONLY) for all
the displays are called before their respective atomic_commits.
Since DPU doesn't support the sequence anymore, clean up
the support from RM. Replace rsvp with the corresponding
encoder id to tag the HW blocks reserved.

Signed-off-by: Jeykumar Sankaran 
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c | 284 +
 drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h |   4 -
 2 files changed, 43 insertions(+), 245 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c
index bdb1177..36a929b 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c
@@ -21,8 +21,8 @@
 #include "dpu_encoder.h"
 #include "dpu_trace.h"
 
-#define RESERVED_BY_OTHER(h, r) \
-   ((h)->rsvp && ((h)->rsvp->enc_id != (r)->enc_id))
+#define RESERVED_BY_OTHER(h, r)  \
+   ((h)->enc_id && (h)->enc_id != r)
 
 /**
  * struct dpu_rm_requirements - Reservation requirements parameter bundle
@@ -34,85 +34,23 @@ struct dpu_rm_requirements {
struct dpu_encoder_hw_resources hw_res;
 };
 
-/**
- * struct dpu_rm_rsvp - Use Case Reservation tagging structure
- * Used to tag HW blocks as reserved by a CRTC->Encoder->Connector chain
- * By using as a tag, rather than lists of pointers to HW blocks used
- * we can avoid some list management since we don't know how many blocks
- * of each type a given use case may require.
- * @list:  List head for list of all reservations
- * @seq:   Global RSVP sequence number for debugging, especially for
- * differentiating differenct allocations for same encoder.
- * @enc_id:Reservations are tracked by Encoder DRM object ID.
- * CRTCs may be connected to multiple Encoders.
- * An encoder or connector id identifies the display path.
- */
-struct dpu_rm_rsvp {
-   struct list_head list;
-   uint32_t seq;
-   uint32_t enc_id;
-};
 
 /**
  * struct dpu_rm_hw_blk - hardware block tracking list member
  * @list:  List head for list of all hardware blocks tracking items
- * @rsvp:  Pointer to use case reservation if reserved by a client
- * @rsvp_nxt:  Temporary pointer used during reservation to the incoming
- * request. Will be swapped into rsvp if proposal is accepted
  * @type:  Type of hardware block this structure tracks
  * @id:Hardware ID number, within it's own space, ie. LM_X
- * @catalog:   Pointer to the hardware catalog entry for this block
+ * @enc_id:Encoder id to which this blk is binded
  * @hw:Pointer to the hardware register access object for this 
block
  */
 struct dpu_rm_hw_blk {
struct list_head list;
-   struct dpu_rm_rsvp *rsvp;
-   struct dpu_rm_rsvp *rsvp_nxt;
enum dpu_hw_blk_type type;
uint32_t id;
+   uint32_t enc_id;
struct dpu_hw_blk *hw;
 };
 
-/**
- * dpu_rm_dbg_rsvp_stage - enum of steps in making reservation for event 
logging
- */
-enum dpu_rm_dbg_rsvp_stage {
-   DPU_RM_STAGE_BEGIN,
-   DPU_RM_STAGE_AFTER_CLEAR,
-   DPU_RM_STAGE_AFTER_RSVPNEXT,
-   DPU_RM_STAGE_FINAL
-};
-
-static void _dpu_rm_print_rsvps(
-   struct dpu_rm *rm,
-   enum dpu_rm_dbg_rsvp_stage stage)
-{
-   struct dpu_rm_rsvp *rsvp;
-   struct dpu_rm_hw_blk *blk;
-   enum dpu_hw_blk_type type;
-
-   DPU_DEBUG("%d\n", stage);
-
-   list_for_each_entry(rsvp, >rsvps, list) {
-   DRM_DEBUG_KMS("%d rsvp[s%ue%u]\n", stage, rsvp->seq,
- rsvp->enc_id);
-   }
-
-   for (type = 0; type < DPU_HW_BLK_MAX; type++) {
-   list_for_each_entry(blk, >hw_blks[type], list) {
-   if (!blk->rsvp && !blk->rsvp_nxt)
-   continue;
-
-   DRM_DEBUG_KMS("%d rsvp[s%ue%u->s%ue%u] %d %d\n", stage,
-   (blk->rsvp) ? blk->rsvp->seq : 0,
-   (blk->rsvp) ? blk->rsvp->enc_id : 0,
-   (blk->rsvp_nxt) ? blk->rsvp_nxt->seq : 0,
-   (blk->rsvp_nxt) ? blk->rsvp_nxt->enc_id : 0,
-   blk->type, blk->id);
-   }
-   }
-}
-
 struct dpu_hw_mdp *dpu_rm_get_mdp(struct dpu_rm *rm)
 {
return rm->hw_mdp;
@@ -148,15 +86,13 @@ static bool _dpu_rm_get_hw_locked(struct dpu_rm *rm, 
struct dpu_rm_hw_iter *i)
i->blk = list_prepare_entry(i->blk, blk_list, list);
 
list_for_each_entry_continue(i->blk, blk_list, list) {
-   struct dpu_rm_rsvp *rsvp = i->blk->

[Freedreno] [PATCH 06/25] drm/msm/dpu: clean up redundant hw type

2018-10-08 Thread Jeykumar Sankaran
struct dpu_hw_blk has hw block type info. Remove duplicate
type tracking in struct dpu_rm_hw_blk.

Signed-off-by: Jeykumar Sankaran 
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c | 17 -
 1 file changed, 4 insertions(+), 13 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c
index 5ce89b9..377def7 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c
@@ -38,14 +38,12 @@ struct dpu_rm_requirements {
 /**
  * struct dpu_rm_hw_blk - hardware block tracking list member
  * @list:  List head for list of all hardware blocks tracking items
- * @type:  Type of hardware block this structure tracks
  * @id:Hardware ID number, within it's own space, ie. LM_X
  * @enc_id:Encoder id to which this blk is binded
  * @hw:Pointer to the hardware register access object for this 
block
  */
 struct dpu_rm_hw_blk {
struct list_head list;
-   enum dpu_hw_blk_type type;
uint32_t id;
uint32_t enc_id;
struct dpu_hw_blk *hw;
@@ -86,12 +84,6 @@ static bool _dpu_rm_get_hw_locked(struct dpu_rm *rm, struct 
dpu_rm_hw_iter *i)
i->blk = list_prepare_entry(i->blk, blk_list, list);
 
list_for_each_entry_continue(i->blk, blk_list, list) {
-   if (i->blk->type != i->type) {
-   DPU_ERROR("found incorrect block type %d on %d list\n",
-   i->blk->type, i->type);
-   return false;
-   }
-
if (i->enc_id == i->blk->enc_id) {
i->hw = i->blk->hw;
DPU_DEBUG("found type %d id %d for enc %d\n",
@@ -151,7 +143,7 @@ int dpu_rm_destroy(struct dpu_rm *rm)
list_for_each_entry_safe(hw_cur, hw_nxt, >hw_blks[type],
list) {
list_del(_cur->list);
-   _dpu_rm_hw_destroy(hw_cur->type, hw_cur->hw);
+   _dpu_rm_hw_destroy(type, hw_cur->hw);
kfree(hw_cur);
}
}
@@ -213,7 +205,6 @@ static int _dpu_rm_hw_blk_create(
return -ENOMEM;
}
 
-   blk->type = type;
blk->id = id;
blk->hw = hw;
blk->enc_id = 0;
@@ -458,7 +449,7 @@ static int _dpu_rm_reserve_lms(struct dpu_rm *rm, uint32_t 
enc_id,
lm[i]->enc_id = enc_id;
pp[i]->enc_id = enc_id;
 
-   trace_dpu_rm_reserve_lms(lm[i]->id, lm[i]->type, enc_id,
+   trace_dpu_rm_reserve_lms(lm[i]->id, DPU_HW_BLK_LM, enc_id,
 pp[i]->id);
}
 
@@ -510,7 +501,7 @@ static int _dpu_rm_reserve_ctls(
 
for (i = 0; i < ARRAY_SIZE(ctls) && i < num_ctls; i++) {
ctls[i]->enc_id = enc_id;
-   trace_dpu_rm_reserve_ctls(ctls[i]->id, ctls[i]->type,
+   trace_dpu_rm_reserve_ctls(ctls[i]->id, DPU_HW_BLK_CTL,
  enc_id);
}
 
@@ -538,7 +529,7 @@ static int _dpu_rm_reserve_intf(
}
 
iter.blk->enc_id = enc_id;
-   trace_dpu_rm_reserve_intf(iter.blk->id, iter.blk->type,
+   trace_dpu_rm_reserve_intf(iter.blk->id, DPU_HW_BLK_INTF,
  enc_id);
break;
}
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project

___
Freedreno mailing list
Freedreno@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/freedreno


[Freedreno] [PATCH 01/25] drm/msm/dpu: fix hw ctl retrieval for mixer muxing

2018-10-08 Thread Jeykumar Sankaran
Layer mixer/pingpong block counts and hw ctl block counts
will not be same for all the topologies (e.g. layer
mixer muxing to single interface)

Use the encoder's split_role info to retrieve the
respective control path for programming.

Signed-off-by: Jeykumar Sankaran 
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 9 ++---
 1 file changed, 6 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
index 96cdf06..d12f896 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
@@ -1060,6 +1060,7 @@ static void dpu_encoder_virt_mode_set(struct drm_encoder 
*drm_enc,
 
for (i = 0; i < dpu_enc->num_phys_encs; i++) {
struct dpu_encoder_phys *phys = dpu_enc->phys_encs[i];
+   int ctl_index;
 
if (phys) {
if (!dpu_enc->hw_pp[i]) {
@@ -1068,14 +1069,16 @@ static void dpu_encoder_virt_mode_set(struct 
drm_encoder *drm_enc,
return;
}
 
-   if (!hw_ctl[i]) {
+   ctl_index = phys->split_role == ENC_ROLE_SLAVE ? 1 : 0;
+
+   if (!hw_ctl[ctl_index]) {
DPU_ERROR_ENC(dpu_enc, "no ctl block assigned"
-"at idx: %d\n", i);
+"at idx: %d\n", ctl_index);
return;
}
 
phys->hw_pp = dpu_enc->hw_pp[i];
-   phys->hw_ctl = hw_ctl[i];
+   phys->hw_ctl = hw_ctl[ctl_index];
 
phys->connector = conn->state->connector;
if (phys->ops.mode_set)
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project

___
Freedreno mailing list
Freedreno@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/freedreno


[Freedreno] [PATCH 05/25] drm/msm/dpu: remove encoder from crtc mixer struct

2018-10-08 Thread Jeykumar Sankaran
Not actively used. Clean up the crtc mixer struct.

Signed-off-by: Jeykumar Sankaran 
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c | 2 --
 drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h | 2 --
 2 files changed, 4 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
index d4530d6..4960641 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
@@ -461,8 +461,6 @@ static void _dpu_crtc_setup_mixer_for_encoder(
return;
}
 
-   mixer->encoder = enc;
-
cstate->num_mixers++;
DPU_DEBUG("setup mixer %d: lm %d\n",
i, mixer->hw_lm->idx - LM_0);
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h
index 3723b48..75fdd3c 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h
@@ -84,14 +84,12 @@ struct dpu_crtc_smmu_state_data {
  * struct dpu_crtc_mixer: stores the map for each virtual pipeline in the CRTC
  * @hw_lm: LM HW Driver context
  * @lm_ctl:CTL Path HW driver context
- * @encoder:   Encoder attached to this lm & ctl
  * @mixer_op_mode: mixer blending operation mode
  * @flush_mask:mixer flush mask for ctl, mixer and pipe
  */
 struct dpu_crtc_mixer {
struct dpu_hw_mixer *hw_lm;
struct dpu_hw_ctl *lm_ctl;
-   struct drm_encoder *encoder;
u32 mixer_op_mode;
u32 flush_mask;
 };
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project

___
Freedreno mailing list
Freedreno@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/freedreno


[Freedreno] [PATCH 13/25] drm/msm/dpu: make RM iterator hw type specific

2018-10-08 Thread Jeykumar Sankaran
Usage of hw block iterators are only RM internal. Instead
of using generic void pointers for HW blocks, use dpu
specific structure. It helps us to get rid of duplicate
hw block id's maintained in RM wrapper.

Signed-off-by: Jeykumar Sankaran 
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c | 27 ---
 1 file changed, 12 insertions(+), 15 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c
index 561120d..303f1b3 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c
@@ -38,13 +38,11 @@ struct dpu_rm_requirements {
 /**
  * struct dpu_rm_hw_blk - hardware block tracking list member
  * @list:  List head for list of all hardware blocks tracking items
- * @id:Hardware ID number, within it's own space, ie. LM_X
  * @enc_id:Encoder id to which this blk is binded
  * @hw:Pointer to the hardware register access object for this 
block
  */
 struct dpu_rm_hw_blk {
struct list_head list;
-   uint32_t id;
uint32_t enc_id;
struct dpu_hw_blk *hw;
 };
@@ -57,7 +55,7 @@ struct dpu_rm_hw_blk {
  * @type: Hardware Block Type client wishes to search for.
  */
 struct dpu_rm_hw_iter {
-   void *hw;
+   struct dpu_hw_blk *hw;
struct dpu_rm_hw_blk *blk;
uint32_t enc_id;
enum dpu_hw_blk_type type;
@@ -96,7 +94,7 @@ static bool _dpu_rm_get_hw_locked(struct dpu_rm *rm, struct 
dpu_rm_hw_iter *i)
if (i->enc_id == i->blk->enc_id) {
i->hw = i->blk->hw;
DPU_DEBUG("found type %d id %d for enc %d\n",
-   i->type, i->blk->id, i->enc_id);
+   i->type, i->blk->hw->id, i->enc_id);
return true;
}
}
@@ -197,7 +195,6 @@ static int _dpu_rm_hw_blk_create(
return -ENOMEM;
}
 
-   blk->id = id;
blk->hw = hw;
blk->enc_id = 0;
list_add_tail(>list, >hw_blks[type]);
@@ -350,7 +347,7 @@ static bool _dpu_rm_check_lm_and_get_connected_blks(
 
_dpu_rm_init_hw_iter(, 0, DPU_HW_BLK_PINGPONG);
while (_dpu_rm_get_hw_locked(rm, )) {
-   if (iter.blk->id == lm_cfg->pingpong) {
+   if (iter.blk->hw->id == lm_cfg->pingpong) {
*pp = iter.blk;
break;
}
@@ -362,8 +359,8 @@ static bool _dpu_rm_check_lm_and_get_connected_blks(
}
 
if (RESERVED_BY_OTHER(*pp, enc_id)) {
-   DPU_DEBUG("lm %d pp %d already reserved\n", lm->id,
-   (*pp)->id);
+   DPU_DEBUG("lm %d pp %d already reserved\n", lm->hw->id,
+   (*pp)->hw->id);
return false;
}
 
@@ -436,8 +433,8 @@ static int _dpu_rm_reserve_lms(struct dpu_rm *rm, uint32_t 
enc_id,
dpu_cstate->mixers[i].hw_lm = to_dpu_hw_mixer(lm[i]->hw);
dpu_cstate->mixers[i].hw_pp = to_dpu_hw_pingpong(pp[i]->hw);
 
-   trace_dpu_rm_reserve_lms(lm[i]->id, DPU_HW_BLK_LM, enc_id,
-pp[i]->id);
+   trace_dpu_rm_reserve_lms(lm[i]->hw->id, DPU_HW_BLK_LM, enc_id,
+pp[i]->hw->id);
}
 
dpu_cstate->num_mixers = lm_count;
@@ -474,13 +471,13 @@ static int _dpu_rm_reserve_ctls(
 
has_split_display = BIT(DPU_CTL_SPLIT_DISPLAY) & features;
 
-   DPU_DEBUG("ctl %d caps 0x%lX\n", iter.blk->id, features);
+   DPU_DEBUG("ctl %d caps 0x%lX\n", iter.blk->hw->id, features);
 
if (needs_split_display != has_split_display)
continue;
 
ctls[i] = iter.blk;
-   DPU_DEBUG("ctl %d match\n", iter.blk->id);
+   DPU_DEBUG("ctl %d match\n", iter.blk->hw->id);
 
if (++i == num_ctls)
break;
@@ -493,7 +490,7 @@ static int _dpu_rm_reserve_ctls(
ctls[i]->enc_id = enc_id;
dpu_cstate->hw_ctls[i] = to_dpu_hw_ctl(ctls[i]->hw);
 
-   trace_dpu_rm_reserve_ctls(ctls[i]->id, DPU_HW_BLK_CTL,
+   trace_dpu_rm_reserve_ctls(ctls[i]->hw->id, DPU_HW_BLK_CTL,
  enc_id);
}
 
@@ -513,7 +510,7 @@ static struct dpu_rm_hw_blk *_dpu_rm_reserve_intf(
/* Find the block entry in the rm, and note the reservation */
_dpu_rm_init_hw_iter(, 0, type);
while (_dpu_rm_get_hw_locked(rm, )) {
-   if (iter.blk->id != id)
+   if (iter.blk->

[Freedreno] [PATCH 09/25] drm/msm/dpu: make RM iterator static

2018-10-08 Thread Jeykumar Sankaran
HW blocks reserved for a display are stored in crtc state.
No one outside RM is interested in using these API's for
HW block list iterations.

Signed-off-by: Jeykumar Sankaran 
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c | 37 ++-
 drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h | 46 --
 2 files changed, 20 insertions(+), 63 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c
index 619b596..24fc1c7 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c
@@ -49,12 +49,26 @@ struct dpu_rm_hw_blk {
struct dpu_hw_blk *hw;
 };
 
+/**
+ * struct dpu_rm_hw_iter - iterator for use with dpu_rm
+ * @hw: dpu_hw object requested, or NULL on failure
+ * @blk: dpu_rm internal block representation. Clients ignore. Used as 
iterator.
+ * @enc_id: DRM ID of Encoder client wishes to search for, or 0 for Any Encoder
+ * @type: Hardware Block Type client wishes to search for.
+ */
+struct dpu_rm_hw_iter {
+   void *hw;
+   struct dpu_rm_hw_blk *blk;
+   uint32_t enc_id;
+   enum dpu_hw_blk_type type;
+};
+
 struct dpu_hw_mdp *dpu_rm_get_mdp(struct dpu_rm *rm)
 {
return rm->hw_mdp;
 }
 
-void dpu_rm_init_hw_iter(
+static void _dpu_rm_init_hw_iter(
struct dpu_rm_hw_iter *iter,
uint32_t enc_id,
enum dpu_hw_blk_type type)
@@ -97,17 +111,6 @@ static bool _dpu_rm_get_hw_locked(struct dpu_rm *rm, struct 
dpu_rm_hw_iter *i)
return false;
 }
 
-bool dpu_rm_get_hw(struct dpu_rm *rm, struct dpu_rm_hw_iter *i)
-{
-   bool ret;
-
-   mutex_lock(>rm_lock);
-   ret = _dpu_rm_get_hw_locked(rm, i);
-   mutex_unlock(>rm_lock);
-
-   return ret;
-}
-
 static void _dpu_rm_hw_destroy(enum dpu_hw_blk_type type, void *hw)
 {
switch (type) {
@@ -365,7 +368,7 @@ static bool _dpu_rm_check_lm_and_get_connected_blks(
return false;
}
 
-   dpu_rm_init_hw_iter(, 0, DPU_HW_BLK_PINGPONG);
+   _dpu_rm_init_hw_iter(, 0, DPU_HW_BLK_PINGPONG);
while (_dpu_rm_get_hw_locked(rm, )) {
if (iter.blk->id == lm_cfg->pingpong) {
*pp = iter.blk;
@@ -404,7 +407,7 @@ static int _dpu_rm_reserve_lms(struct dpu_rm *rm, uint32_t 
enc_id,
}
 
/* Find a primary mixer */
-   dpu_rm_init_hw_iter(_i, 0, DPU_HW_BLK_LM);
+   _dpu_rm_init_hw_iter(_i, 0, DPU_HW_BLK_LM);
while (lm_count != reqs->topology.num_lm &&
_dpu_rm_get_hw_locked(rm, _i)) {
memset(, 0, sizeof(lm));
@@ -421,7 +424,7 @@ static int _dpu_rm_reserve_lms(struct dpu_rm *rm, uint32_t 
enc_id,
++lm_count;
 
/* Valid primary mixer found, find matching peers */
-   dpu_rm_init_hw_iter(_j, 0, DPU_HW_BLK_LM);
+   _dpu_rm_init_hw_iter(_j, 0, DPU_HW_BLK_LM);
 
while (lm_count != reqs->topology.num_lm &&
_dpu_rm_get_hw_locked(rm, _j)) {
@@ -480,7 +483,7 @@ static int _dpu_rm_reserve_ctls(
 
needs_split_display = _dpu_rm_needs_split_display(top);
 
-   dpu_rm_init_hw_iter(, 0, DPU_HW_BLK_CTL);
+   _dpu_rm_init_hw_iter(, 0, DPU_HW_BLK_CTL);
while (_dpu_rm_get_hw_locked(rm, )) {
const struct dpu_hw_ctl *ctl = to_dpu_hw_ctl(iter.blk->hw);
unsigned long features = ctl->caps->features;
@@ -528,7 +531,7 @@ static struct dpu_rm_hw_blk *_dpu_rm_reserve_intf(
struct dpu_rm_hw_iter iter;
 
/* Find the block entry in the rm, and note the reservation */
-   dpu_rm_init_hw_iter(, 0, type);
+   _dpu_rm_init_hw_iter(, 0, type);
while (_dpu_rm_get_hw_locked(rm, )) {
if (iter.blk->id != id)
continue;
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h
index e48e8f2..c7e3b2b 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h
@@ -36,26 +36,6 @@ struct dpu_rm {
 };
 
 /**
- *  struct dpu_rm_hw_blk - resource manager internal structure
- * forward declaration for single iterator definition without void pointer
- */
-struct dpu_rm_hw_blk;
-
-/**
- * struct dpu_rm_hw_iter - iterator for use with dpu_rm
- * @hw: dpu_hw object requested, or NULL on failure
- * @blk: dpu_rm internal block representation. Clients ignore. Used as 
iterator.
- * @enc_id: DRM ID of Encoder client wishes to search for, or 0 for Any Encoder
- * @type: Hardware Block Type client wishes to search for.
- */
-struct dpu_rm_hw_iter {
-   void *hw;
-   struct dpu_rm_hw_blk *blk;
-   uint32_t enc_id;
-   enum dpu_hw_blk_type type;
-};
-
-/**
  * dpu_rm_init - Read hardware catalog and create reservation tracking objects
  * for all HW blocks.
  * @rm: DPU Resource Manager handle
@@ -110

<    1   2   3   4   >