1. 25 2月, 2021 3 次提交
    • M
      drm: Use the state pointer directly in planes atomic_check · dec92020
      Maxime Ripard 提交于
      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: NLaurent Pinchart <laurent.pinchart@ideasonboard.com>
      Signed-off-by: NMaxime Ripard <maxime@cerno.tech>
      Acked-by: NThomas Zimmermann <tzimmermann@suse.de>
      Link: https://patchwork.freedesktop.org/patch/msgid/20210219120032.260676-5-maxime@cerno.tech
      dec92020
    • M
      drm/atomic: Pass the full state to planes atomic_check · 7c11b99a
      Maxime Ripard 提交于
      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: NLaurent Pinchart <laurent.pinchart@ideasonboard.com>
      Signed-off-by: NMaxime Ripard <maxime@cerno.tech>
      Acked-by: NThomas Zimmermann <tzimmermann@suse.de>
      Link: https://patchwork.freedesktop.org/patch/msgid/20210219120032.260676-4-maxime@cerno.tech
      7c11b99a
    • M
      drm: Rename plane atomic_check state names · ba5c1649
      Maxime Ripard 提交于
      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: NLaurent Pinchart <laurent.pinchart@ideasonboard.com>
      Signed-off-by: NMaxime Ripard <maxime@cerno.tech>
      Acked-by: NThomas Zimmermann <tzimmermann@suse.de>
      Link: https://patchwork.freedesktop.org/patch/msgid/20210219120032.260676-2-maxime@cerno.tech
      ba5c1649
  2. 17 2月, 2021 1 次提交
  3. 06 11月, 2020 1 次提交
    • D
      drm/<drivers>: Constify struct drm_driver · 70a59dd8
      Daniel Vetter 提交于
      Only the following drivers aren't converted:
      - amdgpu, because of the driver_feature mangling due to virt support.
        Subsequent patch will address this.
      - nouveau, because DRIVER_ATOMIC uapi is still not the default on the
        platforms where it's supported (i.e. again driver_feature mangling)
      - vc4, again because of driver_feature mangling
      - qxl, because the ioctl table is somewhere else and moving that is
        maybe a bit too much, hence the num_ioctls assignment prevents a
        const driver structure.
      - arcpgu, because that is stuck behind a pending tiny-fication series
        from me.
      - legacy drivers, because legacy requires non-const drm_driver.
      
      Note that for armada I also went ahead and made the ioctl array const.
      
      Only cc'ing the driver people who've not been converted (everyone else
      is way too much).
      
      v2: Fix one misplaced const static, should be static const (0day)
      
      v3:
      - Improve commit message (Sam)
      Acked-by: NSam Ravnborg <sam@ravnborg.org>
      Cc: kernel test robot <lkp@intel.com>
      Acked-by: NMaxime Ripard <mripard@kernel.org>
      Reviewed-by: NAlex Deucher <alexander.deucher@amd.com>
      Signed-off-by: NDaniel Vetter <daniel.vetter@ffwll.ch>
      Cc: Sam Ravnborg <sam@ravnborg.org>
      Cc: Dave Airlie <airlied@redhat.com>
      Cc: Gerd Hoffmann <kraxel@redhat.com>
      Cc: virtualization@lists.linux-foundation.org
      Cc: Harry Wentland <harry.wentland@amd.com>
      Cc: Leo Li <sunpeng.li@amd.com>
      Cc: Alex Deucher <alexander.deucher@amd.com>
      Cc: Christian König <christian.koenig@amd.com>
      Cc: Eric Anholt <eric@anholt.net>
      Cc: Maxime Ripard <mripard@kernel.org>
      Cc: Ben Skeggs <bskeggs@redhat.com>
      Cc: nouveau@lists.freedesktop.org
      Signed-off-by: NDaniel Vetter <daniel.vetter@intel.com>
      Link: https://patchwork.freedesktop.org/patch/msgid/20201104100425.1922351-5-daniel.vetter@ffwll.ch
      70a59dd8
  4. 02 11月, 2020 1 次提交
    • M
      drm/atomic: Pass the full state to CRTC atomic begin and flush · f6ebe9f9
      Maxime Ripard 提交于
      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 CRTC's atomic_begin and atomic_flush.
      
      The conversion was done using the coccinelle script below, built tested on
      all the drivers and actually tested on vc4.
      
      virtual report
      
      @@
      struct drm_crtc_helper_funcs *FUNCS;
      identifier old_crtc_state, old_state;
      identifier crtc;
      identifier f;
      @@
      
       f(struct drm_crtc_state *old_crtc_state)
       {
      	...
       	struct drm_atomic_state *old_state = old_crtc_state->state;
      	<...
      -	FUNCS->atomic_begin(crtc, old_crtc_state);
      +	FUNCS->atomic_begin(crtc, old_state);
      	...>
       }
      
      @@
      struct drm_crtc_helper_funcs *FUNCS;
      identifier old_crtc_state, old_state;
      identifier crtc;
      identifier f;
      @@
      
       f(struct drm_crtc_state *old_crtc_state)
       {
      	...
       	struct drm_atomic_state *old_state = old_crtc_state->state;
      	<...
      -	FUNCS->atomic_flush(crtc, old_crtc_state);
      +	FUNCS->atomic_flush(crtc, old_state);
      	...>
       }
      
      @@
      struct drm_crtc_helper_funcs *FUNCS;
      struct drm_crtc *crtc;
      struct drm_crtc_state *crtc_state;
      identifier dev, state;
      identifier f;
      @@
      
       f(struct drm_device *dev, struct drm_atomic_state *state, ...)
       {
      	<...
      -	FUNCS->atomic_begin(crtc, crtc_state);
      +	FUNCS->atomic_begin(crtc, state);
      	...>
       }
      
      @@
      struct drm_crtc_helper_funcs *FUNCS;
      struct drm_crtc *crtc;
      struct drm_crtc_state *crtc_state;
      identifier dev, state;
      identifier f;
      @@
      
       f(struct drm_device *dev, struct drm_atomic_state *state, ...)
       {
      	<...
      -	FUNCS->atomic_flush(crtc, crtc_state);
      +	FUNCS->atomic_flush(crtc, state);
      	...>
       }
      
      @@
      identifier crtc, old_state;
      @@
      
       struct drm_crtc_helper_funcs {
      	...
      -	void (*atomic_begin)(struct drm_crtc *crtc, struct drm_crtc_state *old_state);
      +	void (*atomic_begin)(struct drm_crtc *crtc, struct drm_atomic_state *state);
      	...
      -	void (*atomic_flush)(struct drm_crtc *crtc, struct drm_crtc_state *old_state);
      +	void (*atomic_flush)(struct drm_crtc *crtc, struct drm_atomic_state *state);
      	...
      }
      
      @ crtc_atomic_func @
      identifier helpers;
      identifier func;
      @@
      
      (
      static struct drm_crtc_helper_funcs helpers = {
      	...,
      	.atomic_begin = func,
      	...,
      };
      |
      static struct drm_crtc_helper_funcs helpers = {
      	...,
      	.atomic_flush = func,
      	...,
      };
      )
      
      @ ignores_old_state @
      identifier crtc_atomic_func.func;
      identifier crtc, old_state;
      @@
      
      void func(struct drm_crtc *crtc,
      		struct drm_crtc_state *old_state)
      {
      	... when != old_state
      }
      
      @ adds_old_state depends on crtc_atomic_func && !ignores_old_state @
      identifier crtc_atomic_func.func;
      identifier crtc, old_state;
      @@
      
      void func(struct drm_crtc *crtc, struct drm_crtc_state *old_state)
      {
      +	struct drm_crtc_state *old_state = drm_atomic_get_old_crtc_state(state, crtc);
      	...
      }
      
      @ depends on crtc_atomic_func @
      identifier crtc_atomic_func.func;
      expression E;
      type T;
      @@
      
      void func(...)
      {
      	...
      -	T state = E;
      +	T crtc_state = E;
      	<+...
      -	state
      +	crtc_state
      	...+>
      
      }
      
      @ depends on crtc_atomic_func @
      identifier crtc_atomic_func.func;
      type T;
      @@
      
      void func(...)
      {
      	...
      -	T state;
      +	T crtc_state;
      	<+...
      -	state
      +	crtc_state
      	...+>
      
      }
      
      @@
      identifier old_state;
      identifier crtc;
      @@
      
       void vc4_hvs_atomic_flush(struct drm_crtc *crtc,
      -			   struct drm_crtc_state *old_state
      +			   struct drm_atomic_state *state
      			   )
      {
      +	struct drm_crtc_state *old_state = drm_atomic_get_old_crtc_state(state, crtc);
      	...
      }
      
      @@
      identifier old_state;
      identifier crtc;
      @@
      
       void vc4_hvs_atomic_flush(struct drm_crtc *crtc,
      -			   struct drm_crtc_state *old_state
      +			   struct drm_atomic_state *state
      			   );
      
      @@
      identifier old_state;
      identifier crtc;
      @@
      
       void vmw_du_crtc_atomic_begin(struct drm_crtc *crtc,
      -			   struct drm_crtc_state *old_state
      +			   struct drm_atomic_state *state
      			   )
      {
      	...
      }
      
      @@
      identifier old_state;
      identifier crtc;
      @@
      
       void vmw_du_crtc_atomic_begin(struct drm_crtc *crtc,
      -			   struct drm_crtc_state *old_state
      +			   struct drm_atomic_state *state
      			   );
      
      @@
      identifier old_state;
      identifier crtc;
      @@
      
       void vmw_du_crtc_atomic_flush(struct drm_crtc *crtc,
      -			   struct drm_crtc_state *old_state
      +			   struct drm_atomic_state *state
      			   )
      {
      	...
      }
      
      @@
      identifier old_state;
      identifier crtc;
      @@
      
       void vmw_du_crtc_atomic_flush(struct drm_crtc *crtc,
      -			   struct drm_crtc_state *old_state
      +			   struct drm_atomic_state *state
      			   );
      
      @ depends on crtc_atomic_func @
      identifier crtc_atomic_func.func;
      identifier old_state;
      identifier crtc;
      @@
      
      void func(struct drm_crtc *crtc,
      -	       struct drm_crtc_state *old_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/...>
      Signed-off-by: NMaxime Ripard <maxime@cerno.tech>
      Reviewed-by: NVille Syrjälä <ville.syrjala@linux.intel.com>
      Acked-by: NDaniel Vetter <daniel.vetter@ffwll.ch>
      Acked-by: NThomas Zimmermann <tzimmermann@suse.de>
      Link: https://patchwork.freedesktop.org/patch/msgid/20201028123222.1732139-2-maxime@cerno.tech
      f6ebe9f9
  5. 09 10月, 2020 1 次提交
    • M
      drm/atomic: Pass the full state to CRTC atomic enable/disable · 351f950d
      Maxime Ripard 提交于
      If the CRTC driver ever needs to access the full DRM state, it can't do so
      at atomic_enable / atomic_disable time since drm_atomic_helper_swap_state
      will have cleared the pointer from the struct drm_crtc_state to the struct
      drm_atomic_state before calling those hooks.
      
      In order to allow that, let's pass the full DRM state to atomic_enable and
      atomic_disable. The conversion was done using the coccinelle script below,
      built tested on all the drivers and actually tested on vc4.
      
      virtual report
      
      @@
      struct drm_crtc_helper_funcs *FUNCS;
      identifier dev, state;
      identifier crtc, crtc_state;
      @@
      
       disable_outputs(struct drm_device *dev, struct drm_atomic_state *state)
       {
       	<...
      -	FUNCS->atomic_disable(crtc, crtc_state);
      +	FUNCS->atomic_disable(crtc, state);
       	...>
       }
      
      @@
      struct drm_crtc_helper_funcs *FUNCS;
      identifier dev, state;
      identifier crtc, crtc_state;
      @@
      
       drm_atomic_helper_commit_modeset_enables(struct drm_device *dev, struct drm_atomic_state *state)
       {
       	<...
      -	FUNCS->atomic_enable(crtc, crtc_state);
      +	FUNCS->atomic_enable(crtc, state);
       	...>
       }
      
      @@
      identifier crtc, old_state;
      @@
      
       struct drm_crtc_helper_funcs {
      	...
      -	void (*atomic_enable)(struct drm_crtc *crtc, struct drm_crtc_state *old_state);
      +	void (*atomic_enable)(struct drm_crtc *crtc, struct drm_atomic_state *state);
      	...
      -	void (*atomic_disable)(struct drm_crtc *crtc, struct drm_crtc_state *old_state);
      +	void (*atomic_disable)(struct drm_crtc *crtc, struct drm_atomic_state *state);
      	...
      }
      
      @ crtc_atomic_func @
      identifier helpers;
      identifier func;
      @@
      
      (
      static struct drm_crtc_helper_funcs helpers = {
      	...,
      	.atomic_enable = func,
      	...,
      };
      |
      static struct drm_crtc_helper_funcs helpers = {
      	...,
      	.atomic_disable = func,
      	...,
      };
      )
      
      @ ignores_old_state @
      identifier crtc_atomic_func.func;
      identifier crtc, old_state;
      @@
      
      void func(struct drm_crtc *crtc,
      		struct drm_crtc_state *old_state)
      {
      	... when != old_state
      }
      
      @ adds_old_state depends on crtc_atomic_func && !ignores_old_state @
      identifier crtc_atomic_func.func;
      identifier crtc, old_state;
      @@
      
      void func(struct drm_crtc *crtc, struct drm_crtc_state *old_state)
      {
      +	struct drm_crtc_state *old_state = drm_atomic_get_old_crtc_state(state, crtc);
      	...
      }
      
      @ depends on crtc_atomic_func @
      identifier crtc_atomic_func.func;
      expression E;
      type T;
      @@
      
      void func(...)
      {
      	...
      -	T state = E;
      +	T crtc_state = E;
      	<+...
      -	state
      +	crtc_state
      	...+>
      
      }
      
      @ depends on crtc_atomic_func @
      identifier crtc_atomic_func.func;
      type T;
      @@
      
      void func(...)
      {
      	...
      -	T state;
      +	T crtc_state;
      	<+...
      -	state
      +	crtc_state
      	...+>
      
      }
      
      @ depends on crtc_atomic_func @
      identifier crtc_atomic_func.func;
      identifier old_state;
      identifier crtc;
      @@
      
      void func(struct drm_crtc *crtc,
      -	       struct drm_crtc_state *old_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/...>
      Signed-off-by: NMaxime Ripard <maxime@cerno.tech>
      Acked-by: NDaniel Vetter <daniel.vetter@ffwll.ch>
      Link: https://patchwork.freedesktop.org/patch/msgid/845aa10ef171fc0ea060495efef142a0c13f7870.1602161031.git-series.maxime@cerno.tech
      351f950d
  6. 10 6月, 2020 3 次提交
  7. 13 4月, 2020 1 次提交
  8. 04 3月, 2020 1 次提交
  9. 22 8月, 2019 22 次提交
  10. 16 7月, 2019 1 次提交
    • S
      drm/hisilicon: drop use of drmP.h · 40b4db43
      Sam Ravnborg 提交于
      Drop the deprecated drmP.h header file.
      
      Made the header file selfcontained, and dropped unused header files.
      Fixed fallout in remaining files.
      Signed-off-by: NSam Ravnborg <sam@ravnborg.org>
      Acked-by: NEmil Velikov <emil.velikov@collabora.com>
      Cc: Xinliang Liu <z.liuxinliang@hisilicon.com>
      Cc: Rongrong Zou <zourongrong@gmail.com>
      Cc: Xinwei Kong <kong.kongxinwei@hisilicon.com>
      Cc: Chen Feng <puck.chen@hisilicon.com>
      Cc: David Airlie <airlied@linux.ie>
      Cc: Daniel Vetter <daniel@ffwll.ch>
      Cc: Gerd Hoffmann <kraxel@redhat.com>
      Cc: Thomas Zimmermann <tzimmermann@suse.de>
      Cc: Sam Ravnborg <sam@ravnborg.org>
      Cc: Allison Randal <allison@lohutok.net>
      Cc: Harry Wentland <harry.wentland@amd.com>
      Cc: Thomas Gleixner <tglx@linutronix.de>
      Cc: Souptick Joarder <jrdr.linux@gmail.com>
      Cc: John Garry <john.garry@huawei.com>
      Cc: Alex Deucher <alexander.deucher@amd.com>
      Cc: "Christian König" <christian.koenig@amd.com>
      Cc: Junwei Zhang <Jerry.Zhang@amd.com>
      Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
      Cc: Hans de Goede <hdegoede@redhat.com>
      Cc: CK Hu <ck.hu@mediatek.com>
      Cc: Benjamin Gaignard <benjamin.gaignard@linaro.org>
      Cc: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
      Cc: Jani Nikula <jani.nikula@intel.com>
      Cc: Eric Anholt <eric@anholt.net>
      Cc: "Noralf Trønnes" <noralf@tronnes.org>
      Link: https://patchwork.freedesktop.org/patch/msgid/20190630061922.7254-34-sam@ravnborg.org
      40b4db43
  11. 19 6月, 2019 1 次提交
  12. 24 1月, 2019 1 次提交
  13. 26 6月, 2018 1 次提交
  14. 01 11月, 2017 1 次提交
  15. 29 8月, 2017 1 次提交
    • J
      drm: kirin: Add mode_valid logic to avoid mode clocks we can't generate · 71f23543
      John Stultz 提交于
      Currently the hikey dsi logic cannot generate accurate byte
      clocks values for all pixel clock values. Thus if a mode clock
      is selected that cannot match the calculated byte clock, the
      device will boot with a blank screen.
      
      This patch uses the new mode_valid callback (many thanks to
      Jose Abreu for upstreaming it!) to ensure we don't select
      modes we cannot generate.
      
      Also, since the ade crtc code will adjust the mode in mode_set,
      this patch also adds a mode_fixup callback which we use to make
      sure we are validating the mode clock that will eventually be
      used.
      
      Cc: Daniel Vetter <daniel.vetter@intel.com>
      Cc: Jani Nikula <jani.nikula@linux.intel.com>
      Cc: Sean Paul <seanpaul@chromium.org>
      Cc: David Airlie <airlied@linux.ie>
      Cc: Rob Clark <robdclark@gmail.com>
      Cc: Xinliang Liu <xinliang.liu@linaro.org>
      Cc: Xinliang Liu <z.liuxinliang@hisilicon.com>
      Cc: Rongrong Zou <zourongrong@gmail.com>
      Cc: Xinwei Kong <kong.kongxinwei@hisilicon.com>
      Cc: Chen Feng <puck.chen@hisilicon.com>
      Cc: Jose Abreu <Jose.Abreu@synopsys.com>
      Cc: Archit Taneja <architt@codeaurora.org>
      Cc: dri-devel@lists.freedesktop.org
      Reviewed-by: NSean Paul <seanpaul@chromium.org>
      Signed-off-by: NJohn Stultz <john.stultz@linaro.org>
      Reviewed-by: NXinliang Liu <xinliang.liu@linaro.org>
      Signed-off-by: NDave Airlie <airlied@redhat.com>
      71f23543