[PATCH 19/26] drm/sun4i: Implement some semblance of vblank event handling

2016-06-02 Thread Daniel Vetter
On Wed, Jun 01, 2016 at 06:18:59PM +0200, Maxime Ripard wrote:
> Hi Daniel,
> 
> On Sun, May 29, 2016 at 08:35:16PM +0200, Daniel Vetter wrote:
> > atomic_flush seems to be the right place, right after we commit the
> > plane updates. Again use the fullproof version, since the pipe might
> > be off.
> 
> This looks fine.
> 
> How can that be tested? modetest requires async vblank, which is not
> there yet, and X doesn't seem to use it at all (since it works fine
> without it).

Run the entire series. It implements nonblocking commit for everyone. I'm
just working on submitting the non-RFC version of this series.
-Daniel
-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch


[PATCH 00/38] nonblocking atomic commits for everyone!

2016-06-02 Thread Daniel Vetter
Hi all,

Now without the RFC tag, but with polish:
- kerneldoc for everything!
- tested on virtio, hdlcd, rockchip and i915.

The big upshot is still that the helpers are really picky about drivers sending
out drm events correctly, and that is the area where most of the debug work was
needed in testing these drivers.

What's needed now:
- review and bikesheds (not too many of the latter pls).
- testing on arcpgu, fsl-du & sun4i. Those are among the drivers which didn't
  implement nonblocking and hence will be forcefully upgraded to use these
  helpers. Which might unearth bugs (I tried to fix them, but can't test).

Cheers, Daniel

Daniel Vetter (37):
  drm/atomic-helper: use for_each_*_in_state more
  drm/i915: Use drm_atomic_get_existing_plane_state
  drm/msm: Use for_each_*_in_state
  drm/rcar-du: Use for_each_*_in_state
  drm/vc4: Use for_each_plane_in_state
  drm/omap: Use for_each_plane_in_state
  drm/exynos: Use for_each_crtc_in_state
  drm/atomic: Add __drm_atomic_get_current_plane_state
  drm: Consolidate connector arrays in drm_atomic_state
  drm: Consolidate plane arrays in drm_atomic_state
  drm: Consolidate crtc arrays in drm_atomic_state
  drm/atomic-helper: Massage swap_state signature somewhat
  drm/arc: Nuke event_list
  drm/arc: Actually bother with handling atomic events.
  drm/hdlcd: Clean up crtc hooks
  drm/hdlcd: Fix up crtc_state->event handling
  drm/fsl-du: Implement some semblance of vblank event handling
  drm/hisilicon: Implement some semblance of vblank event handling
  drm/sun4i: Implement some semblance of vblank event handling
  drm/atomic: kerneldoc for drm_atomic_crtc_needs_modeset
  drm/atomic-helper: nonblocking commit support
  drm/hdlcd: Use helper support for nonblocking commits
  drm/arc: Implement nonblocking commit correctly
  drm/i915: Signal drm events for atomic
  drm/i915: Roll out the helper nonblock tracking
  drm/i915: nonblocking commit
  drm/i915: Use atomic commits for legacy page_flips
  drm/i915: Move fb_bits updating later in atomic_commit
  drm/rockchip: Disarm vop->is_enabled
  drm/rockchip: Fix crtc_state->event signalling
  drm/rockchip: convert to helper nonblocking atomic commit
  drm/rockchip: Nuke pending event handling in preclose
  drm/virtio: Don't reinvent a flipping wheel
  drm: Replace fb_helper->atomic with mode_config->atomic_commit
  drm: Resurrect atomic rmfb code
  drm/sti: Don't call drm_helper_disable_unused_functions
  drm/crtc-helper: disable_unused_functions really isn't for atomic

Gustavo Padovan (1):
  drm/fence: add fence to drm_pending_event

 drivers/gpu/drm/arc/arcpgu.h|   1 -
 drivers/gpu/drm/arc/arcpgu_crtc.c   |  19 +-
 drivers/gpu/drm/arc/arcpgu_drv.c|  27 +-
 drivers/gpu/drm/arm/hdlcd_crtc.c|  37 +-
 drivers/gpu/drm/arm/hdlcd_drv.c |  27 +-
 drivers/gpu/drm/arm/hdlcd_drv.h |   1 -
 drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.c|   2 +-
 drivers/gpu/drm/drm_atomic.c| 168 ++--
 drivers/gpu/drm/drm_atomic_helper.c | 532 
 drivers/gpu/drm/drm_crtc.c  |   9 +
 drivers/gpu/drm/drm_crtc_helper.c   |   3 +
 drivers/gpu/drm/drm_crtc_internal.h |   1 +
 drivers/gpu/drm/drm_fb_helper.c |   6 +-
 drivers/gpu/drm/drm_fops.c  |  22 +-
 drivers/gpu/drm/exynos/exynos_drm_drv.c |  10 +-
 drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_crtc.c  |  23 +-
 drivers/gpu/drm/hisilicon/kirin/kirin_drm_ade.c |  20 +-
 drivers/gpu/drm/i915/intel_atomic.c |   6 +-
 drivers/gpu/drm/i915/intel_display.c| 178 +---
 drivers/gpu/drm/i915/intel_fbdev.c  |   2 -
 drivers/gpu/drm/i915/intel_sprite.c |  14 +
 drivers/gpu/drm/mediatek/mtk_drm_drv.c  |   2 +-
 drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.c |  20 +-
 drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c|  10 +-
 drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c |  12 +-
 drivers/gpu/drm/msm/msm_atomic.c|  37 +-
 drivers/gpu/drm/nouveau/nouveau_usif.c  |   1 -
 drivers/gpu/drm/omapdrm/omap_drv.c  |  13 +-
 drivers/gpu/drm/rcar-du/rcar_du_kms.c   |  10 +-
 drivers/gpu/drm/rcar-du/rcar_du_plane.c |  20 +-
 drivers/gpu/drm/rockchip/rockchip_drm_drv.c |  25 --
 drivers/gpu/drm/rockchip/rockchip_drm_drv.h |  11 -
 drivers/gpu/drm/rockchip/rockchip_drm_fb.c  |  73 +---
 drivers/gpu/drm/rockchip/rockchip_drm_fbdev.c   |   3 -
 drivers/gpu/drm/rockchip/rockchip_drm_vop.c |  68 +--
 drivers/gpu/drm/sti/sti_drv.c   |   3 +-
 drivers/gpu/drm/sun4i/sun4i_crtc.c  |  12 +
 drivers/gpu/drm/tegra/drm.c |   2 +-
 drivers/gpu/drm/vc4/vc4_crtc.c  |  11 +-
 drivers/gpu/drm/vc4/vc4_drv.h   |   2 +-
 drivers/gpu/drm/vc4/vc4_kms.c   |  12 +-
 drivers/gpu/drm/vc4/v

[PATCH 01/38] drm/atomic-helper: use for_each_*_in_state more

2016-06-02 Thread Daniel Vetter
This avois leaking drm_atomic_state internals into the helpers. The
only place where this still happens after this patch is 
drm_atomic_helper_swap_state().
It's unavoidable there, and maybe a good indicator we should actually
move that function into drm_atomic.c.

Signed-off-by: Daniel Vetter 
---
 drivers/gpu/drm/drm_atomic_helper.c | 47 +
 1 file changed, 16 insertions(+), 31 deletions(-)

diff --git a/drivers/gpu/drm/drm_atomic_helper.c 
b/drivers/gpu/drm/drm_atomic_helper.c
index 939df900dcaa..872dbc844d69 100644
--- a/drivers/gpu/drm/drm_atomic_helper.c
+++ b/drivers/gpu/drm/drm_atomic_helper.c
@@ -614,7 +614,7 @@ drm_atomic_helper_check_planes(struct drm_device *dev,
if (!funcs || !funcs->atomic_check)
continue;

-   ret = funcs->atomic_check(crtc, state->crtc_states[i]);
+   ret = funcs->atomic_check(crtc, crtc_state);
if (ret) {
DRM_DEBUG_ATOMIC("[CRTC:%d:%s] atomic driver check 
failed\n",
 crtc->base.id, crtc->name);
@@ -1252,16 +1252,12 @@ EXPORT_SYMBOL(drm_atomic_helper_commit);
 int drm_atomic_helper_prepare_planes(struct drm_device *dev,
 struct drm_atomic_state *state)
 {
-   int nplanes = dev->mode_config.num_total_plane;
-   int ret, i;
+   struct drm_plane *plane;
+   struct drm_plane_state *plane_state;
+   int ret, i, j;

-   for (i = 0; i < nplanes; i++) {
+   for_each_plane_in_state(state, plane, plane_state, i) {
const struct drm_plane_helper_funcs *funcs;
-   struct drm_plane *plane = state->planes[i];
-   struct drm_plane_state *plane_state = state->plane_states[i];
-
-   if (!plane)
-   continue;

funcs = plane->helper_private;

@@ -1275,12 +1271,10 @@ int drm_atomic_helper_prepare_planes(struct drm_device 
*dev,
return 0;

 fail:
-   for (i--; i >= 0; i--) {
+   for_each_plane_in_state(state, plane, plane_state, j) {
const struct drm_plane_helper_funcs *funcs;
-   struct drm_plane *plane = state->planes[i];
-   struct drm_plane_state *plane_state = state->plane_states[i];

-   if (!plane)
+   if (j >= i)
continue;

funcs = plane->helper_private;
@@ -1567,35 +1561,26 @@ void drm_atomic_helper_swap_state(struct drm_device 
*dev,
  struct drm_atomic_state *state)
 {
int i;
+   struct drm_connector *connector;
+   struct drm_connector_state *conn_state;
+   struct drm_crtc *crtc;
+   struct drm_crtc_state *crtc_state;
+   struct drm_plane *plane;
+   struct drm_plane_state *plane_state;

-   for (i = 0; i < state->num_connector; i++) {
-   struct drm_connector *connector = state->connectors[i];
-
-   if (!connector)
-   continue;
-
+   for_each_connector_in_state(state, connector, conn_state, i) {
connector->state->state = state;
swap(state->connector_states[i], connector->state);
connector->state->state = NULL;
}

-   for (i = 0; i < dev->mode_config.num_crtc; i++) {
-   struct drm_crtc *crtc = state->crtcs[i];
-
-   if (!crtc)
-   continue;
-
+   for_each_crtc_in_state(state, crtc, crtc_state, i) {
crtc->state->state = state;
swap(state->crtc_states[i], crtc->state);
crtc->state->state = NULL;
}

-   for (i = 0; i < dev->mode_config.num_total_plane; i++) {
-   struct drm_plane *plane = state->planes[i];
-
-   if (!plane)
-   continue;
-
+   for_each_plane_in_state(state, plane, plane_state, i) {
plane->state->state = state;
swap(state->plane_states[i], plane->state);
plane->state->state = NULL;
-- 
2.8.1



[PATCH 02/38] drm/i915: Use drm_atomic_get_existing_plane_state

2016-06-02 Thread Daniel Vetter
We want to encapsulate the drm_atomic_state internals.

Signed-off-by: Daniel Vetter 
---
 drivers/gpu/drm/i915/intel_atomic.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/intel_atomic.c 
b/drivers/gpu/drm/i915/intel_atomic.c
index 50ff90aea721..3e6d9ff8840a 100644
--- a/drivers/gpu/drm/i915/intel_atomic.c
+++ b/drivers/gpu/drm/i915/intel_atomic.c
@@ -223,7 +223,9 @@ int intel_atomic_setup_scalers(struct drm_device *dev,
continue;
}

-   plane_state = 
to_intel_plane_state(drm_state->plane_states[i]);
+   plane_state = to_intel_plane_state(
+   drm_atomic_get_existing_plane_state(drm_state,
+   plane));
scaler_id = &plane_state->scaler_id;
}

-- 
2.8.1



[PATCH 03/38] drm/msm: Use for_each_*_in_state

2016-06-02 Thread Daniel Vetter
We want to hide drm_atomic_state internals

Cc: Rob Clark 
Signed-off-by: Daniel Vetter 
---
 drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.c| 20 +++--
 drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c| 12 +++---
 drivers/gpu/drm/msm/msm_atomic.c   | 35 ++
 drivers/gpu/drm/rockchip/rockchip_drm_fb.c |  1 +
 4 files changed, 23 insertions(+), 45 deletions(-)

diff --git a/drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.c 
b/drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.c
index 67442d50a6c2..f145d256e332 100644
--- a/drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.c
+++ b/drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.c
@@ -106,31 +106,27 @@ out:
 static void mdp4_prepare_commit(struct msm_kms *kms, struct drm_atomic_state 
*state)
 {
struct mdp4_kms *mdp4_kms = to_mdp4_kms(to_mdp_kms(kms));
-   int i, ncrtcs = state->dev->mode_config.num_crtc;
+   int i;
+   struct drm_crtc *crtc;
+   struct drm_crtc_state *crtc_state;

mdp4_enable(mdp4_kms);

/* see 119ecb7fd */
-   for (i = 0; i < ncrtcs; i++) {
-   struct drm_crtc *crtc = state->crtcs[i];
-   if (!crtc)
-   continue;
+   for_each_crtc_in_state(state, crtc, crtc_state, i)
drm_crtc_vblank_get(crtc);
-   }
 }

 static void mdp4_complete_commit(struct msm_kms *kms, struct drm_atomic_state 
*state)
 {
struct mdp4_kms *mdp4_kms = to_mdp4_kms(to_mdp_kms(kms));
-   int i, ncrtcs = state->dev->mode_config.num_crtc;
+   int i;
+   struct drm_crtc *crtc;
+   struct drm_crtc_state *crtc_state;

/* see 119ecb7fd */
-   for (i = 0; i < ncrtcs; i++) {
-   struct drm_crtc *crtc = state->crtcs[i];
-   if (!crtc)
-   continue;
+   for_each_crtc_in_state(state, crtc, crtc_state, i)
drm_crtc_vblank_put(crtc);
-   }

mdp4_disable(mdp4_kms);
 }
diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c 
b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c
index 484b4d15e71d..f0c285b1c027 100644
--- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c
+++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c
@@ -78,17 +78,11 @@ static void mdp5_complete_commit(struct msm_kms *kms, 
struct drm_atomic_state *s
 {
int i;
struct mdp5_kms *mdp5_kms = to_mdp5_kms(to_mdp_kms(kms));
-   int nplanes = mdp5_kms->dev->mode_config.num_total_plane;
-
-   for (i = 0; i < nplanes; i++) {
-   struct drm_plane *plane = state->planes[i];
-   struct drm_plane_state *plane_state = state->plane_states[i];
-
-   if (!plane)
-   continue;
+   struct drm_plane *plane;
+   struct drm_plane_state *plane_state;

+   for_each_plane_in_state(state, plane, plane_state, i)
mdp5_plane_complete_commit(plane, plane_state);
-   }

mdp5_disable(mdp5_kms);
 }
diff --git a/drivers/gpu/drm/msm/msm_atomic.c b/drivers/gpu/drm/msm/msm_atomic.c
index e3892c263f27..9c0e4261dbba 100644
--- a/drivers/gpu/drm/msm/msm_atomic.c
+++ b/drivers/gpu/drm/msm/msm_atomic.c
@@ -84,17 +84,12 @@ static void msm_atomic_wait_for_commit_done(struct 
drm_device *dev,
struct drm_atomic_state *old_state)
 {
struct drm_crtc *crtc;
+   struct drm_crtc_state *crtc_state;
struct msm_drm_private *priv = old_state->dev->dev_private;
struct msm_kms *kms = priv->kms;
-   int ncrtcs = old_state->dev->mode_config.num_crtc;
int i;

-   for (i = 0; i < ncrtcs; i++) {
-   crtc = old_state->crtcs[i];
-
-   if (!crtc)
-   continue;
-
+   for_each_crtc_in_state(old_state, crtc, crtc_state, i) {
if (!crtc->state->enable)
continue;

@@ -192,9 +187,11 @@ int msm_atomic_commit(struct drm_device *dev,
struct drm_atomic_state *state, bool nonblock)
 {
struct msm_drm_private *priv = dev->dev_private;
-   int nplanes = dev->mode_config.num_total_plane;
-   int ncrtcs = dev->mode_config.num_crtc;
struct msm_commit *c;
+   struct drm_crtc *crtc;
+   struct drm_crtc_state *crtc_state;
+   struct drm_plane *plane;
+   struct drm_plane_state *plane_state;
int i, ret;

ret = drm_atomic_helper_prepare_planes(dev, state);
@@ -210,28 +207,18 @@ int msm_atomic_commit(struct drm_device *dev,
/*
 * Figure out what crtcs we have:
 */
-   for (i = 0; i < ncrtcs; i++) {
-   struct drm_crtc *crtc = state->crtcs[i];
-   if (!crtc)
-   continue;
+   for_each_crtc_in_state(state, crtc, crtc_state, i)
c->crtc_mask |= (1 << drm_crtc_index(crtc));
-   }

/*
 * Figure out what fence to wait for:
 */
-   for (i = 0; i < nplanes; i++) {
-   struct drm_plane *plane = state->planes[i];
-   struct drm_plane_state *new_state = 

[PATCH 04/38] drm/rcar-du: Use for_each_*_in_state

2016-06-02 Thread Daniel Vetter
We want to hide drm_atomic_state internals better.

Cc: Laurent Pinchart 
Signed-off-by: Daniel Vetter 
---
 drivers/gpu/drm/rcar-du/rcar_du_kms.c   |  8 
 drivers/gpu/drm/rcar-du/rcar_du_plane.c | 20 
 2 files changed, 12 insertions(+), 16 deletions(-)

diff --git a/drivers/gpu/drm/rcar-du/rcar_du_kms.c 
b/drivers/gpu/drm/rcar-du/rcar_du_kms.c
index e70a4f33d970..f315c55c1f65 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_kms.c
+++ b/drivers/gpu/drm/rcar-du/rcar_du_kms.c
@@ -288,6 +288,8 @@ static int rcar_du_atomic_commit(struct drm_device *dev,
 {
struct rcar_du_device *rcdu = dev->dev_private;
struct rcar_du_commit *commit;
+   struct drm_crtc *crtc;
+   struct drm_crtc_state *crtc_state;
unsigned int i;
int ret;

@@ -309,10 +311,8 @@ static int rcar_du_atomic_commit(struct drm_device *dev,
/* Wait until all affected CRTCs have completed previous commits and
 * mark them as pending.
 */
-   for (i = 0; i < dev->mode_config.num_crtc; ++i) {
-   if (state->crtcs[i])
-   commit->crtcs |= 1 << drm_crtc_index(state->crtcs[i]);
-   }
+   for_each_crtc_in_state(state, crtc, crtc_state, i)
+   commit->crtcs |= 1 << drm_crtc_index(crtc);

spin_lock(&rcdu->commit.wait.lock);
ret = wait_event_interruptible_locked(rcdu->commit.wait,
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_plane.c 
b/drivers/gpu/drm/rcar-du/rcar_du_plane.c
index d445e67f78e1..bfe31ca870cc 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_plane.c
+++ b/drivers/gpu/drm/rcar-du/rcar_du_plane.c
@@ -140,18 +140,17 @@ int rcar_du_atomic_check_planes(struct drm_device *dev,
bool needs_realloc = false;
unsigned int groups = 0;
unsigned int i;
+   struct drm_plane *drm_plane;
+   struct drm_plane_state *drm_plane_state;

/* Check if hardware planes need to be reallocated. */
-   for (i = 0; i < dev->mode_config.num_total_plane; ++i) {
+   for_each_plane_in_state(state, drm_plane, drm_plane_state, i) {
struct rcar_du_plane_state *plane_state;
struct rcar_du_plane *plane;
unsigned int index;

-   if (!state->planes[i])
-   continue;
-
-   plane = to_rcar_plane(state->planes[i]);
-   plane_state = to_rcar_plane_state(state->plane_states[i]);
+   plane = to_rcar_plane(drm_plane);
+   plane_state = to_rcar_plane_state(drm_plane_state);

dev_dbg(rcdu->dev, "%s: checking plane (%u,%tu)\n", __func__,
plane->group->index, plane - plane->group->planes);
@@ -247,18 +246,15 @@ int rcar_du_atomic_check_planes(struct drm_device *dev,
}

/* Reallocate hardware planes for each plane that needs it. */
-   for (i = 0; i < dev->mode_config.num_total_plane; ++i) {
+   for_each_plane_in_state(state, drm_plane, drm_plane_state, i) {
struct rcar_du_plane_state *plane_state;
struct rcar_du_plane *plane;
unsigned int crtc_planes;
unsigned int free;
int idx;

-   if (!state->planes[i])
-   continue;
-
-   plane = to_rcar_plane(state->planes[i]);
-   plane_state = to_rcar_plane_state(state->plane_states[i]);
+   plane = to_rcar_plane(drm_plane);
+   plane_state = to_rcar_plane_state(drm_plane_state);

dev_dbg(rcdu->dev, "%s: allocating plane (%u,%tu)\n", __func__,
plane->group->index, plane - plane->group->planes);
-- 
2.8.1



[PATCH 05/38] drm/vc4: Use for_each_plane_in_state

2016-06-02 Thread Daniel Vetter
We want to hide drm_atomic_stat internals a bit better.

Cc: Eric Anholt 
Signed-off-by: Daniel Vetter 
---
 drivers/gpu/drm/vc4/vc4_kms.c | 10 +++---
 1 file changed, 3 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/vc4/vc4_kms.c b/drivers/gpu/drm/vc4/vc4_kms.c
index cb37751bc99f..39c0b2048bfd 100644
--- a/drivers/gpu/drm/vc4/vc4_kms.c
+++ b/drivers/gpu/drm/vc4/vc4_kms.c
@@ -111,6 +111,8 @@ static int vc4_atomic_commit(struct drm_device *dev,
int i;
uint64_t wait_seqno = 0;
struct vc4_commit *c;
+   struct drm_plane *plane;
+   struct drm_plane_state *new_state;

c = commit_init(state);
if (!c)
@@ -130,13 +132,7 @@ static int vc4_atomic_commit(struct drm_device *dev,
return ret;
}

-   for (i = 0; i < dev->mode_config.num_total_plane; i++) {
-   struct drm_plane *plane = state->planes[i];
-   struct drm_plane_state *new_state = state->plane_states[i];
-
-   if (!plane)
-   continue;
-
+   for_each_plane_in_state(state, plane, new_state, i) {
if ((plane->state->fb != new_state->fb) && new_state->fb) {
struct drm_gem_cma_object *cma_bo =
drm_fb_cma_get_gem_obj(new_state->fb, 0);
-- 
2.8.1



[PATCH 06/38] drm/omap: Use for_each_plane_in_state

2016-06-02 Thread Daniel Vetter
We want to hide drm_atomic_stat internals a bit better.

Cc: Laurent Pinchart 
Cc: Tomi Valkeinen 
Signed-off-by: Daniel Vetter 
---
 drivers/gpu/drm/omapdrm/omap_drv.c | 11 +--
 1 file changed, 5 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/omap_drv.c 
b/drivers/gpu/drm/omapdrm/omap_drv.c
index d86f5479345b..4798ba43ff5b 100644
--- a/drivers/gpu/drm/omapdrm/omap_drv.c
+++ b/drivers/gpu/drm/omapdrm/omap_drv.c
@@ -142,8 +142,9 @@ static int omap_atomic_commit(struct drm_device *dev,
 {
struct omap_drm_private *priv = dev->dev_private;
struct omap_atomic_state_commit *commit;
-   unsigned int i;
-   int ret;
+   struct drm_crtc *crtc;
+   struct drm_crtc_state *crtc_state;
+   int i, ret;

ret = drm_atomic_helper_prepare_planes(dev, state);
if (ret)
@@ -163,10 +164,8 @@ static int omap_atomic_commit(struct drm_device *dev,
/* Wait until all affected CRTCs have completed previous commits and
 * mark them as pending.
 */
-   for (i = 0; i < dev->mode_config.num_crtc; ++i) {
-   if (state->crtcs[i])
-   commit->crtcs |= 1 << drm_crtc_index(state->crtcs[i]);
-   }
+   for_each_crtc_in_state(state, crtc, crtc_state, i)
+   commit->crtcs |= 1 << drm_crtc_index(crtc);

wait_event(priv->commit.wait, !omap_atomic_is_pending(priv, commit));

-- 
2.8.1



[PATCH 07/38] drm/exynos: Use for_each_crtc_in_state

2016-06-02 Thread Daniel Vetter
We want to hide drm_atomic_state internals better.

Cc: Inki Dae 
Acked-by: Inki Dae 
Signed-off-by: Daniel Vetter 
---
 drivers/gpu/drm/exynos/exynos_drm_drv.c | 8 
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.c 
b/drivers/gpu/drm/exynos/exynos_drm_drv.c
index 2dd820e23b0c..cabc5fd0246d 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_drv.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_drv.c
@@ -267,6 +267,8 @@ int exynos_atomic_commit(struct drm_device *dev, struct 
drm_atomic_state *state,
 {
struct exynos_drm_private *priv = dev->dev_private;
struct exynos_atomic_commit *commit;
+   struct drm_crtc *crtc;
+   struct drm_crtc_state *crtc_state;
int i, ret;

commit = kzalloc(sizeof(*commit), GFP_KERNEL);
@@ -288,10 +290,8 @@ int exynos_atomic_commit(struct drm_device *dev, struct 
drm_atomic_state *state,
/* Wait until all affected CRTCs have completed previous commits and
 * mark them as pending.
 */
-   for (i = 0; i < dev->mode_config.num_crtc; ++i) {
-   if (state->crtcs[i])
-   commit->crtcs |= 1 << drm_crtc_index(state->crtcs[i]);
-   }
+   for_each_crtc_in_state(state, crtc, crtc_state, i)
+   commit->crtcs |= 1 << drm_crtc_index(crtc);

wait_event(priv->wait, !commit_is_pending(priv, commit->crtcs));

-- 
2.8.1



[PATCH 08/38] drm/atomic: Add __drm_atomic_get_current_plane_state

2016-06-02 Thread Daniel Vetter
... and use it in msm&vc4. Again just want to encapsulate
drm_atomic_state internals a bit.

The const threading is a bit awkward in vc4 since C sucks, but I still
think it's worth to enforce this. Eventually I want to make all the
obj->state pointers const too, but that's a lot more work ...

Cc: Eric Anholt 
Cc: Rob Clark 
Signed-off-by: Daniel Vetter 
---
 drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c | 10 +++--
 drivers/gpu/drm/vc4/vc4_crtc.c   | 11 +++---
 drivers/gpu/drm/vc4/vc4_drv.h|  2 +-
 drivers/gpu/drm/vc4/vc4_plane.c  |  5 +++--
 include/drm/drm_atomic.h | 36 
 5 files changed, 46 insertions(+), 18 deletions(-)

diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c 
b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c
index 88fe256c1931..6d4086ee0503 100644
--- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c
+++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c
@@ -383,19 +383,15 @@ static int mdp5_crtc_atomic_check(struct drm_crtc *crtc,
 */
hw_cfg = mdp5_cfg_get_hw_config(mdp5_kms->cfg);
drm_atomic_crtc_state_for_each_plane(plane, state) {
-   struct drm_plane_state *pstate;
+   const struct drm_plane_state *pstate;
if (cnt >= (hw_cfg->lm.nb_stages)) {
dev_err(dev->dev, "too many planes!\n");
return -EINVAL;
}

-   pstate = state->state->plane_states[drm_plane_index(plane)];
+   pstate = __drm_atomic_get_current_plane_state(state->state,
+ plane);

-   /* plane might not have changed, in which case take
-* current state:
-*/
-   if (!pstate)
-   pstate = plane->state;
pstates[cnt].plane = plane;
pstates[cnt].state = to_mdp5_plane_state(pstate);

diff --git a/drivers/gpu/drm/vc4/vc4_crtc.c b/drivers/gpu/drm/vc4/vc4_crtc.c
index 904d0754ad78..703bda170105 100644
--- a/drivers/gpu/drm/vc4/vc4_crtc.c
+++ b/drivers/gpu/drm/vc4/vc4_crtc.c
@@ -405,14 +405,9 @@ static int vc4_crtc_atomic_check(struct drm_crtc *crtc,
return -EINVAL;

drm_atomic_crtc_state_for_each_plane(plane, state) {
-   struct drm_plane_state *plane_state =
-   state->state->plane_states[drm_plane_index(plane)];
-
-   /* plane might not have changed, in which case take
-* current state:
-*/
-   if (!plane_state)
-   plane_state = plane->state;
+   const struct drm_plane_state *plane_state =
+   __drm_atomic_get_current_plane_state(state->state,
+plane);

dlist_count += vc4_plane_dlist_size(plane_state);
}
diff --git a/drivers/gpu/drm/vc4/vc4_drv.h b/drivers/gpu/drm/vc4/vc4_drv.h
index 37cac59401d7..c799baabc008 100644
--- a/drivers/gpu/drm/vc4/vc4_drv.h
+++ b/drivers/gpu/drm/vc4/vc4_drv.h
@@ -469,7 +469,7 @@ int vc4_kms_load(struct drm_device *dev);
 struct drm_plane *vc4_plane_init(struct drm_device *dev,
 enum drm_plane_type type);
 u32 vc4_plane_write_dlist(struct drm_plane *plane, u32 __iomem *dlist);
-u32 vc4_plane_dlist_size(struct drm_plane_state *state);
+u32 vc4_plane_dlist_size(const struct drm_plane_state *state);
 void vc4_plane_async_set_fb(struct drm_plane *plane,
struct drm_framebuffer *fb);

diff --git a/drivers/gpu/drm/vc4/vc4_plane.c b/drivers/gpu/drm/vc4/vc4_plane.c
index 4037b52fde31..5d2c3d9fd17a 100644
--- a/drivers/gpu/drm/vc4/vc4_plane.c
+++ b/drivers/gpu/drm/vc4/vc4_plane.c
@@ -690,9 +690,10 @@ u32 vc4_plane_write_dlist(struct drm_plane *plane, u32 
__iomem *dlist)
return vc4_state->dlist_count;
 }

-u32 vc4_plane_dlist_size(struct drm_plane_state *state)
+u32 vc4_plane_dlist_size(const struct drm_plane_state *state)
 {
-   struct vc4_plane_state *vc4_state = to_vc4_plane_state(state);
+   const struct vc4_plane_state *vc4_state =
+   container_of(state, typeof(*vc4_state), base);

return vc4_state->dlist_count;
 }
diff --git a/include/drm/drm_atomic.h b/include/drm/drm_atomic.h
index 92c84e9ab09a..4e97186293be 100644
--- a/include/drm/drm_atomic.h
+++ b/include/drm/drm_atomic.h
@@ -109,6 +109,42 @@ drm_atomic_get_existing_connector_state(struct 
drm_atomic_state *state,
return state->connector_states[index];
 }

+/**
+ * __drm_atomic_get_current_plane_state - get current plane state
+ * @state: global atomic state object
+ * @plane: plane to grab
+ *
+ * This function returns the plane state for the given plane, either from
+ * @state, or if the plane isn't part of the atomic state update, from @plane.
+ * This is useful in atomic check callbacks, when drivers need to peek at, but
+ * not c

[PATCH 09/38] drm: Consolidate connector arrays in drm_atomic_state

2016-06-02 Thread Daniel Vetter
It's kinda pointless to have 2 separate mallocs for these. And when we
add more per-connector state in the future it's even more pointless.

Right now there's no such thing planned, but both Gustavo's per-crtc
fence patches, and some nonblocking commit helpers I'm playing around
with will add more per-crtc stuff. It makes sense to also consolidate
connectors, just for consistency.

In the future we can use this to store a pointer to the preceeding
state, making an atomic update entirely free-standing. This will be
needed to be able to queue them up with a depth > 1.

Cc: Gustavo Padovan 
Signed-off-by: Daniel Vetter 
---
 drivers/gpu/drm/drm_atomic.c| 27 +--
 drivers/gpu/drm/drm_atomic_helper.c |  2 +-
 include/drm/drm_atomic.h| 10 +-
 include/drm/drm_crtc.h  | 11 +++
 4 files changed, 22 insertions(+), 28 deletions(-)

diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c
index c204ef32df16..8ca0ae21287f 100644
--- a/drivers/gpu/drm/drm_atomic.c
+++ b/drivers/gpu/drm/drm_atomic.c
@@ -44,7 +44,6 @@
 void drm_atomic_state_default_release(struct drm_atomic_state *state)
 {
kfree(state->connectors);
-   kfree(state->connector_states);
kfree(state->crtcs);
kfree(state->crtc_states);
kfree(state->planes);
@@ -139,15 +138,15 @@ void drm_atomic_state_default_clear(struct 
drm_atomic_state *state)
DRM_DEBUG_ATOMIC("Clearing atomic state %p\n", state);

for (i = 0; i < state->num_connector; i++) {
-   struct drm_connector *connector = state->connectors[i];
+   struct drm_connector *connector = state->connectors[i].ptr;

if (!connector)
continue;

connector->funcs->atomic_destroy_state(connector,
-  
state->connector_states[i]);
-   state->connectors[i] = NULL;
-   state->connector_states[i] = NULL;
+  
state->connectors[i].state);
+   state->connectors[i].ptr = NULL;
+   state->connectors[i].state = NULL;
drm_connector_unreference(connector);
}

@@ -897,8 +896,7 @@ drm_atomic_get_connector_state(struct drm_atomic_state 
*state,
index = drm_connector_index(connector);

if (index >= state->num_connector) {
-   struct drm_connector **c;
-   struct drm_connector_state **cs;
+   struct __drm_connnectors_state *c;
int alloc = max(index + 1, config->num_connector);

c = krealloc(state->connectors, alloc * 
sizeof(*state->connectors), GFP_KERNEL);
@@ -909,26 +907,19 @@ drm_atomic_get_connector_state(struct drm_atomic_state 
*state,
memset(&state->connectors[state->num_connector], 0,
   sizeof(*state->connectors) * (alloc - 
state->num_connector));

-   cs = krealloc(state->connector_states, alloc * 
sizeof(*state->connector_states), GFP_KERNEL);
-   if (!cs)
-   return ERR_PTR(-ENOMEM);
-
-   state->connector_states = cs;
-   memset(&state->connector_states[state->num_connector], 0,
-  sizeof(*state->connector_states) * (alloc - 
state->num_connector));
state->num_connector = alloc;
}

-   if (state->connector_states[index])
-   return state->connector_states[index];
+   if (state->connectors[index].state)
+   return state->connectors[index].state;

connector_state = connector->funcs->atomic_duplicate_state(connector);
if (!connector_state)
return ERR_PTR(-ENOMEM);

drm_connector_reference(connector);
-   state->connector_states[index] = connector_state;
-   state->connectors[index] = connector;
+   state->connectors[index].state = connector_state;
+   state->connectors[index].ptr = connector;
connector_state->state = state;

DRM_DEBUG_ATOMIC("Added [CONNECTOR:%d] %p state to %p\n",
diff --git a/drivers/gpu/drm/drm_atomic_helper.c 
b/drivers/gpu/drm/drm_atomic_helper.c
index 872dbc844d69..70504cbb3a9a 100644
--- a/drivers/gpu/drm/drm_atomic_helper.c
+++ b/drivers/gpu/drm/drm_atomic_helper.c
@@ -1570,7 +1570,7 @@ void drm_atomic_helper_swap_state(struct drm_device *dev,

for_each_connector_in_state(state, connector, conn_state, i) {
connector->state->state = state;
-   swap(state->connector_states[i], connector->state);
+   swap(state->connectors[i].state, connector->state);
connector->state->state = NULL;
}

diff --git a/include/drm/drm_atomic.h b/include/drm/drm_atomic.h
index 4e97186293be..37478adb6a16 100644
--- a/include/drm/drm_atomic.h
+++ b/include/drm/drm_atomic.h
@@ -106,7 +106,7 @@ drm_atomic_get_existing_connector_state(

[PATCH 11/38] drm: Consolidate crtc arrays in drm_atomic_state

2016-06-02 Thread Daniel Vetter
It's silly to have 2 mallocs when we could tie these two together.

Also, Gustavo adds another one in his per-crtc out-fence patches. And
I want to add more stuff here for nonblocking commit helpers.

In the future we can use this to store a pointer to the preceeding
state, making an atomic update entirely free-standing. This will be
needed to be able to queue them up with a depth > 1.

Cc: Gustavo Padovan 
Signed-off-by: Daniel Vetter 
---
 drivers/gpu/drm/drm_atomic.c| 17 ++---
 drivers/gpu/drm/drm_atomic_helper.c |  2 +-
 include/drm/drm_atomic.h| 10 +-
 include/drm/drm_crtc.h  |  8 ++--
 4 files changed, 18 insertions(+), 19 deletions(-)

diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c
index dce4627aa1c6..5093d81f60f7 100644
--- a/drivers/gpu/drm/drm_atomic.c
+++ b/drivers/gpu/drm/drm_atomic.c
@@ -45,7 +45,6 @@ void drm_atomic_state_default_release(struct drm_atomic_state 
*state)
 {
kfree(state->connectors);
kfree(state->crtcs);
-   kfree(state->crtc_states);
kfree(state->planes);
 }
 EXPORT_SYMBOL(drm_atomic_state_default_release);
@@ -70,10 +69,6 @@ drm_atomic_state_init(struct drm_device *dev, struct 
drm_atomic_state *state)
   sizeof(*state->crtcs), GFP_KERNEL);
if (!state->crtcs)
goto fail;
-   state->crtc_states = kcalloc(dev->mode_config.num_crtc,
-sizeof(*state->crtc_states), GFP_KERNEL);
-   if (!state->crtc_states)
-   goto fail;
state->planes = kcalloc(dev->mode_config.num_total_plane,
sizeof(*state->planes), GFP_KERNEL);
if (!state->planes)
@@ -146,15 +141,15 @@ void drm_atomic_state_default_clear(struct 
drm_atomic_state *state)
}

for (i = 0; i < config->num_crtc; i++) {
-   struct drm_crtc *crtc = state->crtcs[i];
+   struct drm_crtc *crtc = state->crtcs[i].ptr;

if (!crtc)
continue;

crtc->funcs->atomic_destroy_state(crtc,
- state->crtc_states[i]);
-   state->crtcs[i] = NULL;
-   state->crtc_states[i] = NULL;
+ state->crtcs[i].state);
+   state->crtcs[i].ptr = NULL;
+   state->crtcs[i].state = NULL;
}

for (i = 0; i < config->num_total_plane; i++) {
@@ -264,8 +259,8 @@ drm_atomic_get_crtc_state(struct drm_atomic_state *state,
if (!crtc_state)
return ERR_PTR(-ENOMEM);

-   state->crtc_states[index] = crtc_state;
-   state->crtcs[index] = crtc;
+   state->crtcs[index].state = crtc_state;
+   state->crtcs[index].ptr = crtc;
crtc_state->state = state;

DRM_DEBUG_ATOMIC("Added [CRTC:%d:%s] %p state to %p\n",
diff --git a/drivers/gpu/drm/drm_atomic_helper.c 
b/drivers/gpu/drm/drm_atomic_helper.c
index 451b86ecd253..b2d276d97d32 100644
--- a/drivers/gpu/drm/drm_atomic_helper.c
+++ b/drivers/gpu/drm/drm_atomic_helper.c
@@ -1576,7 +1576,7 @@ void drm_atomic_helper_swap_state(struct drm_device *dev,

for_each_crtc_in_state(state, crtc, crtc_state, i) {
crtc->state->state = state;
-   swap(state->crtc_states[i], crtc->state);
+   swap(state->crtcs[i].state, crtc->state);
crtc->state->state = NULL;
}

diff --git a/include/drm/drm_atomic.h b/include/drm/drm_atomic.h
index 8e616d39353b..d9504dfcd1cc 100644
--- a/include/drm/drm_atomic.h
+++ b/include/drm/drm_atomic.h
@@ -71,7 +71,7 @@ static inline struct drm_crtc_state *
 drm_atomic_get_existing_crtc_state(struct drm_atomic_state *state,
   struct drm_crtc *crtc)
 {
-   return state->crtc_states[drm_crtc_index(crtc)];
+   return state->crtcs[drm_crtc_index(crtc)].state;
 }

 /**
@@ -183,11 +183,11 @@ int __must_check drm_atomic_nonblocking_commit(struct 
drm_atomic_state *state);
 (__i)++)   \
for_each_if (connector)

-#define for_each_crtc_in_state(state, crtc, crtc_state, __i)   \
+#define for_each_crtc_in_state(__state, crtc, crtc_state, __i) \
for ((__i) = 0; \
-(__i) < (state)->dev->mode_config.num_crtc &&  \
-((crtc) = (state)->crtcs[__i], \
-(crtc_state) = (state)->crtc_states[__i], 1);  \
+(__i) < (__state)->dev->mode_config.num_crtc &&\
+((crtc) = (__state)->crtcs[__i].ptr,   \
+(crtc_state) = (__state)->crtcs[__i].state, 1);\
 (__i)++)   \
for_each_if (crtc_state)

diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h
index c7c2b3fa7179..d5d

[PATCH 10/38] drm: Consolidate plane arrays in drm_atomic_state

2016-06-02 Thread Daniel Vetter
It's kinda pointless to have 2 separate mallocs for these. And when we
add more per-plane state in the future it's even more pointless.

Right now there's no such thing planned, but both Gustavo's per-crtc
fence patches, and some nonblocking commit helpers I'm playing around
with will add more per-crtc stuff. It makes sense to also consolidate
planes, just for consistency.

In the future we can use this to store a pointer to the preceeding
state, making an atomic update entirely free-standing. This will be
needed to be able to queue them up with a depth > 1.

Cc: Gustavo Padovan 
Signed-off-by: Daniel Vetter 
---
 drivers/gpu/drm/drm_atomic.c| 17 ++---
 drivers/gpu/drm/drm_atomic_helper.c |  2 +-
 drivers/gpu/drm/i915/intel_atomic.c |  2 +-
 include/drm/drm_atomic.h| 14 +++---
 include/drm/drm_crtc.h  | 11 +++
 5 files changed, 22 insertions(+), 24 deletions(-)

diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c
index 8ca0ae21287f..dce4627aa1c6 100644
--- a/drivers/gpu/drm/drm_atomic.c
+++ b/drivers/gpu/drm/drm_atomic.c
@@ -47,7 +47,6 @@ void drm_atomic_state_default_release(struct drm_atomic_state 
*state)
kfree(state->crtcs);
kfree(state->crtc_states);
kfree(state->planes);
-   kfree(state->plane_states);
 }
 EXPORT_SYMBOL(drm_atomic_state_default_release);

@@ -79,10 +78,6 @@ drm_atomic_state_init(struct drm_device *dev, struct 
drm_atomic_state *state)
sizeof(*state->planes), GFP_KERNEL);
if (!state->planes)
goto fail;
-   state->plane_states = kcalloc(dev->mode_config.num_total_plane,
- sizeof(*state->plane_states), GFP_KERNEL);
-   if (!state->plane_states)
-   goto fail;

state->dev = dev;

@@ -163,15 +158,15 @@ void drm_atomic_state_default_clear(struct 
drm_atomic_state *state)
}

for (i = 0; i < config->num_total_plane; i++) {
-   struct drm_plane *plane = state->planes[i];
+   struct drm_plane *plane = state->planes[i].ptr;

if (!plane)
continue;

plane->funcs->atomic_destroy_state(plane,
-  state->plane_states[i]);
-   state->planes[i] = NULL;
-   state->plane_states[i] = NULL;
+  state->planes[i].state);
+   state->planes[i].ptr = NULL;
+   state->planes[i].state = NULL;
}
 }
 EXPORT_SYMBOL(drm_atomic_state_default_clear);
@@ -631,8 +626,8 @@ drm_atomic_get_plane_state(struct drm_atomic_state *state,
if (!plane_state)
return ERR_PTR(-ENOMEM);

-   state->plane_states[index] = plane_state;
-   state->planes[index] = plane;
+   state->planes[index].state = plane_state;
+   state->planes[index].ptr = plane;
plane_state->state = state;

DRM_DEBUG_ATOMIC("Added [PLANE:%d:%s] %p state to %p\n",
diff --git a/drivers/gpu/drm/drm_atomic_helper.c 
b/drivers/gpu/drm/drm_atomic_helper.c
index 70504cbb3a9a..451b86ecd253 100644
--- a/drivers/gpu/drm/drm_atomic_helper.c
+++ b/drivers/gpu/drm/drm_atomic_helper.c
@@ -1582,7 +1582,7 @@ void drm_atomic_helper_swap_state(struct drm_device *dev,

for_each_plane_in_state(state, plane, plane_state, i) {
plane->state->state = state;
-   swap(state->plane_states[i], plane->state);
+   swap(state->planes[i].state, plane->state);
plane->state->state = NULL;
}
 }
diff --git a/drivers/gpu/drm/i915/intel_atomic.c 
b/drivers/gpu/drm/i915/intel_atomic.c
index 3e6d9ff8840a..7542f5f5db1d 100644
--- a/drivers/gpu/drm/i915/intel_atomic.c
+++ b/drivers/gpu/drm/i915/intel_atomic.c
@@ -191,7 +191,7 @@ int intel_atomic_setup_scalers(struct drm_device *dev,

/* plane scaler case: assign as a plane scaler */
/* find the plane that set the bit as scaler_user */
-   plane = drm_state->planes[i];
+   plane = drm_state->planes[i].ptr;

/*
 * to enable/disable hq mode, add planes that are using 
scaler
diff --git a/include/drm/drm_atomic.h b/include/drm/drm_atomic.h
index 37478adb6a16..8e616d39353b 100644
--- a/include/drm/drm_atomic.h
+++ b/include/drm/drm_atomic.h
@@ -86,7 +86,7 @@ static inline struct drm_plane_state *
 drm_atomic_get_existing_plane_state(struct drm_atomic_state *state,
struct drm_plane *plane)
 {
-   return state->plane_states[drm_plane_index(plane)];
+   return state->planes[drm_plane_index(plane)].state;
 }

 /**
@@ -139,8 +139,8 @@ static inline const struct drm_plane_state *
 __drm_atomic_get_current_plane_state(struct drm_atomic_state *state,
 struct drm_pla

[PATCH 12/38] drm/fence: add fence to drm_pending_event

2016-06-02 Thread Daniel Vetter
From: Gustavo Padovan 

Now a drm_pending_event can either send a real drm_event or signal a
fence, or both. It allow us to signal via fences when the buffer is
displayed on the screen. Which in turn means that the previous buffer
is not in use anymore and can be freed or sent back to another driver
for processing.

v2: Comments from Daniel Vetter
- call fence_signal in drm_send_event_locked()
- remove unneeded !e->event check

v3: Remove drm_pending_event->destroy to fix a leak when e->file_priv
is not set.

Signed-off-by: Gustavo Padovan  (v2)
Signed-off-by: Daniel Vetter 
---
 drivers/gpu/drm/drm_atomic.c| 19 +--
 drivers/gpu/drm/drm_fops.c  | 16 +---
 drivers/gpu/drm/nouveau/nouveau_usif.c  |  1 -
 drivers/gpu/drm/rockchip/rockchip_drm_vop.c |  2 +-
 include/drm/drmP.h  |  3 ++-
 5 files changed, 25 insertions(+), 16 deletions(-)

diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c
index 5093d81f60f7..5e4b820a977c 100644
--- a/drivers/gpu/drm/drm_atomic.c
+++ b/drivers/gpu/drm/drm_atomic.c
@@ -1413,7 +1413,8 @@ EXPORT_SYMBOL(drm_atomic_nonblocking_commit);
  */

 static struct drm_pending_vblank_event *create_vblank_event(
-   struct drm_device *dev, struct drm_file *file_priv, uint64_t 
user_data)
+   struct drm_device *dev, struct drm_file *file_priv,
+   struct fence *fence, uint64_t user_data)
 {
struct drm_pending_vblank_event *e = NULL;
int ret;
@@ -1426,12 +1427,17 @@ static struct drm_pending_vblank_event 
*create_vblank_event(
e->event.base.length = sizeof(e->event);
e->event.user_data = user_data;

-   ret = drm_event_reserve_init(dev, file_priv, &e->base, &e->event.base);
-   if (ret) {
-   kfree(e);
-   return NULL;
+   if (file_priv) {
+   ret = drm_event_reserve_init(dev, file_priv, &e->base,
+&e->event.base);
+   if (ret) {
+   kfree(e);
+   return NULL;
+   }
}

+   e->base.fence = fence;
+
return e;
 }

@@ -1671,7 +1677,8 @@ retry:
for_each_crtc_in_state(state, crtc, crtc_state, i) {
struct drm_pending_vblank_event *e;

-   e = create_vblank_event(dev, file_priv, arg->user_data);
+   e = create_vblank_event(dev, file_priv, NULL,
+   arg->user_data);
if (!e) {
ret = -ENOMEM;
goto out;
diff --git a/drivers/gpu/drm/drm_fops.c b/drivers/gpu/drm/drm_fops.c
index 868871068956..4c4b30f7a9f2 100644
--- a/drivers/gpu/drm/drm_fops.c
+++ b/drivers/gpu/drm/drm_fops.c
@@ -294,7 +294,7 @@ static void drm_events_release(struct drm_file *file_priv)
/* Remove unconsumed events */
list_for_each_entry_safe(e, et, &file_priv->event_list, link) {
list_del(&e->link);
-   e->destroy(e);
+   kfree(e);
}

spin_unlock_irqrestore(&dev->event_lock, flags);
@@ -525,7 +525,7 @@ put_back_event:
}

ret += length;
-   e->destroy(e);
+   kfree(e);
}
}
mutex_unlock(&file_priv->event_read_lock);
@@ -602,9 +602,6 @@ int drm_event_reserve_init_locked(struct drm_device *dev,
list_add(&p->pending_link, &file_priv->pending_event_list);
p->file_priv = file_priv;

-   /* we *could* pass this in as arg, but everyone uses kfree: */
-   p->destroy = (void (*) (struct drm_pending_event *)) kfree;
-
return 0;
 }
 EXPORT_SYMBOL(drm_event_reserve_init_locked);
@@ -667,7 +664,7 @@ void drm_event_cancel_free(struct drm_device *dev,
list_del(&p->pending_link);
}
spin_unlock_irqrestore(&dev->event_lock, flags);
-   p->destroy(p);
+   kfree(p);
 }
 EXPORT_SYMBOL(drm_event_cancel_free);

@@ -689,8 +686,13 @@ void drm_send_event_locked(struct drm_device *dev, struct 
drm_pending_event *e)
 {
assert_spin_locked(&dev->event_lock);

+   if (e->fence) {
+   fence_signal(e->fence);
+   fence_put(e->fence);
+   }
+
if (!e->file_priv) {
-   e->destroy(e);
+   kfree(e);
return;
}

diff --git a/drivers/gpu/drm/nouveau/nouveau_usif.c 
b/drivers/gpu/drm/nouveau/nouveau_usif.c
index 675e9e077a95..08f9c6fa0f7f 100644
--- a/drivers/gpu/drm/nouveau/nouveau_usif.c
+++ b/drivers/gpu/drm/nouveau/nouveau_usif.c
@@ -212,7 +212,6 @@ usif_notify_get(struct drm_file *f, void *data, u32 size, 
void *argv, u32 argc)
ntfy->p->base.event = &ntfy->p->e.base;
ntfy->p->base.file_priv = f;
ntfy->p->base.pid = current->pid;
- 

[PATCH 13/38] drm/atomic-helper: Massage swap_state signature somewhat

2016-06-02 Thread Daniel Vetter
- dev is redundant, we have state->atomic
- add stall parameter, which must be set when swapping needs to stall
  for preceeding commits to stop looking at ->state pointers. Currently
  all drivers need this to be, just prep work for a glorious future.

Signed-off-by: Daniel Vetter 
---
 drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.c | 2 +-
 drivers/gpu/drm/drm_atomic_helper.c  | 8 
 drivers/gpu/drm/exynos/exynos_drm_drv.c  | 2 +-
 drivers/gpu/drm/i915/intel_display.c | 2 +-
 drivers/gpu/drm/mediatek/mtk_drm_drv.c   | 2 +-
 drivers/gpu/drm/msm/msm_atomic.c | 2 +-
 drivers/gpu/drm/omapdrm/omap_drv.c   | 2 +-
 drivers/gpu/drm/rcar-du/rcar_du_kms.c| 2 +-
 drivers/gpu/drm/rockchip/rockchip_drm_fb.c   | 2 +-
 drivers/gpu/drm/sti/sti_drv.c| 2 +-
 drivers/gpu/drm/tegra/drm.c  | 2 +-
 drivers/gpu/drm/vc4/vc4_kms.c| 2 +-
 include/drm/drm_atomic_helper.h  | 4 ++--
 13 files changed, 17 insertions(+), 17 deletions(-)

diff --git a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.c 
b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.c
index 6485fa5bee8b..9ecf16c7911d 100644
--- a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.c
+++ b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.c
@@ -519,7 +519,7 @@ static int atmel_hlcdc_dc_atomic_commit(struct drm_device 
*dev,
}

/* Swap the state, this is the point of no return. */
-   drm_atomic_helper_swap_state(dev, state);
+   drm_atomic_helper_swap_state(state, true);

if (async)
queue_work(dc->wq, &commit->work);
diff --git a/drivers/gpu/drm/drm_atomic_helper.c 
b/drivers/gpu/drm/drm_atomic_helper.c
index b2d276d97d32..65128f258f84 100644
--- a/drivers/gpu/drm/drm_atomic_helper.c
+++ b/drivers/gpu/drm/drm_atomic_helper.c
@@ -1163,7 +1163,7 @@ int drm_atomic_helper_commit(struct drm_device *dev,
 * the software side now.
 */

-   drm_atomic_helper_swap_state(dev, state);
+   drm_atomic_helper_swap_state(state, true);

/*
 * Everything below can be run asynchronously without the need to grab
@@ -1534,8 +1534,8 @@ EXPORT_SYMBOL(drm_atomic_helper_cleanup_planes);

 /**
  * drm_atomic_helper_swap_state - store atomic state into current sw state
- * @dev: DRM device
  * @state: atomic state
+ * @stall: stall for proceeding commits
  *
  * This function stores the atomic state into the current state pointers in all
  * driver objects. It should be called after all failing steps have been done
@@ -1557,8 +1557,8 @@ EXPORT_SYMBOL(drm_atomic_helper_cleanup_planes);
  * 5. Call drm_atomic_helper_cleanup_planes() with @state, which since step 3
  * contains the old state. Also do any other cleanup required with that state.
  */
-void drm_atomic_helper_swap_state(struct drm_device *dev,
- struct drm_atomic_state *state)
+void drm_atomic_helper_swap_state(struct drm_atomic_state *state,
+ bool stall)
 {
int i;
struct drm_connector *connector;
diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.c 
b/drivers/gpu/drm/exynos/exynos_drm_drv.c
index cabc5fd0246d..deba76982358 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_drv.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_drv.c
@@ -299,7 +299,7 @@ int exynos_atomic_commit(struct drm_device *dev, struct 
drm_atomic_state *state,
priv->pending |= commit->crtcs;
spin_unlock(&priv->lock);

-   drm_atomic_helper_swap_state(dev, state);
+   drm_atomic_helper_swap_state(state, true);

if (nonblock)
schedule_work(&commit->work);
diff --git a/drivers/gpu/drm/i915/intel_display.c 
b/drivers/gpu/drm/i915/intel_display.c
index 60cba1956c0d..a59cc0e2e5ca 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -13726,7 +13726,7 @@ static int intel_atomic_commit(struct drm_device *dev,
return ret;
}

-   drm_atomic_helper_swap_state(dev, state);
+   drm_atomic_helper_swap_state(state, true);
dev_priv->wm.distrust_bios_wm = false;
dev_priv->wm.skl_results = intel_state->wm_results;
intel_shared_dpll_commit(state);
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.c 
b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
index b7e5f4a736f0..04e901a80234 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_drv.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
@@ -91,7 +91,7 @@ static int mtk_atomic_commit(struct drm_device *drm,
mutex_lock(&private->commit.lock);
flush_work(&private->commit.work);

-   drm_atomic_helper_swap_state(drm, state);
+   drm_atomic_helper_swap_state(state, true);

if (async)
mtk_atomic_schedule(private, state);
diff --git a/drivers/gpu/drm/msm/msm_atomic.c b/drivers/gpu/drm/msm/msm_atomic.c
index 9c0e4261dbba..d02bd6a50e90 100644
--- a/drivers/gpu/drm/msm/msm_atomic.c
+++ b/drivers/gpu/drm/msm/msm_atomic.c
@@ -238

[PATCH 14/38] drm/arc: Nuke event_list

2016-06-02 Thread Daniel Vetter
This is just used for cleanup in preclose, and with the reworked event
handling code this is now done properly by the core.

Nuke it!

But it also shows that arc totally fails at sending out drm events for
flips. Next patch will hack that up.

Cc: Carlos Palminha 
Cc: Alexey Brodkin 
Cc: linux-snps-arc at lists.infradead.org
Signed-off-by: Daniel Vetter 
---
 drivers/gpu/drm/arc/arcpgu.h  |  1 -
 drivers/gpu/drm/arc/arcpgu_crtc.c |  4 
 drivers/gpu/drm/arc/arcpgu_drv.c  | 19 ---
 3 files changed, 24 deletions(-)

diff --git a/drivers/gpu/drm/arc/arcpgu.h b/drivers/gpu/drm/arc/arcpgu.h
index 86574b698a78..8c01a25d279a 100644
--- a/drivers/gpu/drm/arc/arcpgu.h
+++ b/drivers/gpu/drm/arc/arcpgu.h
@@ -22,7 +22,6 @@ struct arcpgu_drm_private {
struct clk  *clk;
struct drm_fbdev_cma*fbdev;
struct drm_framebuffer  *fb;
-   struct list_headevent_list;
struct drm_crtc crtc;
struct drm_plane*plane;
 };
diff --git a/drivers/gpu/drm/arc/arcpgu_crtc.c 
b/drivers/gpu/drm/arc/arcpgu_crtc.c
index 92f8beff8e60..d5ca0c280e68 100644
--- a/drivers/gpu/drm/arc/arcpgu_crtc.c
+++ b/drivers/gpu/drm/arc/arcpgu_crtc.c
@@ -155,10 +155,6 @@ static void arc_pgu_crtc_atomic_begin(struct drm_crtc 
*crtc,
event->pipe = drm_crtc_index(crtc);

WARN_ON(drm_crtc_vblank_get(crtc) != 0);
-
-   spin_lock_irqsave(&crtc->dev->event_lock, flags);
-   list_add_tail(&event->base.link, &arcpgu->event_list);
-   spin_unlock_irqrestore(&crtc->dev->event_lock, flags);
}
 }

diff --git a/drivers/gpu/drm/arc/arcpgu_drv.c b/drivers/gpu/drm/arc/arcpgu_drv.c
index bc53ebb83f75..d407fd79a400 100644
--- a/drivers/gpu/drm/arc/arcpgu_drv.c
+++ b/drivers/gpu/drm/arc/arcpgu_drv.c
@@ -81,22 +81,6 @@ static const struct file_operations arcpgu_drm_ops = {
.mmap = arcpgu_gem_mmap,
 };

-static void arcpgu_preclose(struct drm_device *drm, struct drm_file *file)
-{
-   struct arcpgu_drm_private *arcpgu = drm->dev_private;
-   struct drm_pending_vblank_event *e, *t;
-   unsigned long flags;
-
-   spin_lock_irqsave(&drm->event_lock, flags);
-   list_for_each_entry_safe(e, t, &arcpgu->event_list, base.link) {
-   if (e->base.file_priv != file)
-   continue;
-   list_del(&e->base.link);
-   e->base.destroy(&e->base);
-   }
-   spin_unlock_irqrestore(&drm->event_lock, flags);
-}
-
 static void arcpgu_lastclose(struct drm_device *drm)
 {
struct arcpgu_drm_private *arcpgu = drm->dev_private;
@@ -122,8 +106,6 @@ static int arcpgu_load(struct drm_device *drm)
if (IS_ERR(arcpgu->clk))
return PTR_ERR(arcpgu->clk);

-   INIT_LIST_HEAD(&arcpgu->event_list);
-
arcpgu_setup_mode_config(drm);

res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
@@ -192,7 +174,6 @@ int arcpgu_unload(struct drm_device *drm)
 static struct drm_driver arcpgu_drm_driver = {
.driver_features = DRIVER_MODESET | DRIVER_GEM | DRIVER_PRIME |
   DRIVER_ATOMIC,
-   .preclose = arcpgu_preclose,
.lastclose = arcpgu_lastclose,
.name = "drm-arcpgu",
.desc = "ARC PGU Controller",
-- 
2.8.1



[PATCH 15/38] drm/arc: Actually bother with handling atomic events.

2016-06-02 Thread Daniel Vetter
The drm core has a nice ready-made helper for exactly the simple case
where it should fire on the next vblank.

Note that arming the vblank event in _begin is probably too early, and
might easily result in the vblank firing too early, before the new set
of planes are actually disabled. But that's kinda a minor issue
compared to just outright hanging userspace.

v2: Be more robust and either arm, when the CRTC is on, or just send
the event out right away.

Cc: Carlos Palminha 
Cc: Alexey Brodkin 
Cc: linux-snps-arc at lists.infradead.org
Signed-off-by: Daniel Vetter 
---
 drivers/gpu/drm/arc/arcpgu_crtc.c | 15 ---
 1 file changed, 8 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/arc/arcpgu_crtc.c 
b/drivers/gpu/drm/arc/arcpgu_crtc.c
index d5ca0c280e68..c9f183b11df9 100644
--- a/drivers/gpu/drm/arc/arcpgu_crtc.c
+++ b/drivers/gpu/drm/arc/arcpgu_crtc.c
@@ -145,16 +145,17 @@ static int arc_pgu_crtc_atomic_check(struct drm_crtc 
*crtc,
 static void arc_pgu_crtc_atomic_begin(struct drm_crtc *crtc,
  struct drm_crtc_state *state)
 {
-   struct arcpgu_drm_private *arcpgu = crtc_to_arcpgu_priv(crtc);
-   unsigned long flags;
-
-   if (crtc->state->event) {
-   struct drm_pending_vblank_event *event = crtc->state->event;
+   struct drm_pending_vblank_event *event = crtc->state->event;

+   if (event) {
crtc->state->event = NULL;
-   event->pipe = drm_crtc_index(crtc);

-   WARN_ON(drm_crtc_vblank_get(crtc) != 0);
+   spin_lock_irq(&crtc->dev->event_lock);
+   if (drm_crtc_vblank_get(crtc) == 0)
+   drm_crtc_arm_vblank_event(crtc, event);
+   else
+   drm_crtc_send_vblank_event(crtc, event);
+   spin_unlock_irq(&crtc->dev->event_lock);
}
 }

-- 
2.8.1



[PATCH 16/38] drm/hdlcd: Clean up crtc hooks

2016-06-02 Thread Daniel Vetter
Those are all no longer needed for a pure atomic driver.

Cc: Liviu Dudau 
Tested-by: Liviu Dudau 
Acked-by: Liviu Dudau 
Signed-off-by: Daniel Vetter 
---
 drivers/gpu/drm/arm/hdlcd_crtc.c | 19 ---
 1 file changed, 19 deletions(-)

diff --git a/drivers/gpu/drm/arm/hdlcd_crtc.c b/drivers/gpu/drm/arm/hdlcd_crtc.c
index fef1b04c2aab..b44f72722764 100644
--- a/drivers/gpu/drm/arm/hdlcd_crtc.c
+++ b/drivers/gpu/drm/arm/hdlcd_crtc.c
@@ -196,30 +196,11 @@ static void hdlcd_crtc_atomic_begin(struct drm_crtc *crtc,
}
 }

-static void hdlcd_crtc_atomic_flush(struct drm_crtc *crtc,
-   struct drm_crtc_state *state)
-{
-}
-
-static bool hdlcd_crtc_mode_fixup(struct drm_crtc *crtc,
-   const struct drm_display_mode *mode,
-   struct drm_display_mode *adjusted_mode)
-{
-   return true;
-}
-
 static const struct drm_crtc_helper_funcs hdlcd_crtc_helper_funcs = {
-   .mode_fixup = hdlcd_crtc_mode_fixup,
-   .mode_set   = drm_helper_crtc_mode_set,
-   .mode_set_base  = drm_helper_crtc_mode_set_base,
-   .mode_set_nofb  = hdlcd_crtc_mode_set_nofb,
.enable = hdlcd_crtc_enable,
.disable= hdlcd_crtc_disable,
-   .prepare= hdlcd_crtc_disable,
-   .commit = hdlcd_crtc_enable,
.atomic_check   = hdlcd_crtc_atomic_check,
.atomic_begin   = hdlcd_crtc_atomic_begin,
-   .atomic_flush   = hdlcd_crtc_atomic_flush,
 };

 static int hdlcd_plane_atomic_check(struct drm_plane *plane,
-- 
2.8.1



[PATCH 17/38] drm/hdlcd: Fix up crtc_state->event handling

2016-06-02 Thread Daniel Vetter
event_list just reimplemented what drm_crtc_arm_vblank_event does. And
we also need to send out drm events when shutting down a pipe.

With this it's possible to use the new nonblocking commit support in
the helpers.

Cc: Liviu Dudau 
Tested-by: Liviu Dudau 
Acked-by: Liviu Dudau 
Signed-off-by: Daniel Vetter 
---
 drivers/gpu/drm/arm/hdlcd_crtc.c | 18 --
 drivers/gpu/drm/arm/hdlcd_drv.c  | 19 +--
 drivers/gpu/drm/arm/hdlcd_drv.h  |  1 -
 3 files changed, 9 insertions(+), 29 deletions(-)

diff --git a/drivers/gpu/drm/arm/hdlcd_crtc.c b/drivers/gpu/drm/arm/hdlcd_crtc.c
index b44f72722764..93486c46c6b0 100644
--- a/drivers/gpu/drm/arm/hdlcd_crtc.c
+++ b/drivers/gpu/drm/arm/hdlcd_crtc.c
@@ -180,19 +180,17 @@ static void hdlcd_crtc_atomic_begin(struct drm_crtc *crtc,
struct drm_crtc_state *state)
 {
struct hdlcd_drm_private *hdlcd = crtc_to_hdlcd_priv(crtc);
-   unsigned long flags;
-
-   if (crtc->state->event) {
-   struct drm_pending_vblank_event *event = crtc->state->event;
+   struct drm_pending_vblank_event *event = crtc->state->event;

+   if (event) {
crtc->state->event = NULL;
-   event->pipe = drm_crtc_index(crtc);
-
-   WARN_ON(drm_crtc_vblank_get(crtc) != 0);

-   spin_lock_irqsave(&crtc->dev->event_lock, flags);
-   list_add_tail(&event->base.link, &hdlcd->event_list);
-   spin_unlock_irqrestore(&crtc->dev->event_lock, flags);
+   spin_lock_irq(&crtc->dev->event_lock);
+   if (drm_crtc_vblank_get(crtc) == 0)
+   drm_crtc_arm_vblank_event(crtc, event);
+   else
+   drm_crtc_send_vblank_event(crtc, event);
+   spin_unlock_irq(&crtc->dev->event_lock);
}
 }

diff --git a/drivers/gpu/drm/arm/hdlcd_drv.c b/drivers/gpu/drm/arm/hdlcd_drv.c
index 4f909378d581..5178f3489897 100644
--- a/drivers/gpu/drm/arm/hdlcd_drv.c
+++ b/drivers/gpu/drm/arm/hdlcd_drv.c
@@ -49,8 +49,6 @@ static int hdlcd_load(struct drm_device *drm, unsigned long 
flags)
atomic_set(&hdlcd->dma_end_count, 0);
 #endif

-   INIT_LIST_HEAD(&hdlcd->event_list);
-
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
hdlcd->mmio = devm_ioremap_resource(drm->dev, res);
if (IS_ERR(hdlcd->mmio)) {
@@ -164,24 +162,9 @@ static irqreturn_t hdlcd_irq(int irq, void *arg)
atomic_inc(&hdlcd->vsync_count);

 #endif
-   if (irq_status & HDLCD_INTERRUPT_VSYNC) {
-   bool events_sent = false;
-   unsigned long flags;
-   struct drm_pending_vblank_event *e, *t;
-
+   if (irq_status & HDLCD_INTERRUPT_VSYNC)
drm_crtc_handle_vblank(&hdlcd->crtc);

-   spin_lock_irqsave(&drm->event_lock, flags);
-   list_for_each_entry_safe(e, t, &hdlcd->event_list, base.link) {
-   list_del(&e->base.link);
-   drm_crtc_send_vblank_event(&hdlcd->crtc, e);
-   events_sent = true;
-   }
-   if (events_sent)
-   drm_crtc_vblank_put(&hdlcd->crtc);
-   spin_unlock_irqrestore(&drm->event_lock, flags);
-   }
-
/* acknowledge interrupt(s) */
hdlcd_write(hdlcd, HDLCD_REG_INT_CLEAR, irq_status);

diff --git a/drivers/gpu/drm/arm/hdlcd_drv.h b/drivers/gpu/drm/arm/hdlcd_drv.h
index aa234784f053..cfd7c73a705e 100644
--- a/drivers/gpu/drm/arm/hdlcd_drv.h
+++ b/drivers/gpu/drm/arm/hdlcd_drv.h
@@ -10,7 +10,6 @@ struct hdlcd_drm_private {
struct clk  *clk;
struct drm_fbdev_cma*fbdev;
struct drm_framebuffer  *fb;
-   struct list_headevent_list;
struct drm_crtc crtc;
struct drm_plane*plane;
 #ifdef CONFIG_DEBUG_FS
-- 
2.8.1



[PATCH 18/38] drm/fsl-du: Implement some semblance of vblank event handling

2016-06-02 Thread Daniel Vetter
No idea how exactly fsl-du commits hw state changes, but here in flush
is probably the safest place.

While at it nuke the dummy functions.

v2: Be more robust and either arm, when the CRTC is on, or just send
the event out right away.

Cc: Stefan Agner 
Signed-off-by: Daniel Vetter 
---
 drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_crtc.c | 23 +++
 1 file changed, 11 insertions(+), 12 deletions(-)

diff --git a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_crtc.c 
b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_crtc.c
index 89c0084c2814..706de3278f1c 100644
--- a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_crtc.c
+++ b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_crtc.c
@@ -22,20 +22,21 @@
 #include "fsl_dcu_drm_drv.h"
 #include "fsl_dcu_drm_plane.h"

-static void fsl_dcu_drm_crtc_atomic_begin(struct drm_crtc *crtc,
+static void fsl_dcu_drm_crtc_atomic_flush(struct drm_crtc *crtc,
  struct drm_crtc_state *old_crtc_state)
 {
-}
+   struct drm_pending_vblank_event *event = crtc->state->event;

-static int fsl_dcu_drm_crtc_atomic_check(struct drm_crtc *crtc,
-struct drm_crtc_state *state)
-{
-   return 0;
-}
+   if (event) {
+   crtc->state->event = NULL;

-static void fsl_dcu_drm_crtc_atomic_flush(struct drm_crtc *crtc,
- struct drm_crtc_state *old_crtc_state)
-{
+   spin_lock_irq(&crtc->dev->event_lock);
+   if (drm_crtc_vblank_get(crtc) == 0)
+   drm_crtc_arm_vblank_event(crtc, event);
+   else
+   drm_crtc_send_vblank_event(crtc, event);
+   spin_unlock_irq(&crtc->dev->event_lock);
+   }
 }

 static void fsl_dcu_drm_disable_crtc(struct drm_crtc *crtc)
@@ -117,8 +118,6 @@ static void fsl_dcu_drm_crtc_mode_set_nofb(struct drm_crtc 
*crtc)
 }

 static const struct drm_crtc_helper_funcs fsl_dcu_drm_crtc_helper_funcs = {
-   .atomic_begin = fsl_dcu_drm_crtc_atomic_begin,
-   .atomic_check = fsl_dcu_drm_crtc_atomic_check,
.atomic_flush = fsl_dcu_drm_crtc_atomic_flush,
.disable = fsl_dcu_drm_disable_crtc,
.enable = fsl_dcu_drm_crtc_enable,
-- 
2.8.1



[PATCH 19/38] drm/hisilicon: Implement some semblance of vblank event handling

2016-06-02 Thread Daniel Vetter
atomic_flush seems to be the right place, but I'm not entirely sure
whether this will catch them all. It could be that when disabling the
crtc we'll miss the vblank.

While at it nuke the dummy functions.

v2: Be more robust and either arm, when the CRTC is on, or just send
the event out right away.

Cc: Xinliang Liu 
Cc: Xinwei Kong 
Cc: Archit Taneja 
Signed-off-by: Daniel Vetter 
---
 drivers/gpu/drm/hisilicon/kirin/kirin_drm_ade.c | 20 
 1 file changed, 12 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/hisilicon/kirin/kirin_drm_ade.c 
b/drivers/gpu/drm/hisilicon/kirin/kirin_drm_ade.c
index fba6372d060e..ed76baad525f 100644
--- a/drivers/gpu/drm/hisilicon/kirin/kirin_drm_ade.c
+++ b/drivers/gpu/drm/hisilicon/kirin/kirin_drm_ade.c
@@ -502,13 +502,6 @@ static void ade_crtc_disable(struct drm_crtc *crtc)
acrtc->enable = false;
 }

-static int ade_crtc_atomic_check(struct drm_crtc *crtc,
-struct drm_crtc_state *state)
-{
-   /* do nothing */
-   return 0;
-}
-
 static void ade_crtc_mode_set_nofb(struct drm_crtc *crtc)
 {
struct ade_crtc *acrtc = to_ade_crtc(crtc);
@@ -537,6 +530,7 @@ static void ade_crtc_atomic_flush(struct drm_crtc *crtc,
 {
struct ade_crtc *acrtc = to_ade_crtc(crtc);
struct ade_hw_ctx *ctx = acrtc->ctx;
+   struct drm_pending_vblank_event *event = crtc->state->event;
void __iomem *base = ctx->base;

/* only crtc is enabled regs take effect */
@@ -545,12 +539,22 @@ static void ade_crtc_atomic_flush(struct drm_crtc *crtc,
/* flush ade registers */
writel(ADE_ENABLE, base + ADE_EN);
}
+
+   if (event) {
+   crtc->state->event = NULL;
+
+   spin_lock_irq(&crtc->dev->event_lock);
+   if (drm_crtc_vblank_get(crtc) == 0)
+   drm_crtc_arm_vblank_event(crtc, event);
+   else
+   drm_crtc_send_vblank_event(crtc, event);
+   spin_unlock_irq(&crtc->dev->event_lock);
+   }
 }

 static const struct drm_crtc_helper_funcs ade_crtc_helper_funcs = {
.enable = ade_crtc_enable,
.disable= ade_crtc_disable,
-   .atomic_check   = ade_crtc_atomic_check,
.mode_set_nofb  = ade_crtc_mode_set_nofb,
.atomic_begin   = ade_crtc_atomic_begin,
.atomic_flush   = ade_crtc_atomic_flush,
-- 
2.8.1



[PATCH 20/38] drm/sun4i: Implement some semblance of vblank event handling

2016-06-02 Thread Daniel Vetter
atomic_flush seems to be the right place, right after we commit the
plane updates. Again use the fullproof version, since the pipe might
be off.

Cc: Boris Brezillon 
Cc: Maxime Ripard 
Signed-off-by: Daniel Vetter 
---
 drivers/gpu/drm/sun4i/sun4i_crtc.c | 12 
 1 file changed, 12 insertions(+)

diff --git a/drivers/gpu/drm/sun4i/sun4i_crtc.c 
b/drivers/gpu/drm/sun4i/sun4i_crtc.c
index 4182a21f5923..f628b6d8f23f 100644
--- a/drivers/gpu/drm/sun4i/sun4i_crtc.c
+++ b/drivers/gpu/drm/sun4i/sun4i_crtc.c
@@ -51,10 +51,22 @@ static void sun4i_crtc_atomic_flush(struct drm_crtc *crtc,
 {
struct sun4i_crtc *scrtc = drm_crtc_to_sun4i_crtc(crtc);
struct sun4i_drv *drv = scrtc->drv;
+   struct drm_pending_vblank_event *event = crtc->state->event;

DRM_DEBUG_DRIVER("Committing plane changes\n");

sun4i_backend_commit(drv->backend);
+
+   if (event) {
+   crtc->state->event = NULL;
+
+   spin_lock_irq(&crtc->dev->event_lock);
+   if (drm_crtc_vblank_get(crtc) == 0)
+   drm_crtc_arm_vblank_event(crtc, event);
+   else
+   drm_crtc_send_vblank_event(crtc, event);
+   spin_unlock_irq(&crtc->dev->event_lock);
+   }
 }

 static void sun4i_crtc_disable(struct drm_crtc *crtc)
-- 
2.8.1



[PATCH 21/38] drm/atomic: kerneldoc for drm_atomic_crtc_needs_modeset

2016-06-02 Thread Daniel Vetter
Just a bit of drive-by ocd.

Signed-off-by: Daniel Vetter 
---
 include/drm/drm_atomic.h | 7 +++
 1 file changed, 7 insertions(+)

diff --git a/include/drm/drm_atomic.h b/include/drm/drm_atomic.h
index d9504dfcd1cc..465a1212f4f0 100644
--- a/include/drm/drm_atomic.h
+++ b/include/drm/drm_atomic.h
@@ -198,6 +198,13 @@ int __must_check drm_atomic_nonblocking_commit(struct 
drm_atomic_state *state);
 (plane_state) = (__state)->planes[__i].state, 1);  \
 (__i)++)   \
for_each_if (plane_state)
+
+/**
+ * drm_atomic_crtc_needs_modeset - compute combined modeset need
+ * @state: &drm_crtc_state for the CRTC
+ *
+ * This computes the combined need for a modeset for @state.
+ */
 static inline bool
 drm_atomic_crtc_needs_modeset(struct drm_crtc_state *state)
 {
-- 
2.8.1



[PATCH 22/38] drm/atomic-helper: nonblocking commit support

2016-06-02 Thread Daniel Vetter
Design ideas:

- split up the actual commit into different phases, and have
  completions for each of them. This will be useful for the future
  when we want to interleave phases much more aggressively, for e.g.
  queue depth > 1. For not it's just a minimal optimization compared
  to current common nonblocking implementation patterns from drivers,
  which all stall for the entire commit to complete, including vblank
  waits and cleanups.

- Extract a separate atomic_commit_hw hook since that's the part most
  drivers will need to overwrite, hopefully allowing even more shared
  code.

- Enforce EBUSY seamntics by attaching one of the completions to the
  flip_done vblank event. Side benefit of forcing atomic drivers using
  these helpers to implement event handlign at least semi-correct. I'm
  evil that way ;-)

- Ridiculously modular, as usual.

- The main tracking unit for a commit stays struct drm_atomic_state,
  and the ownership rules for that are unchanged. Ownership still
  gets transferred to the driver (and subsequently to the worker) on
  successful commits. What is added is a small, per-crtc, refcounted
  structure to track pending commits called struct drm_crtc_commit.
  No actual state is attached to that though, it's purely for ordering
  and waiting.

- Dependencies are implicitly handled by assuming that any CRTC part
  of &drm_atomic_state is a dependency, and that the current commit
  must wait for any commits to complete on those CRTC. This way
  drivers can easily add more depencies using
  drm_atomic_get_crtc_state(), which is very natural since in most
  case a dependency exists iff there's some bit of state that needs to
  be cross checked.

  Removing depencies is not possible, drivers simply need to be
  careful to not include every CRTC in a commit if that's not
  necessary. Which is a good idea anyway, since that also avoids
  ww_mutex lock contention.

- Queue depth > 1 sees some prep work in this patch by adding a stall
  paramater to drm_atomic_helper_swap_states(). To be able to push
  commits entirely free-standing and in a deeper queue through the
  back-end the driver must not access any obj->state pointers. This
  means we need to track the old state in drm_atomic_state (much
  easier with the consolidated arrays), and pass them all explicitly
  to driver backends (this will be serious amounts of churn).

  Once that's done stall can be set to false in swap_states.

Features: Contains bugs because totally untested.

v2: Dont ask for flip_done signalling when the CRTC is off and stays
off: Drivers don't handle events in that case. Instead complete right
away. This way future commits don't need to have special-case logic,
but can keep blocking for the flip_done completion.

v3: Tons of fixes:
- Stall for preceeding commit for real, not the current one by
  accident.
- Add WARN_ON in case drivers don't fire the drm event.
- Don't double-free drm events.

v4: Make legacy cursor not stall.

v5: Extend the helper hook to cover the entire commit tail. Some
drivers need special code for cleanup and vblank waiting, this makes
it a bit more useful. Inspired by the rockchip driver.

v6: Add WARN_ON to catch drivers who forget to send out the
drm event.

v7: Fixup the stalls in swap_state for real!!

v8:
- Fixup trailing whitespace, spotted by Maarten.
- Actually wait for flip_done in cleanup_done, like the comment says
  we should do. Thanks a lot for Tomeu for helping with debugging this
  on.

v9: Now with awesome kerneldoc!

Tested-by: Tomeu Vizoso 
Cc: Maarten Lankhorst 
Cc: Tomeu Vizoso 
Cc: Daniel Stone 
Tested-by: Liviu Dudau 
Signed-off-by: Daniel Vetter 
---
 drivers/gpu/drm/drm_atomic.c |  22 ++
 drivers/gpu/drm/drm_atomic_helper.c  | 475 ---
 drivers/gpu/drm/drm_crtc.c   |   3 +
 drivers/gpu/drm/drm_fops.c   |   6 +
 include/drm/drmP.h   |   1 +
 include/drm/drm_atomic.h |   6 +
 include/drm/drm_atomic_helper.h  |   8 +
 include/drm/drm_crtc.h   | 119 +++-
 include/drm/drm_modeset_helper_vtables.h |  39 +++
 9 files changed, 634 insertions(+), 45 deletions(-)

diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c
index 5e4b820a977c..d99ab2f6663f 100644
--- a/drivers/gpu/drm/drm_atomic.c
+++ b/drivers/gpu/drm/drm_atomic.c
@@ -33,6 +33,20 @@

 #include "drm_crtc_internal.h"

+static void crtc_commit_free(struct kref *kref)
+{
+   struct drm_crtc_commit *commit =
+   container_of(kref, struct drm_crtc_commit, ref);
+
+   kfree(commit);
+}
+
+void drm_crtc_commit_put(struct drm_crtc_commit *commit)
+{
+   kref_put(&commit->ref, crtc_commit_free);
+}
+EXPORT_SYMBOL(drm_crtc_commit_put);
+
 /**
  * drm_atomic_state_default_release -
  * release memory initialized by drm_atomic_state_init
@@ -148,6 +162,14 @@ void drm_atomic_state_default_clear(struct 
drm_atomic_state *state)

crtc->funcs-

[PATCH 23/38] drm/hdlcd: Use helper support for nonblocking commits

2016-06-02 Thread Daniel Vetter
With the fixed up drm event handling for crtc_state->event we can just
use the helper support for nonblocking commits.

Cc: Liviu Dudau 
Tested-by: Liviu Dudau 
Acked-by: Liviu Dudau 
Signed-off-by: Daniel Vetter 
---
 drivers/gpu/drm/arm/hdlcd_drv.c | 8 +---
 1 file changed, 1 insertion(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/arm/hdlcd_drv.c b/drivers/gpu/drm/arm/hdlcd_drv.c
index 5178f3489897..9fd7321de838 100644
--- a/drivers/gpu/drm/arm/hdlcd_drv.c
+++ b/drivers/gpu/drm/arm/hdlcd_drv.c
@@ -110,17 +110,11 @@ static void hdlcd_fb_output_poll_changed(struct 
drm_device *drm)
drm_fbdev_cma_hotplug_event(hdlcd->fbdev);
 }

-static int hdlcd_atomic_commit(struct drm_device *dev,
-  struct drm_atomic_state *state, bool nonblock)
-{
-   return drm_atomic_helper_commit(dev, state, false);
-}
-
 static const struct drm_mode_config_funcs hdlcd_mode_config_funcs = {
.fb_create = drm_fb_cma_create,
.output_poll_changed = hdlcd_fb_output_poll_changed,
.atomic_check = drm_atomic_helper_check,
-   .atomic_commit = hdlcd_atomic_commit,
+   .atomic_commit = drm_atomic_helper_commit,
 };

 static void hdlcd_setup_mode_config(struct drm_device *drm)
-- 
2.8.1



[PATCH 24/38] drm/arc: Implement nonblocking commit correctly

2016-06-02 Thread Daniel Vetter
Committing with block it is not.

Thanks to the fixed up vblank event handling we can just use the
helper support for nonblocking commits now.

Cc: Carlos Palminha 
Cc: Alexey Brodkin 
Cc: linux-snps-arc at lists.infradead.org
Signed-off-by: Daniel Vetter 
---
 drivers/gpu/drm/arc/arcpgu_drv.c | 8 +---
 1 file changed, 1 insertion(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/arc/arcpgu_drv.c b/drivers/gpu/drm/arc/arcpgu_drv.c
index d407fd79a400..a92e533531c3 100644
--- a/drivers/gpu/drm/arc/arcpgu_drv.c
+++ b/drivers/gpu/drm/arc/arcpgu_drv.c
@@ -32,17 +32,11 @@ static void arcpgu_fb_output_poll_changed(struct drm_device 
*dev)
drm_fbdev_cma_hotplug_event(arcpgu->fbdev);
 }

-static int arcpgu_atomic_commit(struct drm_device *dev,
-   struct drm_atomic_state *state, bool async)
-{
-   return drm_atomic_helper_commit(dev, state, false);
-}
-
 static struct drm_mode_config_funcs arcpgu_drm_modecfg_funcs = {
.fb_create  = drm_fb_cma_create,
.output_poll_changed = arcpgu_fb_output_poll_changed,
.atomic_check = drm_atomic_helper_check,
-   .atomic_commit = arcpgu_atomic_commit,
+   .atomic_commit = drm_atomic_helper_commit,
 };

 static void arcpgu_setup_mode_config(struct drm_device *drm)
-- 
2.8.1



[PATCH 25/38] drm/i915: Signal drm events for atomic

2016-06-02 Thread Daniel Vetter
This is part of what atomic must implement. And it's also required
to be able to use the helper nonblocking support.

v2: Always send out the drm event, remove the planes_changed check.

Signed-off-by: Daniel Vetter 
---
 drivers/gpu/drm/i915/intel_display.c | 13 ++---
 drivers/gpu/drm/i915/intel_sprite.c  | 14 ++
 2 files changed, 24 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_display.c 
b/drivers/gpu/drm/i915/intel_display.c
index a59cc0e2e5ca..0618916f825b 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -13797,13 +13797,21 @@ static int intel_atomic_commit(struct drm_device *dev,
bool modeset = needs_modeset(crtc->state);
struct intel_crtc_state *pipe_config =
to_intel_crtc_state(crtc->state);
-   bool update_pipe = !modeset && pipe_config->update_pipe;

if (modeset && crtc->state->active) {
update_scanline_offset(to_intel_crtc(crtc));
dev_priv->display.crtc_enable(crtc);
}

+   /* Complete events for now disable pipes here. */
+   if (modeset && !crtc->state->active && crtc->state->event) {
+   spin_lock_irq(&dev->event_lock);
+   drm_crtc_send_vblank_event(crtc, crtc->state->event);
+   spin_unlock_irq(&dev->event_lock);
+
+   crtc->state->event = NULL;
+   }
+
if (!modeset)

intel_pre_plane_update(to_intel_crtc_state(old_crtc_state));

@@ -13811,8 +13819,7 @@ static int intel_atomic_commit(struct drm_device *dev,
drm_atomic_get_existing_plane_state(state, crtc->primary))
intel_fbc_enable(intel_crtc);

-   if (crtc->state->active &&
-   (crtc->state->planes_changed || update_pipe))
+   if (crtc->state->active)
drm_atomic_helper_commit_planes_on_crtc(old_crtc_state);

if (pipe_config->base.active && needs_vblank_wait(pipe_config))
diff --git a/drivers/gpu/drm/i915/intel_sprite.c 
b/drivers/gpu/drm/i915/intel_sprite.c
index 324ccb06397d..fc654173c491 100644
--- a/drivers/gpu/drm/i915/intel_sprite.c
+++ b/drivers/gpu/drm/i915/intel_sprite.c
@@ -166,6 +166,20 @@ void intel_pipe_update_end(struct intel_crtc *crtc, struct 
intel_flip_work *work

trace_i915_pipe_update_end(crtc, end_vbl_count, scanline_end);

+   /* We're still in the vblank-evade critical section, this can't race.
+* Would be slightly nice to just grab the vblank count and arm the
+* event outside of the critical section - the spinlock might spin for a
+* while ... */
+   if (crtc->base.state->event) {
+   WARN_ON(drm_crtc_vblank_get(&crtc->base) != 0);
+
+   spin_lock(&crtc->base.dev->event_lock);
+   drm_crtc_arm_vblank_event(&crtc->base, crtc->base.state->event);
+   spin_unlock(&crtc->base.dev->event_lock);
+
+   crtc->base.state->event = NULL;
+   }
+
local_irq_enable();

if (crtc->debug.start_vbl_count &&
-- 
2.8.1



[PATCH 26/38] drm/i915: Roll out the helper nonblock tracking

2016-06-02 Thread Daniel Vetter
Right now still all blocking, no worker anywhere to be seen.

Signed-off-by: Daniel Vetter 
---
 drivers/gpu/drm/i915/intel_display.c | 10 +-
 1 file changed, 9 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/intel_display.c 
b/drivers/gpu/drm/i915/intel_display.c
index 0618916f825b..77ff0903540d 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -13720,6 +13720,10 @@ static int intel_atomic_commit(struct drm_device *dev,
unsigned long put_domains[I915_MAX_PIPES] = {};
unsigned crtc_vblank_mask = 0;

+   ret = drm_atomic_helper_setup_commit(state, nonblock);
+   if (ret)
+   return ret;
+
ret = intel_atomic_prepare_commit(dev, state, nonblock);
if (ret) {
DRM_DEBUG_ATOMIC("Preparing state failed with %i\n", ret);
@@ -13731,6 +13735,8 @@ static int intel_atomic_commit(struct drm_device *dev,
dev_priv->wm.skl_results = intel_state->wm_results;
intel_shared_dpll_commit(state);

+   drm_atomic_helper_wait_for_dependencies(state);
+
if (intel_state->modeset) {
memcpy(dev_priv->min_pixclk, intel_state->min_pixclk,
   sizeof(intel_state->min_pixclk));
@@ -13826,7 +13832,7 @@ static int intel_atomic_commit(struct drm_device *dev,
crtc_vblank_mask |= 1 << i;
}

-   /* FIXME: add subpixel order */
+   drm_atomic_helper_commit_hw_done(state);

if (!state->legacy_cursor_update)
intel_atomic_wait_for_vblanks(dev, dev_priv, crtc_vblank_mask);
@@ -13861,6 +13867,8 @@ static int intel_atomic_commit(struct drm_device *dev,
drm_atomic_helper_cleanup_planes(dev, state);
mutex_unlock(&dev->struct_mutex);

+   drm_atomic_helper_commit_cleanup_done(state);
+
drm_atomic_state_free(state);

/* As one of the primary mmio accessors, KMS has a high likelihood
-- 
2.8.1



[PATCH 27/38] drm/i915: nonblocking commit

2016-06-02 Thread Daniel Vetter
Simply split intel_atomic_commit in half and place the new
nonblocking commit helpers at the right spots.

NOTE: There's still trouble with obj->frontbuffer bits getting mangled
when pipelining atomic commits.

v2:
- Remove the check for nonblocking which returned -EINVAL.
- Do wait for requests in the worker thread before committing
  hw state.

v3: Move hw_done after the optimize_wm/post_plane_update step, plus
add FIXME comment how to fix that up again properly.

Signed-off-by: Daniel Vetter 
---
 drivers/gpu/drm/i915/intel_display.c | 121 ---
 1 file changed, 82 insertions(+), 39 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_display.c 
b/drivers/gpu/drm/i915/intel_display.c
index 77ff0903540d..75aa6d90eb13 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -13567,11 +13567,6 @@ static int intel_atomic_prepare_commit(struct 
drm_device *dev,
struct drm_crtc *crtc;
int i, ret;

-   if (nonblock) {
-   DRM_DEBUG_KMS("i915 does not yet support nonblocking commit\n");
-   return -EINVAL;
-   }
-
for_each_crtc_in_state(state, crtc, crtc_state, i) {
if (state->legacy_cursor_update)
continue;
@@ -13690,50 +13685,34 @@ static bool needs_vblank_wait(struct intel_crtc_state 
*crtc_state)
return false;
 }

-/**
- * intel_atomic_commit - commit validated state object
- * @dev: DRM device
- * @state: the top-level driver state object
- * @nonblock: nonblocking commit
- *
- * This function commits a top-level state object that has been validated
- * with drm_atomic_helper_check().
- *
- * FIXME:  Atomic modeset support for i915 is not yet complete.  At the moment
- * we can only handle plane-related operations and do not yet support
- * nonblocking commit.
- *
- * RETURNS
- * Zero for success or -errno.
- */
-static int intel_atomic_commit(struct drm_device *dev,
-  struct drm_atomic_state *state,
-  bool nonblock)
+static void intel_atomic_commit_tail(struct drm_atomic_state *state)
 {
+   struct drm_device *dev = state->dev;
struct intel_atomic_state *intel_state = to_intel_atomic_state(state);
struct drm_i915_private *dev_priv = dev->dev_private;
struct drm_crtc_state *old_crtc_state;
struct drm_crtc *crtc;
struct intel_crtc_state *intel_cstate;
-   int ret = 0, i;
+   struct drm_plane *plane;
+   struct drm_plane_state *plane_state;
bool hw_check = intel_state->modeset;
unsigned long put_domains[I915_MAX_PIPES] = {};
unsigned crtc_vblank_mask = 0;
+   int i, ret;

-   ret = drm_atomic_helper_setup_commit(state, nonblock);
-   if (ret)
-   return ret;
+   for_each_plane_in_state(state, plane, plane_state, i) {
+   struct intel_plane_state *intel_plane_state =
+   to_intel_plane_state(plane_state);

-   ret = intel_atomic_prepare_commit(dev, state, nonblock);
-   if (ret) {
-   DRM_DEBUG_ATOMIC("Preparing state failed with %i\n", ret);
-   return ret;
-   }
+   if (!intel_plane_state->wait_req)
+   continue;

-   drm_atomic_helper_swap_state(state, true);
-   dev_priv->wm.distrust_bios_wm = false;
-   dev_priv->wm.skl_results = intel_state->wm_results;
-   intel_shared_dpll_commit(state);
+   ret = __i915_wait_request(intel_plane_state->wait_req,
+ true, NULL, NULL);
+   /* EIO should be eaten, and we can't get interrupted in the
+* worker, and blocking commits have waited already. */
+   WARN_ON(ret);
+   }

drm_atomic_helper_wait_for_dependencies(state);

@@ -13832,8 +13811,15 @@ static int intel_atomic_commit(struct drm_device *dev,
crtc_vblank_mask |= 1 << i;
}

-   drm_atomic_helper_commit_hw_done(state);
-
+   /* FIXME: We should call drm_atomic_helper_commit_hw_done() here
+* already, but still need the state for the delayed optimization. To
+* fix this:
+* - wrap the optimization/post_plane_update stuff into a per-crtc work.
+* - schedule that vblank worker _before_ calling hw_done
+* - at the start of commit_tail, cancel it _synchrously
+* - switch over to the vblank wait helper in the core after that since
+*   we don't need out special handling any more.
+*/
if (!state->legacy_cursor_update)
intel_atomic_wait_for_vblanks(dev, dev_priv, crtc_vblank_mask);

@@ -13860,6 +13846,8 @@ static int intel_atomic_commit(struct drm_device *dev,
intel_modeset_verify_crtc(crtc, old_crtc_state, crtc->state);
}

+   drm_atomic_helper_commit_hw_done(state);
+
if (intel_state->modeset)
 

[PATCH 29/38] drm/i915: Move fb_bits updating later in atomic_commit

2016-06-02 Thread Daniel Vetter
Currently it's part of prepare_fb, still in the first phase of
atomic_commit which might fail. Which means that we need to have some
heuristics in cleanup_fb to figure out whether things failed, or
whether we just clean up the old fbs.

That's fragile, and worse, once we start pipelining commits gets
confused: While the last commit is still getting cleanup up we already
hammer in the new one, and fb_bits aren't refcounted, resulting in
lost bits and WARN_ON galore. We could instead try to make cleanup_fb
more clever, but a simpler fix is to postpone the fb_bits tracking
past the point of no return, where we commit all the software state.

That also makes conceptually more sense, since fb_bits must be updated
synchronously from the ioctl (they track usage from userspace pov, not
from the hw pov), right before we're fully committed to the updated.

This fixes WARNING splats from track_fb with page_flip implemented
through atomic_commit.

Testcase: igt/kms_flip/flip-vs-rmfb
Signed-off-by: Daniel Vetter 
---
 drivers/gpu/drm/i915/intel_display.c | 41 ++--
 1 file changed, 25 insertions(+), 16 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_display.c 
b/drivers/gpu/drm/i915/intel_display.c
index 14fd10ec1bbf..adf80029ab64 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -13882,6 +13882,25 @@ static void intel_atomic_commit_work(struct 
work_struct *work)
intel_atomic_commit_tail(state);
 }

+static void intel_atomic_track_fbs(struct drm_atomic_state *state)
+{
+   struct drm_plane_state *old_plane_state;
+   struct drm_plane *plane;
+   struct drm_i915_gem_object *obj, *old_obj;
+   struct intel_plane *intel_plane;
+   int i;
+
+   mutex_lock(&state->dev->struct_mutex);
+   for_each_plane_in_state(state, plane, old_plane_state, i) {
+   obj = intel_fb_obj(plane->state->fb);
+   old_obj = intel_fb_obj(old_plane_state->fb);
+   intel_plane = to_intel_plane(plane);
+
+   i915_gem_track_fb(old_obj, obj, intel_plane->frontbuffer_bit);
+   }
+   mutex_unlock(&state->dev->struct_mutex);
+}
+
 /**
  * intel_atomic_commit - commit validated state object
  * @dev: DRM device
@@ -13922,6 +13941,7 @@ static int intel_atomic_commit(struct drm_device *dev,
dev_priv->wm.distrust_bios_wm = false;
dev_priv->wm.skl_results = intel_state->wm_results;
intel_shared_dpll_commit(state);
+   intel_atomic_track_fbs(state);

if (nonblock)
queue_work(system_unbound_wq, &state->commit_work);
@@ -14001,7 +14021,6 @@ intel_prepare_plane_fb(struct drm_plane *plane,
 {
struct drm_device *dev = plane->dev;
struct drm_framebuffer *fb = new_state->fb;
-   struct intel_plane *intel_plane = to_intel_plane(plane);
struct drm_i915_gem_object *obj = intel_fb_obj(fb);
struct drm_i915_gem_object *old_obj = intel_fb_obj(plane->state->fb);
int ret = 0;
@@ -14058,16 +14077,12 @@ intel_prepare_plane_fb(struct drm_plane *plane,
ret = intel_pin_and_fence_fb_obj(fb, new_state->rotation);
}

-   if (ret == 0) {
-   if (obj) {
-   struct intel_plane_state *plane_state =
-   to_intel_plane_state(new_state);
-
-   i915_gem_request_assign(&plane_state->wait_req,
-   obj->last_write_req);
-   }
+   if (ret == 0 && obj) {
+   struct intel_plane_state *plane_state =
+   to_intel_plane_state(new_state);

-   i915_gem_track_fb(old_obj, obj, intel_plane->frontbuffer_bit);
+   i915_gem_request_assign(&plane_state->wait_req,
+   obj->last_write_req);
}

return ret;
@@ -14087,7 +14102,6 @@ intel_cleanup_plane_fb(struct drm_plane *plane,
   const struct drm_plane_state *old_state)
 {
struct drm_device *dev = plane->dev;
-   struct intel_plane *intel_plane = to_intel_plane(plane);
struct intel_plane_state *old_intel_state;
struct drm_i915_gem_object *old_obj = intel_fb_obj(old_state->fb);
struct drm_i915_gem_object *obj = intel_fb_obj(plane->state->fb);
@@ -14101,11 +14115,6 @@ intel_cleanup_plane_fb(struct drm_plane *plane,
!INTEL_INFO(dev)->cursor_needs_physical))
intel_unpin_fb_obj(old_state->fb, old_state->rotation);

-   /* prepare_fb aborted? */
-   if ((old_obj && (old_obj->frontbuffer_bits & 
intel_plane->frontbuffer_bit)) ||
-   (obj && !(obj->frontbuffer_bits & intel_plane->frontbuffer_bit)))
-   i915_gem_track_fb(old_obj, obj, intel_plane->frontbuffer_bit);
-
i915_gem_request_assign(&old_intel_state->wait_req, NULL);
 }

-- 
2.8.1



[PATCH 28/38] drm/i915: Use atomic commits for legacy page_flips

2016-06-02 Thread Daniel Vetter
Note that I didn't start garbage collecting all the legacy flip code
yet, to make it easier to revert this. But there will be _lots_ of
code that can be removed once this is tested on all platforms.

FIXME: obj->frontbuffer_bits gets out of whack when pipelining
commits too hard.

Signed-off-by: Daniel Vetter 
---
 drivers/gpu/drm/i915/intel_display.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/intel_display.c 
b/drivers/gpu/drm/i915/intel_display.c
index 75aa6d90eb13..14fd10ec1bbf 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -11642,6 +11642,7 @@ void intel_check_page_flip(struct drm_i915_private 
*dev_priv, int pipe)
spin_unlock(&dev->event_lock);
 }

+__attribute__((unused))
 static int intel_crtc_page_flip(struct drm_crtc *crtc,
struct drm_framebuffer *fb,
struct drm_pending_vblank_event *event,
@@ -13975,7 +13976,7 @@ static const struct drm_crtc_funcs intel_crtc_funcs = {
.set_config = drm_atomic_helper_set_config,
.set_property = drm_atomic_helper_crtc_set_property,
.destroy = intel_crtc_destroy,
-   .page_flip = intel_crtc_page_flip,
+   .page_flip = drm_atomic_helper_page_flip,
.atomic_duplicate_state = intel_crtc_duplicate_state,
.atomic_destroy_state = intel_crtc_destroy_state,
 };
-- 
2.8.1



[PATCH 30/38] drm/rockchip: Disarm vop->is_enabled

2016-06-02 Thread Daniel Vetter
With atomic helpers there's no need to track the enabled state of a pipe
any more, because atomic helpers track this accurately already.

Just disable the early returns, since the debug checks might be useful.

v2: Don't call drm_helper_disable_unused_functions, it blows up
without this check. At least explains why rockchip still needed this
old legacy-style state tracing - to work around issues from calling
other legacy style functions!

Cc: Tomeu Vizoso 
Cc: Mark yao 
Tested-by: Tomeu Vizoso 
Reviewed-by: Tomeu Vizoso 
Signed-off-by: Daniel Vetter 
---
 drivers/gpu/drm/rockchip/rockchip_drm_fbdev.c | 3 ---
 drivers/gpu/drm/rockchip/rockchip_drm_vop.c   | 6 --
 2 files changed, 9 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_fbdev.c 
b/drivers/gpu/drm/rockchip/rockchip_drm_fbdev.c
index f261512bb4a0..245a567f7b8c 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_fbdev.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_fbdev.c
@@ -156,9 +156,6 @@ int rockchip_drm_fbdev_init(struct drm_device *dev)
goto err_drm_fb_helper_fini;
}

-   /* disable all the possible outputs/crtcs before entering KMS mode */
-   drm_helper_disable_unused_functions(dev);
-
ret = drm_fb_helper_initial_config(helper, PREFERRED_BPP);
if (ret < 0) {
dev_err(dev->dev, "Failed to set initial hw config - %d.\n",
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c 
b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
index 5567fb43e674..957a6b4917c8 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
@@ -431,9 +431,6 @@ static void vop_enable(struct drm_crtc *crtc)
struct vop *vop = to_vop(crtc);
int ret;

-   if (vop->is_enabled)
-   return;
-
ret = pm_runtime_get_sync(vop->dev);
if (ret < 0) {
dev_err(vop->dev, "failed to get pm runtime: %d\n", ret);
@@ -501,9 +498,6 @@ static void vop_crtc_disable(struct drm_crtc *crtc)
struct vop *vop = to_vop(crtc);
int i;

-   if (!vop->is_enabled)
-   return;
-
/*
 * We need to make sure that all windows are disabled before we
 * disable that crtc. Otherwise we might try to scan from a destroyed
-- 
2.8.1



[PATCH 31/38] drm/rockchip: Fix crtc_state->event signalling

2016-06-02 Thread Daniel Vetter
It's not permissible to look at plane->state from interrupt context,
since doing that would need the irq handler to acquire the
plane->mutex lock.

The other problem is that if we pipeline updates using the new
nonblocking atomic helpers new state gets commit before the irq
handler fires, resulting in a lost event.

Fix both issues by caching the necessary values in vop_win, protected
by dev->event_lock.

Cc: Tomeu Vizoso 
Cc: Mark yao 
Tested-by: Tomeu Vizoso 
Reviewed-by: Tomeu Vizoso 
Signed-off-by: Daniel Vetter 
---
 drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 24 ++--
 1 file changed, 18 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c 
b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
index 957a6b4917c8..94eaeec29b6b 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
@@ -98,7 +98,9 @@ struct vop_win {
const struct vop_win_data *data;
struct vop *vop;

-   struct vop_plane_state state;
+   /* protected by dev->event_lock */
+   bool enable;
+   dma_addr_t yrgb_mst;
 };

 struct vop {
@@ -112,6 +114,8 @@ struct vop {
bool vsync_work_pending;
struct completion dsp_hold_completion;
struct completion wait_update_complete;
+
+   /* protected by dev->event_lock */
struct drm_pending_vblank_event *event;

const struct vop_data *data;
@@ -652,6 +656,11 @@ static void vop_plane_atomic_disable(struct drm_plane 
*plane,
if (!old_state->crtc)
return;

+   spin_lock_irq(&plane->dev->event_lock);
+   vop_win->enable = false;
+   vop_win->yrgb_mst = 0;
+   spin_unlock_irq(&plane->dev->event_lock);
+
spin_lock(&vop->reg_lock);

VOP_WIN_SET(vop, win, enable, 0);
@@ -686,7 +695,7 @@ static void vop_plane_atomic_update(struct drm_plane *plane,
/*
 * can't update plane when vop is disabled.
 */
-   if (!crtc)
+   if (WARN_ON(!crtc))
return;

if (WARN_ON(!vop->is_enabled))
@@ -715,6 +724,11 @@ static void vop_plane_atomic_update(struct drm_plane 
*plane,
offset += (src->y1 >> 16) * fb->pitches[0];
vop_plane_state->yrgb_mst = rk_obj->dma_addr + offset + fb->offsets[0];

+   spin_lock_irq(&plane->dev->event_lock);
+   vop_win->enable = true;
+   vop_win->yrgb_mst = vop_plane_state->yrgb_mst;
+   spin_unlock_irq(&plane->dev->event_lock);
+
spin_lock(&vop->reg_lock);

VOP_WIN_SET(vop, win, format, vop_plane_state->format);
@@ -1074,16 +1088,14 @@ static const struct drm_crtc_funcs vop_crtc_funcs = {

 static bool vop_win_pending_is_complete(struct vop_win *vop_win)
 {
-   struct drm_plane *plane = &vop_win->base;
-   struct vop_plane_state *state = to_vop_plane_state(plane->state);
dma_addr_t yrgb_mst;

-   if (!state->enable)
+   if (!vop_win->enable)
return VOP_WIN_GET(vop_win->vop, vop_win->data, enable) == 0;

yrgb_mst = VOP_WIN_GET_YRGBADDR(vop_win->vop, vop_win->data);

-   return yrgb_mst == state->yrgb_mst;
+   return yrgb_mst == vop_win->yrgb_mst;
 }

 static void vop_handle_vblank(struct vop *vop)
-- 
2.8.1



[PATCH 33/38] drm/rockchip: Nuke pending event handling in preclose

2016-06-02 Thread Daniel Vetter
This is now handled by the core, drivers can totally ignore lifetime
issues of drm events.

Cc: Tomeu Vizoso 
Cc: Mark yao 
Tested-by: Tomeu Vizoso 
Reviewed-by: Tomeu Vizoso 
Signed-off-by: Daniel Vetter 
---
 drivers/gpu/drm/rockchip/rockchip_drm_drv.c | 22 --
 drivers/gpu/drm/rockchip/rockchip_drm_drv.h |  1 -
 drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 20 
 3 files changed, 43 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c 
b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
index 2fac6799ceb2..2251121343e6 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
@@ -257,27 +257,6 @@ static int rockchip_drm_unload(struct drm_device *drm_dev)
return 0;
 }

-static void rockchip_drm_crtc_cancel_pending_vblank(struct drm_crtc *crtc,
-   struct drm_file *file_priv)
-{
-   struct rockchip_drm_private *priv = crtc->dev->dev_private;
-   int pipe = drm_crtc_index(crtc);
-
-   if (pipe < ROCKCHIP_MAX_CRTC &&
-   priv->crtc_funcs[pipe] &&
-   priv->crtc_funcs[pipe]->cancel_pending_vblank)
-   priv->crtc_funcs[pipe]->cancel_pending_vblank(crtc, file_priv);
-}
-
-static void rockchip_drm_preclose(struct drm_device *dev,
- struct drm_file *file_priv)
-{
-   struct drm_crtc *crtc;
-
-   list_for_each_entry(crtc, &dev->mode_config.crtc_list, head)
-   rockchip_drm_crtc_cancel_pending_vblank(crtc, file_priv);
-}
-
 void rockchip_drm_lastclose(struct drm_device *dev)
 {
struct rockchip_drm_private *priv = dev->dev_private;
@@ -303,7 +282,6 @@ static struct drm_driver rockchip_drm_driver = {
  DRIVER_PRIME | DRIVER_ATOMIC,
.load   = rockchip_drm_load,
.unload = rockchip_drm_unload,
-   .preclose   = rockchip_drm_preclose,
.lastclose  = rockchip_drm_lastclose,
.get_vblank_counter = drm_vblank_no_hw_counter,
.enable_vblank  = rockchip_drm_crtc_enable_vblank,
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_drv.h 
b/drivers/gpu/drm/rockchip/rockchip_drm_drv.h
index 7684503ff765..005634484441 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_drv.h
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_drv.h
@@ -40,7 +40,6 @@ struct rockchip_crtc_funcs {
int (*enable_vblank)(struct drm_crtc *crtc);
void (*disable_vblank)(struct drm_crtc *crtc);
void (*wait_for_update)(struct drm_crtc *crtc);
-   void (*cancel_pending_vblank)(struct drm_crtc *crtc, struct drm_file 
*file_priv);
 };

 struct rockchip_crtc_state {
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c 
b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
index d2932478ff59..8cd840f602b7 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
@@ -894,30 +894,10 @@ static void vop_crtc_wait_for_update(struct drm_crtc 
*crtc)
WARN_ON(!wait_for_completion_timeout(&vop->wait_update_complete, 100));
 }

-static void vop_crtc_cancel_pending_vblank(struct drm_crtc *crtc,
-  struct drm_file *file_priv)
-{
-   struct drm_device *drm = crtc->dev;
-   struct vop *vop = to_vop(crtc);
-   struct drm_pending_vblank_event *e;
-   unsigned long flags;
-
-   spin_lock_irqsave(&drm->event_lock, flags);
-   e = vop->event;
-   if (e && e->base.file_priv == file_priv) {
-   vop->event = NULL;
-
-   kfree(&e->base);
-   file_priv->event_space += sizeof(e->event);
-   }
-   spin_unlock_irqrestore(&drm->event_lock, flags);
-}
-
 static const struct rockchip_crtc_funcs private_crtc_funcs = {
.enable_vblank = vop_crtc_enable_vblank,
.disable_vblank = vop_crtc_disable_vblank,
.wait_for_update = vop_crtc_wait_for_update,
-   .cancel_pending_vblank = vop_crtc_cancel_pending_vblank,
 };

 static bool vop_crtc_mode_fixup(struct drm_crtc *crtc,
-- 
2.8.1



[PATCH 32/38] drm/rockchip: convert to helper nonblocking atomic commit

2016-06-02 Thread Daniel Vetter
With the various bits fixed rockchip now has an atomic compliant
handling/signalling of crtc_state->event, which means we can just
switch over to the new nonblocking helpers and remove some code.

v2: Fixes from Tomeu.

v3: Send out vblank events correctly when shutting down a crtc for
good. This is part of the atomic interface contract.

v4: Properly protect vop->event.

v5: Add more WARN_ON to check vop->event isn't clobbered.

Cc: Tomeu Vizoso 
Cc: Mark yao 
Tested-by: Tomeu Vizoso 
Reviewed-by: Tomeu Vizoso 
Signed-off-by: Daniel Vetter 
---
 drivers/gpu/drm/rockchip/rockchip_drm_drv.c |  3 --
 drivers/gpu/drm/rockchip/rockchip_drm_drv.h | 10 
 drivers/gpu/drm/rockchip/rockchip_drm_fb.c  | 72 -
 drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 20 +++-
 4 files changed, 27 insertions(+), 78 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c 
b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
index 09a4d429c0f0..2fac6799ceb2 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
@@ -145,9 +145,6 @@ static int rockchip_drm_load(struct drm_device *drm_dev, 
unsigned long flags)
if (!private)
return -ENOMEM;

-   mutex_init(&private->commit.lock);
-   INIT_WORK(&private->commit.work, rockchip_drm_atomic_work);
-
drm_dev->dev_private = private;

drm_mode_config_init(drm_dev);
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_drv.h 
b/drivers/gpu/drm/rockchip/rockchip_drm_drv.h
index 56f43a364c7f..7684503ff765 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_drv.h
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_drv.h
@@ -43,13 +43,6 @@ struct rockchip_crtc_funcs {
void (*cancel_pending_vblank)(struct drm_crtc *crtc, struct drm_file 
*file_priv);
 };

-struct rockchip_atomic_commit {
-   struct work_struct  work;
-   struct drm_atomic_state *state;
-   struct drm_device *dev;
-   struct mutex lock;
-};
-
 struct rockchip_crtc_state {
struct drm_crtc_state base;
int output_type;
@@ -68,11 +61,8 @@ struct rockchip_drm_private {
struct drm_fb_helper fbdev_helper;
struct drm_gem_object *fbdev_bo;
const struct rockchip_crtc_funcs *crtc_funcs[ROCKCHIP_MAX_CRTC];
-
-   struct rockchip_atomic_commit commit;
 };

-void rockchip_drm_atomic_work(struct work_struct *work);
 int rockchip_register_crtc_funcs(struct drm_crtc *crtc,
 const struct rockchip_crtc_funcs *crtc_funcs);
 void rockchip_unregister_crtc_funcs(struct drm_crtc *crtc);
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_fb.c 
b/drivers/gpu/drm/rockchip/rockchip_drm_fb.c
index 5ea141dfae5b..9198ee1ddc87 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_fb.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_fb.c
@@ -229,87 +229,32 @@ rockchip_atomic_wait_for_complete(struct drm_device *dev, 
struct drm_atomic_stat
 }

 static void
-rockchip_atomic_commit_complete(struct rockchip_atomic_commit *commit)
+rockchip_atomic_commit_tail(struct drm_atomic_state *state)
 {
-   struct drm_atomic_state *state = commit->state;
-   struct drm_device *dev = commit->dev;
+   struct drm_device *dev = state->dev;

-   /*
-* TODO: do fence wait here.
-*/
-
-   /*
-* Rockchip crtc support runtime PM, can't update display planes
-* when crtc is disabled.
-*
-* drm_atomic_helper_commit comments detail that:
-* For drivers supporting runtime PM the recommended sequence is
-*
-* drm_atomic_helper_commit_modeset_disables(dev, state);
-*
-* drm_atomic_helper_commit_modeset_enables(dev, state);
-*
-* drm_atomic_helper_commit_planes(dev, state, true);
-*
-* See the kerneldoc entries for these three functions for more details.
-*/
drm_atomic_helper_commit_modeset_disables(dev, state);

drm_atomic_helper_commit_modeset_enables(dev, state);

drm_atomic_helper_commit_planes(dev, state, true);

+   drm_atomic_helper_commit_hw_done(state);
+
rockchip_atomic_wait_for_complete(dev, state);

drm_atomic_helper_cleanup_planes(dev, state);
-
-   drm_atomic_state_free(state);
-}
-
-void rockchip_drm_atomic_work(struct work_struct *work)
-{
-   struct rockchip_atomic_commit *commit = container_of(work,
-   struct rockchip_atomic_commit, work);
-
-   rockchip_atomic_commit_complete(commit);
 }

-int rockchip_drm_atomic_commit(struct drm_device *dev,
-  struct drm_atomic_state *state,
-  bool nonblock)
-{
-   struct rockchip_drm_private *private = dev->dev_private;
-   struct rockchip_atomic_commit *commit = &private->commit;
-   int ret;
-
-   ret = drm_atomic_helper_prepare_planes(dev, state);
-   if (ret)
-   return re

[PATCH 34/38] drm/virtio: Don't reinvent a flipping wheel

2016-06-02 Thread Daniel Vetter
Now that the core helpers support nonblocking atomic commits there's
no need to invent that wheel separately (instead of fixing the bug in
the atomic implementation of virtio, as it should have been done!).

Cc: Gerd Hoffmann 
Tested-by: Gerd Hoffmann 
Reviewed-by: Gerd Hoffmann 
Signed-off-by: Daniel Vetter 
---
 drivers/gpu/drm/virtio/virtgpu_display.c | 48 ++--
 1 file changed, 2 insertions(+), 46 deletions(-)

diff --git a/drivers/gpu/drm/virtio/virtgpu_display.c 
b/drivers/gpu/drm/virtio/virtgpu_display.c
index d4305da88f44..325c6f73814b 100644
--- a/drivers/gpu/drm/virtio/virtgpu_display.c
+++ b/drivers/gpu/drm/virtio/virtgpu_display.c
@@ -118,58 +118,13 @@ static int virtio_gpu_crtc_cursor_move(struct drm_crtc 
*crtc,
return 0;
 }

-static int virtio_gpu_page_flip(struct drm_crtc *crtc,
-   struct drm_framebuffer *fb,
-   struct drm_pending_vblank_event *event,
-   uint32_t flags)
-{
-   struct virtio_gpu_device *vgdev = crtc->dev->dev_private;
-   struct virtio_gpu_output *output =
-   container_of(crtc, struct virtio_gpu_output, crtc);
-   struct drm_plane *plane = crtc->primary;
-   struct virtio_gpu_framebuffer *vgfb;
-   struct virtio_gpu_object *bo;
-   unsigned long irqflags;
-   uint32_t handle;
-
-   plane->fb = fb;
-   vgfb = to_virtio_gpu_framebuffer(plane->fb);
-   bo = gem_to_virtio_gpu_obj(vgfb->obj);
-   handle = bo->hw_res_handle;
-
-   DRM_DEBUG("handle 0x%x%s, crtc %dx%d\n", handle,
- bo->dumb ? ", dumb" : "",
- crtc->mode.hdisplay, crtc->mode.vdisplay);
-   if (bo->dumb) {
-   virtio_gpu_cmd_transfer_to_host_2d
-   (vgdev, handle, 0,
-cpu_to_le32(crtc->mode.hdisplay),
-cpu_to_le32(crtc->mode.vdisplay),
-0, 0, NULL);
-   }
-   virtio_gpu_cmd_set_scanout(vgdev, output->index, handle,
-  crtc->mode.hdisplay,
-  crtc->mode.vdisplay, 0, 0);
-   virtio_gpu_cmd_resource_flush(vgdev, handle, 0, 0,
- crtc->mode.hdisplay,
- crtc->mode.vdisplay);
-
-   if (event) {
-   spin_lock_irqsave(&crtc->dev->event_lock, irqflags);
-   drm_send_vblank_event(crtc->dev, -1, event);
-   spin_unlock_irqrestore(&crtc->dev->event_lock, irqflags);
-   }
-
-   return 0;
-}
-
 static const struct drm_crtc_funcs virtio_gpu_crtc_funcs = {
.cursor_set2= virtio_gpu_crtc_cursor_set,
.cursor_move= virtio_gpu_crtc_cursor_move,
.set_config = drm_atomic_helper_set_config,
.destroy= drm_crtc_cleanup,

-   .page_flip  = virtio_gpu_page_flip,
+   .page_flip  = drm_atomic_helper_page_flip,
.reset  = drm_atomic_helper_crtc_reset,
.atomic_duplicate_state = drm_atomic_helper_crtc_duplicate_state,
.atomic_destroy_state   = drm_atomic_helper_crtc_destroy_state,
@@ -267,6 +222,7 @@ static void virtio_gpu_crtc_atomic_flush(struct drm_crtc 
*crtc,
spin_lock_irqsave(&crtc->dev->event_lock, flags);
if (crtc->state->event)
drm_crtc_send_vblank_event(crtc, crtc->state->event);
+   crtc->state->event = NULL;
spin_unlock_irqrestore(&crtc->dev->event_lock, flags);
 }

-- 
2.8.1



[PATCH 35/38] drm: Replace fb_helper->atomic with mode_config->atomic_commit

2016-06-02 Thread Daniel Vetter
Drivers transitioning to atomic might not yet want to enable full
DRIVER_ATOMIC support when it's not entirely working. But using atomic
internally makes a lot more sense earlier.

Instead of spreading such flags to more places I figured it's simpler
to just check for mode_config->funcs->atomic_commit, and use atomic
paths if that is set. For the only driver currently transitioning
(i915) this does the right thing.

Cc: Maarten Lankhorst 
Signed-off-by: Daniel Vetter 
---
 drivers/gpu/drm/drm_fb_helper.c|  6 ++
 drivers/gpu/drm/i915/intel_fbdev.c |  2 --
 include/drm/drm_fb_helper.h| 11 ---
 3 files changed, 2 insertions(+), 17 deletions(-)

diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c
index c0e0a2e78d75..ba2fcb2a68ad 100644
--- a/drivers/gpu/drm/drm_fb_helper.c
+++ b/drivers/gpu/drm/drm_fb_helper.c
@@ -385,7 +385,7 @@ static int restore_fbdev_mode(struct drm_fb_helper 
*fb_helper)

drm_warn_on_modeset_not_all_locked(dev);

-   if (fb_helper->atomic)
+   if (dev->mode_config.funcs->atomic_commit)
return restore_fbdev_mode_atomic(fb_helper);

drm_for_each_plane(plane, dev) {
@@ -716,8 +716,6 @@ int drm_fb_helper_init(struct drm_device *dev,
i++;
}

-   fb_helper->atomic = !!drm_core_check_feature(dev, DRIVER_ATOMIC);
-
return 0;
 out_free:
drm_fb_helper_crtc_free(fb_helper);
@@ -1344,7 +1342,7 @@ int drm_fb_helper_pan_display(struct fb_var_screeninfo 
*var,
return -EBUSY;
}

-   if (fb_helper->atomic) {
+   if (dev->mode_config.funcs->atomic_commit) {
ret = pan_display_atomic(var, info);
goto unlock;
}
diff --git a/drivers/gpu/drm/i915/intel_fbdev.c 
b/drivers/gpu/drm/i915/intel_fbdev.c
index ef8e67690f3d..4c725ad6fb54 100644
--- a/drivers/gpu/drm/i915/intel_fbdev.c
+++ b/drivers/gpu/drm/i915/intel_fbdev.c
@@ -724,8 +724,6 @@ int intel_fbdev_init(struct drm_device *dev)
return ret;
}

-   ifbdev->helper.atomic = true;
-
dev_priv->fbdev = ifbdev;
INIT_WORK(&dev_priv->fbdev_suspend_work, intel_fbdev_suspend_worker);

diff --git a/include/drm/drm_fb_helper.h b/include/drm/drm_fb_helper.h
index 5b4aa35026a3..db8d4780eaa2 100644
--- a/include/drm/drm_fb_helper.h
+++ b/include/drm/drm_fb_helper.h
@@ -212,17 +212,6 @@ struct drm_fb_helper {
 * needs to be reprobe when fbdev is in control again.
 */
bool delayed_hotplug;
-
-   /**
-* @atomic:
-*
-* Use atomic updates for restore_fbdev_mode(), etc.  This defaults to
-* true if driver has DRIVER_ATOMIC feature flag, but drivers can
-* override it to true after drm_fb_helper_init() if they support atomic
-* modeset but do not yet advertise DRIVER_ATOMIC (note that fb-helper
-* does not require ASYNC commits).
-*/
-   bool atomic;
 };

 #ifdef CONFIG_DRM_FBDEV_EMULATION
-- 
2.8.1



[PATCH 36/38] drm: Resurrect atomic rmfb code

2016-06-02 Thread Daniel Vetter
This was somehow lost between v3 and the merged version in Maarten's
patch merged as:

commit f2d580b9a8149735cbc4b59c4a8df60173658140
Author: Maarten Lankhorst 
Date:   Wed May 4 14:38:26 2016 +0200

drm/core: Do not preserve framebuffer on rmfb, v4.

Actual code copied from Maarten's patch, but with the slight change to
just use dev->mode_config.funcs->atomic_commit to decide whether to
use the atomic path or not.

Cc: Maarten Lankhorst 
Signed-off-by: Daniel Vetter 
---
 drivers/gpu/drm/drm_atomic.c| 66 +
 drivers/gpu/drm/drm_crtc.c  |  6 
 drivers/gpu/drm/drm_crtc_internal.h |  1 +
 3 files changed, 73 insertions(+)

diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c
index d99ab2f6663f..dac0875e669c 100644
--- a/drivers/gpu/drm/drm_atomic.c
+++ b/drivers/gpu/drm/drm_atomic.c
@@ -1564,6 +1564,72 @@ void drm_atomic_clean_old_fb(struct drm_device *dev,
 }
 EXPORT_SYMBOL(drm_atomic_clean_old_fb);

+int drm_atomic_remove_fb(struct drm_framebuffer *fb)
+{
+   struct drm_modeset_acquire_ctx ctx;
+   struct drm_device *dev = fb->dev;
+   struct drm_atomic_state *state;
+   struct drm_plane *plane;
+   int ret = 0;
+   unsigned plane_mask;
+
+   state = drm_atomic_state_alloc(dev);
+   if (!state)
+   return -ENOMEM;
+
+   drm_modeset_acquire_init(&ctx, 0);
+   state->acquire_ctx = &ctx;
+
+retry:
+   plane_mask = 0;
+   ret = drm_modeset_lock_all_ctx(dev, &ctx);
+   if (ret)
+   goto unlock;
+
+   drm_for_each_plane(plane, dev) {
+   struct drm_plane_state *plane_state;
+
+   if (plane->state->fb != fb)
+   continue;
+
+   plane_state = drm_atomic_get_plane_state(state, plane);
+   if (IS_ERR(plane_state)) {
+   ret = PTR_ERR(plane_state);
+   goto unlock;
+   }
+
+   drm_atomic_set_fb_for_plane(plane_state, NULL);
+   ret = drm_atomic_set_crtc_for_plane(plane_state, NULL);
+   if (ret)
+   goto unlock;
+
+   plane_mask |= BIT(drm_plane_index(plane));
+
+   plane->old_fb = plane->fb;
+   plane->fb = NULL;
+   }
+
+   if (plane_mask)
+   ret = drm_atomic_commit(state);
+
+unlock:
+   if (plane_mask)
+   drm_atomic_clean_old_fb(dev, plane_mask, ret);
+
+   if (ret == -EDEADLK) {
+   drm_modeset_backoff(&ctx);
+   goto retry;
+   }
+
+   if (ret || !plane_mask)
+   drm_atomic_state_free(state);
+
+   drm_modeset_drop_locks(&ctx);
+   drm_modeset_acquire_fini(&ctx);
+
+   return ret;
+}
+
 int drm_mode_atomic_ioctl(struct drm_device *dev,
  void *data, struct drm_file *file_priv)
 {
diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
index 1f14c6565210..9e4bc06361ba 100644
--- a/drivers/gpu/drm/drm_crtc.c
+++ b/drivers/gpu/drm/drm_crtc.c
@@ -600,6 +600,11 @@ void drm_framebuffer_remove(struct drm_framebuffer *fb)
 * in this manner.
 */
if (drm_framebuffer_read_refcount(fb) > 1) {
+   if (dev->mode_config.funcs->atomic_commit) {
+   drm_atomic_remove_fb(fb);
+   goto out;
+   }
+
drm_modeset_lock_all(dev);
/* remove from any CRTC */
drm_for_each_crtc(crtc, dev) {
@@ -621,6 +626,7 @@ void drm_framebuffer_remove(struct drm_framebuffer *fb)
drm_modeset_unlock_all(dev);
}

+out:
drm_framebuffer_unreference(fb);
 }
 EXPORT_SYMBOL(drm_framebuffer_remove);
diff --git a/drivers/gpu/drm/drm_crtc_internal.h 
b/drivers/gpu/drm/drm_crtc_internal.h
index 8186c0e05c42..b426d37bc916 100644
--- a/drivers/gpu/drm/drm_crtc_internal.h
+++ b/drivers/gpu/drm/drm_crtc_internal.h
@@ -125,4 +125,5 @@ int drm_atomic_get_property(struct drm_mode_object *obj,
struct drm_property *property, uint64_t *val);
 int drm_mode_atomic_ioctl(struct drm_device *dev,
  void *data, struct drm_file *file_priv);
+int drm_atomic_remove_fb(struct drm_framebuffer *fb);

-- 
2.8.1



[PATCH 37/38] drm/sti: Don't call drm_helper_disable_unused_functions

2016-06-02 Thread Daniel Vetter
Atomic drivers are supposed to do hw/sw state reset with the
drm_mode_config_reset() call right above it.

Cc: Benjamin Gaignard 
Signed-off-by: Daniel Vetter 
---
 drivers/gpu/drm/sti/sti_drv.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/drivers/gpu/drm/sti/sti_drv.c b/drivers/gpu/drm/sti/sti_drv.c
index dd2c400c4a46..26aa85d4b872 100644
--- a/drivers/gpu/drm/sti/sti_drv.c
+++ b/drivers/gpu/drm/sti/sti_drv.c
@@ -279,7 +279,6 @@ static int sti_load(struct drm_device *dev, unsigned long 
flags)

drm_mode_config_reset(dev);

-   drm_helper_disable_unused_functions(dev);
drm_fbdev_cma_init(dev, 32,
   dev->mode_config.num_crtc,
   dev->mode_config.num_connector);
-- 
2.8.1



[PATCH 38/38] drm/crtc-helper: disable_unused_functions really isn't for atomic

2016-06-02 Thread Daniel Vetter
Rockchip just blew up here on testing, because I removed some "is this
crtc already disabled/enabled" state tracking from callbacks (not needed
with atomic). Turns out that was needed to work around rockchip still
calling legacy helper code.

Since me explaining on irc/mailing-list plus kerneldoc isn't enough,
be more verbose and add dmesg output. Not that anyone actually reads that,
either.

Cc: Tomeu Vizoso 
Signed-off-by: Daniel Vetter 
---
 drivers/gpu/drm/drm_crtc_helper.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/gpu/drm/drm_crtc_helper.c 
b/drivers/gpu/drm/drm_crtc_helper.c
index a6e42433ef0e..b47ec24939a0 100644
--- a/drivers/gpu/drm/drm_crtc_helper.c
+++ b/drivers/gpu/drm/drm_crtc_helper.c
@@ -232,6 +232,9 @@ static void __drm_helper_disable_unused_functions(struct 
drm_device *dev)
  */
 void drm_helper_disable_unused_functions(struct drm_device *dev)
 {
+   if (drm_core_check_feature(dev, DRIVER_ATOMIC))
+   DRM_ERROR("Called for atomic driver, this is not what you 
want.\n");
+
drm_modeset_lock_all(dev);
__drm_helper_disable_unused_functions(dev);
drm_modeset_unlock_all(dev);
-- 
2.8.1



[PATCH] drm: Deal with rotation in drm_plane_helper_check_update()

2016-06-02 Thread Patrik Jakobsson
On Wed, May 11, 2016 at 10:05 PM, Ville Syrjälä
 wrote:
> On Fri, Jan 15, 2016 at 08:51:06PM +0200, ville.syrjala at linux.intel.com 
> wrote:
>> From: Ville Syrjälä 
>>
>> drm_plane_helper_check_update() needs to account for the plane rotation
>> for correct clipping/scaling calculations. Do so.
>>
>> There was an earlier attempt [1] to add this into
>> intel_check_primary_plane() but I requested that it'd be put into the
>> helper instead. An updated patch never materialized AFAICS, so I went
>> ahead and cooked one up myself.
>
> Ping. Anyone interested in rotation actually working with
> drm_plane_helper_check_update() ?
>

Passing state structs sounds better but since that patch doesn't exist
I'd go for this one.

There are now more users of drm_plane_helper_check_update() so needs fixing.

With that done;
Reviewed-by: Patrik Jakobsson 

>>
>> [1] https://patchwork.freedesktop.org/patch/65177/
>> Cc: Nabendu Maiti 
>> Signed-off-by: Ville Syrjälä 
>> ---
>>  drivers/gpu/drm/armada/armada_overlay.c |  1 +
>>  drivers/gpu/drm/drm_plane_helper.c  | 28 
>> ++--
>>  drivers/gpu/drm/i915/intel_display.c|  2 ++
>>  drivers/gpu/drm/rockchip/rockchip_drm_vop.c |  1 +
>>  include/drm/drm_plane_helper.h  |  1 +
>>  5 files changed, 23 insertions(+), 10 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/armada/armada_overlay.c 
>> b/drivers/gpu/drm/armada/armada_overlay.c
>> index 148e8a42b2c6..1ee707ef6b8d 100644
>> --- a/drivers/gpu/drm/armada/armada_overlay.c
>> +++ b/drivers/gpu/drm/armada/armada_overlay.c
>> @@ -121,6 +121,7 @@ armada_ovl_plane_update(struct drm_plane *plane, struct 
>> drm_crtc *crtc,
>>   int ret;
>>
>>   ret = drm_plane_helper_check_update(plane, crtc, fb, &src, &dest, 
>> &clip,
>> + BIT(DRM_ROTATE_0),
>>   0, INT_MAX, true, false, &visible);
>>   if (ret)
>>   return ret;
>> diff --git a/drivers/gpu/drm/drm_plane_helper.c 
>> b/drivers/gpu/drm/drm_plane_helper.c
>> index 369d2898ff9e..0c12fa1a696f 100644
>> --- a/drivers/gpu/drm/drm_plane_helper.c
>> +++ b/drivers/gpu/drm/drm_plane_helper.c
>> @@ -115,6 +115,7 @@ static int get_connectors_for_crtc(struct drm_crtc *crtc,
>>   * @src: source coordinates in 16.16 fixed point
>>   * @dest: integer destination coordinates
>>   * @clip: integer clipping coordinates
>> + * @rotation: plane rotation
>>   * @min_scale: minimum @src:@dest scaling factor in 16.16 fixed point
>>   * @max_scale: maximum @src:@dest scaling factor in 16.16 fixed point
>>   * @can_position: is it legal to position the plane such that it
>> @@ -134,16 +135,17 @@ static int get_connectors_for_crtc(struct drm_crtc 
>> *crtc,
>>   * Zero if update appears valid, error code on failure
>>   */
>>  int drm_plane_helper_check_update(struct drm_plane *plane,
>> - struct drm_crtc *crtc,
>> - struct drm_framebuffer *fb,
>> - struct drm_rect *src,
>> - struct drm_rect *dest,
>> - const struct drm_rect *clip,
>> - int min_scale,
>> - int max_scale,
>> - bool can_position,
>> - bool can_update_disabled,
>> - bool *visible)
>> +   struct drm_crtc *crtc,
>> +   struct drm_framebuffer *fb,
>> +   struct drm_rect *src,
>> +   struct drm_rect *dest,
>> +   const struct drm_rect *clip,
>> +   unsigned int rotation,
>> +   int min_scale,
>> +   int max_scale,
>> +   bool can_position,
>> +   bool can_update_disabled,
>> +   bool *visible)
>>  {
>>   int hscale, vscale;
>>
>> @@ -163,6 +165,8 @@ int drm_plane_helper_check_update(struct drm_plane 
>> *plane,
>>   return -EINVAL;
>>   }
>>
>> + drm_rect_rotate(src, fb->width << 16, fb->height << 16, rotation);
>> +
>>   /* Check scaling */
>>   hscale = drm_rect_calc_hscale(src, dest, min_scale, max_scale);
>>   vscale = drm_rect_calc_vscale(src, dest, min_scale, max_scale);
>> @@ -174,6 +178,9 @@ int drm_plane_helper_check_update(struct drm_plane 
>> *plane,
>>   }
>>
>>   *visible = drm_rect_clip_scaled(src, dest, clip, hscale, vscale);
>> +
>> + drm_rect_rotate_inv(src, fb->width << 16, fb->height << 16, rotation);
>> +
>>   if (!*visible)
>>   /*
>>* Plane isn't visible; some drivers can handle this
>> @@ -265,6 +272,7 @@ int drm_primary_helper_update(struct drm_plane *plane, 
>> stru

[PATCH v7 00/12] Support non-lru page migration

2016-06-02 Thread Daniel Vetter
On Wed, Jun 01, 2016 at 02:41:51PM -0700, Andrew Morton wrote:
> On Wed,  1 Jun 2016 08:21:09 +0900 Minchan Kim  wrote:
> 
> > Recently, I got many reports about perfermance degradation in embedded
> > system(Android mobile phone, webOS TV and so on) and easy fork fail.
> > 
> > The problem was fragmentation caused by zram and GPU driver mainly.
> > With memory pressure, their pages were spread out all of pageblock and
> > it cannot be migrated with current compaction algorithm which supports
> > only LRU pages. In the end, compaction cannot work well so reclaimer
> > shrinks all of working set pages. It made system very slow and even to
> > fail to fork easily which requires order-[2 or 3] allocations.
> > 
> > Other pain point is that they cannot use CMA memory space so when OOM
> > kill happens, I can see many free pages in CMA area, which is not
> > memory efficient. In our product which has big CMA memory, it reclaims
> > zones too exccessively to allocate GPU and zram page although there are
> > lots of free space in CMA so system becomes very slow easily.
> 
> But this isn't presently implemented for GPU drivers or for CMA, yes?
> 
> What's the story there?

Broken (out-of-tree) drivers that don't allocate their gpu stuff
correctly.  There's piles of drivers that get_user_page all over the place
but then fail to timely get off these pages again. The fix is to get off
those pages again (either by unpinning timely, or registering an
mmu_notifier if the driver wants to keep the pages pinned indefinitely, as
a caching optimization).

At least that's my guess, and iirc it was confirmed first time around this
series showed up.
-Daniel
-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch


[PATCH 02/11] dma-buf/fence: add fence_array fences v6

2016-06-02 Thread Daniel Vetter
On Wed, Jun 01, 2016 at 09:54:04PM +0530, Sumit Semwal wrote:
> Hi Christian, Gustavo,
> 
> Thanks for these patches.
> 
> On 1 June 2016 at 20:55, Gustavo Padovan  wrote:
> > 2016-06-01 Christian König :
> >
> >> From: Gustavo Padovan 
> >>
> >> struct fence_collection inherits from struct fence and carries a
> >> collection of fences that needs to be waited together.
> >>
> >> It is useful to translate a sync_file to a fence to remove the complexity
> >> of dealing with sync_files on DRM drivers. So even if there are many
> >> fences in the sync_file that needs to waited for a commit to happen,
> >> they all get added to the fence_collection and passed for DRM use as
> >> a standard struct fence.
> >>
> >> That means that no changes needed to any driver besides supporting fences.
> >>
> >> fence_collection's fence doesn't belong to any timeline context, so
> >> fence_is_later() and fence_later() are not meant to be called with
> >> fence_collections fences.
> >>
> >> v2: Comments by Daniel Vetter:
> >>   - merge fence_collection_init() and fence_collection_add()
> >>   - only add callbacks at ->enable_signalling()
> >>   - remove fence_collection_put()
> >>   - check for type on to_fence_collection()
> >>   - adjust fence_is_later() and fence_later() to WARN_ON() if they
> >>   are used with collection fences.
> >>
> >> v3: - Initialize fence_cb.node at fence init.
> >>
> >> Comments by Chris Wilson:
> >>   - return "unbound" on fence_collection_get_timeline_name()
> >>   - don't stop adding callbacks if one fails
> >>   - remove redundant !! on fence_collection_enable_signaling()
> >>   - remove redundant () on fence_collection_signaled
> >>   - use fence_default_wait() instead
> >>
> >> v4 (chk): Rework, simplification and cleanup:
> >>   - Drop FENCE_NO_CONTEXT handling, always allocate a context.
> >>   - Rename to fence_array.
> >>   - Return fixed driver name.
> >>   - Register only one callback at a time.
> >>   - Document that create function takes ownership of array.
> >>
> >> v5 (chk): More work and fixes:
> >>   - Avoid deadlocks by adding all callbacks at once again.
> >>   - Stop trying to remove the callbacks.
> >>   - Provide context and sequence number for the array fence.
> >>
> >> v6 (chk): Fixes found during testing
> >>   - Fix stupid typo in _enable_signaling().
> >>
> >> Signed-off-by: Gustavo Padovan 
> >> Signed-off-by: Christian König 
> >> ---
> >>  drivers/dma-buf/Makefile  |   2 +-
> >>  drivers/dma-buf/fence-array.c | 127 
> >> ++
> >>  include/linux/fence-array.h   |  72 
> >>  3 files changed, 200 insertions(+), 1 deletion(-)
> >>  create mode 100644 drivers/dma-buf/fence-array.c
> >>  create mode 100644 include/linux/fence-array.h
> >
> > This is working fine to me. Once the commit message is fixed:
> >
> > Reviewed-by: Gustavo Padovan 
> >
> > You need to Cc Sumit here to decide who is picking these patches.
> > It would be better to get them through the drm trees so we would need
> > his Ack at least.
> >
> +1 on the commit message consistency change; post that, please feel
> free to add my
> Acked-by: Sumit Semwal 
> 
> for the 3 dma-buf/fences patches and request to take them via DRM tree
> as rightly suggested by Gustavo.

Commit message improved and all 3 queued up for drm-misc. I haven't pushed
out the new branch yet though, since I'm waiting for Dave to open drm-next
and pull in a few other bits first so that I can rebase.

Thanks, Daniel
-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch


[PATCH 00/12] Improve PX support in radeon and amdgpu

2016-06-02 Thread Mike Lothian
Are these in a branch somewhere? If not I'll try apply the mbox from
patchwork.freedesktop.org

On Wed, 1 Jun 2016 at 21:53 Alex Deucher  wrote:

> This patch set cleans up and attempts to make runtime pm more
> reliable in radeon and amdgpu on PX systems.  If you have a PX
> system that requires setting the runpm=0 module parameter for
> stability, please try this patch set.
>
> The main fix is that a minimum of 200ms of delay is required between
> a dGPU power down and a power up.
>
> This patch also properly handles the detection of the ATPX dGPU
> power control method properly and handles dGPU power control for
> platforms that do not support the ATPX dGPU power control method.
>
> Alex Deucher (12):
>   drm/amdgpu: disable power control on hybrid laptops
>   drm/amdgpu: clean up atpx power control handling
>   drm/amdgpu: add a delay after ATPX dGPU power off
>   drm/amdgpu/atpx: add a query for ATPX dGPU power control
>   drm/amdgpu: use PCI_D3hot for PX systems without dGPU power control
>   drm/amdgpu/atpx: drop forcing of dGPU power control
>   drm/radeon: disable power control on hybrid laptops
>   drm/radeon: clean up atpx power control handling
>   drm/radeon: add a delay after ATPX dGPU power off
>   drm/radeon/atpx: add a query for ATPX dGPU power control
>   drm/radeon: use PCI_D3hot for PX systems without dGPU power control
>   drm/radeon/atpx: drop forcing of dGPU power control
>
>  drivers/gpu/drm/amd/amdgpu/amdgpu.h  |  2 +
>  drivers/gpu/drm/amd/amdgpu/amdgpu_atpx_handler.c | 50
> 
>  drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c  |  5 ++-
>  drivers/gpu/drm/radeon/radeon_atpx_handler.c | 49
> +++
>  drivers/gpu/drm/radeon/radeon_drv.c  |  7 +++-
>  5 files changed, 77 insertions(+), 36 deletions(-)
>
> --
> 2.5.5
>
> ___
> dri-devel mailing list
> dri-devel at lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/dri-devel
>
-- next part --
An HTML attachment was scrubbed...
URL: 
<https://lists.freedesktop.org/archives/dri-devel/attachments/20160602/8ce83853/attachment.html>


[PATCH v7 00/12] Support non-lru page migration

2016-06-02 Thread Minchan Kim
On Wed, Jun 01, 2016 at 02:41:51PM -0700, Andrew Morton wrote:
> On Wed,  1 Jun 2016 08:21:09 +0900 Minchan Kim  wrote:
> 
> > Recently, I got many reports about perfermance degradation in embedded
> > system(Android mobile phone, webOS TV and so on) and easy fork fail.
> > 
> > The problem was fragmentation caused by zram and GPU driver mainly.
> > With memory pressure, their pages were spread out all of pageblock and
> > it cannot be migrated with current compaction algorithm which supports
> > only LRU pages. In the end, compaction cannot work well so reclaimer
> > shrinks all of working set pages. It made system very slow and even to
> > fail to fork easily which requires order-[2 or 3] allocations.
> > 
> > Other pain point is that they cannot use CMA memory space so when OOM
> > kill happens, I can see many free pages in CMA area, which is not
> > memory efficient. In our product which has big CMA memory, it reclaims
> > zones too exccessively to allocate GPU and zram page although there are
> > lots of free space in CMA so system becomes very slow easily.
> 
> But this isn't presently implemented for GPU drivers or for CMA, yes?

For GPU driver, Gioh implemented but it was proprietary so couldn't
contribute.

For CMA, [zram: use __GFP_MOVABLE for memory allocation] added __GFP_MOVABLE
for zsmalloc page allocation so it can use CMA area automatically now.

> 
> What's the story there?


[PATCH] drm/rockchip: vop: do axi reset in vop initial time

2016-06-02 Thread Yakir Yang

On 06/01/2016 11:19 PM, Thierry Reding wrote:
> On Wed, Jun 01, 2016 at 05:19:12PM +0800, Yakir Yang wrote:
>> There is a bug in RK3399 VOP, when bootloader/kernel only enable
>> VOP Big or VOP Little to display, then VOP IOMMU would failed to
>> reset at the initial time and VOP register couldn't write rightly.
>>
>> After do the pure reset of VOP module, then things back to right.
>>
>> Signed-off-by: Yakir Yang 
>> ---
>>   drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 15 ++-
>>   1 file changed, 14 insertions(+), 1 deletion(-)
>>
>> diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c 
>> b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
>> index 1c4d5b5..4150323 100644
>> --- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
>> +++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
>> @@ -1292,7 +1292,7 @@ static int vop_initial(struct vop *vop)
>>   {
>>  const struct vop_data *vop_data = vop->data;
>>  const struct vop_reg_data *init_table = vop_data->init_table;
>> -struct reset_control *ahb_rst;
>> +struct reset_control *ahb_rst, *axi_rst;
>>  int i, ret;
>>   
>>  vop->hclk = devm_clk_get(vop->dev, "hclk_vop");
>> @@ -1331,6 +1331,19 @@ static int vop_initial(struct vop *vop)
>>  }
>>   
>>  /*
>> + * do aclk_reset, reset all vop registers.
>> + */
>> +axi_rst = devm_reset_control_get(vop->dev, "axi");
> I don't think you want the managed version here since you only store
> this in a local variable and hence aren't going to need it afterwards.
> Just use reset_control_get() and ...

Great, but seems Mark would not accept this fix now :(
Maybe I should found the root cause why my bootloader/kernel would 
broken the VOP.

Thanks,
- Yakir
>> +if (IS_ERR(axi_rst)) {
>> +dev_err(vop->dev, "failed to get axi reset\n");
>> +ret = PTR_ERR(axi_rst);
>> +goto err_disable_aclk;
>> +}
>> +reset_control_assert(axi_rst);
>> +usleep_range(10, 20);
>> +reset_control_deassert(axi_rst);
> call reset_control_put() here.
>
>> +
>> +/*
>>   * do hclk_reset, reset all vop registers.
>>   */
>>  ahb_rst = devm_reset_control_get(vop->dev, "ahb");
> This uses the same pattern, so you might want to consider reworking this
> as well, though it should be a separate patch.
>
> Thierry




[PATCH 1/2] drm/rockchip: vop: Do check if an update is pending during disable

2016-06-02 Thread Tomeu Vizoso
On 25 May 2016 at 03:33, Mark yao  wrote:
> On 2016年05月25日 09:06, Mark yao wrote:
>
> On 2016年05月24日 18:11, Tomeu Vizoso wrote:
>
> Hi Tomeu
>>
>> Sorry for reply late.
>> I don't agree the changes:
>>
>> - if (!state->enable)
>> - return VOP_WIN_GET(vop_win->vop, vop_win->data, enable) == 0;
>> + if (!state->enable &&
>> +VOP_WIN_GET(vop_win->vop, vop_win->data, enable) == 0)
>> + return true;
>>
>> This changes actually would lead a bug.
>> when we disable a plane, the vop_win_pending_is_complete would always
>> return
>> true, That is not allowed, would cause fb free too early.
>
> Ok, maybe I need to ask you first what the original block of code
> intended to achieve. The TRM I have is very terse and I don't find any
> explanation there. The battery of tests I have pass just fine without
> it.
>
>> Does this patch is needed for "[PATCH 2/2] drm/rockchip: vop: Wait for
>> pending events when disabling a CRTC"
>
> Yes, this function is currently returning false when the pageflip has
> been completed but the plan has been already disabled.
>
> If you have any different idea of how to fix this bug, please share.
>
> Thanks,
>
> Tomeu
>
>
>
> Hi Tomeu
>
> @@ -504,6 +506,9 @@ static void vop_crtc_disable(struct drm_crtc *crtc)
>   if (!vop->is_enabled)
>   return;
>
> + if (crtc->state->event || vop->event)
> + vop_crtc_wait_for_update(crtc);
> +
>
> I think above change has some problem,
>
> the function stack:
> ->drm swap state
> ->vop_crtc_disable
> ->vop_atomic_begin
> ->vop_atomic_flush
>
> on vop_crtc_disable, crtc->state is new state, the crtc->state->event not
> yet update to vop, wait for  crtc->state->event here is wrong.
>
> So I think the patch should be:
> + if (vop->event)
> + vop_crtc_wait_for_update(crtc);
> +
>
>
> call vop_crtc_wait_for_update(crtc) here also is unsafe, it will reinit the
> vop->wait_update_complete.
>
> I doubt that, since use the serialize outstanding nonblocking commits, only
> one process can run into the update stack, old vop->event should be free on
> last time, if we get vop->event here, that should be a bug.
>
>
> Then the patch "drm/rockchip: vop: Do check if an update is pending during
> disable" should be no needed.

Hi Mark,

with Daniel's series linked below this and the other issues I found in
the Rockchip driver are fixed:

http://thread.gmane.org/gmane.comp.freedesktop.xorg.drivers.intel/91023/focus=91053

Thanks,

Tomeu

> Thanks.
>
> -- ï¼­ark Yao
>
> ___
> dri-devel mailing list
> dri-devel at lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/dri-devel
>
>
>
> --
> ï¼­ark Yao
>
>
> ___
> dri-devel mailing list
> dri-devel at lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/dri-devel
>


[PATCH 1/2] drm/rockchip: vop: Do check if an update is pending during disable

2016-06-02 Thread Mark yao
On 2016年06月02日 13:57, Tomeu Vizoso wrote:
> On 25 May 2016 at 03:33, Mark yao  wrote:
>> On 2016年05月25日 09:06, Mark yao wrote:
>>
>> On 2016年05月24日 18:11, Tomeu Vizoso wrote:
>>
>> Hi Tomeu
>>> Sorry for reply late.
>>> I don't agree the changes:
>>>
>>> - if (!state->enable)
>>> - return VOP_WIN_GET(vop_win->vop, vop_win->data, enable) == 0;
>>> + if (!state->enable &&
>>> +VOP_WIN_GET(vop_win->vop, vop_win->data, enable) == 0)
>>> + return true;
>>>
>>> This changes actually would lead a bug.
>>> when we disable a plane, the vop_win_pending_is_complete would always
>>> return
>>> true, That is not allowed, would cause fb free too early.
>> Ok, maybe I need to ask you first what the original block of code
>> intended to achieve. The TRM I have is very terse and I don't find any
>> explanation there. The battery of tests I have pass just fine without
>> it.
>>
>>> Does this patch is needed for "[PATCH 2/2] drm/rockchip: vop: Wait for
>>> pending events when disabling a CRTC"
>> Yes, this function is currently returning false when the pageflip has
>> been completed but the plan has been already disabled.
>>
>> If you have any different idea of how to fix this bug, please share.
>>
>> Thanks,
>>
>> Tomeu
>>
>>
>>
>> Hi Tomeu
>>
>> @@ -504,6 +506,9 @@ static void vop_crtc_disable(struct drm_crtc *crtc)
>>if (!vop->is_enabled)
>>return;
>>
>> + if (crtc->state->event || vop->event)
>> + vop_crtc_wait_for_update(crtc);
>> +
>>
>> I think above change has some problem,
>>
>> the function stack:
>> ->drm swap state
>> ->vop_crtc_disable
>> ->vop_atomic_begin
>> ->vop_atomic_flush
>>
>> on vop_crtc_disable, crtc->state is new state, the crtc->state->event not
>> yet update to vop, wait for  crtc->state->event here is wrong.
>>
>> So I think the patch should be:
>> + if (vop->event)
>> + vop_crtc_wait_for_update(crtc);
>> +
>>
>>
>> call vop_crtc_wait_for_update(crtc) here also is unsafe, it will reinit the
>> vop->wait_update_complete.
>>
>> I doubt that, since use the serialize outstanding nonblocking commits, only
>> one process can run into the update stack, old vop->event should be free on
>> last time, if we get vop->event here, that should be a bug.
>>
>>
>> Then the patch "drm/rockchip: vop: Do check if an update is pending during
>> disable" should be no needed.
> Hi Mark,
>
> with Daniel's series linked below this and the other issues I found in
> the Rockchip driver are fixed:
>
> http://thread.gmane.org/gmane.comp.freedesktop.xorg.drivers.intel/91023/focus=91053

Good news, I also see the Daniel's series patches, wonderful update.

You can add a Tested-by for Daniel's rockchip patches, and I add a 
Acked-by for those rockchip patches.

Thanks

> Thanks,
>
> Tomeu
>
>> Thanks.
>>
>> -- ï¼­ark Yao
>>
>> ___
>> dri-devel mailing list
>> dri-devel at lists.freedesktop.org
>> https://lists.freedesktop.org/mailman/listinfo/dri-devel
>>
>>
>>
>> --
>> ï¼­ark Yao
>>
>>
>> ___
>> dri-devel mailing list
>> dri-devel at lists.freedesktop.org
>> https://lists.freedesktop.org/mailman/listinfo/dri-devel
>>
>
>


-- 
ï¼­ark Yao




[PATCH 1/2] drm/rockchip: vop: Do check if an update is pending during disable

2016-06-02 Thread Tomeu Vizoso
On 2 June 2016 at 08:25, Mark yao  wrote:
> On 2016年06月02日 13:57, Tomeu Vizoso wrote:
>>
>> On 25 May 2016 at 03:33, Mark yao  wrote:
>>>
>>> On 2016年05月25日 09:06, Mark yao wrote:
>>>
>>> On 2016年05月24日 18:11, Tomeu Vizoso wrote:
>>>
>>> Hi Tomeu

 Sorry for reply late.
 I don't agree the changes:

 - if (!state->enable)
 - return VOP_WIN_GET(vop_win->vop, vop_win->data, enable) == 0;
 + if (!state->enable &&
 +VOP_WIN_GET(vop_win->vop, vop_win->data, enable) == 0)
 + return true;

 This changes actually would lead a bug.
 when we disable a plane, the vop_win_pending_is_complete would always
 return
 true, That is not allowed, would cause fb free too early.
>>>
>>> Ok, maybe I need to ask you first what the original block of code
>>> intended to achieve. The TRM I have is very terse and I don't find any
>>> explanation there. The battery of tests I have pass just fine without
>>> it.
>>>
 Does this patch is needed for "[PATCH 2/2] drm/rockchip: vop: Wait for
 pending events when disabling a CRTC"
>>>
>>> Yes, this function is currently returning false when the pageflip has
>>> been completed but the plan has been already disabled.
>>>
>>> If you have any different idea of how to fix this bug, please share.
>>>
>>> Thanks,
>>>
>>> Tomeu
>>>
>>>
>>>
>>> Hi Tomeu
>>>
>>> @@ -504,6 +506,9 @@ static void vop_crtc_disable(struct drm_crtc *crtc)
>>>if (!vop->is_enabled)
>>>return;
>>>
>>> + if (crtc->state->event || vop->event)
>>> + vop_crtc_wait_for_update(crtc);
>>> +
>>>
>>> I think above change has some problem,
>>>
>>> the function stack:
>>> ->drm swap state
>>> ->vop_crtc_disable
>>> ->vop_atomic_begin
>>> ->vop_atomic_flush
>>>
>>> on vop_crtc_disable, crtc->state is new state, the crtc->state->event not
>>> yet update to vop, wait for  crtc->state->event here is wrong.
>>>
>>> So I think the patch should be:
>>> + if (vop->event)
>>> + vop_crtc_wait_for_update(crtc);
>>> +
>>>
>>>
>>> call vop_crtc_wait_for_update(crtc) here also is unsafe, it will reinit
>>> the
>>> vop->wait_update_complete.
>>>
>>> I doubt that, since use the serialize outstanding nonblocking commits,
>>> only
>>> one process can run into the update stack, old vop->event should be free
>>> on
>>> last time, if we get vop->event here, that should be a bug.
>>>
>>>
>>> Then the patch "drm/rockchip: vop: Do check if an update is pending
>>> during
>>> disable" should be no needed.
>>
>> Hi Mark,
>>
>> with Daniel's series linked below this and the other issues I found in
>> the Rockchip driver are fixed:
>>
>>
>> http://thread.gmane.org/gmane.comp.freedesktop.xorg.drivers.intel/91023/focus=91053
>
>
> Good news, I also see the Daniel's series patches, wonderful update.
>
> You can add a Tested-by for Daniel's rockchip patches, and I add a Acked-by
> for those rockchip patches.

Yup, should be already there.

Regards,

Tomeu

> Thanks
>
>
>> Thanks,
>>
>> Tomeu
>>
>>> Thanks.
>>>
>>> -- ï¼­ark Yao
>>>
>>> ___
>>> dri-devel mailing list
>>> dri-devel at lists.freedesktop.org
>>> https://lists.freedesktop.org/mailman/listinfo/dri-devel
>>>
>>>
>>>
>>> --
>>> ï¼­ark Yao
>>>
>>>
>>> ___
>>> dri-devel mailing list
>>> dri-devel at lists.freedesktop.org
>>> https://lists.freedesktop.org/mailman/listinfo/dri-devel
>>>
>>
>>
>
>
> --
> ï¼­ark Yao
>
>
> ___
> dri-devel mailing list
> dri-devel at lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v2 1/5] drm/rockchip: sort registers define by chip's number

2016-06-02 Thread Tomasz Figa
Hi Mark,

Mark Yao  rock-chips.com> writes:
> 
> No functional changes, sort the vop registers to make
> code more readable.

I might have found a typo. I guess it could be just fixed in this patch,
if it's already moving the code around. Please see the comments inline.

> 
> Signed-off-by: Mark Yao  rock-chips.com>
> ---
>  drivers/gpu/drm/rockchip/rockchip_vop_reg.c |  166 +
--
>  drivers/gpu/drm/rockchip/rockchip_vop_reg.h |   88 +++---
>  2 files changed, 127 insertions(+), 127 deletions(-)
> 
> diff --git a/drivers/gpu/drm/rockchip/rockchip_vop_reg.c 
b/drivers/gpu/drm/rockchip/rockchip_vop_reg.c
> index 3166b46..e75b2b8 100644
> --- a/drivers/gpu/drm/rockchip/rockchip_vop_reg.c
> +++ b/drivers/gpu/drm/rockchip/rockchip_vop_reg.c
>  -50,6 +50,87  static const uint32_t 
formats_win_lite[] = {
>   DRM_FORMAT_BGR565,
>  };
> 
> +static const struct vop_scl_regs rk3066_win_scl = {

Why is this rk3066 and not rk3036? It doesn't match the sorting order
introduced by this patch, by the way. Typo?

> + .scale_yrgb_x = VOP_REG(RK3036_WIN0_SCL_FACTOR_YRGB, 0x, 0x0),
> + .scale_yrgb_y = VOP_REG(RK3036_WIN0_SCL_FACTOR_YRGB, 0x, 16),
> + .scale_cbcr_x = VOP_REG(RK3036_WIN0_SCL_FACTOR_CBR, 0x, 0x0),
> + .scale_cbcr_y = VOP_REG(RK3036_WIN0_SCL_FACTOR_CBR, 0x, 16),
> +};
> +
> +static const struct vop_win_phy rk3036_win0_data = {
> + .scl = &rk3066_win_scl,

Ditto.

Best regards,
Tomasz




[PATCH v2 1/5] drm/rockchip: sort registers define by chip's number

2016-06-02 Thread Mark yao
On 2016年06月02日 14:51, Tomasz Figa wrote:
> Hi Mark,
>
> Mark Yao  rock-chips.com> writes:
>> No functional changes, sort the vop registers to make
>> code more readable.
> I might have found a typo. I guess it could be just fixed in this patch,
> if it's already moving the code around. Please see the comments inline.
>
>> Signed-off-by: Mark Yao  rock-chips.com>
>> ---
>>   drivers/gpu/drm/rockchip/rockchip_vop_reg.c |  166 +
> --
>>   drivers/gpu/drm/rockchip/rockchip_vop_reg.h |   88 +++---
>>   2 files changed, 127 insertions(+), 127 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/rockchip/rockchip_vop_reg.c
> b/drivers/gpu/drm/rockchip/rockchip_vop_reg.c
>> index 3166b46..e75b2b8 100644
>> --- a/drivers/gpu/drm/rockchip/rockchip_vop_reg.c
>> +++ b/drivers/gpu/drm/rockchip/rockchip_vop_reg.c
>>   -50,6 +50,87  static const uint32_t
> formats_win_lite[] = {
>>  DRM_FORMAT_BGR565,
>>   };
>>
>> +static const struct vop_scl_regs rk3066_win_scl = {
> Why is this rk3066 and not rk3036? It doesn't match the sorting order
> introduced by this patch, by the way. Typo?

Right, That is my mistake, It's rk3036_win_scl, Typo problem.

Thanks.

>
>> +.scale_yrgb_x = VOP_REG(RK3036_WIN0_SCL_FACTOR_YRGB, 0x, 0x0),
>> +.scale_yrgb_y = VOP_REG(RK3036_WIN0_SCL_FACTOR_YRGB, 0x, 16),
>> +.scale_cbcr_x = VOP_REG(RK3036_WIN0_SCL_FACTOR_CBR, 0x, 0x0),
>> +.scale_cbcr_y = VOP_REG(RK3036_WIN0_SCL_FACTOR_CBR, 0x, 16),
>> +};
>> +
>> +static const struct vop_win_phy rk3036_win0_data = {
>> +.scl = &rk3066_win_scl,
> Ditto.
>
> Best regards,
> Tomasz
>
>
> ___
> dri-devel mailing list
> dri-devel at lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/dri-devel


-- 
ï¼­ark Yao




[PATCH 00/12] Improve PX support in radeon and amdgpu

2016-06-02 Thread Christian König
Am 01.06.2016 um 22:53 schrieb Alex Deucher:
> This patch set cleans up and attempts to make runtime pm more
> reliable in radeon and amdgpu on PX systems.  If you have a PX
> system that requires setting the runpm=0 module parameter for
> stability, please try this patch set.
>
> The main fix is that a minimum of 200ms of delay is required between
> a dGPU power down and a power up.
>
> This patch also properly handles the detection of the ATPX dGPU
> power control method properly and handles dGPU power control for
> platforms that do not support the ATPX dGPU power control method.

Acked-by: Christian König  for the whole series.

>
> Alex Deucher (12):
>drm/amdgpu: disable power control on hybrid laptops
>drm/amdgpu: clean up atpx power control handling
>drm/amdgpu: add a delay after ATPX dGPU power off
>drm/amdgpu/atpx: add a query for ATPX dGPU power control
>drm/amdgpu: use PCI_D3hot for PX systems without dGPU power control
>drm/amdgpu/atpx: drop forcing of dGPU power control
>drm/radeon: disable power control on hybrid laptops
>drm/radeon: clean up atpx power control handling
>drm/radeon: add a delay after ATPX dGPU power off
>drm/radeon/atpx: add a query for ATPX dGPU power control
>drm/radeon: use PCI_D3hot for PX systems without dGPU power control
>drm/radeon/atpx: drop forcing of dGPU power control
>
>   drivers/gpu/drm/amd/amdgpu/amdgpu.h  |  2 +
>   drivers/gpu/drm/amd/amdgpu/amdgpu_atpx_handler.c | 50 
> 
>   drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c  |  5 ++-
>   drivers/gpu/drm/radeon/radeon_atpx_handler.c | 49 
> +++
>   drivers/gpu/drm/radeon/radeon_drv.c  |  7 +++-
>   5 files changed, 77 insertions(+), 36 deletions(-)
>



[PATCH v2 3/5] drm/rockchip: vop: introduce VOP_REG_MASK

2016-06-02 Thread Tomasz Figa
Hi Mark,

Mark Yao  rock-chips.com> writes:

> 
> Some new vop register support mask, bit[16-31] is mask,
> bit[0-15] is value, the mask is correspond to the value.

Please see my comments inline.

> 
> Signed-off-by: Mark Yao  rock-chips.com>
> ---
>  drivers/gpu/drm/rockchip/rockchip_drm_vop.c |   45 ++---
--
>  drivers/gpu/drm/rockchip/rockchip_drm_vop.h |1 +
>  drivers/gpu/drm/rockchip/rockchip_vop_reg.c |9 +-
>  3 files changed, 32 insertions(+), 23 deletions(-)
> 
> diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c 
b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
> index 28596e7..59f24cd 100644
> --- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
> +++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
[snip]
> -static inline void vop_mask_write_relaxed(struct vop *vop, uint32_t 
offset,
> -   uint32_t mask, uint32_t v)
> -{
> - if (mask) {
> + if (write_mask) {
> + v = (v << shift) | (mask << (shift + 16));

If the caller gives "v" too big, it might get over the bit 16 and affect
the mask. IMHO it would be much safer to mask (v << shift) with 0x
just in case.

> + } else {
>   uint32_t cached_val = vop->regsbak[offset >> 2];
> 
> - cached_val = (cached_val & ~mask) | v;
> - writel_relaxed(cached_val, vop->regs + offset);
> - vop->regsbak[offset >> 2] = cached_val;
> + v = (cached_val & ~(mask << shift)) | (v << shift);

Should we also mask "v" with "mask" for better safety?

Best regards,
Tomasz




[PATCH 02/11] dma-buf/fence: add fence_array fences v6

2016-06-02 Thread Christian König
Am 02.06.2016 um 00:44 schrieb Daniel Vetter:
> On Wed, Jun 01, 2016 at 09:54:04PM +0530, Sumit Semwal wrote:
>> Hi Christian, Gustavo,
>>
>> Thanks for these patches.
>>
>> On 1 June 2016 at 20:55, Gustavo Padovan  wrote:
>>> 2016-06-01 Christian König :
>>>
 From: Gustavo Padovan 

 struct fence_collection inherits from struct fence and carries a
 collection of fences that needs to be waited together.

 It is useful to translate a sync_file to a fence to remove the complexity
 of dealing with sync_files on DRM drivers. So even if there are many
 fences in the sync_file that needs to waited for a commit to happen,
 they all get added to the fence_collection and passed for DRM use as
 a standard struct fence.

 That means that no changes needed to any driver besides supporting fences.

 fence_collection's fence doesn't belong to any timeline context, so
 fence_is_later() and fence_later() are not meant to be called with
 fence_collections fences.

 v2: Comments by Daniel Vetter:
- merge fence_collection_init() and fence_collection_add()
- only add callbacks at ->enable_signalling()
- remove fence_collection_put()
- check for type on to_fence_collection()
- adjust fence_is_later() and fence_later() to WARN_ON() if they
are used with collection fences.

 v3: - Initialize fence_cb.node at fence init.

  Comments by Chris Wilson:
- return "unbound" on fence_collection_get_timeline_name()
- don't stop adding callbacks if one fails
- remove redundant !! on fence_collection_enable_signaling()
- remove redundant () on fence_collection_signaled
- use fence_default_wait() instead

 v4 (chk): Rework, simplification and cleanup:
- Drop FENCE_NO_CONTEXT handling, always allocate a context.
- Rename to fence_array.
- Return fixed driver name.
- Register only one callback at a time.
- Document that create function takes ownership of array.

 v5 (chk): More work and fixes:
- Avoid deadlocks by adding all callbacks at once again.
- Stop trying to remove the callbacks.
- Provide context and sequence number for the array fence.

 v6 (chk): Fixes found during testing
- Fix stupid typo in _enable_signaling().

 Signed-off-by: Gustavo Padovan 
 Signed-off-by: Christian König 
 ---
   drivers/dma-buf/Makefile  |   2 +-
   drivers/dma-buf/fence-array.c | 127 
 ++
   include/linux/fence-array.h   |  72 
   3 files changed, 200 insertions(+), 1 deletion(-)
   create mode 100644 drivers/dma-buf/fence-array.c
   create mode 100644 include/linux/fence-array.h
>>> This is working fine to me. Once the commit message is fixed:
>>>
>>> Reviewed-by: Gustavo Padovan 
>>>
>>> You need to Cc Sumit here to decide who is picking these patches.
>>> It would be better to get them through the drm trees so we would need
>>> his Ack at least.
>>>
>> +1 on the commit message consistency change; post that, please feel
>> free to add my
>> Acked-by: Sumit Semwal 
>>
>> for the 3 dma-buf/fences patches and request to take them via DRM tree
>> as rightly suggested by Gustavo.
> Commit message improved and all 3 queued up for drm-misc. I haven't pushed
> out the new branch yet though, since I'm waiting for Dave to open drm-next
> and pull in a few other bits first so that I can rebase.

Thanks and sorry for missing the commit message. I was a bit to 
concentrated on fixing the code.

Leave me a note when the branch is public available, cause I then want 
to rebase the amdgpu changes on top and send a pull request to Alex.

Christian.

>
> Thanks, Daniel



[Bug 91880] Radeonsi on Grenada cards (r9 390) exceptionally unstable and poorly performing

2016-06-02 Thread bugzilla-dae...@freedesktop.org
https://bugs.freedesktop.org/show_bug.cgi?id=91880

--- Comment #104 from Ernst Sjöstrand  ---
https://patchwork.freedesktop.org/series/8116/

-- 
You are receiving this mail because:
You are the assignee for the bug.
-- next part --
An HTML attachment was scrubbed...
URL: 
<https://lists.freedesktop.org/archives/dri-devel/attachments/20160602/b8c5deb9/attachment.html>


[PATCH v2 4/5] drm/rockchip: vop: add rk3399 vop support

2016-06-02 Thread Tomasz Figa
Hi Mark,

Mark Yao  rock-chips.com> writes:

> 
> There are two VOP in rk3399 chip, respectively VOP_BIG and VOP_LIT.
> most registers layout of this two vop is same, their framework are both
> VOP_FULL, the Major differences of this two is that:

Reviewed-by: Tomasz Figa 

Best regards,
Tomasz




[PATCH v2 5/5] dt-bindings: add documentation for Rockchip rk3399 display controllers

2016-06-02 Thread Tomasz Figa
Hi Mark,

Mark Yao  rock-chips.com> writes:

> 
> Cc: Rob Herring  kernel.org>
> Cc: Pawel Moll  arm.com>
> Cc: Mark Rutland  arm.com>
> Cc: Ian Campbell  hellion.org.uk>
> Cc: Kumar Gala  codeaurora.org>
> 
> Signed-off-by: Mark Yao  rock-chips.com>
> ---
>  .../bindings/display/rockchip/rockchip-vop.txt |5 +
>  1 file changed, 5 insertions(+)

Please see my comment inline.

> 
> diff --git a/Documentation/devicetree/bindings/display/rockchip/rockchip-
vop.txt b/Documentation/devicetree/bindings/display/rockchip/rockchip-
vop.txt
> index 196121f..6bf8473 100644
> --- a/Documentation/devicetree/bindings/display/rockchip/rockchip-vop.txt
> +++ b/Documentation/devicetree/bindings/display/rockchip/rockchip-vop.txt
>  -8,6 +8,11  Required properties:
>  - compatible: value should be one of the following
>   "rockchip,rk3036-vop";
>   "rockchip,rk3288-vop";
> + "rockchip,rk3399-vop-big";
> + "rockchip,rk3399-vop-lit";
> +Document compatible values for rk3399 display controllers.
> +Big and little display controllers are not identical and have differing
> +feature sets on the rk3399.

I think this doesn't really need any explanation. If two separate 
compatible strings are given, it means that the hardware is different. :)

Other than that,

Reviewed-by: Tomasz Figa 

Best regards,
Tomasz




[PATCH v4 1/2] drm: bridge: Add sii902x driver

2016-06-02 Thread Boris Brezillon
Hi Daniel,

On Wed, 1 Jun 2016 23:56:02 +0200
Daniel Vetter  wrote:

> On Wed, Jun 01, 2016 at 06:03:37PM +0200, Boris Brezillon wrote:
> > On Tue, 17 May 2016 08:47:11 +0200
> > Daniel Vetter  wrote:
> >   
> > > > +static struct drm_encoder *sii902x_best_encoder(struct drm_connector 
> > > > *connector)
> > > > +{
> > > > +   struct sii902x *sii902x = connector_to_sii902x(connector);
> > > > +
> > > > +   return sii902x->bridge.encoder;
> > > > +}
> > > 
> > > drm_atomic_helper_best_encoder should do exactly this for you. If you feel
> > > board pimp the atomic helpers to call that one by default to even remove
> > > the vfunc assingment line ;-)  
> > 
> > Just to be sure, is that what you had in mind?  
> 
> Exactly, I'll pick this one up for drm-misc. btw if you're even more
> motivated, you can go through all drivers with a static mapping from
> connector to encoder, and nuke those functions. Since if it's just a
> static mapping, the only way to do it is like the helper does.
> 
> Thanks, Daniel
> >   
> > --->8---  
> > From d218b7ea16ca35452b3174c83a207ecd406e5c88 Mon Sep 17 00:00:00 2001
> > From: Boris Brezillon 
> > Date: Wed, 1 Jun 2016 17:57:18 +0200
> > Subject: [PATCH] drm: atomic: Handle funcs->best_encoder == NULL case
> > 
> > Fallback drm_atomic_helper_best_encoder() is funcs->best_encoder() is NULL

Oops, can you fix the commit message before applying?

"
Fallback *to* drm_atomic_helper_best_encoder() *if*
funcs->best_encoder() is NULL
"

Maybe I should resend the patch along with the other modifications you
asked for. This way it will in a dedicated thread, instead of being
hidden in an unrelated patch series.

Regards,

Boris


> > so that DRM drivers can leave this hook unassigned if they know they want
> > to use drm_atomic_helper_best_encoder().
> > 
> > Signed-off-by: Boris Brezillon 
> > ---
> >  drivers/gpu/drm/drm_atomic_helper.c | 4 +++-
> >  1 file changed, 3 insertions(+), 1 deletion(-)
> > 
> > diff --git a/drivers/gpu/drm/drm_atomic_helper.c 
> > b/drivers/gpu/drm/drm_atomic_helper.c
> > index ddfa0d1..f6a3350 100644
> > --- a/drivers/gpu/drm/drm_atomic_helper.c
> > +++ b/drivers/gpu/drm/drm_atomic_helper.c
> > @@ -110,8 +110,10 @@ static int handle_conflicting_encoders(struct 
> > drm_atomic_state *state,
> >  
> > if (funcs->atomic_best_encoder)
> > new_encoder = funcs->atomic_best_encoder(connector, 
> > conn_state);
> > -   else
> > +   else if (funcs->best_encoder)
> > new_encoder = funcs->best_encoder(connector);
> > +   else
> > +   new_encoder = drm_atomic_helper_best_encoder(connector);
> >  
> > if (new_encoder) {
> > if (encoder_mask & (1 << 
> > drm_encoder_index(new_encoder))) {
> > 
> > 
> >   
> 



-- 
Boris Brezillon, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com


[PATCH v4 1/2] drm: bridge: Add sii902x driver

2016-06-02 Thread Boris Brezillon
On Wed, 1 Jun 2016 23:56:02 +0200
Daniel Vetter  wrote:

> On Wed, Jun 01, 2016 at 06:03:37PM +0200, Boris Brezillon wrote:
> > On Tue, 17 May 2016 08:47:11 +0200
> > Daniel Vetter  wrote:
> >   
> > > > +static struct drm_encoder *sii902x_best_encoder(struct drm_connector 
> > > > *connector)
> > > > +{
> > > > +   struct sii902x *sii902x = connector_to_sii902x(connector);
> > > > +
> > > > +   return sii902x->bridge.encoder;
> > > > +}
> > > 
> > > drm_atomic_helper_best_encoder should do exactly this for you. If you feel
> > > board pimp the atomic helpers to call that one by default to even remove
> > > the vfunc assingment line ;-)  
> > 
> > Just to be sure, is that what you had in mind?  
> 
> Exactly, I'll pick this one up for drm-misc. btw if you're even more
> motivated, you can go through all drivers with a static mapping from
> connector to encoder, and nuke those functions. Since if it's just a
> static mapping, the only way to do it is like the helper does.
> 
> Thanks, Daniel
> >   
> > --->8---  
> > From d218b7ea16ca35452b3174c83a207ecd406e5c88 Mon Sep 17 00:00:00 2001
> > From: Boris Brezillon 
> > Date: Wed, 1 Jun 2016 17:57:18 +0200
> > Subject: [PATCH] drm: atomic: Handle funcs->best_encoder == NULL case
> > 
> > Fallback drm_atomic_helper_best_encoder() is funcs->best_encoder() is NULL
> > so that DRM drivers can leave this hook unassigned if they know they want
> > to use drm_atomic_helper_best_encoder().

Please don't apply the patch, it's buggy.

> > 
> > Signed-off-by: Boris Brezillon 
> > ---
> >  drivers/gpu/drm/drm_atomic_helper.c | 4 +++-
> >  1 file changed, 3 insertions(+), 1 deletion(-)
> > 
> > diff --git a/drivers/gpu/drm/drm_atomic_helper.c 
> > b/drivers/gpu/drm/drm_atomic_helper.c
> > index ddfa0d1..f6a3350 100644
> > --- a/drivers/gpu/drm/drm_atomic_helper.c
> > +++ b/drivers/gpu/drm/drm_atomic_helper.c
> > @@ -110,8 +110,10 @@ static int handle_conflicting_encoders(struct 
> > drm_atomic_state *state,
> >  
> > if (funcs->atomic_best_encoder)
> > new_encoder = funcs->atomic_best_encoder(connector, 
> > conn_state);
> > -   else
> > +   else if (funcs->best_encoder)
> > new_encoder = funcs->best_encoder(connector);
> > +   else
> > +   new_encoder = drm_atomic_helper_best_encoder(connector);
> >  
> > if (new_encoder) {
> > if (encoder_mask & (1 << 
> > drm_encoder_index(new_encoder))) {
> > 
> > 
> >   
> 



-- 
Boris Brezillon, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com


[PATCH 1/2] drm/dsi: Implement set tear scanline

2016-06-02 Thread Vinay Simha BN
Provide a small convenience wrapper that transmits
ia set_tear_scanline command as suggested by
Thierry Reding.

Also includes small build fixes from Sumit Semwal.

Cc: Archit Taneja 
Cc: John Stultz 
Cc: Thierry Reding 
Cc: Sumit Semwal 
Signed-off-by: Vinay Simha BN 
---
 drivers/gpu/drm/drm_mipi_dsi.c | 23 +++
 include/drm/drm_mipi_dsi.h |  2 ++
 2 files changed, 25 insertions(+)

diff --git a/drivers/gpu/drm/drm_mipi_dsi.c b/drivers/gpu/drm/drm_mipi_dsi.c
index f5d8083..2f0b85c 100644
--- a/drivers/gpu/drm/drm_mipi_dsi.c
+++ b/drivers/gpu/drm/drm_mipi_dsi.c
@@ -983,6 +983,29 @@ int mipi_dsi_dcs_set_tear_on(struct mipi_dsi_device *dsi,
 EXPORT_SYMBOL(mipi_dsi_dcs_set_tear_on);

 /**
+ * mipi_dsi_set_tear_scanline() - turn on the display module's Tearing Effect
+ * output signal on the TE signal line when display module reaches line N
+ * defined by STS[n:0].
+ * @dsi: DSI peripheral device
+ * @param1: STS[10:8]
+ * @param2: STS[7:0]
+ * Return: 0 on success or a negative error code on failure
+ */
+int mipi_dsi_set_tear_scanline(struct mipi_dsi_device *dsi,
+  u8 param1, u8 param2)
+{
+   u8 payload[3] = { MIPI_DCS_SET_TEAR_SCANLINE, param1, param2};
+   ssize_t err;
+
+   err = mipi_dsi_generic_write(dsi, &payload, sizeof(payload));
+   if (err < 0)
+   return err;
+
+   return 0;
+}
+EXPORT_SYMBOL(mipi_dsi_set_tear_scanline);
+
+/**
  * mipi_dsi_dcs_set_pixel_format() - sets the pixel format for the RGB image
  *data used by the interface
  * @dsi: DSI peripheral device
diff --git a/include/drm/drm_mipi_dsi.h b/include/drm/drm_mipi_dsi.h
index 7a9840f..2788dbe 100644
--- a/include/drm/drm_mipi_dsi.h
+++ b/include/drm/drm_mipi_dsi.h
@@ -263,6 +263,8 @@ int mipi_dsi_dcs_set_column_address(struct mipi_dsi_device 
*dsi, u16 start,
u16 end);
 int mipi_dsi_dcs_set_page_address(struct mipi_dsi_device *dsi, u16 start,
  u16 end);
+int mipi_dsi_set_tear_scanline(struct mipi_dsi_device *dsi, u8 param1,
+  u8 param2);
 int mipi_dsi_dcs_set_tear_off(struct mipi_dsi_device *dsi);
 int mipi_dsi_dcs_set_tear_on(struct mipi_dsi_device *dsi,
 enum mipi_dsi_dcs_tear_mode mode);
-- 
1.9.1



[PATCH 2/2] drm/dsi: Implement dcs backlight brightness

2016-06-02 Thread Vinay Simha BN
Provide a small convenience wrapper that set/get the
backlight brightness control and creates the backlight
device for the panel interface

Cc: John Stultz 
Cc: Sumit Semwal 
Cc: Archit Taneja 
Cc: Rob Clark 
Signed-off-by: Vinay Simha BN 

--
v1:
 *tested in nexus7 2nd gen.
---
 drivers/gpu/drm/drm_mipi_dsi.c | 63 ++
 include/drm/drm_mipi_dsi.h |  3 ++
 2 files changed, 66 insertions(+)

diff --git a/drivers/gpu/drm/drm_mipi_dsi.c b/drivers/gpu/drm/drm_mipi_dsi.c
index 2f0b85c..ac4521e 100644
--- a/drivers/gpu/drm/drm_mipi_dsi.c
+++ b/drivers/gpu/drm/drm_mipi_dsi.c
@@ -1026,6 +1026,69 @@ int mipi_dsi_dcs_set_pixel_format(struct mipi_dsi_device 
*dsi, u8 format)
 }
 EXPORT_SYMBOL(mipi_dsi_dcs_set_pixel_format);

+static int dsi_dcs_bl_get_brightness(struct backlight_device *bl)
+{
+   struct mipi_dsi_device *dsi = bl_get_data(bl);
+   int ret;
+   u8 brightness;
+
+   dsi->mode_flags &= ~MIPI_DSI_MODE_LPM;
+
+   ret = mipi_dsi_dcs_read(dsi, MIPI_DCS_GET_DISPLAY_BRIGHTNESS,
+   &brightness, sizeof(brightness));
+   if (ret < 0)
+   return ret;
+
+   dsi->mode_flags |= MIPI_DSI_MODE_LPM;
+
+   return brightness;
+}
+
+static int dsi_dcs_bl_update_status(struct backlight_device *bl)
+{
+   struct mipi_dsi_device *dsi = bl_get_data(bl);
+   int ret;
+   u8 brightness = bl->props.brightness;
+
+   dsi->mode_flags &= ~MIPI_DSI_MODE_LPM;
+
+   ret = mipi_dsi_dcs_write(dsi, MIPI_DCS_SET_DISPLAY_BRIGHTNESS,
+&brightness, sizeof(brightness));
+   if (ret < 0)
+   return ret;
+
+   dsi->mode_flags |= MIPI_DSI_MODE_LPM;
+
+   return 0;
+}
+
+static const struct backlight_ops dsi_bl_ops = {
+   .update_status = dsi_dcs_bl_update_status,
+   .get_brightness = dsi_dcs_bl_get_brightness,
+};
+
+/**
+ * drm_panel_create_dsi_backlight() - creates the backlight device for the 
panel
+ * @dsi: DSI peripheral device
+ *
+ * @return a struct backlight on success, or an ERR_PTR on error
+ */
+struct backlight_device
+   *drm_panel_create_dsi_backlight(struct mipi_dsi_device *dsi)
+{
+   struct device *dev = &dsi->dev;
+   struct backlight_properties props;
+
+   memset(&props, 0, sizeof(props));
+   props.type = BACKLIGHT_RAW;
+   props.brightness = 255;
+   props.max_brightness = 255;
+
+   return devm_backlight_device_register(dev, dev_name(dev), dev, dsi,
+ &dsi_bl_ops, &props);
+}
+EXPORT_SYMBOL(drm_panel_create_dsi_backlight);
+
 static int mipi_dsi_drv_probe(struct device *dev)
 {
struct mipi_dsi_driver *drv = to_mipi_dsi_driver(dev->driver);
diff --git a/include/drm/drm_mipi_dsi.h b/include/drm/drm_mipi_dsi.h
index 2788dbe..9dd6a97 100644
--- a/include/drm/drm_mipi_dsi.h
+++ b/include/drm/drm_mipi_dsi.h
@@ -12,6 +12,7 @@
 #ifndef __DRM_MIPI_DSI_H__
 #define __DRM_MIPI_DSI_H__

+#include 
 #include 

 struct mipi_dsi_host;
@@ -269,6 +270,8 @@ int mipi_dsi_dcs_set_tear_off(struct mipi_dsi_device *dsi);
 int mipi_dsi_dcs_set_tear_on(struct mipi_dsi_device *dsi,
 enum mipi_dsi_dcs_tear_mode mode);
 int mipi_dsi_dcs_set_pixel_format(struct mipi_dsi_device *dsi, u8 format);
+struct backlight_device
+   *drm_panel_create_dsi_backlight(struct mipi_dsi_device *dsi);

 /**
  * struct mipi_dsi_driver - DSI driver
-- 
1.9.1



[RFC PATCH 3/4] PM / devfreq: rockchip: add devfreq driver for rk3399 dmc

2016-06-02 Thread hl
Hi Myungloo Ham,


On 2016年06月01日 18:47, MyungJoo Ham wrote:
> On Wed, Jun 1, 2016 at 6:35 PM, Lin Huang  wrote:
>> there is dfi controller on rk3399 platform, it can monitor
>> ddr load, register this controller to devfreq framework, and
>> default to use simple_ondeamnd policy, and do ddr frequency
>> scaling base on this result.
>>
>> Signed-off-by: Lin Huang 
>> ---
>>   drivers/devfreq/Kconfig |   2 +-
>>   drivers/devfreq/Makefile|   1 +
>>   drivers/devfreq/rockchip/Kconfig|  14 +
>>   drivers/devfreq/rockchip/Makefile   |   2 +
>>   drivers/devfreq/rockchip/rk3399_dmc.c   | 438 
>> 
>>   drivers/devfreq/rockchip/rockchip_dmc.c | 132 ++
>>   include/soc/rockchip/rockchip_dmc.h |  44 
>>   7 files changed, 632 insertions(+), 1 deletion(-)
>>   create mode 100644 drivers/devfreq/rockchip/Kconfig
>>   create mode 100644 drivers/devfreq/rockchip/Makefile
>>   create mode 100644 drivers/devfreq/rockchip/rk3399_dmc.c
>>   create mode 100644 drivers/devfreq/rockchip/rockchip_dmc.c
>>   create mode 100644 include/soc/rockchip/rockchip_dmc.h
>>
>> +
>> +   /* check the rate we get whether correct */
>> +   dmcfreq->rate = clk_get_rate(dmcfreq->dmc_clk);
>> +   if (dmcfreq->rate != target_rate) {
>> +   dev_err(dev, "get wrong ddr frequency, Request freq %lu,\
>> +   Current freq %lu\n", target_rate, dmcfreq->rate);
>> +   regulator_set_voltage(dmcfreq->vdd_center, dmcfreq->volt,
>> + dmcfreq->volt);
> Why do you need to check this and
> more importantly, why do you assume that dmvfreq->volt
> will be safe in this case? (what if the new dmcfreq->rate is
> larger than the old dmcfreq->rate after clk_get_rate?)
> Note that you didn't update dmcfreq->volt after clk_get_rate()
 Now we will set the ddr clock rate in bl31 use dcf controller(as i 
show in the patch cover letter),
  and there only two result we can get, set clock rate fail(ddr 
clock still in old rate) or set clock rate
 sucessful(use the new ddr rate), if the set rate fail, we should 
keep the voltage old value. Ah, you
 remind me, i should check clock rate before:
 if (old_clk_rate > target_rate)
 otherwise there have chance set high rate fail and use low voltage.

 And about the dmcfreq->volt, i will update this value when into the 
function, throuth

 opp = devfreq_recommended_opp(dev, &dmcfreq->rate, flags);
 if (IS_ERR(opp)) {
 rcu_read_unlock();
 return PTR_ERR(opp);
 }
 dmcfreq->volt = dev_pm_opp_get_voltage(opp);
>
>> +EXPORT_SYMBOL_GPL(dmc_event);
>> +EXPORT_SYMBOL_GPL(rockchip_dmc_enabled);
>> +EXPORT_SYMBOL_GPL(rockchip_dmc_enable);
>> +EXPORT_SYMBOL_GPL(rockchip_dmc_disable);
>> +EXPORT_SYMBOL_GPL(dmc_register_notifier);
>> +EXPORT_SYMBOL_GPL(dmc_unregister_notifier);
>> +EXPORT_SYMBOL_GPL(rockchip_dmc_get);
>> +EXPORT_SYMBOL_GPL(rockchip_dmc_put);
> Do you really need to export all these device driver specific
> functions? Looks like a design flaw here.
>
 there is some situation we need to disable ddr frequency 
scaling(connect two panel etc)
 on rk3399 platform, and it should be also needed on other rockchip 
platform, so i move these
 funticon as separate file.
>
> Cheers,
> MyungJoo
>
>

-- 
Lin Huang




[RFC PATCH 2/4] clk: rockchip: rk3399: add ddrc clock support

2016-06-02 Thread hl
Hi Doug&Heiko,

On 2016年06月01日 23:46, Heiko Stübner wrote:
> Am Mittwoch, 1. Juni 2016, 08:24:48 schrieb Doug Anderson:
>> Lin Huang,
>>
>> On Wed, Jun 1, 2016 at 2:35 AM, Lin Huang  wrote:
>>> add ddrc clock setting, so we can do ddr frequency
>>> scaling on rk3399 platform in future.
>>>
>>> Signed-off-by: Lin Huang 
>>> ---
>>>
>>>   drivers/clk/rockchip/clk-rk3399.c  | 16 
>>>   include/dt-bindings/clock/rk3399-cru.h |  1 +
>>>   2 files changed, 17 insertions(+)
>>>
>>> diff --git a/drivers/clk/rockchip/clk-rk3399.c
>>> b/drivers/clk/rockchip/clk-rk3399.c index f1d8e44..749ea59 100644
>>> --- a/drivers/clk/rockchip/clk-rk3399.c
>>> +++ b/drivers/clk/rockchip/clk-rk3399.c
>>> @@ -118,6 +118,10 @@ PNAME(mux_armclkb_p)   =
>>> { "clk_core_b_lpll_src",>
>>>  "clk_core_b_bpll_src",
>>>  "clk_core_b_dpll_src",
>>>  "clk_core_b_gpll_src"
>>>  };
>>>
>>> +PNAME(mux_ddrclk_p)= { "clk_ddrc_lpll_src",
>>> +   "clk_ddrc_bpll_src",
>>> +   "clk_ddrc_dpll_src",
>>> +   "clk_ddrc_gpll_src" };
>>>
>>>   PNAME(mux_aclk_cci_p)  = { "cpll_aclk_cci_src",
>>>   
>>>  "gpll_aclk_cci_src",
>>>  "npll_aclk_cci_src",
>>>
>>> @@ -1377,6 +1381,18 @@ static struct rockchip_clk_branch
>>> rk3399_clk_branches[] __initdata = {>
>>>  COMPOSITE_NOMUX(0, "clk_test", "clk_test_pre", CLK_IGNORE_UNUSED,
>>>  
>>>  RK3368_CLKSEL_CON(58), 0, 5, DFLAGS,
>>>  RK3368_CLKGATE_CON(13), 11, GFLAGS),
>>>
>>> +
>>> +   /* ddrc */
>>> +   GATE(0, "clk_ddrc_lpll_src", "lpll", CLK_IGNORE_UNUSED,
>>> +RK3399_CLKGATE_CON(3), 0, GFLAGS),
>>> +   GATE(0, "clk_ddrc_bpll_src", "bpll", CLK_IGNORE_UNUSED,
>>> +RK3399_CLKGATE_CON(3), 1, GFLAGS),
>>> +   GATE(0, "clk_ddrc_dpll_src", "dpll", CLK_IGNORE_UNUSED,
>>> +RK3399_CLKGATE_CON(3), 2, GFLAGS),
>>> +   GATE(0, "clk_ddrc_gpll_src", "gpll", CLK_IGNORE_UNUSED,
>>> +RK3399_CLKGATE_CON(3), 3, GFLAGS),
>>> +   COMPOSITE_DDRC(SCLK_DDRCLK, "clk_ddrc", mux_ddrclk_p,
>>> CLK_IGNORE_UNUSED, +  RK3399_CLKSEL_CON(6), 4, 2,
>>> MFLAGS, 0, 3, DFLAGS),
>> It seems slightly unfortunate that we need CLK_IGNORE_UNUSED on these.
>> Only one of these will ever be used at once and it would be awfully
>> nice if the others could get gated, right?
>>
>> ...presumably this is needed because we might not have an actual
>> driver for DDR Freq and we definitely want to make sure that clk_ddrc
>> is enabled in that case.  I guess what we really want is something
>> like CLK_ENABLE_HAND_OFF eventually, but until then I think you might
>> get slightly better behavior by getting rid of all of these
>> CLK_IGNORE_UNUSED and setting "clk_ddrc" as a critical clock, either
>> using the table in this file or the new flag.
> My current feeling is that staying with the homegrown solution for critical
> clocks might be preferable until the clk-handoff mechanism lands as well, as
> our critical clocks fall into both categories and I'd like to not touch
> everything twice.
>
> The clock above should be controlled by the dcf, so falls into the handoff
> category (critical until a driver picks up the clock).
>
> Also mixing both new and old approach might get confusing.
>
> But I'm definitly open to counter-arguments :-)
 I will remove CLK_IGNORE_UNUSED flag  and set
 "clk_ddrc"  as critical clock in next version. Besides, i think we 
should also
 set "clk_ddrc_dpll_src" as critical clock, since we always use dpll 
as ddr clock source,
 and it should always on.
>
>>>   };
>>>   
>>>   static struct rockchip_clk_branch rk3399_clk_pmu_branches[] __initdata =
>>>   {
>>>
>>> diff --git a/include/dt-bindings/clock/rk3399-cru.h
>>> b/include/dt-bindings/clock/rk3399-cru.h index 50a44cf..8a0f0442 100644
>>> --- a/include/dt-bindings/clock/rk3399-cru.h
>>> +++ b/include/dt-bindings/clock/rk3399-cru.h
>>> @@ -131,6 +131,7 @@
>>>
>>>   #define SCLK_DPHY_RX0_CFG  165
>>>   #define SCLK_RMII_SRC  166
>>>   #define SCLK_PCIEPHY_REF100M   167
>>>
>>> +#define SCLK_DDRCLK168
>> Almost certainly you'll want to create a separate patch for the
>> dt-bindings change since it will need to land in a different tree so
>> it can be pulled into both Heiko's clock topic branch and dts64 topic
>> branch.
> correct.
 will fix next version, thanks.
>
> 

[PATCH 2/2] dt-bindings: Add jdi lt070me05000 panel bindings

2016-06-02 Thread Vinay Simha BN
Add documentation for lt070me05000 panel

Cc: Archit Taneja 
Cc: John Stultz 
Cc: Thierry Reding 
Cc: Sumit Semwal 
Signed-off-by: Vinay Simha BN 

--
v2:
 * incorporated rob herring and thierry reviews
   gpio to gpios, gpio to regulator using fixed regulators
   and pwm backlight is removed, since it is controlled by
   dcs commands
---
 .../bindings/display/panel/jdi,lt070me05000.txt| 58 ++
 1 file changed, 58 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/display/panel/jdi,lt070me05000.txt

diff --git 
a/Documentation/devicetree/bindings/display/panel/jdi,lt070me05000.txt 
b/Documentation/devicetree/bindings/display/panel/jdi,lt070me05000.txt
new file mode 100644
index 000..51068ae
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/panel/jdi,lt070me05000.txt
@@ -0,0 +1,58 @@
+JDI model LT070ME05000 1200x1920 7" DSI Panel
+
+Required properties:
+- compatible: should be "jdi,lt070me05000"
+- vddp-supply: phandle of the regulator that provides the supply voltage
+  Power IC supply (3-5V)
+- dcdc_en-supply: phandle of the regulator that provides the supply voltage
+  Power IC supply enable, High active
+- vcc-supply: phandle of the regulator that provides the supply voltage
+  IOVCC , power supply for LCM (1.8V)
+- reset-gpios: phandle of gpio for reset line
+  This should be 8mA, gpio can be configured using mux, pinctrl, pinctrl-names
+  XRES, Reset, Low active
+- enable-gpios: phandle of gpio for enable line
+  LED_EN, LED backlight enable, High active
+
+Example:
+
+   vcc_1p8v: regulator-fixed at 2 {
+   compatible = "regulator-fixed";
+   regulator-min-microvolt = <180>;
+   regulator-max-microvolt = <180>;
+   regulator-name = "vcc_1p8v";
+   regulator-type = "voltage";
+   startup-delay-us = <0>;
+   gpio = <&pm8921_gpio 23 GPIO_ACTIVE_HIGH>;
+   enable-active-high;
+   regulator-boot-on;
+   };
+
+   tlmm_pinmux: pinctrl at 80 {
+
+   dsi_panel_pinctrl: dsi-panel-pinctrl {
+   mux {
+   pins = "gpio54";
+   function = "gpio";
+   bias-pull-up;
+   drive-strength = <8>;
+   };
+   };
+   };
+
+   dsi0: qcom,mdss_dsi at 470 {
+   panel at 0 {
+   compatible = "jdi,lt070me05000";
+   reg = <0>;
+   pinctrl-names = "default";
+   pinctrl-0 = <&dsi_panel_pinctrl>;
+
+   vddp-supply = <&pm8921_l17>;
+   dcdc_en-supply = <&pm8921_lvs7>;
+   vcc-supply = <&vcc_1p8v>;
+
+   reset-gpios = <&tlmm_pinmux 54 0>;
+   enable-gpios = <&pm8921_gpio 36 GPIO_ACTIVE_HIGH>;
+   };
+   };
+
-- 
1.9.1



[PATCH v3] drm/panel: Add JDI LT070ME05000 WUXGA DSI Panel

2016-06-02 Thread Vinay Simha BN
Add support for the JDI lt070me05000 WUXGA DSI panel used in
Nexus 7 2013 devices.

Programming sequence for the panel is was originally found in the
android-msm-flo-3.4-lollipop-release branch from:
https://android.googlesource.com/kernel/msm.git

And video mode setting is from dsi-panel-jdi-dualmipi1-video.dtsi
file in:
git://codeaurora.org/kernel/msm-3.10.git  LNX.LA.3.6_rb1.27

Other fixes folded in were provided
by Archit Taneja 

Cc: Archit Taneja 
[sumit.semwal: Ported to the drm/panel framework]
Signed-off-by: Sumit Semwal 
[jstultz: Cherry-picked to mainline, folded down other fixes
 from Vinay and Archit]
Signed-off-by: John Stultz 
[vinay simha bn: removed interface setting cmd mode, video
mode panel setting selection]
Cc: Rob Clark 
Signed-off-by: Vinay Simha BN 
--
v2:
 * incorporated code reviews from theiry, archit
   code style, alphabetical soring in Makefile, Kconfig, regulator_bulk,
   arrays of u8, generic helper function, documentation bindings,

v3:
 * dcs backlight support added
 * tested this panel driver in nexus7 2013 device
---
 drivers/gpu/drm/panel/Kconfig  |  11 +
 drivers/gpu/drm/panel/Makefile |   1 +
 drivers/gpu/drm/panel/panel-jdi-lt070me05000.c | 479 +
 3 files changed, 491 insertions(+)
 create mode 100644 drivers/gpu/drm/panel/panel-jdi-lt070me05000.c

diff --git a/drivers/gpu/drm/panel/Kconfig b/drivers/gpu/drm/panel/Kconfig
index 1500ab9..83e89e7 100644
--- a/drivers/gpu/drm/panel/Kconfig
+++ b/drivers/gpu/drm/panel/Kconfig
@@ -7,6 +7,17 @@ config DRM_PANEL
 menu "Display Panels"
depends on DRM && DRM_PANEL

+config DRM_PANEL_JDI_LT070ME05000
+tristate "JDI LT070ME05000 WUXGA DSI panel"
+depends on OF
+depends on DRM_MIPI_DSI
+depends on BACKLIGHT_CLASS_DEVICE
+help
+  Say Y here if you want to enable support for JDI WUXGA DSI video
+  mode panel as found in Google Nexus 7 (2013) devices.
+  The panel has a 1200(RGB)×1920 (WUXGA) resolution and uses
+  24 bit RGB per pixel.
+
 config DRM_PANEL_SIMPLE
tristate "support for simple panels"
depends on OF
diff --git a/drivers/gpu/drm/panel/Makefile b/drivers/gpu/drm/panel/Makefile
index f277eed..5d74ac2 100644
--- a/drivers/gpu/drm/panel/Makefile
+++ b/drivers/gpu/drm/panel/Makefile
@@ -1,3 +1,4 @@
+obj-$(CONFIG_DRM_PANEL_JDI_LT070ME05000) += panel-jdi-lt070me05000.o
 obj-$(CONFIG_DRM_PANEL_SIMPLE) += panel-simple.o
 obj-$(CONFIG_DRM_PANEL_LG_LG4573) += panel-lg-lg4573.o
 obj-$(CONFIG_DRM_PANEL_PANASONIC_VVX10F034N00) += 
panel-panasonic-vvx10f034n00.o
diff --git a/drivers/gpu/drm/panel/panel-jdi-lt070me05000.c 
b/drivers/gpu/drm/panel/panel-jdi-lt070me05000.c
new file mode 100644
index 000..44a1aff2f
--- /dev/null
+++ b/drivers/gpu/drm/panel/panel-jdi-lt070me05000.c
@@ -0,0 +1,479 @@
+/*
+ * Copyright (C) 2016 InforceComputing
+ * Author: Vinay Simha BN 
+ *
+ * Copyright (C) 2016 Linaro Ltd
+ * Author: Sumit Semwal 
+ *
+ * From internet archives, the panel for Nexus 7 2nd Gen, 2013 model is a
+ * JDI model LT070ME05000, and its data sheet is at:
+ * http://panelone.net/en/7-0-inch/JDI_LT070ME05000_7.0_inch-datasheet
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License 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.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program.  If not, see .
+ */
+
+#include 
+#include 
+#include 
+#include 
+
+#include 
+#include 
+#include 
+#include 
+
+#include 
+
+#define PANEL_DEV_REGULATOR_MAX   3
+#define PANEL_MAX_BRIGHTNESS   0xFF
+
+const char *regs[] = {
+   "vddp",
+   "dcdc_en",
+   "vcc"
+};
+
+struct jdi_panel {
+   struct drm_panel base;
+   struct mipi_dsi_device *dsi;
+
+   struct regulator_bulk_data supplies[PANEL_DEV_REGULATOR_MAX];
+
+   struct gpio_desc *reset_gpio;
+   struct gpio_desc *enable_gpio;
+   struct backlight_device *backlight;
+
+   bool prepared;
+   bool enabled;
+
+   const struct drm_display_mode *mode;
+};
+
+static inline struct jdi_panel *to_jdi_panel(struct drm_panel *panel)
+{
+   return container_of(panel, struct jdi_panel, base);
+}
+
+static int jdi_panel_init(struct jdi_panel *jdi)
+{
+   struct mipi_dsi_device *dsi = jdi->dsi;
+   int ret;
+
+   dsi->mode_flags |= MIPI_DSI_MODE_LPM;
+
+   ret = mipi_dsi_dcs_soft_reset(dsi);
+   if (ret < 0)
+   return ret;
+
+   usleep_range(1, 2);
+
+   ret = mipi_dsi_dcs_set_pixel_format(dsi, 0x70);
+   if (ret < 0)
+   

[RFC PATCH 3/4] PM / devfreq: rockchip: add devfreq driver for rk3399 dmc

2016-06-02 Thread hl
Hi Chanwoo Choi,

 I just check the devfreq-event framework code, it is good,
i will do more dig to see whether it can fit for rk3399 dmc, thank you.

On 2016年06月01日 19:47, Chanwoo Choi wrote:
> Hi Lin,
>
> This patch include the two features as following:
> - Monitor the ddr load
> - Control the ddr's clock with ondemand governor based on load
>
> The "Monitor the ddr load" has the specific the address in SoC.
> Namely, it is separate the module.
> So, I implemented the devfreq-event framework[1] which was merged.
>
> It is right method to separate two feature from your device driver.
> You can refer to patch[2][3]. The patch[2] show how to implement the
> "monitor the ddr load"
> by using Devfreq-Event framework and the patch[3] include the method
> how to implement the rk3399 dmc driver.
>
> [1] Devfreq-Event framework
> - 
> https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=f262f28c147051e7aa6daaf4fb5996833ffadff4
>
> [2] Exynos Noc probe driver by using Devfreq-Event framework
> - 
> https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=0179a913875a8b39eaf5b848c876439a3a4650af
>
> [3] Exynos Busfreq driver using the devfreq-evnet framework to get the
> monitored data
> - 
> https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=0722249ac1f3dcc3af9e9d7ed89792a68f00
>
> If you have more information and help, please let me know. I'll help you.
>
> Thanks,
> Chanwoo Choi
>
> On Wed, Jun 1, 2016 at 6:35 PM, Lin Huang  wrote:
>> there is dfi controller on rk3399 platform, it can monitor
>> ddr load, register this controller to devfreq framework, and
>> default to use simple_ondeamnd policy, and do ddr frequency
>> scaling base on this result.
>>
>> Signed-off-by: Lin Huang 
>> ---
>>   drivers/devfreq/Kconfig |   2 +-
>>   drivers/devfreq/Makefile|   1 +
>>   drivers/devfreq/rockchip/Kconfig|  14 +
>>   drivers/devfreq/rockchip/Makefile   |   2 +
>>   drivers/devfreq/rockchip/rk3399_dmc.c   | 438 
>> 
>>   drivers/devfreq/rockchip/rockchip_dmc.c | 132 ++
>>   include/soc/rockchip/rockchip_dmc.h |  44 
>>   7 files changed, 632 insertions(+), 1 deletion(-)
>>   create mode 100644 drivers/devfreq/rockchip/Kconfig
>>   create mode 100644 drivers/devfreq/rockchip/Makefile
>>   create mode 100644 drivers/devfreq/rockchip/rk3399_dmc.c
>>   create mode 100644 drivers/devfreq/rockchip/rockchip_dmc.c
>>   create mode 100644 include/soc/rockchip/rockchip_dmc.h
>>
>> diff --git a/drivers/devfreq/Kconfig b/drivers/devfreq/Kconfig
>> index 78dac0e..a883744 100644
>> --- a/drivers/devfreq/Kconfig
>> +++ b/drivers/devfreq/Kconfig
>> @@ -101,5 +101,5 @@ config ARM_TEGRA_DEVFREQ
>>operating frequencies and voltages with OPP support.
>>
>>   source "drivers/devfreq/event/Kconfig"
>> -
>> +source "drivers/devfreq/rockchip/Kconfig"
>>   endif # PM_DEVFREQ
>> diff --git a/drivers/devfreq/Makefile b/drivers/devfreq/Makefile
>> index 09f11d9..48e2ae6 100644
>> --- a/drivers/devfreq/Makefile
>> +++ b/drivers/devfreq/Makefile
>> @@ -9,6 +9,7 @@ obj-$(CONFIG_DEVFREQ_GOV_PASSIVE)   += governor_passive.o
>>   # DEVFREQ Drivers
>>   obj-$(CONFIG_ARM_EXYNOS_BUS_DEVFREQ)   += exynos-bus.o
>>   obj-$(CONFIG_ARM_TEGRA_DEVFREQ)+= tegra-devfreq.o
>> +obj-$(CONFIG_ARCH_ROCKCHIP)+= rockchip/
>>
>>   # DEVFREQ Event Drivers
>>   obj-$(CONFIG_PM_DEVFREQ_EVENT) += event/
>> diff --git a/drivers/devfreq/rockchip/Kconfig 
>> b/drivers/devfreq/rockchip/Kconfig
>> new file mode 100644
>> index 000..617b5fe
>> --- /dev/null
>> +++ b/drivers/devfreq/rockchip/Kconfig
>> @@ -0,0 +1,14 @@
>> +config ARM_ROCKCHIP_DMC_DEVFREQ
>> +   tristate "ARM ROCKCHIP DMC DEVFREQ Driver"
>> +   depends on ARCH_ROCKCHIP
>> +   help
>> + This adds the DEVFREQ driver framework for the rockchip dmc.
>> +
>> +config ARM_RK3399_DMC_DEVFREQ
>> +   tristate "ARM RK3399 DMC DEVFREQ Driver"
>> +   depends on ARM_ROCKCHIP_DMC_DEVFREQ
>> +   select PM_OPP
>> +   select DEVFREQ_GOV_SIMPLE_ONDEMAND
>> +   help
>> + This adds the DEVFREQ driver for the RK3399 dmc. It sets the 
>> frequency
>> + for the memory controller and reads the usage counts from hardware.
>> diff --git a/drivers/devfreq/rockchip/Makefile 
>> b/drivers/devfreq/rockchip/Makefile
>> new file mode 100644
>> index 000..caca525
>> --- /dev/null
>> +++ b/drivers/devfreq/rockchip/Makefile
>> @@ -0,0 +1,2 @@
>> +obj-$(CONFIG_ARM_ROCKCHIP_DMC_DEVFREQ) += rockchip_dmc.o
>> +obj-$(CONFIG_ARM_RK3399_DMC_DEVFREQ)   += rk3399_dmc.o
>> diff --git a/drivers/devfreq/rockchip/rk3399_dmc.c 
>> b/drivers/devfreq/rockchip/rk3399_dmc.c
>> new file mode 100644
>> index 000..4907d38
>> --- /dev/null
>> +++ b/drivers/devfreq/rockchip/rk3399_dmc.c
>> @@ -0,0 +1,438 @@
>> +/*
>> + * Copyright (c) 2016, Fuzhou Rockchip Electronics Co., Ltd
>> + * Author:

[PATCH] drm/vc4: clean up error exit path on failed dpi_connector allocation

2016-06-02 Thread Colin King
From: Colin Ian King 

There is redundant code in the clean up exit path when dpi_connector
fails to be allocated.  The current code checks if connector is NULL
before destroying it, in fact, connector is NULL at this point so
the check is redundant and can be removed. The final clean up is
that we can remove the goto fail with a simple return and the unused
variable ret.

Signed-off-by: Colin Ian King 
---
 drivers/gpu/drm/vc4/vc4_dpi.c | 14 +++---
 1 file changed, 3 insertions(+), 11 deletions(-)

diff --git a/drivers/gpu/drm/vc4/vc4_dpi.c b/drivers/gpu/drm/vc4/vc4_dpi.c
index 9817dbf..9cb2d3e 100644
--- a/drivers/gpu/drm/vc4/vc4_dpi.c
+++ b/drivers/gpu/drm/vc4/vc4_dpi.c
@@ -236,14 +236,12 @@ static struct drm_connector 
*vc4_dpi_connector_init(struct drm_device *dev,
 {
struct drm_connector *connector = NULL;
struct vc4_dpi_connector *dpi_connector;
-   int ret = 0;

dpi_connector = devm_kzalloc(dev->dev, sizeof(*dpi_connector),
 GFP_KERNEL);
-   if (!dpi_connector) {
-   ret = -ENOMEM;
-   goto fail;
-   }
+   if (!dpi_connector)
+   return ERR_PTR(-ENOMEM);
+
connector = &dpi_connector->base;

dpi_connector->encoder = dpi->encoder;
@@ -260,12 +258,6 @@ static struct drm_connector *vc4_dpi_connector_init(struct 
drm_device *dev,
drm_mode_connector_attach_encoder(connector, dpi->encoder);

return connector;
-
- fail:
-   if (connector)
-   vc4_dpi_connector_destroy(connector);
-
-   return ERR_PTR(ret);
 }

 static const struct drm_encoder_funcs vc4_dpi_encoder_funcs = {
-- 
2.8.1



[PATCH] drm: atmel-hlcdc: actually disable scaling when no scaling is required

2016-06-02 Thread Nicolas Ferre
Le 01/06/2016 13:42, Boris Brezillon a écrit :
> The driver is only enabling scaling, but never disabling it, thus, if you
> enable the scaling feature once it stays enabled forever.
> 
> Signed-off-by: Boris Brezillon 
> Reported-by: Alex Vazquez 
> Fixes: 1a396789f65a ("drm: add Atmel HLCDC Display Controller support")
> Cc: 

Reviewed-by: Nicolas Ferre 

Thanks!

> ---
>  drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c | 2 ++
>  1 file changed, 2 insertions(+)
> 
> diff --git a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c 
> b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c
> index aef3ca8..016c191 100644
> --- a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c
> +++ b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c
> @@ -339,6 +339,8 @@ atmel_hlcdc_plane_update_pos_and_size(struct 
> atmel_hlcdc_plane *plane,
>  
>   atmel_hlcdc_layer_update_cfg(&plane->layer, 13, 0x,
>factor_reg);
> + } else {
> + atmel_hlcdc_layer_update_cfg(&plane->layer, 13, 0x, 0);
>   }
>  }
>  
> 


-- 
Nicolas Ferre


[PATCH 1/2] drm/atomic: Add struct drm_crtc_commit to track async updates

2016-06-02 Thread Daniel Vetter
Split out from my big nonblocking atomic commit helper code as prep
work. While add it, also add some neat asciiart to document how it's
supposed to be used.

Tested-by: Tomeu Vizoso 
Cc: Maarten Lankhorst 
Cc: Tomeu Vizoso 
Cc: Daniel Stone 
Tested-by: Liviu Dudau 
Signed-off-by: Daniel Vetter 
---
 drivers/gpu/drm/drm_atomic.c |  22 +++
 drivers/gpu/drm/drm_crtc.c   |   3 +
 drivers/gpu/drm/drm_fops.c   |   6 ++
 include/drm/drmP.h   |   1 +
 include/drm/drm_atomic.h |   6 ++
 include/drm/drm_crtc.h   | 146 +--
 6 files changed, 178 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c
index 5e4b820a977c..d99ab2f6663f 100644
--- a/drivers/gpu/drm/drm_atomic.c
+++ b/drivers/gpu/drm/drm_atomic.c
@@ -33,6 +33,20 @@

 #include "drm_crtc_internal.h"

+static void crtc_commit_free(struct kref *kref)
+{
+   struct drm_crtc_commit *commit =
+   container_of(kref, struct drm_crtc_commit, ref);
+
+   kfree(commit);
+}
+
+void drm_crtc_commit_put(struct drm_crtc_commit *commit)
+{
+   kref_put(&commit->ref, crtc_commit_free);
+}
+EXPORT_SYMBOL(drm_crtc_commit_put);
+
 /**
  * drm_atomic_state_default_release -
  * release memory initialized by drm_atomic_state_init
@@ -148,6 +162,14 @@ void drm_atomic_state_default_clear(struct 
drm_atomic_state *state)

crtc->funcs->atomic_destroy_state(crtc,
  state->crtcs[i].state);
+
+   if (state->crtcs[i].commit) {
+   kfree(state->crtcs[i].commit->event);
+   state->crtcs[i].commit->event = NULL;
+   drm_crtc_commit_put(state->crtcs[i].commit);
+   }
+
+   state->crtcs[i].commit = NULL;
state->crtcs[i].ptr = NULL;
state->crtcs[i].state = NULL;
}
diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
index 1cb3b471aadc..1f14c6565210 100644
--- a/drivers/gpu/drm/drm_crtc.c
+++ b/drivers/gpu/drm/drm_crtc.c
@@ -669,6 +669,9 @@ int drm_crtc_init_with_planes(struct drm_device *dev, 
struct drm_crtc *crtc,
crtc->dev = dev;
crtc->funcs = funcs;

+   INIT_LIST_HEAD(&crtc->commit_list);
+   spin_lock_init(&crtc->commit_lock);
+
drm_modeset_lock_init(&crtc->mutex);
ret = drm_mode_object_get(dev, &crtc->base, DRM_MODE_OBJECT_CRTC);
if (ret)
diff --git a/drivers/gpu/drm/drm_fops.c b/drivers/gpu/drm/drm_fops.c
index 4c4b30f7a9f2..5921b203503a 100644
--- a/drivers/gpu/drm/drm_fops.c
+++ b/drivers/gpu/drm/drm_fops.c
@@ -686,6 +686,12 @@ void drm_send_event_locked(struct drm_device *dev, struct 
drm_pending_event *e)
 {
assert_spin_locked(&dev->event_lock);

+   if (e->completion) {
+   /* ->completion might disappear as soon as it signalled. */
+   complete_all(e->completion);
+   e->completion = NULL;
+   }
+
if (e->fence) {
fence_signal(e->fence);
fence_put(e->fence);
diff --git a/include/drm/drmP.h b/include/drm/drmP.h
index 51f751d1c8a4..781db4f562d4 100644
--- a/include/drm/drmP.h
+++ b/include/drm/drmP.h
@@ -283,6 +283,7 @@ struct drm_ioctl_desc {

 /* Event queued up for userspace to read */
 struct drm_pending_event {
+   struct completion *completion;
struct drm_event *event;
struct fence *fence;
struct list_head link;
diff --git a/include/drm/drm_atomic.h b/include/drm/drm_atomic.h
index 465a1212f4f0..abec2a3f0225 100644
--- a/include/drm/drm_atomic.h
+++ b/include/drm/drm_atomic.h
@@ -30,6 +30,12 @@

 #include 

+void drm_crtc_commit_put(struct drm_crtc_commit *commit);
+static inline void drm_crtc_commit_get(struct drm_crtc_commit *commit)
+{
+   kref_get(&commit->ref);
+}
+
 struct drm_atomic_state * __must_check
 drm_atomic_state_alloc(struct drm_device *dev);
 void drm_atomic_state_clear(struct drm_atomic_state *state);
diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h
index d5d5e343531e..cf4aad0929d9 100644
--- a/include/drm/drm_crtc.h
+++ b/include/drm/drm_crtc.h
@@ -725,9 +725,6 @@ struct drm_crtc_funcs {
  * @gamma_store: gamma ramp values
  * @helper_private: mid-layer private data
  * @properties: property tracking for this CRTC
- * @state: current atomic state for this CRTC
- * @acquire_ctx: per-CRTC implicit acquire context used by atomic drivers for
- * legacy IOCTLs
  *
  * Each CRTC may have one or more connectors associated with it.  This 
structure
  * allows the CRTC to be controlled.
@@ -780,11 +777,37 @@ struct drm_crtc {

struct drm_object_properties properties;

+   /**
+* @state:
+*
+* Current atomic state for this CRTC.
+*/
struct drm_crtc_state *state;

-   /*
-* For legacy crtc IOCTLs so that atomic drivers can get at the locking
-* acquire context.
+   /

[PATCH 2/2] drm/atomic-helper: nonblocking commit support

2016-06-02 Thread Daniel Vetter
Design ideas:

- split up the actual commit into different phases, and have
  completions for each of them. This will be useful for the future
  when we want to interleave phases much more aggressively, for e.g.
  queue depth > 1. For not it's just a minimal optimization compared
  to current common nonblocking implementation patterns from drivers,
  which all stall for the entire commit to complete, including vblank
  waits and cleanups.

- Extract a separate atomic_commit_hw hook since that's the part most
  drivers will need to overwrite, hopefully allowing even more shared
  code.

- Enforce EBUSY seamntics by attaching one of the completions to the
  flip_done vblank event. Side benefit of forcing atomic drivers using
  these helpers to implement event handlign at least semi-correct. I'm
  evil that way ;-)

- Ridiculously modular, as usual.

- The main tracking unit for a commit stays struct drm_atomic_state,
  and the ownership rules for that are unchanged. Ownership still
  gets transferred to the driver (and subsequently to the worker) on
  successful commits. What is added is a small, per-crtc, refcounted
  structure to track pending commits called struct drm_crtc_commit.
  No actual state is attached to that though, it's purely for ordering
  and waiting.

- Dependencies are implicitly handled by assuming that any CRTC part
  of &drm_atomic_state is a dependency, and that the current commit
  must wait for any commits to complete on those CRTC. This way
  drivers can easily add more depencies using
  drm_atomic_get_crtc_state(), which is very natural since in most
  case a dependency exists iff there's some bit of state that needs to
  be cross checked.

  Removing depencies is not possible, drivers simply need to be
  careful to not include every CRTC in a commit if that's not
  necessary. Which is a good idea anyway, since that also avoids
  ww_mutex lock contention.

- Queue depth > 1 sees some prep work in this patch by adding a stall
  paramater to drm_atomic_helper_swap_states(). To be able to push
  commits entirely free-standing and in a deeper queue through the
  back-end the driver must not access any obj->state pointers. This
  means we need to track the old state in drm_atomic_state (much
  easier with the consolidated arrays), and pass them all explicitly
  to driver backends (this will be serious amounts of churn).

  Once that's done stall can be set to false in swap_states.

Features: Contains bugs because totally untested.

v2: Dont ask for flip_done signalling when the CRTC is off and stays
off: Drivers don't handle events in that case. Instead complete right
away. This way future commits don't need to have special-case logic,
but can keep blocking for the flip_done completion.

v3: Tons of fixes:
- Stall for preceeding commit for real, not the current one by
  accident.
- Add WARN_ON in case drivers don't fire the drm event.
- Don't double-free drm events.

v4: Make legacy cursor not stall.

v5: Extend the helper hook to cover the entire commit tail. Some
drivers need special code for cleanup and vblank waiting, this makes
it a bit more useful. Inspired by the rockchip driver.

v6: Add WARN_ON to catch drivers who forget to send out the
drm event.

v7: Fixup the stalls in swap_state for real!!

v8:
- Fixup trailing whitespace, spotted by Maarten.
- Actually wait for flip_done in cleanup_done, like the comment says
  we should do. Thanks a lot for Tomeu for helping with debugging this
  on.

v9: Now with awesome kerneldoc!

v10: Split out drm_crtc_commit tracking infrastructure.

Tested-by: Tomeu Vizoso 
Cc: Maarten Lankhorst 
Cc: Tomeu Vizoso 
Cc: Daniel Stone 
Tested-by: Liviu Dudau 
Signed-off-by: Daniel Vetter 
---
 drivers/gpu/drm/drm_atomic_helper.c  | 475 ---
 include/drm/drm_atomic_helper.h  |   8 +
 include/drm/drm_crtc.h   |   6 +
 include/drm/drm_modeset_helper_vtables.h |  39 +++
 4 files changed, 489 insertions(+), 39 deletions(-)

diff --git a/drivers/gpu/drm/drm_atomic_helper.c 
b/drivers/gpu/drm/drm_atomic_helper.c
index 65128f258f84..290318d6f5b5 100644
--- a/drivers/gpu/drm/drm_atomic_helper.c
+++ b/drivers/gpu/drm/drm_atomic_helper.c
@@ -1116,22 +1116,17 @@ drm_atomic_helper_wait_for_vblanks(struct drm_device 
*dev,
 EXPORT_SYMBOL(drm_atomic_helper_wait_for_vblanks);

 /**
- * drm_atomic_helper_commit - commit validated state object
- * @dev: DRM device
- * @state: the driver state object
- * @nonblocking: whether nonblocking behavior is requested.
+ * drm_atomic_helper_commit_tail - commit atomic update to hardware
+ * @state: new modeset state to be committed
  *
- * This function commits a with drm_atomic_helper_check() pre-validated state
- * object. This can still fail when e.g. the framebuffer reservation fails. For
- * now this doesn't implement nonblocking commits.
+ * This is the default implemenation for the ->atomic_commit_tail() hook of the
+ * &drm_mode_config_helper_funcs vtable.
  *
- * No

[Bug 114711] ubsan: "shift exponent 32 is too large" in drivers/gpu/drm/nouveau/nvkm/subdev/gpio/base.c:167:16

2016-06-02 Thread bugzilla-dae...@bugzilla.kernel.org
https://bugzilla.kernel.org/show_bug.cgi?id=114711

Navin  changed:

   What|Removed |Added

 CC||navinp1912 at gmail.com

--- Comment #1 from Navin  ---
Does this fix work for you ?

diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gpio/base.c
b/drivers/gpu/drm/nouveau/nvkm/subdev/gpio/base.c
index 77c64972..0e40584 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/gpio/base.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gpio/base.c
@@ -164,7 +164,7 @@ static int
 nvkm_gpio_fini(struct nvkm_subdev *subdev, bool suspend)
 {
struct nvkm_gpio *gpio = nvkm_gpio(subdev);
-   u32 mask = (1 << gpio->func->lines) - 1;
+   u32 mask = (1LL << min(gpio->func->lines, 32)) - 1;

gpio->func->intr_mask(gpio, NVKM_GPIO_TOGGLED, mask, 0);
gpio->func->intr_stat(gpio, &mask, &mask);

-- 
You are receiving this mail because:
You are watching the assignee of the bug.


[PATCH] drm/nouveau/iccsense: fix memory leak on default sensor->type case

2016-06-02 Thread Colin King
From: Colin Ian King 

The default sensor->type case leaks memory allocated to rail. Fix
this by free'ing rail before we continue with the next loop iteration.

Signed-off-by: Colin Ian King 
---
 drivers/gpu/drm/nouveau/nvkm/subdev/iccsense/base.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/iccsense/base.c 
b/drivers/gpu/drm/nouveau/nvkm/subdev/iccsense/base.c
index 323c79a..79b0eb5 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/iccsense/base.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/iccsense/base.c
@@ -305,6 +305,7 @@ nvkm_iccsense_oneinit(struct nvkm_subdev *subdev)
rail->read = nvkm_iccsense_ina3221_read;
break;
default:
+   kfree(rail);
continue;
}

-- 
2.8.1



[PATCH v4] drm: Only create a cmdline mode if no probed modes match

2016-06-02 Thread Chris Wilson
On Thu, Jun 02, 2016 at 11:38:26AM +0200, Radek Dostál wrote:
> On 06/01/2016 11:50 AM, Chris Wilson wrote:
> >Fixes regression from
> >
> >commit eaf99c749d43ae74ac7ffece5512f3c73f01dfd2
> >Author: Chris Wilson
> >Date:   Wed Aug 6 10:08:32 2014 +0200
> >
> > drm: Perform cmdline mode parsing during connector initialisation
> >
> >that breaks HDMI output on BeagleBone Black with LG TV (model 19LS4R-ZA).
> 
> please remove this from the commit message. The original bug is no
> longer reproducible with 4.7-rc1

If there's no motivation for the patch anymore, it can just wither away
in one of my old trees.

Does anyone care about pruning the autogenerated video= mode if a probed
one matches? Presumably, it is still visible to userspace and switching
to it will cause the same issue as before? Or was it always a driver
bug (failing to set the mode)?
-Chris

-- 
Chris Wilson, Intel Open Source Technology Centre


[PATCH 02/38] drm/i915: Use drm_atomic_get_existing_plane_state

2016-06-02 Thread Maarten Lankhorst
Op 02-06-16 om 00:06 schreef Daniel Vetter:
> We want to encapsulate the drm_atomic_state internals.
>
> Signed-off-by: Daniel Vetter 
> ---
>  drivers/gpu/drm/i915/intel_atomic.c | 4 +++-
>  1 file changed, 3 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/gpu/drm/i915/intel_atomic.c 
> b/drivers/gpu/drm/i915/intel_atomic.c
> index 50ff90aea721..3e6d9ff8840a 100644
> --- a/drivers/gpu/drm/i915/intel_atomic.c
> +++ b/drivers/gpu/drm/i915/intel_atomic.c
> @@ -223,7 +223,9 @@ int intel_atomic_setup_scalers(struct drm_device *dev,
>   continue;
>   }
>  
> - plane_state = 
> to_intel_plane_state(drm_state->plane_states[i]);
> + plane_state = to_intel_plane_state(
> + drm_atomic_get_existing_plane_state(drm_state,
> + plane));
>   scaler_id = &plane_state->scaler_id;
>   }
>  
intel_plane_get_atomic_state(drm_state, intel_plane); ?

If fixed,

Reviewed-by: Maarten Lankhorst 



[PATCH 01/38] drm/atomic-helper: use for_each_*_in_state more

2016-06-02 Thread Maarten Lankhorst
Op 02-06-16 om 00:06 schreef Daniel Vetter:
> This avois leaking drm_atomic_state internals into the helpers. The
> only place where this still happens after this patch is 
> drm_atomic_helper_swap_state().
> It's unavoidable there, and maybe a good indicator we should actually
> move that function into drm_atomic.c.
>
> Signed-off-by: Daniel Vetter 
Reviewed-by: Maarten Lankhorst 


[PATCH v4] drm: Only create a cmdline mode if no probed modes match

2016-06-02 Thread Ville Syrjälä
On Thu, Jun 02, 2016 at 11:52:17AM +0100, Chris Wilson wrote:
> On Thu, Jun 02, 2016 at 11:38:26AM +0200, Radek Dostál wrote:
> > On 06/01/2016 11:50 AM, Chris Wilson wrote:
> > >Fixes regression from
> > >
> > >commit eaf99c749d43ae74ac7ffece5512f3c73f01dfd2
> > >Author: Chris Wilson
> > >Date:   Wed Aug 6 10:08:32 2014 +0200
> > >
> > > drm: Perform cmdline mode parsing during connector initialisation
> > >
> > >that breaks HDMI output on BeagleBone Black with LG TV (model 19LS4R-ZA).
> > 
> > please remove this from the commit message. The original bug is no
> > longer reproducible with 4.7-rc1
> 
> If there's no motivation for the patch anymore, it can just wither away
> in one of my old trees.
> 
> Does anyone care about pruning the autogenerated video= mode if a probed
> one matches? Presumably, it is still visible to userspace and switching
> to it will cause the same issue as before? Or was it always a driver
> bug (failing to set the mode)?

IMO the patch makes total sense even if it's not needed for this
particular bug. Feel free to add

Reviewed-by: Ville Syrjälä 

-- 
Ville Syrjälä
Intel OTC


[GIT PULL] drm/hdlcd: fixes for v4.7

2016-06-02 Thread Liviu Dudau
Hi Dave,

I have accumulated some cleanup patches for HDLCD, partly triggered by
Daniel Vetter's work on non-blocking atomic operations, that I would like
to integrate into v4.7. My first patch is important for the newly enabled
hibernate option for AArch64 on Juno, the others are fixing behaviour in
HDLCD and adding a debugfs entry to help track the underlying framebuffer
usage. I'm also taking one of Daniel's patches from his non-blocking series
to help with the integration of his patches later.

The following changes since commit 1a695a905c18548062509178b98bc91e67510864:

  Linux 4.7-rc1 (2016-05-29 09:29:24 -0700)

are available in the git repository at:

  git://linux-arm.org/linux-ld.git for-upstream/hdlcd

for you to fetch changes up to c41ef79e281e08c3a4f8242615d55d1226cd9c69:

  drm: hdlcd: Add information about the underlying framebuffers in debugfs 
(2016-06-02 11:09:27 +0100)


Daniel Vetter (1):
  drm/hdlcd: Fix up crtc_state->event handling

Liviu Dudau (3):
  drm: hdlcd: Revamp runtime power management
  drm: hdlcd: Cleanup the atomic plane operations
  drm: hdlcd: Add information about the underlying framebuffers in debugfs

 drivers/gpu/drm/arm/hdlcd_crtc.c  | 86 ++-
 drivers/gpu/drm/arm/hdlcd_drv.c   | 68 +--
 drivers/gpu/drm/arm/hdlcd_drv.h   |  5 +--
 drivers/gpu/drm/i2c/tda998x_drv.c |  4 ++
 4 files changed, 82 insertions(+), 81 deletions(-)


Best regards,
Liviu


-- 

| I would like to |
| fix the world,  |
| but they're not |
| giving me the   |
 \ source code!  /
  ---
¯\_(ツ)_/¯


[PATCH] amdgpu: fix fence status query

2016-06-02 Thread Christian König
From: Christian König 

Not initializing the ip instance leads to sporadic fails in the tests.

Signed-off-by: Christian König 
---
 tests/amdgpu/basic_tests.c | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/tests/amdgpu/basic_tests.c b/tests/amdgpu/basic_tests.c
index d2086ce..f778a7e 100644
--- a/tests/amdgpu/basic_tests.c
+++ b/tests/amdgpu/basic_tests.c
@@ -346,6 +346,7 @@ static void amdgpu_command_submission_gfx_separate_ibs(void)

fence_status.context = context_handle;
fence_status.ip_type = AMDGPU_HW_IP_GFX;
+   fence_status.ip_instance = 0;
fence_status.fence = ibs_request.seq_no;

r = amdgpu_cs_query_fence_status(&fence_status,
@@ -427,6 +428,7 @@ static void amdgpu_command_submission_gfx_shared_ib(void)

fence_status.context = context_handle;
fence_status.ip_type = AMDGPU_HW_IP_GFX;
+   fence_status.ip_instance = 0;
fence_status.fence = ibs_request.seq_no;

r = amdgpu_cs_query_fence_status(&fence_status,
@@ -541,6 +543,7 @@ static void amdgpu_semaphore_test(void)

fence_status.context = context_handle[0];
fence_status.ip_type = AMDGPU_HW_IP_GFX;
+   fence_status.ip_instance = 0;
fence_status.fence = ibs_request[1].seq_no;
r = amdgpu_cs_query_fence_status(&fence_status,
 5, 0, &expired);
@@ -581,6 +584,7 @@ static void amdgpu_semaphore_test(void)

fence_status.context = context_handle[1];
fence_status.ip_type = AMDGPU_HW_IP_GFX;
+   fence_status.ip_instance = 0;
fence_status.fence = ibs_request[1].seq_no;
r = amdgpu_cs_query_fence_status(&fence_status,
 5, 0, &expired);
@@ -653,6 +657,7 @@ static void amdgpu_command_submission_compute(void)

fence_status.context = context_handle;
fence_status.ip_type = AMDGPU_HW_IP_COMPUTE;
+   fence_status.ip_instance = 0;
fence_status.ring = instance;
fence_status.fence = ibs_request.seq_no;

@@ -739,6 +744,7 @@ static void 
amdgpu_test_exec_cs_helper(amdgpu_context_handle context_handle,
CU_ASSERT_EQUAL(r, 0);

fence_status.ip_type = ip_type;
+   fence_status.ip_instance = 0;
fence_status.ring = ibs_request->ring;
fence_status.context = context_handle;
fence_status.fence = ibs_request->seq_no;
-- 
2.5.0



[PATCH] amdgpu: fix fence status query

2016-06-02 Thread Michel Dänzer
On 02.06.2016 20:40, Christian König wrote:
> From: Christian König 
> 
> Not initializing the ip instance leads to sporadic fails in the tests.
> 
> Signed-off-by: Christian König 

Reviewed-by: Michel Dänzer 


P.S. Please run

 git config format.subjectprefix "PATCH libdrm"

in your libdrm tree.

-- 
Earthling Michel Dänzer   |   http://www.amd.com
Libre software enthusiast | Mesa and X developer


[PATCH v2 00/27] fb/drm: omapdss: Clean up the headers and separate the two stack

2016-06-02 Thread Tomi Valkeinen
Hi Tony,

On 01/06/16 11:35, Peter Ujfalusi wrote:
> Hi,
> 
> Changes since v1:
> - patches (2) added to remove the inclusion of video/omap-panel-data.h when it
>   is not needed
> - Transitional patch to create the video/omapfb_dss.h has been changed to copy
>   the content of the omapdss.h in one step.
> 
> omapfb is deprecated. It will not receive new features, only bug fixes. On 
> the.
> other hand omapdrm is in active development and the fact that both
> implementation (omapfb and omapdrm) is using the same header file
> (video/omapdss.h) makes implementing new features or doing bigger clean ups in
> omapdrm harder and hared as the change should not break omapfb.
> 
> To overcome this issue we need to separate the two implementation. This is the
> aim of this series:
> Create platform_data header for omapdss,
> clean up the header usage and dependencies,
> new header file for omapfb stack (video/omapfb_dss.h)
> local omapdss.h header file for omapdrm.

Tony, can you have a look at the arch/arm parts here and give your ack
if they're fine? They should be quite small and display specific, so I
don't see much chance for conflict there.

 Tomi

-- next part --
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: OpenPGP digital signature
URL: 
<https://lists.freedesktop.org/archives/dri-devel/attachments/20160602/164897ac/attachment.sig>


[PATCH 00/12] Improve PX support in radeon and amdgpu

2016-06-02 Thread Alex Deucher
On Wed, Jun 1, 2016 at 8:02 PM, Mike Lothian  wrote:
> Are these in a branch somewhere? If not I'll try apply the mbox from
> patchwork.freedesktop.org
>

Just pushed to my drm-next-4.8-wip branch.

Alex

> On Wed, 1 Jun 2016 at 21:53 Alex Deucher  wrote:
>>
>> This patch set cleans up and attempts to make runtime pm more
>> reliable in radeon and amdgpu on PX systems.  If you have a PX
>> system that requires setting the runpm=0 module parameter for
>> stability, please try this patch set.
>>
>> The main fix is that a minimum of 200ms of delay is required between
>> a dGPU power down and a power up.
>>
>> This patch also properly handles the detection of the ATPX dGPU
>> power control method properly and handles dGPU power control for
>> platforms that do not support the ATPX dGPU power control method.
>>
>> Alex Deucher (12):
>>   drm/amdgpu: disable power control on hybrid laptops
>>   drm/amdgpu: clean up atpx power control handling
>>   drm/amdgpu: add a delay after ATPX dGPU power off
>>   drm/amdgpu/atpx: add a query for ATPX dGPU power control
>>   drm/amdgpu: use PCI_D3hot for PX systems without dGPU power control
>>   drm/amdgpu/atpx: drop forcing of dGPU power control
>>   drm/radeon: disable power control on hybrid laptops
>>   drm/radeon: clean up atpx power control handling
>>   drm/radeon: add a delay after ATPX dGPU power off
>>   drm/radeon/atpx: add a query for ATPX dGPU power control
>>   drm/radeon: use PCI_D3hot for PX systems without dGPU power control
>>   drm/radeon/atpx: drop forcing of dGPU power control
>>
>>  drivers/gpu/drm/amd/amdgpu/amdgpu.h  |  2 +
>>  drivers/gpu/drm/amd/amdgpu/amdgpu_atpx_handler.c | 50
>> 
>>  drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c  |  5 ++-
>>  drivers/gpu/drm/radeon/radeon_atpx_handler.c | 49
>> +++
>>  drivers/gpu/drm/radeon/radeon_drv.c  |  7 +++-
>>  5 files changed, 77 insertions(+), 36 deletions(-)
>>
>> --
>> 2.5.5
>>
>> ___
>> dri-devel mailing list
>> dri-devel at lists.freedesktop.org
>> https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH 3/5] Documentation/devicetree/bindings: Add b850v3_lvds_dp

2016-06-02 Thread Philipp Zabel
Hi Peter,

Am Montag, den 30.05.2016, 18:39 +0200 schrieb Peter Senna Tschudin:
> Devicetree bindings documentation for the GE B850v3 LVDS/DP++
> display bridge.
> 
> Signed-off-by: Peter Senna Tschudin 
> ---
>  .../devicetree/bindings/ge/b850v3_lvds_dp.txt  | 38 
> ++
>  1 file changed, 38 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/ge/b850v3_lvds_dp.txt
> 
> diff --git a/Documentation/devicetree/bindings/ge/b850v3_lvds_dp.txt 
> b/Documentation/devicetree/bindings/ge/b850v3_lvds_dp.txt
> new file mode 100644
> index 000..32e123a
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/ge/b850v3_lvds_dp.txt
> @@ -0,0 +1,38 @@
> +Driver for GE B850v3 LVDS/DP++ display bridge
> +
> +Required properties:
> +  - compatible : should be "ge,b850v3_lvds_dp".

In the cover mail you write that this is a combination of the STDP4028
DP transmitter and STDP2690 DP/DP++ converter. So shouldn't this binding
comprise two device tree nodes, one with compatible "st,stdp4028", one
with "st,stdp2690", then?
Is the stdp2690 connected to the stdp4028's i2c master?

regards
Philipp



[PATCH 2/5] arm/dts/imx6q-b850v3: Configure IPU assignment order

2016-06-02 Thread Philipp Zabel
Am Montag, den 30.05.2016, 18:39 +0200 schrieb Peter Senna Tschudin:
> Configure the IPU assignment order to assign one IPU per external
> display. A single IPU can drive multiple external displays but there are
> resolution restrictions. After this patch the GPU is capalbe of driving two
> Full-HD monitors.

It's also capable to do it before this patch, if you use the first and
third crtc. You are just reordering the crtcs.
Unfortunately the IPU has combined limitations across multiple crtcs in
one IPU, which currently can't be communicated to userspace.

regards
Philipp



[RFC PATCH v2 0/3]

2016-06-02 Thread Yakir Yang
The full name of PSR is Panel Self Refresh, panel device could refresh
itself with the hardware framebuffer in panel, this would make a lots
of sense to save the power consumption.

For example, when desktop haven't change the context for a long time,
then we could refresh the data to the hardware framebuffer of panel,
and then let panel enter into PSR mode. After that system could poweroff
the LCDC controller and eDP controller, just let panel refresh the screen
by itself.

It's hard to decide when panel should enter into PSR or exit from PSR, in
this time I chose to let the drm_vblank enable/disable event driver the PSR.

This thread is based on Mark's RK3399 VOP thread[0] and my RK3399 eDP
thread[1].

[0]: https://patchwork.kernel.org/patch/8886041/
[1]: https://patchwork.kernel.org/patch/9132713/

BR.
- Yakir


Changes in v2:
- Introduce in v2, splite the common Analogix DP changes out
- introduce in v2, split VOP line flag changes out
- Remove vblank notify out (Daniel)
- Create a psr_active() callback in vop data struct.

Yakir Yang (3):
  drm: bridge/analogix_dp: add the PSR function support
  drm/rockchip: vop: add line flag function support
  drm/rockchip: analogix_dp: add PSR support

 drivers/gpu/drm/bridge/analogix/analogix_dp_core.c |  69 ++
 drivers/gpu/drm/bridge/analogix/analogix_dp_core.h |   4 +
 drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c  |  54 +++
 drivers/gpu/drm/bridge/analogix/analogix_dp_reg.h  |  28 ++
 drivers/gpu/drm/rockchip/Makefile  |   2 +-
 drivers/gpu/drm/rockchip/analogix_dp-rockchip.c|  64 -
 drivers/gpu/drm/rockchip/rockchip_drm_drv.h|   7 ++
 drivers/gpu/drm/rockchip/rockchip_drm_notify.c |  54 +++
 drivers/gpu/drm/rockchip/rockchip_drm_notify.h |  23 +
 drivers/gpu/drm/rockchip/rockchip_drm_vop.c| 104 +
 drivers/gpu/drm/rockchip/rockchip_drm_vop.h|   3 +
 drivers/gpu/drm/rockchip/rockchip_vop_reg.c|   2 +
 include/drm/bridge/analogix_dp.h   |   3 +
 13 files changed, 415 insertions(+), 2 deletions(-)
 create mode 100644 drivers/gpu/drm/rockchip/rockchip_drm_notify.c
 create mode 100644 drivers/gpu/drm/rockchip/rockchip_drm_notify.h

-- 
1.9.1




[RFC PATCH v2 1/3] drm: bridge/analogix_dp: add the PSR function support

2016-06-02 Thread Yakir Yang
The full name of PSR is Panel Self Refresh, panel device could refresh
itself with the hardware framebuffer in panel, this would make lots of
sense to save the power consumption.

This patch have export two symbols for platform driver:
analogix_dp_active_psr()
analogix_dp_inactive_psr()

Signed-off-by: Yakir Yang 
---
Changes in v2:
- Introduce in v2, splite the common Analogix DP changes out

 drivers/gpu/drm/bridge/analogix/analogix_dp_core.c | 69 ++
 drivers/gpu/drm/bridge/analogix/analogix_dp_core.h |  4 ++
 drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c  | 54 +
 drivers/gpu/drm/bridge/analogix/analogix_dp_reg.h  | 28 +
 include/drm/bridge/analogix_dp.h   |  3 +
 5 files changed, 158 insertions(+)

diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c 
b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
index 5af9ce4..a66ccb6 100644
--- a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
+++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
@@ -39,6 +39,72 @@ struct bridge_init {
struct device_node *node;
 };

+int analogix_dp_actice_psr(struct device *dev)
+{
+   struct analogix_dp_device *dp = dev_get_drvdata(dev);
+
+   if (!dp->psr_support)
+   return -EINVAL;
+
+   analogix_dp_send_vsc(dp, EDP_VSC_PSR_STATE_ACTIVE |
+EDP_VSC_PSR_CRC_VALUES_VALID);
+
+   return 0;
+}
+EXPORT_SYMBOL_GPL(analogix_dp_actice_psr);
+
+int analogix_dp_inactice_psr(struct device *dev)
+{
+   struct analogix_dp_device *dp = dev_get_drvdata(dev);
+
+   if (!dp->psr_support)
+   return -EINVAL;
+
+   analogix_dp_send_vsc(dp, 0);
+
+   return 0;
+}
+EXPORT_SYMBOL_GPL(analogix_dp_inactice_psr);
+
+int analogix_dp_enable_psr(struct analogix_dp_device *dp)
+{
+   unsigned char psr_version, psr_caps;
+   unsigned char psr_en;
+
+   /* disable psr function */
+   analogix_dp_read_byte_from_dpcd(dp, DP_PSR_EN_CFG, &psr_en);
+   psr_en &= ~DP_PSR_ENABLE;
+   analogix_dp_write_byte_to_dpcd(dp, DP_PSR_EN_CFG, psr_en);
+
+   /* check panel psr version */
+   analogix_dp_read_byte_from_dpcd(dp, DP_PSR_SUPPORT, &psr_version);
+   analogix_dp_read_byte_from_dpcd(dp, DP_PSR_CAPS, &psr_caps);
+   dev_info(dp->dev, "Panel PSR version : %x.%x\n", psr_version, psr_caps);
+
+   if (!(psr_version & DP_PSR_IS_SUPPORTED))
+   return -1;
+
+   /* Main-Link transmitter remains active during PSR active states */
+   analogix_dp_read_byte_from_dpcd(dp, DP_PSR_EN_CFG, &psr_en);
+   psr_en = DP_PSR_MAIN_LINK_ACTIVE | DP_PSR_CRC_VERIFICATION;
+   analogix_dp_write_byte_to_dpcd(dp, DP_PSR_EN_CFG, psr_en);
+
+   /* enable PSR function */
+   analogix_dp_read_byte_from_dpcd(dp, DP_PSR_EN_CFG, &psr_en);
+   psr_en = DP_PSR_ENABLE | DP_PSR_MAIN_LINK_ACTIVE |
+DP_PSR_CRC_VERIFICATION;
+   analogix_dp_write_byte_to_dpcd(dp, DP_PSR_EN_CFG, psr_en);
+
+   /* read sink psr state */
+   analogix_dp_read_byte_from_dpcd(dp, DP_PSR_EN_CFG, &psr_en);
+   dev_info(dp->dev, "DP_PSR_EN_CFG: %x\n", psr_en);
+
+   analogix_dp_enable_psr_crc(dp);
+   dp->psr_support = true;
+
+   return 0;
+}
+
 static void analogix_dp_init_dp(struct analogix_dp_device *dp)
 {
analogix_dp_reset(dp);
@@ -921,6 +987,9 @@ static void analogix_dp_commit(struct analogix_dp_device 
*dp)

/* Enable video */
analogix_dp_start_video(dp);
+
+   /* Enable PSR support */
+   analogix_dp_enable_psr(dp);
 }

 int analogix_dp_get_modes(struct drm_connector *connector)
diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.h 
b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.h
index b456380..2d1dae2 100644
--- a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.h
+++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.h
@@ -177,6 +177,7 @@ struct analogix_dp_device {
int hpd_gpio;
boolforce_hpd;
unsigned char   edid[EDID_BLOCK_LENGTH * 2];
+   boolpsr_support;

struct analogix_dp_plat_data *plat_data;
 };
@@ -278,4 +279,7 @@ int analogix_dp_is_video_stream_on(struct 
analogix_dp_device *dp);
 void analogix_dp_config_video_slave_mode(struct analogix_dp_device *dp);
 void analogix_dp_enable_scrambling(struct analogix_dp_device *dp);
 void analogix_dp_disable_scrambling(struct analogix_dp_device *dp);
+void analogix_dp_enable_psr_crc(struct analogix_dp_device *dp);
+void analogix_dp_send_vsc(struct analogix_dp_device *dp, int db1);
+
 #endif /* _ANALOGIX_DP_CORE_H */
diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c 
b/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c
index 31366bf..8d8c37a 100644
--- a/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c
+++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c
@@ -1322,3 +1322,57 @@ void analogix_dp_disable_scr

[RFC PATCH v2 2/3] drm/rockchip: vop: add line flag function support

2016-06-02 Thread Yakir Yang
VOP could use line flag interrupt to detect some target timing.
For example, eDP PSR is interesting in vact_end, then VOP could
configure the line number to vact_end, and wait for line flag
interrupt coming.

Signed-off-by: Yakir Yang 
---
Changes in v2:
- introduce in v2, split VOP line flag changes out

 drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 63 +
 drivers/gpu/drm/rockchip/rockchip_drm_vop.h |  3 ++
 drivers/gpu/drm/rockchip/rockchip_vop_reg.c |  2 +
 3 files changed, 68 insertions(+)

diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c 
b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
index 257501f..b2a36db 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
@@ -117,6 +117,8 @@ struct vop {
struct completion wait_update_complete;
struct drm_pending_vblank_event *event;

+   struct completion line_flag_completion;
+
const struct vop_data *data;

uint32_t *regsbak;
@@ -427,6 +429,59 @@ static void vop_dsp_hold_valid_irq_disable(struct vop *vop)
spin_unlock_irqrestore(&vop->irq_lock, flags);
 }

+/*
+ * (1) each frame starts at the start of the Vsync pulse which is signaled by
+ * the "FRAME_SYNC" interrupt.
+ * (2) the active data region of each frame ends at dsp_vact_end
+ * (3) we should program this same number (dsp_vact_end) into 
dsp_line_frag_num,
+ *  to get "LINE_FLAG" interrupt at the end of the active on screen data.
+ *
+ * VOP_INTR_CTRL0.dsp_line_frag_num = VOP_DSP_VACT_ST_END.dsp_vact_end
+ * Interrupts
+ * LINE_FLAG ---+
+ * FRAME_SYNC + |
+ *| |
+ *v v
+ *| Vsync | Vbp |  Vactive  | Vfp |
+ *^ ^   ^ ^
+ *| |   | |
+ *| |   | |
+ * dsp_vs_end + |   | |   VOP_DSP_VTOTAL_VS_END
+ * dsp_vact_start --+   | |   VOP_DSP_VACT_ST_END
+ * dsp_vact_end + |   VOP_DSP_VACT_ST_END
+ * dsp_total -+   VOP_DSP_VTOTAL_VS_END
+ */
+
+static void vop_line_flag_irq_enable(struct vop *vop, int line_num)
+{
+   unsigned long flags;
+
+   if (WARN_ON(!vop->is_enabled))
+   return;
+
+   spin_lock_irqsave(&vop->irq_lock, flags);
+
+   VOP_CTRL_SET(vop, line_flag_num_0, line_num);
+   VOP_INTR_SET_TYPE(vop, enable, LINE_FLAG_INTR, 1);
+   vop_cfg_done(vop);
+
+   spin_unlock_irqrestore(&vop->irq_lock, flags);
+}
+
+static void vop_line_flag_irq_disable(struct vop *vop)
+{
+   unsigned long flags;
+
+   if (WARN_ON(!vop->is_enabled))
+   return;
+
+   spin_lock_irqsave(&vop->irq_lock, flags);
+
+   VOP_INTR_SET_TYPE(vop, enable, LINE_FLAG_INTR, 0);
+
+   spin_unlock_irqrestore(&vop->irq_lock, flags);
+}
+
 static void vop_enable(struct drm_crtc *crtc)
 {
struct vop *vop = to_vop(crtc);
@@ -1154,6 +1209,13 @@ static irqreturn_t vop_isr(int irq, void *data)
ret = IRQ_HANDLED;
}

+   if (active_irqs & LINE_FLAG_INTR) {
+   if (!completion_done(&vop->line_flag_completion))
+   complete(&vop->line_flag_completion);
+   active_irqs &= ~LINE_FLAG_INTR;
+   ret = IRQ_HANDLED;
+   }
+
if (active_irqs & FS_INTR) {
drm_crtc_handle_vblank(crtc);
vop_handle_vblank(vop);
@@ -1252,6 +1314,7 @@ static int vop_create_crtc(struct vop *vop)

init_completion(&vop->dsp_hold_completion);
init_completion(&vop->wait_update_complete);
+   init_completion(&vop->line_flag_completion);
crtc->port = port;
rockchip_register_crtc_funcs(crtc, &private_crtc_funcs);

diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.h 
b/drivers/gpu/drm/rockchip/rockchip_drm_vop.h
index ff4f52e..34fcd03 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.h
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.h
@@ -61,6 +61,9 @@ struct vop_ctrl {
struct vop_reg hpost_st_end;
struct vop_reg vpost_st_end;

+   struct vop_reg line_flag_num_0;
+   struct vop_reg line_flag_num_1;
+
struct vop_reg cfg_done;
 };

diff --git a/drivers/gpu/drm/rockchip/rockchip_vop_reg.c 
b/drivers/gpu/drm/rockchip/rockchip_vop_reg.c
index 6f42e56..bf78892 100644
--- a/drivers/gpu/drm/rockchip/rockchip_vop_reg.c
+++ b/drivers/gpu/drm/rockchip/rockchip_vop_reg.c
@@ -299,6 +299,8 @@ static const struct vop_ctrl rk3399_ctrl_data = {
.vact_st_end = VOP_REG(RK3399_DSP_VACT_ST_END, 0x1fff1fff, 0),
.hpost_st_end = VOP_REG(RK3399_POST_DSP_HACT_INFO, 0x1fff1fff, 0),
.vpost_st_end = VOP_REG(RK3399_POST_DSP_VACT_INFO, 0x1fff1fff, 0),
+   .line_flag_num_0 = VOP_REG(RK3399_LINE_F

[RFC PATCH v2 3/3] drm/rockchip: analogix_dp: add PSR support

2016-06-02 Thread Yakir Yang
Let VOP vblank status decide whether panle should enter into or
exit from PSR status. Before eDP start to change PSR status, it
need to wait for VOP vact_end event. In order to listen vact_end
event, I create a new file about PSR notify between eDP and VOP.

Signed-off-by: Yakir Yang 
---
Changes in v2:
- Remove vblank notify out (Daniel)
- Create a psr_active() callback in vop data struct.

 drivers/gpu/drm/rockchip/Makefile   |  2 +-
 drivers/gpu/drm/rockchip/analogix_dp-rockchip.c | 64 -
 drivers/gpu/drm/rockchip/rockchip_drm_drv.h |  7 +++
 drivers/gpu/drm/rockchip/rockchip_drm_notify.c  | 54 +
 drivers/gpu/drm/rockchip/rockchip_drm_notify.h  | 23 +
 drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 41 
 6 files changed, 189 insertions(+), 2 deletions(-)
 create mode 100644 drivers/gpu/drm/rockchip/rockchip_drm_notify.c
 create mode 100644 drivers/gpu/drm/rockchip/rockchip_drm_notify.h

diff --git a/drivers/gpu/drm/rockchip/Makefile 
b/drivers/gpu/drm/rockchip/Makefile
index 05d0713..49fee8c 100644
--- a/drivers/gpu/drm/rockchip/Makefile
+++ b/drivers/gpu/drm/rockchip/Makefile
@@ -3,7 +3,7 @@
 # Direct Rendering Infrastructure (DRI) in XFree86 4.1.0 and higher.

 rockchipdrm-y := rockchip_drm_drv.o rockchip_drm_fb.o \
-   rockchip_drm_gem.o rockchip_drm_vop.o
+   rockchip_drm_gem.o rockchip_drm_vop.o rockchip_drm_notify.o
 rockchipdrm-$(CONFIG_DRM_FBDEV_EMULATION) += rockchip_drm_fbdev.o

 obj-$(CONFIG_ROCKCHIP_ANALOGIX_DP) += analogix_dp-rockchip.o
diff --git a/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c 
b/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
index 4b64964..25fb687 100644
--- a/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
+++ b/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
@@ -33,6 +33,7 @@

 #include "rockchip_drm_drv.h"
 #include "rockchip_drm_vop.h"
+#include "rockchip_drm_notify.h"

 #define to_dp(nm)  container_of(nm, struct rockchip_dp_device, nm)

@@ -54,6 +55,10 @@ struct rockchip_dp_device {
struct regmap*grf;
struct reset_control *rst;

+   struct workqueue_struct  *dp_workq;
+   struct work_struct   psr_work;
+   unsigned int psr_state;
+
const struct rockchip_dp_chip_data *data;

struct analogix_dp_plat_data plat_data;
@@ -97,6 +102,42 @@ static int rockchip_dp_powerdown(struct 
analogix_dp_plat_data *plat_data)
return 0;
 }

+static int rockchip_dp_psr_active(enum psr_action action, void *priv)
+{
+   struct rockchip_dp_device *dp = (struct rockchip_dp_device *)priv;
+
+   switch (action) {
+   case PSR_INACTIVE:
+   dp->psr_state = 0;
+   break;
+   case PSR_ACTIVE:
+   dp->psr_state = EDP_VSC_PSR_STATE_ACTIVE;
+   break;
+   default:
+   return 0;
+   }
+
+   queue_work(dp->dp_workq, &dp->psr_work);
+   return 0;
+}
+
+static void dp_psr_work(struct work_struct *psr_work)
+{
+   struct rockchip_dp_device *dp = to_dp(psr_work);
+   int psr_state = dp->psr_state;
+   int ret;
+
+   if (psr_state == EDP_VSC_PSR_STATE_ACTIVE) {
+   ret = rockchip_psr_ready_wait();
+   if (ret == 0)
+   analogix_dp_actice_psr(dp->dev);
+   } else {
+   ret = rockchip_psr_ready_wait();
+   if (ret == 0)
+   analogix_dp_inactice_psr(dp->dev);
+   }
+}
+
 static enum drm_mode_status
 rockchip_dp_mode_valid(struct analogix_dp_plat_data *plat_data,
   struct drm_connector *connector,
@@ -128,9 +169,18 @@ static void rockchip_dp_drm_encoder_mode_set(struct 
drm_encoder *encoder,
 struct drm_display_mode *mode,
 struct drm_display_mode *adjusted)
 {
-   /* do nothing */
+   struct rockchip_dp_device *dp = to_dp(encoder);
+   struct drm_crtc *crtc = encoder->crtc;
+   struct rockchip_crtc_state *s;
+
+   if (crtc) {
+   s = to_rockchip_crtc_state(crtc->state);
+   s->psr_active = rockchip_dp_psr_active;
+   s->psr_priv = dp;
+   }
 }

+
 static void rockchip_dp_drm_encoder_enable(struct drm_encoder *encoder)
 {
struct rockchip_dp_device *dp = to_dp(encoder);
@@ -198,6 +248,9 @@ rockchip_dp_drm_encoder_atomic_check(struct drm_encoder 
*encoder,
break;
}

+   s->psr_active = rockchip_dp_psr_active;
+   s->psr_priv = dp;
+
return 0;
 }

@@ -320,6 +373,15 @@ static int rockchip_dp_bind(struct device *dev, struct 
device *master,
dp->plat_data.power_off = rockchip_dp_powerdown;
dp->plat_data.mode_valid = rockchip_dp_mode_valid;

+   dp->dp_workq = create_singlethread_workqueue("dp");
+   if (!dp->dp_workq) {
+   dev_err(dp->dev, "failed to create workqueue\n");

[PATCH 1/5] drm/imx-ldb: Add support to drm-bridge

2016-06-02 Thread Philipp Zabel
Am Montag, den 30.05.2016, 18:39 +0200 schrieb Peter Senna Tschudin:
> Add support to attach a drm_bridge to imx-ldb in addition to
> existing support to attach a LVDS panel.
> 
> Signed-off-by: Peter Senna Tschudin 
> ---
>  drivers/gpu/drm/imx/imx-ldb.c | 75 
> +++
>  1 file changed, 54 insertions(+), 21 deletions(-)
> 
> diff --git a/drivers/gpu/drm/imx/imx-ldb.c b/drivers/gpu/drm/imx/imx-ldb.c
> index a58eee5..7233a81 100644
> --- a/drivers/gpu/drm/imx/imx-ldb.c
> +++ b/drivers/gpu/drm/imx/imx-ldb.c
> @@ -57,7 +57,11 @@ struct imx_ldb_channel {
>   struct imx_ldb *ldb;
>   struct drm_connector connector;
>   struct drm_encoder encoder;
> +
> + /* Defines what is connected to the ldb, only one at a time */
>   struct drm_panel *panel;
> + struct drm_bridge *ext_bridge;
> +

Just bridge should be clear enough.

>   struct device_node *child;
>   int chno;
>   void *edid;
> @@ -295,6 +299,10 @@ static void imx_ldb_encoder_mode_set(struct drm_encoder 
> *encoder,
>   }
>  }
>  
> +static void imx_ldb_encoder_enable(struct drm_encoder *encoder)
> +{
> +}
> +

Why?

Note that Liu Ying's atomic series touches this also, and after
"drm/imx: atomic phase 3 step 3: Legacy callback fixups" the enable
callback exists. Depending on how either series proceeds, one will have
to be rebased onto the other.

>  static void imx_ldb_encoder_disable(struct drm_encoder *encoder)
>  {
>   struct imx_ldb_channel *imx_ldb_ch = enc_to_imx_ldb_ch(encoder);
> @@ -373,6 +381,7 @@ static const struct drm_encoder_helper_funcs 
> imx_ldb_encoder_helper_funcs = {
>   .prepare = imx_ldb_encoder_prepare,
>   .commit = imx_ldb_encoder_commit,
>   .mode_set = imx_ldb_encoder_mode_set,
> + .enable = imx_ldb_encoder_enable,
>   .disable = imx_ldb_encoder_disable,
>  };
>  
> @@ -417,16 +426,28 @@ static int imx_ldb_register(struct drm_device *drm,
>   drm_encoder_init(drm, &imx_ldb_ch->encoder, &imx_ldb_encoder_funcs,
>DRM_MODE_ENCODER_LVDS, NULL);
>  
> - drm_connector_helper_add(&imx_ldb_ch->connector,
> - &imx_ldb_connector_helper_funcs);
> - drm_connector_init(drm, &imx_ldb_ch->connector,
> -&imx_ldb_connector_funcs, DRM_MODE_CONNECTOR_LVDS);
> -
> - if (imx_ldb_ch->panel)
> + if (imx_ldb_ch->panel) {

if (!imx_ldb_ch->bridge) {

> + drm_connector_helper_add(&imx_ldb_ch->connector,
> + &imx_ldb_connector_helper_funcs);
> + drm_connector_init(drm, &imx_ldb_ch->connector,
> + &imx_ldb_connector_funcs,
> + DRM_MODE_CONNECTOR_LVDS);
>   drm_panel_attach(imx_ldb_ch->panel, &imx_ldb_ch->connector);
>  
> - drm_mode_connector_attach_encoder(&imx_ldb_ch->connector,
> - &imx_ldb_ch->encoder);
> + drm_mode_connector_attach_encoder(&imx_ldb_ch->connector,
> + &imx_ldb_ch->encoder);
> + }
> +
> + if (imx_ldb_ch->ext_bridge) {
> + imx_ldb_ch->ext_bridge->encoder = &imx_ldb_ch->encoder;
> +
> + imx_ldb_ch->encoder.bridge = imx_ldb_ch->ext_bridge;
> + ret = drm_bridge_attach(drm, imx_ldb_ch->ext_bridge);
> + if (ret) {
> + DRM_ERROR("Failed to initialize bridge with drm\n");
> + return ret;
> + }
> + }
>  
>   return 0;
>  }
> @@ -583,23 +604,35 @@ static int imx_ldb_bind(struct device *dev, struct 
> device *master, void *data)
>   endpoint = of_get_child_by_name(port, "endpoint");
>   if (endpoint) {
>   remote = 
> of_graph_get_remote_port_parent(endpoint);
> - if (remote)
> - channel->panel = 
> of_drm_find_panel(remote);
> - else
> - return -EPROBE_DEFER;
> - if (!channel->panel) {
> - dev_err(dev, "panel not found: %s\n",
> - remote->full_name);

Let's keep this message, at least as dev_dbg.

> - return -EPROBE_DEFER;
> + if (remote) {
> + /* Only one of these two will succeed */
> + channel->panel =
> + of_drm_find_panel(remote);
> +
> + channel->ext_bridge =
> + of_drm_find_bridge(remote);
> +
> + /*
> +  * If the bridge is compiled as a
> +  * module, it may take some time until
> +   

[PATCH v4] drm: Only create a cmdline mode if no probed modes match

2016-06-02 Thread Daniel Vetter
On Thu, Jun 02, 2016 at 02:30:40PM +0300, Ville Syrjälä wrote:
> On Thu, Jun 02, 2016 at 11:52:17AM +0100, Chris Wilson wrote:
> > On Thu, Jun 02, 2016 at 11:38:26AM +0200, Radek Dostál wrote:
> > > On 06/01/2016 11:50 AM, Chris Wilson wrote:
> > > >Fixes regression from
> > > >
> > > >commit eaf99c749d43ae74ac7ffece5512f3c73f01dfd2
> > > >Author: Chris Wilson
> > > >Date:   Wed Aug 6 10:08:32 2014 +0200
> > > >
> > > > drm: Perform cmdline mode parsing during connector initialisation
> > > >
> > > >that breaks HDMI output on BeagleBone Black with LG TV (model 19LS4R-ZA).
> > > 
> > > please remove this from the commit message. The original bug is no
> > > longer reproducible with 4.7-rc1
> > 
> > If there's no motivation for the patch anymore, it can just wither away
> > in one of my old trees.
> > 
> > Does anyone care about pruning the autogenerated video= mode if a probed
> > one matches? Presumably, it is still visible to userspace and switching
> > to it will cause the same issue as before? Or was it always a driver
> > bug (failing to set the mode)?
> 
> IMO the patch makes total sense even if it's not needed for this
> particular bug. Feel free to add
> 
> Reviewed-by: Ville Syrjälä 

Agreed. I dropped the cc: stable and adjusted the commit message to
explain the situation. Merged to drm-misc, thanks.
-Daniel
-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch


[PATCH 03/38] drm/msm: Use for_each_*_in_state

2016-06-02 Thread Maarten Lankhorst
Op 02-06-16 om 00:06 schreef Daniel Vetter:
> We want to hide drm_atomic_state internals
>
> Cc: Rob Clark 
> Signed-off-by: Daniel Vetter 
> ---
>  drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.c| 20 +++--
>  drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c| 12 +++---
>  drivers/gpu/drm/msm/msm_atomic.c   | 35 
> ++
>  drivers/gpu/drm/rockchip/rockchip_drm_fb.c |  1 +
>  4 files changed, 23 insertions(+), 45 deletions(-)
>
> diff --git a/drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.c 
> b/drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.c
> index 67442d50a6c2..f145d256e332 100644
> --- a/drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.c
> +++ b/drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.c
> @@ -106,31 +106,27 @@ out:
>  static void mdp4_prepare_commit(struct msm_kms *kms, struct drm_atomic_state 
> *state)
>  {
>   struct mdp4_kms *mdp4_kms = to_mdp4_kms(to_mdp_kms(kms));
> - int i, ncrtcs = state->dev->mode_config.num_crtc;
> + int i;
> + struct drm_crtc *crtc;
> + struct drm_crtc_state *crtc_state;
>  
>   mdp4_enable(mdp4_kms);
>  
>   /* see 119ecb7fd */
> - for (i = 0; i < ncrtcs; i++) {
> - struct drm_crtc *crtc = state->crtcs[i];
> - if (!crtc)
> - continue;
> + for_each_crtc_in_state(state, crtc, crtc_state, i)
>   drm_crtc_vblank_get(crtc);
> - }
>  }
>  
>  static void mdp4_complete_commit(struct msm_kms *kms, struct 
> drm_atomic_state *state)
>  {
>   struct mdp4_kms *mdp4_kms = to_mdp4_kms(to_mdp_kms(kms));
> - int i, ncrtcs = state->dev->mode_config.num_crtc;
> + int i;
> + struct drm_crtc *crtc;
> + struct drm_crtc_state *crtc_state;
>  
>   /* see 119ecb7fd */
> - for (i = 0; i < ncrtcs; i++) {
> - struct drm_crtc *crtc = state->crtcs[i];
> - if (!crtc)
> - continue;
> + for_each_crtc_in_state(state, crtc, crtc_state, i)
>   drm_crtc_vblank_put(crtc);
> - }
>  
>   mdp4_disable(mdp4_kms);
>  }
> diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c 
> b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c
> index 484b4d15e71d..f0c285b1c027 100644
> --- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c
> +++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c
> @@ -78,17 +78,11 @@ static void mdp5_complete_commit(struct msm_kms *kms, 
> struct drm_atomic_state *s
>  {
>   int i;
>   struct mdp5_kms *mdp5_kms = to_mdp5_kms(to_mdp_kms(kms));
> - int nplanes = mdp5_kms->dev->mode_config.num_total_plane;
> -
> - for (i = 0; i < nplanes; i++) {
> - struct drm_plane *plane = state->planes[i];
> - struct drm_plane_state *plane_state = state->plane_states[i];
> -
> - if (!plane)
> - continue;
> + struct drm_plane *plane;
> + struct drm_plane_state *plane_state;
>  
> + for_each_plane_in_state(state, plane, plane_state, i)
>   mdp5_plane_complete_commit(plane, plane_state);
> - }
>  
>   mdp5_disable(mdp5_kms);
>  }
> diff --git a/drivers/gpu/drm/msm/msm_atomic.c 
> b/drivers/gpu/drm/msm/msm_atomic.c
> index e3892c263f27..9c0e4261dbba 100644
> --- a/drivers/gpu/drm/msm/msm_atomic.c
> +++ b/drivers/gpu/drm/msm/msm_atomic.c
> @@ -84,17 +84,12 @@ static void msm_atomic_wait_for_commit_done(struct 
> drm_device *dev,
>   struct drm_atomic_state *old_state)
>  {
>   struct drm_crtc *crtc;
> + struct drm_crtc_state *crtc_state;
>   struct msm_drm_private *priv = old_state->dev->dev_private;
>   struct msm_kms *kms = priv->kms;
> - int ncrtcs = old_state->dev->mode_config.num_crtc;
>   int i;
>  
> - for (i = 0; i < ncrtcs; i++) {
> - crtc = old_state->crtcs[i];
> -
> - if (!crtc)
> - continue;
> -
> + for_each_crtc_in_state(old_state, crtc, crtc_state, i) {
>   if (!crtc->state->enable)
>   continue;
>  
> @@ -192,9 +187,11 @@ int msm_atomic_commit(struct drm_device *dev,
>   struct drm_atomic_state *state, bool nonblock)
>  {
>   struct msm_drm_private *priv = dev->dev_private;
> - int nplanes = dev->mode_config.num_total_plane;
> - int ncrtcs = dev->mode_config.num_crtc;
>   struct msm_commit *c;
> + struct drm_crtc *crtc;
> + struct drm_crtc_state *crtc_state;
> + struct drm_plane *plane;
> + struct drm_plane_state *plane_state;
>   int i, ret;
>  
>   ret = drm_atomic_helper_prepare_planes(dev, state);
> @@ -210,28 +207,18 @@ int msm_atomic_commit(struct drm_device *dev,
>   /*
>* Figure out what crtcs we have:
>*/
> - for (i = 0; i < ncrtcs; i++) {
> - struct drm_crtc *crtc = state->crtcs[i];
> - if (!crtc)
> - continue;
> + for_each_crtc_in_state(state, crtc, crtc_state, i)
>   c->crtc_mask |= (1 << drm_crtc_index(crtc));
Maybe also change this to use drm_crtc_mask(crtc); ?
> -  

[PATCH 04/38] drm/rcar-du: Use for_each_*_in_state

2016-06-02 Thread Maarten Lankhorst
Op 02-06-16 om 00:06 schreef Daniel Vetter:
> We want to hide drm_atomic_state internals better.
>
> Cc: Laurent Pinchart 
> Signed-off-by: Daniel Vetter 
> ---
>  drivers/gpu/drm/rcar-du/rcar_du_kms.c   |  8 
>  drivers/gpu/drm/rcar-du/rcar_du_plane.c | 20 
>  2 files changed, 12 insertions(+), 16 deletions(-)
>
> diff --git a/drivers/gpu/drm/rcar-du/rcar_du_kms.c 
> b/drivers/gpu/drm/rcar-du/rcar_du_kms.c
> index e70a4f33d970..f315c55c1f65 100644
> --- a/drivers/gpu/drm/rcar-du/rcar_du_kms.c
> +++ b/drivers/gpu/drm/rcar-du/rcar_du_kms.c
> @@ -288,6 +288,8 @@ static int rcar_du_atomic_commit(struct drm_device *dev,
>  {
>   struct rcar_du_device *rcdu = dev->dev_private;
>   struct rcar_du_commit *commit;
> + struct drm_crtc *crtc;
> + struct drm_crtc_state *crtc_state;
>   unsigned int i;
>   int ret;
>  
> @@ -309,10 +311,8 @@ static int rcar_du_atomic_commit(struct drm_device *dev,
>   /* Wait until all affected CRTCs have completed previous commits and
>* mark them as pending.
>*/
> - for (i = 0; i < dev->mode_config.num_crtc; ++i) {
> - if (state->crtcs[i])
> - commit->crtcs |= 1 << drm_crtc_index(state->crtcs[i]);
> - }
> + for_each_crtc_in_state(state, crtc, crtc_state, i)
> + commit->crtcs |= 1 << drm_crtc_index(crtc);
>  
Maybe also change this one to _mask,
either way.

Reviewed-by: Maarten Lankhorst 


[RFC PATCH v2 3/3] drm/rockchip: analogix_dp: add PSR support

2016-06-02 Thread Daniel Vetter
On Thu, Jun 02, 2016 at 08:57:38PM +0800, Yakir Yang wrote:
> Let VOP vblank status decide whether panle should enter into or
> exit from PSR status. Before eDP start to change PSR status, it
> need to wait for VOP vact_end event. In order to listen vact_end
> event, I create a new file about PSR notify between eDP and VOP.
> 
> Signed-off-by: Yakir Yang 
> ---
> Changes in v2:
> - Remove vblank notify out (Daniel)
> - Create a psr_active() callback in vop data struct.

Still contains a notifier. Still doesn't contain a proper fb->dirty
callback. Please don't just act on review without understanding the deeper
implications, since I didn't ask you to remove the vblank logic (you
probably still need that), I suggested to implement it differently
(withotu notifiers).
-Daniel

> 
>  drivers/gpu/drm/rockchip/Makefile   |  2 +-
>  drivers/gpu/drm/rockchip/analogix_dp-rockchip.c | 64 
> -
>  drivers/gpu/drm/rockchip/rockchip_drm_drv.h |  7 +++
>  drivers/gpu/drm/rockchip/rockchip_drm_notify.c  | 54 +
>  drivers/gpu/drm/rockchip/rockchip_drm_notify.h  | 23 +
>  drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 41 
>  6 files changed, 189 insertions(+), 2 deletions(-)
>  create mode 100644 drivers/gpu/drm/rockchip/rockchip_drm_notify.c
>  create mode 100644 drivers/gpu/drm/rockchip/rockchip_drm_notify.h
> 
> diff --git a/drivers/gpu/drm/rockchip/Makefile 
> b/drivers/gpu/drm/rockchip/Makefile
> index 05d0713..49fee8c 100644
> --- a/drivers/gpu/drm/rockchip/Makefile
> +++ b/drivers/gpu/drm/rockchip/Makefile
> @@ -3,7 +3,7 @@
>  # Direct Rendering Infrastructure (DRI) in XFree86 4.1.0 and higher.
>  
>  rockchipdrm-y := rockchip_drm_drv.o rockchip_drm_fb.o \
> - rockchip_drm_gem.o rockchip_drm_vop.o
> + rockchip_drm_gem.o rockchip_drm_vop.o rockchip_drm_notify.o
>  rockchipdrm-$(CONFIG_DRM_FBDEV_EMULATION) += rockchip_drm_fbdev.o
>  
>  obj-$(CONFIG_ROCKCHIP_ANALOGIX_DP) += analogix_dp-rockchip.o
> diff --git a/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c 
> b/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
> index 4b64964..25fb687 100644
> --- a/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
> +++ b/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
> @@ -33,6 +33,7 @@
>  
>  #include "rockchip_drm_drv.h"
>  #include "rockchip_drm_vop.h"
> +#include "rockchip_drm_notify.h"
>  
>  #define to_dp(nm)container_of(nm, struct rockchip_dp_device, nm)
>  
> @@ -54,6 +55,10 @@ struct rockchip_dp_device {
>   struct regmap*grf;
>   struct reset_control *rst;
>  
> + struct workqueue_struct  *dp_workq;
> + struct work_struct   psr_work;
> + unsigned int psr_state;
> +
>   const struct rockchip_dp_chip_data *data;
>  
>   struct analogix_dp_plat_data plat_data;
> @@ -97,6 +102,42 @@ static int rockchip_dp_powerdown(struct 
> analogix_dp_plat_data *plat_data)
>   return 0;
>  }
>  
> +static int rockchip_dp_psr_active(enum psr_action action, void *priv)
> +{
> + struct rockchip_dp_device *dp = (struct rockchip_dp_device *)priv;
> +
> + switch (action) {
> + case PSR_INACTIVE:
> + dp->psr_state = 0;
> + break;
> + case PSR_ACTIVE:
> + dp->psr_state = EDP_VSC_PSR_STATE_ACTIVE;
> + break;
> + default:
> + return 0;
> + }
> +
> + queue_work(dp->dp_workq, &dp->psr_work);
> + return 0;
> +}
> +
> +static void dp_psr_work(struct work_struct *psr_work)
> +{
> + struct rockchip_dp_device *dp = to_dp(psr_work);
> + int psr_state = dp->psr_state;
> + int ret;
> +
> + if (psr_state == EDP_VSC_PSR_STATE_ACTIVE) {
> + ret = rockchip_psr_ready_wait();
> + if (ret == 0)
> + analogix_dp_actice_psr(dp->dev);
> + } else {
> + ret = rockchip_psr_ready_wait();
> + if (ret == 0)
> + analogix_dp_inactice_psr(dp->dev);
> + }
> +}
> +
>  static enum drm_mode_status
>  rockchip_dp_mode_valid(struct analogix_dp_plat_data *plat_data,
>  struct drm_connector *connector,
> @@ -128,9 +169,18 @@ static void rockchip_dp_drm_encoder_mode_set(struct 
> drm_encoder *encoder,
>struct drm_display_mode *mode,
>struct drm_display_mode *adjusted)
>  {
> - /* do nothing */
> + struct rockchip_dp_device *dp = to_dp(encoder);
> + struct drm_crtc *crtc = encoder->crtc;
> + struct rockchip_crtc_state *s;
> +
> + if (crtc) {
> + s = to_rockchip_crtc_state(crtc->state);
> + s->psr_active = rockchip_dp_psr_active;
> + s->psr_priv = dp;
> + }
>  }
>  
> +
>  static void rockchip_dp_drm_encoder_enable(struct drm_encoder *encoder)
>  {
>   struct rockchip_dp_device *dp = to_dp(encoder);
> @@ -198,6 +248,9 @@ rockchip_dp_drm_encoder_atomi

[Intel-gfx] [PATCH 06/38] drm/omap: Use for_each_plane_in_state

2016-06-02 Thread Maarten Lankhorst
Op 02-06-16 om 00:06 schreef Daniel Vetter:
> We want to hide drm_atomic_stat internals a bit better.
>
> Cc: Laurent Pinchart 
> Cc: Tomi Valkeinen 
> Signed-off-by: Daniel Vetter 
> ---
>  drivers/gpu/drm/omapdrm/omap_drv.c | 11 +--
>  1 file changed, 5 insertions(+), 6 deletions(-)
>
> diff --git a/drivers/gpu/drm/omapdrm/omap_drv.c 
> b/drivers/gpu/drm/omapdrm/omap_drv.c
> index d86f5479345b..4798ba43ff5b 100644
> --- a/drivers/gpu/drm/omapdrm/omap_drv.c
> +++ b/drivers/gpu/drm/omapdrm/omap_drv.c
> @@ -142,8 +142,9 @@ static int omap_atomic_commit(struct drm_device *dev,
>  {
>   struct omap_drm_private *priv = dev->dev_private;
>   struct omap_atomic_state_commit *commit;
> - unsigned int i;
> - int ret;
> + struct drm_crtc *crtc;
> + struct drm_crtc_state *crtc_state;
> + int i, ret;
>  
>   ret = drm_atomic_helper_prepare_planes(dev, state);
>   if (ret)
> @@ -163,10 +164,8 @@ static int omap_atomic_commit(struct drm_device *dev,
>   /* Wait until all affected CRTCs have completed previous commits and
>* mark them as pending.
>*/
> - for (i = 0; i < dev->mode_config.num_crtc; ++i) {
> - if (state->crtcs[i])
> - commit->crtcs |= 1 << drm_crtc_index(state->crtcs[i]);
> - }
> + for_each_crtc_in_state(state, crtc, crtc_state, i)
> + commit->crtcs |= 1 << drm_crtc_index(crtc);
>  
>   wait_event(priv->commit.wait, !omap_atomic_is_pending(priv, commit));
>  

(again 1 << index -> crtc_mask)

Reviewed-by: Maarten Lankhorst 



[PATCH 05/38] drm/vc4: Use for_each_plane_in_state

2016-06-02 Thread Maarten Lankhorst
Op 02-06-16 om 00:06 schreef Daniel Vetter:
> We want to hide drm_atomic_stat internals a bit better.
>
> Cc: Eric Anholt 
> Signed-off-by: Daniel Vetter 
Reviewed-by: Maarten Lankhorst 


[PATCH 16/38] drm/hdlcd: Clean up crtc hooks

2016-06-02 Thread Daniel Vetter
On Thu, Jun 02, 2016 at 12:06:39AM +0200, Daniel Vetter wrote:
> Those are all no longer needed for a pure atomic driver.
> 
> Cc: Liviu Dudau 
> Tested-by: Liviu Dudau 
> Acked-by: Liviu Dudau 
> Signed-off-by: Daniel Vetter 

Applied this one to drm-misc, since Liviua already acked it. The other
prep patch is already in a -fixes pull request.
-Daniel

> ---
>  drivers/gpu/drm/arm/hdlcd_crtc.c | 19 ---
>  1 file changed, 19 deletions(-)
> 
> diff --git a/drivers/gpu/drm/arm/hdlcd_crtc.c 
> b/drivers/gpu/drm/arm/hdlcd_crtc.c
> index fef1b04c2aab..b44f72722764 100644
> --- a/drivers/gpu/drm/arm/hdlcd_crtc.c
> +++ b/drivers/gpu/drm/arm/hdlcd_crtc.c
> @@ -196,30 +196,11 @@ static void hdlcd_crtc_atomic_begin(struct drm_crtc 
> *crtc,
>   }
>  }
>  
> -static void hdlcd_crtc_atomic_flush(struct drm_crtc *crtc,
> - struct drm_crtc_state *state)
> -{
> -}
> -
> -static bool hdlcd_crtc_mode_fixup(struct drm_crtc *crtc,
> - const struct drm_display_mode *mode,
> - struct drm_display_mode *adjusted_mode)
> -{
> - return true;
> -}
> -
>  static const struct drm_crtc_helper_funcs hdlcd_crtc_helper_funcs = {
> - .mode_fixup = hdlcd_crtc_mode_fixup,
> - .mode_set   = drm_helper_crtc_mode_set,
> - .mode_set_base  = drm_helper_crtc_mode_set_base,
> - .mode_set_nofb  = hdlcd_crtc_mode_set_nofb,
>   .enable = hdlcd_crtc_enable,
>   .disable= hdlcd_crtc_disable,
> - .prepare= hdlcd_crtc_disable,
> - .commit = hdlcd_crtc_enable,
>   .atomic_check   = hdlcd_crtc_atomic_check,
>   .atomic_begin   = hdlcd_crtc_atomic_begin,
> - .atomic_flush   = hdlcd_crtc_atomic_flush,
>  };
>  
>  static int hdlcd_plane_atomic_check(struct drm_plane *plane,
> -- 
> 2.8.1
> 

-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch


[PATCH 1/6] drm/amdgpu/atpx: track whether if this is a hybrid graphics platform

2016-06-02 Thread Alex Deucher
hybrid graphics in this case refers to systems which use the new
platform d3 cold ACPI methods as opposed to ATPX for dGPU power
control.

Signed-off-by: Alex Deucher 
---
 drivers/gpu/drm/amd/amdgpu/amdgpu.h  | 2 ++
 drivers/gpu/drm/amd/amdgpu/amdgpu_atpx_handler.c | 9 -
 2 files changed, 10 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h 
b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
index 19d15dc..c6b5ce3 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
@@ -2394,10 +2394,12 @@ bool amdgpu_device_is_px(struct drm_device *dev);
 void amdgpu_register_atpx_handler(void);
 void amdgpu_unregister_atpx_handler(void);
 bool amdgpu_has_atpx_dgpu_power_cntl(void);
+bool amdgpu_is_atpx_hybrid(void);
 #else
 static inline void amdgpu_register_atpx_handler(void) {}
 static inline void amdgpu_unregister_atpx_handler(void) {}
 static inline bool amdgpu_has_atpx_dgpu_power_cntl(void) { return false; }
+static inline bool amdgpu_is_atpx_hybrid(void) { return false; }
 #endif

 /*
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_atpx_handler.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_atpx_handler.c
index 90dfedc..3e973c7 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_atpx_handler.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_atpx_handler.c
@@ -28,6 +28,7 @@ struct amdgpu_atpx_functions {
 struct amdgpu_atpx {
acpi_handle handle;
struct amdgpu_atpx_functions functions;
+   bool is_hybrid;
 };

 static struct amdgpu_atpx_priv {
@@ -68,6 +69,10 @@ bool amdgpu_has_atpx_dgpu_power_cntl(void) {
return amdgpu_atpx_priv.atpx.functions.power_cntl;
 }

+bool amdgpu_is_atpx_hybrid(void) {
+   return amdgpu_atpx_priv.atpx.is_hybrid;
+}
+
 /**
  * amdgpu_atpx_call - call an ATPX method
  *
@@ -192,9 +197,11 @@ static int amdgpu_atpx_validate(struct amdgpu_atpx *atpx)
  ATPX_DYNAMIC_DGPU_POWER_OFF_SUPPORTED))
atpx->functions.power_cntl = true;

+   atpx->is_hybrid = false;
if (valid_bits & ATPX_MS_HYBRID_GFX_SUPPORTED) {
-   printk("Hybrid Graphics, ATPX dGPU power cntl disabled\n");
+   printk("ATPX Hybrid Graphics\n");
atpx->functions.power_cntl = false;
+   atpx->is_hybrid = true;
}

return 0;
-- 
2.5.5



[PATCH 2/6] drm/amdgpu/atpx: hybrid platforms use d3cold

2016-06-02 Thread Alex Deucher
The platform d3 cold is used to power down the dGPU.

Signed-off-by: Alex Deucher 
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
index 7e49bf4..6c38901 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
@@ -417,7 +417,9 @@ static int amdgpu_pmops_runtime_suspend(struct device *dev)
pci_save_state(pdev);
pci_disable_device(pdev);
pci_ignore_hotplug(pdev);
-   if (amdgpu_has_atpx_dgpu_power_cntl())
+   if (amdgpu_is_atpx_hybrid())
+   pci_set_power_state(pdev, PCI_D3cold);
+   else if (amdgpu_has_atpx_dgpu_power_cntl())
pci_set_power_state(pdev, PCI_D3cold);
else
pci_set_power_state(pdev, PCI_D3hot);
-- 
2.5.5



[PATCH 6/6] drm/radeon: drop explicit pci D3/D0 setting for ATPX power control

2016-06-02 Thread Alex Deucher
The ATPX power control method does this for you.

Signed-off-by: Alex Deucher 
---
 drivers/gpu/drm/radeon/radeon_drv.c | 8 
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/radeon/radeon_drv.c 
b/drivers/gpu/drm/radeon/radeon_drv.c
index f453450..56d15e6 100644
--- a/drivers/gpu/drm/radeon/radeon_drv.c
+++ b/drivers/gpu/drm/radeon/radeon_drv.c
@@ -419,9 +419,7 @@ static int radeon_pmops_runtime_suspend(struct device *dev)
pci_ignore_hotplug(pdev);
if (radeon_is_atpx_hybrid())
pci_set_power_state(pdev, PCI_D3cold);
-   else if (radeon_has_atpx_dgpu_power_cntl())
-   pci_set_power_state(pdev, PCI_D3cold);
-   else
+   else if (!radeon_has_atpx_dgpu_power_cntl())
pci_set_power_state(pdev, PCI_D3hot);
drm_dev->switch_power_state = DRM_SWITCH_POWER_DYNAMIC_OFF;

@@ -439,7 +437,9 @@ static int radeon_pmops_runtime_resume(struct device *dev)

drm_dev->switch_power_state = DRM_SWITCH_POWER_CHANGING;

-   pci_set_power_state(pdev, PCI_D0);
+   if (radeon_is_atpx_hybrid() ||
+   !radeon_has_atpx_dgpu_power_cntl())
+   pci_set_power_state(pdev, PCI_D0);
pci_restore_state(pdev);
ret = pci_enable_device(pdev);
if (ret)
-- 
2.5.5



[PATCH 3/6] drm/amdgpu: drop explicit pci D3/D0 setting for ATPX power control

2016-06-02 Thread Alex Deucher
The ATPX power control method does this for you.

Signed-off-by: Alex Deucher 
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c | 8 
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
index 6c38901..e2bf4ef 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
@@ -419,9 +419,7 @@ static int amdgpu_pmops_runtime_suspend(struct device *dev)
pci_ignore_hotplug(pdev);
if (amdgpu_is_atpx_hybrid())
pci_set_power_state(pdev, PCI_D3cold);
-   else if (amdgpu_has_atpx_dgpu_power_cntl())
-   pci_set_power_state(pdev, PCI_D3cold);
-   else
+   else if (!amdgpu_has_atpx_dgpu_power_cntl())
pci_set_power_state(pdev, PCI_D3hot);
drm_dev->switch_power_state = DRM_SWITCH_POWER_DYNAMIC_OFF;

@@ -439,7 +437,9 @@ static int amdgpu_pmops_runtime_resume(struct device *dev)

drm_dev->switch_power_state = DRM_SWITCH_POWER_CHANGING;

-   pci_set_power_state(pdev, PCI_D0);
+   if (amdgpu_is_atpx_hybrid() ||
+   !amdgpu_has_atpx_dgpu_power_cntl())
+   pci_set_power_state(pdev, PCI_D0);
pci_restore_state(pdev);
ret = pci_enable_device(pdev);
if (ret)
-- 
2.5.5



[PATCH 4/6] drm/radeon/atpx: track whether if this is a hybrid graphics platform

2016-06-02 Thread Alex Deucher
hybrid graphics in this case refers to systems which use the new
platform d3 cold ACPI methods as opposed to ATPX for dGPU power
control.

Signed-off-by: Alex Deucher 
---
 drivers/gpu/drm/radeon/radeon_atpx_handler.c | 9 -
 drivers/gpu/drm/radeon/radeon_drv.c  | 2 ++
 2 files changed, 10 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/radeon/radeon_atpx_handler.c 
b/drivers/gpu/drm/radeon/radeon_atpx_handler.c
index 6996b31..de17b5e 100644
--- a/drivers/gpu/drm/radeon/radeon_atpx_handler.c
+++ b/drivers/gpu/drm/radeon/radeon_atpx_handler.c
@@ -28,6 +28,7 @@ struct radeon_atpx_functions {
 struct radeon_atpx {
acpi_handle handle;
struct radeon_atpx_functions functions;
+   bool is_hybrid;
 };

 static struct radeon_atpx_priv {
@@ -67,6 +68,10 @@ bool radeon_has_atpx_dgpu_power_cntl(void) {
return radeon_atpx_priv.atpx.functions.power_cntl;
 }

+bool radeon_is_atpx_hybrid(void) {
+   return radeon_atpx_priv.atpx.is_hybrid;
+}
+
 /**
  * radeon_atpx_call - call an ATPX method
  *
@@ -190,9 +195,11 @@ static int radeon_atpx_validate(struct radeon_atpx *atpx)
  ATPX_DYNAMIC_DGPU_POWER_OFF_SUPPORTED))
atpx->functions.power_cntl = true;

+   atpx->is_hybrid = false;
if (valid_bits & ATPX_MS_HYBRID_GFX_SUPPORTED) {
-   printk("Hybrid Graphics, ATPX dGPU power cntl disabled\n");
+   printk("ATPX Hybrid Graphics\n");
atpx->functions.power_cntl = false;
+   atpx->is_hybrid = true;
}

return 0;
diff --git a/drivers/gpu/drm/radeon/radeon_drv.c 
b/drivers/gpu/drm/radeon/radeon_drv.c
index ec80050..af52f10 100644
--- a/drivers/gpu/drm/radeon/radeon_drv.c
+++ b/drivers/gpu/drm/radeon/radeon_drv.c
@@ -166,10 +166,12 @@ void radeon_debugfs_cleanup(struct drm_minor *minor);
 void radeon_register_atpx_handler(void);
 void radeon_unregister_atpx_handler(void);
 bool radeon_has_atpx_dgpu_power_cntl(void);
+bool radeon_is_atpx_hybrid(void);
 #else
 static inline void radeon_register_atpx_handler(void) {}
 static inline void radeon_unregister_atpx_handler(void) {}
 static inline bool radeon_has_atpx_dgpu_power_cntl(void) { return false; }
+static inline bool radeon_is_atpx_hybrid(void) { return false; }
 #endif

 int radeon_no_wb;
-- 
2.5.5



  1   2   3   >