1. 25 Feb, 2021 4 commits
    • Noralf Trønnes's avatar
      drm/shmem-helpers: vunmap: Don't put pages for dma-buf · cdea7251
      Noralf Trønnes authored
      dma-buf importing was reworked in commit 7d2cd72a
      ("drm/shmem-helpers: Simplify dma-buf importing"). Before that commit
      drm_gem_shmem_prime_import_sg_table() did set ->pages_use_count=1 and
      drm_gem_shmem_vunmap_locked() could call drm_gem_shmem_put_pages()
      unconditionally. Now without the use count set, put pages is called also
      on dma-bufs. Fix this by only putting pages if it's not imported.
      Signed-off-by: default avatarNoralf Trønnes <noralf@tronnes.org>
      Fixes: 7d2cd72a ("drm/shmem-helpers: Simplify dma-buf importing")
      Cc: Daniel Vetter <daniel.vetter@ffwll.ch>
      Cc: Thomas Zimmermann <tzimmermann@suse.de>
      Acked-by: default avatarThomas Zimmermann <tzimmermann@suse.de>
      Tested-by: default avatarThomas Zimmermann <tzimmermann@suse.de>
      Signed-off-by: default avatarThomas Zimmermann <tzimmermann@suse.de>
      Link: https://patchwork.freedesktop.org/patch/msgid/20210219122203.51130-1-noralf@tronnes.org
      cdea7251
    • Maxime Ripard's avatar
      drm/todo: Remove the drm_atomic_state todo item · c129b498
      Maxime Ripard authored
      Only planes' prepare_fb and cleanup_fb, and encoders' atomic_check and
      atomic_mode_set hooks remain with an object state and not the global
      drm_atomic_state.
      
      prepare_fb and cleanup_fb operate by design on a given state and
      depending on the calling site can operate on either the old or new
      state, so it doesn't really make much sense to convert them.
      
      The encoders' atomic_check and atomic_mode_set operate on the CRTC and
      connector state connected to them since encoders don't have a state of
      their own. Without those state pointers, we would need to get the CRTC
      through the drm_connector_state crtc pointer.
      
      However, in order to get the drm_connector_state pointer, we would need
      to get the connector itself and while usually we have a single connector
      connected to the encoder, we can't really get it from the encoder at
      the moment since it could be behind any number of bridges.
      
      While this could be addressed by (for example) listing all the
      connectors and finding the one that has the encoder as its source, it
      feels like an unnecessary rework for something that is slowly getting
      replaced by bridges.
      
      Since all the users that matter have been converted, let's remove the
      TODO item.
      Acked-by: default avatarDaniel Vetter <daniel.vetter@ffwll.ch>
      Signed-off-by: default avatarMaxime Ripard <maxime@cerno.tech>
      Acked-by: default avatarThomas Zimmermann <tzimmermann@suse.de>
      Link: https://patchwork.freedesktop.org/patch/msgid/20210219120032.260676-11-maxime@cerno.tech
      c129b498
    • Maxime Ripard's avatar
      drm: Use state helper instead of the plane state pointer · 37418bf1
      Maxime Ripard authored
      Many drivers reference the plane->state pointer in order to get the
      current plane state in their atomic_update or atomic_disable hooks,
      which would be the new plane state in the global atomic state since
      _swap_state happened when those hooks are run.
      
      Use the drm_atomic_get_new_plane_state helper to get that state to make it
      more obvious.
      
      This was made using the coccinelle script below:
      
      @ plane_atomic_func @
      identifier helpers;
      identifier func;
      @@
      
      (
       static const struct drm_plane_helper_funcs helpers = {
       	...,
       	.atomic_disable = func,
      	...,
       };
      |
       static const struct drm_plane_helper_funcs helpers = {
       	...,
       	.atomic_update = func,
      	...,
       };
      )
      
      @ adds_new_state @
      identifier plane_atomic_func.func;
      identifier plane, state;
      identifier new_state;
      @@
      
       func(struct drm_plane *plane, struct drm_atomic_state *state)
       {
       	...
      -	struct drm_plane_state *new_state = plane->state;
      +	struct drm_plane_state *new_state = drm_atomic_get_new_plane_state(state, plane);
      	...
       }
      
      @ include depends on adds_new_state @
      @@
      
       #include <drm/drm_atomic.h>
      
      @ no_include depends on !include && adds_new_state @
      @@
      
      + #include <drm/drm_atomic.h>
        #include <drm/...>
      Reviewed-by: default avatarVille Syrjälä <ville.syrjala@linux.intel.com>
      Signed-off-by: default avatarMaxime Ripard <maxime@cerno.tech>
      Acked-by: default avatarThomas Zimmermann <tzimmermann@suse.de>
      Link: https://lore.kernel.org/r/20210219120032.260676-1-maxime@cerno.tech
      37418bf1
    • Maxime Ripard's avatar
      drm/atomic: Pass the full state to planes atomic disable and update · 977697e2
      Maxime Ripard authored
      The current atomic helpers have either their object state being passed as
      an argument or the full atomic state.
      
      The former is the pattern that was done at first, before switching to the
      latter for new hooks or when it was needed.
      
      Let's convert the remaining helpers to provide a consistent interface,
      this time with the planes atomic_update and atomic_disable.
      
      The conversion was done using the coccinelle script below, built tested on
      all the drivers.
      
      @@
      identifier plane, plane_state;
      symbol state;
      @@
      
       struct drm_plane_helper_funcs {
       	...
      	void (*atomic_update)(struct drm_plane *plane,
      -			      struct drm_plane_state *plane_state);
      +			      struct drm_atomic_state *state);
       	...
       }
      
      @@
      identifier plane, plane_state;
      symbol state;
      @@
      
       struct drm_plane_helper_funcs {
      	...
      	void (*atomic_disable)(struct drm_plane *plane,
      -			       struct drm_plane_state *plane_state);
      +			       struct drm_atomic_state *state);
      	...
       }
      
      @ plane_atomic_func @
      identifier helpers;
      identifier func;
      @@
      
      (
       static const struct drm_plane_helper_funcs helpers = {
       	...,
       	.atomic_update = func,
      	...,
       };
      |
       static const struct drm_plane_helper_funcs helpers = {
       	...,
       	.atomic_disable = func,
      	...,
       };
      )
      
      @@
      struct drm_plane_helper_funcs *FUNCS;
      identifier f;
      identifier crtc_state;
      identifier plane, plane_state, state;
      expression e;
      @@
      
       f(struct drm_crtc_state *crtc_state)
       {
       	...
       	struct drm_atomic_state *state = e;
       	<+...
      (
      -	FUNCS->atomic_disable(plane, plane_state)
      +	FUNCS->atomic_disable(plane, state)
      |
      -	FUNCS->atomic_update(plane, plane_state)
      +	FUNCS->atomic_update(plane, state)
      )
       	...+>
       }
      
      @@
      identifier plane_atomic_func.func;
      identifier plane;
      symbol state;
      @@
      
       func(struct drm_plane *plane,
      -    struct drm_plane_state *state)
      +    struct drm_plane_state *old_plane_state)
       {
      	<...
      -	state
      +	old_plane_state
      	...>
       }
      
      @ ignores_old_state @
      identifier plane_atomic_func.func;
      identifier plane, old_state;
      @@
      
       func(struct drm_plane *plane, struct drm_plane_state *old_state)
       {
      	... when != old_state
       }
      
      @ adds_old_state depends on plane_atomic_func && !ignores_old_state @
      identifier plane_atomic_func.func;
      identifier plane, plane_state;
      @@
      
       func(struct drm_plane *plane, struct drm_plane_state *plane_state)
       {
      +	struct drm_plane_state *plane_state = drm_atomic_get_old_plane_state(state, plane);
       	...
       }
      
      @ depends on plane_atomic_func @
      identifier plane_atomic_func.func;
      identifier plane, plane_state;
      @@
      
       func(struct drm_plane *plane,
      -     struct drm_plane_state *plane_state
      +     struct drm_atomic_state *state
           )
       { ... }
      
      @ include depends on adds_old_state @
      @@
      
       #include <drm/drm_atomic.h>
      
      @ no_include depends on !include && adds_old_state @
      @@
      
      + #include <drm/drm_atomic.h>
        #include <drm/...>
      
      @@
      identifier plane_atomic_func.func;
      identifier plane, state;
      identifier plane_state;
      @@
      
       func(struct drm_plane *plane, struct drm_atomic_state *state) {
       	...
       	struct drm_plane_state *plane_state = drm_atomic_get_old_plane_state(state, plane);
       	<+...
      -	plane_state->state
      +	state
       	...+>
       }
      Reviewed-by: default avatarLaurent Pinchart <laurent.pinchart@ideasonboard.com>
      Signed-off-by: default avatarMaxime Ripard <maxime@cerno.tech>
      Acked-by: default avatarThomas Zimmermann <tzimmermann@suse.de>
      Link: https://patchwork.freedesktop.org/patch/msgid/20210219120032.260676-9-maxime@cerno.tech
      977697e2
  2. 24 Feb, 2021 10 commits
    • Maxime Ripard's avatar
      drm: Rename plane->state variables in atomic update and disable · 41016fe1
      Maxime Ripard authored
      Some drivers are storing the plane->state pointer in atomic_update and
      atomic_disable in a variable simply called state, while the state passed
      as an argument is called old_state.
      
      In order to ease subsequent reworks and to avoid confusing or
      inconsistent names, let's rename those variables to new_state.
      
      This was done using the following coccinelle script, plus some manual
      changes for mtk and tegra.
      
      @ plane_atomic_func @
      identifier helpers;
      identifier func;
      @@
      
      (
       static const struct drm_plane_helper_funcs helpers = {
       	...,
       	.atomic_disable = func,
      	...,
       };
      |
       static const struct drm_plane_helper_funcs helpers = {
       	...,
       	.atomic_update = func,
      	...,
       };
      )
      
      @ moves_new_state_old_state @
      identifier plane_atomic_func.func;
      identifier plane;
      symbol old_state;
      symbol state;
      @@
      
       func(struct drm_plane *plane, struct drm_plane_state *old_state)
       {
       	...
      -	struct drm_plane_state *state = plane->state;
      +	struct drm_plane_state *new_state = plane->state;
      	...
       }
      
      @ depends on moves_new_state_old_state @
      identifier plane_atomic_func.func;
      identifier plane;
      identifier old_state;
      symbol state;
      @@
      
       func(struct drm_plane *plane, struct drm_plane_state *old_state)
       {
       	<...
      -	state
      +	new_state
      	...>
       }
      
      @ moves_new_state_oldstate @
      identifier plane_atomic_func.func;
      identifier plane;
      symbol oldstate;
      symbol state;
      @@
      
       func(struct drm_plane *plane, struct drm_plane_state *oldstate)
       {
       	...
      -	struct drm_plane_state *state = plane->state;
      +	struct drm_plane_state *newstate = plane->state;
      	...
       }
      
      @ depends on moves_new_state_oldstate @
      identifier plane_atomic_func.func;
      identifier plane;
      identifier old_state;
      symbol state;
      @@
      
       func(struct drm_plane *plane, struct drm_plane_state *old_state)
       {
       	<...
      -	state
      +	newstate
      	...>
       }
      
      @ moves_new_state_old_pstate @
      identifier plane_atomic_func.func;
      identifier plane;
      symbol old_pstate;
      symbol state;
      @@
      
       func(struct drm_plane *plane, struct drm_plane_state *old_pstate)
       {
       	...
      -	struct drm_plane_state *state = plane->state;
      +	struct drm_plane_state *new_pstate = plane->state;
      	...
       }
      
      @ depends on moves_new_state_old_pstate @
      identifier plane_atomic_func.func;
      identifier plane;
      identifier old_pstate;
      symbol state;
      @@
      
       func(struct drm_plane *plane, struct drm_plane_state *old_pstate)
       {
       	<...
      -	state
      +	new_pstate
      	...>
       }
      Reviewed-by: default avatarVille Syrjälä <ville.syrjala@linux.intel.com>
      Signed-off-by: default avatarMaxime Ripard <maxime@cerno.tech>
      Acked-by: default avatarThomas Zimmermann <tzimmermann@suse.de>
      Link: https://patchwork.freedesktop.org/patch/msgid/20210219120032.260676-8-maxime@cerno.tech
      41016fe1
    • Maxime Ripard's avatar
      drm: Store new plane state in a variable for atomic_update and disable · e05162c0
      Maxime Ripard authored
      In order to store the new plane state in a subsequent helper, let's move
      the plane->state dereferences into a variable.
      
      This was done using the following coccinelle script, plus some hand
      changes for vmwgfx:
      
      @ plane_atomic_func @
      identifier helpers;
      identifier func;
      @@
      
      (
       static const struct drm_plane_helper_funcs helpers = {
       	...,
       	.atomic_disable = func,
      	...,
       };
      |
       static const struct drm_plane_helper_funcs helpers = {
       	...,
       	.atomic_update = func,
      	...,
       };
      )
      
      @ has_new_state_old_state @
      identifier plane_atomic_func.func;
      identifier plane;
      identifier new_state;
      symbol old_state;
      @@
      
       func(struct drm_plane *plane, struct drm_plane_state *old_state)
       {
       	...
       	struct drm_plane_state *new_state = plane->state;
      	...
       }
      
      @ depends on !has_new_state_old_state @
      identifier plane_atomic_func.func;
      identifier plane;
      symbol old_state;
      @@
      
       func(struct drm_plane *plane, struct drm_plane_state *old_state)
       {
      +	struct drm_plane_state *new_state = plane->state;
       	<+...
      -	plane->state
      +	new_state
      	...+>
       }
      
      @ has_new_state_state @
      identifier plane_atomic_func.func;
      identifier plane;
      identifier new_state;
      symbol state;
      @@
      
       func(struct drm_plane *plane, struct drm_plane_state *state)
       {
       	...
       	struct drm_plane_state *new_state = plane->state;
      	...
       }
      
      @ depends on !has_new_state_state @
      identifier plane_atomic_func.func;
      identifier plane;
      symbol state;
      @@
      
       func(struct drm_plane *plane, struct drm_plane_state *state)
       {
      +	struct drm_plane_state *new_plane_state = plane->state;
       	<+...
      -	plane->state
      +	new_plane_state
      	...+>
       }
      
      @ has_new_state_old_s @
      identifier plane_atomic_func.func;
      identifier plane;
      identifier new_state;
      symbol old_s;
      @@
      
       func(struct drm_plane *plane, struct drm_plane_state *old_s)
       {
       	...
       	struct drm_plane_state *new_state = plane->state;
      	...
       }
      
      @ depends on !has_new_state_old_s @
      identifier plane_atomic_func.func;
      identifier plane;
      symbol old_s;
      @@
      
       func(struct drm_plane *plane, struct drm_plane_state *old_s)
       {
      +	struct drm_plane_state *new_s = plane->state;
       	<+...
      -	plane->state
      +	new_s
      	...+>
       }
      Reviewed-by: default avatarLaurent Pinchart <laurent.pinchart@ideasonboard.com>
      Signed-off-by: default avatarMaxime Ripard <maxime@cerno.tech>
      Acked-by: default avatarThomas Zimmermann <tzimmermann@suse.de>
      Link: https://lore.kernel.org/r/20210219120032.260676-1-maxime@cerno.tech
      e05162c0
    • Maxime Ripard's avatar
      drm: Use state helper instead of plane state pointer in atomic_check · 0b6aaf9d
      Maxime Ripard authored
      Many drivers reference the plane->state pointer in order to get the
      current plane state in their atomic_check hook, which would be the old
      plane state in the global atomic state since _swap_state hasn't happened
      when atomic_check is run.
      
      Use the drm_atomic_get_old_plane_state helper to get that state to make
      it more obvious.
      
      This was made using the coccinelle script below:
      
      @ plane_atomic_func @
      identifier helpers;
      identifier func;
      @@
      
      static struct drm_plane_helper_funcs helpers = {
      	...,
      	.atomic_check = func,
      	...,
      };
      
      @ replaces_old_state @
      identifier plane_atomic_func.func;
      identifier plane, state, plane_state;
      @@
      
       func(struct drm_plane *plane, struct drm_atomic_state *state) {
       	...
      -	struct drm_plane_state *plane_state = plane->state;
      +	struct drm_plane_state *plane_state = drm_atomic_get_old_plane_state(state, plane);
       	...
       }
      
      @@
      identifier plane_atomic_func.func;
      identifier plane, state, plane_state;
      @@
      
       func(struct drm_plane *plane, struct drm_atomic_state *state) {
       	struct drm_plane_state *plane_state = drm_atomic_get_old_plane_state(state, plane);
       	<...
      -	plane->state
      +	plane_state
       	...>
       }
      
      @ adds_old_state @
      identifier plane_atomic_func.func;
      identifier plane, state;
      @@
      
       func(struct drm_plane *plane, struct drm_atomic_state *state) {
      +	struct drm_plane_state *old_plane_state = drm_atomic_get_old_plane_state(state, plane);
       	<...
      -	plane->state
      +	old_plane_state
       	...>
       }
      
      @ include depends on adds_old_state || replaces_old_state @
      @@
      
       #include <drm/drm_atomic.h>
      
      @ no_include depends on !include && (adds_old_state || replaces_old_state) @
      @@
      
      + #include <drm/drm_atomic.h>
        #include <drm/...>
      Reviewed-by: default avatarVille Syrjälä <ville.syrjala@linux.intel.com>
      Signed-off-by: default avatarMaxime Ripard <maxime@cerno.tech>
      Acked-by: default avatarThomas Zimmermann <tzimmermann@suse.de>
      Link: https://patchwork.freedesktop.org/patch/msgid/20210219120032.260676-6-maxime@cerno.tech
      0b6aaf9d
    • Maxime Ripard's avatar
      drm: Use the state pointer directly in planes atomic_check · dec92020
      Maxime Ripard authored
      Now that atomic_check takes the global atomic state as a parameter, we
      don't need to go through the pointer in the plane state.
      
      This was done using the following coccinelle script:
      
      @ plane_atomic_func @
      identifier helpers;
      identifier func;
      @@
      
      static struct drm_plane_helper_funcs helpers = {
      	...,
      	.atomic_check = func,
      	...,
      };
      
      @@
      identifier plane_atomic_func.func;
      identifier plane, state;
      identifier plane_state;
      @@
      
        func(struct drm_plane *plane, struct drm_atomic_state *state) {
        ...
      - struct drm_plane_state *plane_state = drm_atomic_get_new_plane_state(state, plane);
        <... when != plane_state
      - plane_state->state
      + state
        ...>
       }
      
      @@
      identifier plane_atomic_func.func;
      identifier plane, state;
      identifier plane_state;
      @@
      
        func(struct drm_plane *plane, struct drm_atomic_state *state) {
        ...
        struct drm_plane_state *plane_state = drm_atomic_get_new_plane_state(state, plane);
        <...
      - plane_state->state
      + state
        ...>
       }
      Reviewed-by: default avatarLaurent Pinchart <laurent.pinchart@ideasonboard.com>
      Signed-off-by: default avatarMaxime Ripard <maxime@cerno.tech>
      Acked-by: default avatarThomas Zimmermann <tzimmermann@suse.de>
      Link: https://patchwork.freedesktop.org/patch/msgid/20210219120032.260676-5-maxime@cerno.tech
      dec92020
    • Maxime Ripard's avatar
      drm/atomic: Pass the full state to planes atomic_check · 7c11b99a
      Maxime Ripard authored
      The current atomic helpers have either their object state being passed as
      an argument or the full atomic state.
      
      The former is the pattern that was done at first, before switching to the
      latter for new hooks or when it was needed.
      
      Let's convert all the remaining helpers to provide a consistent
      interface, starting with the planes atomic_check.
      
      The conversion was done using the coccinelle script below plus some
      manual changes for vmwgfx, built tested on all the drivers.
      
      @@
      identifier plane, plane_state;
      symbol state;
      @@
      
       struct drm_plane_helper_funcs {
       	...
      	int (*atomic_check)(struct drm_plane *plane,
      -			    struct drm_plane_state *plane_state);
      +			    struct drm_atomic_state *state);
      	...
      }
      
      @ plane_atomic_func @
      identifier helpers;
      identifier func;
      @@
      
      static const struct drm_plane_helper_funcs helpers = {
      	...,
       	.atomic_check = func,
      	...,
      };
      
      @@
      struct drm_plane_helper_funcs *FUNCS;
      identifier f;
      identifier dev;
      identifier plane, plane_state, state;
      @@
      
       f(struct drm_device *dev, struct drm_atomic_state *state)
       {
       	<+...
      -	FUNCS->atomic_check(plane, plane_state)
      +	FUNCS->atomic_check(plane, state)
       	...+>
       }
      
      @ ignores_new_state @
      identifier plane_atomic_func.func;
      identifier plane, new_plane_state;
      @@
      
       func(struct drm_plane *plane, struct drm_plane_state *new_plane_state)
       {
      	... when != new_plane_state
       }
      
      @ adds_new_state depends on plane_atomic_func && !ignores_new_state @
      identifier plane_atomic_func.func;
      identifier plane, new_plane_state;
      @@
      
       func(struct drm_plane *plane, struct drm_plane_state *new_plane_state)
       {
      +	struct drm_plane_state *new_plane_state = drm_atomic_get_new_plane_state(state, plane);
       	...
       }
      
      @ depends on plane_atomic_func @
      identifier plane_atomic_func.func;
      identifier plane, new_plane_state;
      @@
      
       func(struct drm_plane *plane,
      -     struct drm_plane_state *new_plane_state
      +     struct drm_atomic_state *state
           )
       { ... }
      
      @ include depends on adds_new_state @
      @@
      
       #include <drm/drm_atomic.h>
      
      @ no_include depends on !include && adds_new_state @
      @@
      
      + #include <drm/drm_atomic.h>
        #include <drm/...>
      Reviewed-by: default avatarLaurent Pinchart <laurent.pinchart@ideasonboard.com>
      Signed-off-by: default avatarMaxime Ripard <maxime@cerno.tech>
      Acked-by: default avatarThomas Zimmermann <tzimmermann@suse.de>
      Link: https://patchwork.freedesktop.org/patch/msgid/20210219120032.260676-4-maxime@cerno.tech
      7c11b99a
    • Maxime Ripard's avatar
      drm/atmel-hlcdc: Rename custom plane state variable · 6af70eb3
      Maxime Ripard authored
      Subsequent reworks will pass the global atomic state in the function
      prototype, and atomic_check and atomic_update already have such a
      variable already. Let's change them to ease the rework.
      Acked-by: default avatarSam Ravnborg <sam@ravnborg.org>
      Signed-off-by: default avatarMaxime Ripard <maxime@cerno.tech>
      Acked-by: default avatarThomas Zimmermann <tzimmermann@suse.de>
      Link: https://patchwork.freedesktop.org/patch/msgid/20210219120032.260676-3-maxime@cerno.tech
      6af70eb3
    • Maxime Ripard's avatar
      drm: Rename plane atomic_check state names · ba5c1649
      Maxime Ripard authored
      Most drivers call the argument to the plane atomic_check hook simply
      state, which is going to conflict with the global atomic state in a
      later rework. Let's rename it to new_plane_state (or new_state depending
      on the convention used in the driver).
      
      This was done using the coccinelle script below, and built tested:
      
      @ plane_atomic_func @
      identifier helpers;
      identifier func;
      @@
      
       static const struct drm_plane_helper_funcs helpers = {
       	.atomic_check = func,
       };
      
      @ has_old_state @
      identifier plane_atomic_func.func;
      identifier plane;
      expression e;
      symbol old_state;
      symbol state;
      @@
      
       func(struct drm_plane *plane, struct drm_plane_state *state)
       {
       	...
       	struct drm_plane_state *old_state = e;
       	...
       }
      
      @ depends on has_old_state @
      identifier plane_atomic_func.func;
      identifier plane;
      symbol old_state;
      @@
      
       func(struct drm_plane *plane,
      -	struct drm_plane_state *state
      +	struct drm_plane_state *new_state
           )
       {
       	<+...
      -	state
      +	new_state
      	...+>
       }
      
      @ has_state @
      identifier plane_atomic_func.func;
      identifier plane;
      symbol state;
      @@
      
       func(struct drm_plane *plane, struct drm_plane_state *state)
       {
       	...
       }
      
      @ depends on has_state @
      identifier plane_atomic_func.func;
      identifier plane;
      symbol old_state;
      @@
      
       func(struct drm_plane *plane,
      -	struct drm_plane_state *state
      +	struct drm_plane_state *new_plane_state
           )
       {
       	<+...
      -	state
      +	new_plane_state
      	...+>
       }
      Reviewed-by: default avatarLaurent Pinchart <laurent.pinchart@ideasonboard.com>
      Signed-off-by: default avatarMaxime Ripard <maxime@cerno.tech>
      Acked-by: default avatarThomas Zimmermann <tzimmermann@suse.de>
      Link: https://patchwork.freedesktop.org/patch/msgid/20210219120032.260676-2-maxime@cerno.tech
      ba5c1649
    • Maxime Ripard's avatar
      drm/atomic: Pass the full state to planes async atomic check and update · 5ddb0bd4
      Maxime Ripard authored
      The current atomic helpers have either their object state being passed as
      an argument or the full atomic state.
      
      The former is the pattern that was done at first, before switching to the
      latter for new hooks or when it was needed.
      
      Let's start convert all the remaining helpers to provide a consistent
      interface, starting with the planes atomic_async_check and
      atomic_async_update.
      
      The conversion was done using the coccinelle script below, built tested on
      all the drivers.
      
      @@
      identifier plane, plane_state;
      symbol state;
      @@
      
       struct drm_plane_helper_funcs {
       	...
      	int (*atomic_async_check)(struct drm_plane *plane,
      -				  struct drm_plane_state *plane_state);
      +				  struct drm_atomic_state *state);
      	...
       }
      
      @@
      identifier plane, plane_state;
      symbol state;
      @@
       struct drm_plane_helper_funcs {
       	...
      	void (*atomic_async_update)(struct drm_plane *plane,
      -				    struct drm_plane_state *plane_state);
      +				    struct drm_atomic_state *state);
      	...
       }
      
      @ plane_atomic_func @
      identifier helpers;
      identifier func;
      @@
      
      (
       static const struct drm_plane_helper_funcs helpers = {
      	...,
       	.atomic_async_check = func,
      	...,
       };
      |
       static const struct drm_plane_helper_funcs helpers = {
       	...,
       	.atomic_async_update = func,
       	...,
       };
      )
      
      @@
      struct drm_plane_helper_funcs *FUNCS;
      identifier f;
      identifier dev;
      identifier plane, plane_state, state;
      @@
      
       f(struct drm_device *dev, struct drm_atomic_state *state)
       {
       	<+...
      -	FUNCS->atomic_async_check(plane, plane_state)
      +	FUNCS->atomic_async_check(plane, state)
       	...+>
       }
      
      @@
      struct drm_plane_helper_funcs *FUNCS;
      identifier f;
      identifier dev;
      identifier plane, plane_state, state;
      @@
      
       f(struct drm_device *dev, struct drm_atomic_state *state)
       {
       	<+...
      -	FUNCS->atomic_async_update(plane, plane_state)
      +	FUNCS->atomic_async_update(plane, state)
       	...+>
       }
      
      @@
      identifier mtk_plane_atomic_async_update;
      identifier plane;
      symbol new_state, state;
      expression e;
      @@
      
        void mtk_plane_atomic_async_update(struct drm_plane *plane, struct drm_plane_state *new_state)
      {
        ...
      - struct mtk_plane_state *state = e;
      + struct mtk_plane_state *new_plane_state = e;
        <+...
      -       state
      +       new_plane_state
        ...+>
        }
      
      @@
      identifier plane_atomic_func.func;
      identifier plane;
      symbol state;
      @@
      
       func(struct drm_plane *plane,
      -    struct drm_plane_state *state)
      +    struct drm_plane_state *new_plane_state)
       {
      	<...
      -	state
      +	new_plane_state
      	...>
       }
      
      @ ignores_new_state @
      identifier plane_atomic_func.func;
      identifier plane, new_plane_state;
      @@
      
       func(struct drm_plane *plane, struct drm_plane_state *new_plane_state)
       {
      	... when != new_plane_state
       }
      
      @ adds_new_state depends on plane_atomic_func && !ignores_new_state @
      identifier plane_atomic_func.func;
      identifier plane, new_plane_state;
      @@
      
       func(struct drm_plane *plane, struct drm_plane_state *new_plane_state)
       {
      +	struct drm_plane_state *new_plane_state = drm_atomic_get_new_plane_state(state, plane);
       	...
       }
      
      @ depends on plane_atomic_func @
      identifier plane_atomic_func.func;
      identifier plane, plane_state;
      @@
      
       func(struct drm_plane *plane,
      -     struct drm_plane_state *plane_state
      +     struct drm_atomic_state *state
           )
       { ... }
      
      @ include depends on adds_new_state @
      @@
      
       #include <drm/drm_atomic.h>
      
      @ no_include depends on !include && adds_new_state @
      @@
      
      + #include <drm/drm_atomic.h>
        #include <drm/...>
      
      @@
      identifier plane_atomic_func.func;
      identifier plane, state;
      identifier plane_state;
      @@
      
       func(struct drm_plane *plane, struct drm_atomic_state *state) {
              ...
              struct drm_plane_state *plane_state = drm_atomic_get_new_plane_state(state, plane);
              <+...
      -       plane_state->state
      +       state
              ...+>
       }
      Acked-by: default avatarThomas Zimmermann <tzimmermann@suse.de>
      Signed-off-by: default avatarMaxime Ripard <maxime@cerno.tech>
      Link: https://patchwork.freedesktop.org/patch/msgid/20210219120032.260676-1-maxime@cerno.tech
      5ddb0bd4
    • Wayne Lin's avatar
      drm/dp_mst: Set CLEAR_PAYLOAD_ID_TABLE as broadcast · d919d3d6
      Wayne Lin authored
      [Why & How]
      According to DP spec, CLEAR_PAYLOAD_ID_TABLE is a path broadcast request
      message and current implementation is incorrect. Fix it.
      Signed-off-by: default avatarWayne Lin <Wayne.Lin@amd.com>
      Cc: stable@vger.kernel.org
      Reviewed-by: default avatarLyude Paul <lyude@redhat.com>
      Signed-off-by: default avatarLyude Paul <lyude@redhat.com>
      Link: https://patchwork.freedesktop.org/patch/msgid/20210224101521.6713-3-Wayne.Lin@amd.com
      d919d3d6
    • Wayne Lin's avatar
      drm/dp_mst: Revise broadcast msg lct & lcr · 419e91ea
      Wayne Lin authored
      [Why & How]
      According to DP spec, broadcast message LCT equals to 1 and LCR equals
      to 6. Current implementation is incorrect. Fix it.
      In addition, revise a bit the hdr->rad handling to include broadcast
      case.
      Signed-off-by: default avatarWayne Lin <Wayne.Lin@amd.com>
      Cc: stable@vger.kernel.org
      Reviewed-by: default avatarLyude Paul <lyude@redhat.com>
      Signed-off-by: default avatarLyude Paul <lyude@redhat.com>
      Link: https://patchwork.freedesktop.org/patch/msgid/20210224101521.6713-2-Wayne.Lin@amd.com
      419e91ea
  3. 23 Feb, 2021 9 commits
  4. 22 Feb, 2021 3 commits
    • Tong Zhang's avatar
      drm/ast: fix memory leak when unload the driver · dc739820
      Tong Zhang authored
      a connector is leaked upon module unload, it seems that we should do
      similar to sample driver as suggested in drm_drv.c.
      
      Adding drm_atomic_helper_shutdown() in ast_pci_remove to prevent leaking.
      
      [  153.822134] WARNING: CPU: 0 PID: 173 at drivers/gpu/drm/drm_mode_config.c:504 drm_mode_config_cle0
      [  153.822698] Modules linked in: ast(-) drm_vram_helper drm_ttm_helper ttm [last unloaded: ttm]
      [  153.823197] CPU: 0 PID: 173 Comm: modprobe Tainted: G        W         5.11.0-03615-g55f62bc873474
      [  153.823708] Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS rel-1.13.0-48-gd9c812dda519-4
      [  153.824333] RIP: 0010:drm_mode_config_cleanup+0x418/0x470
      [  153.824637] Code: 0c 00 00 00 00 48 8b 84 24 a8 00 00 00 65 48 33 04 25 28 00 00 00 75 65 48 81 c0
      [  153.825668] RSP: 0018:ffff888103c9fb70 EFLAGS: 00010212
      [  153.825962] RAX: ffff888102b0d100 RBX: ffff888102b0c298 RCX: ffffffff818d8b2b
      [  153.826356] RDX: dffffc0000000000 RSI: 000000007fffffff RDI: ffff888102b0c298
      [  153.826748] RBP: ffff888103c9fba0 R08: 0000000000000001 R09: ffffed1020561857
      [  153.827146] R10: ffff888102b0c2b7 R11: ffffed1020561856 R12: ffff888102b0c000
      [  153.827538] R13: ffff888102b0c2d8 R14: ffff888102b0c2d8 R15: 1ffff11020793f70
      [  153.827935] FS:  00007f24bff456a0(0000) GS:ffff88815b400000(0000) knlGS:0000000000000000
      [  153.828380] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
      [  153.828697] CR2: 0000000001c39018 CR3: 0000000103c90000 CR4: 00000000000006f0
      [  153.829096] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
      [  153.829486] DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
      [  153.829883] Call Trace:
      [  153.830024]  ? drmm_mode_config_init+0x930/0x930
      [  153.830281]  ? cpumask_next+0x16/0x20
      [  153.830488]  ? mnt_get_count+0x66/0x80
      [  153.830699]  ? drm_mode_config_cleanup+0x470/0x470
      [  153.830972]  drm_managed_release+0xed/0x1c0
      [  153.831208]  drm_dev_release+0x3a/0x50
      [  153.831420]  release_nodes+0x39e/0x410
      [  153.831631]  ? devres_release+0x40/0x40
      [  153.831852]  device_release_driver_internal+0x158/0x270
      [  153.832143]  driver_detach+0x76/0xe0
      [  153.832344]  bus_remove_driver+0x7e/0x100
      [  153.832568]  pci_unregister_driver+0x28/0xf0
      [  153.832821]  __x64_sys_delete_module+0x268/0x300
      [  153.833086]  ? __ia32_sys_delete_module+0x300/0x300
      [  153.833357]  ? call_rcu+0x372/0x4f0
      [  153.833553]  ? fpregs_assert_state_consistent+0x4d/0x60
      [  153.833840]  ? exit_to_user_mode_prepare+0x2f/0x130
      [  153.834118]  do_syscall_64+0x33/0x40
      [  153.834317]  entry_SYSCALL_64_after_hwframe+0x44/0xae
      [  153.834597] RIP: 0033:0x7f24bfec7cf7
      [  153.834797] Code: 48 89 57 30 48 8b 04 24 48 89 47 38 e9 1d a0 02 00 48 89 f8 48 89 f7 48 89 d6 41
      [  153.835812] RSP: 002b:00007fff72e6cb58 EFLAGS: 00000202 ORIG_RAX: 00000000000000b0
      [  153.836234] RAX: ffffffffffffffda RBX: 00007f24bff45690 RCX: 00007f24bfec7cf7
      [  153.836623] RDX: 00000000ffffffff RSI: 0000000000000080 RDI: 0000000001c2fb10
      [  153.837018] RBP: 0000000001c2fac0 R08: 2f2f2f2f2f2f2f2f R09: 0000000001c2fac0
      [  153.837408] R10: fefefefefefefeff R11: 0000000000000202 R12: 0000000001c2fac0
      [  153.837798] R13: 0000000001c2f9d0 R14: 0000000000000000 R15: 0000000000000001
      [  153.838194] ---[ end trace b92031513bbe596c ]---
      [  153.838441] [drm:drm_mode_config_cleanup] *ERROR* connector VGA-1 leaked!
      Signed-off-by: default avatarTong Zhang <ztong0001@gmail.com>
      Signed-off-by: default avatarThomas Zimmermann <tzimmermann@suse.de>
      Link: https://patchwork.freedesktop.org/patch/msgid/20210222023322.984885-1-ztong0001@gmail.com
      dc739820
    • Kai-Heng Feng's avatar
      efifb: Ensure graphics device for efifb stays at PCI D0 · a6c0fd3d
      Kai-Heng Feng authored
      We are seeing root ports on some desktop boards support D3cold for
      discrete graphics card. So when efifb is in use while graphics device
      isn't bound to a driver, PCI and ACPI will put the graphics to D3cold
      when runtime suspend kicks in, makes efifb stop working.
      
      So ensure the graphics device won't be runtime suspended, to keep efifb
      work all the time.
      Signed-off-by: default avatarKai-Heng Feng <kai.heng.feng@canonical.com>
      Reviewed-by: default avatarAlex Deucher <alexander.deucher@amd.com>
      Signed-off-by: default avatarThomas Zimmermann <tzimmermann@suse.de>
      Link: https://patchwork.freedesktop.org/patch/msgid/20210129084327.986630-1-kai.heng.feng@canonical.com
      a6c0fd3d
    • Tian Tao's avatar
      drm/drv: Remove initialization of static variables · c00697b5
      Tian Tao authored
      Address the following checkpatch errors:
      ERROR: do not initialise statics to false
      Signed-off-by: default avatarTian Tao <tiantao6@hisilicon.com>
      Acked-by: default avatarThomas Zimmermann <tzimmermann@suse.de>
      Link: https://patchwork.freedesktop.org/patch/msgid/1613701811-32037-1-git-send-email-tiantao6@hisilicon.com
      c00697b5
  5. 19 Feb, 2021 11 commits
  6. 18 Feb, 2021 3 commits